コード例 #1
0
ファイル: enum.c プロジェクト: att/ast
static_fn void put_enum(Namval_t *np, const void *val, nvflag_t flags, Namfun_t *fp) {
    struct Enum *ep = (struct Enum *)fp;
    const char *v;
    int n;
    if (!val && !(flags & NV_INTEGER)) {
        nv_putv(np, val, flags, fp);
        nv_disc(np, &ep->namfun, DISC_OP_POP);
        if (!ep->namfun.nofree) free_enum(ep);
        return;
    }
    if (flags & NV_INTEGER) {
        nv_putv(np, val, flags, fp);
        return;
    }

    for (int i = 0; i < ep->nelem; i++) {
        v = ep->values[i];
        if (ep->iflag) {
            n = strcasecmp(v, val);
        } else {
            n = strcmp(v, val);
        }

        if (n == 0) {
            // TODO: Figure out if a static var is correct. The code used to store a pointer to the
            // stack local var `i` which is obviously wrong and only works by accident if the
            // pointer is used before the stack location is overwritten.
            static uint16_t x;
            x = i;
            nv_putv(np, (char *)&x, NV_UINT16, fp);
            return;
        }
    }
    if (nv_isattr(np, NV_NOFREE)) error(ERROR_exit(1), "%s:  invalid value %s", nv_name(np), val);
}
コード例 #2
0
ファイル: enum.c プロジェクト: nathanmkaya/ksh-arch
static void put_enum(Namval_t* np,const char *val,int flags,Namfun_t *fp)
{
	struct Enum 		*ep = (struct Enum*)fp;
	register const char	*v;
	unsigned short		i=0, n;
	if(!val && !(flags&NV_INTEGER))
	{
		nv_putv(np, val, flags,fp);
		nv_disc(np,&ep->hdr,NV_POP);
		if(!ep->hdr.nofree)
			free((void*)ep);
		return;
	}
	if(flags&NV_INTEGER)
	{
		nv_putv(np,val,flags,fp);
		return;
	}
	while(v=ep->values[i])
	{
		if(ep->iflag)
			n = strcasecmp(v,val);
		else
			n = strcmp(v,val);
		if(n==0)
		{
			nv_putv(np, (char*)&i, NV_UINT16, fp);
			return;
		}
		i++;
	}
	if(nv_isattr(np,NV_NOFREE))
		error(ERROR_exit(1), "%s:  invalid value %s",nv_name(np),val);
}
コード例 #3
0
ファイル: misc.c プロジェクト: apprisi/illumos-gate
int    b_dot_cmd(register int n,char *argv[],void* extra)
{
	register char *script;
	register Namval_t *np;
	register int jmpval;
	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
	struct sh_scoped savst, *prevscope = shp->st.self;
	char *filename=0;
	int	fd;
	struct dolnod   *argsave=0, *saveargfor;
	struct checkpt buff;
	Sfio_t *iop=0;
	short level;
	while (n = optget(argv,sh_optdot)) switch (n)
	{
	    case ':':
		errormsg(SH_DICT,2, "%s", opt_info.arg);
		break;
	    case '?':
		errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
		return(2);
	}
	argv += opt_info.index;
	script = *argv;
	if(error_info.errors || !script)
		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
	if(shp->dot_depth+1 > DOTMAX)
		errormsg(SH_DICT,ERROR_exit(1),e_toodeep,script);
	if(!(np=shp->posix_fun))
	{
		/* check for KornShell style function first */
		np = nv_search(script,shp->fun_tree,0);
		if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX))
		{
			if(!np->nvalue.ip)
			{
				path_search(script,NIL(Pathcomp_t**),0);
				if(np->nvalue.ip)
				{
					if(nv_isattr(np,NV_FPOSIX))
						np = 0;
				}
				else
					errormsg(SH_DICT,ERROR_exit(1),e_found,script);
			}
		}
