perl 3.0 beta kit [8/23]
Larry Wall
lwall at jato.Jpl.Nasa.Gov
Sun Sep 3 11:55:11 AEST 1989
#! /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
More information about the Alt.sources
mailing list