Applications/V7: Batch two from last night
authorAlan Cox <alan@linux.intel.com>
Thu, 19 Mar 2015 14:05:59 +0000 (14:05 +0000)
committerAlan Cox <alan@linux.intel.com>
Thu, 19 Mar 2015 14:05:59 +0000 (14:05 +0000)
Applications/V7/cmd/rev.c [new file with mode: 0644]
Applications/V7/cmd/split.c [new file with mode: 0644]
Applications/V7/cmd/su.c [new file with mode: 0644]
Applications/V7/cmd/sum.c [new file with mode: 0644]
Applications/V7/cmd/test.c [new file with mode: 0644]
Applications/V7/cmd/time.c [new file with mode: 0644]
Applications/V7/cmd/tsort.c [new file with mode: 0644]
Applications/V7/cmd/wall.c [new file with mode: 0644]

diff --git a/Applications/V7/cmd/rev.c b/Applications/V7/cmd/rev.c
new file mode 100644 (file)
index 0000000..8ce5041
--- /dev/null
@@ -0,0 +1,49 @@
+/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */
+/* ANSIfied for FUZIX */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* reverse lines of a file */
+
+#define N 1024
+char line[N];
+FILE *input;
+
+int main(int argc, 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:
+               if (input != stdin)
+                       fclose(input);
+               argc--;
+               argv++;
+       } while (argc > 1);
+       return 0;
+}
diff --git a/Applications/V7/cmd/split.c b/Applications/V7/cmd/split.c
new file mode 100644 (file)
index 0000000..6d1ba9d
--- /dev/null
@@ -0,0 +1,83 @@
+/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+unsigned count = 1000;
+int    fnumber;
+char   fname[100];
+const char *ifil;
+const char *ofil;
+FILE   *is;
+FILE   *os;
+
+int main(int argc, const char *argv[])
+{
+       register i, c, f;
+       int iflg = 0;
+
+       for(i=1; i<argc; i++)
+               if(argv[i][0] == '-')
+                       switch(argv[i][1]) {
+               
+                       case '\0':
+                               iflg = 1;
+                               continue;
+               
+                       case '0':
+                       case '1':
+                       case '2':
+                       case '3':
+                       case '4':
+                       case '5':
+                       case '6':
+                       case '7':
+                       case '8':
+                       case '9':
+                               count = atoi(argv[i]+1);
+                               continue;
+                       }
+               else if(iflg)
+                       ofil = argv[i];
+               else {
+                       ifil = argv[i];
+                       iflg = 2;
+               }
+       if(iflg != 2)
+               is = stdin;
+       else
+               if((is=fopen(ifil,"r")) == NULL) {
+                       fprintf(stderr,"cannot open input\n");
+                       exit(1);
+               }
+       if(ofil == 0)
+               ofil = "x";
+
+loop:
+       f = 1;
+       for(i=0; i<count; i++)
+       do {
+               c = getc(is);
+               if(c == EOF) {
+                       if(f == 0)
+                               fclose(os);
+                       exit(0);
+               }
+               if(f) {
+                       for(f=0; ofil[f]; f++)
+                               fname[f] = ofil[f];
+                       fname[f++] = fnumber/26 + 'a';
+                       fname[f++] = fnumber%26 + 'a';
+                       fname[f] = '\0';
+                       fnumber++;
+                       if((os=fopen(fname,"w")) == NULL) {
+                               fprintf(stderr,"Cannot create output\n");
+                               exit(1);
+                       }
+                       f = 0;
+               }
+               putc(c, os);
+       } while(c != '\n');
+       fclose(os);
+       goto loop;
+}
diff --git a/Applications/V7/cmd/su.c b/Applications/V7/cmd/su.c
new file mode 100644 (file)
index 0000000..a41091b
--- /dev/null
@@ -0,0 +1,63 @@
+
+/* ANSIfield for FUZIX, some security holes fixed */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <err.h>
+#include <pwd.h>
+
+struct passwd *pwd;
+
+/* FIXME: su - and other semantics of later su versions */
+
+int main(int argc, char *argv[])
+{
+       register const char **p;
+       const char *nptr;
+       char *password;
+       int badsw = 0;
+       const char *shell = "/bin/sh";
+
+       /* If fd 0,1,2 are not all open something funny is up so
+          exit */
+       if (dup(0) < 3)
+               _exit(1);
+
+       if (argc > 1)
+               nptr = argv[1];
+       else
+               nptr = "root";
+       if ((pwd = getpwnam(nptr)) == NULL) {
+               printf("Unknown id: %s\n", nptr);
+               exit(1);
+       }
+       if (pwd->pw_passwd[0] == '\0' || getuid() == 0)
+               goto ok;
+       password = getpass("Password:");
+       if (badsw
+           || (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) !=
+               0)) {
+               printf("Sorry\n");
+               exit(2);
+       }
+
+      ok:
+       endpwent();
+       if (setgid(pwd->pw_gid) < 0)
+               err(1, "setgid");
+       if (setuid(pwd->pw_uid) < 0)
+               err(1, "setuid");
+       if (pwd->pw_shell && *pwd->pw_shell)
+               shell = pwd->pw_shell;
+       for (p = environ; *p; p++) {
+               if (strncmp("PS1=", *p, 4) == 0) {
+                       *p = "PS1=# ";
+                       break;
+               }
+       }
+       execl(shell, "su", 0);
+       printf("No shell\n");
+       exit(3);
+}
diff --git a/Applications/V7/cmd/sum.c b/Applications/V7/cmd/sum.c
new file mode 100644 (file)
index 0000000..ff8fdb3
--- /dev/null
@@ -0,0 +1,52 @@
+/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */
+
+/*
+ * Sum bytes in file mod 2^16
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, const char *argv[])
+{
+       register unsigned sum;
+       register i, c;
+       register FILE *f;
+       register long nbytes;
+       int errflg = 0;
+
+       i = 1;
+       do {
+               if (i < argc) {
+                       if ((f = fopen(argv[i], "r")) == NULL) {
+                               fprintf(stderr, "sum: Can't open %s\n",
+                                       argv[i]);
+                               errflg += 10;
+                               continue;
+                       }
+               } else
+                       f = stdin;
+               sum = 0;
+               nbytes = 0;
+               while ((c = getc(f)) != EOF) {
+                       nbytes++;
+                       if (sum & 01)
+                               sum = (sum >> 1) + 0x8000;
+                       else
+                               sum >>= 1;
+                       sum += c;
+                       sum &= 0xFFFF;
+               }
+               if (ferror(f)) {
+                       errflg++;
+                       fprintf(stderr, "sum: read error on %s\n",
+                               argc > 1 ? argv[i] : "-");
+               }
+               printf("%05u%6ld", sum, (nbytes + BUFSIZ - 1) / BUFSIZ);
+               if (argc > 2)
+                       printf(" %s", argv[i]);
+               printf("\n");
+               fclose(f);
+       } while (++i < argc);
+       exit(errflg);
+}
diff --git a/Applications/V7/cmd/test.c b/Applications/V7/cmd/test.c
new file mode 100644 (file)
index 0000000..d80a731
--- /dev/null
@@ -0,0 +1,203 @@
+/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */
+/* ANSIfied for FUZIX */
+
+/*
+ *     test expression
+ *     [ expression ]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#define EQ(a,b)        ((tmp=a)==0?0:(strcmp(tmp,b)==0))
+
+#define DIR 1
+#define FIL 2
+int ap;
+int ac;
+const char **av;
+const char *tmp;
+
+void synbad(const char *s1, const char *s2)
+{
+       write(2, "test: ", 6);
+       write(2, s1, strlen(s1));
+       write(2, s2, strlen(s2));
+       write(2, "\n", 1);
+       exit(255);
+}
+
+int length(char *s)
+{
+       char *es = s;
+       while (*es++);
+       return (es - s - 1);
+}
+
+char *nxtarg(int mt)
+{
+       if (ap >= ac) {
+               if (mt) {
+                       ap++;
+                       return (0);
+               }
+               synbad("argument expected", "");
+       }
+       return (av[ap++]);
+}
+
+int tio(char *a, int f)
+{
+       /* FIXME: should use stat and parse permissions */
+       f = open(a, f);
+       if (f >= 0) {
+               close(f);
+               return (1);
+       }
+       return (0);
+}
+
+int ftype(char *f)
+{
+       struct stat statb;
+
+       if (stat(f, &statb) < 0)
+               return (0);
+       if ((statb.st_mode & S_IFMT) == S_IFDIR)
+               return (DIR);
+       return (FIL);
+}
+
+int fsizep(char *f)
+{
+       struct stat statb;
+       if (stat(f, &statb) < 0)
+               return (0);
+       return (statb.st_size > 0);
+}
+
+
+int e3(void)
+{
+       int p1;
+       register char *a;
+       char *p2;
+       int int1, int2;
+
+       extern int exp(void);
+
+       a = nxtarg(0);
+       if (EQ(a, "(")) {
+               p1 = exp();
+               if (!EQ(nxtarg(0), ")"))
+                       synbad(") expected", "");
+               return (p1);
+       }
+
+       if (EQ(a, "-r"))
+               return (tio(nxtarg(0), 0));
+
+       if (EQ(a, "-w"))
+               return (tio(nxtarg(0), 1));
+
+       if (EQ(a, "-d"))
+               return (ftype(nxtarg(0)) == DIR);
+
+       if (EQ(a, "-f"))
+               return (ftype(nxtarg(0)) == FIL);
+
+       if (EQ(a, "-s"))
+               return (fsizep(nxtarg(0)));
+
+       if (EQ(a, "-t"))
+               if (ap >= ac)
+                       return (isatty(1));
+               else
+                       return (isatty(atoi(nxtarg(0))));
+
+       if (EQ(a, "-n"))
+               return (!EQ(nxtarg(0), ""));
+       if (EQ(a, "-z"))
+               return (EQ(nxtarg(0), ""));
+
+       p2 = nxtarg(1);
+       if (p2 == 0)
+               return (!EQ(a, ""));
+       if (EQ(p2, "="))
+               return (EQ(nxtarg(0), a));
+
+       if (EQ(p2, "!="))
+               return (!EQ(nxtarg(0), a));
+
+       if (EQ(a, "-l")) {
+               int1 = length(p2);
+               p2 = nxtarg(0);
+       } else {
+               int1 = atoi(a);
+       }
+       int2 = atoi(nxtarg(0));
+       if (EQ(p2, "-eq"))
+               return (int1 == int2);
+       if (EQ(p2, "-ne"))
+               return (int1 != int2);
+       if (EQ(p2, "-gt"))
+               return (int1 > int2);
+       if (EQ(p2, "-lt"))
+               return (int1 < int2);
+       if (EQ(p2, "-ge"))
+               return (int1 >= int2);
+       if (EQ(p2, "-le"))
+               return (int1 <= int2);
+
+       synbad("unknown operator ", p2);
+}
+
+int e2(void)
+{
+       if (EQ(nxtarg(0), "!"))
+               return (!e3());
+       ap--;
+       return (e3());
+}
+
+int e1(void)
+{
+       int p1;
+
+       p1 = e2();
+       if (EQ(nxtarg(1), "-a"))
+               return (p1 & e1());
+       ap--;
+       return (p1);
+}
+
+int exp(void)
+{
+       int p1;
+
+       p1 = e1();
+       if (EQ(nxtarg(1), "-o"))
+               return (p1 | exp());
+       ap--;
+       return (p1);
+}
+
+
+int main(int argc, const char *argv[])
+{
+
+       ac = argc;
+       av = argv;
+       ap = 1;
+       if (EQ(argv[0], "[")) {
+               if (!EQ(argv[--ac], "]"))
+                       synbad("] missing", "");
+       }
+       argv[ac] = 0;
+       if (ac <= 1)
+               exit(1);
+       exit(exp()? 0 : 1);
+}
diff --git a/Applications/V7/cmd/time.c b/Applications/V7/cmd/time.c
new file mode 100644 (file)
index 0000000..6ddeb6d
--- /dev/null
@@ -0,0 +1,79 @@
+/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */
+/* ANSIfied and shrunk a bit for FUZIX */
+
+/* time command */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/times.h>
+
+char quant[] = { 6, 10, 10, 6, 10, 6, 10, 10, 10 };
+
+const char *pad = "000      ";
+const char *sep = "\0\0.\0:\0:\0\0";
+const char *nsep = "\0\0.\0 \0 \0\0";
+
+void printt(const char *s, long a)
+{
+       char digit[9];
+       register i;
+       char c;
+       int nonzero;
+
+       for (i = 0; i < 9; i++) {
+               digit[i] = a % quant[i];
+               a /= quant[i];
+       }
+       fputs(s, stderr);
+       nonzero = 0;
+       while (--i > 0) {
+               c = digit[i] != 0 ? digit[i] + '0' :
+                   nonzero ? '0' : pad[i];
+               fputc(c, stderr);
+               nonzero |= digit[i];
+               c = nonzero ? sep[i] : nsep[i];
+               fputc(c, stderr);
+       }
+       fputc('\n', stderr);
+}
+
+int main(int argc, const char *argv[])
+{
+       struct tms buffer, obuffer;
+       int status;
+       register p;
+       time_t before, after;
+
+       if (argc <= 1)
+               exit(0);
+       time(&before);
+       p = fork();
+       if (p == -1) {
+               fputs("Try again.\n", stderr);
+               exit(1);
+       }
+       if (p == 0) {
+               execvp(argv[1], &argv[1]);
+               perror(argv[1]);
+               _exit(1);
+       }
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+       times(&obuffer);
+       while (wait(&status) != p)
+               times(&obuffer);
+       time(&after);
+       if ((status & 0377) != 0)
+               fputs("Command terminated abnormally.\n", stderr);
+       times(&buffer);
+       fprintf(stderr, "\n");
+       printt("real", (after - before) * 60);
+       printt("user", buffer.tms_cutime - obuffer.tms_cutime);
+       printt("sys ", buffer.tms_cstime - obuffer.tms_cstime);
+       exit(status >> 8);
+}
diff --git a/Applications/V7/cmd/tsort.c b/Applications/V7/cmd/tsort.c
new file mode 100644 (file)
index 0000000..984e0da
--- /dev/null
@@ -0,0 +1,191 @@
+/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */
+/* ANSIfied for FUZIX */
+
+/*     topological sort
+ *     input is sequence of pairs of items (blank-free strings)
+ *     nonidentical pair is a directed edge in graph
+ *     identical pair merely indicates presence of node
+ *     output is ordered list of items consistent with
+ *     the partial ordering specified by the graph
+*/
+#include <stdio.h>
+#include <stdlib.h>
+
+/*     the nodelist always has an empty element at the end to
+ *     make it easy to grow in natural order
+*/
+
+struct nodelist {
+       struct nodelist *nextnode;
+       struct predlist *inedges;
+       char *name;
+       enum { DEAD, LIVE, ONCE, TWICE } live;
+} firstnode = {
+NULL, NULL, NULL, DEAD};
+
+/*     a predecessor list tells all the immediate
+ *     predecessors of a given node
+*/
+struct predlist {
+       struct predlist *nextpred;
+       struct nodelist *pred;
+};
+
+const char *empty = "";
+
+/*     is i present on j's predecessor list?
+*/
+int present(struct nodelist *i, struct nodelist *j)
+{
+       register struct predlist *t;
+       for (t = j->inedges; t != NULL; t = t->nextpred)
+               if (t->pred == i)
+                       return (1);
+       return (0);
+}
+
+/*     is there any live predecessor for i?
+*/
+int anypred(struct nodelist *i)
+{
+       register struct predlist *t;
+       for (t = i->inedges; t != NULL; t = t->nextpred)
+               if (t->pred->live == LIVE)
+                       return (1);
+       return (0);
+}
+
+void note(const char *s, const char *t)
+{
+       fprintf(stderr, "tsort: %s%s\n", s, t);
+}
+
+void error(const char *s, const char *t)
+{
+       note(s, t);
+       exit(1);
+}
+
+int cmp(const char *s, const char *t)
+{
+       while (*s == *t) {
+               if (*s == 0)
+                       return (1);
+               s++;
+               t++;
+       }
+       return (0);
+}
+
+/*     turn a string into a node pointer
+*/
+struct nodelist *index(const char *s)
+{
+       register struct nodelist *i;
+       register const char *t;
+       register char *n;
+       for (i = &firstnode; i->nextnode != NULL; i = i->nextnode)
+               if (cmp(s, i->name))
+                       return (i);
+       for (t = s; *t; t++);
+       n = malloc((unsigned) (t + 1 - s));
+       i->nextnode = (struct nodelist *) malloc(sizeof(struct nodelist));
+       if (i->nextnode == NULL || n == NULL)
+               error("too many items", empty);
+       i->name = n;
+       i->live = LIVE;
+       i->nextnode->nextnode = NULL;
+       i->nextnode->inedges = NULL;
+       i->nextnode->live = DEAD;
+       while (*n++ = *s++);
+       return (i);
+}
+
+
+
+/*     given that there is a cycle, find some
+ *     node in it
+*/
+struct nodelist *findloop(void)
+{
+       register struct nodelist *i, *j;
+       register struct predlist *p;
+       for (i = &firstnode; i->nextnode != NULL; i = i->nextnode)
+               if (i->live == LIVE)
+                       break;
+       note("cycle in reverse order", empty);
+       while (i->live == LIVE) {
+               i->live = ONCE;
+               for (p = i->inedges;; p = p->nextpred) {
+                       if (p == NULL)
+                               error("error 1", "");
+                       i = p->pred;
+                       if (i->live != DEAD)
+                               break;
+               }
+       }
+       while (i->live == ONCE) {
+               i->live = TWICE;
+               note(i->name, empty);
+               for (p = i->inedges;; p = p->nextpred) {
+                       if (p == NULL)
+                               error("error 2", "");
+                       i = p->pred;
+                       if (i->live != DEAD)
+                               break;
+               }
+       }
+       for (j = &firstnode; j->nextnode != NULL; j = j->nextnode)
+               if (j->live != DEAD)
+                       j->live = LIVE;
+       return (i);
+}
+
+
+/*     the first for loop reads in the graph,
+ *     the second prints out the ordering
+*/
+int main(int argc, const char *argv[])
+{
+       register struct predlist *t;
+       FILE *input = stdin;
+       register struct nodelist *i, *j;
+       int x;
+       char precedes[50], follows[50];
+       if (argc > 1) {
+               input = fopen(argv[1], "r");
+               if (input == NULL)
+                       error("cannot open ", argv[1]);
+       }
+       for (;;) {
+               x = fscanf(input, "%s%s", precedes, follows);
+               if (x == EOF)
+                       break;
+               if (x != 2)
+                       error("odd data", empty);
+               i = index(precedes);
+               j = index(follows);
+               if (i == j || present(i, j))
+                       continue;
+               t = (struct predlist *) malloc(sizeof(struct predlist));
+               t->nextpred = j->inedges;
+               t->pred = i;
+               j->inedges = t;
+       }
+       for (;;) {
+               x = 0;          /*anything LIVE on this sweep? */
+               for (i = &firstnode; i->nextnode != NULL; i = i->nextnode) {
+                       if (i->live == LIVE) {
+                               x = 1;
+                               if (!anypred(i))
+                                       break;
+                       }
+               }
+               if (x == 0)
+                       break;
+               if (i->nextnode == NULL)
+                       i = findloop();
+               printf("%s\n", i->name);
+               i->live = DEAD;
+       }
+}
diff --git a/Applications/V7/cmd/wall.c b/Applications/V7/cmd/wall.c
new file mode 100644 (file)
index 0000000..52001b0
--- /dev/null
@@ -0,0 +1,71 @@
+/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utmp.h>
+#define        USERS   50
+
+char mesg[3000];
+int msize;
+struct utmp utmp[USERS];
+
+void sendmes(char *tty)
+{
+       register i;
+       char t[50], buf[BUFSIZ];
+       FILE *f;
+
+       i = fork();
+       if (i == -1) {
+               fprintf(stderr, "Try again\n");
+               return;
+       }
+       if (i)
+               return;
+       strcpy(t, "/dev/");
+       strcat(t, tty);
+
+       /* FIXME: needs to use unix I/O and O_NDELAY, plus set an alarm */
+       if ((f = fopen(t, "w")) == NULL) {
+               fprintf(stderr, "cannot open %s\n", t);
+               exit(1);
+       }
+       setbuf(f, buf);
+       fprintf(f, "\a\a\aBroadcast Message ...\n\n");
+       fwrite(mesg, msize, 1, f);
+       exit(0);
+}
+
+int main(int argc, const char *argv[])
+{
+       register i;
+       register struct utmp *p;
+       FILE *f;
+
+       if ((f = fopen("/etc/utmp", "r")) == NULL) {
+               fprintf(stderr, "Cannot open /etc/utmp\n");
+               exit(1);
+       }
+       fread((char *) utmp, sizeof(struct utmp), USERS, f);
+       fclose(f);
+       f = stdin;
+       if (argc >= 2) {
+               if ((f = fopen(argv[1], "r")) == NULL) {
+                       fprintf(stderr, "Cannot open %s\n", argv[1]);
+                       exit(1);
+               }
+       }
+       while ((i = getc(f)) != EOF)
+               mesg[msize++] = i;
+       fclose(f);
+       for (i = 0; i < USERS; i++) {
+               p = &utmp[i];
+               if (p->ut_user[0] == 0)
+                       continue;
+               sleep(1);
+               sendmes(p->ut_line);
+       }
+       exit(0);
+}