コード例 #4
0
ファイル: enum.c プロジェクト: nathanmkaya/ksh-arch
void lib_init(int flag, void* context)
{
	Shell_t		*shp = ((Shbltin_t*)context)->shp;
	Namval_t	*mp,*bp;
	if(flag)
		return;
	bp = sh_addbuiltin(shp,"Enum", enum_create, (void*)0); 
	mp = nv_search("typeset",shp->bltin_tree,0);
	nv_onattr(bp,nv_isattr(mp,NV_PUBLIC));
}
コード例 #5
0
ファイル: open.c プロジェクト: ISLEcode/kornshell
static void put_classval(Namval_t* np, const char* val, int flag, Namfun_t* nfp)
{
	walk_class(np,1,(struct dcclass *)nfp);
	if(nfp = nv_stack(np,(Namfun_t*)0))
	{
		free((void*)nfp);
		if(np->nvalue && !nv_isattr(np,NV_NOFREE))
			free((void*)np->nvalue);
	}
	if(val)
		nv_putval(np,val,flag);
}
コード例 #6
0
ファイル: enum.c プロジェクト: att/ast
static_fn char *get_enum(Namval_t *np, Namfun_t *fp) {
    if (nv_isattr(np, NV_NOTSET) == NV_NOTSET) return "";

    struct Enum *ep = (struct Enum *)fp;
    long n = nv_getn(np, fp);
    assert(n >= 0);
    if (n < ep->nelem) return (char *)ep->values[n];

    static char buff[6];
    sfsprintf(buff, sizeof(buff), "%u%c", n, 0);
    return buff;
}
コード例 #7
0
ファイル: enum.c プロジェクト: nathanmkaya/ksh-arch
static char* get_enum(register Namval_t* np, Namfun_t *fp)
{
	static char buff[6];
	struct Enum *ep = (struct Enum*)fp;
	long n = nv_getn(np,fp);
	if(nv_isattr(np,NV_NOTSET)==NV_NOTSET)
		return("");
	if(n < ep->nelem)
		return((char*)ep->values[n]);
	sfsprintf(buff,sizeof(buff),"%u%c",n,0);
	return(buff);
}
コード例 #8
0
ファイル: whence.c プロジェクト: ISLEcode/kornshell
static int whence(Shell_t *shp,char **argv, register int flags)
{
	register const char *name;
	register Namval_t *np;
	register const char *cp;
	register int aflag,r=0;
	register const char *msg;
	int	tofree;
	Dt_t *root;
	Namval_t *nq;
	char *notused;
	Pathcomp_t *pp=0;
	int notrack = 1;
	if(flags&Q_FLAG)
		flags &= ~A_FLAG;
	while(name= *argv++)
	{
		tofree=0;
		aflag = ((flags&A_FLAG)!=0);
		cp = 0;
		np = 0;
		if(flags&P_FLAG)
			goto search;
		if(flags&Q_FLAG)
			goto bltins;
		/* reserved words first */
		if(sh_lookup(name,shtab_reserved))
		{
			sfprintf(sfstdout,"%s%s\n",name,(flags&V_FLAG)?sh_translate(is_reserved):"");
			if(!aflag)
				continue;
			aflag++;
		}
		/* non-tracked aliases */
		if((np=nv_search(name,shp->alias_tree,0))
			&& !nv_isnull(np) && !(notrack=nv_isattr(np,NV_TAGGED))
			&& (cp=nv_getval(np))) 
		{
			if(flags&V_FLAG)
			{
				if(nv_isattr(np,NV_EXPORT))
					msg = sh_translate(is_xalias);
				else
					msg = sh_translate(is_alias);
				sfprintf(sfstdout,msg,name);
			}
			sfputr(sfstdout,sh_fmtq(cp),'\n');
			if(!aflag)
				continue;
			cp = 0;
			aflag++;
		}
		/* built-ins and functions next */
	bltins:
		root = (flags&F_FLAG)?shp->bltin_tree:shp->fun_tree;
		if(np= nv_bfsearch(name, root, &nq, &notused))
		{
			if(is_abuiltin(np) && nv_isnull(np))
				goto search;
			cp = "";
			if(flags&V_FLAG)
			{
				if(nv_isnull(np))
					cp = sh_translate(is_ufunction);
				else if(is_abuiltin(np))
				{
					if(nv_isattr(np,BLT_SPC))
						cp = sh_translate(is_spcbuiltin);
					else
						cp = sh_translate(is_builtin);
				}
				else
					cp = sh_translate(is_function);
			}
			if(flags&Q_FLAG)
				continue;
			sfprintf(sfstdout,"%s%s\n",name,cp);
			if(!aflag)
				continue;
			cp = 0;
			aflag++;
		}
	search:
		if(sh_isstate(SH_DEFPATH))
		{
			cp=0;
			notrack=1;
		}
		do
		{
			if(path_search(shp,name,&pp,2+(aflag>1)))
			{
				cp = name;
				if((flags&P_FLAG) && *cp!='/')
					cp = 0;
			}
			else
			{
				cp = stakptr(PATH_OFFSET);
				if(*cp==0)
					cp = 0;
				else if(*cp!='/')
				{
					cp = path_fullname(shp,cp);
					tofree=1;
				}
			}
			if(flags&Q_FLAG)
			{
				pp = 0;
				r |= !cp;
			}
			else if(cp)
			{
				if(flags&V_FLAG)
				{
					if(*cp!= '/')
					{
						if(!np && (np=nv_search(name,shp->track_tree,0)))
							sfprintf(sfstdout,"%s %s %s/%s\n",name,sh_translate(is_talias),path_pwd(shp,0),cp);
						else if(!np || nv_isnull(np))
							sfprintf(sfstdout,"%s%s\n",name,sh_translate(is_ufunction));
						continue;
					}
					sfputr(sfstdout,sh_fmtq(name),' ');
					/* built-in version of program */
					if(*cp=='/' && (np=nv_search(cp,shp->bltin_tree,0)))
						msg = sh_translate(is_builtver);
					/* tracked aliases next */
					else if(aflag>1 || !notrack || strchr(name,'/'))
						msg = sh_translate("is");
					else
						msg = sh_translate(is_talias);
					sfputr(sfstdout,msg,' ');
				}
				sfputr(sfstdout,sh_fmtq(cp),'\n');
				if(aflag)
				{
					if(aflag<=1)
						aflag++;
					if (pp)
						pp = pp->next;
				}
				else
					pp = 0;
				if(tofree)
				{
					free((char*)cp);
					tofree = 0;
				}
			}
			else if(aflag<=1) 
			{
				r |= 1;
				if(flags&V_FLAG)
					 errormsg(SH_DICT,ERROR_exit(0),e_found,sh_fmtq(name));
			}
		} while(pp);
	}
	return(r);
}
コード例 #9
0
ファイル: open.c プロジェクト: ISLEcode/kornshell
static void genvalue(Sfio_t *out, Shclass_t *sp, int indent, Namval_t *npar)
{
	Shfield_t *fp = sp->fields;
	Namval_t *np, **nodes= (Namval_t**)(sp+1);
	register int i,isarray;
	if(out)
	{
		sfwrite(out,"(\n",2);
		indent++;
	}
	for(i=0; i < sp->nelem; i++,fp++)
	{
#if 0
		/* handle recursive case */
#endif
		if(!(np=nodes[i]) && out)
			np = sh_newnode(fp,npar);
		if(np)
		{
			isarray=0;
			if(nv_isattr(np,NV_ARRAY))
			{
				isarray=1;
				if(array_elem(nv_arrayptr(np))==0)
					isarray=2;
				else
					nv_putsub(np,(char*)0,ARRAY_SCAN);
			}
			sfnputc(out,'\t',indent);
			sfputr(out,fp->name,(isarray==2?'\n':'='));
			if(isarray)
			{
				if(isarray==2)
					continue;
				sfwrite(out,"(\n",2);
				sfnputc(out,'\t',++indent);
			}
			while(1)
			{
				char *fmtq;
				if(isarray)
				{
					sfprintf(out,"[%s]",sh_fmtq(nv_getsub(np)));
					sfputc(out,'=');
				}
				if(!(fmtq=nv_getval(np)) || !(fmtq=sh_fmtq(fmtq)))
					fmtq = "";
				sfputr(out,fmtq,'\n');
				if(!nv_nextsub(np))
					break;
				sfnputc(out,'\t',indent);
			}
			if(isarray)
			{
				sfnputc(out,'\t',--indent);
				sfwrite(out,")\n",2);
			}
		}
	}
	if(out)
	{
		if(indent>1)
			sfnputc(out,'\t',indent-1);
		sfputc(out,')');
	}
}
コード例 #10
0
ファイル: test.c プロジェクト: ISLEcode/kornshell
int test_unop(Shell_t *shp,register int op,register const char *arg)
{
	struct stat statb;
	int f;
	switch(op)
	{
	    case 'r':
		return(permission(arg, R_OK));
	    case 'w':
		return(permission(arg, W_OK));
	    case 'x':
		return(permission(arg, X_OK));
	    case 'V':
#if SHOPT_FS_3D
	    {
		register int offset = staktell();
		if(stat(arg,&statb)<0 || !S_ISREG(statb.st_mode))
			return(0);
		/* add trailing / */
		stakputs(arg);
		stakputc('/');
		stakputc(0);
		arg = (const char*)stakptr(offset);
		stakseek(offset);
		/* FALL THRU */
	    }
#else
		return(0);
#endif /* SHOPT_FS_3D */
	    case 'd':
		return(test_stat(arg,&statb)>=0 && S_ISDIR(statb.st_mode));
	    case 'c':
		return(test_stat(arg,&statb)>=0 && S_ISCHR(statb.st_mode));
	    case 'b':
		return(test_stat(arg,&statb)>=0 && S_ISBLK(statb.st_mode));
	    case 'f':
		return(test_stat(arg,&statb)>=0 && S_ISREG(statb.st_mode));
	    case 'u':
		return(test_mode(arg)&S_ISUID);
	    case 'g':
		return(test_mode(arg)&S_ISGID);
	    case 'k':
#ifdef S_ISVTX
		return(test_mode(arg)&S_ISVTX);
#else
		return(0);
#endif /* S_ISVTX */
#if SHOPT_TEST_L
	    case 'l':
#endif
	    case 'L':
	    case 'h': /* undocumented, and hopefully will disappear */
		if(*arg==0 || arg[strlen(arg)-1]=='/' || lstat(arg,&statb)<0)
			return(0);
		return(S_ISLNK(statb.st_mode));

	    case 'C':
#ifdef S_ISCTG
		return(test_stat(arg,&statb)>=0 && S_ISCTG(statb.st_mode));
#else
		return(0);
#endif	/* S_ISCTG */
	    case 'H':
#ifdef S_ISCDF
	    {
		register int offset = staktell();
		if(test_stat(arg,&statb)>=0 && S_ISCDF(statb.st_mode))
			return(1);
		stakputs(arg);
		stakputc('+');
		stakputc(0);
		arg = (const char*)stakptr(offset);
		stakseek(offset);
		return(test_stat(arg,&statb)>=0 && S_ISCDF(statb.st_mode));
	    }
#else
		return(0);
#endif	/* S_ISCDF */

	    case 'S':
		return(isasock(arg,&statb));
	    case 'N':
		return(test_stat(arg,&statb)>=0 && tmxgetmtime(&statb) > tmxgetatime(&statb));
	    case 'p':
		return(isapipe(arg,&statb));
	    case 'n':
		return(*arg != 0);
	    case 'z':
		return(*arg == 0);
	    case 's':
		sfsync(sfstdout);
	    case 'O':
	    case 'G':
		if(*arg==0 || test_stat(arg,&statb)<0)
			return(0);
		if(op=='s')
			return(statb.st_size>0);
		else if(op=='O')
			return(statb.st_uid==shp->gd->userid);
		return(statb.st_gid==shp->gd->groupid);
	    case 'a':
	    case 'e':
		if(memcmp(arg,"/dev/",5)==0 && sh_open(arg,O_NONBLOCK))
			return(1);
		return(permission(arg, F_OK));
	    case 'o':
		f=1;
		if(*arg=='?')
			return(sh_lookopt(arg+1,&f)>0);
		op = sh_lookopt(arg,&f);
		return(op && (f==(sh_isoption(op)!=0)));
	    case 't':
	    {
		char *last;
		op = strtol(arg,&last, 10);
		return(*last?0:tty_check(op));
	    }
	    case 'v':
	    case 'R':
	    {
		Namval_t *np;
		Namarr_t *ap;
		int isref;
		if(!(np = nv_open(arg,shp->var_tree,NV_VARNAME|NV_NOFAIL|NV_NOADD|NV_NOREF)))
			return(0);
		isref = nv_isref(np);
		if(op=='R')
			return(isref);
		if(isref)
		{
			if(np->nvalue.cp)
				np = nv_refnode(np);
			else
				return(0);
			
		}
		if(ap = nv_arrayptr(np))
			return(nv_arrayisset(np,ap));
		return(!nv_isnull(np) || nv_isattr(np,NV_INTEGER));
	    }
	    default:
	    {
		static char a[3] = "-?";
		a[1]= op;
		errormsg(SH_DICT,ERROR_exit(2),e_badop,a);
		/* NOTREACHED  */
		return(0);
	    }
	}
}
コード例 #11
0
ファイル: misc.c プロジェクト: att/ast
int b_dot_cmd(int n, char *argv[], Shbltin_t *context) {
    char *script;
    Namval_t *np;
    int jmpval;
    Shell_t *shp = context->shp;
    struct sh_scoped savst, *prevscope = shp->st.self;
    int fd;
    char *filename = NULL;
    char *buffer = NULL;
    struct dolnod *saveargfor = NULL;
    volatile struct dolnod *argsave = NULL;
    checkpt_t buff;
    Sfio_t *iop = NULL;
    short level;
    Optdisc_t disc;

    memset(&disc, 0, sizeof(disc));
    disc.version = OPT_VERSION;
    opt_info.disc = &disc;

    while ((n = optget(argv, sh_optdot))) {
        switch (n) {
            case ':': {
                errormsg(SH_DICT, 2, "%s", opt_info.arg);
                break;
            }
            case '?': {
                errormsg(SH_DICT, ERROR_usage(0), "%s", opt_info.arg);
                return 2;
            }
            default: { break; }
        }
    }

    argv += opt_info.index;
    script = *argv;
    if (error_info.errors || !script) {
        errormsg(SH_DICT, ERROR_usage(2), "%s", optusage(NULL));
        __builtin_unreachable();
    }
    if (shp->dot_depth + 1 > DOTMAX) {
        errormsg(SH_DICT, ERROR_exit(1), e_toodeep, script);
        __builtin_unreachable();
    }
    np = shp->posix_fun;
    if (!np) {
        // Check for KornShell style function first.
        np = nv_search(script, shp->fun_tree, 0);
        if (np && is_afunction(np) && !nv_isattr(np, NV_FPOSIX)) {
            if (!FETCH_VT(np->nvalue, ip)) {
                // TODO: Replace this with a comment explaining why the return value of this
                // path_search() call is ignored. At the time I wrote this (2019-03-16) no unit test
                // exercises this statement. I added the void cast to silence Coverity Scan 253792.
                (void)path_search(shp, script, NULL, 0);
                if (FETCH_VT(np->nvalue, ip)) {
                    if (nv_isattr(np, NV_FPOSIX)) np = NULL;
                } else {
                    errormsg(SH_DICT, ERROR_exit(1), e_found, script);
                    __builtin_unreachable();
                }
            }
        } else {
            np = NULL;
        }

        if (!np) {
            fd = path_open(shp, script, path_get(shp, script));
            if (fd < 0) {
                errormsg(SH_DICT, ERROR_system(1), e_open, script);
                __builtin_unreachable();
            }
            filename = path_fullname(shp, stkptr(shp->stk, PATH_OFFSET));
        }
    }
    *prevscope = shp->st;
    shp->st.lineno = np ? ((struct functnod *)nv_funtree(np))->functline : 1;
    shp->st.var_local = shp->st.save_tree = shp->var_tree;
    if (filename) {
        shp->st.filename = filename;
        shp->st.lineno = 1;
    }
    level = shp->fn_depth + shp->dot_depth + 1;
    nv_putval(SH_LEVELNOD, (char *)&level, NV_INT16);
    shp->st.prevst = prevscope;
    shp->st.self = &savst;
    shp->topscope = (Shscope_t *)shp->st.self;
    prevscope->save_tree = shp->var_tree;
    if (np) {
        struct Ufunction *rp = FETCH_VT(np->nvalue, rp);
        shp->st.filename = strdup(rp->fname ? rp->fname : "");
    }
    nv_putval(SH_PATHNAMENOD, shp->st.filename, NV_NOFREE);
    shp->posix_fun = NULL;
    if (np || argv[1]) argsave = sh_argnew(shp, argv, &saveargfor);
    sh_pushcontext(shp, &buff, SH_JMPDOT);
    jmpval = sigsetjmp(buff.buff, 0);
    if (jmpval == 0) {
        shp->dot_depth++;
        if (np) {
            sh_exec(shp, (Shnode_t *)(nv_funtree(np)), sh_isstate(shp, SH_ERREXIT));
        } else {
            buffer = malloc(IOBSIZE + 1);
            iop = sfnew(NULL, buffer, IOBSIZE, fd, SF_READ);
            sh_offstate(shp, SH_NOFORK);
            sh_eval(shp, iop, sh_isstate(shp, SH_PROFILE) ? SH_FUNEVAL : 0);
        }
    }
    sh_popcontext(shp, &buff);
    if (buffer) free(buffer);
    if (!np) {
        free(shp->st.filename);
        shp->st.filename = NULL;
    }
    shp->dot_depth--;
    if ((np || argv[1]) && jmpval != SH_JMPSCRIPT) {
        sh_argreset(shp, (struct dolnod *)argsave, saveargfor);
    } else {
        prevscope->dolc = shp->st.dolc;
        prevscope->dolv = shp->st.dolv;
    }
    if (shp->st.self != &savst) *shp->st.self = shp->st;
    // Only restore the top Shscope_t portion for posix functions.
    memcpy(&shp->st, prevscope, sizeof(Shscope_t));
    shp->topscope = (Shscope_t *)prevscope;
    nv_putval(SH_PATHNAMENOD, shp->st.filename, NV_NOFREE);
    if (jmpval && jmpval != SH_JMPFUN) siglongjmp(shp->jmplist->buff, jmpval);
    return shp->exitval;
}