home *** CD-ROM | disk | FTP | other *** search
- Subject: v20i090: Perl, a language with features of C/sed/awk/shell/etc, Part07/24
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Larry Wall <lwall@jpl-devvax.jpl.nasa.gov>
- Posting-number: Volume 20, Issue 90
- Archive-name: perl3.0/part07
-
- #! /bin/sh
-
- # Make a new directory for the perl sources, cd to it, and run kits 1
- # thru 24 through sh. When all 24 kits have been run, read README.
-
- echo "This is perl 3.0 kit 7 (of 24). If kit 7 is complete, the line"
- echo '"'"End of kit 7 (of 24)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- mkdir 2>/dev/null
- echo Extracting doio.c
- sed >doio.c <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: doio.c,v 3.0 89/10/18 15:10:54 lwall Locked $
- X *
- X * Copyright (c) 1989, Larry Wall
- X *
- X * You may distribute under the terms of the GNU General Public License
- X * as specified in the README file that comes with the perl 3.0 kit.
- X *
- X * $Log: doio.c,v $
- X * Revision 3.0 89/10/18 15:10:54 lwall
- X * 3.0 baseline
- X *
- X */
- X
- X#include "EXTERN.h"
- X#include "perl.h"
- X
- X#ifdef SOCKET
- X#include <sys/socket.h>
- X#include <netdb.h>
- X#endif
- X
- X#include <errno.h>
- X#ifdef I_PWD
- X#include <pwd.h>
- X#endif
- X#ifdef I_GRP
- X#include <grp.h>
- X#endif
- X
- Xextern int errno;
- X
- Xbool
- Xdo_open(stab,name)
- XSTAB *stab;
- Xregister char *name;
- X{
- X FILE *fp;
- X int len = strlen(name);
- X register STIO *stio = stab_io(stab);
- X char *myname = savestr(name);
- X int result;
- X int fd;
- X int writing = 0;
- X char mode[3]; /* stdio file mode ("r\0" or "r+\0") */
- X
- X name = myname;
- X forkprocess = 1; /* assume true if no fork */
- X while (len && isspace(name[len-1]))
- X name[--len] = '\0';
- X if (!stio)
- X stio = stab_io(stab) = stio_new();
- X else if (stio->ifp) {
- X fd = fileno(stio->ifp);
- X if (stio->type == '|')
- X result = mypclose(stio->ifp);
- X else if (stio->ifp != stio->ofp) {
- X if (stio->ofp)
- X fclose(stio->ofp);
- X result = fclose(stio->ifp);
- X }
- X else if (stio->type != '-')
- X result = fclose(stio->ifp);
- X else
- X result = 0;
- X if (result == EOF && fd > 2)
- X fprintf(stderr,"Warning: unable to close filehandle %s properly.\n",
- X stab_name(stab));
- X stio->ofp = stio->ifp = Nullfp;
- X }
- X if (*name == '+' && len > 1 && name[len-1] != '|') { /* scary */
- X mode[1] = *name++;
- X mode[2] = '\0';
- X --len;
- X writing = 1;
- X }
- X else {
- X mode[1] = '\0';
- X }
- X stio->type = *name;
- X if (*name == '|') {
- X for (name++; isspace(*name); name++) ;
- X#ifdef TAINT
- X taintenv();
- X taintproper("Insecure dependency in piped open");
- X#endif
- X fp = mypopen(name,"w");
- X writing = 1;
- X }
- X else if (*name == '>' && name[1] == '>') {
- X#ifdef TAINT
- X taintproper("Insecure dependency in open");
- X#endif
- X mode[0] = stio->type = 'a';
- X for (name += 2; isspace(*name); name++) ;
- X fp = fopen(name, mode);
- X writing = 1;
- X }
- X else if (*name == '>' && name[1] == '&') {
- X#ifdef TAINT
- X taintproper("Insecure dependency in open");
- X#endif
- X for (name += 2; isspace(*name); name++) ;
- X if (isdigit(*name))
- X fd = atoi(name);
- X else {
- X stab = stabent(name,FALSE);
- X if (stab_io(stab) && stab_io(stab)->ifp) {
- X fd = fileno(stab_io(stab)->ifp);
- X stio->type = stab_io(stab)->type;
- X }
- X else
- X fd = -1;
- X }
- X fp = fdopen(dup(fd),stio->type == 'a' ? "a" :
- X (stio->type == '<' ? "r" : "w") );
- X writing = 1;
- X }
- X else if (*name == '>') {
- X#ifdef TAINT
- X taintproper("Insecure dependency in open");
- X#endif
- X for (name++; isspace(*name); name++) ;
- X if (strEQ(name,"-")) {
- X fp = stdout;
- X stio->type = '-';
- X }
- X else {
- X mode[0] = 'w';
- X fp = fopen(name,mode);
- X }
- X writing = 1;
- X }
- X else {
- X if (*name == '<') {
- X for (name++; isspace(*name); name++) ;
- X if (strEQ(name,"-")) {
- X fp = stdin;
- X stio->type = '-';
- X }
- X else {
- X mode[0] = 'r';
- X fp = fopen(name,mode);
- X }
- X }
- X else if (name[len-1] == '|') {
- X#ifdef TAINT
- X taintenv();
- X taintproper("Insecure dependency in piped open");
- X#endif
- X name[--len] = '\0';
- X while (len && isspace(name[len-1]))
- X name[--len] = '\0';
- X for (; isspace(*name); name++) ;
- X fp = mypopen(name,"r");
- X stio->type = '|';
- X }
- X else {
- X stio->type = '<';
- X for (; isspace(*name); name++) ;
- X if (strEQ(name,"-")) {
- X fp = stdin;
- X stio->type = '-';
- X }
- X else
- X fp = fopen(name,"r");
- X }
- X }
- X Safefree(myname);
- X if (!fp)
- X return FALSE;
- X if (stio->type &&
- X stio->type != '|' && stio->type != '-') {
- X if (fstat(fileno(fp),&statbuf) < 0) {
- X (void)fclose(fp);
- X return FALSE;
- X }
- X if ((statbuf.st_mode & S_IFMT) != S_IFREG &&
- X#ifdef S_IFSOCK
- X (statbuf.st_mode & S_IFMT) != S_IFSOCK &&
- X#endif
- X#ifdef S_IFFIFO
- X (statbuf.st_mode & S_IFMT) != S_IFFIFO &&
- X#endif
- X (statbuf.st_mode & S_IFMT) != S_IFCHR) {
- X (void)fclose(fp);
- X return FALSE;
- X }
- X }
- X stio->ifp = fp;
- X if (writing)
- X stio->ofp = fp;
- X return TRUE;
- X}
- X
- XFILE *
- Xnextargv(stab)
- Xregister STAB *stab;
- X{
- X register STR *str;
- X char *oldname;
- X int filemode,fileuid,filegid;
- X
- X while (alen(stab_xarray(stab)) >= 0) {
- X str = ashift(stab_xarray(stab));
- X str_sset(stab_val(stab),str);
- X STABSET(stab_val(stab));
- X oldname = str_get(stab_val(stab));
- X if (do_open(stab,oldname)) {
- X if (inplace) {
- X#ifdef TAINT
- X taintproper("Insecure dependency in inplace open");
- X#endif
- X filemode = statbuf.st_mode;
- X fileuid = statbuf.st_uid;
- X filegid = statbuf.st_gid;
- X if (*inplace) {
- X str_cat(str,inplace);
- X#ifdef RENAME
- X (void)rename(oldname,str->str_ptr);
- X#else
- X (void)UNLINK(str->str_ptr);
- X (void)link(oldname,str->str_ptr);
- X (void)UNLINK(oldname);
- X#endif
- X }
- X else {
- X (void)UNLINK(oldname);
- X }
- X
- X str_nset(str,">",1);
- X str_cat(str,oldname);
- X errno = 0; /* in case sprintf set errno */
- X if (!do_open(argvoutstab,str->str_ptr))
- X fatal("Can't do inplace edit");
- X defoutstab = argvoutstab;
- X#ifdef FCHMOD
- X (void)fchmod(fileno(stab_io(argvoutstab)->ifp),filemode);
- X#else
- X (void)chmod(oldname,filemode);
- X#endif
- X#ifdef FCHOWN
- X (void)fchown(fileno(stab_io(argvoutstab)->ifp),fileuid,filegid);
- X#else
- X (void)chown(oldname,fileuid,filegid);
- X#endif
- X }
- X str_free(str);
- X return stab_io(stab)->ifp;
- X }
- X else
- X fprintf(stderr,"Can't open %s\n",str_get(str));
- X str_free(str);
- X }
- X if (inplace) {
- X (void)do_close(argvoutstab,FALSE);
- X defoutstab = stabent("STDOUT",TRUE);
- X }
- X return Nullfp;
- X}
- X
- Xbool
- Xdo_close(stab,explicit)
- XSTAB *stab;
- Xbool explicit;
- X{
- X bool retval = FALSE;
- X register STIO *stio = stab_io(stab);
- X int status;
- X
- X if (!stio) { /* never opened */
- X if (dowarn && explicit)
- X warn("Close on unopened file <%s>",stab_name(stab));
- X return FALSE;
- X }
- X if (stio->ifp) {
- X if (stio->type == '|') {
- X status = mypclose(stio->ifp);
- X retval = (status >= 0);
- X statusvalue = (unsigned)status & 0xffff;
- X }
- X else if (stio->type == '-')
- X retval = TRUE;
- X else {
- X if (stio->ofp && stio->ofp != stio->ifp) /* a socket */
- X fclose(stio->ofp);
- X retval = (fclose(stio->ifp) != EOF);
- X }
- X stio->ofp = stio->ifp = Nullfp;
- X }
- X if (explicit)
- X stio->lines = 0;
- X stio->type = ' ';
- X return retval;
- X}
- X
- Xbool
- Xdo_eof(stab)
- XSTAB *stab;
- X{
- X register STIO *stio;
- X int ch;
- X
- X if (!stab) { /* eof() */
- X if (argvstab)
- X stio = stab_io(argvstab);
- X else
- X return TRUE;
- X }
- X else
- X stio = stab_io(stab);
- X
- X if (!stio)
- X return TRUE;
- X
- X while (stio->ifp) {
- X
- X#ifdef STDSTDIO /* (the code works without this) */
- X if (stio->ifp->_cnt > 0) /* cheat a little, since */
- X return FALSE; /* this is the most usual case */
- X#endif
- X
- X ch = getc(stio->ifp);
- X if (ch != EOF) {
- X (void)ungetc(ch, stio->ifp);
- X return FALSE;
- X }
- X if (!stab) { /* not necessarily a real EOF yet? */
- X if (!nextargv(argvstab)) /* get another fp handy */
- X return TRUE;
- X }
- X else
- X return TRUE; /* normal fp, definitely end of file */
- X }
- X return TRUE;
- X}
- X
- Xlong
- Xdo_tell(stab)
- XSTAB *stab;
- X{
- X register STIO *stio;
- X
- X if (!stab)
- X goto phooey;
- X
- X stio = stab_io(stab);
- X if (!stio || !stio->ifp)
- X goto phooey;
- X
- X if (feof(stio->ifp))
- X (void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
- X
- X return ftell(stio->ifp);
- X
- Xphooey:
- X if (dowarn)
- X warn("tell() on unopened file");
- X return -1L;
- X}
- X
- Xbool
- Xdo_seek(stab, pos, whence)
- XSTAB *stab;
- Xlong pos;
- Xint whence;
- X{
- X register STIO *stio;
- X
- X if (!stab)
- X goto nuts;
- X
- X stio = stab_io(stab);
- X if (!stio || !stio->ifp)
- X goto nuts;
- X
- X if (feof(stio->ifp))
- X (void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
- X
- X return fseek(stio->ifp, pos, whence) >= 0;
- X
- Xnuts:
- X if (dowarn)
- X warn("seek() on unopened file");
- X return FALSE;
- X}
- X
- Xint
- Xdo_ctl(optype,stab,func,argstr)
- Xint optype;
- XSTAB *stab;
- Xint func;
- XSTR *argstr;
- X{
- X register STIO *stio;
- X register char *s;
- X int retval;
- X
- X if (!stab || !argstr)
- X return -1;
- X stio = stab_io(stab);
- X if (!stio)
- X return -1;
- X
- X if (argstr->str_pok || !argstr->str_nok) {
- X if (!argstr->str_pok)
- X s = str_get(argstr);
- X
- X#ifdef IOCPARM_MASK
- X#ifndef IOCPARM_LEN
- X#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
- X#endif
- X#endif
- X#ifdef IOCPARM_LEN
- X retval = IOCPARM_LEN(func); /* on BSDish systes we're safe */
- X#else
- X retval = 256; /* otherwise guess at what's safe */
- X#endif
- X if (argstr->str_cur < retval) {
- X str_grow(argstr,retval+1);
- X argstr->str_cur = retval;
- X }
- X
- X s = argstr->str_ptr;
- X s[argstr->str_cur] = 17; /* a little sanity check here */
- X }
- X else {
- X retval = (int)str_gnum(argstr);
- X s = (char*)retval; /* ouch */
- X }
- X
- X#ifndef lint
- X if (optype == O_IOCTL)
- X retval = ioctl(fileno(stio->ifp), func, s);
- X else
- X#ifdef I_FCNTL
- X retval = fcntl(fileno(stio->ifp), func, s);
- X#else
- X fatal("fcntl is not implemented");
- X#endif
- X#else /* lint */
- X retval = 0;
- X#endif /* lint */
- X
- X if (argstr->str_pok) {
- X if (s[argstr->str_cur] != 17)
- X fatal("Return value overflowed string");
- X s[argstr->str_cur] = 0; /* put our null back */
- X }
- X return retval;
- X}
- X
- Xint
- Xdo_stat(str,arg,gimme,arglast)
- XSTR *str;
- Xregister ARG *arg;
- Xint gimme;
- Xint *arglast;
- X{
- X register ARRAY *ary = stack;
- X register int sp = arglast[0] + 1;
- X int max = 13;
- X register int i;
- X
- X if ((arg[1].arg_type & A_MASK) == A_WORD) {
- X tmpstab = arg[1].arg_ptr.arg_stab;
- X if (tmpstab != defstab) {
- X statstab = tmpstab;
- X str_set(statname,"");
- X if (!stab_io(tmpstab) ||
- X fstat(fileno(stab_io(tmpstab)->ifp),&statcache) < 0) {
- X max = 0;
- X }
- X }
- X }
- X else {
- X str_sset(statname,ary->ary_array[sp]);
- X statstab = Nullstab;
- X#ifdef SYMLINK
- X if (arg->arg_type == O_LSTAT)
- X i = lstat(str_get(statname),&statcache);
- X else
- X#endif
- X i = stat(str_get(statname),&statcache);
- X if (i < 0)
- X max = 0;
- X }
- X
- X if (gimme != G_ARRAY) {
- X if (max)
- X str_sset(str,&str_yes);
- X else
- X str_sset(str,&str_undef);
- X STABSET(str);
- X ary->ary_array[sp] = str;
- X return sp;
- X }
- X sp--;
- X if (max) {
- X#ifndef lint
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_dev)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_ino)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_mode)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_nlink)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_uid)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_gid)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_rdev)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_size)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_atime)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_mtime)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_ctime)));
- X#ifdef STATBLOCKS
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_blksize)));
- X (void)astore(ary,++sp,
- X str_2static(str_nmake((double)statcache.st_blocks)));
- X#else
- X (void)astore(ary,++sp,
- X str_2static(str_make("",0)));
- X (void)astore(ary,++sp,
- X str_2static(str_make("",0)));
- X#endif
- X#else /* lint */
- X (void)astore(ary,++sp,str_nmake(0.0));
- X#endif /* lint */
- X }
- X return sp;
- X}
- X
- Xint
- Xlooks_like_number(str)
- XSTR *str;
- X{
- X register char *s;
- X register char *send;
- X
- X if (!str->str_pok)
- X return TRUE;
- X s = str->str_ptr;
- X send = s + str->str_cur;
- X while (isspace(*s))
- X s++;
- X if (s >= send)
- X return FALSE;
- X if (*s == '+' || *s == '-')
- X s++;
- X while (isdigit(*s))
- X s++;
- X if (s == send)
- X return TRUE;
- X if (*s == '.')
- X s++;
- X else if (s == str->str_ptr)
- X return FALSE;
- X while (isdigit(*s))
- X s++;
- X if (s == send)
- X return TRUE;
- X if (*s == 'e' || *s == 'E') {
- X s++;
- X if (*s == '+' || *s == '-')
- X s++;
- X while (isdigit(*s))
- X s++;
- X }
- X while (isspace(*s))
- X s++;
- X if (s >= send)
- X return TRUE;
- X return FALSE;
- X}
- X
- Xbool
- Xdo_print(str,fp)
- Xregister STR *str;
- XFILE *fp;
- X{
- X register char *tmps;
- X
- X if (!fp) {
- X if (dowarn)
- X warn("print to unopened file");
- X return FALSE;
- X }
- X if (!str)
- X return FALSE;
- X if (ofmt &&
- X ((str->str_nok && str->str_u.str_nval != 0.0)
- X || (looks_like_number(str) && str_gnum(str) != 0.0) ) )
- X fprintf(fp, ofmt, str->str_u.str_nval);
- X else {
- X tmps = str_get(str);
- X if (*tmps == 'S' && tmps[1] == 't' && tmps[2] == 'a' && tmps[3] == 'b'
- X && str->str_cur == sizeof(STBP) && strlen(tmps) < str->str_cur) {
- X tmps = stab_name(((STAB*)str)); /* a stab value, be nice */
- X str = ((STAB*)str)->str_magic;
- X putc('*',fp);
- X }
- X if (str->str_cur && fwrite(tmps,1,str->str_cur,fp) == 0)
- X return FALSE;
- X }
- X return TRUE;
- X}
- X
- Xbool
- Xdo_aprint(arg,fp,arglast)
- Xregister ARG *arg;
- Xregister FILE *fp;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[1];
- X register int retval;
- X register int items = arglast[2] - sp;
- X
- X if (!fp) {
- X if (dowarn)
- X warn("print to unopened file");
- X return FALSE;
- X }
- X st += ++sp;
- X if (arg->arg_type == O_PRTF) {
- X do_sprintf(arg->arg_ptr.arg_str,items,st);
- X retval = do_print(arg->arg_ptr.arg_str,fp);
- X }
- X else {
- X retval = (items <= 0);
- X for (; items > 0; items--,st++) {
- X if (retval && ofslen) {
- X if (fwrite(ofs, 1, ofslen, fp) == 0) {
- X retval = FALSE;
- X break;
- X }
- X }
- X if (!(retval = do_print(*st, fp)))
- X break;
- X }
- X if (retval && orslen)
- X if (fwrite(ors, 1, orslen, fp) == 0)
- X retval = FALSE;
- X }
- X return retval;
- X}
- X
- Xint
- Xmystat(arg,str)
- XARG *arg;
- XSTR *str;
- X{
- X STIO *stio;
- X
- X if (arg[1].arg_type & A_DONT) {
- X stio = stab_io(arg[1].arg_ptr.arg_stab);
- X if (stio && stio->ifp) {
- X statstab = arg[1].arg_ptr.arg_stab;
- X str_set(statname,"");
- X return fstat(fileno(stio->ifp), &statcache);
- X }
- X else {
- X if (arg[1].arg_ptr.arg_stab == defstab)
- X return 0;
- X if (dowarn)
- X warn("Stat on unopened file <%s>",
- X stab_name(arg[1].arg_ptr.arg_stab));
- X statstab = Nullstab;
- X str_set(statname,"");
- X return -1;
- X }
- X }
- X else {
- X statstab = Nullstab;
- X str_sset(statname,str);
- X return stat(str_get(str),&statcache);
- X }
- X}
- X
- XSTR *
- Xdo_fttext(arg,str)
- Xregister ARG *arg;
- XSTR *str;
- X{
- X int i;
- X int len;
- X int odd = 0;
- X STDCHAR tbuf[512];
- X register STDCHAR *s;
- X register STIO *stio;
- X
- X if (arg[1].arg_type & A_DONT) {
- X if (arg[1].arg_ptr.arg_stab == defstab) {
- X if (statstab)
- X stio = stab_io(statstab);
- X else {
- X str = statname;
- X goto really_filename;
- X }
- X }
- X else {
- X statstab = arg[1].arg_ptr.arg_stab;
- X str_set(statname,"");
- X stio = stab_io(statstab);
- X }
- X if (stio && stio->ifp) {
- X#ifdef STDSTDIO
- X fstat(fileno(stio->ifp),&statcache);
- X if (stio->ifp->_cnt <= 0) {
- X i = getc(stio->ifp);
- X if (i != EOF)
- X (void)ungetc(i,stio->ifp);
- X }
- X if (stio->ifp->_cnt <= 0) /* null file is anything */
- X return &str_yes;
- X len = stio->ifp->_cnt + (stio->ifp->_ptr - stio->ifp->_base);
- X s = stio->ifp->_base;
- X#else
- X fatal("-T and -B not implemented on filehandles\n");
- X#endif
- X }
- X else {
- X if (dowarn)
- X warn("Test on unopened file <%s>",
- X stab_name(arg[1].arg_ptr.arg_stab));
- X return &str_undef;
- X }
- X }
- X else {
- X statstab = Nullstab;
- X str_sset(statname,str);
- X really_filename:
- X i = open(str_get(str),0);
- X if (i < 0)
- X return &str_undef;
- X fstat(i,&statcache);
- X len = read(i,tbuf,512);
- X if (len <= 0) /* null file is anything */
- X return &str_yes;
- X (void)close(i);
- X s = tbuf;
- X }
- X
- X /* now scan s to look for textiness */
- X
- X for (i = 0; i < len; i++,s++) {
- X if (!*s) { /* null never allowed in text */
- X odd += len;
- X break;
- X }
- X else if (*s & 128)
- X odd++;
- X else if (*s < 32 &&
- X *s != '\n' && *s != '\r' && *s != '\b' &&
- X *s != '\t' && *s != '\f' && *s != 27)
- X odd++;
- X }
- X
- X if ((odd * 10 > len) == (arg->arg_type == O_FTTEXT)) /* allow 10% odd */
- X return &str_no;
- X else
- X return &str_yes;
- X}
- X
- Xbool
- Xdo_aexec(really,arglast)
- XSTR *really;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[1];
- X register int items = arglast[2] - sp;
- X register char **a;
- X char **argv;
- X char *tmps;
- X
- X if (items) {
- X New(401,argv, items+1, char*);
- X a = argv;
- X for (st += ++sp; items > 0; items--,st++) {
- X if (*st)
- X *a++ = str_get(*st);
- X else
- X *a++ = "";
- X }
- X *a = Nullch;
- X#ifdef TAINT
- X if (*argv[0] != '/') /* will execvp use PATH? */
- X taintenv(); /* testing IFS here is overkill, probably */
- X#endif
- X if (really && *(tmps = str_get(really)))
- X execvp(tmps,argv);
- X else
- X execvp(argv[0],argv);
- X Safefree(argv);
- X }
- X return FALSE;
- X}
- X
- Xbool
- Xdo_exec(cmd)
- Xchar *cmd;
- X{
- X register char **a;
- X register char *s;
- X char **argv;
- X char flags[10];
- X
- X#ifdef TAINT
- X taintenv();
- X taintproper("Insecure dependency in exec");
- X#endif
- X
- X /* save an extra exec if possible */
- X
- X if (csh > 0 && strnEQ(cmd,"/bin/csh -c",11)) {
- X strcpy(flags,"-c");
- X s = cmd+11;
- X if (*s == 'f') {
- X s++;
- X strcat(flags,"f");
- X }
- X if (*s == ' ')
- X s++;
- X if (*s++ == '\'') {
- X char *ncmd = s;
- X
- X while (*s)
- X s++;
- X if (s[-1] == '\n')
- X *--s = '\0';
- X if (s[-1] == '\'') {
- X *--s = '\0';
- X execl("/bin/csh","csh", flags,ncmd,(char*)0);
- X *s = '\'';
- X return FALSE;
- X }
- X }
- X }
- X
- X /* see if there are shell metacharacters in it */
- X
- X for (s = cmd; *s; s++) {
- X if (*s != ' ' && !isalpha(*s) && index("$&*(){}[]'\";\\|?<>~`\n",*s)) {
- X if (*s == '\n' && !s[1]) {
- X *s = '\0';
- X break;
- X }
- X doshell:
- X execl("/bin/sh","sh","-c",cmd,(char*)0);
- X return FALSE;
- X }
- X }
- X New(402,argv, (s - cmd) / 2 + 2, char*);
- X
- X a = argv;
- X for (s = cmd; *s;) {
- X while (*s && isspace(*s)) s++;
- X if (*s)
- X *(a++) = s;
- X while (*s && !isspace(*s)) s++;
- X if (*s)
- X *s++ = '\0';
- X }
- X *a = Nullch;
- X if (argv[0]) {
- X execvp(argv[0],argv);
- X if (errno == ENOEXEC) /* for system V NIH syndrome */
- X goto doshell;
- X }
- X Safefree(argv);
- X return FALSE;
- X}
- X
- X#ifdef SOCKET
- Xint
- Xdo_socket(stab, arglast)
- XSTAB *stab;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[1];
- X register STIO *stio;
- X int domain, type, protocol, fd;
- X
- X if (!stab)
- X return FALSE;
- X
- X stio = stab_io(stab);
- X if (!stio)
- X stio = stab_io(stab) = stio_new();
- X else if (stio->ifp)
- X do_close(stab,FALSE);
- X
- X domain = (int)str_gnum(st[++sp]);
- X type = (int)str_gnum(st[++sp]);
- X protocol = (int)str_gnum(st[++sp]);
- X#ifdef TAINT
- X taintproper("Insecure dependency in socket");
- X#endif
- X fd = socket(domain,type,protocol);
- X if (fd < 0)
- X return FALSE;
- X stio->ifp = fdopen(fd, "r"); /* stdio gets confused about sockets */
- X stio->ofp = fdopen(fd, "w");
- X stio->type = 's';
- X
- X return TRUE;
- X}
- X
- Xint
- Xdo_bind(stab, arglast)
- XSTAB *stab;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[1];
- X register STIO *stio;
- X char *addr;
- X
- X if (!stab)
- X goto nuts;
- X
- X stio = stab_io(stab);
- X if (!stio || !stio->ifp)
- X goto nuts;
- X
- X addr = str_get(st[++sp]);
- X#ifdef TAINT
- X taintproper("Insecure dependency in bind");
- X#endif
- X return bind(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;
- X
- Xnuts:
- X if (dowarn)
- X warn("bind() on closed fd");
- X return FALSE;
- X
- X}
- X
- Xint
- Xdo_connect(stab, arglast)
- XSTAB *stab;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[1];
- X register STIO *stio;
- X char *addr;
- X
- X if (!stab)
- X goto nuts;
- X
- X stio = stab_io(stab);
- X if (!stio || !stio->ifp)
- X goto nuts;
- X
- X addr = str_get(st[++sp]);
- X#ifdef TAINT
- X taintproper("Insecure dependency in connect");
- X#endif
- X return connect(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;
- X
- Xnuts:
- X if (dowarn)
- X warn("connect() on closed fd");
- X return FALSE;
- X
- X}
- X
- Xint
- Xdo_listen(stab, arglast)
- XSTAB *stab;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[1];
- X register STIO *stio;
- X int backlog;
- X
- X if (!stab)
- X goto nuts;
- X
- X stio = stab_io(stab);
- X if (!stio || !stio->ifp)
- X goto nuts;
- X
- X backlog = (int)str_gnum(st[++sp]);
- X return listen(fileno(stio->ifp), backlog) >= 0;
- X
- Xnuts:
- X if (dowarn)
- X warn("listen() on closed fd");
- X return FALSE;
- X}
- X
- Xvoid
- Xdo_accept(str, nstab, gstab)
- XSTR *str;
- XSTAB *nstab;
- XSTAB *gstab;
- X{
- X register STIO *nstio;
- X register STIO *gstio;
- X int len = sizeof buf;
- X int fd;
- X
- X if (!nstab)
- X goto badexit;
- X if (!gstab)
- X goto nuts;
- X
- X gstio = stab_io(gstab);
- X nstio = stab_io(nstab);
- X
- X if (!gstio || !gstio->ifp)
- X goto nuts;
- X if (!nstio)
- X nstio = stab_io(nstab) = stio_new();
- X else if (nstio->ifp)
- X do_close(nstab,FALSE);
- X
- X fd = accept(fileno(gstio->ifp),buf,&len);
- X if (fd < 0)
- X goto badexit;
- X nstio->ifp = fdopen(fd, "r");
- X nstio->ofp = fdopen(fd, "w");
- X nstio->type = 's';
- X
- X str_nset(str, buf, len);
- X return;
- X
- Xnuts:
- X if (dowarn)
- X warn("accept() on closed fd");
- Xbadexit:
- X str_sset(str,&str_undef);
- X return;
- X}
- X
- Xint
- Xdo_shutdown(stab, arglast)
- XSTAB *stab;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[1];
- X register STIO *stio;
- X int how;
- X
- X if (!stab)
- X goto nuts;
- X
- X stio = stab_io(stab);
- X if (!stio || !stio->ifp)
- X goto nuts;
- X
- X how = (int)str_gnum(st[++sp]);
- X return shutdown(fileno(stio->ifp), how) >= 0;
- X
- Xnuts:
- X if (dowarn)
- X warn("shutdown() on closed fd");
- X return FALSE;
- X
- X}
- X
- Xint
- Xdo_sopt(optype, stab, arglast)
- Xint optype;
- XSTAB *stab;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[1];
- X register STIO *stio;
- X int fd;
- X int lvl;
- X int optname;
- X
- X if (!stab)
- X goto nuts;
- X
- X stio = stab_io(stab);
- X if (!stio || !stio->ifp)
- X goto nuts;
- X
- X fd = fileno(stio->ifp);
- X lvl = (int)str_gnum(st[sp+1]);
- X optname = (int)str_gnum(st[sp+2]);
- X switch (optype) {
- X case O_GSOCKOPT:
- X st[sp] = str_2static(str_new(257));
- X st[sp]->str_cur = 256;
- X if (getsockopt(fd, lvl, optname, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
- X goto nuts;
- X break;
- X case O_SSOCKOPT:
- X st[sp] = st[sp+3];
- X if (setsockopt(fd, lvl, optname, st[sp]->str_ptr, st[sp]->str_cur) < 0)
- X goto nuts;
- X st[sp] = &str_yes;
- X break;
- X }
- X
- X return sp;
- X
- Xnuts:
- X if (dowarn)
- X warn("shutdown() on closed fd");
- X st[sp] = &str_undef;
- X return sp;
- X
- X}
- X
- Xint
- Xdo_getsockname(optype, stab, arglast)
- Xint optype;
- XSTAB *stab;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[1];
- X register STIO *stio;
- X int fd;
- X
- X if (!stab)
- X goto nuts;
- X
- X stio = stab_io(stab);
- X if (!stio || !stio->ifp)
- X goto nuts;
- X
- X st[sp] = str_2static(str_new(257));
- X st[sp]->str_cur = 256;
- X fd = fileno(stio->ifp);
- X switch (optype) {
- X case O_GETSOCKNAME:
- X if (getsockname(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
- X goto nuts;
- X break;
- X case O_GETPEERNAME:
- X if (getpeername(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
- X goto nuts;
- X break;
- X }
- X
- X return sp;
- X
- Xnuts:
- X if (dowarn)
- X warn("shutdown() on closed fd");
- X st[sp] = &str_undef;
- X return sp;
- X
- X}
- X
- Xint
- Xdo_ghent(which,gimme,arglast)
- Xint which;
- Xint gimme;
- Xint *arglast;
- X{
- X register ARRAY *ary = stack;
- X register int sp = arglast[0];
- X register char **elem;
- X register STR *str;
- X struct hostent *gethostbynam();
- X struct hostent *gethostbyaddr();
- X#ifdef GETHOSTENT
- X struct hostent *gethostent();
- X#endif
- X struct hostent *hent;
- X unsigned long len;
- X
- X if (gimme != G_ARRAY) {
- X astore(ary, ++sp, str_static(&str_undef));
- X return sp;
- X }
- X
- X if (which == O_GHBYNAME) {
- X char *name = str_get(ary->ary_array[sp+1]);
- X
- X hent = gethostbyname(name);
- X }
- X else if (which == O_GHBYADDR) {
- X STR *addrstr = ary->ary_array[sp+1];
- X int addrtype = (int)str_gnum(ary->ary_array[sp+2]);
- X char *addr = str_get(addrstr);
- X
- X hent = gethostbyaddr(addr,addrstr->str_cur,addrtype);
- X }
- X else
- X#ifdef GETHOSTENT
- X hent = gethostent();
- X#else
- X fatal("gethostent not implemented");
- X#endif
- X if (hent) {
- X#ifndef lint
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, hent->h_name);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X for (elem = hent->h_aliases; *elem; elem++) {
- X str_cat(str, *elem);
- X if (elem[1])
- X str_ncat(str," ",1);
- X }
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_numset(str, (double)hent->h_addrtype);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X len = hent->h_length;
- X str_numset(str, (double)len);
- X#ifdef h_addr
- X for (elem = hent->h_addr_list; *elem; elem++) {
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_nset(str, *elem, len);
- X }
- X#else
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_nset(str, hent->h_addr, len);
- X#endif /* h_addr */
- X#else /* lint */
- X elem = Nullch;
- X elem = elem;
- X (void)astore(ary, ++sp, str_static(&str_no));
- X#endif /* lint */
- X }
- X
- X return sp;
- X}
- X
- Xint
- Xdo_gnent(which,gimme,arglast)
- Xint which;
- Xint gimme;
- Xint *arglast;
- X{
- X register ARRAY *ary = stack;
- X register int sp = arglast[0];
- X register char **elem;
- X register STR *str;
- X struct netent *getnetbyname();
- X struct netent *getnetbyaddr();
- X struct netent *getnetent();
- X struct netent *nent;
- X
- X if (gimme != G_ARRAY) {
- X astore(ary, ++sp, str_static(&str_undef));
- X return sp;
- X }
- X
- X if (which == O_GNBYNAME) {
- X char *name = str_get(ary->ary_array[sp+1]);
- X
- X nent = getnetbyname(name);
- X }
- X else if (which == O_GNBYADDR) {
- X STR *addrstr = ary->ary_array[sp+1];
- X int addrtype = (int)str_gnum(ary->ary_array[sp+2]);
- X char *addr = str_get(addrstr);
- X
- X nent = getnetbyaddr(addr,addrtype);
- X }
- X else
- X nent = getnetent();
- X
- X if (nent) {
- X#ifndef lint
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, nent->n_name);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X for (elem = nent->n_aliases; *elem; elem++) {
- X str_cat(str, *elem);
- X if (elem[1])
- X str_ncat(str," ",1);
- X }
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_numset(str, (double)nent->n_addrtype);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_numset(str, (double)nent->n_net);
- X#else /* lint */
- X elem = Nullch;
- X elem = elem;
- X (void)astore(ary, ++sp, str_static(&str_no));
- X#endif /* lint */
- X }
- X
- X return sp;
- X}
- X
- Xint
- Xdo_gpent(which,gimme,arglast)
- Xint which;
- Xint gimme;
- Xint *arglast;
- X{
- X register ARRAY *ary = stack;
- X register int sp = arglast[0];
- X register char **elem;
- X register STR *str;
- X struct protoent *getprotobyname();
- X struct protoent *getprotobynumber();
- X struct protoent *getprotoent();
- X struct protoent *pent;
- X
- X if (gimme != G_ARRAY) {
- X astore(ary, ++sp, str_static(&str_undef));
- X return sp;
- X }
- X
- X if (which == O_GPBYNAME) {
- X char *name = str_get(ary->ary_array[sp+1]);
- X
- X pent = getprotobyname(name);
- X }
- X else if (which == O_GPBYNUMBER) {
- X int proto = (int)str_gnum(ary->ary_array[sp+1]);
- X
- X pent = getprotobynumber(proto);
- X }
- X else
- X pent = getprotoent();
- X
- X if (pent) {
- X#ifndef lint
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, pent->p_name);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X for (elem = pent->p_aliases; *elem; elem++) {
- X str_cat(str, *elem);
- X if (elem[1])
- X str_ncat(str," ",1);
- X }
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_numset(str, (double)pent->p_proto);
- X#else /* lint */
- X elem = Nullch;
- X elem = elem;
- X (void)astore(ary, ++sp, str_static(&str_no));
- X#endif /* lint */
- X }
- X
- X return sp;
- X}
- X
- Xint
- Xdo_gsent(which,gimme,arglast)
- Xint which;
- Xint gimme;
- Xint *arglast;
- X{
- X register ARRAY *ary = stack;
- X register int sp = arglast[0];
- X register char **elem;
- X register STR *str;
- X struct servent *getservbyname();
- X struct servent *getservbynumber();
- X struct servent *getservent();
- X struct servent *sent;
- X
- X if (gimme != G_ARRAY) {
- X astore(ary, ++sp, str_static(&str_undef));
- X return sp;
- X }
- X
- X if (which == O_GSBYNAME) {
- X char *name = str_get(ary->ary_array[sp+1]);
- X char *proto = str_get(ary->ary_array[sp+2]);
- X
- X if (proto && !*proto)
- X proto = Nullch;
- X
- X sent = getservbyname(name,proto);
- X }
- X else if (which == O_GSBYPORT) {
- X int port = (int)str_gnum(ary->ary_array[sp+1]);
- X char *proto = str_get(ary->ary_array[sp+2]);
- X
- X sent = getservbyport(port,proto);
- X }
- X else
- X sent = getservent();
- X if (sent) {
- X#ifndef lint
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, sent->s_name);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X for (elem = sent->s_aliases; *elem; elem++) {
- X str_cat(str, *elem);
- X if (elem[1])
- X str_ncat(str," ",1);
- X }
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X#ifdef NTOHS
- X str_numset(str, (double)ntohs(sent->s_port));
- X#else
- X str_numset(str, (double)(sent->s_port));
- X#endif
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, sent->s_proto);
- X#else /* lint */
- X elem = Nullch;
- X elem = elem;
- X (void)astore(ary, ++sp, str_static(&str_no));
- X#endif /* lint */
- X }
- X
- X return sp;
- X}
- X
- Xint
- Xdo_select(gimme,arglast)
- Xint gimme;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[0];
- X register int i;
- X register int j;
- X register char *s;
- X register STR *str;
- X double value;
- X int maxlen = 0;
- X int nfound;
- X struct timeval timebuf;
- X struct timeval *tbuf = &timebuf;
- X
- X for (i = 1; i <= 3; i++) {
- X j = st[sp+i]->str_len;
- X if (maxlen < j)
- X maxlen = j;
- X }
- X for (i = 1; i <= 3; i++) {
- X str = st[sp+i];
- X j = str->str_len;
- X if (j < maxlen) {
- X if (str->str_pok) {
- X str_grow(str,maxlen);
- X s = str_get(str) + j;
- X while (++j <= maxlen) {
- X *s++ = '\0';
- X }
- X }
- X else if (str->str_ptr) {
- X Safefree(str->str_ptr);
- X str->str_ptr = Nullch;
- X }
- X }
- X }
- X str = st[sp+4];
- X if (str->str_nok || str->str_pok) {
- X value = str_gnum(str);
- X if (value < 0.0)
- X value = 0.0;
- X timebuf.tv_sec = (long)value;
- X value -= (double)timebuf.tv_sec;
- X timebuf.tv_usec = (long)(value * 1000000.0);
- X }
- X else
- X tbuf = Null(struct timeval*);
- X
- X nfound = select(
- X maxlen * 8,
- X st[sp+1]->str_ptr,
- X st[sp+2]->str_ptr,
- X st[sp+3]->str_ptr,
- X tbuf);
- X
- X st[++sp] = str_static(&str_no);
- X str_numset(st[sp], (double)nfound);
- X if (gimme == G_ARRAY && tbuf) {
- X value = (double)(timebuf.tv_sec) +
- X (double)(timebuf.tv_usec) / 1000000.0;
- X st[++sp] = str_static(&str_no);
- X str_numset(st[sp], value);
- X }
- X return sp;
- X}
- X
- Xint
- Xdo_spair(stab1, stab2, arglast)
- XSTAB *stab1;
- XSTAB *stab2;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[2];
- X register STIO *stio1;
- X register STIO *stio2;
- X int domain, type, protocol, fd[2];
- X
- X if (!stab1 || !stab2)
- X return FALSE;
- X
- X stio1 = stab_io(stab1);
- X stio2 = stab_io(stab2);
- X if (!stio1)
- X stio1 = stab_io(stab1) = stio_new();
- X else if (stio1->ifp)
- X do_close(stab1,FALSE);
- X if (!stio2)
- X stio2 = stab_io(stab2) = stio_new();
- X else if (stio2->ifp)
- X do_close(stab2,FALSE);
- X
- X domain = (int)str_gnum(st[++sp]);
- X type = (int)str_gnum(st[++sp]);
- X protocol = (int)str_gnum(st[++sp]);
- X#ifdef TAINT
- X taintproper("Insecure dependency in socketpair");
- X#endif
- X#ifdef SOCKETPAIR
- X if (socketpair(domain,type,protocol,fd) < 0)
- X return FALSE;
- X#else
- X fatal("Socketpair unimplemented");
- X#endif
- X stio1->ifp = fdopen(fd[0], "r");
- X stio1->ofp = fdopen(fd[0], "w");
- X stio1->type = 's';
- X stio2->ifp = fdopen(fd[1], "r");
- X stio2->ofp = fdopen(fd[1], "w");
- X stio2->type = 's';
- X
- X return TRUE;
- X}
- X
- X#endif /* SOCKET */
- X
- Xint
- Xdo_gpwent(which,gimme,arglast)
- Xint which;
- Xint gimme;
- Xint *arglast;
- X{
- X#ifdef I_PWD
- X register ARRAY *ary = stack;
- X register int sp = arglast[0];
- X register char **elem;
- X register STR *str;
- X struct passwd *getpwnam();
- X struct passwd *getpwuid();
- X struct passwd *getpwent();
- X struct passwd *pwent;
- X unsigned long len;
- X
- X if (gimme != G_ARRAY) {
- X astore(ary, ++sp, str_static(&str_undef));
- X return sp;
- X }
- X
- X if (which == O_GPWNAM) {
- X char *name = str_get(ary->ary_array[sp+1]);
- X
- X pwent = getpwnam(name);
- X }
- X else if (which == O_GPWUID) {
- X int uid = (int)str_gnum(ary->ary_array[sp+1]);
- X
- X pwent = getpwuid(uid);
- X }
- X else
- X pwent = getpwent();
- X
- X if (pwent) {
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, pwent->pw_name);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, pwent->pw_passwd);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_numset(str, (double)pwent->pw_uid);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_numset(str, (double)pwent->pw_gid);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X#ifdef PWQUOTA
- X str_numset(str, (double)pwent->pw_quota);
- X#else
- X#ifdef PWAGE
- X str_set(str, pwent->pw_age);
- X#endif
- X#endif
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, pwent->pw_comment);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, pwent->pw_gecos);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, pwent->pw_dir);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, pwent->pw_shell);
- X }
- X
- X return sp;
- X#else
- X fatal("password routines not implemented");
- X#endif
- X}
- X
- Xint
- Xdo_ggrent(which,gimme,arglast)
- Xint which;
- Xint gimme;
- Xint *arglast;
- X{
- X#ifdef I_GRP
- X register ARRAY *ary = stack;
- X register int sp = arglast[0];
- X register char **elem;
- X register STR *str;
- X struct group *getgrnam();
- X struct group *getgrgid();
- X struct group *getgrent();
- X struct group *grent;
- X unsigned long len;
- X
- X if (gimme != G_ARRAY) {
- X astore(ary, ++sp, str_static(&str_undef));
- X return sp;
- X }
- X
- X if (which == O_GGRNAM) {
- X char *name = str_get(ary->ary_array[sp+1]);
- X
- X grent = getgrnam(name);
- X }
- X else if (which == O_GGRGID) {
- X int gid = (int)str_gnum(ary->ary_array[sp+1]);
- X
- X grent = getgrgid(gid);
- X }
- X else
- X grent = getgrent();
- X
- X if (grent) {
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, grent->gr_name);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_set(str, grent->gr_passwd);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X str_numset(str, (double)grent->gr_gid);
- X (void)astore(ary, ++sp, str = str_static(&str_no));
- X for (elem = grent->gr_mem; *elem; elem++) {
- X str_cat(str, *elem);
- X if (elem[1])
- X str_ncat(str," ",1);
- X }
- X }
- X
- X return sp;
- X#else
- X fatal("group routines not implemented");
- X#endif
- X}
- X
- Xint
- Xdo_dirop(optype,stab,gimme,arglast)
- Xint optype;
- XSTAB *stab;
- Xint gimme;
- Xint *arglast;
- X{
- X#ifdef DIRENT
- X register ARRAY *ary = stack;
- X register STR **st = ary->ary_array;
- X register int sp = arglast[1];
- X register STIO *stio;
- X long along;
- X long telldir();
- X struct DIRENT *readdir();
- X register struct DIRENT *dp;
- X
- X if (!stab)
- X goto nope;
- X if (!(stio = stab_io(stab)))
- X stio = stab_io(stab) = stio_new();
- X if (!stio->dirp && optype != O_OPENDIR)
- X goto nope;
- X st[sp] = &str_yes;
- X switch (optype) {
- X case O_OPENDIR:
- X if (stio->dirp)
- X closedir(stio->dirp);
- X if (!(stio->dirp = opendir(str_get(st[sp+1]))))
- X goto nope;
- X break;
- X case O_READDIR:
- X if (gimme == G_ARRAY) {
- X --sp;
- X while (dp = readdir(stio->dirp)) {
- X#ifdef DIRNAMLEN
- X (void)astore(ary,++sp,
- X str_2static(str_make(dp->d_name,dp->d_namlen)));
- X#else
- X (void)astore(ary,++sp,
- X str_2static(str_make(dp->d_name,0)));
- X#endif
- X }
- X }
- X else {
- X if (!(dp = readdir(stio->dirp)))
- X goto nope;
- X st[sp] = str_static(&str_undef);
- X#ifdef DIRNAMLEN
- X str_nset(st[sp], dp->d_name, dp->d_namlen);
- X#else
- X str_set(st[sp], dp->d_name);
- X#endif
- X }
- X break;
- X case O_TELLDIR:
- X st[sp] = str_static(&str_undef);
- X str_numset(st[sp], (double)telldir(stio->dirp));
- X break;
- X case O_SEEKDIR:
- X st[sp] = str_static(&str_undef);
- X along = (long)str_gnum(st[sp+1]);
- X (void)seekdir(stio->dirp,along);
- X break;
- X case O_REWINDDIR:
- X st[sp] = str_static(&str_undef);
- X (void)rewinddir(stio->dirp);
- X break;
- X case O_CLOSEDIR:
- X st[sp] = str_static(&str_undef);
- X (void)closedir(stio->dirp);
- X stio->dirp = 0;
- X break;
- X }
- X return sp;
- X
- Xnope:
- X st[sp] = &str_undef;
- X return sp;
- X
- X#else
- X fatal("Unimplemented directory operation");
- X#endif
- X}
- X
- Xapply(type,arglast)
- Xint type;
- Xint *arglast;
- X{
- X register STR **st = stack->ary_array;
- X register int sp = arglast[1];
- X register int items = arglast[2] - sp;
- X register int val;
- X register int val2;
- X register int tot = 0;
- X char *s;
- X
- X#ifdef TAINT
- X for (st += ++sp; items--; st++)
- X tainted |= (*st)->str_tainted;
- X st = stack->ary_array;
- X sp = arglast[1];
- X items = arglast[2] - sp;
- X#endif
- X switch (type) {
- X case O_CHMOD:
- X#ifdef TAINT
- X taintproper("Insecure dependency in chmod");
- X#endif
- X if (--items > 0) {
- X tot = items;
- X val = (int)str_gnum(st[++sp]);
- X while (items--) {
- X if (chmod(str_get(st[++sp]),val))
- X tot--;
- X }
- X }
- X break;
- X case O_CHOWN:
- X#ifdef TAINT
- X taintproper("Insecure dependency in chown");
- X#endif
- X if (items > 2) {
- X items -= 2;
- X tot = items;
- X val = (int)str_gnum(st[++sp]);
- X val2 = (int)str_gnum(st[++sp]);
- X while (items--) {
- X if (chown(str_get(st[++sp]),val,val2))
- X tot--;
- X }
- X }
- X break;
- X case O_KILL:
- X#ifdef TAINT
- X taintproper("Insecure dependency in kill");
- X#endif
- X if (--items > 0) {
- X tot = items;
- X s = str_get(st[++sp]);
- X if (isupper(*s)) {
- X if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
- X s += 3;
- X if (!(val = whichsig(s)))
- X fatal("Unrecognized signal name \"%s\"",s);
- X }
- X else
- X val = (int)str_gnum(st[sp]);
- X if (val < 0) {
- X val = -val;
- X while (items--) {
- X int proc = (int)str_gnum(st[++sp]);
- X#ifdef KILLPG
- X if (killpg(proc,val)) /* BSD */
- X#else
- X if (kill(-proc,val)) /* SYSV */
- X#endif
- X tot--;
- X }
- X }
- X else {
- X while (items--) {
- X if (kill((int)(str_gnum(st[++sp])),val))
- X tot--;
- X }
- X }
- X }
- X break;
- X case O_UNLINK:
- X#ifdef TAINT
- X taintproper("Insecure dependency in unlink");
- X#endif
- X tot = items;
- X while (items--) {
- X s = str_get(st[++sp]);
- X if (euid || unsafe) {
- X if (UNLINK(s))
- X tot--;
- X }
- X else { /* don't let root wipe out directories without -U */
- X#ifdef SYMLINK
- X if (lstat(s,&statbuf) < 0 ||
- X#else
- X if (stat(s,&statbuf) < 0 ||
- X#endif
- X (statbuf.st_mode & S_IFMT) == S_IFDIR )
- X tot--;
- X else {
- X if (UNLINK(s))
- X tot--;
- X }
- X }
- X }
- X break;
- X case O_UTIME:
- X#ifdef TAINT
- X taintproper("Insecure dependency in utime");
- X#endif
- X if (items > 2) {
- X struct {
- X long atime,
- X mtime;
- X } utbuf;
- X
- X utbuf.atime = (long)str_gnum(st[++sp]); /* time accessed */
- X utbuf.mtime = (long)str_gnum(st[++sp]); /* time modified */
- X items -= 2;
- X#ifndef lint
- X tot = items;
- X while (items--) {
- X if (utime(str_get(st[++sp]),&utbuf))
- X tot--;
- X }
- X#endif
- X }
- X else
- X items = 0;
- X break;
- X }
- X return tot;
- X}
- X
- X/* Do the permissions allow some operation? Assumes statcache already set. */
- X
- Xint
- Xcando(bit, effective, statbufp)
- Xint bit;
- Xint effective;
- Xregister struct stat *statbufp;
- X{
- X if ((effective ? euid : uid) == 0) { /* root is special */
- X if (bit == S_IEXEC) {
- X if (statbufp->st_mode & 0111 ||
- X (statbufp->st_mode & S_IFMT) == S_IFDIR )
- X return TRUE;
- X }
- X else
- X return TRUE; /* root reads and writes anything */
- X return FALSE;
- X }
- X if (statbufp->st_uid == (effective ? euid : uid) ) {
- X if (statbufp->st_mode & bit)
- X return TRUE; /* ok as "user" */
- X }
- X else if (ingroup((int)statbufp->st_gid,effective)) {
- X if (statbufp->st_mode & bit >> 3)
- X return TRUE; /* ok as "group" */
- X }
- X else if (statbufp->st_mode & bit >> 6)
- X return TRUE; /* ok as "other" */
- X return FALSE;
- X}
- X
- Xint
- Xingroup(testgid,effective)
- Xint testgid;
- Xint effective;
- X{
- X if (testgid == (effective ? egid : gid))
- X return TRUE;
- X#ifdef GETGROUPS
- X#ifndef NGROUPS
- X#define NGROUPS 32
- X#endif
- X {
- X GIDTYPE gary[NGROUPS];
- X int anum;
- X
- X anum = getgroups(NGROUPS,gary);
- X while (--anum >= 0)
- X if (gary[anum] == testgid)
- X return TRUE;
- X }
- X#endif
- X return FALSE;
- X}
- !STUFFY!FUNK!
- echo Extracting regcomp.h
- sed >regcomp.h <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: regcomp.h,v 3.0 89/10/18 15:22:39 lwall Locked $
- X *
- X * $Log: regcomp.h,v $
- X * Revision 3.0 89/10/18 15:22:39 lwall
- X * 3.0 baseline
- X *
- X */
- X
- X/*
- X * The "internal use only" fields in regexp.h are present to pass info from
- X * compile to execute that permits the execute phase to run lots faster on
- X * simple cases. They are:
- X *
- X * regstart str that must begin a match; Nullch if none obvious
- X * reganch is the match anchored (at beginning-of-line only)?
- X * regmust string (pointer into program) that match must include, or NULL
- X * [regmust changed to STR* for bminstr()--law]
- X * regmlen length of regmust string
- X * [regmlen not used currently]
- X *
- X * Regstart and reganch permit very fast decisions on suitable starting points
- X * for a match, cutting down the work a lot. Regmust permits fast rejection
- X * of lines that cannot possibly match. The regmust tests are costly enough
- X * that regcomp() supplies a regmust only if the r.e. contains something
- X * potentially expensive (at present, the only such thing detected is * or +
- X * at the start of the r.e., which can involve a lot of backup). Regmlen is
- X * supplied because the test in regexec() needs it and regcomp() is computing
- X * it anyway.
- X * [regmust is now supplied always. The tests that use regmust have a
- X * heuristic that disables the test if it usually matches.]
- X *
- X * [In fact, we now use regmust in many cases to locate where the search
- X * starts in the string, so if regback is >= 0, the regmust search is never
- X * wasted effort. The regback variable says how many characters back from
- X * where regmust matched is the earliest possible start of the match.
- X * For instance, /[a-z].foo/ has a regmust of 'foo' and a regback of 2.]
- X */
- X
- X/*
- X * Structure for regexp "program". This is essentially a linear encoding
- X * of a nondeterministic finite-state machine (aka syntax charts or
- X * "railroad normal form" in parsing technology). Each node is an opcode
- X * plus a "next" pointer, possibly plus an operand. "Next" pointers of
- X * all nodes except BRANCH implement concatenation; a "next" pointer with
- X * a BRANCH on both ends of it is connecting two alternatives. (Here we
- X * have one of the subtle syntax dependencies: an individual BRANCH (as
- X * opposed to a collection of them) is never concatenated with anything
- X * because of operator precedence.) The operand of some types of node is
- X * a literal string; for others, it is a node leading into a sub-FSM. In
- X * particular, the operand of a BRANCH node is the first node of the branch.
- X * (NB this is *not* a tree structure: the tail of the branch connects
- X * to the thing following the set of BRANCHes.) The opcodes are:
- X */
- X
- X/* definition number opnd? meaning */
- X#define END 0 /* no End of program. */
- X#define BOL 1 /* no Match "" at beginning of line. */
- X#define EOL 2 /* no Match "" at end of line. */
- X#define ANY 3 /* no Match any one character. */
- X#define ANYOF 4 /* str Match any character in this string. */
- X#define ANYBUT 5 /* str Match any character not in this string. */
- X#define BRANCH 6 /* node Match this alternative, or the next... */
- X#define BACK 7 /* no Match "", "next" ptr points backward. */
- X#define EXACTLY 8 /* str Match this string (preceded by length). */
- X#define NOTHING 9 /* no Match empty string. */
- X#define STAR 10 /* node Match this (simple) thing 0 or more times. */
- X#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
- X#define ALNUM 12 /* no Match any alphanumeric character */
- X#define NALNUM 13 /* no Match any non-alphanumeric character */
- X#define BOUND 14 /* no Match "" at any word boundary */
- X#define NBOUND 15 /* no Match "" at any word non-boundary */
- X#define SPACE 16 /* no Match any whitespace character */
- X#define NSPACE 17 /* no Match any non-whitespace character */
- X#define DIGIT 18 /* no Match any numeric character */
- X#define NDIGIT 19 /* no Match any non-numeric character */
- X#define REF 20 /* no Match some already matched string */
- X#define OPEN 30 /* no Mark this point in input as start of #n. */
- X /* OPEN+1 is number 1, etc. */
- X#define CLOSE 40 /* no Analogous to OPEN. */
- X/* CLOSE must be last one! see regmust finder */
- X
- X/*
- X * Opcode notes:
- X *
- X * BRANCH The set of branches constituting a single choice are hooked
- X * together with their "next" pointers, since precedence prevents
- X * anything being concatenated to any individual branch. The
- X * "next" pointer of the last BRANCH in a choice points to the
- X * thing following the whole choice. This is also where the
- X * final "next" pointer of each individual branch points; each
- X * branch starts with the operand node of a BRANCH node.
- X *
- X * BACK Normal "next" pointers all implicitly point forward; BACK
- X * exists to make loop structures possible.
- X *
- X * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
- X * BRANCH structures using BACK. Simple cases (one character
- X * per match) are implemented with STAR and PLUS for speed
- X * and to minimize recursive plunges.
- X *
- X * OPEN,CLOSE ...are numbered at compile time.
- X */
- X
- X/* The following have no fixed length. */
- X#ifndef DOINIT
- Xextern char varies[];
- X#else
- Xchar varies[] = {BRANCH,BACK,STAR,PLUS,
- X REF+1,REF+2,REF+3,REF+4,REF+5,REF+6,REF+7,REF+8,REF+9,0};
- X#endif
- X
- X/* The following always have a length of 1. */
- X#ifndef DOINIT
- Xextern char simple[];
- X#else
- Xchar simple[] = {ANY,ANYOF,ANYBUT,ALNUM,NALNUM,SPACE,NSPACE,DIGIT,NDIGIT,0};
- X#endif
- X
- XEXT char regdummy;
- X
- X/*
- X * A node is one char of opcode followed by two chars of "next" pointer.
- X * "Next" pointers are stored as two 8-bit pieces, high order first. The
- X * value is a positive offset from the opcode of the node containing it.
- X * An operand, if any, simply follows the node. (Note that much of the
- X * code generation knows about this implicit relationship.)
- X *
- X * Using two bytes for the "next" pointer is vast overkill for most things,
- X * but allows patterns to get big without disasters.
- X *
- X * [If REGALIGN is defined, the "next" pointer is always aligned on an even
- X * boundary, and reads the offset directly as a short. Also, there is no
- X * special test to reverse the sign of BACK pointers since the offset is
- X * stored negative.]
- X */
- X
- X#ifndef gould
- X#ifndef cray
- X#define REGALIGN
- X#endif
- X#endif
- X
- X#define OP(p) (*(p))
- X
- X#ifndef lint
- X#ifdef REGALIGN
- X#define NEXT(p) (*(short*)(p+1))
- X#else
- X#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
- X#endif
- X#else /* lint */
- X#define NEXT(p) 0
- X#endif /* lint */
- X
- X#define OPERAND(p) ((p) + 3)
- X
- X#ifdef REGALIGN
- X#define NEXTOPER(p) ((p) + 4)
- X#else
- X#define NEXTOPER(p) ((p) + 3)
- X#endif
- X
- X#define MAGIC 0234
- X
- X/*
- X * Utility definitions.
- X */
- X#ifndef lint
- X#ifndef CHARBITS
- X#define UCHARAT(p) ((int)*(unsigned char *)(p))
- X#else
- X#define UCHARAT(p) ((int)*(p)&CHARBITS)
- X#endif
- X#else /* lint */
- X#define UCHARAT(p) regdummy
- X#endif /* lint */
- X
- X#define FAIL(m) fatal("/%s/: %s",regprecomp,m)
- X
- Xchar *regnext();
- X#ifdef DEBUGGING
- Xvoid regdump();
- Xchar *regprop();
- X#endif
- X
- !STUFFY!FUNK!
- echo ""
- echo "End of kit 7 (of 24)"
- cat /dev/null >kit7isdone
- run=''
- config=''
- for iskit in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24; do
- if test -f kit${iskit}isdone; then
- run="$run $iskit"
- else
- todo="$todo $iskit"
- fi
- done
- case $todo in
- '')
- echo "You have run all your kits. Please read README and then type Configure."
- chmod 755 Configure
- ;;
- *) echo "You have run$run."
- echo "You still need to run$todo."
- ;;
- esac
- : Someone might mail this, so...
- exit
-
-