lwall@jato.Jpl.Nasa.Gov (Larry Wall) (09/03/89)
#! /bin/sh # Make a new directory for the perl sources, cd to it, and run kits 1 # thru 23 through sh. When all 23 kits have been run, read README. echo "This is perl 3.0 kit 8 (of 23). If kit 8 is complete, the line" echo '"'"End of kit 8 (of 23)"'" 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: arg.c,v 2.0.1.6 88/11/18 23:44:15 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: arg.c,v $ 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 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 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 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 } 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 } 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 } 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 } 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 } 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->ofp = stio->ifp = 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->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 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 >= 0; 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 if (arg->arg_type == O_LSTAT) X i = lstat(str_get(statname),&statcache); X else 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,str_nmake((double)statcache.st_dev)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_ino)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_mode)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_nlink)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_uid)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_gid)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_rdev)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_size)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_atime)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_mtime)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_ctime)); X#ifdef STATBLOCKS X (void)astore(ary,++sp,str_nmake((double)statcache.st_blksize)); X (void)astore(ary,++sp,str_nmake((double)statcache.st_blocks)); X#else X (void)astore(ary,++sp,str_make("",0)); X (void)astore(ary,++sp,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 (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 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 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_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 *gethostbynumber(); 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 hent = gethostent(); 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 str_numset(str, (double)ntohs(sent->s_port)); 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 X X#ifdef SOCKET 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#endif 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 if (socketpair(domain,type,protocol,fd) < 0) X return FALSE; 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 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) || !(val = whichsig(s))) X val = (int)str_gnum(st[sp]); X if (val < 0) { X val = -val; X while (items--) { X#ifdef KILLPG X if (killpg((int)(str_gnum(st[++sp])),val)) /* BSD */ X#else X if (kill(-(int)(str_gnum(st[++sp])),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(gid,effective) Xint gid; Xint effective; X{ X if (gid == (effective ? getegid() : getgid())) 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] == gid) X return TRUE; X } X#endif X return FALSE; X} !STUFFY!FUNK! echo Extracting config.h.SH sed >config.h.SH <<'!STUFFY!FUNK!' -e 's/X//' Xcase $CONFIG in X'') X if test ! -f config.sh; then X ln ../config.sh . || \ X ln ../../config.sh . || \ X ln ../../../config.sh . || \ X (echo "Can't find config.sh."; exit 1) X echo "Using config.sh from above..." X fi X . ./config.sh X ;; Xesac Xecho "Extracting config.h (with variable substitutions)" Xsed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#undef!' X/* config.h X * This file was produced by running the config.h.SH script, which X * gets its values from config.sh, which is generally produced by X * running Configure. X * X * Feel free to modify any of this as the need arises. Note, however, X * that running config.h.SH again will wipe out any changes you've made. X * For a more permanent change edit config.sh and rerun config.h.SH. X */ X X X/* EUNICE: X * This symbol, if defined, indicates that the program is being compiled X * under the EUNICE package under VMS. The program will need to handle X * things like files that don't go away the first time you unlink them, X * due to version numbering. It will also need to compensate for lack X * of a respectable link() command. X */ X/* VMS: X * This symbol, if defined, indicates that the program is running under X * VMS. It is currently only set in conjunction with the EUNICE symbol. X */ X#$d_eunice EUNICE /**/ X#$d_eunice VMS /**/ X X/* BIN: X * This symbol holds the name of the directory in which the user wants X * to put publicly executable images for the package in question. It X * is most often a local directory such as /usr/local/bin. X */ X#define BIN "$bin" /**/ X X/* BYTEORDER: X * This symbol contains an encoding of the order of bytes in a long. X * Usual values (in octal) are 01234, 04321, 02143, 03412... X */ X#define BYTEORDER 0$byteorder /**/ X X/* CPPSTDIN: X * This symbol contains the first part of the string which will invoke X * the C preprocessor on the standard input and produce to standard X * output. Typical value of "cc -E" or "/lib/cpp". X */ X/* CPPMINUS: X * This symbol contains the second part of the string which will invoke X * the C preprocessor on the standard input and produce to standard X * output. This symbol will have the value "-" if CPPSTDIN needs a minus X * to specify standard input, otherwise the value is "". X */ X#define CPPSTDIN "$cppstdin" X#define CPPMINUS "$cppminus" X X/* BCOPY: X * This symbol, if defined, indicates that the bcopy routine is available X * to copy blocks of memory. Otherwise you should probably use memcpy(). X */ X#$d_bcopy BCOPY /**/ X X/* CHARSPRINTF: X * This symbol is defined if this system declares "char *sprintf()" in X * stdio.h. The trend seems to be to declare it as "int sprintf()". It X * is up to the package author to declare sprintf correctly based on the X * symbol. X */ X#$d_charsprf CHARSPRINTF /**/ X X/* CRYPT: X * This symbol, if defined, indicates that the crypt routine is available X * to encrypt passwords and the like. X */ X#$d_crypt CRYPT /**/ X X/* DOSUID: X * This symbol, if defined, indicates that the C program should X * check the script that it is executing for setuid/setgid bits, and X * attempt to emulate setuid/setgid on systems that have disabled X * setuid #! scripts because the kernel can't do it securely. X * It is up to the package designer to make sure that this emulation X * is done securely. Among other things, it should do an fstat on X * the script it just opened to make sure it really is a setuid/setgid X * script, it should make sure the arguments passed correspond exactly X * to the argument on the #! line, and it should not trust any X * subprocesses to which it must pass the filename rather than the X * file descriptor of the script to be executed. X */ X#$d_dosuid DOSUID /**/ X X/* FCHMOD: X * This symbol, if defined, indicates that the fchmod routine is available X * to change mode of opened files. If unavailable, use chmod(). X */ X#$d_fchmod FCHMOD /**/ X X/* FCHOWN: X * This symbol, if defined, indicates that the fchown routine is available X * to change ownership of opened files. If unavailable, use chown(). X */ X#$d_fchown FCHOWN /**/ X X/* FCNTL: X * This symbol, if defined, indicates to the C program that it should X * include fcntl.h. X */ X#$d_fcntl FCNTL /**/ X X/* FLOCK: X * This symbol, if defined, indicates that the flock() routine is X * available to do file locking. X */ X#$d_flock FLOCK /**/ X X/* GETGROUPS: X * This symbol, if defined, indicates that the getgroups() routine is X * available to get the list of process groups. If unavailable, multiple X * groups are probably not supported. X */ X#$d_getgrps GETGROUPS /**/ X X/* GETPGRP: X * This symbol, if defined, indicates that the getpgrp() routine is X * available to get the current process group. X */ X#$d_getpgrp GETPGRP /**/ X X/* GETPRIORITY: X * This symbol, if defined, indicates that the getpriority() routine is X * available to get a process's priority. X */ X#$d_getprior GETPRIORITY /**/ X X/* HTONS: X * This symbol, if defined, indicates that the htons routine (and friends) X * are available to do network order byte swapping. X */ X/* HTONL: X * This symbol, if defined, indicates that the htonl routine (and friends) X * are available to do network order byte swapping. X */ X/* NTOHS: X * This symbol, if defined, indicates that the ntohs routine (and friends) X * are available to do network order byte swapping. X */ X/* NTOHL: X * This symbol, if defined, indicates that the ntohl routine (and friends) X * are available to do network order byte swapping. X */ X#$d_htonl HTONS /**/ X#$d_htonl HTONL /**/ X#$d_htonl NTOHS /**/ X#$d_htonl NTOHL /**/ X X/* index: X * This preprocessor symbol is defined, along with rindex, if the system X * uses the strchr and strrchr routines instead. X */ X/* rindex: X * This preprocessor symbol is defined, along with index, if the system X * uses the strchr and strrchr routines instead. X */ X#$d_index index strchr /* cultural */ X#$d_index rindex strrchr /* differences? */ X X/* IOCTL: X * This symbol, if defined, indicates that sys/ioctl.h exists and should X * be included. X */ X#$d_ioctl IOCTL /**/ X X/* KILLPG: X * This symbol, if defined, indicates that the killpg routine is available X * to kill process groups. If unavailable, you probably should use kill X * with a negative process number. X */ X#$d_killpg KILLPG /**/ X X/* MEMCPY: X * This symbol, if defined, indicates that the memcpy routine is available X * to copy blocks of memory. Otherwise you should probably use bcopy(). X * If neither is defined, roll your own. X */ X#$d_memcpy MEMCPY /**/ X X/* MKDIR: X * This symbol, if defined, indicates that the mkdir routine is available X * to create directories. Otherwise you should fork off a new process to X * exec /bin/mkdir. X */ X#$d_mkdir MKDIR /**/ X X/* NDBM: X * This symbol, if defined, indicates that ndbm.h exists and should X * be included. X */ X#$d_ndbm NDBM /**/ X X/* ODBM: X * This symbol, if defined, indicates that dbm.h exists and should X * be included. X */ X#$d_odbm ODBM /**/ X X/* RENAME: X * This symbol, if defined, indicates that the rename routine is available X * to rename files. Otherwise you should do the unlink(), link(), unlink() X * trick. X */ X#$d_rename RENAME /**/ X X/* RMDIR: X * This symbol, if defined, indicates that the rmdir routine is available X * to remove directories. Otherwise you should fork off a new process to X * exec /bin/rmdir. X */ X#$d_rmdir RMDIR /**/ X X/* SETEGID: X * This symbol, if defined, indicates that the setegid routine is available X * to change the effective gid of the current program. X */ X#$d_setegid SETEGID /**/ X X/* SETEUID: X * This symbol, if defined, indicates that the seteuid routine is available X * to change the effective uid of the current program. X */ X#$d_seteuid SETEUID /**/ X X/* SETPGRP: X * This symbol, if defined, indicates that the setpgrp() routine is X * available to set the current process group. X */ X#$d_setpgrp SETPGRP /**/ X X/* SETPRIORITY: X * This symbol, if defined, indicates that the setpriority() routine is X * available to set a process's priority. X */ X#$d_setprior SETPRIORITY /**/ X X/* SETREGID: X * This symbol, if defined, indicates that the setregid routine is available X * to change the real and effective gid of the current program. X */ X#$d_setregid SETREGID /**/ X X/* SETREUID: X * This symbol, if defined, indicates that the setreuid routine is available X * to change the real and effective uid of the current program. X */ X#$d_setreuid SETREUID /**/ X X/* SETRGID: X * This symbol, if defined, indicates that the setrgid routine is available X * to change the real gid of the current program. X */ X#$d_setrgid SETRGID /**/ X X/* SETRUID: X * This symbol, if defined, indicates that the setruid routine is available X * to change the real uid of the current program. X */ X#$d_setruid SETRUID /**/ X X/* SOCKET: X * This symbol, if defined, indicates that the BSD socket interface is X * supported. X */ X/* OLDSOCKET: X * This symbol, if defined, indicates that the 4.1c BSD socket interface X * is supported instead of the 4.2/4.3 BSD socket interface. X */ X#$d_socket SOCKET /**/ X X#$d_oldsock OLDSOCKET /**/ X X/* STATBLOCKS: X * This symbol is defined if this system has a stat structure declaring X * st_blksize and st_blocks. X */ X#$d_statblks STATBLOCKS /**/ X X/* STDSTDIO: X * This symbol is defined if this system has a FILE structure declaring X * _ptr and _cnt in stdio.h. X */ X#$d_stdstdio STDSTDIO /**/ X X/* STRUCTCOPY: X * This symbol, if defined, indicates that this C compiler knows how X * to copy structures. If undefined, you'll need to use a block copy X * routine of some sort instead. X */ X#$d_strctcpy STRUCTCOPY /**/ X X/* SYMLINK: X * This symbol, if defined, indicates that the symlink routine is available X * to create symbolic links. X */ X#$d_symlink SYMLINK /**/ X X/* TMINSYS: X * This symbol is defined if this system declares "struct tm" in X * in <sys/time.h> rather than <time.h>. We can't just say X * -I/usr/include/sys because some systems have both time files, and X * the -I trick gets the wrong one. X */ X/* I_SYSTIME: X * This symbol is defined if this system has the file <sys/time.h>. X */ X#$d_tminsys TMINSYS /**/ X#$i_systime I_SYSTIME /**/ X X/* VARARGS: X * This symbol, if defined, indicates to the C program that it should X * include varargs.h. X */ X#$d_varargs VARARGS /**/ X X/* vfork: X * This symbol, if defined, remaps the vfork routine to fork if the X * vfork() routine isn't supported here. X */ X#$d_vfork vfork fork /**/ X X/* VOIDSIG: X * This symbol is defined if this system declares "void (*signal())()" in X * signal.h. The old way was to declare it as "int (*signal())()". It X * is up to the package author to declare things correctly based on the X * symbol. X */ X#$d_voidsig VOIDSIG /**/ X X/* VPRINTF: X * This symbol, if defined, indicates that the vprintf routine is available X * to printf with a pointer to an argument list. If unavailable, you X * may need to write your own, probably in terms of _doprnt(). X */ X#$d_vprintf VPRINTF /**/ X X/* GIDTYPE: X * This symbol has a value like gid_t, int, ushort, or whatever type is X * used to declare group ids in the kernel. X */ X#define GIDTYPE $gidtype /**/ X X/* INTSIZE: X * This symbol contains the size of an int, so that the C preprocessor X * can make decisions based on it. X */ X#define INTSIZE $intsize /**/ X X/* RANDBITS: X * This symbol contains the number of bits of random number the rand() X * function produces. Usual values are 15, 16, and 31. X */ X#define RANDBITS $randbits /**/ X X/* SIG_NAME: X * This symbol contains an list of signal names in order. X */ X#define SIG_NAME "`echo $sig_name | sed 's/ /","/g'`" /**/ X X/* STDCHAR: X * This symbol is defined to be the type of char used in stdio.h. X * It has the values "unsigned char" or "char". X */ X#define STDCHAR $stdchar /**/ X X/* UIDTYPE: X * This symbol has a value like uid_t, int, ushort, or whatever type is X * used to declare user ids in the kernel. X */ X#define UIDTYPE $uidtype /**/ X X/* VOIDFLAGS: X * This symbol indicates how much support of the void type is given by this X * compiler. What various bits mean: X * X * 1 = supports declaration of void X * 2 = supports arrays of pointers to functions returning void X * 4 = supports comparisons between pointers to void functions and X * addresses of void functions X * X * The package designer should define VOIDUSED to indicate the requirements X * of the package. This can be done either by #defining VOIDUSED before X * including config.h, or by defining defvoidused in Myinit.U. If the X * latter approach is taken, only those flags will be tested. If the X * level of void support necessary is not present, defines void to int. X */ X#ifndef VOIDUSED X#define VOIDUSED $defvoidused X#endif X#define VOIDFLAGS $voidflags X#if (VOIDFLAGS & VOIDUSED) != VOIDUSED X#$define void int /* is void to be avoided? */ X#$define M_VOID /* Xenix strikes again */ X#endif X X/* PRIVLIB: X * This symbol contains the name of the private library for this package. X * The library is private in the sense that it needn't be in anyone's X * execution path, but it should be accessible by the world. The program X * should be prepared to do ~ expansion. X */ X#define PRIVLIB "$privlib" /**/ X X!GROK!THIS! !STUFFY!FUNK! echo Extracting hash.h sed >hash.h <<'!STUFFY!FUNK!' -e 's/X//' X/* $Header: hash.h,v 2.0 88/06/05 00:09:08 root Exp $ 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: hash.h,v $ X */ X X#define FILLPCT 80 /* don't make greater than 99 */ X#define DBM_CACHE_MAX 63 /* cache 64 entries for dbm file */ X /* (resident array acts as a write-thru cache)*/ X X#define COEFFSIZE (16 * 8) /* size of array below */ X#ifdef DOINIT Xchar coeff[] = { X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1, X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1, X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1, X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1, X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1, X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1, X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1, X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1}; X#else Xextern char coeff[]; X#endif X Xtypedef struct hentry HENT; X Xstruct hentry { X HENT *hent_next; X char *hent_key; X STR *hent_val; X int hent_hash; X int hent_klen; X}; X Xstruct htbl { X HENT **tbl_array; X int tbl_max; /* subscript of last element of tbl_array */ X int tbl_dosplit; /* how full to get before splitting */ X int tbl_fill; /* how full tbl_array currently is */ X int tbl_riter; /* current root of iterator */ X HENT *tbl_eiter; /* current entry of iterator */ X SPAT *tbl_spatroot; /* list of spats for this package */ X#ifdef SOME_DBM X#ifdef NDBM X DBM *tbl_dbm; X#else X int tbl_dbm; X#endif X#endif X unsigned char tbl_coeffsize; /* is 0 for symbol tables */ X}; X XSTR *hfetch(); Xbool hstore(); XSTR *hdelete(); XHASH *hnew(); Xvoid hclear(); Xvoid hentfree(); Xint hiterinit(); XHENT *hiternext(); Xchar *hiterkey(); XSTR *hiterval(); Xbool hdbmopen(); Xvoid hdbmclose(); Xbool hdbmstore(); !STUFFY!FUNK! echo "" echo "End of kit 8 (of 23)" cat /dev/null >kit8isdone 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; 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