Research V7 development
authorKen Thompson <ken@research.uucp>
Wed, 10 Jan 1979 20:02:16 +0000 (15:02 -0500)
committerKen Thompson <ken@research.uucp>
Wed, 10 Jan 1979 20:02:16 +0000 (15:02 -0500)
Work on file usr/src/cmd/od.c
Work on file usr/src/cmd/passwd.c
Work on file usr/src/cmd/ps.c
Work on file usr/src/cmd/ptx.c
Work on file usr/src/cmd/pwd.c
Work on file usr/src/cmd/quot.c
Work on file usr/src/cmd/random.c
Work on file usr/src/cmd/rev.c
Work on file usr/src/cmd/rm.c
Work on file usr/src/cmd/rmdir.c
Work on file usr/src/cmd/size.c
Work on file usr/src/cmd/sleep.c

Co-Authored-By: Dennis Ritchie <dmr@research.uucp>
Synthesized-from: v7

12 files changed:
usr/src/cmd/od.c [new file with mode: 0644]
usr/src/cmd/passwd.c [new file with mode: 0644]
usr/src/cmd/ps.c [new file with mode: 0644]
usr/src/cmd/ptx.c [new file with mode: 0644]
usr/src/cmd/pwd.c [new file with mode: 0644]
usr/src/cmd/quot.c [new file with mode: 0644]
usr/src/cmd/random.c [new file with mode: 0644]
usr/src/cmd/rev.c [new file with mode: 0644]
usr/src/cmd/rm.c [new file with mode: 0644]
usr/src/cmd/rmdir.c [new file with mode: 0644]
usr/src/cmd/size.c [new file with mode: 0644]
usr/src/cmd/sleep.c [new file with mode: 0644]

