From: Alan Cox Date: Thu, 19 Mar 2015 14:05:59 +0000 (+0000) Subject: Applications/V7: Batch two from last night X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=3eef476e4e42a9edb90a0a9312767c03685fc462;p=FUZIX.git Applications/V7: Batch two from last night --- diff --git a/Applications/V7/cmd/rev.c b/Applications/V7/cmd/rev.c new file mode 100644 index 00000000..8ce5041c --- /dev/null +++ b/Applications/V7/cmd/rev.c @@ -0,0 +1,49 @@ +/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */ +/* ANSIfied for FUZIX */ + +#include +#include + +/* 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 index 00000000..6d1ba9d8 --- /dev/null +++ b/Applications/V7/cmd/split.c @@ -0,0 +1,83 @@ +/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */ + +#include +#include + +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 +#include +#include +#include +#include +#include + +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 index 00000000..ff8fdb3f --- /dev/null +++ b/Applications/V7/cmd/sum.c @@ -0,0 +1,52 @@ +/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */ + +/* + * Sum bytes in file mod 2^16 + */ + +#include +#include + +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 index 00000000..d80a7311 --- /dev/null +++ b/Applications/V7/cmd/test.c @@ -0,0 +1,203 @@ +/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */ +/* ANSIfied for FUZIX */ + +/* + * test expression + * [ expression ] + */ + +#include +#include +#include +#include +#include +#include +#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 index 00000000..6ddeb6d3 --- /dev/null +++ b/Applications/V7/cmd/time.c @@ -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 +#include +#include +#include +#include + +#include +#include + +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 index 00000000..984e0da3 --- /dev/null +++ b/Applications/V7/cmd/tsort.c @@ -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 +#include + +/* 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 index 00000000..52001b03 --- /dev/null +++ b/Applications/V7/cmd/wall.c @@ -0,0 +1,71 @@ +/* UNIX V7 source code: see /COPYRIGHT or www.tuhs.org for details. */ + +#include +#include +#include +#include +#include +#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, "Broadcast 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); +}