--- /dev/null
+/* Copyright (c) 1979 Regents of the University of California */
+/*
+ * Hacked "printf" which prints through putchar.
+ * DONT USE WITH STDIO!
+ */
+printf(fmt, args)
+char *fmt;
+{
+ _doprnt(fmt, &args, 0);
+}
+
+_strout(string, count, adjust, foo, fillch)
+register char *string;
+register int count;
+int adjust;
+register struct { int a[6]; } *foo;
+{
+
+ if (foo != 0)
+ abort();
+ while (adjust < 0) {
+ if (*string=='-' && fillch=='0') {
+ putchar(*string++);
+ count--;
+ }
+ putchar(fillch);
+ adjust++;
+ }
+ while (--count>=0)
+ putchar(*string++);
+ while (adjust) {
+ putchar(fillch);
+ adjust--;
+ }
+}
--- /dev/null
+g/^[ ]*\.data/s//.text/
+w
+q
--- /dev/null
+Thu Apr 19 12:17:29 PST 1979
+
+This shell needs a printf which prints through putchar like it used to.
+The printf.c in this dir hacks one from the stdio printf without dragging
+in all the stdio stuff. It should work on most systems which only have stdio.
+Some early versions of stdio have a "strout" whose first 2 arguments are
+reversed. Check this before you run the shell.
+
+The getpw*.c stuff here is simply to keep from dragging in all the data space
+from the stdio stuff (an input buffer, output buffer, file structs, etc)
+since the shell does its own i/o anyways because of the way
+it parses in loops. If you don't care about more data space you dont need
+to take these.
+
+For the debugging "alloc" command to work it needs to work its
+way through the alloc list. A modified version of alloc which does this
+is in this directory. If you wish you can simply get rid of the "alloc"
+command and not define "debug" in makefile.
+
+For the shell to coexist with another shell you can define OTHERSH
+in sh.local.h as, e.g. "/bin/sh". If a file which purports to be a shell
+script doesn't start with a `#' this other shell interprets it.
+If necessary a longer string than just `#' could easily be used.
+If OTHERSH is not defined then this hack doesn't occur.
+For full sanity complementary code should be placed in OTHERSH!
+
+Look at sh.local.h for other things which you may need/want to change.
--- /dev/null
+/* Copyright (c) 1979 Regents of the University of California */
+char *sys_errlist[] {
+ "Error 0",
+ "Not super-user",
+ "No such file or directory",
+ "No such process",
+ "Interrupted system call",
+ "I/O error",
+ "No such device or address",
+ "Arguments too long",
+ "Exec format error",
+ "Bad file number",
+ "No children",
+ "No more processes",
+ "Not enough core",
+ "Permission denied",
+ "Error 14",
+ "Block device required",
+ "Mount device busy",
+ "File exists",
+ "Cross-device link",
+ "No such device",
+ "Not a directory",
+ "Is a directory",
+ "Invalid argument",
+ "File table overflow",
+ "Too many open files",
+ "Not a typewriter",
+ "Text file busy",
+ "File too large",
+ "No space left on device",
+ "Illegal seek",
+ "Read-only file system",
+ "Too many links",
+ "Broken Pipe",
+ "Disk quota exceeded",
+};
+int sys_nerr { sizeof sys_errlist/sizeof sys_errlist[0] };
--- /dev/null
+/* Copyright (c) 1979 Regents of the University of California */
+#include <pwd.h>
+
+#define BUFSIZ 160
+
+static int pwf = -1;
+static char line[BUFSIZ+1];
+static struct passwd passwd;
+
+setpwent()
+{
+ if( pwf == -1 )
+ pwf = open( "/etc/passwd", 0 );
+ else
+ lseek(pwf, 0l, 0);
+}
+
+endpwent()
+{
+ if( pwf != -1 ){
+ close( pwf );
+ pwf = -1;
+ }
+}
+
+static char *
+pwskip(p)
+register char *p;
+{
+ while( *p && *p != ':' )
+ ++p;
+ if( *p ) *p++ = 0;
+ return(p);
+}
+
+struct passwd *
+getpwent()
+{
+ register char *p, *q;
+ register int i, j;
+
+ if (pwf == -1) {
+ if( (pwf = open( "/etc/passwd", 0 )) == -1 )
+ return(0);
+ }
+ i = read(pwf, line, BUFSIZ);
+ for (j = 0; j < i; j++)
+ if (line[j] == '\n')
+ break;
+ if (j >= i)
+ return(0);
+ line[++j] = 0;
+ lseek(pwf, (long) (j - i), 1);
+ p = line;
+ passwd.pw_name = p;
+ p = pwskip(p);
+/* passwd.pw_passwd = p; */
+ p = q = pwskip(p);
+/* passwd.pw_uid = atoi(p); */
+ p = pwskip(p);
+ p[-1] = 0;
+ passwd.pw_uid = atou(q);
+/* passwd.pw_gid = atoi(p); */
+/* passwd.pw_quota = 0; */
+/* passwd.pw_comment = ""; */
+ q = p;
+ p = pwskip(p);
+ p[-1] = 0;
+#ifdef CORY
+ passwd.pw_uid =+ atou(q) << 8;
+#endif
+#ifdef CC
+ passwd.pw_uid =+ atou(q) << 8;
+#endif
+#ifndef CORY
+#ifndef CC
+ passwd.pw_gid = atou(q);
+#endif
+#endif
+/* passwd.pw_gecos = p; */
+ p = pwskip(p);
+ passwd.pw_dir = p;
+ p = pwskip(p);
+/* passwd.pw_shell = p; */
+/* while(*p && *p != '\n') p++; */
+ *p = '\0';
+ return(&passwd);
+}
+
+atou(p)
+ register char *p;
+{
+ register int i = 0;
+
+ if (p != 0)
+ while (*p)
+ i = i * 10 + *p++ - '0';
+ return (i);
+}
--- /dev/null
+/* Copyright (c) 1979 Regents of the University of California */
+#include <pwd.h>
+
+struct passwd *
+getpwnam(name)
+char *name;
+{
+ register struct passwd *p;
+ struct passwd *getpwent();
+
+ setpwent();
+ while( (p = getpwent()) && strcmp(name,p->pw_name) );
+ endpwent();
+ return(p);
+}
--- /dev/null
+/* Copyright (c) 1979 Regents of the University of California */
+#include <pwd.h>
+
+struct passwd *
+getpwuid(uid)
+register uid;
+{
+ register struct passwd *p;
+ struct passwd *getpwent();
+
+ setpwent();
+ while( (p = getpwent()) && p->pw_uid != uid );
+ endpwent();
+ return(p);
+}
--- /dev/null
+/* Copyright (c) 1979 Regents of the University of California */
+#ifdef debug
+#define ASSERT(p) if(!(p))botch("p");else
+botch(s)
+char *s;
+{
+ printf("assertion botched: %s\n",s);
+ abort();
+}
+#else
+#define ASSERT(p)
+#endif
+
+/* avoid break bug */
+#ifdef pdp11
+#define GRANULE 64
+#else
+#define GRANULE 0
+#endif
+/* C storage allocator
+ * circular first-fit strategy
+ * works with noncontiguous, but monotonically linked, arena
+ * each block is preceded by a ptr to the (pointer of)
+ * the next following block
+ * blocks are exact number of words long
+ * aligned to the data type requirements of ALIGN
+ * pointers to blocks must have BUSY bit 0
+ * bit in ptr is 1 for busy, 0 for idle
+ * gaps in arena are merely noted as busy blocks
+ * last block of arena (pointed to by alloct) is empty and
+ * has a pointer to first
+ * idle blocks are coalesced during space search
+ *
+ * a different implementation may need to redefine
+ * ALIGN, NALIGN, BLOCK, BUSY, INT
+ * where INT is integer type to which a pointer can be cast
+*/
+#define INT int
+#define ALIGN int
+#define NALIGN 1
+#define WORD sizeof(union store)
+#define BLOCK 1024 /* a multiple of WORD*/
+#define BUSY 1
+#define NULL 0
+#define testbusy(p) ((INT)(p)&BUSY)
+#define setbusy(p) (union store *)((INT)(p)|BUSY)
+#define clearbusy(p) (union store *)((INT)(p)&~BUSY)
+
+union store { union store *ptr;
+ ALIGN dummy[NALIGN];
+ int calloc; /*calloc clears an array of integers*/
+};
+
+static union store allocs[2]; /*initial arena*/
+static union store *allocp; /*search ptr*/
+static union store *alloct; /*arena top*/
+static union store *allocx; /*for benefit of realloc*/
+char *sbrk();
+
+char *
+malloc(nbytes)
+unsigned nbytes;
+{
+ register union store *p, *q;
+ register nw;
+ static temp; /*coroutines assume no auto*/
+
+ if(allocs[0].ptr==0) { /*first time*/
+ allocs[0].ptr = setbusy(&allocs[1]);
+ allocs[1].ptr = setbusy(&allocs[0]);
+ alloct = &allocs[1];
+ allocp = &allocs[0];
+ }
+ nw = (nbytes+WORD+WORD-1)/WORD;
+ ASSERT(allocp>=allocs && allocp<=alloct);
+ ASSERT(allock());
+ for(p=allocp; ; ) {
+ for(temp=0; ; ) {
+ if(!testbusy(p->ptr)) {
+ while(!testbusy((q=p->ptr)->ptr)) {
+ ASSERT(q>p&&q<alloct);
+ p->ptr = q->ptr;
+ }
+ if(q>=p+nw && p+nw>=p)
+ goto found;
+ }
+ q = p;
+ p = clearbusy(p->ptr);
+ if(p>q)
+ ASSERT(p<=alloct);
+ else if(q!=alloct || p!=allocs) {
+ ASSERT(q==alloct&&p==allocs);
+ return(NULL);
+ } else if(++temp>1)
+ break;
+ }
+ temp = ((nw+BLOCK/WORD)/(BLOCK/WORD))*(BLOCK/WORD);
+ q = (union store *)sbrk(0);
+ if(q+temp+GRANULE < q) {
+ return(NULL);
+ }
+ q = (union store *)sbrk(temp*WORD);
+ if((INT)q == -1) {
+ return(NULL);
+ }
+ ASSERT(q>alloct);
+ alloct->ptr = q;
+ if(q!=alloct+1)
+ alloct->ptr = setbusy(alloct->ptr);
+ alloct = q->ptr = q+temp-1;
+ alloct->ptr = setbusy(allocs);
+ }
+found:
+ allocp = p + nw;
+ ASSERT(allocp<=alloct);
+ if(q>allocp) {
+ allocx = allocp->ptr;
+ allocp->ptr = p->ptr;
+ }
+ p->ptr = setbusy(allocp);
+ return((char *)(p+1));
+}
+
+/* freeing strategy tuned for LIFO allocation
+*/
+free(ap)
+register char *ap;
+{
+ register union store *p = (union store *)ap;
+
+ ASSERT(p>clearbusy(allocs[1].ptr)&&p<=alloct);
+ ASSERT(allock());
+ allocp = --p;
+ ASSERT(testbusy(p->ptr));
+ p->ptr = clearbusy(p->ptr);
+ ASSERT(p->ptr > allocp && p->ptr <= alloct);
+}
+
+/* realloc(p, nbytes) reallocates a block obtained from malloc()
+ * and freed since last call of malloc()
+ * to have new size nbytes, and old content
+ * returns new location, or 0 on failure
+*/
+
+char *
+realloc(p, nbytes)
+register union store *p;
+unsigned nbytes;
+{
+ register union store *q;
+ union store *s, *t;
+ register unsigned nw;
+ unsigned onw;
+
+ if(testbusy(p[-1].ptr))
+ free((char *)p);
+ onw = p[-1].ptr - p;
+ q = (union store *)malloc(nbytes);
+ if(q==NULL || q==p)
+ return((char *)q);
+ s = p;
+ t = q;
+ nw = (nbytes+WORD-1)/WORD;
+ if(nw<onw)
+ onw = nw;
+ while(onw--!=0)
+ *t++ = *s++;
+ if(q<p && q+nw>=p)
+ (q+(q+nw-p))->ptr = allocx;
+ return((char *)q);
+}
+
+#ifdef debug
+allock()
+{
+#ifdef longdebug
+ register union store *p;
+ int x;
+ x = 0;
+ for(p= &allocs[0]; clearbusy(p->ptr) > p; p=clearbusy(p->ptr)) {
+ if(p==allocp)
+ x++;
+ }
+ ASSERT(p==alloct);
+ return(x==1|p==allocp);
+#else
+ return(1);
+#endif
+}
+#endif
--- /dev/null
+/* Copyright (c) 1979 Regents of the University of California */
+/*
+ * Hacked "printf" which prints through putchar.
+ * DONT USE WITH STDIO!
+ */
+printf(fmt, args)
+char *fmt;
+{
+ _doprnt(fmt, &args, 0);
+}
+
+_strout(count, string, adjust, foo, fillch)
+register char *string;
+register int count;
+int adjust;
+register struct { int a[6]; } *foo;
+{
+
+ if (foo != 0)
+ abort();
+ while (adjust < 0) {
+ if (*string=='-' && fillch=='0') {
+ putchar(*string++);
+ count--;
+ }
+ putchar(fillch);
+ adjust++;
+ }
+ while (--count>=0)
+ putchar(*string++);
+ while (adjust) {
+ putchar(fillch);
+ adjust--;
+ }
+}