diff --git a/usr/src/cmd/od.c b/usr/src/cmd/od.c
new file mode 100644 (file)
index 0000000..f0809c9
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * od -- octal (also hex, decimal, and character) dump
+ */
+
+#include <stdio.h>
+
+unsigned short word[8];
+unsigned short lastword[8];
+int    conv;
+int    base =  010;
+int    max;
+long   addr;
+
+main(argc, argv)
+char **argv;
+{
+       register char *p;
+       register n, f, same;
+
+
+       argv++;
+       f = 0;
+       if(argc > 1) {
+               p = *argv;
+               if(*p == '-') {
+                       while(*p != '\0') {
+                               switch(*p++) {
+                               case 'o':
+                                       conv |= 001;
+                                       f = 6;
+                                       break;
+                               case 'd':
+                                       conv |= 002;
+                                       f = 5;
+                                       break;
+                               case 'x':
+                               case 'h':
+                                       conv |= 010;
+                                       f = 4;
+                                       break;
+                               case 'c':
+                                       conv |= 020;
+                                       f = 7;
+                                       break;
+                               case 'b':
+                                       conv |= 040;
+                                       f = 7;
+                                       break;
+                               }
+                               if(f > max)
+                                       max = f;
+                       }
+                       argc--;
+                       argv++;
+               }
+       }
+       if(!conv) {
+               max = 6;
+               conv = 1;
+       }
+       if(argc > 1)
+       if(**argv != '+') {
+               if (freopen(*argv, "r", stdin) == NULL) {
+                       printf("cannot open %s\n", *argv);
+                       exit(1);
+               }
+               argv++;
+               argc--;
+       }
+       if(argc > 1)
+               offset(*argv);
+
+       same = -1;
+       for ( ; (n = fread((char *)word, 1, sizeof(word), stdin)) > 0; addr += n) {
+               if (same>=0) {
+                       for (f=0; f<8; f++)
+                               if (lastword[f] != word[f])
+                                       goto notsame;
+                       if (same==0) {
+                               printf("*\n");
+                               same = 1;
+                       }
+                       continue;
+               }
+       notsame:
+               line(addr, word, (n+sizeof(word[0])-1)/sizeof(word[0]));
+               same = 0;
+               for (f=0; f<8; f++)
+                       lastword[f] = word[f];
+               for (f=0; f<8; f++)
+                       word[f] = 0;
+       }
+       putn(addr, base, 7);
+       putchar('\n');
+}
+
+line(a, w, n)
+long a;
+unsigned short *w;
+{
+       register i, f, c;
+
+       f = 1;
+       for(c=1; c; c<<=1) {
+               if((c&conv) == 0)
+                       continue;
+               if(f) {
+                       putn(a, base, 7);
+                       putchar(' ');
+                       f = 0;
+               } else
+                       putchar('\t');
+               for (i=0; i<n; i++) {
+                       putx(w[i], c);
+                       putchar(i==n-1? '\n': ' ');
+               }
+       }
+}
+
+putx(n, c)
+unsigned n;
+{
+
+       switch(c) {
+       case 001:
+               pre(6);
+               putn((long)n, 8, 6);
+               break;
+       case 002:
+               pre(5);
+               putn((long)n, 10, 5);
+               break;
+       case 010:
+               pre(4);
+               putn((long)n, 16, 4);
+               break;
+       case 020:
+               pre(7);
+               {
+                       unsigned short sn = n;
+                       cput(*(char *)&sn);
+                       putchar(' ');
+                       cput(*((char *)&sn + 1));
+                       break;
+               }
+       case 040:
+               pre(7);
+               {
+                       unsigned short sn = n;
+                       putn((long)(*(char *)&sn)&0377, 8, 3);
+                       putchar(' ');
+                       putn((long)(*((char *)&sn + 1))&0377, 8, 3);
+                       break;
+               }
+       }
+}
+
+cput(c)
+{
+       c &= 0377;
+       if(c>037 && c<0177) {
+               printf("  ");
+               putchar(c);
+               return;
+       }
+       switch(c) {
+       case '\0':
+               printf(" \\0");
+               break;
+       case '\b':
+               printf(" \\b");
+               break;
+       case '\f':
+               printf(" \\f");
+               break;
+       case '\n':
+               printf(" \\n");
+               break;
+       case '\r':
+               printf(" \\r");
+               break;
+       case '\t':
+               printf(" \\t");
+               break;
+       default:
+               putn((long)c, 8, 3);
+       }
+}
+
+putn(n, b, c)
+long n;
+{
+       register d;
+
+       if(!c)
+               return;
+       putn(n/b, b, c-1);
+       d = n%b;
+       if (d > 9)
+               putchar(d-10+'a');
+       else
+               putchar(d+'0');
+}
+
+pre(n)
+{
+       int i;
+
+       for(i=n; i<max; i++)
+               putchar(' ');
+}
+
+offset(s)
+register char *s;
+{
+       register char *p;
+       long a;
+       register int d;
+
+       if (*s=='+')
+               s++;
+       if (*s=='x') {
+               s++;
+               base = 16;
+       } else if (*s=='0' && s[1]=='x') {
+               s += 2;
+               base = 16;
+       } else if (*s == '0')
+               base = 8;
+       p = s;
+       while(*p) {
+               if (*p++=='.')
+                       base = 10;
+       }
+       for (a=0; *s; s++) {
+               d = *s;
+               if(d>='0' && d<='9')
+                       a = a*base + d - '0';
+               else if (d>='a' && d<='f' && base==16)
+                       a = a*base + d + 10 - 'a';
+               else
+                       break;
+       }
+       if (*s == '.')
+               s++;
+       if(*s=='b' || *s=='B')
+               a *= 512;
+       fseek(stdin, a, 0);
+       addr = a;
+}
diff --git a/usr/src/cmd/passwd.c b/usr/src/cmd/passwd.c
new file mode 100644 (file)
index 0000000..2ecf762
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * enter a password in the password file
+ * this program should be suid with owner
+ * with an owner with write permission on /etc/passwd
+ */
+#include <stdio.h>
+#include <signal.h>
+#include <pwd.h>
+
+char   passwd[] = "/etc/passwd";
+char   temp[]   = "/etc/ptmp";
+struct passwd *pwd;
+struct passwd *getpwent();
+int    endpwent();
+char   *strcpy();
+char   *crypt();
+char   *getpass();
+char   *getlogin();
+char   *pw;
+char   pwbuf[10];
+char   buf[512];
+
+main(argc, argv)
+char *argv[];
+{
+       char *p;
+       int i;
+       char saltc[2];
+       long salt;
+       int u,fi,fo;
+       int insist;
+       int ok, flags;
+       int c;
+       int pwlen;
+       FILE *tf;
+       char *uname;
+
+       insist = 0;
+       if(argc < 2) {
+               if ((uname = getlogin()) == NULL) {
+                       printf ("Usage: passwd user\n");
+                       goto bex;
+               } else {
+                       printf("Changing password for %s\n", uname);
+               }
+       } else {
+               uname = argv[1];
+       }
+       while(((pwd=getpwent()) != NULL)&&(strcmp(pwd->pw_name,uname)!=0));
+       u = getuid();
+       if((pwd==NULL) || (u!=0 && u != pwd->pw_uid))
+               {
+               printf("Permission denied.\n");
+               goto bex;
+               }
+       endpwent();
+       if (pwd->pw_passwd[0] && u != 0) {
+               strcpy(pwbuf, getpass("Old password:"));
+               pw = crypt(pwbuf, pwd->pw_passwd);
+               if(strcmp(pw, pwd->pw_passwd) != 0) {
+                       printf("Sorry.\n");
+                       goto bex;
+               }
+       }
+tryagn:
+       strcpy(pwbuf, getpass("New password:"));
+       pwlen = strlen(pwbuf);
+       if (pwlen == 0) {
+               printf("Password unchanged.\n");
+               goto bex;
+       }
+       ok = 0;
+       flags = 0;
+       p = pwbuf;
+       while(c = *p++){
+               if(c>='a' && c<='z') flags |= 2;
+               else if(c>='A' && c<='Z') flags |= 4;
+               else if(c>='0' && c<='9') flags |= 1;
+               else flags |= 8;
+       }
+       if(flags >=7 && pwlen>= 4) ok = 1;
+       if(((flags==2)||(flags==4)) && pwlen>=6) ok = 1;
+       if(((flags==3)||(flags==5)||(flags==6))&&pwlen>=5) ok = 1;
+
+       if((ok==0) && (insist<2)){
+               if(flags==1)
+               printf("Please use at least one non-numeric character.\n");
+               else
+               printf("Please use a longer password.\n");
+               insist++;
+               goto tryagn;
+               }
+
+       if (strcmp(pwbuf,getpass("Retype new password:")) != 0) {
+               printf ("Mismatch - password unchanged.\n");
+               goto bex;
+       }
+
+       time(&salt);
+       salt += getpid();
+
+       saltc[0] = salt & 077;
+       saltc[1] = (salt>>6) & 077;
+       for(i=0;i<2;i++){
+               c = saltc[i] + '.';
+               if(c>'9') c += 7;
+               if(c>'Z') c += 6;
+               saltc[i] = c;
+       }
+       pw = crypt(pwbuf, saltc);
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+
+       if(access(temp, 0) >= 0) {
+               printf("Temporary file busy -- try again\n");
+               goto bex;
+       }
+       close(creat(temp,0600));
+       if((tf=fopen(temp,"w")) == NULL) {
+               printf("Cannot create temporary file\n");
+               goto bex;
+       }
+
+/*
+ *     copy passwd to temp, replacing matching lines
+ *     with new password.
+ */
+
+       while((pwd=getpwent()) != NULL) {
+               if(strcmp(pwd->pw_name,uname) == 0) {
+                       u = getuid();
+                       if(u != 0 && u != pwd->pw_uid) {
+                               printf("Permission denied.\n");
+                               goto out;
+                       }
+                       pwd->pw_passwd = pw;
+               }
+               fprintf(tf,"%s:%s:%d:%d:%s:%s:%s\n",
+                       pwd->pw_name,
+                       pwd->pw_passwd,
+                       pwd->pw_uid,
+                       pwd->pw_gid,
+                       pwd->pw_gecos,
+                       pwd->pw_dir,
+                       pwd->pw_shell);
+       }
+       endpwent();
+       fclose(tf);
+
+/*
+ *     copy temp back to passwd file
+ */
+
+       if((fi=open(temp,0)) < 0) {
+               printf("Temp file disappeared!\n");
+               goto out;
+       }
+       if((fo=creat(passwd, 0644)) < 0) {
+               printf("Cannot recreat passwd file.\n");
+               goto out;
+       }
+       while((u=read(fi,buf,sizeof(buf))) > 0) write(fo,buf,u);
+
+out:
+       unlink(temp);
+
+bex:
+       exit(1);
+}
diff --git a/usr/src/cmd/ps.c b/usr/src/cmd/ps.c
new file mode 100644 (file)
index 0000000..a5e2bb7
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ *     ps - process status
+ *     examine and print certain things about processes
+ */
+
+#include <stdio.h>
+#include <a.out.h>
+#include <core.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+
+struct nlist nl[] = {
+       { "_proc" },
+       { "_swapdev" },
+       { "_swplo" },
+       { "" },
+};
+
+struct proc mproc;
+
+struct user u;
+int    chkpid;
+int    retcode=1;
+int    lflg;
+int    vflg;
+int    kflg;
+int    xflg;
+char   *tptr;
+long   lseek();
+char   *gettty();
+char   *getptr();
+char   *strncmp();
+int    aflg;
+int    mem;
+int    swmem;
+int    swap;
+daddr_t        swplo;
+
+int    ndev;
+struct devl {
+       char    dname[DIRSIZ];
+       dev_t   dev;
+} devl[256];
+
+char   *coref;
+
+main(argc, argv)
+char **argv;
+{
+       int i;
+       char *ap;
+       int uid, puid;
+
+       if (argc>1) {
+               ap = argv[1];
+               while (*ap) switch (*ap++) {
+
+               case 'v':
+                       vflg++;
+                       break;
+
+               case 'a':
+                       aflg++;
+                       break;
+
+               case 't':
+                       if(*ap)
+                               tptr = ap;
+                       aflg++;
+                       if (*tptr == '?')
+                               xflg++;
+                       goto bbreak;
+
+               case 'x':
+                       xflg++;
+                       break;
+
+               case '-':
+                       break;
+
+               case 'l':
+                       lflg++;
+                       break;
+
+               case 'k':
+                       kflg++;
+                       break;
+
+               default:
+                       chkpid = atoi(ap-1);
+                       goto bbreak;
+                       break;
+               }
+       }
+
+bbreak:
+       if(chdir("/dev") < 0) {
+               fprintf(stderr, "Can't change to /dev\n");
+               exit(1);
+       }
+       nlist(argc>2? argv[2]:"/unix", nl);
+       if (nl[0].n_type==0) {
+               fprintf(stderr, "No namelist\n");
+               exit(1);
+       }
+       coref = "/dev/mem";
+       if(kflg)
+               coref = "/usr/sys/core";
+       if ((mem = open(coref, 0)) < 0) {
+               fprintf(stderr, "No mem\n");
+               exit(1);
+       }
+       swmem = open(coref, 0);
+       /*
+        * read mem to find swap dev.
+        */
+       lseek(mem, (long)nl[1].n_value, 0);
+       read(mem, (char *)&nl[1].n_value, sizeof(nl[1].n_value));
+       /*
+        * Find base of swap
+        */
+       lseek(mem, (long)nl[2].n_value, 0);
+       read(mem, (char *)&swplo, sizeof(swplo));
+       /*
+        * Locate proc table
+        */
+       lseek(mem, (long)nl[0].n_value, 0);
+       getdev();
+       uid = getuid();
+       if (lflg)
+       printf(" F S UID   PID  PPID CPU PRI NICE  ADDR  SZ  WCHAN TTY TIME CMD\n"); else
+               if (chkpid==0) printf("   PID TTY TIME CMD\n");
+       for (i=0; i<NPROC; i++) {
+               read(mem, (char *)&mproc, sizeof mproc);
+               if (mproc.p_stat==0)
+                       continue;
+               if (mproc.p_pgrp==0 && xflg==0 && mproc.p_uid==0)
+                       continue;
+               puid = mproc.p_uid;
+               if ((uid != puid && aflg==0) ||
+                   (chkpid!=0 && chkpid!=mproc.p_pid))
+                       continue;
+               if(prcom(puid)) {
+                       printf("\n");
+                       retcode=0;
+               }
+       }
+       exit(retcode);
+}
+
+getdev()
+{
+#include <sys/stat.h>
+       register FILE *df;
+       struct stat sbuf;
+       struct direct dbuf;
+
+       if ((df = fopen("/dev", "r")) == NULL) {
+               fprintf(stderr, "Can't open /dev\n");
+               exit(1);
+       }
+       ndev = 0;
+       while (fread((char *)&dbuf, sizeof(dbuf), 1, df) == 1) {
+               if(dbuf.d_ino == 0)
+                       continue;
+               if(stat(dbuf.d_name, &sbuf) < 0)
+                       continue;
+               if ((sbuf.st_mode&S_IFMT) != S_IFCHR)
+                       continue;
+               strcpy(devl[ndev].dname, dbuf.d_name);
+               devl[ndev].dev = sbuf.st_rdev;
+               ndev++;
+       }
+       fclose(df);
+       if ((swap = open("/dev/swap", 0)) < 0) {
+               fprintf(stderr, "Can't open /dev/swap\n");
+               exit(1);
+       }
+}
+
+long
+round(a, b)
+       long            a, b;
+{
+       long            w = ((a+b-1)/b)*b;
+
+       return(w);
+}
+
+struct map {
+       long    b1, e1; long f1;
+       long    b2, e2; long f2;
+};
+struct map datmap;
+int    file;
+prcom(puid)
+{
+       char abuf[512];
+       long addr;
+       register int *ip;
+       register char *cp, *cp1;
+       long tm;
+       int c, nbad;
+       register char *tp;
+       long txtsiz, datsiz, stksiz;
+       int septxt;
+       int lw=(lflg?35:80);
+       char **ap;
+
+       if (mproc.p_flag&SLOAD) {
+               addr = ctob((long)mproc.p_addr);
+               file = swmem;
+       } else {
+               addr = (mproc.p_addr+swplo)<<9;
+               file = swap;
+       }
+       lseek(file, addr, 0);
+       if (read(file, (char *)&u, sizeof(u)) != sizeof(u))
+               return(0);
+
+       /* set up address maps for user pcs */
+       txtsiz = ctob(u.u_tsize);
+       datsiz = ctob(u.u_dsize);
+       stksiz = ctob(u.u_ssize);
+       septxt = u.u_sep;
+       datmap.b1 = (septxt ? 0 : round(txtsiz,TXTRNDSIZ));
+       datmap.e1 = datmap.b1+datsiz;
+       datmap.f1 = ctob(USIZE)+addr;
+       datmap.b2 = stackbas(stksiz);
+       datmap.e2 = stacktop(stksiz);
+       datmap.f2 = ctob(USIZE)+(datmap.e1-datmap.b1)+addr;
+
+       tp = gettty();
+       if (tptr && strncmp(tptr, tp, 2))
+               return(0);
+       if (lflg) {
+               printf("%2o %c%4d", mproc.p_flag,
+                       "0SWRIZT"[mproc.p_stat], puid);
+       }
+       printf("%6u", mproc.p_pid);
+       if (lflg) {
+               printf("%6u%4d%4d%5d%6o%4d", mproc.p_ppid, mproc.p_cpu&0377,
+                       mproc.p_pri,
+                       mproc.p_nice,
+                       mproc.p_addr, (mproc.p_size+7)>>3);
+               if (mproc.p_wchan)
+                       printf("%7o", mproc.p_wchan);
+               else
+                       printf("       ");
+       }
+       printf(" %-2.2s", tp);
+       if (mproc.p_stat==SZOMB) {
+               printf("  <defunct>");
+               return(1);
+       }
+       tm = (u.u_utime + u.u_stime + 30)/60;
+       printf(" %2ld:", tm/60);
+       tm %= 60;
+       printf(tm<10?"0%ld":"%ld", tm);
+       if (vflg && lflg==0) {  /* 0 == old tflg (print long times) */
+               tm = (u.u_cstime + 30)/60;
+               printf(" %2ld:", tm/60);
+               tm %= 60;
+               printf(tm<10?"0%ld":"%ld", tm);
+               tm = (u.u_cutime + 30)/60;
+               printf(" %2ld:", tm/60);
+               tm %= 60;
+               printf(tm<10?"0%ld":"%ld", tm);
+       }
+       if (mproc.p_pid == 0) {
+               printf(" swapper");
+               return(1);
+       }
+       addr += ctob((long)mproc.p_size) - 512;
+
+       /* look for sh special */
+       lseek(file, addr+512-sizeof(char **), 0);
+       if (read(file, (char *)&ap, sizeof(char *)) != sizeof(char *))
+               return(1);
+       if (ap) {
+               char b[82];
+               char *bp = b;
+               while((cp=getptr(ap++)) && cp && (bp<b+lw) ) {
+                       nbad = 0;
+                       while((c=getbyte(cp++)) && (bp<b+lw)) {
+                               if (c<' ' || c>'~') {
+                                       if (nbad++>3)
+                                               break;
+                                       continue;
+                               }
+                               *bp++ = c;
+                       }
+                       *bp++ = ' ';
+               }
+               *bp++ = 0;
+               printf(lflg?" %.30s":" %.60s", b);
+               return(1);
+       }
+
+       lseek(file, addr, 0);
+       if (read(file, abuf, sizeof(abuf)) != sizeof(abuf))
+               return(1);
+       for (ip = (int *)&abuf[512]-2; ip > (int *)abuf; ) {
+               if (*--ip == -1 || *ip==0) {
+                       cp = (char *)(ip+1);
+                       if (*cp==0)
+                               cp++;
+                       nbad = 0;
+                       for (cp1 = cp; cp1 < &abuf[512]; cp1++) {
+                               c = *cp1&0177;
+                               if (c==0)
+                                       *cp1 = ' ';
+                               else if (c < ' ' || c > 0176) {
+                                       if (++nbad >= 5) {
+                                               *cp1++ = ' ';
+                                               break;
+                                       }
+                                       *cp1 = '?';
+                               } else if (c=='=') {
+                                       *cp1 = 0;
+                                       while (cp1>cp && *--cp1!=' ')
+                                               *cp1 = 0;
+                                       break;
+                               }
+                       }
+                       while (*--cp1==' ')
+                               *cp1 = 0;
+                       printf(lflg?" %.30s":" %.60s", cp);
+                       return(1);
+               }
+       }
+       return(1);
+}
+
+char *
+gettty()
+{
+       register i;
+       register char *p;
+
+       if (u.u_ttyp==0)
+               return("?");
+       for (i=0; i<ndev; i++) {
+               if (devl[i].dev == u.u_ttyd) {
+                       p = devl[i].dname;
+                       if (p[0]=='t' && p[1]=='t' && p[2]=='y')
+                               p += 3;
+                       return(p);
+               }
+       }
+       return("?");
+}
+
+char *
+getptr(adr)
+char **adr;
+{
+       char *ptr;
+       register char *p, *pa;
+       register i;
+
+       ptr = 0;
+       pa = (char *)adr;
+       p = (char *)&ptr;
+       for (i=0; i<sizeof(ptr); i++)
+               *p++ = getbyte(pa++);
+       return(ptr);
+}
+
+getbyte(adr)
+char *adr;
+{
+       register struct map *amap = &datmap;
+       char b;
+       long saddr;
+
+       if(!within(adr, amap->b1, amap->e1)) {
+               if(within(adr, amap->b2, amap->e2)) {
+                       saddr = (unsigned)adr + amap->f2 - amap->b2;
+               } else
+                       return(0);
+       } else
+               saddr = (unsigned)adr + amap->f1 - amap->b1;
+       if(lseek(file, saddr, 0)==-1
+                  || read(file, &b, 1)<1) {
+               return(0);
+       }
+       return((unsigned)b);
+}
+
+
+within(adr,lbd,ubd)
+char *adr;
+long lbd, ubd;
+{
+       return((unsigned)adr>=lbd && (unsigned)adr<ubd);
+}
diff --git a/usr/src/cmd/ptx.c b/usr/src/cmd/ptx.c
new file mode 100644 (file)
index 0000000..712911d
--- /dev/null
@@ -0,0 +1,551 @@
+#
+
+/*     permuted title index
+       ptx [-t] [-i ignore] [-o only] [-w num] [-f] [input] [output]
+       Ptx reads the input file and permutes on words in it.
+       It excludes all words in the ignore file.
+       Alternately it includes words in the only file.
+       if neither is given it excludes the words in /usr/lib/eign.
+
+       The width of the output line can be changed to num
+       characters.  If omitted 72 is default unless troff than 100.
+       the -f flag tells the program to fold the output
+       the -t flag says the output is for troff and the
+       output is then wider.
+
+\e      make: cc ptx.c -lS
+       */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#define DEFLTX "/usr/lib/eign"
+#define TILDE 0177
+#define SORT "/bin/sort"
+#define        N 30
+#define        MAX     N*BUFSIZ
+#define LMAX   200
+#define MAXT   2048
+#define MASK   03777
+#define SET    1
+
+#define isabreak(c) (btable[c])
+
+extern char *calloc(), *mktemp();
+extern char *getline();
+int status;
+
+
+char *hasht[MAXT];
+char line[LMAX];
+char btable[128];
+int ignore;
+int only;
+int llen = 72;
+int gap = 3;
+int gutter = 3;
+int mlen = LMAX;
+int wlen;
+int rflag;
+int halflen;
+char *strtbufp, *endbufp;
+char *empty = "";
+
+char *infile;
+FILE *inptr = stdin;
+
+char *outfile;
+FILE *outptr = stdout;
+
+char *sortfile;        /* output of sort program */
+char nofold[] = {'-', 'd', 't', TILDE, 0};
+char fold[] = {'-', 'd', 'f', 't', TILDE, 0};
+char *sortopt = nofold;
+FILE *sortptr;
+
+char *bfile;   /*contains user supplied break chars */
+FILE *bptr;
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+       register int c;
+       register char *bufp;
+       int pid;
+       char *pend;
+       extern onintr();
+
+       char *xfile;
+       FILE *xptr;
+
+       if(signal(SIGHUP,onintr)==SIG_IGN)
+               signal(SIGHUP,SIG_IGN);
+       if(signal(SIGINT,onintr)==SIG_IGN)
+               signal(SIGINT,SIG_IGN);
+       signal(SIGPIPE,onintr);
+       signal(SIGTERM,onintr);
+
+/*     argument decoding       */
+
+       xfile = DEFLTX;
+       argv++;
+       while(argc>1 && **argv == '-') {
+               switch (*++*argv){
+
+               case 'r':
+                       rflag++;
+                       break;
+               case 'f':
+                       sortopt = fold;
+                       break;
+
+               case 'w':
+                       if(argc >= 2) {
+                               argc--;
+                               wlen++;
+                               llen = atoi(*++argv);
+                               if(llen == 0)
+                                       diag("Wrong width:",*argv);
+                               if(llen > LMAX) {
+                                       llen = LMAX;
+                                       msg("Lines truncated to 200 chars.",empty);
+                               }
+                               break;
+                       }
+
+               case 't':
+                       if(wlen == 0)
+                               llen = 100;
+                       break;
+               case 'g':
+                       if(argc >=2) {
+                               argc--;
+                               gap = gutter = atoi(*++argv);
+                       }
+                       break;
+
+               case 'i':
+                       if(only) 
+                               diag("Only file already given.",empty);
+                       if (argc>=2){
+                               argc--;
+                               ignore++;
+                               xfile = *++argv;
+                       }
+                       break;
+
+               case 'o':
+                       if(ignore)
+                               diag("Ignore file already given",empty);
+                       if (argc>=2){
+                               only++;
+                               argc--;
+                               xfile = *++argv;
+                       }
+                       break;
+
+               case 'b':
+                       if(argc>=2) {
+                               argc--;
+                               bfile = *++argv;
+                       }
+                       break;
+
+               default:
+                       msg("Illegal argument:",*argv);
+               }
+               argc--;
+               argv++;
+       }
+
+       if(argc>3)
+               diag("Too many filenames",empty);
+       else if(argc==3){
+               infile = *argv++;
+               outfile = *argv;
+               if((outptr = fopen(outfile,"w")) == NULL)
+                       diag("Cannot open output file:",outfile);
+       } else if(argc==2) {
+               infile = *argv;
+               outfile = 0;
+       }
+
+
+       /* Default breaks of blank, tab and newline */
+       btable[' '] = SET;
+       btable['\t'] = SET;
+       btable['\n'] = SET;
+       if(bfile) {
+               if((bptr = fopen(bfile,"r")) == NULL)
+                       diag("Cannot open break char file",bfile);
+
+               while((c = getc(bptr)) != EOF)
+                       btable[c] = SET;
+       }
+
+/*     Allocate space for a buffer.  If only or ignore file present
+       read it into buffer. Else read in default ignore file
+       and put resulting words in buffer.
+       */
+
+
+       if((strtbufp = calloc(N,BUFSIZ)) == NULL)
+               diag("Out of memory space",empty);
+       bufp = strtbufp;
+       endbufp = strtbufp+MAX;
+
+       if((xptr = fopen(xfile,"r")) == NULL)
+               diag("Cannot open  file",xfile);
+
+       while(bufp < endbufp && (c = getc(xptr)) != EOF) {
+               if(isabreak(c)) {
+                       if(storeh(hash(strtbufp,bufp),strtbufp))
+                               diag("Too many words",xfile);
+                       *bufp++ = '\0';
+                       strtbufp = bufp;
+               }
+               else {
+                       *bufp++ = (isupper(c)?tolower(c):c);
+               }
+       }
+       if (bufp >= endbufp)
+               diag("Too many words in file",xfile);
+       endbufp = --bufp;
+
+       /* open output file for sorting */
+
+       sortfile = mktemp("/tmp/ptxsXXXXX");
+       if((sortptr = fopen(sortfile, "w")) == NULL)
+               diag("Cannot open output for sorting:",sortfile);
+
+/*     get a line of data and compare each word for
+       inclusion or exclusion in the sort phase
+*/
+
+       if (infile!=0 && (inptr = fopen(infile,"r")) == NULL)
+               diag("Cannot open data: ",infile);
+       while(pend=getline())
+               cmpline(pend);
+       fclose(sortptr);
+
+       switch (pid = fork()){
+
+       case -1:        /* cannot fork */
+               diag("Cannot fork",empty);
+
+       case 0:         /* child */
+               execl(SORT, SORT, sortopt, "+0", "-1", "+1",
+                       sortfile, "-o", sortfile, 0);
+
+       default:        /* parent */
+               while(wait(&status) != pid);
+       }
+
+
+       getsort();
+       onintr();
+}
+
+msg(s,arg)
+char *s;
+char *arg;
+{
+       fprintf(stderr,"%s %s\n",s,arg);
+       return;
+}
+diag(s,arg)
+char *s, *arg;
+{
+
+       msg(s,arg);
+       exit(1);
+}
+
+
+char *getline()
+{
+
+       register c;
+       register char *linep;
+       char *endlinep;
+
+
+       endlinep= line + mlen;
+       linep = line;
+       /* Throw away leading white space */
+
+       while(isspace(c=getc(inptr)))
+               ;
+       if(c==EOF)
+               return(0);
+       ungetc(c,inptr);
+       while(( c=getc(inptr)) != EOF) {
+               switch (c) {
+
+                       case '\t':
+                               if(linep<endlinep)
+                                       *linep++ = ' ';
+                               break;
+                       case '\n':
+                               while(isspace(*--linep));
+                               *++linep = '\n';
+                               return(linep);
+                       default:
+                               if(linep < endlinep)
+                                       *linep++ = c;
+               }
+       }
+       return(0);
+}
+
+cmpline(pend)
+char *pend;
+{
+
+       char *pstrt, *pchar, *cp;
+       char **hp;
+       int flag;
+
+       pchar = line;
+       if(rflag)
+               while(pchar<pend&&!isspace(*pchar))
+                       pchar++;
+       while(pchar<pend){
+       /* eliminate white space */
+               if(isabreak(*pchar++))
+                       continue;
+               pstrt = --pchar;
+
+               flag = 1;
+               while(flag){
+                       if(isabreak(*pchar)) {
+                               hp = &hasht[hash(pstrt,pchar)];
+                               pchar--;
+                               while(cp = *hp++){
+                                       if(hp == &hasht[MAXT])
+                                               hp = hasht;
+       /* possible match */
+                                       if(cmpword(pstrt,pchar,cp)){
+       /* exact match */
+                                               if(!ignore && only)
+                                                       putline(pstrt,pend);
+                                               flag = 0;
+                                               break;
+                                       }
+                               }
+       /* no match */
+                               if(flag){
+                                       if(ignore || !only)
+                                               putline(pstrt,pend);
+                                       flag = 0;
+                               }
+                       }
+               pchar++;
+               }
+       }
+}
+
+cmpword(cpp,pend,hpp)
+char *cpp, *pend, *hpp;
+{
+       char c;
+
+       while(*hpp != '\0'){
+               c = *cpp++;
+               if((isupper(c)?tolower(c):c) != *hpp++)
+                       return(0);
+       }
+       if(--cpp == pend) return(1);
+       return(0);
+}
+
+putline(strt, end)
+char *strt, *end;
+{
+       char *cp;
+
+       for(cp=strt; cp<end; cp++)
+               putc(*cp, sortptr);
+       /* Add extra blank before TILDE to sort correctly
+          with -fd option */
+       putc(' ',sortptr);
+       putc(TILDE,sortptr);
+       for (cp=line; cp<strt; cp++)
+               putc(*cp,sortptr);
+       putc('\n',sortptr);
+}
+
+getsort()
+{
+       register c;
+       register char *tilde, *linep, *ref;
+       char *p1a,*p1b,*p2a,*p2b,*p3a,*p3b,*p4a,*p4b;
+       int w;
+       char *rtrim(), *ltrim();
+
+       if((sortptr = fopen(sortfile,"r")) == NULL)
+               diag("Cannot open sorted data:",sortfile);
+
+       halflen = (llen-gutter)/2;
+       linep = line;
+       while((c = getc(sortptr)) != EOF) {
+               switch(c) {
+
+               case TILDE:
+                       tilde = linep;
+                       break;
+
+               case '\n':
+                       while(isspace(linep[-1]))
+                               linep--;
+                       ref = tilde;
+                       if(rflag) {
+                               while(ref<linep&&!isspace(*ref))
+                                       ref++;
+                               *ref++ = 0;
+                       }
+               /* the -1 is an overly conservative test to leave
+                  space for the / that signifies truncation*/
+                       p3b = rtrim(p3a=line,tilde,halflen-1);
+                       if(p3b-p3a>halflen-1)
+                               p3b = p3a+halflen-1;
+                       p2a = ltrim(ref,p2b=linep,halflen-1);
+                       if(p2b-p2a>halflen-1)
+                               p2a = p2b-halflen-1;
+                       p1b = rtrim(p1a=p3b+(isspace(p3b[0])!=0),tilde,
+                               w=halflen-(p2b-p2a)-gap);
+                       if(p1b-p1a>w)
+                               p1b = p1a;
+                       p4a = ltrim(ref,p4b=p2a-(isspace(p2a[-1])!=0),
+                               w=halflen-(p3b-p3a)-gap);
+                       if(p4b-p4a>w)
+                               p4a = p4b;
+                       fprintf(outptr,".xx \"");
+                       putout(p1a,p1b);
+       /* tilde-1 to account for extra space before TILDE */
+                       if(p1b!=(tilde-1) && p1a!=p1b)
+                               fprintf(outptr,"/");
+                       fprintf(outptr,"\" \"");
+                       if(p4a==p4b && p2a!=ref && p2a!=p2b)
+                               fprintf(outptr,"/");
+                       putout(p2a,p2b);
+                       fprintf(outptr,"\" \"");
+                       putout(p3a,p3b);
+       /* ++p3b to account for extra blank after TILDE */
+       /* ++p3b to account for extra space before TILDE */
+                       if(p1a==p1b && ++p3b!=tilde)
+                               fprintf(outptr,"/");
+                       fprintf(outptr,"\" \"");
+                       if(p1a==p1b && p4a!=ref && p4a!=p4b)
+                               fprintf(outptr,"/");
+                       putout(p4a,p4b);
+                       if(rflag)
+                               fprintf(outptr,"\" %s\n",tilde);
+                       else
+                               fprintf(outptr,"\"\n");
+                       linep = line;
+                       break;
+
+               case '"':
+       /* put double " for "  */
+                       *linep++ = c;
+               default:
+                       *linep++ = c;
+               }
+       }
+}
+
+char *rtrim(a,c,d)
+char *a,*c;
+{
+       char *b,*x;
+       b = c;
+       for(x=a+1; x<=c&&x-a<=d; x++)
+               if((x==c||isspace(x[0]))&&!isspace(x[-1]))
+                       b = x;
+       if(b<c&&!isspace(b[0]))
+               b++;
+       return(b);
+}
+
+char *ltrim(c,b,d)
+char *c,*b;
+{
+       char *a,*x;
+       a = c;
+       for(x=b-1; x>=c&&b-x<=d; x--)
+               if(!isspace(x[0])&&(x==c||isspace(x[-1])))
+                       a = x;
+       if(a>c&&!isspace(a[-1]))
+               a--;
+       return(a);
+}
+
+putout(strt,end)
+char *strt, *end;
+{
+       char *cp;
+
+       cp = strt;
+
+       for(cp=strt; cp<end; cp++) {
+               putc(*cp,outptr);
+       }
+}
+
+onintr()
+{
+
+       if(*sortfile)
+               unlink(sortfile);
+       exit(1);
+}
+
+hash(strtp,endp)
+char *strtp, *endp;
+{
+       char *cp, c;
+       int i, j, k;
+
+       /* Return zero hash number for single letter words */
+       if((endp - strtp) == 1)
+               return(0);
+
+       cp = strtp;
+       c = *cp++;
+       i = (isupper(c)?tolower(c):c);
+       c = *cp;
+       j = (isupper(c)?tolower(c):c);
+       i = i*j;
+       cp = --endp;
+       c = *cp--;
+       k = (isupper(c)?tolower(c):c);
+       c = *cp;
+       j = (isupper(c)?tolower(c):c);
+       j = k*j;
+
+       k = (i ^ (j>>2)) & MASK;
+       return(k);
+}
+
+storeh(num,strtp)
+int num;
+char *strtp;
+{
+       int i;
+
+       for(i=num; i<MAXT; i++) {
+               if(hasht[i] == 0) {
+                       hasht[i] = strtp;
+                       return(0);
+               }
+       }
+       for(i=0; i<num; i++) {
+               if(hasht[i] == 0) {
+                       hasht[i] = strtp;
+                       return(0);
+               }
+       }
+       return(1);
+}
diff --git a/usr/src/cmd/pwd.c b/usr/src/cmd/pwd.c
new file mode 100644 (file)
index 0000000..b060709
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Print working (current) directory
+ */
+#include       <stdio.h>
+#include       <sys/param.h>
+#include       <sys/stat.h>
+#include       <sys/dir.h>
+
+char   dot[]   = ".";
+char   dotdot[] = "..";
+char   name[512];
+int    file;
+int    off     = -1;
+struct stat    d, dd;
+struct direct  dir;
+
+main()
+{
+       int rdev, rino;
+
+       stat("/", &d);
+       rdev = d.st_dev;
+       rino = d.st_ino;
+       for (;;) {
+               stat(dot, &d);
+               if (d.st_ino==rino && d.st_dev==rdev)
+                       prname();
+               if ((file = open(dotdot,0)) < 0) {
+                       fprintf(stderr,"pwd: cannot open ..\n");
+                       exit(1);
+               }
+               fstat(file, &dd);
+               chdir(dotdot);
+               if(d.st_dev == dd.st_dev) {
+                       if(d.st_ino == dd.st_ino)
+                               prname();
+                       do
+                               if (read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) {
+                                       fprintf(stderr,"read error in ..\n");
+                                       exit(1);
+                               }
+                       while (dir.d_ino != d.st_ino);
+               }
+               else do {
+                               if(read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) {
+                                       fprintf(stderr,"read error in ..\n");
+                                       exit(1);
+                               }
+                               stat(dir.d_name, &dd);
+                       } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
+               close(file);
+               cat();
+       }
+}
+
+prname()
+{
+       write(1, "/", 1);
+       if (off<0)
+               off = 0;
+       name[off] = '\n';
+       write(1, name, off+1);
+       exit(0);
+}
+
+cat()
+{
+       register i, j;
+
+       i = -1;
+       while (dir.d_name[++i] != 0);
+       if ((off+i+2) > 511)
+               prname();
+       for(j=off+1; j>=0; --j)
+               name[j+i+1] = name[j];
+       off=i+off+1;
+       name[i] = '/';
+       for(--i; i>=0; --i)
+               name[i] = dir.d_name[i];
+}
diff --git a/usr/src/cmd/quot.c b/usr/src/cmd/quot.c
new file mode 100644 (file)
index 0000000..984102a
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Disk usage by user
+ */
+
+char   *dargv[] = {
+       "/dev/rrp3",
+       0
+};
+
+#include <stdio.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <sys/param.h>
+#include <sys/ino.h>
+#include <sys/inode.h>
+#include <sys/filsys.h>
+
+#define        ITABSZ  256
+#define        ISIZ    (BSIZE/sizeof(struct dinode))
+#define        NUID    300
+struct filsys  sblock;
+struct dinode  itab[ITABSZ];
+struct du
+{
+       long    blocks;
+       long    nfiles;
+       int     uid;
+       char    *name;
+} du[NUID];
+#define        TSIZE   500
+int    sizes[TSIZE];
+long   overflow;
+
+int    nflg;
+int    fflg;
+int    cflg;
+
+int    fi;
+unsigned       ino;
+unsigned       nfiles;
+
+struct passwd  *getpwent();
+char   *malloc();
+char   *copy();
+
+main(argc, argv)
+char **argv;
+{
+       register int n;
+       register struct passwd *lp;
+       register char **p;
+
+       for(n=0; n<NUID; n++)
+               du[n].uid = n;
+       while((lp=getpwent()) != 0) {
+               n = lp->pw_uid;
+               if (n>NUID)
+                       continue;
+               if(du[n].name)
+                       continue;
+               du[n].name = copy(lp->pw_name);
+       }
+       if (argc == 1) {
+               for (p = dargv; *p;) {
+                       check(*p++);
+                       report();
+               }
+               return(0);
+       }
+       while (--argc) {
+               argv++;
+               if (argv[0][0]=='-') {
+                       if (argv[0][1]=='n')
+                               nflg++;
+                       else if (argv[0][1]=='f')
+                               fflg++;
+                       else if (argv[0][1]=='c')
+                               cflg++;
+               } else {
+                       check(*argv);
+                       report();
+               }
+       }
+       return(0);
+}
+
+check(file)
+char *file;
+{
+       register unsigned i, j;
+       register c;
+
+       fi = open(file, 0);
+       if (fi < 0) {
+               printf("cannot open %s\n", file);
+               return;
+       }
+       printf("%s:\n", file);
+       sync();
+       bread(1, (char *)&sblock, sizeof sblock);
+       nfiles = (sblock.s_isize-2)*(BSIZE/sizeof(struct dinode));
+       ino = 0;
+       if (nflg) {
+               if (isdigit(c = getchar()))
+                       ungetc(c, stdin);
+               else while (c!='\n' && c != EOF)
+                       c = getchar();
+       }
+       for(i=2; ino<nfiles; i += ITABSZ/ISIZ) {
+               bread(i, (char *)itab, sizeof itab);
+               for (j=0; j<ITABSZ && ino<nfiles; j++) {
+                       ino++;
+                       acct(&itab[j]);
+               }
+       }
+}
+
+acct(ip)
+register struct dinode *ip;
+{
+       register n;
+       register char *np;
+       static fino;
+
+       if ((ip->di_mode&IFMT) == 0)
+               return;
+       if (cflg) {
+               if ((ip->di_mode&IFMT)!=IFDIR && (ip->di_mode&IFMT)!=IFREG)
+                       return;
+               n = (ip->di_size+BSIZE-1)/BSIZE;
+               if (n >= TSIZE) {
+                       overflow += n;
+                       n = TSIZE-1;
+               }
+               sizes[n]++;
+               return;
+       }
+       if (ip->di_uid >= NUID)
+               return;
+       du[ip->di_uid].blocks += (ip->di_size+BSIZE-1)/BSIZE;
+       du[ip->di_uid].nfiles++;
+       if (nflg) {
+       tryagain:
+               if (fino==0)
+                       if (scanf("%d", &fino)<=0)
+                               return;
+               if (fino > ino)
+                       return;
+               if (fino<ino) {
+                       while ((n=getchar())!='\n' && n!=EOF)
+                               ;
+                       fino = 0;
+                       goto tryagain;
+               }
+               if (np = du[ip->di_uid].name)
+                       printf("%.7s    ", np);
+               else
+                       printf("%d      ", ip->di_uid);
+               while ((n = getchar())==' ' || n=='\t')
+                       ;
+               putchar(n);
+               while (n!=EOF && n!='\n') {
+                       n = getchar();
+                       putchar(n);
+               }
+               fino = 0;
+       }
+}
+
+bread(bno, buf, cnt)
+unsigned bno;
+char *buf;
+{
+
+       lseek(fi, (long)bno*BSIZE, 0);
+       if (read(fi, buf, cnt) != cnt) {
+               printf("read error %u\n", bno);
+               exit(1);
+       }
+}
+
+qcmp(p1, p2)
+register struct du *p1, *p2;
+{
+       if (p1->blocks > p2->blocks)
+               return(-1);
+       if (p1->blocks < p2->blocks)
+               return(1);
+       return(strcmp(p1->name, p2->name));
+}
+
+report()
+{
+       register i;
+
+       if (nflg)
+               return;
+       if (cflg) {
+               long t = 0;
+               for (i=0; i<TSIZE-1; i++)
+                       if (sizes[i]) {
+                               t += i*sizes[i];
+                               printf("%d      %d      %D\n", i, sizes[i], t);
+                       }
+               printf("%d      %d      %D\n", TSIZE-1, sizes[TSIZE-1], overflow+t);
+               return;
+       }
+       qsort(du, NUID, sizeof(du[0]), qcmp);
+       for (i=0; i<NUID; i++) {
+               if (du[i].blocks==0)
+                       return;
+               printf("%5D\t", du[i].blocks);
+               if (fflg)
+                       printf("%5D\t", du[i].nfiles);
+               if (du[i].name)
+                       printf("%s\n", du[i].name);
+               else
+                       printf("#%d\n", du[i].uid);
+       }
+}
+
+char *
+copy(s)
+char *s;
+{
+       register char *p;
+       register n;
+
+       for(n=0; s[n]; n++)
+               ;
+       p = malloc((unsigned)n+1);
+       for(n=0; p[n] = s[n]; n++)
+               ;
+       return(p);
+}
diff --git a/usr/src/cmd/random.c b/usr/src/cmd/random.c
new file mode 100644 (file)
index 0000000..8242d8b
--- /dev/null
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#define MAXINT 32768.
+float fract = 2;
+double atof();
+char rflag,eflag,c;
+char ibuf[BUFSIZ],obuf[BUFSIZ],line[BUFSIZ];
+main(argc,argv) char **argv;
+{
+       long tvec;
+       int i;
+       for(i=1;i<argc;i++)
+       {       if(*argv[i]!='-')
+                       fract=atof(argv[i]);
+               else if((c=argv[i][1])=='e')
+                       eflag=1;
+               else if(c=='r')
+                       rflag=1;
+       }
+       time(&tvec);
+       srand((int)tvec);
+       if(!rflag && !eflag)
+       {       setbuf(stdin,ibuf);
+               setbuf(stdout,obuf);
+       }
+       for(;eflag==0;)
+       {       gets(line);
+               if(feof(stdin)) break;
+               if(rand()/MAXINT*fract<1) puts(line);
+       }
+       exit((int)(rand()/MAXINT*fract));
+}
diff --git a/usr/src/cmd/rev.c b/usr/src/cmd/rev.c
new file mode 100644 (file)
index 0000000..9ced2bf
--- /dev/null
@@ -0,0 +1,44 @@
+#include <stdio.h>
+
+/* reverse lines of a file */
+
+#define N 256
+char line[N];
+FILE *input;
+
+main(argc,argv)
+char **argv;
+{
+       register i,c;
+       input = stdin;
+       do {
+               if(argc>1) {
+                       if((input=fopen(argv[1],"r"))==NULL) {
+                               fprintf(stderr,"rev: cannot open %s\n",
+                                       argv[1]);
+                               exit(1);
+                       }
+               }
+               for(;;){
+                       for(i=0;i<N;i++) {
+                               line[i] = c = getc(input);
+                               switch(c) {
+                               case EOF:
+                                       goto eof;
+                               default:
+                                       continue;
+                               case '\n':
+                                       break;
+                               }
+                               break;
+                       }
+                       while(--i>=0)
+                               putc(line[i],stdout);
+                       putc('\n',stdout);
+               }
+eof:
+               fclose(input);
+               argc--;
+               argv++;
+       } while(argc>1);
+}
diff --git a/usr/src/cmd/rm.c b/usr/src/cmd/rm.c
new file mode 100644 (file)
index 0000000..fcab28c
--- /dev/null
@@ -0,0 +1,162 @@
+int    errcode;
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+
+char   *sprintf();
+
+main(argc, argv)
+char *argv[];
+{
+       register char *arg;
+       int fflg, iflg, rflg;
+
+       fflg = 0;
+       if (isatty(0) == 0)
+               fflg++;
+       iflg = 0;
+       rflg = 0;
+       if(argc>1 && argv[1][0]=='-') {
+               arg = *++argv;
+               argc--;
+               while(*++arg != '\0')
+                       switch(*arg) {
+                       case 'f':
+                               fflg++;
+                               break;
+                       case 'i':
+                               iflg++;
+                               break;
+                       case 'r':
+                               rflg++;
+                               break;
+                       default:
+                               printf("rm: unknown option %s\n", *argv);
+                               exit(1);
+                       }
+       }
+       while(--argc > 0) {
+               if(!strcmp(*++argv, "..")) {
+                       fprintf(stderr, "rm: cannot remove `..'\n");
+                       continue;
+               }
+               rm(*argv, fflg, rflg, iflg, 0);
+       }
+
+       exit(errcode);
+}
+
+rm(arg, fflg, rflg, iflg, level)
+char arg[];
+{
+       struct stat buf;
+       struct direct direct;
+       char name[100];
+       int d;
+
+       if(stat(arg, &buf)) {
+               if (fflg==0) {
+                       printf("rm: %s nonexistent\n", arg);
+                       ++errcode;
+               }
+               return;
+       }
+       if ((buf.st_mode&S_IFMT) == S_IFDIR) {
+               if(rflg) {
+                       if (access(arg, 02) < 0) {
+                               if (fflg==0)
+                                       printf("%s not changed\n", arg);
+                               errcode++;
+                               return;
+                       }
+                       if(iflg && level!=0) {
+                               printf("directory %s: ", arg);
+                               if(!yes())
+                                       return;
+                       }
+                       if((d=open(arg, 0)) < 0) {
+                               printf("rm: %s: cannot read\n", arg);
+                               exit(1);
+                       }
+                       while(read(d, (char *)&direct, sizeof(direct)) == sizeof(direct)) {
+                               if(direct.d_ino != 0 && !dotname(direct.d_name)) {
+                                       sprintf(name, "%s/%.14s", arg, direct.d_name);
+                                       rm(name, fflg, rflg, iflg, level+1);
+                               }
+                       }
+                       close(d);
+                       errcode += rmdir(arg, iflg);
+                       return;
+               }
+               printf("rm: %s directory\n", arg);
+               ++errcode;
+               return;
+       }
+
+       if(iflg) {
+               printf("%s: ", arg);
+               if(!yes())
+                       return;
+       }
+       else if(!fflg) {
+               if (access(arg, 02)<0) {
+                       printf("rm: %s %o mode ", arg, buf.st_mode&0777);
+                       if(!yes())
+                               return;
+               }
+       }
+       if(unlink(arg) && (fflg==0 || iflg)) {
+               printf("rm: %s not removed\n", arg);
+               ++errcode;
+       }
+}
+
+dotname(s)
+char *s;
+{
+       if(s[0] == '.')
+               if(s[1] == '.')
+                       if(s[2] == '\0')
+                               return(1);
+                       else
+                               return(0);
+               else if(s[1] == '\0')
+                       return(1);
+       return(0);
+}
+
+rmdir(f, iflg)
+char *f;
+{
+       int status, i;
+
+       if(dotname(f))
+               return(0);
+       if(iflg) {
+               printf("%s: ", f);
+               if(!yes())
+                       return(0);
+       }
+       while((i=fork()) == -1)
+               sleep(3);
+       if(i) {
+               wait(&status);
+               return(status);
+       }
+       execl("/bin/rmdir", "rmdir", f, 0);
+       execl("/usr/bin/rmdir", "rmdir", f, 0);
+       printf("rm: can't find rmdir\n");
+       exit(1);
+}
+
+yes()
+{
+       int i, b;
+
+       i = b = getchar();
+       while(b != '\n' && b != EOF)
+               b = getchar();
+       return(i == 'y');
+}
diff --git a/usr/src/cmd/rmdir.c b/usr/src/cmd/rmdir.c
new file mode 100644 (file)
index 0000000..5b896c4
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Remove directory
+ */
+
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+int    Errors = 0;
+char   *rindex();
+char   *strcat();
+char   *strcpy();
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+
+       if(argc < 2) {
+               fprintf(stderr, "rmdir: arg count\n");
+               exit(1);
+       }
+       while(--argc)
+               rmdir(*++argv);
+       exit(Errors!=0);
+}
+
+rmdir(d)
+char *d;
+{
+       int     fd;
+       char    *np, name[500];
+       struct  stat    st, cst;
+       struct  direct  dir;
+
+       strcpy(name, d);
+       if((np = rindex(name, '/')) == NULL)
+               np = name;
+       if(stat(name,&st) < 0) {
+               fprintf(stderr, "rmdir: %s non-existent\n", name);
+               ++Errors;
+               return;
+       }
+       if (stat("", &cst) < 0) {
+               fprintf(stderr, "rmdir: cannot stat \"\"");
+               ++Errors;
+               exit(1);
+       }
+       if((st.st_mode & S_IFMT) != S_IFDIR) {
+               fprintf(stderr, "rmdir: %s not a directory\n", name);
+               ++Errors;
+               return;
+       }
+       if(st.st_ino==cst.st_ino &&st.st_dev==cst.st_dev) {
+               fprintf(stderr, "rmdir: cannot remove current directory\n");
+               ++Errors;
+               return;
+       }
+       if((fd = open(name,0)) < 0) {
+               fprintf(stderr, "rmdir: %s unreadable\n", name);
+               ++Errors;
+               return;
+       }
+       while(read(fd, (char *)&dir, sizeof dir) == sizeof dir) {
+               if(dir.d_ino == 0) continue;
+               if(!strcmp(dir.d_name, ".") || !strcmp(dir.d_name, ".."))
+                       continue;
+               fprintf(stderr, "rmdir: %s not empty\n", name);
+               ++Errors;
+               close(fd);
+               return;
+       }
+       close(fd);
+       if(!strcmp(np, ".") || !strcmp(np, "..")) {
+               fprintf(stderr, "rmdir: cannot remove . or ..\n");
+               ++Errors;
+               return;
+       }
+       strcat(name, "/.");
+       if((access(name, 0)) < 0) {             /* name/. non-existent */
+               strcat(name, ".");
+               goto unl;
+       }
+       strcat(name, ".");
+       if((access(name, 0)) < 0)               /* name/.. non-existent */
+               goto unl2;
+       if(access(name, 02)) {
+               name[strlen(name)-3] = '\0';
+               fprintf(stderr, "rmdir: %s: no permission\n", name);
+               ++Errors;
+               return;
+       }
+unl:
+       unlink(name);   /* unlink name/.. */
+unl2:
+       name[strlen(name)-1] = '\0';
+       unlink(name);   /* unlink name/.  */
+       name[strlen(name)-2] = '\0';
+       if (unlink(name) < 0) {
+               fprintf(stderr, "rmdir: %s not removed\n", name);
+               ++Errors;
+       }
+}
diff --git a/usr/src/cmd/size.c b/usr/src/cmd/size.c
new file mode 100644 (file)
index 0000000..7a3d75f
--- /dev/null
@@ -0,0 +1,46 @@
+#include       <stdio.h>
+#include       <a.out.h>
+
+/*
+       size -- determine object size
+
+*/
+
+int a_magic[] = {A_MAGIC1,A_MAGIC2,A_MAGIC3,A_MAGIC4,0};
+
+main(argc, argv)
+char **argv;
+{
+       struct exec buf;
+       long sum;
+       int gorp,i;
+       FILE *f;
+
+       if (argc==1) {
+               *argv = "a.out";
+               argc++;
+               --argv;
+       }
+       gorp = argc;
+       while(--argc) {
+               ++argv;
+               if ((f = fopen(*argv, "r"))==NULL) {
+                       printf("size: %s not found\n", *argv);
+                       continue;
+               }
+               fread((char *)&buf, sizeof(buf), 1, f);
+               for(i=0;a_magic[i];i++)
+                       if(a_magic[i] == buf.a_magic) break;
+               if(a_magic[i] == 0) {
+                       printf("size: %s not an object file\n", *argv);
+                       fclose(f);
+                       continue;
+               }
+               if (gorp>2)
+                       printf("%s: ", *argv);
+               printf("%u+%u+%u = ", buf.a_text,buf.a_data,buf.a_bss);
+               sum = (long) buf.a_text + (long) buf.a_data + (long) buf.a_bss;
+               printf("%Db = 0%Ob\n", sum, sum);
+               fclose(f);
+       }
+}
diff --git a/usr/src/cmd/sleep.c b/usr/src/cmd/sleep.c
new file mode 100644 (file)
index 0000000..a52bc3d
--- /dev/null
@@ -0,0 +1,21 @@
+main(argc, argv)
+char **argv;
+{
+       int c, n;
+       char *s;
+
+       n = 0;
+       if(argc < 2) {
+               printf("arg count\n");
+               exit(0);
+       }
+       s = argv[1];
+       while(c = *s++) {
+               if(c<'0' || c>'9') {
+                       printf("bad character\n");
+                       exit(0);
+               }
+               n = n*10 + c - '0';
+       }
+       sleep(n);
+}