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