home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume35
/
zsh
/
part08
< prev
next >
Wrap
Text File
|
1993-02-20
|
57KB
|
2,470 lines
Newsgroups: comp.sources.misc
From: zsh-list@cs.uow.edu.au (The Zsh Mailing List)
Subject: v35i058: zsh - The Z Shell, version 2.3.1, Part08/22
Message-ID: <1993Feb20.212307.28579@sparky.imd.sterling.com>
X-Md4-Signature: 3be6b34a9bb71c4ba8cbe65a22f1d0fc
Date: Sat, 20 Feb 1993 21:23:07 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: zsh-list@cs.uow.edu.au (The Zsh Mailing List)
Posting-number: Volume 35, Issue 58
Archive-name: zsh/part08
Environment: UNIX
Supersedes: zsh2.2: Volume 29, Issue 97-113
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents: src/builtin.c.01 src/config.h.sample
# Wrapped by mattson@odin on Sat Feb 6 14:41:52 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 8 (of 22)."'
if test -f 'src/builtin.c.01' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/builtin.c.01'\"
else
echo shar: Extracting \"'src/builtin.c.01'\" \(49195 characters\)
sed "s/^X//" >'src/builtin.c.01' <<'END_OF_FILE'
X/*
X *
X * builtin.c - builtin commands
X *
X * This file is part of zsh, the Z shell.
X *
X * This software is Copyright 1992 by Paul Falstad
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made.
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk.
X *
X */
X
X#include "zsh.h"
X#include <sys/errno.h>
X
X#define makecond() allocnode(N_COND)
X
X/* builtin flags */
X
X#define BINF_PLUSOPTS 1 /* +xyz legal */
X#define BINF_R 2 /* this is r (fc -e -) */
X#define BINF_PRINTOPTS 4
X#define BINF_SETOPTS 8
X#define BINF_FCOPTS 16
X#define BINF_TYPEOPT 32
X#define BINF_TYPEOPTS (BINF_TYPEOPT|BINF_PLUSOPTS)
X#define BINF_ECHOPTS 64
X
X/* builtin funcs */
X
X#define BIN_TYPESET 0
X#define BIN_BG 1
X#define BIN_FG 2
X#define BIN_JOBS 3
X#define BIN_WAIT 4
X#define BIN_DISOWN 5
X#define BIN_BREAK 6
X#define BIN_CONTINUE 7
X#define BIN_EXIT 8
X#define BIN_RETURN 9
X#define BIN_SHIFT 10
X#define BIN_CD 11
X#define BIN_POPD 12
X#define BIN_PUSHD 13
X#define BIN_PRINT 14
X#define BIN_EVAL 15
X#define BIN_SCHED 16
X#define BIN_FC 17
X#define BIN_PUSHLINE 18
X#define BIN_LOGOUT 19
X#define BIN_BUILTIN 20
X#define BIN_TEST 21
X#define BIN_BRACKET 22
X
Xstruct bincmd {
X char *name;
X int (*handlerfunc) DCLPROTO((char *,char **,char *,int));
X int minargs; /* min # of args */
X int maxargs; /* max # of args, or -1 for no limit */
X int flags; /* BINF_flags (see above) */
X int funcid; /* xbins (see above) for overloaded handlerfuncs */
X char *optstr; /* string of legal options */
X char *defopts; /* options set by default for overloaded handlerfuncs */
X };
X
X/* structure for foo=bar assignments */
X
Xstruct asgment {
X struct asgment *next;
X char *name,*value;
X };
X
Xstatic char *auxdata;
Xstatic int auxlen;
Xstatic int showflag = 0,showflag2 = 0;
X
X#define NULLBINCMD ((int (*) DCLPROTO((char *,char **,char *,int))) 0)
X
Xstruct bincmd builtins[] = {
X {"[",bin_test,0,-1,0,BIN_BRACKET,NULL,NULL},
X {".",bin_dot,1,-1,0,0,NULL,NULL},
X {":",bin_colon,0,-1,0,0,NULL,NULL},
X {"alias",bin_alias,0,-1,0,0,"ga",NULL},
X {"autoload",bin_typeset,0,-1,BINF_TYPEOPTS,0,"tx","fu"},
X {"bg",bin_fg,0,-1,0,BIN_BG,NULL,NULL},
X {"bindkey",bin_bindkey,0,-1,0,0,"asvemdrl",NULL},
X {"break",bin_break,0,1,0,BIN_BREAK,NULL,NULL},
X {"builtin",NULLBINCMD,0,0,0,BIN_BUILTIN,NULL,NULL},
X {"bye",bin_break,0,1,0,BIN_EXIT,NULL,NULL},
X {"cd",bin_cd,0,2,0,BIN_CD,NULL,NULL},
X {"chdir",bin_cd,0,2,0,BIN_CD,NULL,NULL},
X {"compctl",bin_compctl,0,-1,0,0,NULL,NULL},
X {"continue",bin_break,0,1,0,BIN_CONTINUE,NULL,NULL},
X {"declare",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZfilrtux",NULL},
X {"dirs",bin_dirs,0,-1,0,0,"v",NULL},
X {"disable",bin_disable,1,-1,0,0,NULL,NULL},
X {"disown",bin_fg,1,-1,0,BIN_DISOWN,NULL,NULL},
X {"echo",bin_print,0,-1,BINF_PRINTOPTS|BINF_ECHOPTS,BIN_PRINT,"n","-"},
X {"echotc",bin_echotc,1,-1,0,0,NULL,NULL},
X {"enable",bin_enable,1,-1,0,0,NULL,NULL},
X {"eval",bin_eval,0,-1,0,BIN_EVAL,NULL,NULL},
X {"exit",bin_break,0,1,0,BIN_EXIT,NULL,NULL},
X {"export",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZfilrtu","x"},
X {"false",bin_let,0,0,0,0,NULL,NULL},
X {"fc",bin_fc,0,-1,BINF_FCOPTS,BIN_FC,"nlreIRWAdDfE",NULL},
X {"fg",bin_fg,0,-1,0,BIN_FG,NULL,NULL},
X {"functions",bin_typeset,0,-1,BINF_TYPEOPTS,0,"tu","f"},
X {"getln",bin_read,0,-1,0,0,NULL,"zr"},
X {"getopts",bin_getopts,2,-1,0,0,NULL,NULL},
X {"hash",bin_hash,2,2,0,0,"r",NULL},
X {"history",bin_fc,0,-1,0,BIN_FC,"nrdDfE","l"},
X {"integer",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZlrtux","i"},
X {"jobs",bin_fg,0,-1,0,BIN_JOBS,"lpZ",NULL},
X {"kill",bin_kill,0,-1,0,0,NULL,NULL},
X {"let",bin_let,1,-1,0,0,NULL,NULL},
X {"limit",bin_limit,0,-1,0,0,"sh",NULL},
X {"local",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZfilrtux",NULL},
X {"log",bin_log,0,0,0,0,NULL,NULL},
X {"logout",bin_break,0,1,0,BIN_LOGOUT,NULL,NULL},
X {"popd",bin_cd,0,2,0,BIN_POPD,NULL,NULL},
X {"print",bin_print,0,-1,BINF_PRINTOPTS,BIN_PRINT,"RDPnrslzNu0123456789p-",NULL},
X {"pushd",bin_cd,0,2,0,BIN_PUSHD,NULL,NULL},
X {"pushln",bin_print,0,-1,BINF_PRINTOPTS,BIN_PRINT,NULL,"-nz"},
X {"pwd",bin_pwd,0,0,0,0,NULL,NULL},
X {"r",bin_fc,0,-1,BINF_R,BIN_FC,"nrl",NULL},
X {"read",bin_read,0,-1,0,0,"rzu0123456789p",NULL},
X {"readonly",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZfiltux","r"},
X {"rehash",bin_rehash,0,0,0,0,"f",NULL},
X {"return",bin_break,0,1,0,BIN_RETURN,NULL,NULL},
X {"sched",bin_sched,0,-1,0,0,NULL,NULL},
X {"set",bin_set,0,-1,BINF_SETOPTS|BINF_PLUSOPTS,0,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZaefghjklmnosuvwxy",NULL},
X {"setopt",bin_setopt,0,-1,BINF_PLUSOPTS,0,"0123456789BCDEFGHIJKLMNOPQRSTUVWXYZaefghjklmnosuvwxy",NULL},
X {"shift",bin_break,0,1,0,BIN_SHIFT,NULL,NULL},
X {"source",bin_dot,1,-1,0,0,NULL,NULL},
X {"suspend",bin_suspend,0,0,0,0,"f",NULL},
X {"test",bin_test,0,-1,0,BIN_TEST,NULL,NULL},
X {"ttyctl",bin_ttyctl,0,0,0,0,"fu",NULL},
X {"times",bin_times,0,0,0,0,NULL,NULL},
X {"trap",bin_trap,0,-1,0,0,NULL,NULL},
X {"true",bin_colon,0,0,0,0,NULL,NULL},
X {"type",bin_whence,0,-1,0,0,"pfa","v"},
X {"typeset",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZfilrtux",NULL},
X {"ulimit",bin_ulimit,0,1,0,0,"HSacdfmnt",NULL},
X {"umask",bin_umask,0,1,0,0,NULL,NULL},
X {"unalias",bin_unalias,1,-1,0,0,NULL,NULL},
X {"unfunction",bin_unhash,1,-1,0,0,NULL,NULL},
X {"unhash",bin_unhash,1,-1,0,0,NULL,NULL},
X {"unlimit",bin_unlimit,0,-1,0,0,"h",NULL},
X {"unset",bin_unset,1,-1,0,0,NULL,NULL},
X {"unsetopt",bin_setopt,0,-1,BINF_PLUSOPTS,1,"0123456789BCDEFGHIJKLMNOPQRSTUWXYZabefghjklmnosuvwxy",NULL},
X {"vared",bin_vared,1,1,0,0,NULL,NULL},
X {"wait",bin_fg,0,-1,0,BIN_WAIT,NULL,NULL},
X {"whence",bin_whence,0,-1,0,0,"pvcfa",NULL},
X {"which",bin_whence,0,-1,0,0,"pa","c"},
X {NULL,NULLBINCMD,0,0,0,0,NULL,NULL}
X };
X
X/* print options */
X
Xstatic void prtopt()
X{
Xstruct option *opp;
X
X if (isset(KSHOPTIONPRINT)) {
X printf("Current option settings\n");
X for (opp = optns; opp->name; opp++)
X printf("%-20s%s\n", opp->name, isset(opp->id) ? "on" : "off");
X } else
X for (opp = optns; opp->name; opp++)
X if (isset(opp->id))
X puts(opp->name);
X}
X
X/* add builtins to the command hash table */
X
Xvoid addbuiltins() /**/
X{
Xstruct cmdnam *c;
Xstruct bincmd *b;
Xint t0;
X
X for (t0 = 0, b = builtins; b->name; b++,t0++)
X {
X c = (Cmdnam) zcalloc(sizeof *c);
X c->type = BUILTIN;
X c->u.binnum = t0;
X addhperm(b->name,c,cmdnamtab,freecmdnam);
X }
X}
X
X/* enable */
X
Xint bin_enable(name,argv,ops,whocares) /**/
Xchar *name;char **argv;char *ops;int whocares;
X{
Xstruct cmdnam *c;
Xstruct bincmd *b;
Xint t0,ret = 0;
X
X for (; *argv; argv++)
X {
X for (t0 = 0, b = builtins; b->name; b++,t0++)
X if (!strcmp(*argv,b->name))
X break;
X if (!b->name)
X {
X zerrnam(name,"no such builtin: %s",*argv,0);
X ret = 1;
X }
X else
X {
X c = (Cmdnam) zcalloc(sizeof *c);
X c->type = BUILTIN;
X c->u.binnum = t0;
X addhperm(b->name,c,cmdnamtab,freecmdnam);
X }
X }
X return ret;
X}
X
X/* :, true */
X
Xint bin_colon(name,argv,ops,whocares) /**/
Xchar *name;char **argv;char *ops;int whocares;
X{
X return 0;
X}
X
X/* break, bye, continue, exit, logout, return, shift */
X
Xint bin_break(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
Xint num = -1;
X
X if (*argv)
X num = matheval(*argv);
X if ((func == BIN_BREAK || func == BIN_CONTINUE) && !loops)
X {
X if (func == BIN_CONTINUE)
X zerrnam(name,"not in loop",NULL,0);
X return 1;
X }
X switch (func)
X {
X case BIN_CONTINUE:
X contflag = 1;
X case BIN_BREAK:
X breaks = (num == -1) ? 1 : num;
X if (breaks > loops) breaks = loops;
X break;
X case BIN_LOGOUT:
X if (!islogin)
X {
X zerrnam(name,"not login shell",NULL,0);
X return 1;
X }
X case BIN_EXIT:
X zexit((num == -1) ? lastval : num);
X break;
X case BIN_RETURN:
X retflag = 1;
X breaks = loops;
X return lastval = (num == -1) ? lastval : num;
X case BIN_SHIFT:
X {
X char **s;
X
X if (num == -1)
X num = 1;
X if (num > arrlen(pparams))
X num = arrlen(pparams);
X permalloc();
X s = arrdup(pparams+num);
X heapalloc();
X freearray(pparams);
X pparams = s;
X break;
X }
X }
X return 0;
X}
X
X/* bg, disown, fg, jobs, wait */
X
Xint bin_fg(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
Xint job,lng,firstjob = -1,retval = 0;
X
X if (ops['Z']) { if (*argv) strcpy(hackzero,*argv); return 0; }
X lng = (ops['l']) ? 1 : (ops['p']) ? 2 : 0;
X if ((func == BIN_FG || func == BIN_BG) && !jobbing)
X {
X zerrnam(name,"no job control in this shell.",NULL,0);
X return 1;
X }
X if (unset(NOTIFY)) scanjobs();
X if (curjob != -1 && !(jobtab[curjob].stat & STAT_INUSE))
X {
X curjob = prevjob; setprevjob();
X if (curjob != -1 && !(jobtab[curjob].stat & STAT_INUSE))
X curjob = prevjob; setprevjob();
X }
X if (func == BIN_JOBS)
X stopmsg = 2;
X if (!*argv)
X if (func == BIN_FG || func == BIN_BG)
X {
X if (curjob == -1 || curjob == thisjob)
X {
X zerrnam(name,"no current job",NULL,0);
X return 1;
X }
X firstjob = curjob;
X }
X else if (func == BIN_JOBS)
X {
X for (job = 0; job != MAXJOB; job++)
X if (job != thisjob && jobtab[job].stat)
X printjob(job+jobtab,lng);
X return 0;
X }
X else
X {
X for (job = 0; job != MAXJOB; job++)
X if (job != thisjob && jobtab[job].stat)
X waitjob(job);
X return lastval;
X }
X for (; (firstjob != -1) || *argv; ( void ) (*argv && argv++))
X {
X int stopped,ocj = thisjob;
X
X if (func == BIN_WAIT && isanum(*argv)) {
X waitforpid((long) atoi(*argv));
X retval = lastval;
X thisjob = ocj;
X continue;
X }
X job = (*argv) ? getjob(*argv,name) : firstjob;
X firstjob = -1;
X if (job == -1)
X break;
X if (!(jobtab[job].stat & STAT_INUSE))
X {
X zerrnam(name,"no such job: %d",0,job);
X return 1;
X }
X switch (func)
X {
X case BIN_FG:
X case BIN_BG:
X if (stopped = (jobtab[job].stat & STAT_STOPPED))
X makerunning(jobtab+job);
X else if (func == BIN_BG)
X {
X zerrnam(name,"job already in background",NULL,0);
X thisjob = ocj;
X return 1;
X }
X if (curjob == job)
X {
X curjob = prevjob;
X prevjob = (func == BIN_BG) ? -1 : job;
X }
X if (prevjob == job)
X prevjob = -1;
X if (prevjob == -1)
X setprevjob();
X if (curjob == -1)
X {
X curjob = prevjob;
X setprevjob();
X }
X printjob(jobtab+job,(stopped) ? -1 : 0);
X if (func == BIN_FG)
X {
X thisjob = job;
X if (strcmp(jobtab[job].pwd,pwd))
X {
X printf("(pwd : ");
X printdir(jobtab[job].pwd);
X printf(")\n");
X }
X fflush(stdout);
X attachtty(jobtab[job].gleader);
X }
X if (stopped)
X killpg(jobtab[job].gleader,SIGCONT);
X if (func == BIN_FG)
X waitjobs();
X break;
X case BIN_JOBS:
X printjob(job+jobtab,lng);
X break;
X case BIN_WAIT:
X waitjob(job);
X retval = lastval;
X break;
X case BIN_DISOWN:
X {
X static struct job zero;
X jobtab[job] = zero;
X break;
X }
X }
X thisjob = ocj;
X }
X return retval;
X}
X
X/* false, let */
X
Xint bin_let(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
Xlong val = 0;
X
X while (*argv)
X val = matheval(*argv++);
X return !val;
X}
X
X/* print the directory stack */
X
Xstatic void pdstack()
X{
XLknode node;
X
X printdir(pwd);
X for (node = firstnode(dirstack); node; incnode(node))
X {
X putchar(' ');
X printdir(getdata(node));
X }
X putchar('\n');
X}
X
X/* exit the shell */
X
Xint zexit(val) /**/
Xint val;
X{
X if (isset(MONITOR))
X if (!stopmsg) {
X checkjobs();
X if (stopmsg) {
X stopmsg = 2;
X return 1;
X }
X } else killrunjobs();
X if (unset(NORCS) && interact) {
X if (isset(APPENDHISTORY)) {
X savehistfile(getsparam("HISTFILE"),0,3);
X readhistfile(getsparam("HISTFILE"),0);
X }
X savehistfile(getsparam("HISTFILE"),0,0);
X if (islogin)
X sourcehome(".zlogout");
X }
X if (sigtrapped[SIGEXIT])
X dotrap(SIGEXIT);
X exit(val); return 0;
X}
X
X/* identify an option name */
X
Xint optlookup(s) /**/
Xchar *s;
X{
Xchar *t;
Xstruct option *o;
X
X t = s = strdup(s);
X while (*t)
X if (*t == '_')
X chuck(t);
X else {
X *t = tulower(*t);
X t++;
X }
X for (o = optns; o->name; o++)
X if (!strcmp(o->name,s))
X return o->id;
X return -1;
X}
X
X/* setopt, unsetopt */
X
Xint bin_setopt(nam,args,ops,isun) /**/
Xchar *nam;char **args;char *ops;int isun;
X{
Xstruct option *opp;
Xint c;
X
X if (!ops['@'] && !*args) {
X if (!isun)
X prtopt();
X return 0;
X }
X for (opp = optns; opp->name; opp++)
X if (ops[opp->id] == 1+isun)
X opts[(int)opp->id] = OPT_SET;
X else if (ops[(int)opp->id] == 2-isun)
X opts[(int)opp->id] = OPT_UNSET;
X while (*args) {
X c = optlookup(*args++);
X if (c != -1) {
X if (c == INTERACTIVE)
X zerrnam(nam,"can't change option: %s",args[-1],0);
X else
X opts[c] = (isun) ? OPT_UNSET : OPT_SET;
X } else {
X zerrnam(nam,"no such option: %s",args[-1],0);
X return 1;
X }
X }
X return 0;
X}
X
X/* execute func on each member of the hash table ht */
X
Xstatic hnamcmp DCLPROTO((struct hashnode **a,struct hashnode **b));
Xstatic int hnamcmp(a,b)
Xstruct hashnode **a;struct hashnode **b;
X{
X return forstrcmp(&((*a)->nam), &((*b)->nam));
X}
X
Xvoid listhtable(ht,func) /**/
XHashtab ht;HFunc func;
X{
Xint t0;
Xstruct hashnode *hn;
X
X#ifndef HASHORDER
X
Xint nhash; struct hashnode **hnsorttab, **htp;
X
X for (nhash = 0, t0 = ht->hsize-1; t0 >= 0; t0--)
X for (hn = ht->nodes[t0]; hn; hn = hn->next)
X nhash++;
X
X hnsorttab = (struct hashnode **)zalloc (nhash * sizeof(struct hashnode *));
X for (htp = hnsorttab, t0 = ht->hsize-1; t0 >= 0; t0--)
X for (hn = ht->nodes[t0]; hn; hn = hn->next)
X *htp++ = hn;
X
X qsort((vptr)&hnsorttab[0],nhash,sizeof(struct hashnode *),
X (int (*) DCLPROTO((const void *, const void *)))hnamcmp);
X
X for (htp = hnsorttab; nhash; nhash--, htp++)
X func((*htp)->nam, (char *) (*htp));
X
X free (hnsorttab);
X
X#else
X
X for (t0 = ht->hsize-1; t0 >= 0; t0--)
X for (hn = ht->nodes[t0]; hn; hn = hn->next)
X func(hn->nam,(char *) hn);
X
X#endif HASHORDER
X}
X
X/* print a shell function (used with listhtable) */
X
Xvoid pshfunc(s,cc) /**/
Xchar *s;Cmdnam cc;
X{
Xchar *t;
X
X if (cc->type != SHFUNC)
X return;
X if (showflag && (cc->flags & showflag2) != showflag2)
X return;
X if (cc->flags & PMFLAG_u)
X printf("undefined ");
X if (cc->flags & PMFLAG_t)
X printf("traced ");
X if (!cc->u.list || !showflag) {
X printf("%s ()\n",s);
X return;
X }
X t = getpermtext((vptr) (cc->u.list));
X printf("%s () {\n\t%s\n}\n",s,t);
X free(t);
X}
X
Xvoid niceprint(s) /**/
Xchar *s;
X{
X niceprintf(s,stdout);
X}
X
Xvoid niceprintf(s,f) /**/
Xchar *s;FILE *f;
X{
X for (; *s; s++)
X {
X if (isprint(*s))
X fputc(*s,f);
X else if (*s == '\n')
X {
X putc('\\',f);
X putc('n',f);
X }
X else
X {
X putc('^',f);
X fputc(*s | 0x40,f);
X }
X }
X}
X
Xint bin_umask(nam,args,ops,func) /**/
Xchar *nam;char **args;char *ops;int func;
X{
Xint um;
Xchar *s = *args;
X
X um = umask(0);
X umask(um);
X if (!s)
X {
X printf("%03o\n",um);
X return 0;
X }
X if (idigit(*s))
X {
X um = zstrtol(s,&s,8);
X if (*s)
X {
X zerrnam(nam,"bad umask",NULL,0);
X return 1;
X }
X }
X else
X {
X int whomask,op,mask;
X
X for (;;)
X {
X if (*s == 'u')
X s++, whomask = 0100;
X else if (*s == 'g')
X s++, whomask = 0010;
X else if (*s == 'o')
X s++, whomask = 0001;
X else
X whomask = 0111;
X op = *s++;
X if (!(op == '+' || op == '-' || op == '='))
X {
X zerrnam(nam,"bad symbolic mode operator: %c",NULL,op);
X return 1;
X }
X mask = whomask;
X if (*s == 'r')
X mask *= 04;
X else if (*s == 'w')
X mask *= 02;
X else if (*s != 'x')
X {
X zerrnam(nam,"bad symbolic mode permission: %c",NULL,*s);
X return 1;
X }
X if (op == '+')
X um |= mask;
X else if (op == '-')
X um &= ~mask;
X else /* op == '=' */
X um = (um & ~(whomask*07)) | mask;
X if (*++s == ',')
X s++;
X else
X break;
X }
X if (*s)
X {
X zerrnam(nam,"bad character in symbolic mode: %c",NULL,*s);
X return 1;
X }
X }
X umask(um);
X return 0;
X}
X
X/* type, whence, which */
X
Xint bin_whence(nam,argv,ops,func) /**/
Xchar *nam;char **argv;char *ops;int func;
X{
Xstruct cmdnam *chn;
Xstruct alias *a;
Xint retval = 0;
Xint csh = ops['c'],all = ops['a'];
Xint v = ops['v'] || csh;
Xchar *cnam;
Xint informed;
X
X for (; *argv; argv++) {
X informed = 0;
X if (!ops['p'] && (a = (Alias) gethnode(*argv,aliastab))) {
X if (a->cmd < 0)
X printf((csh) ? "%s: shell reserved word\n" :
X (v) ? "%s is a reserved word\n" : "%s\n",*argv);
X else if (!v)
X puts(a->text);
X else if (a->cmd)
X printf((csh) ? "%s: aliased to %s\n" :
X "%s is an alias for %s\n",*argv,a->text);
X else
X printf((csh) ? "%s: globally aliased to %s\n" :
X "%s is a global alias for %s\n",*argv,a->text);
X retval = 0;
X if (!all) continue;
X informed = 1;
X }
X if (!ops['p'] && (chn = (Cmdnam) gethnode(*argv,cmdnamtab)) &&
X (chn->type == SHFUNC || chn->type == BUILTIN)) {
X if (chn->type == SHFUNC) {
X if (csh || ops['f']) {
X showflag = 1; showflag2 = 0;
X pshfunc(*argv,chn);
X } else {
X printf((v) ? "%s is a function\n" : "%s\n",*argv);
X }
X } else
X printf((csh) ? "%s: shell built-in command\n" :
X (v) ? "%s is a shell builtin\n" : "%s\n",*argv);
X retval = 0;
X if (!all) continue;
X informed = 1;
X }
X if (all) {
X char **pp,buf[MAXPATHLEN],*z;
X for (pp = path; *pp; pp++) {
X z = buf;
X strucpy(&z,*pp);
X *z++ = '/';
X strcpy(z,*argv);
X if (iscom(buf)) {
X if (v && !csh) printf("%s is %s\n",*argv,buf);
X else puts(buf);
X retval = 0;
X informed = 1;
X }
X }
X if (!informed && v) {
X printf("%s not found\n",*argv);
X retval = 1;
X break;
X }
X } else if (!(cnam = findcmd(*argv))) {
X if (v) printf("%s not found\n",*argv);
X retval = 1;
X break;
X } else {
X if (v && !csh) printf("%s is %s\n",*argv,cnam);
X else puts(cnam);
X retval = 0;
X free(cnam);
X }
X }
X return retval;
X}
X
X/* cd, chdir, pushd, popd */
X
Xint bin_cd(nam,argv,ops,func) /**/
Xchar *nam;char **argv;char *ops;int func;
X{
Xchar *dest, *dir;
X
X if (func == BIN_CD && isset(AUTOPUSHD))
X func = BIN_PUSHD;
X dir = dest = cd_get_dest(nam,argv,ops,func);
X if (!dest)
X return 1;
X dest = cd_do_chdir(nam,dest);
X if (dest != dir)
X free(dir);
X if (!dest)
X return 1;
X cd_new_pwd(func,dest);
X free(dest);
X return 0;
X}
X
Xchar *cd_get_dest(nam,argv,ops,func) /**/
Xchar *nam;char **argv;char *ops;int func;
X{
Xchar *dest;
X
X if (!argv[0])
X if (func == BIN_CD || ((func == BIN_PUSHD && isset(PUSHDTOHOME))
X || empty(dirstack)))
X dest = ztrdup(home);
X else
X dest = ztrdup(getnode(dirstack));
X else if (!argv[1]) {
X Lknode n;
X int dd;
X char *end;
X
X if (argv[0][1] && argv[0][0] == (isset(PUSHDMINUS) ? '-' : '+')) {
X dd = zstrtol(argv[0]+1,&end,10)-1;
X if (dd < 0 || *end != '\0') {
X zerrnam(nam,"%s: bad directory specification",argv[0],0);
X return NULL;
X }
X for (n = firstnode(dirstack); n && dd; dd--, incnode(n));
X if (!n) {
X zerrnam(nam,"no such entry in dir stack",NULL,0);
X return NULL;
X }
X dest = remnode(dirstack,n);
X } else if (argv[0][1] && argv[0][0] == (isset(PUSHDMINUS) ? '+' : '-')) {
X dd = zstrtol(argv[0]+1,&end,10);
X if (*end != '\0') {
X zerrnam(nam,"%s: bad directory specification",argv[0],0);
X return NULL;
X }
X for (n = lastnode(dirstack); n != (Lknode) dirstack && dd;
X dd--, n = prevnode(n));
X if (n == (Lknode) dirstack) {
X zerrnam(nam,"no such entry in dir stack",NULL,0);
X return NULL;
X }
X dest = remnode(dirstack,n);
X } else {
X if (!strcmp(argv[0],"-")) printdircr(dest = ztrdup(oldpwd));
X else dest = ztrdup(argv[0]);
X }
X } else {
X char *u;
X int len1,len2,len3;
X
X if (!(u = ztrstr(pwd,argv[0]))) {
X zerrnam(nam,"string not in pwd: %s",argv[0],0);
X return NULL;
X }
X len1 = strlen(argv[0]);
X len2 = strlen(argv[1]);
X len3 = u-pwd;
X dest = zalloc(len3+len2+strlen(u+len1)+1);
X strncpy(dest,pwd,len3);
X strcpy(dest+len3,argv[1]);
X strcat(dest,u+len1);
X printdircr(dest);
X }
X return dest;
X}
X
Xchar *cd_do_chdir(cnam,dest) /**/
Xchar *cnam; char *dest;
X{
Xint hasdot = 0, eno = ENOENT;
Xchar **pp,*ret;
X
X if (*dest == '/') {
X if (ret = cd_try_chdir(NULL,dest)) return ret;
X zerrnam(cnam,"%e: %s",dest,errno);
X return NULL;
X }
X for (pp = cdpath; *pp; pp++)
X if ((*pp)[0] == '.' && (*pp)[1] == '\0') hasdot = 1;
X if (!hasdot) {
X if (ret = cd_try_chdir(NULL,dest)) return ret;
X if (errno != ENOENT) eno = errno;
X }
X for (pp = cdpath; *pp; pp++) {
X if (ret = cd_try_chdir(*pp,dest)) {
X if (strcmp(*pp,".")) {
X printdircr(ret);
X }
X return ret;
X }
X if (errno != ENOENT) eno = errno;
X }
X if (isset(CDABLEVARS)) {
X char *s = getsparam(dest);
X if (s && *s == '/' && chdir(s) != -1) {
X printdircr(s);
X return ztrdup(s);
X }
X if (errno != ENOENT) eno = errno;
X }
X zerrnam(cnam,"%e: %s",dest,eno);
X return NULL;
X}
X
Xchar *cd_try_chdir(pfix,dest) /**/
Xchar *pfix; char *dest;
X{
Xchar buf[MAXPATHLEN], buf2[MAXPATHLEN];
Xchar *s;
Xint dotsct;
X
X if (pfix) sprintf(buf,"%s/%s",(!strcmp("/",pfix)) ? "" : pfix,dest);
X else strcpy(buf,dest);
X dotsct = fixdir(buf2,buf);
X if (buf2[0] == '/') return (chdir(buf) == -1) ? NULL : ztrdup(buf2);
X if (!dotsct) {
X if (chdir(buf) == -1) return NULL;
X if (*buf2) sprintf(buf,"%s/%s",(!strcmp("/",pwd)) ? "" : pwd,buf2);
X else strcpy(buf,pwd);
X return ztrdup(buf);
X }
X strcpy(buf,pwd);
X s = buf+strlen(buf)-1;
X while (dotsct--) while (s != buf) if (*--s == '/') break;
X if (s == buf || *buf2) s++;
X strcpy(s,buf2);
X if (chdir(buf) != -1 || chdir(dest) != -1) return ztrdup(buf);
X return NULL;
X}
X
Xint fixdir(d,s) /**/
Xchar *d; char *s;
X{
Xint ct = 0;
Xchar *d0 = d;
X
X#ifdef HAS_RFS
X while (*s == '/' && s[1] == '.' && s[2] == '.') {
X *d++ = '/'; *d++ = '.'; *d++ = '.';
X s += 3;
X }
X#endif
X#ifdef apollo
X if (*s == '/') *d++ = *s++; /*added RBC 18/05/92 */
X#endif
X for (;;) {
X if (*s == '/') {
X *d++ = *s++;
X while (*s == '/') s++;
X }
X if (!*s) {
X while (d > d0+1 && d[-1] == '/') d--;
X *d = '\0';
X return ct;
X }
X if (s[0] == '.' && s[1] == '.' && (s[2] == '\0' || s[2] == '/')) {
X if (d > d0+1) {
X for (d--; d > d0+1 && d[-1] != '/'; d--);
X if (d[-1] != '/') d--;
X } else ct++;
X s += 2; if (*s) s++;
X } else if (s[0] == '.' && (s[1] == '/' || s[1] == '\0')) {
X s++; if (*s) s++;
X } else {
X while (*s != '/' && *s != '\0') *d++ = *s++;
X }
X }
X}
X
Xvoid cd_new_pwd(func,s) /**/
Xint func; char *s;
X{
XParam pm;
XList l;
Xchar *new_pwd;
X
X if (isset(CHASELINKS))
X new_pwd = findpwd(s);
X else
X new_pwd = ztrdup(s);
X if (!strcmp(new_pwd, pwd)) {
X free(new_pwd);
X#ifdef ALWAYS_DO_CD_PROCESSING
X if (unset(PUSHDSILENT) && func != BIN_CD && isset(INTERACTIVE))
X pdstack();
X if (l = getshfunc("chpwd")) {
X fflush(stdout); fflush(stderr);
X doshfuncnoval(dupstruct(l),NULL,0);
X }
X#endif
X return;
X }
X free(oldpwd);
X oldpwd = pwd;
X pwd = new_pwd;
X if ((pm = gethnode("PWD", paramtab)) &&
X (pm->flags & PMFLAG_x) && pm->env)
X pm->env = replenv(pm->env,pwd);
X if ((pm = gethnode("OLDPWD", paramtab)) &&
X (pm->flags & PMFLAG_x) && pm->env)
X pm->env = replenv(pm->env,oldpwd);
X if (func == BIN_PUSHD) {
X permalloc();
X if (isset(PUSHDIGNOREDUPS)) {
X Lknode n;
X char *nodedata;
X for (n = firstnode(dirstack); n; incnode(n)) {
X nodedata = getdata(n);
X if (!strcmp(oldpwd,nodedata) || !strcmp(pwd,nodedata)) {
X free(remnode(dirstack,n)); break;
X }
X }
X }
X pushnode(dirstack,ztrdup(oldpwd));
X heapalloc();
X }
X if (unset(PUSHDSILENT) && func != BIN_CD && isset(INTERACTIVE))
X pdstack();
X if (l = getshfunc("chpwd")) {
X fflush(stdout); fflush(stderr);
X doshfuncnoval(dupstruct(l),NULL,0);
X }
X if (dirstacksize != -1 && countnodes(dirstack) >= dirstacksize) {
X if (dirstacksize < 2)
X dirstacksize = 2;
X else
X free(remnode(dirstack,lastnode(dirstack)));
X }
X}
X
Xvoid convertwd(s,t,off) /**/
Xchar *s; char *t; int off;
X{
Xchar *u,*start;
X
X *t++ = '/';
X start = t;
X while (off--) *t++ = *s++;
X for (;;) {
X while (*s == '/') s++;
X for (u = s; *u && *u != '/'; u++);
X if (!strncmp(s,".",u-s)) {
X ;
X } else if (!strncmp(s,"..",u-s)) {
X while (t != start && *--t != '/');
X } else {
X if (t != start) *t++ = '/';
X struncpy(&t,s,u-s);
X }
X if (!*u) break;
X s = u;
X }
X *t = '\0';
X}
X
Xint bin_rehash(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
X newcmdnamtab();
X if (ops['f']) fullhash();
X return 0;
X}
X
Xint bin_hash(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
Xstruct cmdnam *chn;
X
X chn = (Cmdnam) zcalloc(sizeof *chn);
X chn->type = EXCMD;
X chn->pcomp = NULL; /* this is probably a bug ! */
X chn->u.nam = ztrdup(argv[1]);
X addhnode(ztrdup(argv[0]),chn,cmdnamtab,freecmdnam);
X return 0;
X}
X
X/* != 0 if s is a prefix of t */
X
Xint prefix(s,t) /**/
Xchar *s;char *t;
X{
X while (*s && *t && *s == *t) s++,t++;
X return (!*s);
X}
X
X/* convert %%, %1, %foo, %?bar? to a job number */
X
Xint getjob(s,prog) /**/
Xchar *s;char *prog;
X{
Xint t0,retval;
X
X if (*s != '%')
X goto jump;
X s++;
X if (*s == '%' || *s == '+' || !*s)
X {
X if (curjob == -1)
X {
X zerrnam(prog,"no current job",NULL,0);
X retval = -1; goto done;
X }
X retval = curjob; goto done;
X }
X if (*s == '-')
X {
X if (prevjob == -1)
X {
X zerrnam(prog,"no previous job",NULL,0);
X retval = -1; goto done;
X }
X retval = prevjob; goto done;
X }
X if (idigit(*s))
X {
X t0 = atoi(s);
X if (t0 && t0 < MAXJOB && jobtab[t0].stat && t0 != thisjob)
X { retval = t0; goto done; }
X zerrnam(prog,"no such job",NULL,0);
X retval = -1; goto done;
X }
X if (*s == '?')
X {
X struct process *pn;
X
X for (t0 = MAXJOB-1; t0 >= 0; t0--)
X if (jobtab[t0].stat && t0 != thisjob)
X for (pn = jobtab[t0].procs; pn; pn = pn->next)
X if (ztrstr(pn->text,s+1))
X { retval = t0; goto done; }
X zerrnam(prog,"job not found: %s",s,0);
X retval = -1; goto done;
X }
Xjump:
X if ((t0 = findjobnam(s)) != -1)
X { retval = t0; goto done; }
X zerrnam(prog,"job not found: %s",s,0);
X retval = -1;
Xdone:
X return retval;
X}
X
X/* find a job named s */
X
Xint findjobnam(s) /**/
Xchar *s;
X{
Xint t0;
X
X for (t0 = MAXJOB-1; t0 >= 0; t0--)
X if (jobtab[t0].stat && jobtab[t0].procs && t0 != thisjob &&
X jobtab[t0].procs->text && prefix(s,jobtab[t0].procs->text))
X return t0;
X return -1;
X}
X
Xint isanum(s) /**/
Xchar *s;
X{
X while (*s == '-' || idigit(*s)) s++;
X return *s == '\0';
X}
X
Xint bin_kill(nam,argv,ops,func) /**/
Xchar *nam;char **argv;char *ops;int func;
X{
Xint sig = SIGTERM;
Xint retval = 0;
X
X if (*argv && **argv == '-') {
X if (idigit((*argv)[1]))
X sig = atoi(*argv+1);
X else {
X if ((*argv)[1] == 'l' && (*argv)[2] == '\0') {
X printf("%s",sigs[1]);
X for (sig = 2; sig <= SIGCOUNT; sig++)
X printf(" %s",sigs[sig]);
X putchar('\n');
X return 0;
X }
X for (sig = 1; sig <= SIGCOUNT; sig++)
X if (!strcmp(sigs[sig],*argv+1)) break;
X if (sig > SIGCOUNT) {
X zerrnam(nam,"unknown signal: SIG%s",*argv+1,0);
X zerrnam(nam,"type kill -l for a List of signals",NULL,0);
X return 1;
X }
X }
X argv++;
X }
X for (; *argv; argv++) {
X if (**argv == '%') {
X int p = getjob(*argv,"kill");
X
X if (p == -1) {
X retval = 1;
X continue;
X }
X if (killjb(jobtab+p,sig) == -1) {
X zerrnam("kill","kill failed: %e",NULL,errno);
X retval = 1;
X continue;
X }
X if (jobtab[p].stat & STAT_STOPPED) {
X if (sig == SIGCONT)
X jobtab[p].stat &= ~STAT_STOPPED;
X if (sig != SIGKILL && sig != SIGCONT && sig != SIGTSTP
X && sig != SIGTTOU && sig != SIGTTIN && sig != SIGSTOP)
X killjb(jobtab+p,SIGCONT);
X }
X } else if (!isanum(*argv)) {
X zerrnam("kill","illegal pid: %s",*argv,0);
X retval = 1;
X } else if (kill(atoi(*argv),sig) == -1) {
X zerrnam("kill","kill failed: %e",NULL,errno);
X retval = 1;
X }
X }
X return retval;
X}
X
Xstatic char *recs[] = {
X "cputime","filesize","datasize","stacksize","coredumpsize",
X#ifdef RLIMIT_RSS
X#ifdef RLIMIT_MEMLOCK
X "memoryuse",
X#else
X "resident",
X#endif /* RLIMIT_MEMLOCK */
X#endif /* RLIMIT_RSS */
X#ifdef RLIMIT_MEMLOCK
X "memorylocked",
X#endif
X#ifdef RLIMIT_NPROC
X "maxproc",
X#endif
X#ifdef RLIMIT_OFILE
X "openfiles",
X#endif
X#ifdef RLIMIT_NOFILE
X "descriptors",
X#endif
X#ifdef RLIMIT_VMEM
X "memorysize"
X#endif
X };
X
Xint bin_limit(nam,argv,ops,func) /**/
Xchar *nam;char **argv;char *ops;int func;
X{
X#ifndef RLIM_INFINITY
X zerrnam(nam,"not available on this system",NULL,0);
X return 1;
X#else
Xchar *s;
Xint hard = ops['h'],t0,lim;
Xlong val;
X
X if (ops['s'])
X {
X if (*argv)
X zerrnam(nam,"arguments after -s ignored",NULL,0);
X for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
X if (setrlimit(t0,limits+t0) < 0)
X zerrnam(nam,"setrlimit failed: %e",NULL,errno);
X return 0;
X }
X if (!*argv)
X {
X showlimits(hard,-1);
X return 0;
X }
X while (s = *argv++)
X {
X for (lim = -1, t0 = 0; t0 != RLIM_NLIMITS; t0++)
X if (!strncmp(recs[t0],s,strlen(s)))
X {
X if (lim != -1)
X lim = -2;
X else
X lim = t0;
X }
X if (lim < 0)
X {
X zerrnam("limit",
X (lim == -2) ? "ambiguous resource specification: %s"
X : "no such resource: %s",s,0);
X return 1;
X }
X if (!(s = *argv++))
X {
X showlimits(hard,lim);
X return 0;
X }
X if (!lim)
X {
X val = zstrtol(s,&s,10);
X if (*s)
X if ((*s == 'h' || *s == 'H') && !s[1])
X val *= 3600L;
X else if ((*s == 'm' || *s == 'M') && !s[1])
X val *= 60L;
X else if (*s == ':')
X val = val*60+zstrtol(s+1,&s,10);
X else
X {
X zerrnam("limit","unknown scaling factor: %s",s,0);
X return 1;
X }
X }
X#ifdef RLIMIT_NPROC
X else if (lim == RLIMIT_NPROC)
X val = zstrtol(s,&s,10);
X#endif
X#ifdef RLIMIT_OFILE
X else if (lim == RLIMIT_OFILE)
X val = zstrtol(s,&s,10);
X#endif
X#ifdef RLIMIT_NOFILE
X else if (lim == RLIMIT_NOFILE)
X val = zstrtol(s,&s,10);
X#endif
X else
X {
X val = zstrtol(s,&s,10);
X if (!*s || ((*s == 'k' || *s == 'K') && !s[1]))
X val *= 1024L;
X else if ((*s == 'M' || *s == 'm') && !s[1])
X val *= 1024L*1024;
X else
X {
X zerrnam("limit","unknown scaling factor: %s",s,0);
X return 1;
X }
X }
X if (hard)
X if (val > limits[lim].rlim_max && geteuid())
X {
X zerrnam("limit","can't raise hard limits",NULL,0);
X return 1;
X }
X else
X {
X limits[lim].rlim_max = val;
X if (limits[lim].rlim_max < limits[lim].rlim_cur)
X limits[lim].rlim_cur = limits[lim].rlim_max;
X }
X else
X if (val > limits[lim].rlim_max)
X {
X zerrnam("limit","limit exceeds hard limit",NULL,0);
X return 1;
X }
X else
X limits[lim].rlim_cur = val;
X }
X return 0;
X#endif
X}
X
Xint bin_unlimit(nam,argv,ops,func) /**/
Xchar *nam;char **argv;char *ops;int func;
X{
X#ifndef RLIM_INFINITY
X zerrnam(nam,"not available on this system",NULL,0);
X return 1;
X#else
Xint hard = ops['h'],t0,lim;
X
X if (hard && geteuid())
X {
X zerrnam(nam,"can't remove hard limits",NULL,0);
X return 1;
X }
X if (!*argv)
X {
X for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
X {
X if (hard)
X limits[t0].rlim_max = RLIM_INFINITY;
X else
X limits[t0].rlim_cur = limits[t0].rlim_max;
X }
X return 0;
X }
X for (; *argv; argv++)
X {
X for (lim = -1, t0 = 0; t0 != RLIM_NLIMITS; t0++)
X if (!strncmp(recs[t0],*argv,strlen(*argv)))
X {
X if (lim != -1)
X lim = -2;
X else
X lim = t0;
X }
X if (lim < 0)
X {
X zerrnam(nam,
X (lim == -2) ? "ambiguous resource specification: %s"
X : "no such resource: %s",*argv,0);
X return 1;
X }
X if (hard)
X limits[lim].rlim_max = RLIM_INFINITY;
X else
X limits[lim].rlim_cur = limits[lim].rlim_max;
X }
X return 0;
X#endif
X}
X
Xvoid showlimits(hard,lim) /**/
Xint hard;int lim;
X{
Xint t0;
Xlong val;
X
X#ifdef RLIM_INFINITY
X for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
X if (t0 == lim || lim == -1)
X {
X printf("%-16s",recs[t0]);
X val = (hard) ? limits[t0].rlim_max : limits[t0].rlim_cur;
X if (val == RLIM_INFINITY)
X printf("unlimited\n");
X else if (!t0)
X printf("%d:%02d:%02d\n",(int) (val/3600),
X (int) (val/60) % 60,(int) (val % 60));
X#ifdef RLIMIT_NPROC
X else if (t0 == RLIMIT_NPROC)
X printf("%d\n",(int) val);
X#endif
X#ifdef RLIMIT_OFILE
X else if (t0 == RLIMIT_OFILE)
X printf("%d\n",(int) val);
X#endif
X#ifdef RLIMIT_NOFILE
X else if (t0 == RLIMIT_NOFILE)
X printf("%d\n",(int) val);
X#endif
X else if (val >= 1024L*1024L)
X printf("%ldMb\n",val/(1024L*1024L));
X else
X printf("%ldKb\n",val/1024L);
X }
X#endif
X}
X
Xint bin_sched(nam,argv,ops,func) /**/
Xchar *nam;char **argv;char *ops;int func;
X{
Xchar *s = *argv++;
Xtime_t t;
Xlong h,m;
Xstruct tm *tm;
Xstruct schedcmd *sch,*sch2,*schl;
Xint t0;
X
X if (s && *s == '-')
X {
X t0 = atoi(s+1);
X
X if (!t0)
X {
X zerrnam("sched","usage for delete: sched -<item#>.",NULL,0);
X return 1;
X }
X for (schl = (struct schedcmd *) &schedcmds, sch = schedcmds, t0--;
X sch && t0; sch = (schl = sch)->next, t0--);
X if (!sch)
X {
X zerrnam("sched","not that many entries",NULL,0);
X return 1;
X }
X schl->next = sch->next;
X free(sch->cmd);
X free(sch);
X return 0;
X }
X if (!s)
X {
X char tbuf[40];
X
X for (t0 = 1, sch = schedcmds; sch; sch = sch->next,t0++)
X {
X t = sch->time;
X tm = localtime(&t);
X ztrftime(tbuf,20,"%a %b %e %k:%M:%S",tm);
X printf("%3d %s %s\n",t0,tbuf,sch->cmd);
X }
X return 0;
X }
X else if (!*argv)
X {
X zerrnam("sched","not enough arguments",NULL,0);
X return 1;
X }
X if (*s == '+')
X {
X h = zstrtol(s+1,&s,10);
X if (*s != ':')
X {
X zerrnam("sched","bad time specifier",NULL,0);
X return 1;
X }
X m = zstrtol(s+1,&s,10);
X if (*s)
X {
X zerrnam("sched","bad time specifier",NULL,0);
X return 1;
X }
X t = time(NULL)+h*3600+m*60;
X }
X else
X {
X h = zstrtol(s,&s,10);
X if (*s != ':')
X {
X zerrnam("sched","bad time specifier",NULL,0);
X return 1;
X }
X m = zstrtol(s+1,&s,10);
X if (*s && *s != 'a' && *s != 'p')
X {
X zerrnam("sched","bad time specifier",NULL,0);
X return 1;
X }
X t = time(NULL);
X tm = localtime(&t);
X t -= tm->tm_sec+tm->tm_min*60+tm->tm_hour*3600;
X if (*s == 'p')
X h += 12;
X t += h*3600+m*60;
X if (t < time(NULL))
X t += 3600*24;
X }
X sch = zcalloc(sizeof *sch);
X sch->time = t;
X sch->cmd = ztrdup(spacejoin(argv));
X sch->next = NULL;
X for (sch2 = (struct schedcmd *) &schedcmds; sch2->next; sch2 = sch2->next);
X sch2->next = sch;
X return 0;
X}
X
Xint bin_eval(nam,argv,ops,func) /**/
Xchar *nam;char **argv;char *ops;int func;
X{
Xchar *s = ztrdup(spacejoin(argv));
XList list;
X
X hungets(s);
X free(s);
X strinbeg();
X if (!(list = parse_list()))
X {
X hflush();
X strinend();
X return 1;
X }
X strinend();
X runlist(list);
X return lastval;
X}
X
X/* get the history event associated with s */
X
Xint fcgetcomm(s) /**/
Xchar *s;
X{
Xint cmd;
X
X if (cmd = atoi(s))
X {
X if (cmd < 0)
X cmd = curhist+cmd+1;
X return cmd;
X }
X cmd = hcomsearch(s);
X if (cmd == -1)
X zerrnam("fc","event not found: %s",s,0);
X return cmd;
X}
X
X/* perform old=new substituion */
X
Xint fcsubs(sp,sub) /**/
Xchar **sp;struct asgment *sub;
X{
Xchar *s1,*s2,*s3,*s4,*s = *sp,*s5;
Xint subbed = 0;
X
X while (sub)
X {
X s1 = sub->name;
X s2 = sub->value;
X sub = sub->next;
X s5 = s;
X while (s3 = (char *) ztrstr(s5,s1))
X {
X s4 = alloc(1+(s3-s)+strlen(s2)+strlen(s3+strlen(s1)));
X ztrncpy(s4,s,s3-s);
X strcat(s4,s2);
X s5 = s4+strlen(s4);
X strcat(s4,s3+strlen(s1));
X s = s4;
X subbed = 1;
X }
X }
X *sp = s;
X return subbed;
X}
X
X/* print a series of history events to a file */
X
Xint fclist(f,n,r,D,d,first,last,subs) /**/
XFILE *f;int n;int r;int D;int d;int first;int last;struct asgment *subs;
X{
Xint done = 0;
Xchar *s,*hs;
XHistent ent;
X
X if (r) {
X r = last;
X last = first;
X first = r;
X }
X if (!subs) done = 1;
X for (;;) {
X hs = quietgetevent(first);
X if (!hs) {
X zerrnam("fc","no such event: %d",NULL,first);
X return 1;
X }
X s = makehstr(hs);
X done |= fcsubs(&s,subs);
X if (n) fprintf(f,"%5d ",first);
X ent = NULL;
X if (d) {
X struct tm *ltm;
X
X if (!ent) ent = gethistent(first);
X ltm = localtime(&ent->stim);
X if (d >= 2) {
X if (d >= 4) {
X fprintf(f,"%d.%d.%d ",
X ltm->tm_mday,ltm->tm_mon+1,
X ltm->tm_year+1900);
X } else {
X fprintf(f,"%d/%d/%d ",
X ltm->tm_mon+1,
X ltm->tm_mday,
X ltm->tm_year+1900);
X }
X }
X fprintf(f,"%02d:%02d ",ltm->tm_hour, ltm->tm_min);
X }
X if (D) {
X long diff;
X
X if (!ent) ent = gethistent(first);
X diff = (ent->ftim) ? ent->ftim-ent->stim : 0;
X fprintf(f,"%d:%02d ",diff/60,diff%60);
X }
X if (f == stdout) {
X niceprintf(s,f);
X putc('\n',f);
X } else fprintf(f,"%s\n",s);
X if (first == last) break;
X else if (first > last) first--;
X else first++;
X }
X if (f != stdout) fclose(f);
X if (!done) {
X zerrnam("fc","no substitutions performed",NULL,0);
X return 1;
X }
X return 0;
X}
X
Xint fcedit(ename,fn) /**/
Xchar *ename;char *fn;
X{
X if (!strcmp(ename,"-"))
X return 1;
X return !zyztem(ename,fn);
X}
X
X/* fc, history, r */
X
Xint bin_fc(nam,argv,ops,func) /**/
Xchar *nam;char **argv;char *ops;int func;
X{
Xint first = -1,last = -1,retval,delayrem,minflag = 0;
Xchar *s;
Xstruct asgment *asgf = NULL,*asgl = NULL;
X
X if (!interact) {
X zerrnam(nam,"not interactive shell",NULL,0);
X return 1;
X }
X delayrem = !strcmp(nam,"r")
X && argv[0]
X &&(argv[1] || !strchr(argv[0],'='));
X if (!delayrem && !(ops['l'] && unset(HISTNOSTORE))) remhist();
X if (ops['R']) {
X readhistfile(*argv ? *argv : getsparam("HISTFILE"),1);
X return 0;
X }
X if (ops['W']) {
X savehistfile(*argv ? *argv : getsparam("HISTFILE"),1,
X (ops['I'] ? 2 : 0));
X return 0;
X }
X if (ops['A']) {
X savehistfile(*argv ? *argv : getsparam("HISTFILE"),1,
X (ops['I'] ? 3 : 1));
X return 0;
X }
X while (*argv && equalsplit(*argv,&s)) {
X struct asgment *a = (struct asgment *) alloc(sizeof *a);
X
X if (!asgf) asgf = asgl = a;
X else {
X asgl->next = a;
X asgl = a;
X }
X a->name = *argv;
X a->value = s;
X argv++;
X }
X if (*argv) {
X minflag = **argv == '-';
X first = fcgetcomm(*argv);
X if (first == -1) return 1;
X argv++;
X }
X if (*argv) {
X last = fcgetcomm(*argv);
X if (last == -1) return 1;
X argv++;
X }
X if (*argv) {
X zerrnam("fc","too many arguments",NULL,0);
X return 1;
X }
X if (delayrem) remhist();
X if (first == -1) first = (ops['l']) ? curhist-16 : curhist;
X if (last == -1) last = (ops['l']) ? curhist : first;
X if (first < firsthist()) first = firsthist();
X if (last == -1) last = (minflag) ? curhist : first;
X if (ops['l'])
X retval = fclist(stdout,!ops['n'],ops['r'],ops['D'],
X ops['d'] + ops['f'] * 2 + ops['E'] * 4,
X first,last,asgf);
X else {
X FILE *out;
X char *fil = gettemp();
X
X retval = 1;
X out = fopen(fil,"w");
X if (!out)
X zerrnam("fc","can't open temp file: %e",NULL,errno);
X else {
X if (!fclist(out,0,ops['r'],0,0,first,last,asgf))
X if (fcedit(auxdata ? auxdata : fceditparam,fil))
X if (stuff(fil))
X zerrnam("fc","%e: %s",s,errno);
X else
X retval = 0;
X }
X unlink(fil);
X }
X return retval;
X}
X
Xint bin_suspend(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
X if (islogin && !ops['f']) {
X zerrnam(name,"can't suspend login shell",NULL,0);
X return 1;
X }
X if (jobbing) {
X signal(SIGPIPE,SIG_DFL);
X signal(SIGTTIN,SIG_DFL);
X signal(SIGTSTP,SIG_DFL);
X signal(SIGTTOU,SIG_DFL);
X }
X kill(0,SIGTSTP);
X if (jobbing) {
X while (gettygrp() != mypgrp) {
X sleep(1);
X if (gettygrp() != mypgrp) kill(0,SIGTTIN);
X }
X signal(SIGTTOU,SIG_IGN);
X signal(SIGTSTP,SIG_IGN);
X signal(SIGTTIN,SIG_IGN);
X signal(SIGPIPE,SIG_IGN);
X }
X return 0;
X}
X
Xint bin_alias(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
Xstruct alias *an;
Xstruct asgment *asg;
Xint incm = !(ops['a'] || ops['g']),ret = 0;
X
X showflag = !incm;
X if (!*argv)
X listhtable(aliastab,(HFunc) printalias);
X else while (asg = getasg(*argv++))
X {
X if (asg->value)
X addhnode(ztrdup(asg->name),mkanode(ztrdup(asg->value),incm),
X aliastab,freeanode);
X else if (an = (Alias) gethnode(asg->name,aliastab))
X printalias(asg->name,an);
X else
X ret = 1;
X }
X return ret;
X}
X
X/* print an alias; used with listhtable */
X
Xvoid printalias(s,a) /**/
Xchar *s;struct alias *a;
X{
X if (a->cmd >= 0 && !(showflag && a->cmd))
X printf("%s=%s\n",s,a->text);
X}
X
X/* print a param; used with listhtable */
X
Xvoid printparam(s,p) /**/
Xchar *s;Param p;
X{
X if (showflag > 0 && !(p->flags & showflag))
X return;
X if (!showflag)
X {
X int fgs = p->flags;
X
X if (fgs & PMFLAG_i) printf("integer ");
X if (fgs & PMFLAG_A) printf("array ");
X if (fgs & PMFLAG_L) printf("left justified %d ",p->ct);
X if (fgs & PMFLAG_R) printf("right justified %d ",p->ct);
X if (fgs & PMFLAG_Z) printf("zero filled %d ",p->ct);
X if (fgs & PMFLAG_l) printf("lowercase ");
X if (fgs & PMFLAG_u) printf("uppercase ");
X if (fgs & PMFLAG_r) printf("readonly ");
X if (fgs & PMFLAG_t) printf("tagged ");
X if (fgs & PMFLAG_x) printf("exported ");
X }
X if (showflag2)
X printf("%s\n",s);
X else
X {
X char *t,**u;
X
X printf("%s=",s);
X switch (p->flags & PMTYPE)
X {
X case PMFLAG_s:
X if (p->gets.cfn && (t = p->gets.cfn(p)))
X puts(t);
X else
X putchar('\n');
X break;
X case PMFLAG_i: printf("%ld\n",p->gets.ifn(p)); break;
X case PMFLAG_A:
X putchar('(');
X u = p->gets.afn(p);
X if (!*u)
X printf(")\n");
X else
X {
X while (u[1])
X printf("%s ",*u++);
X printf("%s)\n",*u);
X }
X break;
X }
X }
X}
X
X/* autoload, declare, export, functions, integer, local, readonly, typeset */
X
Xint bin_typeset(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
Xint on = 0,off = 0,roff,bit = 1,retcode = 0;
Xchar *optstr = "LRZilurtx";
Xstruct param *pm;
Xstruct asgment *asg;
X
X for (; *optstr; optstr++,bit <<= 1)
X if (ops[*optstr] == 1)
X on |= bit;
X else if (ops[*optstr] == 2)
X off |= bit;
X roff = off;
X if (ops['f']) {
X on &= PMFLAG_t|PMFLAG_u;
X off &= PMFLAG_t|PMFLAG_u;
X showflag = (ops['f'] == 1);
X if (ops['@'] && ((off & ~PMFLAG_t) || (on & ~(PMFLAG_u|PMFLAG_t)))) {
X zerrnam(name,"invalid option(s)",NULL,0);
X return 1;
X }
X showflag2 = 0;
X if (!*argv) {
X showflag2 = off|on;
X listhtable(cmdnamtab,(HFunc) pshfunc);
X } else for (; *argv; argv++) {
X Cmdnam cc;
X
X if ((cc = (Cmdnam) gethnode(*argv,cmdnamtab)) && cc->type == SHFUNC)
X if (on|off) cc->flags = (cc->flags | on) & (~off);
X else pshfunc(*argv,cc);
X else if (on & PMFLAG_u) {
X cc = (Cmdnam) zcalloc(sizeof *cc);
X cc->type = SHFUNC;
X cc->flags = on;
X addhnode(ztrdup(*argv),cc,cmdnamtab,freecmdnam);
X } else
X retcode = 1;
X }
X return retcode;
X }
X if (on & PMFLAG_L)
X off |= PMFLAG_R;
X if (on & PMFLAG_R)
X off |= PMFLAG_L;
X if (on & PMFLAG_u)
X off |= PMFLAG_l;
X if (on & PMFLAG_l)
X off |= PMFLAG_u;
X on &= ~off;
X showflag = showflag2 = 0;
X if (!*argv) {
X showflag = on|off;
X showflag2 = roff;
X listhtable(paramtab,(HFunc) printparam);
X } else while (asg = getasg(*argv++)) {
X if (asg->value && *asg->value == '~') {
X *asg->value = Tilde;
X singsub(&asg->value);
X }
X pm = (Param) gethnode(asg->name,paramtab);
X if (pm) {
X if (!on && !roff && !asg->value) {
X printparam(asg->name,pm);
X continue;
X }
X pm->flags = (pm->flags | on) & ~off;
X if ((on & (PMFLAG_L | PMFLAG_R | PMFLAG_Z | PMFLAG_i))
X && (pmtype(pm) != PMFLAG_A))
X pm->ct = auxlen;
X if (pmtype(pm) != PMFLAG_A) {
X if (pm->flags & PMFLAG_x) {
X if (!pm->env)
X pm->env = addenv(asg->name,
X (asg->value) ? asg->value : getsparam(asg->name));
X } else if (pm->env) {
X delenv(pm->env);
X free(pm->env);
X pm->env = NULL;
X }
X if (asg->value)
X setsparam(asg->name,ztrdup(asg->value));
X }
X } else {
X if (locallist && !(on & PMFLAG_x)) {
X permalloc();
X addnode(locallist,ztrdup(asg->name));
X heapalloc();
X }
X createparam(ztrdup(asg->name),
X ztrdup((asg->value) ? asg->value : ""),on);
X pm = (Param) gethnode(asg->name,paramtab);
X pm->ct = auxlen;
X }
X }
X return 0;
X}
X
X/* convert s with escape sequences */
X
Xchar *escsubst(s,nnl) /**/
Xchar *s; int *nnl;
X{
Xchar *t = alloc(strlen(s)+1),*ret = t;
X
X for (; *s; s++)
X if (*s == '\\' && s[1])
X switch (*++s) {
X case 'b': *t++ = '\b'; break;
X case 'c': *nnl |= 1; break;
X case 'e': *t++ = '\033'; break;
X case 'f': *t++ = '\f'; break;
X case 'n': *t++ = '\n'; break;
X case 'r': *t++ = '\r'; break;
X case 't': *t++ = '\t'; break;
X case 'v': *t++ = '\v'; break;
X case '\\': *t++ = '\\'; break;
X case '0': *t++ = zstrtol(s,&s,8); s--; break;
X default: *t++ = '\\'; *t++ = *s; break;
X }
X else *t++ = *s;
X *t = '\0';
X return ret;
X}
X
X/* echo, print, pushln */
X
Xint bin_print(name,args,ops,func) /**/
Xchar *name;char **args;char *ops;int func;
X{
Xint nnl = 0, fd;
XHistent ent;
XFILE *fout = stdout;
X
X if (ops['z']) {
X permalloc();
X pushnode(bufstack,ztrdup(spacejoin(args)));
X heapalloc();
X return 0;
X }
X if (ops['s']) {
X permalloc();
X ent = gethistent(++curhist);
X ent->lex = ztrdup(join(args,HISTSPACE));
X ent->lit = ztrdup(join(args,' '));
X ent->stim = ent->ftim = time(NULL);
X ent->flags = 0;
X heapalloc();
X return 0;
X }
X if (ops['R'])
X ops['r'] = 1;
X if (ops['u'] || ops['p']) {
X if (ops['u']) {
X for (fd = 0; fd < 10; fd++) if (ops[fd+'0']) break;
X if (fd == 10) fd = 0;
X } else fd = coprocout;
X if ((fd = dup(fd)) < 0) {
X zerrnam(name,"bad file number",NULL,0);
X return 1;
X }
X if ((fout = fdopen(fd,"w")) == 0) {
X zerrnam(name,"bad mode on fd",NULL,0);
X return 1;
X }
X }
X for (; *args; args++) {
X if (!ops['r']) *args = escsubst(*args,&nnl);
X if (ops['D']) fprintdir(*args,fout);
X else if (ops['P']) {
X int junk;
X fputs(putprompt(*args,&junk,0),fout);
X } else fputs(*args,fout);
X if (args[1]) fputc(ops['l'] ? '\n' : ops['0'] ? '\0' : ' ',fout);
X }
X if (!(ops['n'] || nnl)) fputc(ops['N'] ? '\0' : '\n',fout);
X if (fout != stdout) fclose(fout);
X return 0;
X}
X
Xint bin_dirs(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
XLklist l;
X
X if (ops['v'])
X {
X Lknode node;
X int t0 = 1;
X
X printf("0\t");
X printdir(pwd);
X for (node = firstnode(dirstack); node; incnode(node))
X {
X printf("\n%d\t",t0++);
X printdir(getdata(node));
X }
X putchar('\n');
X return 0;
X }
X if (!*argv)
X {
X pdstack();
X return 0;
X }
X permalloc();
X l = newlist();
X if (!*argv)
X {
X heapalloc();
X return 0;
X }
X while (*argv)
X addnode(l,ztrdup(*argv++));
X freetable(dirstack,freestr);
X dirstack = l;
X heapalloc();
X return 0;
X}
X
Xint bin_unalias(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
Xint ret = 0;
Xvptr dat;
X
X while (*argv)
X {
X if (dat = remhnode(*argv++,aliastab))
X freeanode(dat);
X else
X ret = 1;
X }
X return ret;
X}
X
Xint bin_disable(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
XCmdnam chn;
X
X while (*argv) {
X if (!strncmp(*argv,"TRAP",4))
X unsettrap(getsignum(*argv+4));
X chn = zalloc(sizeof *chn);
X chn->type = DISABLED;
X addhnode(ztrdup(*argv++),chn,cmdnamtab,freecmdnam);
X }
X return 0;
X}
X
Xint bin_unhash(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
Xvptr dat;
X
X while (*argv) {
X if (!strncmp(*argv,"TRAP",4)) unsettrap(getsignum(*argv+4));
X if (dat = remhnode(*argv++,cmdnamtab)) freecmdnam(dat);
X }
X return 0;
X}
X
Xint bin_unset(name,argv,ops,func) /**/
Xchar *name;char **argv;char *ops;int func;
X{
Xint retval = 0;
Xchar *s;
X
X while (s = *argv++)
X if (gethnode(s,paramtab))
X unsetparam(s);
X else
X retval = 1;
X return retval;
X}
X
Xstatic char *zbuf;
Xstatic int readfd;
X
Xint zread() /**/
X{
Xchar cc;
X
X if (zbuf)
X return (*zbuf) ? *zbuf++ : EOF;
X if (read(readfd,&cc,1) != 1)
X return EOF;
X return cc;
X}
X
Xint bin_read(name,args,ops,func) /**/
Xchar *name;char **args;char *ops;int func;
X{
Xchar *reply,*pmpt;
Xint bsiz,c = 0,gotnl = 0;
Xchar *buf,*bptr;
X
X reply = (*args) ? *args++ : "REPLY";
X if (ops['u'] && !ops['p']) {
X for (readfd = 0; readfd < 10; ++readfd) if (ops[readfd+'0']) break;
X if (readfd == 10) readfd = 0;
X } else if (ops['p']) readfd = coprocin;
X else {
X attachtty((jobtab[thisjob].gleader) ? jobtab[thisjob].gleader : mypgrp);
X readfd = 0;
X if (isatty(0)) {
X for (pmpt = reply; *pmpt && *pmpt != '?'; pmpt++);
X if (*pmpt++) {
X write(2,pmpt,strlen(pmpt));
X pmpt[-1] = '\0';
X }
X }
X#if 0
X else if (isset(SHINSTDIN) && unset(INTERACTIVE)) {
X if (isatty(1)) readfd = 1;
X else if (isatty(2)) readfd = 2;
X }
X#endif
X }
X zbuf = (!ops['z']) ? NULL :
X (full(bufstack)) ? (char *) getnode(bufstack) : NULL;
X while (*args) {
X buf = bptr = zalloc(bsiz = 64);
X for(;;) {
X if (gotnl) break;
X c = zread();
X if (!ops['r'] && c == '\n' && bptr != buf && bptr[-1] == '\\') {
X bptr--;
X continue;
X }
X if (c == EOF || (isep(c) && bptr != buf) || c == '\n') break;
X if (isep(c)) continue;
X *bptr++ = c;
X if (bptr == buf+bsiz) {
X buf = realloc(buf,bsiz *= 2);
X bptr = buf+(bsiz/2);
X }
X }
X if (c == EOF) {
X if (readfd == coprocin) {
X close(coprocin);
X close(coprocout);
X coprocin = coprocout = -1;
X }
X return 1;
X }
X if (c == '\n') gotnl = 1;
X *bptr = '\0';
X setsparam(reply,buf);
X reply = *args++;
X }
X buf = bptr = zalloc(bsiz = 64);
X if (!gotnl)
X for (;;) {
X c = zread();
X if (!ops['r'] && c == '\n' && bptr != buf && bptr[-1] == '\\') {
X bptr--;
X continue;
X }
X if (c == EOF || (c == '\n' && !zbuf)) break;
X if (isep(c) && bptr == buf) continue;
X *bptr++ = c;
X if (bptr == buf+bsiz) {
X buf = realloc(buf,bsiz *= 2);
X bptr = buf+(bsiz/2);
X }
X }
X while(bptr > buf && isep(bptr[-1])) bptr--;
X *bptr = '\0';
X setsparam(reply,buf);
X if (c == EOF) {
X if (readfd == coprocin) {
X close(coprocin);
X close(coprocout);
X coprocin = coprocout = -1;
X }
X return 1;
X }
X return 0;
X}
X
Xint bin_vared(name,args,ops,func) /**/
Xchar *name;char **args;char *ops;int func;
X{
END_OF_FILE
if test 49195 -ne `wc -c <'src/builtin.c.01'`; then
echo shar: \"'src/builtin.c.01'\" unpacked with wrong size!
fi
# end of 'src/builtin.c.01'
fi
if test -f 'src/config.h.sample' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/config.h.sample'\"
else
echo shar: Extracting \"'src/config.h.sample'\" \(2966 characters\)
sed "s/^X//" >'src/config.h.sample' <<'END_OF_FILE'
X/* this file is created automatically by buildzsh */
X
X/* define this if you are sysvish */
X/* #define SYSV */
X
X#define TERMIOS
X/* #define TTY_NEEDS_DRAINING */
X/* #define CLOBBERS_TYPEAHEAD */
X
X#define HAS_DIRENT
X
X#define HAS_UNISTD
X
X#define HAS_STDLIB
X
X#define HAS_STRING
X
X#define HAS_MEMORY
X
X#define HAS_LOCALE
X
X/*#define HAS_UTMPX*/
X
X#define UTMP_HOST
X
X/*#define HAS_TIME*/
X
X/*#define HAS_WAIT*/
X
X/* define this if you have WAITPID */
X#define WAITPID
X
X/* define this if you have SELECT */
X#define HAS_SELECT
X
X/* define this if you have <sys/select.h> */
X/* #define HAS_SYS_SELECT */
X
X/* we can't just test for S_IFIFO or check to see if the mknod worked,
X because the NeXTs sold by a vendor which will remain nameless will
X happily create the FIFO for you, and then panic when you try to do
X something weird with them, because they aren't supported by the OS. */
X
X/* #define NO_FIFOS */
X
X/* define this if you have strftime() */
X#define HAS_STRFTIME
X
X#define HAS_TCSETPGRP
X
X#define HAS_TCCRAP
X
X#define HAS_SETPGID
X
X/* #define HAS_SIGRELSE */
X
X/* define this if you have RFS */
X/* #define HAS_RFS */
X
X/* define this if you have a working getrusage and wait3 */
X#define HAS_RUSAGE
X/* define this if you use NIS for your passwd map */
X#define HAS_NIS_PASSWD
X
X/* define this if your signal handlers return void */
X#define SIGVOID
X#ifdef sgi
X#undef SIGVOID
X#endif
X
X/* define this if signal handlers need to be reset each time */
X/* #define RESETHANDNEEDED */
X
X#ifdef SIGVOID
X#define HANDTYPE void
X#else
X#define HANDTYPE int
X#define INTHANDTYPE
X#endif
X
X/* a string corresponding to the host type */
X#define HOSTTYPE "sun4"
X
X/* the default editor for the fc builtin */
X#define DEFFCEDIT "vi"
X
X/* the path of wtmp */
X#define WTMP_FILE "/var/adm/wtmp"
X
X/* the path of utmp */
X#define UTMP_FILE "/etc/utmp"
X
X/* default prefix for temporary files */
X#define DEFTMPPREFIX "/tmp/zsh"
X
X/* define if you prefer "suspended" to "stopped" */
X#define USE_SUSPENDED
X
X/* the file to source absolutely first whenever zsh is run; if undefined,
X don't source anything */
X#define GLOBALZSHENV "/etc/zshenv"
X
X/* the file to source whenever zsh is run; if undefined, don't source
X anything */
X#define GLOBALZSHRC "/etc/zshrc"
X
X/* the file to source whenever zsh is run as a login shell; if
X undefined, don't source anything */
X#define GLOBALZLOGIN "/etc/zlogin"
X
X/* the file to source whenever zsh is run as a login shell, before
X zshrc is read; if undefined, don't source anything */
X#define GLOBALZPROFILE "/etc/zprofile"
X
X/* the default HISTSIZE */
X#define DEFAULT_HISTSIZE 30
X
X#define _BSD_SIGNALS /* this could be an iris, you never know */
X#define _BSD /* this could be HP-UX, you never know */
X#define _BSD_INCLUDES /* this could be AIX, you never know */
X#define _BBN_POSIX_SUPPORT /* this could be nX, you never know */
X
X/* if your compiler doesn't like void *, change this to char *
X and ignore all the warnings.
X*/
X
Xtypedef void *vptr;
X
X#define JOB_CONTROL
END_OF_FILE
if test 2966 -ne `wc -c <'src/config.h.sample'`; then
echo shar: \"'src/config.h.sample'\" unpacked with wrong size!
fi
# end of 'src/config.h.sample'
fi
echo shar: End of archive 8 \(of 22\).
cp /dev/null ark8isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 22 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...