home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-11-12 | 54.6 KB | 2,377 lines |
- Newsgroups: comp.sources.misc
- From: sjg@zen.void.oz.au (Simon J. Gerraty)
- Subject: v25i052: pdksh - Public Domain Korn Shell, v4, Part06/09
- Message-ID: <1991Nov13.031201.16173@sparky.imd.sterling.com>
- X-Md4-Signature: cc2e0220e22181fc52021675471393dc
- Date: Wed, 13 Nov 1991 03:12:01 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: sjg@zen.void.oz.au (Simon J. Gerraty)
- Posting-number: Volume 25, Issue 52
- Archive-name: pdksh/part06
- Environment: UNIX
-
- #! /bin/sh
- # 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: ReadMe.jrm sh/ChangeLog sh/alloc.c sh/expr.c sh/mail.c
- # sh/misc.c sh/sh.h sh/table.c sh/ulimit.c std/stdc/vprintf.c
- # Wrapped by kent@sparky on Tue Nov 12 20:44:33 1991
- 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 6 (of 9)."'
- if test -f 'ReadMe.jrm' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ReadMe.jrm'\"
- else
- echo shar: Extracting \"'ReadMe.jrm'\" \(4951 characters\)
- sed "s/^X//" >'ReadMe.jrm' <<'END_OF_FILE'
- XBUILDING THE PD KSH
- X===================
- X
- XAs usual, there are differences between BSD and System V
- Xversions. Ideally, all you have to do is edit the Makefile in
- Xthis directory to set the CONFIG macro to the appropriate value.
- X(Actually, you may wish to change the CONFIG macro in all
- XMakefiles; if you always invoke make(1) from here, CONFIG will
- Xbe passed down, but if you invoke make(1) from a subdirectory
- Xyou'll want the appropriate definition in that Makefile.)
- X
- XOf course it's not quite that simple. You may, however, take
- Xsolace in the knowledge that it used to be worse.
- X
- XThe Compatibility Libraries
- X---------------------------
- X
- XEric Gisin wrote this shell using ANSI C and POSIX as
- Xportability guidlines. Realizing that nobody had a POSIX
- Xsystem and almost no one had an ANSI C environment, he provided
- Xminimal compatibility libraries.
- X
- XThere are two libraries, one for POSIX (libposix.a) and one for
- XANSI C (libstdc.a).
- X
- XLibposix.a is pretty simple. Nothing in it has ever broken on
- Xme, so I'd just leave it. It provides a version of dup2() for
- XSystem V systems.
- X
- XLibstdc.a is a bit hairy. I recommend looking at the routines
- Xprovided and, and editing the std/stdc Makefile and only
- Xincluding objects that have routines your system libc.a is
- Xlacking. Various of the provided routines are just plain
- Xflaky, but only when they're not really needed. The other
- Xhairy thing he does is craft an ANSI stdio.h from the system
- Xsupplied one and one of his own. Again, it's better than it
- Xused to be, but it's still a hack, and you may have to modify
- Xit by hand.
- X
- XYou will also need a POSIX compatible set of directory reading
- Xroutines. System V.3 systems have this in libc.a. The
- Xstd/posix directory provides a something for BSD systems. I
- Xuse a slightly modified version of Doug Gwyn's PD version.
- X
- X(The ``slightly modified'' is to work around a bug in Gwyn's version.
- XThe POSIX routines are documented as returning failure if the file for
- Xopendir(3) is not a directory. Gwyn attempts to open(2) the file, and
- Xthen stats it to see if the file is a directory. However, if the file
- Xis a special file, and the open(2) doesn't return, you're screwed. My
- Xchange was to open the file with the O_NDELAY flag, but Gwyn didn't
- Xfeel this was portable (true, but I only do it where it works) and
- Xthat stat-ing before the open would be too slow (true). The upshot is
- Xif you use his routines unmodified, don't ever do an "ls -l /dev/*/*".)
- X
- XThe Shell Source
- X----------------
- X
- XThe source for the shell itself is in the sh directory. There you
- Xwill want to edit config.h to determine the configuration options. Vi
- Xmode is in kind of rough shape, but does work. DIRSTACK routines
- Xaren't implemented yet, so again, why bother. SWTCH is a bit arcane,
- Xbut it you use shl(1) and you define EMACS or VI you want to define
- Xthis. JOBS is really only useful on BSD systems. It might work on
- Xsystems that have POSIX job control, but I wouldn't bet on it.
- XSHARPBANG is only useful on systems where the exec() family don't
- Xhonour the #!/prog/path convention.
- X
- XThis is where the shell gets built so you may wish to change
- Xthe OTHERLIBS macro in the Makefile to point to your POSIX
- Xdirectory routines, or to use -lc_s, or whatever.
- X
- XMiscellaneous
- X-------------
- X
- XThe Makefiles that actually compile things use the macro
- XCCOPTS, so you can change it in individual Makefiles or specify
- Xit on the command line, eg. "make CCOPTS=-O OTHERLIBS=-lc_s".
- XLDOPTS is used in the Makefile where the ksh is actually built.
- X
- XThe very first time on a new system, do a "make clobber"
- X
- XGood luck.
- X
- XDocumentation
- X-------------
- X
- XThe ksh.1 is a man page for the PD ksh, although it lags
- Xsomewhat behind the code. You get what you pay for.
- X
- XThe ksh88.1 is a man page for AT&T's ksh88 (the latest version)
- Xprovided for comparison.
- X
- XHistory
- X-------
- X
- XMuch of the shell was written by Eric Gisin at the University
- Xof Waterloo, using some pieces of other stuff, notably Charles
- XForsythe's V7 shell, and some enhancements from the BRL shell.
- XHe placed it (in a alpha test state) into the public domain
- Xwhile I was at UW. I snarfed a copy, and got it running on my
- XUNIXpc, and later some machines at work. I sent Gisin some bug
- Xreports, but he seems to have lost interest in the project.
- XThis may be because he now does some work for MKS, who produce a
- Xcommercial version of the ksh for MS-DOS machines, so there may
- Xbe a conflict of interest.
- X
- XSo I gave up on getting future versions, and adopted it. I've
- Xmade some enhancements, and quite a few bug fixes, and various
- Xpeople at work have contributed as well. It remains in the
- Xpublic domain, although I imagine the people involved would
- Xappreciate leaving their names attached (I'm exempt; I haven't
- Xactually included my name anywhere but here).
- X
- XThe README in the sh directory is Gisin's, and tells a bit of
- Xthe story from his point of view. Note that his compilation
- Xinstructions don't really apply anymore.
- X
- XJohn R. MacMillan
- END_OF_FILE
- if test 4951 -ne `wc -c <'ReadMe.jrm'`; then
- echo shar: \"'ReadMe.jrm'\" unpacked with wrong size!
- fi
- # end of 'ReadMe.jrm'
- fi
- if test -f 'sh/ChangeLog' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sh/ChangeLog'\"
- else
- echo shar: Extracting \"'sh/ChangeLog'\" \(4281 characters\)
- sed "s/^X//" >'sh/ChangeLog' <<'END_OF_FILE'
- XSat Nov 9 14:57:30 1991 Simon J. Gerraty (sjg at zen)
- X
- X * Release version 4.1 as a new base line.
- X
- XThu Nov 7 23:11:25 1991 Simon J. Gerraty (sjg at zen)
- X
- X * John R MacMillan suppied a fix for a bug in yylex() that was the
- X cause of several odd problems such as:
- X $ foo=echo
- X $ $foo bar
- X bar: not found
- X $ pwd
- X $ /local/src/pdksh
- X $ $foo bar
- X bar
- X $
- X
- XSun Sep 15 23:19:27 1991 Simon J. Gerraty (sjg at zen)
- X
- X * emacs.c:
- X Added function x_lastcp() which returns a pointer to that char in
- X the edit buffer that will be the last displayed on the screen.
- X Thus:
- X
- X cp = x_lastcp();
- X while (cp > xcp)
- X x_bs(*--cp);
- X
- X Will correctly position the cursor on the screen (regardless of
- X TABs etc in the buffer). The previous method got out of sync if
- X there were any TABs to display.
- X
- XWed Aug 7 11:26:55 1991 Simon J. Gerraty (sjg at sun0)
- X
- X * jobs.c:
- X The Sun SPARCstation 2 was proving extremely unreliable using ksh.
- X After puting traces in jobs.c, it turns out the problem was
- X multiple SIGCHLD events happening too quickly causing the handler
- X to be interupted and thus not recognise the job that it had just
- X reaped was one of its own. Having done the waitpid(), but not
- X adjusted the job table entry, j_waitj() would loop forever waiting
- X for a job to finnish (that had already done so!)
- X Solution was to have the SIGCHLD handler simply record the events
- X by inrcrementing sigchld_caught. The actual reaping is now done
- X in a new funtion j_reapchld(), which does what the old signal
- X handler did but blocks SIGCHLD while scanning the job table.
- X j_waitj() calls j_reapchld() when sigchld_caught is non-zero.
- X The SS2 is now much more reliable...
- X
- X * trace.c:
- X Added my simple _TRACE facility (used to track the j_waitj
- X problem). Simply -DUSE_TRACE for it to have effect. If USE_TRACE
- X is undefined, calls to _TRACE() expand to while(0) which an
- X optimizer will usually remove. sh.h now includes trace.h
- X
- XMon Jun 10 10:27:14 1991 Simon J. Gerraty (sjg at zen)
- X
- X * emacs.c:
- X A couple of assignments (xbp = xbuf) were not migrated from the
- X 3.2 version. Caused an anoying bug when retrieving history
- X commands.
- X
- XMon May 27 12:50:20 1991 Simon J. Gerraty (sjg at sun0)
- X
- X * added fixes supplied by Mike Jetzer:
- X These relate mainly to vi mode. See Changes.mlj
- X
- X * c_sh.c c_exit():
- X Modified behavior to not imediately exit if there are stopped
- X jobs. A subsequent exit will kill any jobs left and terminate the
- X shell.
- X
- XFri May 24 15:20:10 1991 Simon J. Gerraty (sjg at sun0)
- X
- X * edit.h:
- X Cleaned up prototypes. Built shell on sun3.
- X While gcc-1.39 builds the ksh ok on the 386i, on the sun3 jobs
- X don't work correctly - any non-builtin command gets stopped and
- X put into the background. Had same problem with 3.2, using
- X /usr/bin/cc works fine.
- X
- XThu May 23 13:45:20 1991 Simon J. Gerraty (sjg at sun0)
- X
- X * migrated my 3.2 edit.c changes to the new shell.
- X Affects edit.c, emacs.c
- X Added edit.h which is now included by edit.c,emacs.c and vi.c
- X
- X * vi.c:
- X Fixed handling of '!' in prompt by using pprompt() as in emacs.c
- X
- X * std/stdc/vprintf.c:
- X Fixed bug in output of left '0' padded unsigned numbers was
- X always padding with ' ' which left a space in ksh's temp file
- X names. This prevented fc -l from working.
- X
- XHere is my 3.2 ChangeLog:
- XFri Mar 22 16:50:14 1991 Simon J. Gerraty (sjg at sun0)
- X
- X * edit.c:
- X Added x_set_arg() and x_prev_histword().
- X x_set_arg() handles 'ESC''0-9' type args which are used by word
- X related commands.
- X x_prev_histword() recovers the last (default) or sepcified arg
- X word from the previous command line. Bound to ESC. and ESC_ to be
- X compatible with real ksh.
- X
- XTue Feb 26 14:16:17 1991 Simon J. Gerraty (sjg at zen)
- X
- X * edit.c:
- X Changes to handle editing of command lines longer than $COLUMNS in
- X a manner compatible with real ksh.
- X
- XMon Feb 25 12:20:36 1991 Simon J. Gerraty (sjg at sun0)
- X
- X * var.c,table.h:
- X Implemented $RANDOM
- X Some scripts use [ "$RANDOM" != "$RANDOM" ] to check for ksh.
- X
- XWed Feb 20 12:20:36 1991 Simon J. Gerraty (sjg at sun0)
- X
- X Changes so that shell will compile on sun386i.
- X
- X * exec.c,main.c,io.c:
- X Handle the case where FD_CLEXEC isn't defined.
- X
- X * jobs.c:
- X SunOS has its own ideas about job status etc.
- X
- X * tree.c:
- X Fixed conflict between varargs and stdarg.
- X
- X
- X
- X
- END_OF_FILE
- if test 4281 -ne `wc -c <'sh/ChangeLog'`; then
- echo shar: \"'sh/ChangeLog'\" unpacked with wrong size!
- fi
- # end of 'sh/ChangeLog'
- fi
- if test -f 'sh/alloc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sh/alloc.c'\"
- else
- echo shar: Extracting \"'sh/alloc.c'\" \(4744 characters\)
- sed "s/^X//" >'sh/alloc.c' <<'END_OF_FILE'
- X/*
- X * area-based allocation built on malloc/free
- X */
- X
- Xstatic char *RCSid = "$Id";
- X
- X#include <stddef.h>
- X#include <stdlib.h>
- X#include <setjmp.h>
- X#include "sh.h"
- X
- X#define ICELLS 100 /* number of Cells in small Block */
- X
- Xtypedef union Cell Cell;
- Xtypedef struct Block Block;
- X
- X/*
- X * The Cells in a Block are organized as a set of objects.
- X * Each object (pointed to by dp) begins with a size in (dp-1)->size,
- X * followed with "size" data Cells. Free objects are
- X * linked together via dp->next.
- X */
- X
- Xunion Cell {
- X size_t size;
- X Cell *next;
- X struct {int _;} junk; /* alignment */
- X};
- X
- Xstruct Block {
- X Block *next; /* list of Blocks in Area */
- X Cell *free; /* object free list */
- X Cell *last; /* &b.cell[size] */
- X Cell cell [1]; /* [size] Cells for allocation */
- X};
- X
- XBlock aempty = {&aempty, aempty.cell, aempty.cell};
- X
- X/* create empty Area */
- XArea *
- Xainit(ap)
- X register Area *ap;
- X{
- X ap->free = &aempty;
- X return ap;
- X}
- X
- X/* free all object in Area */
- Xvoid
- Xafreeall(ap)
- X register Area *ap;
- X{
- X register Block *bp;
- X
- X if (ap->free == NULL || ap->free == &aempty)
- X return;
- X for (bp = ap->free; ; bp = bp->next) {
- X free((Void*)bp);
- X if (bp->next == ap->free)
- X break;
- X }
- X ap->free = &aempty;
- X}
- X
- X/* allocate object from Area */
- XVoid *
- Xalloc(size, ap)
- X size_t size;
- X register Area *ap;
- X{
- X int cells, split;
- X register Block *bp;
- X register Cell *dp, *fp, *fpp;
- X
- X if (size <= 0) {
- X aerror(ap, "allocate bad size");
- X return NULL;
- X }
- X cells = (unsigned)(size - 1) / sizeof(Cell) + 1;
- X
- X /* find Cell large enough */
- X for (bp = ap->free; ; bp = bp->next) {
- X for (fpp = NULL, fp = bp->free;
- X fp != bp->last; fpp = fp, fp = fpp->next)
- X if ((fp-1)->size >= cells)
- X goto Found;
- X
- X /* wrapped around Block list, create new Block */
- X if (bp->next == ap->free) {
- X bp = (Block*) malloc(offsetof(Block, cell[ICELLS + cells]));
- X if (bp == NULL) {
- X aerror(ap, "cannot allocate");
- X return NULL;
- X }
- X if (ap->free == &aempty)
- X bp->next = bp;
- X else {
- X bp->next = ap->free->next;
- X ap->free->next = bp;
- X }
- X bp->last = bp->cell + ICELLS + cells;
- X fp = bp->free = bp->cell + 1; /* initial free list */
- X (fp-1)->size = ICELLS + cells - 1;
- X fp->next = bp->last;
- X fpp = NULL;
- X break;
- X }
- X }
- X Found:
- X ap->free = bp;
- X dp = fp; /* allocated object */
- X split = (dp-1)->size - cells;
- X if (split < 0)
- X aerror(ap, "allocated object too small");
- X if (--split <= 0) { /* allocate all */
- X fp = fp->next;
- X } else { /* allocate head, free tail */
- X (fp-1)->size = cells;
- X fp += cells + 1;
- X (fp-1)->size = split;
- X fp->next = dp->next;
- X }
- X if (fpp == NULL)
- X bp->free = fp;
- X else
- X fpp->next = fp;
- X return (Void*) dp;
- X}
- X
- X/* change size of object -- like realloc */
- XVoid *
- Xaresize(ptr, size, ap)
- X register Void *ptr;
- X size_t size;
- X Area *ap;
- X{
- X int cells;
- X register Cell *dp = (Cell*) ptr;
- X
- X if (size <= 0) {
- X aerror(ap, "allocate bad size");
- X return NULL;
- X }
- X cells = (unsigned)(size - 1) / sizeof(Cell) + 1;
- X
- X if (dp == NULL || (dp-1)->size < cells) { /* enlarge object */
- X register Cell *np;
- X register int i;
- X Void *optr = ptr;
- X
- X ptr = alloc(size, ap);
- X np = (Cell*) ptr;
- X if (dp != NULL)
- X for (i = (dp-1)->size; i--; )
- X *np++ = *dp++;
- X afree(optr, ap);
- X } else { /* shrink object */
- X int split;
- X
- X split = (dp-1)->size - cells;
- X if (--split <= 0) /* cannot split */
- X ;
- X else { /* shrink head, free tail */
- X (dp-1)->size = cells;
- X dp += cells + 1;
- X (dp-1)->size = split;
- X afree((Void*)dp, ap);
- X }
- X }
- X return (Void*) ptr;
- X}
- X
- Xvoid
- Xafree(ptr, ap)
- X Void *ptr;
- X register Area *ap;
- X{
- X register Block *bp;
- X register Cell *fp, *fpp;
- X register Cell *dp = (Cell*)ptr;
- X
- X /* find Block containing Cell */
- X for (bp = ap->free; ; bp = bp->next) {
- X if (bp->cell <= dp && dp < bp->last)
- X break;
- X if (bp->next == ap->free) {
- X aerror(ap, "freeing with invalid area");
- X return;
- X }
- X }
- X
- X /* find position in free list */
- X for (fpp = NULL, fp = bp->free; fp < dp; fpp = fp, fp = fpp->next)
- X ;
- X
- X if (fp == dp) {
- X aerror(ap, "freeing free object");
- X return;
- X }
- X
- X /* join object with next */
- X if (dp + (dp-1)->size == fp-1) { /* adjacent */
- X (dp-1)->size += (fp-1)->size + 1;
- X dp->next = fp->next;
- X } else /* non-adjacent */
- X dp->next = fp;
- X
- X /* join previous with object */
- X if (fpp == NULL)
- X bp->free = dp;
- X else if (fpp + (fpp-1)->size == dp-1) { /* adjacent */
- X (fpp-1)->size += (dp-1)->size + 1;
- X fpp->next = dp->next;
- X } else /* non-adjacent */
- X fpp->next = dp;
- X}
- X
- X
- X#if TEST_ALLOC
- X
- XArea a;
- X
- Xmain(int argc, char **argv) {
- X int i;
- X char *p [9];
- X
- X ainit(&a);
- X for (i = 0; i < 9; i++) {
- X p[i] = alloc(124, &a);
- X printf("alloc: %x\n", p[i]);
- X }
- X for (i = 1; i < argc; i++)
- X afree(p[atoi(argv[i])], &a);
- X afreeall(&a);
- X return 0;
- X}
- X
- Xvoid aerror(Area *ap, const char *msg) {
- X abort();
- X}
- X
- X#endif
- X
- END_OF_FILE
- if test 4744 -ne `wc -c <'sh/alloc.c'`; then
- echo shar: \"'sh/alloc.c'\" unpacked with wrong size!
- fi
- # end of 'sh/alloc.c'
- fi
- if test -f 'sh/expr.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sh/expr.c'\"
- else
- echo shar: Extracting \"'sh/expr.c'\" \(4590 characters\)
- sed "s/^X//" >'sh/expr.c' <<'END_OF_FILE'
- X/*
- X * Korn expression evaluation
- X */
- X
- Xstatic char *RCSid = "$Id: expr.c,v 3.2 89/03/27 15:50:20 egisin Exp $";
- X
- X#include <stddef.h>
- X#include <errno.h>
- X#include <setjmp.h>
- X#include "sh.h"
- X#include "table.h"
- X
- X#define ef else if /* fashion statement */
- X
- X#define VAR 0x01
- X#define LIT 0x02
- X#define LEQ 0x03
- X#define LNE 0x04
- X#define LLE 0x05
- X#define LGE 0x06
- X
- Xstatic void token(); /* read next token */
- Xstatic Const char *expression; /* expression being evaluated */
- Xstatic Const char *tokp; /* lexical position */
- Xstatic int tok; /* token from token() */
- Xstatic struct tbl *val; /* value from token() */
- X
- Xstatic struct tbl *tempvar(), *intvar();
- Xstatic struct tbl *asn(), *e6(), *e5(), *e3(), *e2(), *e0();
- X
- X/*
- X * parse and evalute expression
- X */
- Xvoid
- Xevalerr(err)
- X char *err;
- X{
- X errorf("%s: %s\n", expression, err);
- X}
- X
- Xlong
- Xevaluate(expr)
- X Const char *expr;
- X{
- X struct tbl *v;
- X
- X expression = tokp = expr;
- X token();
- X v = intvar(asn());
- X if (!(tok == 0))
- X evalerr("bad expression");
- X return v->val.i;
- X}
- X
- Xstatic struct tbl *
- Xasn()
- X{
- X register struct tbl *vl, *vr;
- X
- X vr = vl = e6();
- X if ((tok == '=')) {
- X Area * olastarea = lastarea;
- X token();
- X if ((vl->flag&RDONLY)) /* assign to rvalue */
- X evalerr("bad assignment");
- X vr = intvar(asn());
- X lastarea = olastarea;
- X setint(vl, vr->val.i);
- X if ((vl->flag&INTEGER) && vl->type == 0) /* default base? */
- X vl->type = vr->type;
- X }
- X return vr;
- X}
- X
- Xstatic struct tbl *
- Xe6()
- X{
- X register struct tbl *vl, *vr;
- X
- X vl = e5();
- X while ((tok == LEQ) || (tok == LNE)) {
- X int op = tok;
- X token();
- X vl = intvar(vl);
- X vr = intvar(e5());
- X vl->val.i = vl->val.i == vr->val.i;
- X if (op == LNE)
- X vl->val.i = ! vl->val.i;
- X }
- X return vl;
- X}
- X
- Xstatic struct tbl *
- Xe5()
- X{
- X register struct tbl *vl, *vr;
- X
- X vl = e3();
- X while ((tok == LLE) || (tok == '<') || (tok == '>') || (tok == LGE)) {
- X int op = tok;
- X token();
- X vl = intvar(vl);
- X vr = intvar(e3());
- X if (op == LLE)
- X vl->val.i = vl->val.i <= vr->val.i;
- X ef (op == '<')
- X vl->val.i = vl->val.i < vr->val.i;
- X ef (op == LGE)
- X vl->val.i = vl->val.i >= vr->val.i;
- X ef (op == '>')
- X vl->val.i = vl->val.i > vr->val.i;
- X }
- X return vl;
- X}
- X
- Xstatic struct tbl *
- Xe3()
- X{
- X register struct tbl *vl, *vr;
- X
- X vl = e2();
- X while ((tok == '+') || (tok == '-')) {
- X int op = tok;
- X token();
- X vl = intvar(vl);
- X vr = intvar(e2());
- X if (op == '+')
- X vl->val.i += vr->val.i;
- X ef (op == '-')
- X vl->val.i -= vr->val.i;
- X }
- X return vl;
- X}
- X
- Xstatic struct tbl *
- Xe2()
- X{
- X register struct tbl *vl, *vr;
- X
- X vl = e0();
- X while ((tok == '*') || (tok == '/') || (tok == '%')) {
- X int op = tok;
- X token();
- X vl = intvar(vl);
- X vr = intvar(e0());
- X if (op != '*' && vr->val.i == 0)
- X evalerr("zero divisor");
- X if (op == '*')
- X vl->val.i *= vr->val.i;
- X ef (op == '/')
- X vl->val.i /= vr->val.i;
- X ef (op == '%')
- X vl->val.i %= vr->val.i;
- X }
- X return vl;
- X}
- X
- Xstatic struct tbl *
- Xe0()
- X{
- X register struct tbl *v;
- X
- X if ((tok == '!') || (tok == '-')) {
- X int op = tok;
- X token();
- X v = intvar(e0());
- X if (op == '!')
- X v->val.i = !v->val.i;
- X ef (op == '-')
- X v->val.i = -v->val.i;
- X } else
- X if ((tok == '(')) {
- X token();
- X v = asn();
- X if (!(tok == ')'))
- X evalerr("missing )");
- X token();
- X } else
- X if ((tok == VAR) || (tok == LIT)) {
- X v = val;
- X token();
- X } else
- X evalerr("bad expression");
- X return v;
- X}
- X
- Xstatic void
- Xtoken()
- X{
- X register char *cp = (char *) tokp;
- X register int c, c2;
- X
- X /* skip white space */
- X do c = *cp++; while (c != '\0' && (c == ' ' || c == '\t'));
- X tokp = cp-1;
- X
- X if (letter(c)) {
- X for (; letnum(c); c = *cp++)
- X ;
- X c = *--cp;
- X *cp = 0;
- X val = global(tokp);
- X *cp = c;
- X tok = VAR;
- X } else
- X if (digit(c)) {
- X for (; letnum(c) || c == '#'; c = *cp++)
- X ;
- X c = *--cp;
- X *cp = 0;
- X val = tempvar();
- X setstr(val, tokp);
- X val->flag |= RDONLY;
- X *cp = c;
- X tok = LIT;
- X } else {
- X c2 = *cp++;
- X if (c == '=' && c2 == '=')
- X c = LEQ;
- X ef (c == '!' && c2 == '=')
- X c = LNE;
- X ef (c == '<' && c2 == '=')
- X c = LLE;
- X ef (c == '>' && c2 == '=')
- X c = LGE;
- X else
- X cp--;
- X tok = c;
- X }
- X tokp = cp;
- X}
- X
- Xstatic struct tbl *
- Xtempvar()
- X{
- X register struct tbl *vp;
- X
- X vp = (struct tbl*) alloc(sizeof(struct tbl), ATEMP);
- X lastarea = ATEMP;
- X vp->flag = ISSET|INTEGER;
- X vp->type = 0;
- X vp->name[0] = '\0';
- X return vp;
- X}
- X
- X/* cast (string) variable to temporary integer variable */
- Xstatic struct tbl *
- Xintvar(vp)
- X register struct tbl *vp;
- X{
- X register struct tbl *vq;
- X
- X vq = tempvar();
- X vq->type = 10;
- X if (strint(vq, vp) == NULL) {
- X if ((vp->flag&ISSET) && vp->val.s && *(vp->val.s)) {
- X evalerr("bad number");
- X } else {
- X vq->flag |= (ISSET|INTEGER);
- X vq->type = 10;
- X vq->val.i = 0;
- X }
- X }
- X return vq;
- X}
- X
- END_OF_FILE
- if test 4590 -ne `wc -c <'sh/expr.c'`; then
- echo shar: \"'sh/expr.c'\" unpacked with wrong size!
- fi
- # end of 'sh/expr.c'
- fi
- if test -f 'sh/mail.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sh/mail.c'\"
- else
- echo shar: Extracting \"'sh/mail.c'\" \(4237 characters\)
- sed "s/^X//" >'sh/mail.c' <<'END_OF_FILE'
- X/*
- X * Mailbox checking code by Robert J. Gibson, adapted for PD ksh by
- X * John R. MacMillan
- X */
- X
- X#include <stddef.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include <signal.h>
- X#include <errno.h>
- X#include <setjmp.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "sh.h"
- X#include "table.h"
- X
- XVoid mcheck(); /* check for new mail */
- XVoid mbset(); /* set $MAIL */
- XVoid mpset(); /* set $MAILPATH */
- XVoid mprint(); /* print a list of mail messages */
- X
- X#define MBMESSAGE "you have mail in $_"
- X
- Xtypedef struct mbox {
- X struct mbox *mb_next; /* next mbox in list */
- X char *mb_path; /* path to mail file */
- X char *mb_msg; /* to announce arrival of new mail */
- X unsigned int mb_size; /* size of mail file (bytes) */
- X} mbox_t;
- X
- Xstruct mailmsg {
- X char *msg; /* Text of message */
- X struct mailmsg *next; /* Next message */
- X};
- X
- X/*
- X * $MAILPATH is a linked list of mboxes. $MAIL is a treated as a
- X * special case of $MAILPATH, where the list has only one node. The
- X * same list is used for both since they are exclusive.
- X */
- X
- Xstatic mbox_t *mplist = NULL;
- Xstatic mbox_t mbox = { NULL, NULL, NULL, 0 };
- Xstatic long mlastchkd = 0; /* when mail was last checked */
- Xstatic struct mailmsg *mmsgs = NULL; /* Messages to be printed */
- Xstatic Void munset(); /* free mlist and mval */
- Xstatic mbox_t *mballoc(); /* allocate a new mbox */
- Xstatic Void maddmsg();
- X
- XVoid
- Xmcheck()
- X{
- X register mbox_t *mbp;
- X long now;
- X struct tbl *vp, mailcheck;
- X struct stat stbuf;
- X
- X vp = global("MAILCHECK");
- X if (!(vp->flag & ISSET) || strint(&mailcheck, vp) == NULL)
- X return;
- X
- X if (mlastchkd == 0)
- X mlastchkd = time((long *)0);
- X
- X if ((now=time((long *)0)) - mlastchkd >= mailcheck.val.i) {
- X mlastchkd = now;
- X
- X vp = global("MAILPATH");
- X if (vp && (vp->flag & ISSET))
- X mbp = mplist;
- X else if ((vp = global("MAIL")) && (vp->flag & ISSET))
- X mbp = &mbox;
- X else
- X mbp = NULL;
- X
- X while (mbp) {
- X if (stat(mbp->mb_path, &stbuf) == 0 &&
- X (stbuf.st_mode & S_IFMT) == S_IFREG) {
- X if (mbp->mb_size < stbuf.st_size)
- X maddmsg( mbp );
- X mbp->mb_size = stbuf.st_size;
- X } else {
- X /*
- X * Some mail readers remove the mail
- X * file if all mail is read. If file
- X * does not exist, assume this is the
- X * case and set size to zero.
- X */
- X mbp->mb_size = 0;
- X }
- X mbp = mbp->mb_next;
- X }
- X }
- X}
- X
- XVoid
- Xmbset(p)
- X register char *p;
- X{
- X struct stat stbuf;
- X
- X if (mbox.mb_msg)
- X afree((Void *)mbox.mb_msg, APERM);
- X mbox.mb_path = p;
- X mbox.mb_msg = NULL;
- X if (stat(p,&stbuf) == 0 && (stbuf.st_mode & S_IFMT) == S_IFREG)
- X mbox.mb_size = stbuf.st_size;
- X else
- X mbox.mb_size = 0;
- X}
- X
- XVoid
- Xmpset(mptoparse)
- X register char *mptoparse;
- X{
- X register mbox_t *mbp;
- X register char *mpath, *mmsg, *mval;
- X
- X munset( mplist );
- X mplist = NULL;
- X mval = strsave(mptoparse, APERM);
- X while (mval) {
- X mpath = mval;
- X if ((mval = strchr(mval, ':')) != NULL) {
- X *mval ='\0', mval++;
- X }
- X if ((mmsg = strchr(mpath, '?')) != NULL) {
- X *mmsg = '\0', mmsg++;
- X }
- X mbp = mballoc(mpath, mmsg);
- X mbp->mb_next = mplist;
- X mplist = mbp;
- X }
- X}
- X
- Xstatic Void
- Xmunset(mlist)
- Xregister mbox_t *mlist;
- X{
- X register mbox_t *mbp;
- X
- X while (mlist != NULL) {
- X mbp = mlist;
- X mlist = mbp->mb_next;
- X if (!mlist)
- X afree((Void *)mbp->mb_path, APERM);
- X afree((Void *)mbp, APERM);
- X }
- X}
- X
- Xstatic mbox_t *
- Xmballoc(p, m)
- X char *p;
- X char *m;
- X{
- X struct stat stbuf;
- X register mbox_t *mbp;
- X
- X mbp = (mbox_t *)alloc(sizeof(mbox_t), APERM);
- X mbp->mb_next = NULL;
- X mbp->mb_path = p;
- X mbp->mb_msg = m;
- X if (stat(mbp->mb_path, &stbuf) == 0 &&
- X (stbuf.st_mode & S_IFMT) == S_IFREG) {
- X mbp->mb_size = stbuf.st_size;
- X } else {
- X mbp->mb_size = 0;
- X }
- X return(mbp);
- X}
- X
- XVoid
- Xmprint()
- X{
- X struct mailmsg *mm;
- X
- X while ((mm = mmsgs) != NULL) {
- X shellf( "%s\n", mm->msg );
- X fflush(shlout);
- X afree((Void *)mm->msg, APERM);
- X mmsgs = mm->next;
- X afree((Void *)mm, APERM);
- X }
- X}
- X
- Xstatic Void
- Xmaddmsg( mbp )
- Xmbox_t *mbp;
- X{
- X struct mailmsg *message;
- X struct tbl *vp;
- X
- X message = (struct mailmsg *)alloc(sizeof(struct mailmsg), APERM);
- X setstr((vp = typeset("_", LOCAL, 0)), mbp->mb_path);
- X
- X if (mbp->mb_msg)
- X message->msg = strsave(substitute(mbp->mb_msg,0),APERM);
- X else
- X message->msg = strsave(substitute(MBMESSAGE,0),APERM);
- X
- X unset(vp);
- X message->next = mmsgs;
- X mmsgs = message;
- X}
- END_OF_FILE
- if test 4237 -ne `wc -c <'sh/mail.c'`; then
- echo shar: \"'sh/mail.c'\" unpacked with wrong size!
- fi
- # end of 'sh/mail.c'
- fi
- if test -f 'sh/misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sh/misc.c'\"
- else
- echo shar: Extracting \"'sh/misc.c'\" \(6802 characters\)
- sed "s/^X//" >'sh/misc.c' <<'END_OF_FILE'
- X/*
- X * Miscellaneous functions
- X */
- X
- Xstatic char *RCSid = "$Id: misc.c,v 3.2 89/03/27 15:51:44 egisin Exp $";
- X
- X#include <stddef.h>
- X#include <limits.h>
- X#include <string.h>
- X#include <signal.h>
- X#include <errno.h>
- X#include <setjmp.h>
- X#include "sh.h"
- X#include "expand.h"
- X
- Xchar ctypes [UCHAR_MAX+1]; /* type bits for unsigned char */
- X
- X/*
- X * Fast character classes
- X */
- Xvoid
- Xsetctypes(s, t)
- X register Const char *s;
- X register int t;
- X{
- X register int i;
- X
- X if ((t&C_IFS)) {
- X for (i = 0; i < UCHAR_MAX+1; i++)
- X ctypes[i] &=~ C_IFS;
- X ctypes[0] |= C_IFS; /* include \0 in C_IFS */
- X }
- X ctypes[(unsigned char) *s++] |= t; /* allow leading \0 in string */
- X while (*s != 0)
- X ctypes[(unsigned char) *s++] |= t;
- X}
- X
- Xvoid
- Xinitctypes()
- X{
- X register int c;
- X
- X for (c = 'a'; c <= 'z'; c++)
- X ctypes[c] |= C_ALPHA;
- X for (c = 'A'; c <= 'Z'; c++)
- X ctypes[c] |= C_ALPHA;
- X ctypes['_'] |= C_ALPHA;
- X setctypes("0123456789", C_DIGIT);
- X setctypes("\0 \t\n|&;<>()", C_LEX1);
- X setctypes("*@#!$-?", C_VAR1);
- X setctypes("=-+?#%", C_SUBOP);
- X}
- X
- X/* convert unsigned long to base N string */
- X
- Xchar *
- Xulton(n, base)
- X register unsigned long n;
- X int base;
- X{
- X register char *p;
- X static char buf [20];
- X
- X p = &buf[sizeof(buf)];
- X *--p = '\0';
- X do {
- X *--p = "0123456789ABCDEF"[n%base];
- X n /= base;
- X } while (n != 0);
- X return p;
- X}
- X
- Xchar *
- Xstrsave(s, ap)
- X register char *s;
- X Area *ap;
- X{
- X return strcpy((char*) alloc((size_t)strlen(s)+1, ap), s);
- X}
- X
- Xstatic struct option {
- X char *name;
- X int flag;
- X} options[] = {
- X {"allexport", FEXPORT},
- X {"bgnice", FBGNICE},
- X#if defined(EDIT) && defined(EMACS)
- X {"emacs", FEMACS},
- X#endif
- X {"errexit", FERREXIT},
- X {"hashall", FHASHALL},
- X {"ignoreeof", FIGNEOF},
- X {"interactive", FTALKING},
- X {"keyword", FKEYWORD},
- X {"markdirs", FMARKDIRS},
- X {"monitor", FMONITOR},
- X {"noexec", FNOEXEC},
- X {"noglob", FNOGLOB},
- X {"nounset", FNOUNSET},
- X {"privileged", FPRIVILEGED},
- X {"stdin", FSTDIN},
- X {"trackall", FHASHALL},
- X {"verbose", FVERBOSE},
- X#if defined(EDIT) && defined(VI)
- X {"vi", FVI},
- X#endif
- X {"xtrace", FXTRACE},
- X {NULL, 0}
- X};
- X
- X/*
- X * translate -o option into F* constant
- X */
- Xint
- Xoption(n)
- X Const char *n;
- X{
- X register struct option *op;
- X
- X for (op = options; op->name != NULL; op++)
- X if (strcmp(op->name, n) == 0)
- X return op->flag;
- X return 0;
- X}
- X
- Xchar *
- Xgetoptions()
- X{
- X register int c;
- X char m [26+1];
- X register char *cp = m;
- X
- X for (c = 'a'; c <= 'z'; c++)
- X if (flag[FLAG(c)])
- X *cp++ = (char) c;
- X *cp = 0;
- X return strsave(m, ATEMP);
- X}
- X
- Xvoid
- Xprintoptions()
- X{
- X register struct option *op;
- X
- X for (op = options; op->name != NULL; op++)
- X if (flag[op->flag])
- X shellf("%s ", op->name);
- X shellf("\n");
- X}
- X
- X/* atoi with error detection */
- X
- Xgetn(as)
- X char *as;
- X{
- X register char *s;
- X register int n;
- X
- X s = as;
- X if (*s == '-')
- X s++;
- X for (n = 0; digit(*s); s++)
- X n = (n*10) + (*s-'0');
- X if (*s)
- X errorf("%s: bad number\n", as);
- X return (*as == '-') ? -n : n;
- X}
- X
- X/*
- X * stripped down strerror for kill and exec
- X */
- Xchar *
- Xstrerror(i)
- X int i;
- X{
- X switch (i) {
- X case EINVAL:
- X return "Invalid argument";
- X case EACCES:
- X return "Permission denied";
- X case ESRCH:
- X return "No such process";
- X case EPERM:
- X return "Not owner";
- X case ENOENT:
- X return "No such file or directory";
- X case ENOTDIR:
- X return "Not a directory";
- X case ENOEXEC:
- X return "Exec format error";
- X case ENOMEM:
- X return "Not enough memory";
- X case E2BIG:
- X return "Argument list too long";
- X default:
- X return "Unknown system error";
- X }
- X}
- X
- X/* -------- gmatch.c -------- */
- X
- X/*
- X * int gmatch(string, pattern)
- X * char *string, *pattern;
- X *
- X * Match a pattern as in sh(1).
- X * pattern character are prefixed with MAGIC by expand.
- X */
- X
- Xstatic char *cclass ARGS((char *, int c));
- X
- Xint
- Xgmatch(s, p)
- X register char *s, *p;
- X{
- X register int sc, pc;
- X
- X if (s == NULL || p == NULL)
- X return 0;
- X while ((pc = *p++) != 0) {
- X sc = *s++;
- X if (pc == MAGIC)
- X switch (*p++) {
- X case '[':
- X if (sc == 0 || (p = cclass(p, sc)) == NULL)
- X return (0);
- X break;
- X
- X case '?':
- X if (sc == 0)
- X return (0);
- X break;
- X
- X case '*':
- X s--;
- X do {
- X if (*p == '\0' || gmatch(s, p))
- X return (1);
- X } while (*s++ != '\0');
- X return (0);
- X
- X default:
- X if (sc != p[-1])
- X return 0;
- X break;
- X }
- X else
- X if (sc != pc)
- X return 0;
- X }
- X return (*s == 0);
- X}
- X
- Xstatic char *
- Xcclass(p, sub)
- X register char *p;
- X register int sub;
- X{
- X register int c, d, not, found = 0;
- X
- X if ((not = (*p == MAGIC && *++p == NOT)))
- X p++;
- X do {
- X if (*p == MAGIC)
- X p++;
- X if (*p == '\0')
- X return NULL;
- X c = *p;
- X if (p[1] == '-' && p[2] != ']') {
- X d = p[2];
- X p++;
- X } else
- X d = c;
- X if (c == sub || c <= sub && sub <= d)
- X found = 1;
- X } while (*++p != ']');
- X
- X return (found != not) ? p+1 : NULL;
- X}
- X
- X/* -------- qsort.c -------- */
- X
- X/*
- X * quick sort of array of generic pointers to objects.
- X */
- X
- Xvoid
- Xqsortp(base, n, f)
- X Void **base; /* base address */
- X size_t n; /* elements */
- X int (*f)(); /* compare function */
- X{
- X qsort1(base, base + n, f);
- X}
- X
- X#define swap2(a, b) {\
- X register Void *t; t = *(a); *(a) = *(b); *(b) = t;\
- X}
- X#define swap3(a, b, c) {\
- X register Void *t; t = *(a); *(a) = *(c); *(c) = *(b); *(b) = t;\
- X}
- X
- Xqsort1(base, lim, f)
- X Void **base, **lim;
- X int (*f)();
- X{
- X register Void **i, **j;
- X register Void **lptr, **hptr;
- X size_t n;
- X int c;
- X
- X top:
- X n = (lim - base) / 2;
- X if (n == 0)
- X return;
- X hptr = lptr = base+n;
- X i = base;
- X j = lim - 1;
- X
- X for (;;) {
- X if (i < lptr) {
- X if ((c = (*f)(*i, *lptr)) == 0) {
- X lptr --;
- X swap2(i, lptr);
- X continue;
- X }
- X if (c < 0) {
- X i += 1;
- X continue;
- X }
- X }
- X
- X begin:
- X if (j > hptr) {
- X if ((c = (*f)(*hptr, *j)) == 0) {
- X hptr ++;
- X swap2(hptr, j);
- X goto begin;
- X }
- X if (c > 0) {
- X if (i == lptr) {
- X hptr ++;
- X swap3(i, hptr, j);
- X i = lptr += 1;
- X goto begin;
- X }
- X swap2(i, j);
- X j -= 1;
- X i += 1;
- X continue;
- X }
- X j -= 1;
- X goto begin;
- X }
- X
- X if (i == lptr) {
- X if (lptr-base >= lim-hptr) {
- X qsort1(hptr+1, lim, f);
- X lim = lptr;
- X } else {
- X qsort1(base, lptr, f);
- X base = hptr+1;
- X }
- X goto top;
- X }
- X
- X lptr -= 1;
- X swap3(j, lptr, i);
- X j = hptr -= 1;
- X }
- X}
- X
- Xint
- Xxstrcmp(p1, p2)
- X Void *p1, *p2;
- X{
- X return (strcmp((char *)p1, (char *)p2));
- X}
- X
- XVoid
- Xcleanpath(pwd, dir, clean)
- X char *pwd, *dir, *clean;
- X{
- X register char *s, *d, *p;
- X char *slash = "/";
- X register int inslash = 0;
- X
- X d = clean;
- X if (*dir != '/') {
- X s = pwd;
- X while (*d++ = *s++)
- X ;
- X *(d - 1) = '/';
- X }
- X
- X s = dir;
- X while (*s) {
- X if ((*d++ = *s++) == '/' && d > clean + 1) {
- X if (*(p = d - 2) == '/') {
- X --d;
- X } else if (*p == '.') {
- X if (*--p == '/') {
- X d -= 2;
- X } else if (*p == '.' && *--p == '/') {
- X while (p > clean && *--p != '/')
- X ;
- X d = p + 1;
- X }
- X }
- X }
- X if (!*s && !inslash && *(s - 1) != '/') {
- X inslash = 1;
- X s = slash;
- X }
- X }
- X
- X if (*(d - 1) == '/' && (d - 1) > clean)
- X d--;
- X *d = '\0';
- X}
- END_OF_FILE
- if test 6802 -ne `wc -c <'sh/misc.c'`; then
- echo shar: \"'sh/misc.c'\" unpacked with wrong size!
- fi
- # end of 'sh/misc.c'
- fi
- if test -f 'sh/sh.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sh/sh.h'\"
- else
- echo shar: Extracting \"'sh/sh.h'\" \(7087 characters\)
- sed "s/^X//" >'sh/sh.h' <<'END_OF_FILE'
- X/*
- X * Public Domain Bourne/Korn shell
- X */
- X
- X/* $Id: sh.h,v 3.3 89/03/27 15:46:34 egisin Exp $ */
- X
- X#include "config.h"
- X
- X/* allow for non-Unix linkers. main.c has a "#define Extern " */
- X#ifndef Extern
- X#define Extern extern
- X#endif
- X
- X#ifndef SHELL
- X#define SHELL "/bin/sh" /* shell to exec scripts */
- X#endif
- X
- X/* some people object to this use of __STDC__ */
- X#if __STDC__
- X#define ARGS(args) args /* prototype declaration */
- X#define Void void /* generic pointer */
- X#define Const const /* constant data */
- X#define Volatile volatile /* you know */
- X#else
- X#define ARGS(args) () /* K&R declaration */
- X#define Void char
- X#define Const
- X#define Volatile
- X#endif
- X
- X#ifdef _ULTRIX /* Ultrix 2.x gets dup2 wrong */
- Xint dup2 ARGS ((int, int));
- X/* assumes we don't want dup2 return value */
- X#define dup2(ofd, nfd) \
- X (void) ((dup2)(ofd, nfd), fcntl(nfd, F_SETFD, 0))
- X#endif
- X
- X#if defined(EMACS) || defined(VI)
- X#define EDIT
- X#endif
- X
- Xtypedef int bool_t;
- X#define FALSE 0
- X#define TRUE 1
- X
- X#define sizeofN(type, n) (sizeof(type) * (n))
- X#define BIT(i) (1<<(i)) /* define bit in flag */
- X
- X#define NUFILE 10 /* Number of user-accessible files */
- X#define FDBASE 10 /* First file usable by Shell */
- X
- X/* you're not going to run setuid shell scripts, are you? */
- X#define eaccess(path, mode) access(path, mode)
- X
- X#define MAGIC (char)0x80 /* prefix for ~*?[ during expand */
- X#define NOT '!' /* might use ^ */
- X
- X#define LINE 256 /* input line size */
- X#define PATH 256 /* pathname size */
- X
- XExtern int kshpid; /* $$, shell pid */
- XExtern int exstat; /* exit status */
- XExtern int async; /* $!, last &'d pid */
- X
- X/*
- X * Area-based allocation built on malloc/free
- X */
- X
- Xtypedef struct Area {
- X struct Block *free; /* free list */
- X} Area;
- X
- Xextern Area aperm; /* permanent object space */
- X#define APERM &aperm
- X#define ATEMP &e.area
- X
- XArea *ainit ARGS((Area *ap)); /* initialize Area */
- Xvoid afreeall ARGS((Area *ap)); /* free Area's contents */
- Xvoid ashrink ARGS((Area *ap)); /* unimplimented */
- Xvoid aerror ARGS((Area *ap, const char *msg)); /* error handler */
- X
- XVoid *alloc ARGS((size_t size, Area *ap)); /* alloc object from Area */
- XVoid *aresize ARGS((Void *ptr, size_t size, Area *ap)); /* shrink object */
- Xvoid afree ARGS((Void *ptr, Area *ap)); /* free ojbect in Area */
- X
- X/*
- X * parsing & execution environment
- X */
- XExtern struct env {
- X int type; /* enviroment type - see below */
- X Area area; /* temporary allocation area */
- X struct block *loc; /* local variables and functions */
- X short *savefd; /* original redirected fd's */
- X struct env *oenv; /* link to previous enviroment */
- X jmp_buf jbuf; /* long jump back to env creator */
- X int interactive; /* fd's 0,1,2 are tty */
- X struct temp *temps; /* temp files */
- X} e;
- X
- X#define E_NONE 0 /* dummy enviroment */
- X#define E_PARSE 1 /* parsing command # */
- X#define E_EXEC 2 /* executing command tree */
- X#define E_LOOP 3 /* executing for/while # */
- X#define E_TCOM 5 /* executing simple command */
- X#define E_FUNC 6 /* executing function */
- X#define E_ERRH 7 /* general error handler # */
- X/* # indicates env has valid jbuf */
- X
- X/*
- X * flags
- X */
- X#define FEXPORT FLAG('a') /* -a: allexport */
- X#define FERREXIT FLAG('e') /* -e: errexit (quit on error) */
- X#define FBGNICE 29 /* bgnice */
- X#define FEMACS 30 /* emacs command editing */
- X#define FIGNEOF 27 /* ignoreeof (eof does not exit) */
- X#define FHASHALL FLAG('h') /* -h: trackall, hashall */
- X#define FTALKING FLAG('i') /* -i: interactive (talking type wireless) */
- X#define FKEYWORD FLAG('k') /* -k: keyword (name=value anywhere) */
- X#define FMARKDIRS 28 /* markdirs */
- X#define FMONITOR FLAG('m') /* -m: monitor */
- X#define FNOEXEC FLAG('n') /* -n: noexec */
- X#define FNOGLOB FLAG('f') /* -f: noglob */
- X#define FPRIVILEGED FLAG('p') /* -p: privileged */
- X#define FSTDIN FLAG('s') /* -s (invocation): parse stdin */
- X#define FNOUNSET FLAG('u') /* -u: nounset (unset vars is error) */
- X#define FVERBOSE FLAG('v') /* -v: verbose (echo input) */
- X#define FVI 31 /* vi command editing */
- X#define FXTRACE FLAG('x') /* -x: (execute) xtrace */
- X
- X#define FLAG(c) (1 + c - 'a') /* map char to flags index */
- X#define FLAGS 32
- XExtern char flag [FLAGS];
- Xint option ARGS((Const char *name));
- Xchar *getoptions ARGS((void));
- Xvoid printoptions ARGS((void));
- X
- Xextern char null []; /* null value for variable */
- X
- X/*
- X * other functions
- X */
- Xchar *search();
- Xstruct tbl *findcom();
- Xchar *strsave ARGS((char *, Area *));
- Xchar *ulton ARGS((unsigned long n, int base));
- Xint xstrcmp();
- Xvoid qsortp ARGS((void **base, size_t n, int (*compare)(void *, void *)));
- Xlong evaluate ARGS((Const char *expr));
- Xvoid resetopts();
- Xvoid histsave();
- Xvoid histlist();
- X
- Xvoid j_init ARGS((void));
- Xvoid j_exit ARGS((void));
- Xvoid j_notify ARGS((void));
- Xvoid j_kill ARGS((int job, int sig));
- X#ifdef JOBS
- Xvoid j_change ARGS((void));
- Xint j_resume ARGS((int job, int bg));
- X#endif
- X
- X/*
- X * error handling
- X */
- Xvoid leave(); /* abort shell (or fail in subshell) */
- X
- X/*
- X * library functions
- X */
- Xtypedef void (*handler_t)(); /* signal handler */
- X
- X/* temp/here files. the file is removed when the struct is freed */
- Xstruct temp {
- X struct temp * next;
- X char *name;
- X};
- Xstruct temp *maketemp ARGS((Area *ap));
- X
- X/*
- X * stdio and our IO routines
- X */
- X
- X#ifdef BUFSIZ /* <stdio.h> included? */
- Xextern FILE * shf [NUFILE]; /* map shell fd to FILE */
- X#endif
- Xvoid fopenshf();
- Xvoid flushshf();
- X
- X#undef stdin
- X#undef stdout
- X
- X#define stdin shf[0] /* standard input */
- X#define stdout shf[1] /* standard output */
- X#define shlout shf[2] /* shell output */
- X
- Xint shellf ARGS((Const char *fmt, ...)); /* fprintf(shlout, ); */
- Xint errorf ARGS((Const char *fmt, ...)); /* fprintf(shlout, ); error(); */
- X
- X/*
- X * IO control
- X */
- Xextern int ttyfd; /* tty fd (original fd 0) */
- X
- Xint savefd ARGS((int fd)); /* save user fd */
- Xvoid restfd ARGS((int fd, int ofd));
- Xvoid openpipe ARGS((int [2]));
- Xvoid closepipe ARGS((int [2]));;
- X
- X/*
- X * trap handlers
- X */
- Xtypedef struct trap {
- X int signal; /* signal number */
- X char *name; /* short name */
- X char *mess; /* descriptive name */
- X char *trap; /* trap command */
- X int Volatile set; /* trap pending */
- X int ourtrap; /* not ignored (?) */
- X int sig_dfl; /* originally SIG_DFL */
- X} Trap;
- X
- X#ifndef SIGKILL
- X#include <signal.h>
- X#endif /* SIGKILL */
- X#ifdef NSIG
- X#define SIGNALS NSIG
- X#else
- X#define SIGNALS 32
- X#endif /* NSIG */
- X
- XExtern int Volatile trap; /* traps pending? */
- Xextern Trap sigtraps[SIGNALS];
- XTrap *gettrap ARGS((char *)); /* search for struct trap by number or name */
- Xvoid trapsig ARGS((int sig)); /* trap signal handler */
- X
- X/*
- X * fast character classes
- X */
- X#define C_ALPHA 0x01 /* a-z_A-Z */
- X#define C_DIGIT 0x02 /* 0-9 */
- X#define C_LEX1 0x04 /* \0 \t\n|&;<>() */
- X#define C_VAR1 0x08 /* *@#!$-? */
- X#define C_SUBOP 0x40 /* "=-+?#%" */
- X#define C_IFS 0x80 /* $IFS */
- X
- Xextern char ctypes [];
- Xvoid initctypes ARGS((void));
- Xvoid setctypes ARGS((Const char*, int type));
- X
- X#define ctype(c, t) !!(ctypes[(unsigned char)(c)]&(t))
- X#define letter(c) ctype(c, C_ALPHA)
- X#define digit(c) ctype(c, C_DIGIT)
- X#define letnum(c) ctype(c, C_ALPHA|C_DIGIT)
- X
- X/*
- X * 91-07-06 <sjg@sun0>
- X * use my simple debug tracing...
- X */
- X#include "trace.h"
- X
- END_OF_FILE
- if test 7087 -ne `wc -c <'sh/sh.h'`; then
- echo shar: \"'sh/sh.h'\" unpacked with wrong size!
- fi
- # end of 'sh/sh.h'
- fi
- if test -f 'sh/table.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sh/table.c'\"
- else
- echo shar: Extracting \"'sh/table.c'\" \(3715 characters\)
- sed "s/^X//" >'sh/table.c' <<'END_OF_FILE'
- Xstatic char *RCSid = "$Id: table.c,v 3.2 89/03/27 15:51:58 egisin Exp $";
- X
- X/*
- X * dynamic hashed associative table for commands and variables
- X */
- X
- X#include <stddef.h>
- X#include <errno.h>
- X#include <setjmp.h>
- X#include "sh.h"
- X#include "table.h"
- X
- X#define INIT_TBLS 8 /* initial table size (power of 2) */
- X
- Xstatic struct tstate {
- X int left;
- X struct tbl **next;
- X} tstate;
- X
- Xstatic void texpand();
- X
- Xunsigned int
- Xhash(n)
- X register char * n;
- X{
- X register unsigned int h = 0;
- X
- X while (*n != '\0')
- X h = 2*h + *n++;
- X return h * 32821; /* scatter bits */
- X}
- X
- X#if 0
- Xphash(s) char *s; {
- X printf("%2d: %s\n", hash(s)%32, s);
- X}
- X#endif
- X
- Xvoid
- Xtinit(tp, ap)
- X register struct table *tp;
- X register Area *ap;
- X{
- X tp->areap = ap;
- X tp->size = tp->free = 0;
- X tp->tbls = NULL;
- X}
- X
- Xstatic void
- Xtexpand(tp, nsize)
- X register struct table *tp;
- X int nsize;
- X{
- X register int i;
- X register struct tbl *tblp, **p;
- X register struct tbl **ntblp, **otblp = tp->tbls;
- X int osize = tp->size;
- X
- X ntblp = (struct tbl**) alloc(sizeofN(struct tbl *, nsize), tp->areap);
- X for (i = 0; i < nsize; i++)
- X ntblp[i] = NULL;
- X tp->size = nsize;
- X tp->free = 8*nsize/10; /* table can get 80% full */
- X tp->tbls = ntblp;
- X if (otblp == NULL)
- X return;
- X for (i = 0; i < osize; i++)
- X if ((tblp = otblp[i]) != NULL)
- X if ((tblp->flag&DEFINED)) {
- X for (p = &ntblp[hash(tblp->name) & tp->size-1];
- X *p != NULL; p--)
- X if (p == ntblp) /* wrap */
- X p += tp->size;
- X *p = tblp;
- X tp->free--;
- X } else {
- X afree((Void*)tblp, tp->areap);
- X }
- X afree((Void*)otblp, tp->areap);
- X}
- X
- Xstruct tbl *
- Xtsearch(tp, n, h)
- X register struct table *tp; /* table */
- X register char *n; /* name to enter */
- X unsigned int h; /* hash(n) */
- X{
- X register struct tbl **pp, *p;
- X
- X if (tp->size == 0)
- X return NULL;
- X
- X /* search for name in hashed table */
- X for (pp = &tp->tbls[h & tp->size-1]; (p = *pp) != NULL; pp--) {
- X if (*p->name == *n && strcmp(p->name, n) == 0
- X && (p->flag&DEFINED))
- X return p;
- X if (pp == tp->tbls) /* wrap */
- X pp += tp->size;
- X }
- X
- X return NULL;
- X}
- X
- Xstruct tbl *
- Xtenter(tp, n, h)
- X register struct table *tp; /* table */
- X register char *n; /* name to enter */
- X unsigned int h; /* hash(n) */
- X{
- X register struct tbl **pp, *p;
- X register char *cp;
- X
- X if (tp->size == 0)
- X texpand(tp, INIT_TBLS);
- X Search:
- X /* search for name in hashed table */
- X for (pp = &tp->tbls[h & tp->size-1]; (p = *pp) != NULL; pp--) {
- X if (*p->name == *n && strcmp(p->name, n) == 0)
- X return p; /* found */
- X if (pp == tp->tbls) /* wrap */
- X pp += tp->size;
- X }
- X
- X if (tp->free <= 0) { /* too full */
- X texpand(tp, 2*tp->size);
- X goto Search;
- X }
- X
- X /* create new tbl entry */
- X for (cp = n; *cp != '\0'; cp++)
- X ;
- X p = (struct tbl *) alloc(offsetof(struct tbl, name[(cp-n)+1]), tp->areap);
- X p->flag = 0;
- X p->type = 0;
- X for (cp = p->name; *n != '\0';)
- X *cp++ = *n++;
- X *cp = '\0';
- X
- X /* enter in tp->tbls */
- X tp->free--;
- X *pp = p;
- X return p;
- X}
- X
- Xvoid
- Xtdelete(p)
- X register struct tbl *p;
- X{
- X p->flag = 0;
- X}
- X
- Xvoid
- Xtwalk(tp)
- X register struct table *tp;
- X{
- X tstate.left = tp->size;
- X tstate.next = tp->tbls;
- X}
- X
- Xstruct tbl *
- Xtnext()
- X{
- X while (--tstate.left >= 0) {
- X struct tbl *p = *tstate.next++;
- X if (p != NULL && (p->flag&DEFINED))
- X return p;
- X }
- X return NULL;
- X}
- X
- Xstatic int
- Xtnamecmp(p1, p2)
- X Void *p1, *p2;
- X{
- X return strcmp(((struct tbl *)p1)->name, ((struct tbl *)p2)->name);
- X}
- X
- Xstruct tbl **
- Xtsort(tp)
- X register struct table *tp;
- X{
- X register int i;
- X register struct tbl **p, **sp, **dp;
- X
- X p = (struct tbl **)alloc(sizeofN(struct tbl *, tp->size+1), ATEMP);
- X sp = tp->tbls; /* source */
- X dp = p; /* dest */
- X for (i = 0; i < tp->size; i++)
- X if ((*dp = *sp++) != NULL && ((*dp)->flag&DEFINED))
- X dp++;
- X i = dp - p;
- X qsortp((Void**)p, (size_t)i, tnamecmp);
- X p[i] = NULL;
- X return p;
- X}
- X
- END_OF_FILE
- if test 3715 -ne `wc -c <'sh/table.c'`; then
- echo shar: \"'sh/table.c'\" unpacked with wrong size!
- fi
- # end of 'sh/table.c'
- fi
- if test -f 'sh/ulimit.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sh/ulimit.c'\"
- else
- echo shar: Extracting \"'sh/ulimit.c'\" \(2799 characters\)
- sed "s/^X//" >'sh/ulimit.c' <<'END_OF_FILE'
- X/*
- X ulimit -- handle "ulimit" builtin
- X
- X Eric Gisin, September 1988
- X Adapted to PD KornShell. Removed AT&T code.
- X
- X last edit: 06-Jun-1987 D A Gwyn
- X
- X This started out as the BRL UNIX System V system call emulation
- X for 4.nBSD, and was later extended by Doug Kingston to handle
- X the extended 4.nBSD resource limits. It now includes the code
- X that was originally under case SYSULIMIT in source file "xec.c".
- X*/
- X
- Xstatic char *RCSid = "$Id: ulimit.c,v 3.2 89/03/27 15:52:19 egisin Exp $";
- X
- X#include <stddef.h>
- X#include <errno.h>
- X#include <signal.h>
- X#include <setjmp.h>
- X#if defined(_BSD) || defined(_BSD_SYSV)
- X#include <sys/time.h>
- X#include <sys/resource.h>
- X#else
- X#define RLIMIT_FSIZE 2
- X#endif
- X#include "sh.h"
- X
- Xextern long ulimit();
- X
- Xint
- Xdo_ulimit(a1, a2)
- X char *a1, *a2;
- X{
- X register int c;
- X long i;
- X#if defined(_BSD) || defined(_BSD_SYSV)
- X struct rlimit limit; /* data being gotten/set */
- X int softonly = 0; /* set => soft limit, clear => hard limit */
- X int factor = 1024; /* unit scaling (1K or 1) */
- X#endif
- X int command = RLIMIT_FSIZE;
- X
- X if (a1 && (*a1 == '-')) /* DAG -- Gould added first test */
- X { c = *++a1; /* DAG */
- X#if defined(_BSD) || defined(_BSD_SYSV)
- X if (c >= 'A' && c <= 'Z')
- X {
- X ++softonly;
- X c += 'a' - 'A'; /* DAG -- map to lower-case */
- X }
- X#endif
- X switch(c)
- X {
- X#if defined(_BSD) || defined(_BSD_SYSV)
- X case 'c':
- X command = RLIMIT_CORE;
- X break;
- X case 'd':
- X command = RLIMIT_DATA;
- X break;
- X case 'm':
- X command = RLIMIT_RSS;
- X break;
- X case 's':
- X command = RLIMIT_STACK;
- X break;
- X case 't':
- X factor = 1;
- X command = RLIMIT_CPU;
- X break;
- X#endif /* _BSD || _BSD_SYSV */
- X case 'f':
- X command = RLIMIT_FSIZE;
- X#if _BSD_SYSV
- X factor = 512;
- X#endif
- X break;
- X default:
- X#if _BSD
- X errorf("Usage: %s [-cdmstf] [limit]\n", "ulimit");
- X#else
- X errorf("Usage: %s [-f] [limit]\n", "ulimit");
- X#endif
- X }
- X a1 = a2;
- X }
- X if (a1)
- X {
- X i = 0;
- X while ((c = *a1++) >= '0' && c <= '9')
- X {
- X i = (i * 10) + (long)(c - '0');
- X if (i < 0)
- X goto Error;
- X }
- X if (c || i < 0)
- X goto Error;
- X }
- X#if !(defined(_BSD) || defined(_BSD_SYSV))
- X else
- X {
- X i = -1;
- X command--;
- X }
- X
- X if ((i = ulimit(command, i)) < 0L)
- X goto Error;
- X
- X if (command != RLIMIT_FSIZE)
- X shellf("%ld\n", i);
- X#else /* DPK -- generalized for 4.nBSD: */
- X if (getrlimit(command, &limit))
- X goto Error; /* errno is already set */
- X
- X if (a1)
- X {
- X limit.rlim_cur = i * factor;
- X
- X if (!softonly)
- X limit.rlim_max = limit.rlim_cur;
- X
- X if (setrlimit(command, &limit))
- X goto Error;
- X }
- X else
- X {
- X i = softonly ? limit.rlim_cur : limit.rlim_max;
- X#if _BSD /* DAG -- System V always prints an integer */
- X if (i == RLIM_INFINITY)
- X shellf("unlimited\n");
- X else
- X#endif
- X shellf("%ld\n", i/factor);
- X }
- X#endif /* _BSD || _BSD_SYSV */
- X return 0;
- X
- X Error:
- X errorf("bad ulimit\n");
- X}
- X
- END_OF_FILE
- if test 2799 -ne `wc -c <'sh/ulimit.c'`; then
- echo shar: \"'sh/ulimit.c'\" unpacked with wrong size!
- fi
- # end of 'sh/ulimit.c'
- fi
- if test -f 'std/stdc/vprintf.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'std/stdc/vprintf.c'\"
- else
- echo shar: Extracting \"'std/stdc/vprintf.c'\" \(4964 characters\)
- sed "s/^X//" >'std/stdc/vprintf.c' <<'END_OF_FILE'
- X#if __STDC__
- X#include <stdarg.h>
- X#else
- X#include <varargs.h>
- X#endif
- X#include <stdio.h>
- X
- X#define BUF 40 /* buffer for int -> string conversion */
- X
- Xint
- X#if __STDC__
- Xvprintf(Const char *fmt, va_list va) {
- X#else
- Xvprintf(fmt, va) char *fmt; va_list va; {
- X#endif
- X return vfprintf(stdout, fmt, va);
- X}
- X
- Xint
- X#if __STDC__
- Xvfprintf(register FILE *f, register Const char *fmt, register va_list va) {
- X#else
- Xvfprintf(f, fmt, va) register FILE *f; register char *fmt; register va_list va; {
- X#endif
- X register int c;
- X int pos = 0; /* todo: implement */
- X
- X while ((c = *fmt++))
- X if (c == '%') {
- X long n;
- X register unsigned long u;
- X char buf [BUF+1];
- X register char *p = buf + BUF;
- X register enum {
- X FF_ALT = 0x01, /* #, alternate format */
- X FF_SHORT = 0x02, /* h, short arg */
- X FF_LONG = 0x04, /* l, long arg */
- X FF_ZERO = 0x08, /* 0, zero fill */
- X FF_LEFT = 0x10, /* -, left adjust */
- X FF_PREC = 0x20, /* .*, precision */
- X FF_NEG = 0x40, /* signed arg */
- X FF_PUTS = 0x80, /* fputs(p, f) */
- X FF_DEFAULT = 0
- X } flags = FF_DEFAULT;
- X int sign = '-'; /* sign: [ +-] */
- X int width = 0, prec = 0; /* width, precision */
- X
- X *p = 0;
- X
- X /* scan flag characters */
- X for (c = *fmt++; ; c = *fmt++) switch (c) {
- X case '0':
- X flags |= FF_ZERO;
- X break;
- X
- X case '#': /* alternate format */
- X flags |= FF_ALT;
- X break;
- X
- X case ' ': /* blank sign */
- X sign = ' ';
- X break;
- X case '+': /* +/- sign */
- X sign = '+';
- X break;
- X
- X case '-': /* left just. */
- X flags |= FF_LEFT;
- X break;
- X
- X default:
- X goto Frogs;
- X }
- X Frogs:
- X
- X /* scan width */
- X if (c == '*') { /* width from arg list */
- X width = va_arg(va, int);
- X c = *fmt++;
- X } else
- X while ('0' <= c && c <= '9') {
- X width = width*10 + (c-'0');
- X c = *fmt++;
- X }
- X
- X if (c == '.') { /* scan precision */
- X flags |= FF_PREC;
- X c = *fmt++;
- X if (c == '*') { /* precision from arg list */
- X prec = va_arg(va, int);
- X c = *fmt++;
- X } else
- X while ('0' <= c && c <= '9') {
- X prec = prec*10 + (c-'0');
- X c = *fmt++;
- X }
- X }
- X
- X /* length modifiers */
- X if (c == 'h') {
- X flags |= FF_SHORT;
- X c = *fmt++;
- X } else if (c == 'l') {
- X flags |= FF_LONG;
- X c = *fmt++;
- X }
- X
- X /* do conversion */
- X switch (c) {
- X case '%': /* %% -> % */
- X putc(c, f);
- X pos ++;
- X break;
- X
- X case 'p': /* pointer */
- X *--p = '}';
- X u = (unsigned long) va_arg(va, Void*);
- X do {
- X *--p = "0123456789ABCDEF"[u%16];
- X u /= 16;
- X } while (u != 0);
- X *--p = '{';
- X flags |= FF_PUTS;
- X break;
- X
- X case 'n': /* save position */
- X *va_arg(va, int*) = pos;
- X break;
- X
- X case 'c': /* character */
- X u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
- X : (flags&&FF_LONG) ? va_arg(va, unsigned long)
- X : va_arg(va, unsigned int);
- X *--p = u;
- X flags |= FF_PUTS;
- X break;
- X
- X case 's': /* string */
- X p = va_arg(va, char *);
- X if ((flags&FF_PREC) && strlen(p) > prec) {
- X pos += prec;
- X while (--prec >= 0)
- X putc(*p++, f);
- X break;
- X }
- X flags |= FF_PUTS;
- X break;
- X
- X case 'i': case 'd': case 'u': /* decimal */
- X if (c != 'u') { /* signed */
- X n = (flags&FF_SHORT) ? va_arg(va, short)
- X : (flags&&FF_LONG) ? va_arg(va, long)
- X : va_arg(va, int);
- X if (n < 0)
- X flags |= FF_NEG;
- X u = (n < 0) ? -n : n;
- X } else
- X u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
- X : (flags&&FF_LONG) ? va_arg(va, unsigned long)
- X : va_arg(va, unsigned int);
- X do {
- X *--p = '0' + u%10;
- X u /= 10;
- X } while (u != 0);
- X prec -= buf+BUF - p;
- X while (--prec >= 0)
- X *--p = '0';
- X if (flags&FF_NEG)
- X *--p = '-';
- X else
- X if (sign != '-')
- X *--p = (sign == '+') ? '+' : ' ';
- X flags |= FF_PUTS;
- X break;
- X
- X case 'x': case 'X': /* hex, Hex */
- X u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
- X : (flags&&FF_LONG) ? va_arg(va, unsigned long)
- X : va_arg(va, unsigned int);
- X do {
- X *--p = "0123456789ABCDEF"[u%16];
- X u /= 16;
- X } while (u != 0);
- X prec -= buf+BUF - p;
- X while (--prec >= 0)
- X *--p = '0';
- X if (flags&&FF_ALT)
- X *--p = 'x', *--p = '0';
- X flags |= FF_PUTS;
- X break;
- X
- X case 'o': /* octal */
- X u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
- X : (flags&&FF_LONG) ? va_arg(va, unsigned long)
- X : va_arg(va, unsigned int);
- X do {
- X *--p = '0' + u%8;
- X u /= 8;
- X } while (u != 0);
- X prec -= buf+BUF - p;
- X while (--prec >= 0)
- X *--p = '0';
- X if (flags&&FF_ALT && *p != '0')
- X *--p = '0';
- X flags |= FF_PUTS;
- X break;
- X
- X default: /* todo: error */
- X putc('%', f);
- X putc(c, f);
- X pos += 2;
- X break;
- X }
- X
- X /* copy adjusted string "p" to output */
- X if (flags&FF_PUTS) {
- X int len = strlen(p);
- X int pad = width - len;
- X if (!(flags&FF_LEFT))
- X while (--pad >= 0)
- X putc((flags&FF_ZERO) ? '0' : ' ', f);
- X while (*p)
- X putc(*p++, f);
- X if ((flags&FF_LEFT))
- X while (--pad >= 0)
- X putc(' ', f);
- X pos += (len < width) ? width : len;
- X }
- X } else { /* ordinary character */
- X putc(c, f);
- X pos ++;
- X }
- X return pos;
- X}
- X
- END_OF_FILE
- if test 4964 -ne `wc -c <'std/stdc/vprintf.c'`; then
- echo shar: \"'std/stdc/vprintf.c'\" unpacked with wrong size!
- fi
- # end of 'std/stdc/vprintf.c'
- fi
- echo shar: End of archive 6 \(of 9\).
- cp /dev/null ark6isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 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...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-