📄 doarg.c
字号:
if (*relem) str_sset(str,*relem); *(relem++) = str; (void)astore(ary,i++,str); } } else if (str->str_state == SS_HASH) { char *tmps; STR *tmpstr; int magic = 0; STAB *tmpstab = str->str_u.str_stab; if (makelocal) hash = savehash(str->str_u.str_stab); else { hash = stab_hash(str->str_u.str_stab); if (tmpstab == envstab) { magic = 'E'; environ[0] = Nullch; } else if (tmpstab == sigstab) { magic = 'S';#ifndef NSIG#define NSIG 32#endif for (i = 1; i < NSIG; i++) signal(i, SIG_DFL); /* crunch, crunch, crunch */ }#ifdef SOME_DBM else if (hash->tbl_dbm) magic = 'D';#endif hclear(hash, magic == 'D'); /* wipe any dbm file too */ } while (relem < lastrelem) { /* gobble up all the rest */ if (*relem) str = *(relem++); else str = &str_no, relem++; tmps = str_get(str); tmpstr = Str_new(29,0); if (*relem) str_sset(tmpstr,*relem); /* value */ *(relem++) = tmpstr; (void)hstore(hash,tmps,str->str_cur,tmpstr,0); if (magic) { str_magic(tmpstr, tmpstab, magic, tmps, str->str_cur); stabset(tmpstr->str_magic, tmpstr); } } } else fatal("panic: do_assign"); } else { if (makelocal) saveitem(str); if (relem <= lastrelem) { str_sset(str, *relem); *(relem++) = str; } else { str_sset(str, &str_undef); if (gimme == G_ARRAY) { i = ++lastrelem - firstrelem; relem++; /* tacky, I suppose */ astore(stack,i,str); if (st != stack->ary_array) { st = stack->ary_array; firstrelem = st + arglast[1] + 1; firstlelem = st + arglast[0] + 1; lastlelem = st + arglast[1]; lastrelem = st + i; relem = lastrelem + 1; } } } STABSET(str); } } if (delaymagic & ~DM_DELAY) { if (delaymagic & DM_UID) {#ifdef HAS_SETREUID (void)setreuid(uid,euid);#else /* not HAS_SETREUID */#ifdef HAS_SETRUID if ((delaymagic & DM_UID) == DM_RUID) { (void)setruid(uid); delaymagic =~ DM_RUID; }#endif /* HAS_SETRUID */#ifdef HAS_SETEUID if ((delaymagic & DM_UID) == DM_EUID) { (void)seteuid(uid); delaymagic =~ DM_EUID; }#endif /* HAS_SETEUID */ if (delaymagic & DM_UID) { if (uid != euid) fatal("No setreuid available"); (void)setuid(uid); }#endif /* not HAS_SETREUID */ uid = (int)getuid(); euid = (int)geteuid(); } if (delaymagic & DM_GID) {#ifdef HAS_SETREGID (void)setregid(gid,egid);#else /* not HAS_SETREGID */#ifdef HAS_SETRGID if ((delaymagic & DM_GID) == DM_RGID) { (void)setrgid(gid); delaymagic =~ DM_RGID; }#endif /* HAS_SETRGID */#ifdef HAS_SETEGID if ((delaymagic & DM_GID) == DM_EGID) { (void)setegid(gid); delaymagic =~ DM_EGID; }#endif /* HAS_SETEGID */ if (delaymagic & DM_GID) { if (gid != egid) fatal("No setregid available"); (void)setgid(gid); }#endif /* not HAS_SETREGID */ gid = (int)getgid(); egid = (int)getegid(); } } delaymagic = 0; localizing = FALSE; if (gimme == G_ARRAY) { i = lastrelem - firstrelem + 1; if (ary || hash) Copy(firstrelem, firstlelem, i, STR*); return arglast[0] + i; } else { str_numset(arg->arg_ptr.arg_str,(double)(arglast[2] - arglast[1])); *firstlelem = arg->arg_ptr.arg_str; return arglast[0] + 1; }}int /*SUPPRESS 590*/do_study(str,arg,gimme,arglast)STR *str;ARG *arg;int gimme;int *arglast;{ register unsigned char *s; register int pos = str->str_cur; register int ch; register int *sfirst; register int *snext; static int maxscream = -1; static STR *lastscream = Nullstr; int retval; int retarg = arglast[0] + 1;#ifndef lint s = (unsigned char*)(str_get(str));#else s = Null(unsigned char*);#endif if (lastscream) lastscream->str_pok &= ~SP_STUDIED; lastscream = str; if (pos <= 0) { retval = 0; goto ret; } if (pos > maxscream) { if (maxscream < 0) { maxscream = pos + 80; New(301,screamfirst, 256, int); New(302,screamnext, maxscream, int); } else { maxscream = pos + pos / 4; Renew(screamnext, maxscream, int); } } sfirst = screamfirst; snext = screamnext; if (!sfirst || !snext) fatal("do_study: out of memory"); for (ch = 256; ch; --ch) *sfirst++ = -1; sfirst -= 256; while (--pos >= 0) { ch = s[pos]; if (sfirst[ch] >= 0) snext[pos] = sfirst[ch] - pos; else snext[pos] = -pos; sfirst[ch] = pos; /* If there were any case insensitive searches, we must assume they * all are. This speeds up insensitive searches much more than * it slows down sensitive ones. */ if (sawi) sfirst[fold[ch]] = pos; } str->str_pok |= SP_STUDIED; retval = 1; ret: str_numset(arg->arg_ptr.arg_str,(double)retval); stack->ary_array[retarg] = arg->arg_ptr.arg_str; return retarg;}int /*SUPPRESS 590*/do_defined(str,arg,gimme,arglast)STR *str;register ARG *arg;int gimme;int *arglast;{ register int type; register int retarg = arglast[0] + 1; int retval; ARRAY *ary; HASH *hash; if ((arg[1].arg_type & A_MASK) != A_LEXPR) fatal("Illegal argument to defined()"); arg = arg[1].arg_ptr.arg_arg; type = arg->arg_type; if (type == O_SUBR || type == O_DBSUBR) { if ((arg[1].arg_type & A_MASK) == A_WORD) retval = stab_sub(arg[1].arg_ptr.arg_stab) != 0; else { STR *tmpstr = STAB_STR(arg[1].arg_ptr.arg_stab); retval = tmpstr && stab_sub(stabent(str_get(tmpstr),TRUE)) != 0; } } else if (type == O_ARRAY || type == O_LARRAY || type == O_ASLICE || type == O_LASLICE ) retval = ((ary = stab_xarray(arg[1].arg_ptr.arg_stab)) != 0 && ary->ary_max >= 0 ); else if (type == O_HASH || type == O_LHASH || type == O_HSLICE || type == O_LHSLICE ) retval = ((hash = stab_xhash(arg[1].arg_ptr.arg_stab)) != 0 && hash->tbl_array); else retval = FALSE; str_numset(str,(double)retval); stack->ary_array[retarg] = str; return retarg;}int /*SUPPRESS 590*/do_undef(str,arg,gimme,arglast)STR *str;register ARG *arg;int gimme;int *arglast;{ register int type; register STAB *stab; int retarg = arglast[0] + 1; if ((arg[1].arg_type & A_MASK) != A_LEXPR) fatal("Illegal argument to undef()"); arg = arg[1].arg_ptr.arg_arg; type = arg->arg_type; if (type == O_ARRAY || type == O_LARRAY) { stab = arg[1].arg_ptr.arg_stab; afree(stab_xarray(stab)); stab_xarray(stab) = anew(stab); /* so "@array" still works */ } else if (type == O_HASH || type == O_LHASH) { stab = arg[1].arg_ptr.arg_stab; if (stab == envstab) environ[0] = Nullch; else if (stab == sigstab) { int i; for (i = 1; i < NSIG; i++) signal(i, SIG_DFL); /* munch, munch, munch */ } (void)hfree(stab_xhash(stab), TRUE); stab_xhash(stab) = Null(HASH*); } else if (type == O_SUBR || type == O_DBSUBR) { stab = arg[1].arg_ptr.arg_stab; if ((arg[1].arg_type & A_MASK) != A_WORD) { STR *tmpstr = STAB_STR(arg[1].arg_ptr.arg_stab); if (tmpstr) stab = stabent(str_get(tmpstr),TRUE); else stab = Nullstab; } if (stab && stab_sub(stab)) { cmd_free(stab_sub(stab)->cmd); stab_sub(stab)->cmd = Nullcmd; afree(stab_sub(stab)->tosave); Safefree(stab_sub(stab)); stab_sub(stab) = Null(SUBR*); } } else fatal("Can't undefine that kind of object"); str_numset(str,0.0); stack->ary_array[retarg] = str; return retarg;}intdo_vec(lvalue,astr,arglast)int lvalue;STR *astr;int *arglast;{ STR **st = stack->ary_array; int sp = arglast[0]; register STR *str = st[++sp]; register int offset = (int)str_gnum(st[++sp]); register int size = (int)str_gnum(st[++sp]); unsigned char *s = (unsigned char*)str_get(str); unsigned long retnum; int len; sp = arglast[1]; offset *= size; /* turn into bit offset */ len = (offset + size + 7) / 8; if (offset < 0 || size < 1) retnum = 0; else if (!lvalue && len > str->str_cur) retnum = 0; else { if (len > str->str_cur) { STR_GROW(str,len); (void)memzero(str->str_ptr + str->str_cur, len - str->str_cur); str->str_cur = len; } s = (unsigned char*)str_get(str); if (size < 8) retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1); else { offset >>= 3; if (size == 8) retnum = s[offset]; else if (size == 16) retnum = ((unsigned long) s[offset] << 8) + s[offset+1]; else if (size == 32) retnum = ((unsigned long) s[offset] << 24) + ((unsigned long) s[offset + 1] << 16) + (s[offset + 2] << 8) + s[offset+3]; } if (lvalue) { /* it's an lvalue! */ struct lstring *lstr = (struct lstring*)astr; astr->str_magic = str; st[sp]->str_rare = 'v'; lstr->lstr_offset = offset; lstr->lstr_len = size; } } str_numset(astr,(double)retnum); st[sp] = astr; return sp;}voiddo_vecset(mstr,str)STR *mstr;STR *str;{ struct lstring *lstr = (struct lstring*)str; register int offset; register int size; register unsigned char *s = (unsigned char*)mstr->str_ptr; register unsigned long lval = U_L(str_gnum(str)); int mask; mstr->str_rare = 0; str->str_magic = Nullstr; offset = lstr->lstr_offset; size = lstr->lstr_len; if (size < 8) { mask = (1 << size) - 1; size = offset & 7; lval &= mask; offset >>= 3; s[offset] &= ~(mask << size); s[offset] |= lval << size; } else { if (size == 8) s[offset] = lval & 255; else if (size == 16) { s[offset] = (lval >> 8) & 255; s[offset+1] = lval & 255; } else if (size == 32) { s[offset] = (lval >> 24) & 255; s[offset+1] = (lval >> 16) & 255; s[offset+2] = (lval >> 8) & 255; s[offset+3] = lval & 255; } }}voiddo_chop(astr,str)register STR *astr;register STR *str;{ register char *tmps; register int i; ARRAY *ary; HASH *hash; HENT *entry; if (!str) return; if (str->str_state == SS_ARY) { ary = stab_array(str->str_u.str_stab); for (i = 0; i <= ary->ary_fill; i++) do_chop(astr,ary->ary_array[i]); return; } if (str->str_state == SS_HASH) { hash = stab_hash(str->str_u.str_stab); (void)hiterinit(hash); /*SUPPRESS 560*/ while (entry = hiternext(hash)) do_chop(astr,hiterval(hash,entry)); return; } tmps = str_get(str); if (tmps && str->str_cur) { tmps += str->str_cur - 1; str_nset(astr,tmps,1); /* remember last char */ *tmps = '\0'; /* wipe it out */ str->str_cur = tmps - str->str_ptr; str->str_nok = 0; STABSET(str); } else str_nset(astr,"",0);}voiddo_vop(optype,str,left,right)STR *str;STR *left;STR *right;{ register char *s; register char *l = str_get(left); register char *r = str_get(right); register int len; len = left->str_cur; if (len > right->str_cur) len = right->str_cur; if (str->str_cur > len) str->str_cur = len; else if (str->str_cur < len) { STR_GROW(str,len); (void)memzero(str->str_ptr + str->str_cur, len - str->str_cur); str->str_cur = len; } str->str_pok = 1; str->str_nok = 0; s = str->str_ptr; if (!s) { str_nset(str,"",0); s = str->str_ptr; } switch (optype) { case O_BIT_AND: while (len--) *s++ = *l++ & *r++; break; case O_XOR: while (len--) *s++ = *l++ ^ *r++; goto mop_up; case O_BIT_OR: while (len--) *s++ = *l++ | *r++; mop_up: len = str->str_cur; if (right->str_cur > len) str_ncat(str,right->str_ptr+len,right->str_cur - len); else if (left->str_cur > len) str_ncat(str,left->str_ptr+len,left->str_cur - len); break; }}intdo_syscall(arglast)int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register int items = arglast[2] - sp;#ifdef atarist unsigned long arg[14]; /* yes, we really need that many ! */#else unsigned long arg[8];#endif register int i = 0; int retval = -1;#ifdef HAS_SYSCALL#ifdef TAINT for (st += ++sp; items--; st++) tainted |= (*st)->str_tainted; st = stack->ary_array; sp = arglast[1]; items = arglast[2] - sp;#endif#ifdef TAINT taintproper("Insecure dependency in syscall");#endif /* This probably won't work on machines where sizeof(long) != sizeof(int) * or where sizeof(long) != sizeof(char*). But such machines will * not likely have syscall implemented either, so who cares? */ while (items--) { if (st[++sp]->str_nok || !i) arg[i++] = (unsigned long)str_gnum(st[sp]);#ifndef lint else arg[i++] = (unsigned long)st[sp]->str_ptr;#endif /* lint */ } sp = arglast[1]; items = arglast[2] - sp; switch (items) { case 0: fatal("Too few args to syscall"); case 1: retval = syscall(arg[0]); break; case 2: retval = syscall(arg[0],arg[1]); break; case 3: retval = syscall(arg[0],arg[1],arg[2]); break; case 4: retval = syscall(arg[0],arg[1],arg[2],arg[3]); break; case 5: retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4]); break; case 6: retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]); break; case 7: retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]); break; case 8: retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], arg[7]); break;#ifdef atarist case 9: retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], arg[7], arg[8]); break; case 10: retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], arg[7], arg[8], arg[9]); break; case 11: retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], arg[7], arg[8], arg[9], arg[10]); break; case 12: retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], arg[7], arg[8], arg[9], arg[10], arg[11]); break; case 13: retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12]); break; case 14: retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13]); break;#endif /* atarist */ } return retval;#else fatal("syscall() unimplemented");#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -