/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
*
* Shell initialization
*
* David Korn
* AT&T Labs
*
*/
#include "defs.h"
#include <stak.h>
#include <ccode.h>
#include <pwd.h>
#include <tmx.h>
#include <regex.h>
#include "variables.h"
#include "path.h"
#include "fault.h"
#include "name.h"
#include "edit.h"
#include "jobs.h"
#include "io.h"
#include "shlex.h"
#include "builtins.h"
#include "lexstates.h"
#include "version.h"
#if _hdr_wctype
#include <ast_wchar.h>
#include <wctype.h>
#endif
#if !_typ_wctrans_t
typedef long wctrans_t;
#endif
#if !_lib_wctrans
{
return(1);
return(2);
return(0);
}
#endif
#if !_lib_towctrans
{
if(t==1 && isupper(c))
c = tolower(c);
else if(t==2 && islower(c))
c = toupper(c);
return(c);
}
#endif
#if SHOPT_AUDIT
"A"
#endif
#if SHOPT_BASH
"B"
#endif
#if SHOPT_COSHELL
"J"
#else
#if SHOPT_BGX
#define ATTRS 1
"j"
#endif
#endif
#if SHOPT_ACCT
"L"
#endif
#if SHOPT_MULTIBYTE
"M"
#endif
#if SHOPT_PFSH && _hdr_exec_attr
"P"
#endif
#if SHOPT_REGRESS
"R"
#endif
#if ATTRS
" "
#endif
SH_RELEASE " $\0\n";
#if SHOPT_BASH
#endif
#ifndef ARG_MAX
#endif
#ifndef CHILD_MAX
#endif
#ifndef CLK_TCK
#endif /* CLK_TCK */
#ifndef environ
extern char **environ;
#endif
struct seconds
{
};
struct rand
{
};
struct ifs
{
};
struct match
{
const char *v;
char *val;
int vsize;
int nmatch;
int index;
};
typedef struct _init_
{
#if SHOPT_FS_3D
#endif /* SHOPT_FS_3D */
#if SHOPT_COSHELL
#endif /* SHOPT_COSHELL */
#ifdef _hdr_locale
#endif /* _hdr_locale */
} Init_t;
static int lctype;
static int nbltins;
static int shlvl;
#ifdef _WINIX
#else
# define EXE
#endif
static int rand_shift;
/*
* Invalidate all path name bindings
*/
{
}
/*
* out of memory routine for stak routines
*/
{
return(NIL(char*));
}
/* Trap for VISUAL and EDITOR variables */
{
register int newopt=0;
goto done;
goto done;
/* turn on vi or emacs option if editor name is either*/
if(newopt)
{
}
done:
}
/* Trap for HISTFILE and HISTSIZE variables */
{
char *cp;
{
return;
return;
}
if(histopen)
{
if(val)
else
}
}
/* Trap for OPTINDEX */
{
if(!val)
}
{
}
{
return(dp);
}
/* Trap for restricted variables FPATH, PATH, SHELL, ENV */
{
{
if(path_scoped && !val)
}
return;
{
else
return;
{
}
#if 0
#endif
}
}
{
if(!shp->cdpathlist)
return;
}
#ifdef _hdr_locale
/*
* This function needs to be modified to handle international
* error message translations
*/
#if ERROR_VERSION >= 20000101L
{
return((char*)message);
}
#else
{
return((char*)message);
}
#endif
/* Trap for LC_ALL, LC_CTYPE, LC_MESSAGES, LC_COLLATE and LANG */
{
int type;
type = LC_MESSAGES;
type = LC_COLLATE;
type = LC_NUMERIC;
#ifdef LC_LANG
#else
#endif
else
type= -1;
{
char* r;
#ifdef AST_LC_setenv
#endif
#ifdef AST_LC_setenv
#endif
if(!r && val)
{
return;
}
}
{
lctype++;
{
register int c;
for(c=0; c<(1<<CHAR_BIT); c++)
{
continue;
continue;
if(isblank(c))
{
state[0][c]=0;
continue;
}
if(!isalpha(c))
continue;
state[1][c]=0;
state[3][c]=0;
}
}
else
{
}
}
#if ERROR_VERSION < 20000101L
#endif
}
#endif /* _hdr_locale */
/* Trap for IFS assignment and invalidates state table */
{
if(!val)
{
{
fp = 0;
}
}
if(!val)
{
if(fp)
}
}
/*
* This is the lookup function for IFS
* It keeps the sh.ifstable up to date
*/
{
register int c,n;
{
{
#if SHOPT_MULTIBYTE
#else
while(c= *(unsigned char*)cp++)
#endif /* SHOPT_MULTIBYTE */
{
#if SHOPT_MULTIBYTE
cp++;
if(n>1)
{
cp += (n-1);
continue;
}
#endif /* SHOPT_MULTIBYTE */
n = S_DELIM;
if(c== *cp)
cp++;
else if(c=='\n')
n = S_NL;
else if(isspace(c))
n = S_SPACE;
}
}
else
{
}
}
return(value);
}
/*
* these functions are used to get and set the SECONDS variable
*/
#ifdef timeofday
#else
# define timeofday(a)
#endif
{
double d;
if(!val)
{
return;
}
{
}
}
{
}
{
}
/*
* These three functions are used to get and set the RANDOM variable
*/
{
register long n;
if(!val)
{
return;
}
if(flags&NV_INTEGER)
n = *(double*)val;
else
}
/*
* get random number in range of 0 - 2**15
* never pick same number twice in a row
*/
{
do
return((Sfdouble_t)cur);
}
{
return(fmtbase(n, 10, 0));
}
/*
* These three routines are for LINENO
*/
{
double d=1;
if(error_info.line >0)
d = error_info.line;
return(d);
}
{
register long n;
if(!val)
{
return;
}
if(flags&NV_INTEGER)
n = *(double*)val;
else
}
{
return(fmtbase(n, 10, 0));
}
{
char *cp;
int pid;
}
{
if(flags&NV_INTEGER)
{
}
if(val)
else
}
{
return(fp!=0);
}
/*
* store the most recent value for use in .sh.match
* treat .sh.match as a two dimensional array
*/
{
#ifndef SHOPT_2DMATCH
index = 0;
#else
if(index==0)
#endif /* SHOPT_2DMATCH */
{
{
}
if(ap)
{
i = array_elem(ap);
while(--i>= 0)
{
nv_putsub(SH_MATCHNOD, (char*)0,i);
}
}
if(nmatch)
mp->v = v;
}
#ifdef SHOPT_2DMATCH
else
{
if(index==1)
{
SH_MATCHNOD->nvfun = 0;
{
nv_putsub(SH_MATCHNOD, (char*)0, i);
}
}
}
#endif /* SHOPT_2DMATCH */
{
{
}
{
else
}
for(x=0,i=0; i < 2*nmatch; i++)
{
if(match[i]>=0)
else
x=1;
}
}
}
{
char *val;
if(np!=SH_MATCHNOD)
return(0);
if(sub2>0)
if(n<=0)
return(val);
{
}
}
{
}
{
register int c;
Sflong_t t = 0;
while (c = *cp++)
if (c >= '0' && c <= '9')
{
t *= 10;
t += c - '0';
}
return((Sfdouble_t)t);
}
#if SHOPT_FS_3D
/*
* set or unset the mappings given a colon separated list of directories
*/
{
return;
while(newp)
{
*newp++ = 0;
*lastp = 0;
}
}
/* catch vpath assignments */
{
register char *cp;
if(val)
}
#endif /* SHOPT_FS_3D */
static const Namdisc_t OPTINDEX_disc = { sizeof(Namfun_t), put_optindex, 0, nget_optindex, 0, 0, clone_optindex };
static const Namdisc_t SECONDS_disc = { sizeof(struct seconds), put_seconds, get_seconds, nget_seconds };
{
}
{
0,0,0,0,0,0,0,
};
{
};
{
char *name;
int i;
for(i=0; i < MAX_MATH_ARGS; i++)
{
name+=5;
}
}
{
if(!name)
return(SH_MATHNOD);
if(name[0]!='a' || name[1]!='r' || name[2]!='g' || name[4] || !isdigit(name[3]) || (name[3]=='0' || (name[3]-'0')>MAX_MATH_ARGS))
return(0);
}
{
char *val;
int first=0;
{
break;
if(first++)
}
return(val);
}
{
char *name;
if(!event)
{
if(!action)
{
}
getname = 1;
}
stakputc('.');
stakputc(0);
if(getname)
}
#if SHOPT_COSHELL
#endif /* SHOPT_COSHELL */
#if SHOPT_NAMESPACE
{
}
#endif /* SHOPT_NAMESPACE */
#ifdef _hdr_locale
#endif /* _hdr_locale */
/*
* This function will get called whenever a configuration parameter changes
*/
{
register char *arg;
if(!name)
{
/* set directory in new universe */
/* clear out old tracked alias */
stakseek(0);
stakputc(0);
}
return(1);
}
static void a2e(char *d, const char *s)
{
register const unsigned char *t;
register int i;
for(i=0; i<(1<<CHAR_BIT); i++)
d[t[i]] = s[i];
}
static void init_ebcdic(void)
{
int i;
for(i=0; i < ST_NONE; i++)
{
sh_lexstates[i] = cp;
}
}
#endif
/*
* return SH_TYPE_* bitmask for path
* 0 for "not a shell"
*/
{
register const char* s;
register int t = 0;
{
if (*path == '-')
t |= SH_TYPE_LOGIN;
s++;
}
else
s = path;
if (*s == '-')
{
s++;
t |= SH_TYPE_LOGIN;
}
for (;;)
{
if (!(t & (SH_TYPE_KSH|SH_TYPE_BASH)))
{
if (*s == 'k')
{
s++;
t |= SH_TYPE_KSH;
continue;
}
#if SHOPT_BASH
if (*s == 'b' && *(s+1) == 'a')
{
s += 2;
t |= SH_TYPE_BASH;
continue;
}
#endif
}
if (!(t & (SH_TYPE_PROFILE|SH_TYPE_RESTRICTED)))
{
#if SHOPT_PFSH
if (*s == 'p' && *(s+1) == 'f')
{
s += 2;
t |= SH_TYPE_PROFILE;
continue;
}
#endif
if (*s == 'r')
{
s++;
t |= SH_TYPE_RESTRICTED;
continue;
}
}
break;
}
if (*s++ == 's' && (*s == 'h' || *s == 'u'))
{
s++;
t |= SH_TYPE_SH;
s += 2;
#if _WINIX
if (*s == '.' && *(s+1) == 'e' && *(s+2) == 'x' && *(s+3) == 'e')
s += 4;
#endif
if (!isalnum(*s))
return t;
}
}
{
}
{
if(val)
{
char *last=0;
if(flag&NV_INTEGER)
{
else
}
else
if(*last)
}
else
}
{
0,
};
/*
* initialize the shell
*/
{
static int beenhere;
register int n;
int type;
memfatal();
e_version[n-2]=0;
#else
init_ebcdic();
#endif
if(!beenhere)
{
beenhere = 1;
#if SHOPT_FS_3D
#endif /* SHOPT_FS_3D */
}
else
#if ERROR_VERSION >= 20000102L
#endif
#if SHOPT_REGRESS
{
char* a;
regress[0] = "__regress__";
regress[2] = 0;
/* NOTE: only shp is used by __regress__ at this point */
{
if (a[1] == 'I')
{
if (a[2])
break;
}
break;
else if (a[9] == '=')
break;
}
}
#endif
for(n=0;n < 10; n++)
{
/* don't use lower bits when rand() generates large numbers */
{
rand_shift = 3;
break;
}
}
/* initialize signal handling */
/* set up memory for name-value pairs */
/* read the environment */
if(argc>0)
{
if(type&SH_TYPE_LOGIN)
}
{
}
#if SHOPT_SPAWN
{
/*
* try to find the pathname for this interpreter
* try using environment variable _ or argv[0]
*/
#if _AST_VERSION >= 20090202L
#else
{
buff[n] = 0;
}
#endif
{
if(*cp=='/')
{
stakputc('/');
}
}
}
#endif
#if SHOPT_FS_3D
#endif /* SHOPT_FS_3D */
#if SHOPT_TIMEOUT
#endif /* SHOPT_TIMEOUT */
/* initialize jobs table */
job_clear();
if(argc>0)
{
/* check for restricted shell */
#if SHOPT_PFSH
/* check for profile shell */
else if(type&SH_TYPE_PROFILE)
#endif
#if SHOPT_BASH
/* check for invocation as bash */
if(type&SH_TYPE_BASH)
{
}
#endif
/* look for options */
/* shp->st.dolc is $# */
{
}
if(!sh_isoption(SH_SFLAG))
{
#if _WINIX
{
char* name;
{
#if _lib_pathposix
char* p;
{
name = p;
}
else
#endif
{
}
}
}
#endif /* _WINIX */
}
if(beenhere==1)
{
beenhere = 2;
}
}
#if SHOPT_PFSH
if (sh_isoption(SH_PFSH))
{
if(pw)
}
#endif
/* set[ug]id scripts require the -p flag */
{
#ifdef SHOPT_P_SUID
{
}
else
#endif /* SHOPT_P_SUID */
#ifdef SHELLMAGIC
/* careful of #! setuid scripts with name beginning with - */
#endif /*SHELLMAGIC*/
}
else
/* shname for $0 in profiles and . scripts */
else
/*
* return here for shell script execution
* but not for parenthesis subshells
*/
login_files[0] = (char*)e_profile;
#if _AST_VERSION >= 20080617L
#endif
#if 0
NV_MKINTTYPE(size_t,(const char*)0,0);
NV_MKINTTYPE(ssize_t,(const char*)0,0);
nv_mkstat();
#endif
return(shp);
}
{
return(&sh);
}
/*
* reinitialize before executing a script
*/
{
struct adata
{
} data;
{
continue;
continue;
continue;
}
shp->inuse_bits = 0;
{
}
/* remove locals */
#if SHOPT_NAMESPACE
{
}
#endif /* SHOPT_NAMESPACE */
if(sh_isoption(SH_TRACKALL))
if(sh_isoption(SH_EMACS))
if(sh_isoption(SH_GMACS))
if(sh_isoption(SH_VI))
if(sh_isoption(SH_VIRAW))
/* set up new args */
if(argv)
sh_sigreset(0);
{
shlvl = 0;
}
job_clear();
job.in_critical = 0;
return(1);
}
/*
* set when creating a local variable of this name
*/
{
if(np==IFSNOD || np==PATHNOD || np==SHELLNOD || np==FPATHNOD || np==CDPNOD || np==SECONDS || np==ENVNOD || np==LINENO)
#ifdef _hdr_locale
#endif
return(0);
}
#ifdef SHOPT_STATS
struct Stats
{
char *nodes;
int numnodes;
int current;
};
{
if(!root)
return(0);
}
{
register int i=0,n;
if(!name)
return(SH_STATS);
{
goto found;
}
nq = 0;
if(nq)
{
}
else
return(nq);
}
{
0, 0, 0, 0, 0,
0, 0,
};
{
}
{
0,0,0,0,0,0,0,
};
{
};
{
for(i=0; i < nstat; i++)
{
}
}
#else
# define stat_init(x)
#endif /* SHOPT_STATS */
/*
* Initialize the shell name and alias table
*/
{
double d=0;
if(!ip)
return(0);
#if SHOPT_COSHELL
#endif /* SHOPT_COSHELL */
#ifdef _hdr_locale
#endif /* _hdr_locale */
#ifdef _hdr_locale
#endif /* _hdr_locale */
/* set up the seconds clock */
return(ip);
}
/*
* initialize name-value pairs
*/
{
register unsigned n = 0;
n++;
if(!shgd->bltin_nodes)
{
shgd->bltin_nnodes = n;
}
{
nbltins = n;
}
{
else
{
treep = base_treep;
}
else
{
if(name_vals == shtab_variables)
}
else
nv_setsize(np,0);
if(nv_istable(np))
}
return(treep);
}
/*
* read in the process environment and set up name-value pairs
* skip over items that are not name-value pairs
*/
{
register char *cp;
#ifdef _ENV_H
#endif
if(!ep)
goto skip;
while(*ep++)
nenv++;
{
if(!dp)
continue;
*dp++ = 0;
{
}
{
continue;
}
else
{
k++;
}
else
{
}
}
while(k-->0)
{
}
{
*next = 0;
{
{
/* check for floating*/
{
char *lp;
if(*dp=='.')
{
if(*lp)
}
{
flag |= NV_EXPNOTE;
}
else
size--;
}
}
}
else
cp += 2;
}
skip:
#ifdef _ENV_H
#endif
{
}
return;
}
/*
* terminate shell and free up the space
*/
int sh_term(void)
{
return(0);
}
/* function versions of these */
{
return(sh_isoption(opt));
}
{
return(sh_onoption(opt));
}
{
return(sh_offoption(opt));
}
{
if(!shp)
shp = sh_getinterp();
}
{
return(sh.bltin_tree);
}
/*
* This code is for character mapped variables with wctrans()
*/
struct Mapchar
{
const char *name;
int lctype;
};
{
if(val)
{
{
}
goto skip;
{
off += c;
}
stakputc(0);
}
else
{
return;
}
skip:
}
{
int n=0,low;
if(np)
if(!name)
if(!trans)
return(0);
if(!np)
return(((Namfun_t*)0)+1);
if(mp)
{
}
if(low==0)
else if(n==0)
else
{
}
}