diff options
Diffstat (limited to 'stab.c')
-rw-r--r-- | stab.c | 239 |
1 files changed, 190 insertions, 49 deletions
@@ -1,24 +1,16 @@ -/* $Header: stab.c,v 1.0.1.2 88/02/02 11:25:53 root Exp $ +/* $Header: stab.c,v 2.0 88/06/05 00:11:01 root Exp $ * * $Log: stab.c,v $ - * Revision 1.0.1.2 88/02/02 11:25:53 root - * patch13: moved extern int out of function for a poor Xenix machine. - * - * Revision 1.0.1.1 88/01/28 10:35:17 root - * patch8: changed some stabents to support eval operator. - * - * Revision 1.0 87/12/18 13:06:14 root - * Initial revision + * Revision 2.0 88/06/05 00:11:01 root + * Baseline version 2.0. * */ -#include <signal.h> -#include "handy.h" #include "EXTERN.h" -#include "search.h" -#include "util.h" #include "perl.h" +#include <signal.h> + static char *sig_name[] = { "", "HUP", @@ -68,6 +60,8 @@ static char *sig_name[] = { }; extern int errno; +extern int sys_nerr; +extern char *sys_errlist[]; STR * stab_str(stab) @@ -75,27 +69,31 @@ STAB *stab; { register int paren; register char *s; + register int i; switch (*stab->stab_name) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '&': if (curspat) { paren = atoi(stab->stab_name); - if (curspat->spat_compex.subend[paren] && - (s = getparen(&curspat->spat_compex,paren))) { - curspat->spat_compex.subend[paren] = Nullch; - str_set(stab->stab_val,s); + getparen: + if (curspat->spat_regexp && + paren <= curspat->spat_regexp->nparens && + (s = curspat->spat_regexp->startp[paren]) ) { + i = curspat->spat_regexp->endp[paren] - s; + if (i >= 0) + str_nset(stab->stab_val,s,i); + else + str_nset(stab->stab_val,"",0); } + else + str_nset(stab->stab_val,"",0); } break; case '+': if (curspat) { - paren = curspat->spat_compex.lastparen; - if (curspat->spat_compex.subend[paren] && - (s = getparen(&curspat->spat_compex,paren))) { - curspat->spat_compex.subend[paren] = Nullch; - str_set(stab->stab_val,s); - } + paren = curspat->spat_regexp->lastparen; + goto getparen; } break; case '.': @@ -115,7 +113,7 @@ STAB *stab; str_set(stab->stab_val,s); break; case '=': - str_numset(stab->stab_val,(double)curoutstab->stab_io->lines); + str_numset(stab->stab_val,(double)curoutstab->stab_io->page_len); break; case '-': str_numset(stab->stab_val,(double)curoutstab->stab_io->lines_left); @@ -123,18 +121,6 @@ STAB *stab; case '%': str_numset(stab->stab_val,(double)curoutstab->stab_io->page); break; - case '(': - if (curspat) { - str_numset(stab->stab_val,(double)(curspat->spat_compex.subbeg[0] - - curspat->spat_compex.subbase)); - } - break; - case ')': - if (curspat) { - str_numset(stab->stab_val,(double)(curspat->spat_compex.subend[0] - - curspat->spat_compex.subbeg[0])); - } - break; case '/': *tokenbuf = record_separator; tokenbuf[1] = '\0'; @@ -157,7 +143,41 @@ STAB *stab; str_set(stab->stab_val,ofmt); break; case '!': - str_numset(stab->stab_val,(double)errno); + str_numset(stab->stab_val, (double)errno); + str_set(stab->stab_val, + errno < 0 || errno > sys_nerr ? "(unknown)" : sys_errlist[errno]); + stab->stab_val->str_nok = 1; /* what a wonderful hack! */ + break; + case '<': + str_numset(stab->stab_val,(double)uid); + break; + case '>': + str_numset(stab->stab_val,(double)euid); + break; + case '(': + s = tokenbuf; + sprintf(s,"%d",(int)getgid()); + goto add_groups; + case ')': + s = tokenbuf; + sprintf(s,"%d",(int)getegid()); + add_groups: + while (*s) s++; +#ifdef GETGROUPS +#ifndef NGROUPS +#define NGROUPS 32 +#endif + { + GIDTYPE gary[NGROUPS]; + + i = getgroups(NGROUPS,gary); + while (--i >= 0) { + sprintf(s," %ld", (long)gary[i]); + while (*s) s++; + } + } +#endif + str_set(stab->stab_val,tokenbuf); break; } return stab->stab_val; @@ -175,13 +195,13 @@ STR *str; switch (stab->stab_name[0]) { case '^': safefree(curoutstab->stab_io->top_name); - curoutstab->stab_io->top_name = str_get(str); - curoutstab->stab_io->top_stab = stabent(str_get(str),TRUE); + curoutstab->stab_io->top_name = s = savestr(str_get(str)); + curoutstab->stab_io->top_stab = stabent(s,TRUE); break; case '~': safefree(curoutstab->stab_io->fmt_name); - curoutstab->stab_io->fmt_name = str_get(str); - curoutstab->stab_io->fmt_stab = stabent(str_get(str),TRUE); + curoutstab->stab_io->fmt_name = s = savestr(str_get(str)); + curoutstab->stab_io->fmt_stab = stabent(s,TRUE); break; case '=': curoutstab->stab_io->page_len = (long)str_gnum(str); @@ -222,9 +242,44 @@ STR *str; case '[': arybase = (int)str_gnum(str); break; + case '?': + statusvalue = (unsigned short)str_gnum(str); + break; case '!': errno = (int)str_gnum(str); /* will anyone ever use this? */ break; + case '<': +#ifdef SETRUID + uid = (int)str_gnum(str); + if (setruid(uid) < 0) + uid = (int)getuid(); +#else + fatal("setruid() not implemented"); +#endif + break; + case '>': +#ifdef SETEUID + euid = (int)str_gnum(str); + if (seteuid(euid) < 0) + euid = (int)geteuid(); +#else + fatal("seteuid() not implemented"); +#endif + break; + case '(': +#ifdef SETRGID + setrgid((int)str_gnum(str)); +#else + fatal("setrgid() not implemented"); +#endif + break; + case ')': +#ifdef SETEGID + setegid((int)str_gnum(str)); +#else + fatal("setegid() not implemented"); +#endif + break; case '.': case '+': case '&': @@ -238,8 +293,6 @@ STR *str; case '7': case '8': case '9': - case '(': - case ')': break; /* "read-only" registers */ } } @@ -261,15 +314,18 @@ STR *str; safefree(signame); signame = Nullch; } + else if (stab->stab_array) { + afill(stab->stab_array, (int)str_gnum(str) - arybase); + } } -whichsig(signame) -char *signame; +whichsig(sig) +char *sig; { register char **sigv; for (sigv = sig_name+1; *sigv; sigv++) - if (strEQ(signame,*sigv)) + if (strEQ(sig,*sigv)) return sigv - sig_name; return 0; } @@ -280,16 +336,39 @@ int sig; STAB *stab; ARRAY *savearray; STR *str; + char *oldfile = filename; + int oldsave = savestack->ary_fill; + SUBR *sub; stab = stabent(str_get(hfetch(sigstab->stab_hash,sig_name[sig])),TRUE); + sub = stab->stab_sub; + if (!sub) { + if (dowarn) + warn("SIG%s handler \"%s\" not defined.\n", + sig_name[sig], stab->stab_name ); + return; + } savearray = defstab->stab_array; - defstab->stab_array = anew(); + defstab->stab_array = anew(defstab); str = str_new(0); str_set(str,sig_name[sig]); apush(defstab->stab_array,str); - str = cmd_exec(stab->stab_sub); + sub->depth++; + if (sub->depth >= 2) { /* save temporaries on recursion? */ + if (sub->depth == 100 && dowarn) + warn("Deep recursion on subroutine \"%s\"",stab->stab_name); + savelist(sub->tosave->ary_array,sub->tosave->ary_fill); + } + filename = sub->filename; + + str = cmd_exec(sub->cmd); /* so do it already */ + + sub->depth--; /* assuming no longjumps out of here */ afree(defstab->stab_array); /* put back old $_[] */ defstab->stab_array = savearray; + filename = oldfile; + if (savestack->ary_fill > oldsave) + restorelist(oldsave); } char * @@ -313,7 +392,7 @@ aadd(stab) register STAB *stab; { if (!stab->stab_array) - stab->stab_array = anew(); + stab->stab_array = anew(stab); return stab; } @@ -325,3 +404,65 @@ register STAB *stab; stab->stab_hash = hnew(); return stab; } + +STAB * +stabent(name,add) +register char *name; +int add; +{ + register STAB *stab; + + for (stab = stab_index[*name]; stab; stab = stab->stab_next) { + if (strEQ(name,stab->stab_name)) { + stab->stab_flags |= SF_MULTI; /* is okay, probably */ + return stab; + } + } + + /* no entry--should we add one? */ + + if (add) { + stab = (STAB *) safemalloc(sizeof(STAB)); + bzero((char*)stab, sizeof(STAB)); + stab->stab_name = savestr(name); + stab->stab_val = str_new(0); + stab->stab_next = stab_index[*name]; + stab_index[*name] = stab; + return stab; + } + return Nullstab; +} + +STIO * +stio_new() +{ + STIO *stio = (STIO *) safemalloc(sizeof(STIO)); + + bzero((char*)stio, sizeof(STIO)); + stio->page_len = 60; + return stio; +} + +stab_check(min,max) +int min; +register int max; +{ + register int i; + register STAB *stab; + + for (i = min; i <= max; i++) { + for (stab = stab_index[i]; stab; stab = stab->stab_next) { + if (stab->stab_flags & SF_MULTI) + continue; + if (i == 'A' && strEQ(stab->stab_name, "ARGV")) + continue; + if (i == 'E' && strEQ(stab->stab_name, "ENV")) + continue; + if (i == 'S' && strEQ(stab->stab_name, "SIG")) + continue; + if (i == 'I' && strEQ(stab->stab_name, "INC")) + continue; + warn("Possible typo: %s,", stab->stab_name); + } + } +} |