v08i038: UNaXcess Conferencing, version 1.00.02, Part02/04
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Fri Feb 6 07:22:14 AEST 1987
Submitted by: abic!cwruecmp!allbery%ncoast.UUCP
Mod.sources: Volume 8, Issue 38
Archive-name: unaxcess2/Part02
#--------------------------------CUT HERE-------------------------------------
#! /bin/sh
#
# This is a shell archive. Save this into a file, edit it
# and delete all lines above this comment. Then give this
# file to sh by executing the command "sh file". The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-rw-rw- 1 allbery System 17362 Feb 3 21:10 message.c
# -rw-rw-rw- 1 allbery System 1052 Feb 3 21:11 mkconf.c
# -rw-rw-rw- 1 allbery System 4762 Feb 3 21:29 mvmsg.c
# -rw-rw-rw- 1 allbery System 18613 Feb 3 21:30 system.c
# -rw-rw-rw- 1 allbery System 1357 Feb 3 21:31 system.h
# -rw-rw-rw- 1 allbery System 8484 Feb 3 21:48 ua.c
# -rw-rw-rw- 1 allbery System 2555 Feb 3 21:32 ua.h
# -rw-rw-rw- 1 allbery System 419 Feb 3 21:33 udate.c
#
echo 'x - message.c'
sed 's/^X//' << '________This_Is_The_END________' > message.c
X/*
X * @(#)message.c 1.1 (TDI) 2/3/87
X * @(#)Copyright (C) 1984, 85, 86, 87 by Brandon S. Allbery.
X * @(#)This file is part of UNaXcess version 1.0.2.
X *
X * Permission is hereby granted to copy and distribute this program
X * freely. Permission is NOT given to modify this program or distribute
X * it at cost, except for charging a reasonable media/copying fee.
X */
X
X#ifndef lint
Xstatic char _FileID_[] = "@(#)message.c 1.1 (TDI) 2/3/87";
Xstatic char _UAID_[] = "@(#)UNaXcess version 1.0.2";
X#endif lint
X
X#include "ua.h"
X
Xextern struct cmd maincmd[];
X
Xselmsg(fn)
Xint (*fn)(); {
X char line[256], *p;
X short lomsg, himsg;
X FILE *f;
X
X sprintf(line, "%s/%s/himsg", MSGBASE, conference);
X if ((f = fopen(line, "r")) == NULL) {
X log("Error %d opening %s", errno, line);
X if (strcmp(conference, "general") == 0)
X panic("conf");
X writes("I can't find the high message file. Moving back to general...");
X strcpy(conference, "general");
X return 1;
X }
X fgets(line, 32, f);
X fclose(f);
X himsg = atoi(line);
X writef("Forward, Reverse, Individual, or New (RETURN to abort): ");
X line[0] = readc();
X log("Mode: %c", line[0]);
X switch (line[0]) {
X case 'F':
X lomsg = 1;
X break;
X case 'R':
X lomsg = himsg;
X himsg = 1;
X break;
X case 'I':
X writef("Enter message number: ");
X reads(line);
X log("Message: %s", line);
X if ((lomsg = atoi(line)) < 1 || lomsg > himsg) {
X writes("No such message.");
X log("No such message.");
X return 1;
X }
X domsg(conference, lomsg, lomsg, fn);
X return 1;
X case 'N':
X lomsg = 0;
X break;
X case ' ':
X return 1;
X default:
X writes("What? Valid commands are F, R, I, N, or ENTER.");
X log("Illegal search mode.");
X return 1;
X }
X if (lomsg != 0) {
X writef("Starting message (%d): ", lomsg);
X reads(line);
X log("Start: %s", line);
X if (line[0] != 0)
X if (atoi(line) < 1 || (lomsg > 1 && atoi(line) > lomsg)) {
X writes("Bad message number.");
X log("Bad message number.");
X return 1;
X }
X else
X lomsg = atoi(line);
X writef("Ending message (%d): ", himsg);
X reads(line);
X log("End: %s", line);
X if (line[0] != 0)
X if (atoi(line) < 1 || (himsg > 1 && atoi(line) > himsg)) {
X writes("Bad message number.");
X log("Bad message number.");
X return 1;
X }
X else
X himsg = atoi(line);
X }
X domsg(conference, lomsg, himsg, fn);
X return 1;
X}
X
Xreadmsg() {
X return selmsg(doread);
X}
X
Xscanmsg() {
X return selmsg(doscan);
X}
X
Xdoread(msg, conf, mnum)
Xchar *msg, *conf;
Xshort mnum; {
X char ch;
X
X writef("\nMessage %d of %s:\n", mnum, conf);
X if (isprivate(msg)) {
X writes("This message is private.");
X return 1;
X }
X cat(msg);
X
XDR_Loop:
X writef("\nContinue, Stop, %sEnter a message, Unsubscribe, Xecute, or Reply? C\b", (user.u_access == A_WITNESS || s_cmp(getowner(msg), user.u_name) == 0? "Kill, ": ""));
X if (!isatty(0)) {
X ch = ' ';
X writes("C");
X }
X else
X ch = readc();
X log("C/S/K/E/U/R/X: %c", ch);
X switch (ch) {
X case 'c':
X case 'C':
X case '\n':
X case '\r':
X case ' ':
X return 1;
X case 'U':
X case 'u':
X unsubscribe(conf);
X return 0;
X case 's':
X case 'S':
X return 0;
X case 'r':
X case 'R':
X reply(msg, conf);
X goto DR_Loop;
X case 'k':
X case 'K':
X if (unlink(msg) < 0) {
X writef("Can't kill message: %d", mnum);
X log("Error %d unlinking %s", errno, msg);
X goto DR_Loop;
X }
X log("Deleted %s:%d", conference, mnum);
X return 1;
X case 'E':
X case 'e':
X enter("");
X goto DR_Loop;
X case 'x':
X case 'X':
X __recurse++;
X pcmd("Command (? for help, G to return): ", maincmd, (char *) 0);
X goto DR_Loop;
X default:
X writef("What? Please enter one of C, S, %sE, U, X, or R.", (user.u_access == A_WITNESS || s_cmp(getowner(msg), user.u_name) == 0? "K, ": ""));
X goto DR_Loop;
X }
X}
X
Xmsgok(file)
Xchar *file; {
X FILE *fp;
X
X if ((fp = fopen(file, "r")) == NULL)
X return 0;
X fclose(fp);
X return 1;
X}
X
Xdoscan(msg, conf, mnum)
Xchar *msg, *conf;
Xshort mnum; {
X char line[1024];
X FILE *f;
X short dflag, fflag, tflag, sflag;
X
X if ((f = fopen(msg, "r")) == NULL) {
X writes("Cannot open file.");
X log("Error %d opening %s", errno, msg);
X return 1;
X }
X writef("\nMessage %d of %s: \n", mnum, conf);
X dflag = fflag = tflag = sflag = 0;
X if (isprivate(msg))
X writes("Message is private.");
X else {
X while (fgets(line, 1024, f) != NULL) {
X if (line[0] == '\n')
X break;
X if (!dflag && strncmp(line, "Date: ", 6) == 0) {
X writef("%s", line);
X dflag++;
X continue;
X }
X if (!fflag && strncmp(line, "From: ", 6) == 0) {
X writef("%s", line);
X fflag++;
X continue;
X }
X if (!tflag && strncmp(line, "To: ", 4) == 0) {
X writef("%s", line);
X tflag++;
X continue;
X }
X if (!sflag && strncmp(line, "Subject: ", 9) == 0) {
X writef("%s", line);
X sflag++;
X continue;
X }
X if (!sflag && strncmp(line, "Subject (Private): ", 19) == 0) {
X writef("%s", line);
X sflag++;
X continue;
X }
X }
X if (!tflag)
X writes("To: All");
X }
X fclose(f);
X writes("--------------------------------");
X return 1;
X}
X
Xdomsg(conf, lomsg, himsg, fn)
Xchar *conf;
Xshort lomsg, himsg;
Xint (*fn)(); {
X short mcnt;
X char tmps[256];
X struct _himsg *ptr;
X
X for (ptr = hicnts; ptr != NULL; ptr = ptr->hi_next)
X if (strcmp(conf, ptr->hi_conf) == 0)
X break;
X if (ptr == NULL) {
X/*
X * Query: how do you silence lint's complaints about calloc() casting?
X */
X if ((ptr = (struct _himsg *) calloc((unsigned) 1, sizeof (struct _himsg))) == NULL) {
X log("Error %d allocating _himsg for %s", errno, conf);
X panic("alloc");
X }
X ptr->hi_next = hicnts;
X hicnts = ptr;
X ptr->hi_uns = HI_SUBSCR;
X strcpy(ptr->hi_conf, conf);
X ptr->hi_num = 0;
X }
X if (lomsg == 0) /* read new messages */
X for (mcnt = ptr->hi_num + 1; mcnt <= himsg; mcnt++) {
X sprintf(tmps, "%s/%s/%d", MSGBASE, conf, mcnt);
X if (msgok(tmps) <= 0)
X continue;
X if (!(*fn)(tmps, conf, mcnt))
X break;
X }
X else if (lomsg <= himsg) /* forward or individual read */
X for (mcnt = lomsg; mcnt <= himsg; mcnt++) {
X sprintf(tmps, "%s/%s/%d", MSGBASE, conf, mcnt);
X if (msgok(tmps) <= 0)
X continue;
X if (!(*fn)(tmps, conf, mcnt))
X break;
X }
X else
X for (mcnt = lomsg; mcnt >= himsg; mcnt--) {
X sprintf(tmps, "%s/%s/%d", MSGBASE, conf, mcnt);
X if (msgok(tmps) <= 0)
X continue;
X if (!(*fn)(tmps, conf, mcnt))
X break;
X }
X ptr->hi_num = himsg;
X writehigh(hicnts);
X}
X
Xreadnew() {
X DIR *dp;
X struct direct *dirp;
X FILE *hp;
X short himsg;
X char line[256], ch;
X
X if ((dp = opendir(MSGBASE)) == NULL) {
X log("Error %d reading dir %s/", errno, MSGBASE);
X panic("msgdir");
X }
X while ((dirp = readdir(dp)) != NULL) {
X if (dirp->d_name[0] == '.')
X continue;
X if (isunsub(dirp->d_name))
X continue;
X log("Reading %s.", dirp->d_name);
X if (user.u_access != A_WITNESS && parms.ua_xrc)
X if (!isrcmem(user.u_name, dirp->d_name)) {
X log("Skipping Restricted conference.");
X continue;
X }
X writef("\nExamining conference %s...\n", dirp->d_name);
X sprintf(line, "%s/%s/himsg", MSGBASE, dirp->d_name);
X if ((hp = fopen(line, "r")) == NULL) {
X log("Error %d opening %s", errno, line);
X writes("Can't open high message file.");
X continue;
X }
X fgets(line, 32, hp);
X fclose(hp);
X himsg = atoi(line);
X domsg(dirp->d_name, 0, himsg, doread);
X
XRN_Loop:
X writef("\nNext conference, Unsubscribe, or Stop? N\b");
X if (!isatty(0)) {
X writes("N");
X ch = ' ';
X }
X else
X ch = readc();
X log("Next/Unsub/Stop: %c", ch);
X switch (ch) {
X case 'N':
X case 'n':
X case ' ':
X case '\r':
X case '\n':
X break;
X case 'U':
X case 'u':
X unsubscribe(dirp->d_name);
X break;
X case 'S':
X case 's':
X closedir(dp);
X return 1;
X default:
X writes("Please enter one of N, U, or S.");
X goto RN_Loop;
X }
X }
X closedir(dp);
X return 1;
X}
X
Xenter() {
X char to[256], subj[256], *p, line[256];
X short pflag;
X
X if (user.u_access == A_GUEST && strcmp(conference, "guest") != 0) {
X log("Security violation: GUEST entering messages.");
X writes("You aren't allowed to enter messages in this conference.");
X return 1;
X }
X writef("Who is this message to (ENTER to abort)? ");
X reads(line);
X log("To: %s", line);
X if (line[0] == '\0')
X return 1;
X for (p = line; *p != '\0'; p++)
X *p = ToLower(*p);
X strcpy(to, line);
X writef("Subject: ");
X reads(line);
X if (line[0] == '\0')
X return 1;
X strcpy(subj, line);
X log("Subject: %s", line);
X mkmsg(to, subj, conference, 0);
X return 1;
X}
X
Xreply(msg, conf)
Xchar *msg, *conf; {
X char to[256], subj[256], line[1024];
X short fflag, sflag, pflag;
X FILE *f;
X
X if (user.u_access == A_GUEST && strcmp(conf, "guest") != 0) {
X log("Security violation: GUEST entering messages");
X writes("You aren't allowed to enter messages.");
X return;
X }
X if ((f = fopen(msg, "r")) == NULL) {
X log("Error %d opening %s", errno, msg);
X writes("Can't re-open message file.");
X return;
X }
X fflag = sflag = 0;
X strcpy(to, "All\n");
X strcpy(subj, "Re: Orphaned Response\n"); /* now you know... */
X while (fgets(line, 1024, f) != NULL) {
X if (line[0] == '\n')
X break;
X if (!fflag && strncmp(line, "From: ", 6) == 0) {
X strcpy(to, &line[6]);
X fflag++;
X continue;
X }
X if (!sflag && strncmp(line, "Subject: ", 9) == 0) {
X if (strncmp(&line[9], "Re: ", 4) == 0)
X strcpy(subj, &line[9]);
X else
X strcpy(&subj[4], &line[9]);
X sflag++;
X pflag = 0;
X continue;
X }
X if (!sflag && strncmp(line, "Subject (Private): ", 19) == 0) {
X if (strncmp(&line[19], "Re: ", 4) == 0)
X strcpy(subj, &line[19]);
X else
X strcpy(&subj[4], &line[19]);
X sflag++;
X pflag = 1;
X continue;
X }
X }
X fclose(f);
X to[strlen(to) - 1] = '\0'; /* get rid of trailing nl */
X subj[strlen(subj) - 1] = '\0';
X mkmsg(to, subj, conf, pflag);
X}
X
Xdoqscan(msg, conf, mnum)
Xchar *msg, *conf;
Xshort mnum; {
X char line[1024];
X FILE *f;
X
X#ifdef lint
X puts(conf); /* shut lint up about "arg not used" */
X#endif lint
X if ((f = fopen(msg, "r")) == NULL) {
X writes("Cannot open file.");
X log("Error %d opening %s", errno, msg);
X return 1;
X }
X writef("%5d. ", mnum);
X if (isprivate(msg))
X writes("Private message.");
X else
X while (fgets(line, 1024, f) != NULL) {
X if (line[0] == '\n')
X break;
X if (strncmp(line, "Subject: ", 9) == 0) {
X writef("%s", &line[9]);
X break;
X }
X if (strncmp(line, "Subject (Private): ", 19) == 0) {
X writef("%s", &line[8]); /* include privacy tag */
X break;
X }
X }
X fclose(f);
X return 1;
X}
X
Xqscan() {
X return selmsg(doqscan);
X}
X
Xmkmsg(to, subj, conf, dpflag)
Xchar *to, *subj, *conf; {
X static char lockfile[] = "msgbase.lock";
X char *tempfile = mktemp("/tmp/UAmXXXXXX");
X FILE *mfp, *sfp;
X char line[1024], *p, ch, rconf[256];
X short mcnt;
X struct user ubuf;
X
X for (;;) {
X writef("To which conference do you wish this message to go (%s)? ", conf);
X reads(rconf);
X if (rconf[0] == '\0')
X strcpy(rconf, conf);
X if (!isconf(rconf)) {
X writes("That conference doesn't exist.");
X continue;
X }
X if (!isrcmem(user.u_name, rconf)) {
X writes("You aren't a member of that conference.");
X continue;
X }
X if (user.u_access != A_WITNESS && parms.ua_roc && conf[0] == 'r' && conf[1] == '-') {
X writes("That conference is read-only. Try dropping the R- prefix.");
X continue;
X }
X break;
X }
X if (parms.ua_pm) {
X writef("Is this message to be private? %c\b", (dpflag? 'Y': 'N'));
X line[0] = readc();
X log("Private? %c", line[0]);
X if (line[0] == 'Y')
X dpflag = 1;
X else if (line[0] == 'N')
X dpflag = 0;
X }
X if (dpflag && !getuser(to, &ubuf)) {
X writef("You can't send a private message to %s; he's unregistered.\n", upstr(to));
X log("Attempted private message to unregistered user.");
X return 0;
X }
X if ((mfp = fopen(tempfile, "w")) == NULL) {
X log("Error %d opening %s", errno, tempfile);
X panic("tmp");
X }
X for (p = to; *p != '\0'; p++)
X *p = ToUpper(*p);
X fprintf(mfp, "To: %s\nSubject%s: %s\n\n", to, (dpflag? " (Private)": ""), subj);
X fclose(mfp);
X input(tempfile);
X for (;;) {
X writef("\nList, Continue entry, Edit, Save, or Abort? ");
X ch = readc();
X log("Edit command: %c", ch);
X switch (ch) {
X case 'L':
X writes("\n--------------------");
X cat(tempfile);
X writes("--------------------");
X break;
X case 'C':
X input(tempfile);
X break;
X case 'E':
X edit(tempfile);
X break;
X case 'A':
X writef("Do you really want to abort this edit? N\b");
X line[0] = readc();
X log("Abort? %c", line[0]);
X if (line[0] == 'Y') {
X unlink(tempfile);
X return 0;
X }
X break;
X case '?':
X writes("Message entry commands:\n\nL - List message\nC - Continue message entry\nE - Edit message\nS - Save message\nA - Abort message\n");
X break;
X case 'S':
X writes("Saving message...");
X mklock(lockfile);
X sprintf(line, "%s/%s/himsg", MSGBASE, rconf);
X if ((sfp = fopen(line, "r")) == NULL) {
X log("Error %d opening %s", errno, line);
X rmlock(lockfile);
X unlink(tempfile);
X panic("himsg");
X }
X fgets(line, 32, sfp);
X fclose(sfp);
X mcnt = atoi(line) + 1;
X sprintf(line, "%s/%s/%d", MSGBASE, rconf, mcnt);
X if ((sfp = fopen(line, "w")) == NULL) {
X log("Error %d opening %s", errno, line);
X unlink(tempfile);
X rmlock(lockfile);
X panic("msg");
X }
X fprintf(sfp, "Date: %s\nFrom: %s\n", longdate(), upstr(user.u_name));
X if ((mfp = fopen(tempfile, "r")) == NULL) {
X fclose(sfp);
X log("Error %d opening %s", errno, tempfile);
X unlink(tempfile);
X unlink(line);
X rmlock(lockfile);
X panic("tmp");
X }
X while (fgets(line, 1024, mfp) != NULL)
X fputs(line, sfp);
X fclose(sfp);
X fclose(mfp);
X unlink(tempfile);
X sprintf(line, "%s/%s/himsg", MSGBASE, rconf);
X if ((sfp = fopen(line, "w")) == NULL) {
X log("Error %d opening %s", errno, line);
X panic("himsg_w");
X }
X fprintf(sfp, "%d\n", mcnt);
X fclose(sfp);
X rmlock(lockfile);
X return 1;
X default:
X writes("Please enter L, C, E, S, or A; or ? for help.");
X }
X }
X}
X
Xedit(file)
Xchar *file; {
X char find[256], replace[256], buf[1024], tempfile[80];
X char *bufp, *strp;
X long offset;
X FILE *src, *tmp;
X short ch, fch;
X
X sprintf(tempfile, "/tmp/UaEd%05d", getpid());
X writef("At the \"Find:\" prompt, enter the string to locate; pressing ENTER / RETURN alone exits the editor. At each occurrence of the string you will be ");
X writef("shown that part of the message and prompted to Replace, Skip to the next occurence, or Quit the search. If you Replace, you will be asked ");
X writef("for the replacement string; pressing ENTER or RETURN alone indicates that you wish to ");
X writef("to delete the string.\n\n");
X for (;;) {
X writef("Find: ");
X reads(find);
X if (find[0] == '\0')
X return;
X if ((tmp = fopen(tempfile, "w")) == (FILE *) 0) {
X log("Error %d opening %s", tempfile);
X panic("msged_tmpf");
X }
X if ((src = fopen(file, "r")) == (FILE *) 0) {
X log("Error %d opening %s", file);
X panic("msged_srcf");
X }
X offset = 0L;
X strp = find;
X writes("---------------");
X for (;;) {
X while ((ch = getc(src)) != EOF) {
X offset++;
X writec(ch);
X fch = ch;
X if (ToUpper(ch) == ToUpper(*strp))
X break;
X putc(ch, tmp);
X }
X if (ch == EOF)
X break;
X strp++;
X while (*strp != '\0' && (ch = getc(src)) != EOF) {
X if (ToUpper(ch) != ToUpper(*strp))
X break;
X strp++;
X }
X if (ch == EOF && *strp != '\0') {
X for (bufp = find; bufp != strp; bufp++) {
X putc(*bufp, tmp);
X writec(*bufp);
X }
X break;
X }
X if (*strp != '\0') {
X fseek(src, offset, 0L);
X strp = find;
X putc(fch, tmp);
X continue;
X }
X writef("\b \b[%s]\n---------------\n", find);
X
Xaskrepl:
X writef("Replace, Skip this one, Quit? S\b");
X ch = readc();
X switch (ch) {
X case ' ':
X case 'S':
X fseek(src, offset, 0L);
X strp = find;
X writes("---------------");
X continue;
X case 'R':
X writef("Replacement: ");
X reads(replace);
X fputs(replace, tmp);
X offset += strlen(find);
X writes("---------------");
X continue;
X case 'Q':
X while ((ch = getc(src)) != EOF)
X putc(ch, tmp);
X break;
X default:
X putchar('\7');
X goto askrepl;
X }
X break;
X }
X writes("---------------");
X fclose(src);
X fclose(tmp);
X if (unlink(file) < 0) {
X log("Error %d unlinking %s", errno, file);
X panic("msged_unlk");
X }
X if (copylink(tempfile, file) < 0) {
X log("Error %d copylinking %s to %s", errno, tempfile, file);
X panic("msged_cplk");
X }
X }
X}
X
Xinput(file)
Xchar *file; {
X FILE *fp;
X char line[256];
X char *cp;
X char ch;
X int lastwasnl;
X
X if ((fp = fopen(file, "a")) == NULL) {
X log("Error %d opening %s", errno, file);
X unlink(file);
X panic("tmp");
X }
X writes("\nEnter your text now. End it by typing any of ESCAPE, CONTROL-Z or CONTROL-D on a line by itself. Your text will be word-wrapped automatically.\n");
X log("Entering text...");
X cp = line;
X interact();
X while (((ch = getchar() & 0x7f) != '\033' && ch != '\032' && ch != '\004') || !lastwasnl) {
X if (ch == '\b' || ch == '\177')
X if (cp == line) {
X putchar('\7');
X fflush(stdout);
X }
X else {
X writec('\b');
X writec(' ');
X writec('\b');
X cp--;
X }
X else if (ch == '\n' || ch == '\r') {
X *cp++ = '\n';
X *cp++ = '\0';
X fputs(line, fp);
X cp = line;
X writec('\n');
X lastwasnl = 1;
X }
X else if (ch < ' ') {
X putchar('\7');
X fflush(stdout);
X }
X else {
X lastwasnl = 0;
X *cp++ = ch;
X writec(ch == '\t'? ' ': ch);
X if (wrapped() != 0) {
X cp -= wrapped() + 1;
X ch = *cp;
X *cp = '\0';
X fputs(line, fp);
X cp = line + strlen(line);
X *cp = ch;
X strcpy(line, cp);
X cp = line + wrapped() + 1;
X }
X }
X }
X buffer();
X fclose(fp);
X}
________This_Is_The_END________
echo 'x - mkconf.c'
sed 's/^X//' << '________This_Is_The_END________' > mkconf.c
X/*
X * @(#)mkconf.c 1.1 (TDI) 2/3/87
X *
X * Permission is hereby granted to copy and distribute this program
X * freely. Permission is NOT given to modify this program or distribute
X * it at cost, except for charging a reasonable media/copying fee.
X */
X
X#ifndef lint
Xstatic char _FileID_[] = "@(#)mkconf.c 1.1 (TDI) 2/3/87";
Xstatic char _UAID_[] = "@(#)UNaXcess version 1.0.2";
X#endif lint
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/dir.h>
X
Xchar line[256];
X
X#ifdef SYS5
X# define SYS3
X#endif SYS5
X
X#ifdef SYS3
X# define RIndex strrchr
X#else
X# ifdef XENIX3
X# define RIndex strrchr
X# else
X# ifdef XENIX5
X# define RIndex strrchr
X# else
X# define RIndex rindex
X# endif XENIX5
X# endif XENIX3
X#endif SYS3
X
Xchar *RIndex();
X
Xmain(argc, argv)
X char **argv;
X {
X if (argc != 3)
X exit(1);
X mknod(argv[1], S_IFDIR|0755, 0);
X chown(argv[1], atoi(argv[2]), 50);
X sprintf(line, "%s/.", argv[1]);
X link(argv[1], line);
X *RIndex(argv[1], '/') = '\0';
X strcat(line, ".");
X link(argv[1], line);
X }
________This_Is_The_END________
echo 'x - mvmsg.c'
sed 's/^X//' << '________This_Is_The_END________' > mvmsg.c
X/*
X * @(#)mvmsg.c 1.1 (TDI) 2/3/87
X * @(#)Copyright (C) 1984, 85, 86, 87 by Brandon S. Allbery.
X *
X * @(#)This file is part of UNaXcess version 1.0.2.
X *
X * Permission is hereby granted to copy and distribute this program
X * freely. Permission is NOT given to modify this program or distribute
X * it at cost, except for charging a reasonable media/copying fee.
X */
X
X#ifndef lint
Xstatic char _FileID_[] = "@(#)mvmsg.c 1.1 (TDI) 2/3/87";
Xstatic char _UAID_[] = "@(#)UNaXcess version 1.0.2";
X#endif lint
X
X#include <stdio.h>
X#include <pwd.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#ifndef SYS3
X# ifdef XENIX3
X# define RIndex(s,c) strrchr(s, c)
X# define Index(s,c) strchr(s, c)
Xextern char *strrchr(), *strchr();
X# else XENIX3
X# ifdef XENIX5
X# define RIndex(s,c) strrchr(s, c)
X# define Index(s,c) strchr(s, c)
Xextern char *strrchr(), *strchr();
X# else XENIX5
X# define RIndex(s,c) rindex(s,c)
X# define Index(s,c) index(s,c)
Xextern char *rindex(), *index();
X# endif XENIX5
X# endif XENIX3
X#else
X# define RIndex(s,c) strrchr(s, c)
X# define Index(s,c) strchr(s, c)
Xextern char *strrchr(), *strchr();
X#endif
X
Xextern long atol();
Xextern struct passwd *getpwuid();
X
Xmain(argc, argv)
Xchar **argv; {
X char msgdir[256], conf[33];
X long msg;
X char *cp, *dp;
X int status;
X
X if (argc != 3) {
X fprintf(stderr, "Usage: mvmsg conf[/n] conf\n");
X exit(1);
X }
X strcpy(msgdir, getpwuid(geteuid())->pw_dir);
X strcat(msgdir, "/msgdir");
X for (cp = argv[1], dp = conf; *cp != '/' && *cp != '\0'; cp++, dp++)
X *dp = *cp;
X *dp = '\0';
X if (*cp == '\0') {
X FILE *fp;
X char tmp[512];
X long limit, cnt;
X
X sprintf(tmp, "%s/%s/himsg", msgdir, conf);
X if ((fp = fopen(tmp, "r")) == (FILE *) 0) {
X fprintf(stderr, "Conference %s: missing himsg...\n", conf);
X exit(7);
X }
X fgets(tmp, sizeof tmp, fp);
X fclose(fp);
X if ((limit = atol(tmp)) <= 0) {
X fprintf(stderr, "Conference %s: invalid himsg...\n", conf);
X exit(8);
X }
X for (cnt = 0, msg = 1; msg <= limit; msg++)
X if ((status = mvmsg(msgdir, conf, msg, argv[2])) > 0)
X exit(status);
X else if (status == 0)
X cnt++;
X printf("%ld messages moved from %s to %s.\n", cnt, conf, argv[2]);
X sprintf(tmp, "%s/%s/himsg", msgdir, conf);
X if (unlink(tmp) != 0)
X exit(12);
X sprintf(tmp, "%s/%s", msgdir, conf);
X if (rmdir(tmp) != 0)
X exit(13);
X exit(cnt == 0? 9: 0);
X }
X msg = atol(++cp);
X if (Index(argv[2], '/') != (char *) 0) {
X fprintf(stderr, "Usage: mvmsg conf[/n] conf\n");
X exit(1);
X }
X if ((status = mvmsg(msgdir, conf, msg, argv[2])) == -1)
X fprintf(stderr, "Couldn't read %s/%ld\n", conf, msg);
X exit(status);
X}
X
Xmvmsg(base, conf, msg, dest)
Xchar *base, *conf, *dest;
Xlong msg; {
X char path[512], temp[512];
X long newmsg;
X FILE *ifp, *ofp;
X struct stat sbuf;
X
X sprintf(path, "%s/%s/%ld", base, conf, msg);
X if (stat(path, &sbuf) < 0)
X return -1; /* likely to be common... */
X sprintf(path, "%s/%s/himsg", base, dest);
X if ((ifp = fopen(path, "r")) == (FILE *) 0) {
X fprintf(stderr, "Conference %s: missing himsg...\n", dest);
X return 2;
X }
X fgets(temp, sizeof temp, ifp);
X fclose(ifp);
X if ((newmsg = atol(temp)) <= 0) {
X fprintf(stderr, "Conference %s: invalid himsg...\n", dest);
X return 2;
X }
X newmsg++;
X sprintf(path, "%s/%s/%ld", base, conf, msg);
X if ((ifp = fopen(path, "r")) == (FILE *) 0) {
X fprintf(stderr, "Conference %s: check permissions on message %ld\n", conf, msg);
X return 3;
X }
X sprintf(path, "%s/%s/%ld", base, dest, newmsg);
X if (stat(path, &sbuf) == 0) {
X fprintf(stderr, "Conference %s: corrupted (himsg incorrect)\n", dest);
X fclose(ifp);
X return 4;
X }
X if ((ofp = fopen(path, "w")) == (FILE *) 0) {
X fprintf(stderr, "Conference %s: check permissions (can't create message)\n", dest);
X fclose(ifp);
X return 5;
X }
X while (fgets(temp, sizeof temp, ifp) != (char *) 0) {
X fputs(temp, ofp);
X if (ferror(ofp)) {
X fprintf(stderr, "Write error on %s/%ld\n", dest, newmsg);
X exit(5); /* fatal! */
X }
X }
X if (ferror(ifp)) {
X fprintf(stderr, "Read error on %s/%ld\n", conf, msg);
X fclose(ifp);
X fclose(ofp);
X return 6;
X }
X fclose(ifp);
X fclose(ofp);
X sprintf(path, "%s/%s/himsg", base, dest);
X if ((ifp = fopen(path, "w")) == (FILE *) 0) {
X fprintf(stderr, "Conference %s: check permissions on himsg...\n", dest);
X return 2;
X }
X fprintf(ifp, "%ld\n", newmsg);
X fclose(ifp);
X sprintf(path, "%s/%s/%ld", base, conf, msg);
X if (unlink(path) < 0)
X return 10;
X return 0;
X}
X
X#ifndef BSD
X
X/* Berkeley has a rmdir() system call! Heaven! But I'm on sys3 (boo hiss) */
X
Xrmdir(path)
Xchar *path; {
X int pid, status;
X
X switch (pid = fork()) {
X case -1:
X return -1;
X case 0:
X execl("/bin/rmdir", "rmdir", path, 0);
X exit(-100);
X default:
X while (wait(&status) != pid)
X ;
X return status;
X }
X}
X
X#endif BSD
________This_Is_The_END________
echo 'x - system.c'
sed 's/^X//' << '________This_Is_The_END________' > system.c
X/*
X * @(#)system.c 1.2 (TDI) 2/3/87
X * @(#)Copyright (C) 1984, 85, 86, 87 by Brandon S. Allbery.
X * @(#)This file is part of UNaXcess version 1.0.2.
X *
X * Permission is hereby granted to copy and distribute this program
X * freely. Permission is NOT given to modify this program or distribute
X * it at cost, except for charging a reasonable media/copying fee.
X */
X
X#ifndef lint
Xstatic char _FileID_[] = "@(#)system.c 1.2 (TDI) 2/3/87";
Xstatic char _UAID_[] = "@(#)UNaXcess version 1.0.2";
X#endif lint
X
X#include "ua.h"
X
Xstruct sys parms = {
X#ifdef NOAUTOPATH
X NOAUTOPATH,
X#else
X "/usr/unaxcess",
X#endif NOAUTOPATH
X 1,
X 0,
X "/bin/sh",
X 1,
X "unaxcess",
X 30,
X "sysop",
X 1,
X 0,
X "",
X "",
X 3,
X "trap '' 2; stty -echo; echo 'Begin sending your file. End with a CONTROL-D.'; cat - > %s; stty echo",
X "trap '' 2; cat %s",
X "umodem -rbld",
X "umodem -sbld",
X "kermit -iwr ;:",
X "kermit -iws",
X A_GUEST,
X};
X
X#define NUM 0
X#define STR 1
X#define BOOL 2
X
Xstruct rparm {
X char *parmname;
X char parmtype;
X char *parmval;
X} sysparms[] = {
X "bbs-directory",STR, parms.ua_home,
X "readonly", BOOL, &parms.ua_roc,
X "restricted", BOOL, &parms.ua_xrc,
X "shell", STR, parms.ua_shell,
X "read-env", BOOL, &parms.ua_env,
X "bbs-user", STR, parms.ua_bbs,
X "time-limit", NUM, &parms.ua_tlimit,
X "sysop", STR, parms.ua_sysop,
X "private-msgs", BOOL, &parms.ua_pm,
X "logging", BOOL, &parms.ua_log,
X "banner", STR, parms.ua_bnr,
X "login-msg", STR, parms.ua_login,
X "login-tries", NUM, &parms.ua_nla,
X "ascii-upload", STR, parms.ua_auc,
X "ascii-download",STR, parms.ua_adc,
X "xmodem-upload",STR, parms.ua_xuc,
X "xmodem-download",STR, parms.ua_xdc,
X "kermit-upload",STR, parms.ua_kuc,
X "kermit-download",STR, parms.ua_kdc,
X "validation-level",NUM, &parms.ua_vaxs,
X 0, 0, 0,
X};
X
Xstatic FILE *lfp;
Xstatic int __tlog = 0;
Xshort critical = 0;
Xshort quitc = 0;
Xshort intr = 0;
Xshort alrm = 0;
Xshort warned = 0;
X
Xlogon() {
X struct stat sb;
X char *cp;
X
X if (!parms.ua_log || stat(LOG, &sb) < 0) { /* no logfile => no logging */
X lfp = NULL;
X return;
X }
X if ((lfp = fopen(LOG, "a")) == NULL) {
X io_off();
X perror(LOG);
X fprintf(stderr, "panic: log\n");
X exit(2);
X }
X}
X
Xlog(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
Xchar *fmt, *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9; {
X char buf[1024];
X static char lockfile[] = "logfile.lock";
X
X if (lfp == NULL) /* logging not enabled */
X return;
X CRIT();
X sprintf(buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
X mklock(lockfile);
X fprintf(lfp, "%s (%05d) %s\n", date(), getpid(), visible(buf));
X fflush(lfp);
X rmlock(lockfile);
X NOCRIT();
X}
X
Xlogsig(sig)
Xint sig; {
X static int dbl = 0; /* OOPS! 9 lines added 2/3/87 ++bsa */
X
X if (dbl++) {
X fprintf(stderr, "\r\n\r\nDOUBLE PANIC: SIG %d\r\n\r\n", sig);
X setuid(getuid());
X chdir("/tmp");
X signal(SIGIOT, SIG_DFL);
X kill(getpid(), SIGIOT);
X }
X dolog();
X log("Received signal %d.", sig);
X fprintf(stderr, "\r\n\r\nUNaXcess internal error: %d.\r\n\r\n", sig);
X unlink(RIndex(ttyname(fileno(stdin)), '/') + 1);
X io_off();
X signal(SIGIOT, SIG_DFL);
X setuid(getuid()); /* OOPS! 2 lines added */
X chdir(getpwuid(getuid())->pw_dir); /* 2/3/87 ++bsa */
X kill(getpid(), SIGIOT);
X}
X
Xpanic(s)
Xchar *s; {
X static int dbl = 0; /* OOPS! 9 lines added 2/3/87 ++bsa */
X
X if (dbl++) {
X fprintf(stderr, "\r\n\r\nDOUBLE PANIC: %s\r\n\r\n", s);
X setuid(getuid());
X chdir("/tmp");
X signal(SIGIOT, SIG_DFL);
X kill(getpid(), SIGIOT);
X }
X dolog();
X log("panic: %s", s);
X fprintf(stderr, "\r\n\r\nUNaXcess internal error: %s\r\n\r\n", s);
X io_off();
X unlink(RIndex(ttyname(2), '/') + 1);
X setuid(getuid());
X chdir(getpwuid(getuid())->pw_dir);
X signal(SIGIOT, SIG_DFL);
X kill(getpid(), SIGIOT);
X}
X
Xquit() {
X char line[256];
X
X if (critical) {
X quitc++;
X return;
X }
X writes("\n\nFast logout\n");
X signal(SIGQUIT, quit);
X log("Signalled QUIT.");
X writef("\nDo you really want to leave UNaXcess? N\b");
X line[0] = readc();
X if (line[0] == 'Y') {
X writef("OK");
X if (user.u_name[0] != '\0')
X writef(", %s", upstr(user.u_name));
X writef(". See you later!\n\n\n");
X cleanup();
X }
X}
X
Xintrp() {
X if (critical) {
X intr++;
X return;
X }
X writes("\n\nAborted.");
X log("Command aborted.");
X signal(SIGINT, intrp);
X longjmp(cmdloop, 1);
X}
X
Xchar *visible(s)
Xchar *s; {
X static char vs[256];
X char *sp, *vp;
X
X vp = vs;
X for (sp = s; *sp != '\0'; sp++)
X if (!iscntrl(*sp))
X *vp++ = *sp;
X else {
X *vp++ = '^';
X *vp++ = uncntrl(*sp);
X }
X *vp = '\0';
X return vs;
X}
X
Xshell() {
X short sig;
X
X if (user.u_access == A_GUEST || user.u_access == A_USER || parms.ua_shell[0] == '\0') {
X writes("You don't have shell access privileges.");
X log("Security violation: Unauthorized SHELL");
X return 1;
X }
X switch (fork()) {
X case -1:
X log("Error %d forking shell", errno);
X writes("Sorry, the system's full. Try again later.");
X return 1;
X case 0:
X for (sig = SIGINT; sig <= SIGTERM; sig++)
X signal(sig, SIG_DFL);
X setuid(getuid());
X chdir(getpwuid(getuid())->pw_dir);
X run(parms.ua_shell, 0);
X log("Error %d exec'ing %s", errno, parms.ua_shell);
X writes("Couldn't run the shell.");
X exit(1);
X default:
X CRIT();
X io_off();
X for (sig = SIGINT; sig <= SIGTERM; sig++)
X signal(sig, SIG_IGN);
X signal(SIGALRM, thatsall); /* trapped by the CRIT() */
X wait(NULL);
X signal(SIGINT, intrp);
X signal(SIGQUIT, quit);
X for (sig = SIGIOT; sig < SIGTERM; sig++)
X signal(sig, logsig);
X signal(SIGALRM, thatsall);
X io_on(0);
X NOCRIT();
X }
X return 1;
X}
X
Xthatsall() {
X if (critical) {
X alrm++;
X return;
X }
X if (warned) {
X log("Timeout.");
X writes("\nI'm sorry, but you're out of time.\n\n");
X cleanup();
X }
X else {
X log("5-minute warning.");
X writes("\nYou have only five minutes left in this session.\n\n");
X warned = 1;
X alarm(5 * 60);
X }
X}
X
Xmklock(lockfile)
Xchar *lockfile; {
X char lockpath[50];
X int lock_fd;
X struct stat statbuf;
X long now;
X
X strcpy(lockpath, "lock/");
X strcat(lockpath, lockfile);
X while (stat(lockpath, &statbuf) == 0) {
X time(&now);
X if (now - statbuf.st_mtime > 90) { /* OOPS! 2/3/87 ++bsa */
X unlink(lockpath);
X break;
X }
X sleep(5); /* OOPS! 1 line added 2/3/87 ++bsa */
X }
X if ((lock_fd = creat(lockpath, 0600)) < 0) {
X fprintf(stderr, "Errno = %d creating lockfile %s\n", errno, lockpath);
X /* OOPS! 1 line deleted 2/3/87 ++bsa */
X panic(lockpath);
X }
X close(lock_fd);
X sync(); /* insure disk files are updated! */
X}
X
Xrmlock(lockfile)
Xchar *lockfile; {
X char lockpath[50];
X struct stat statbuf;
X
X sync();
X strcpy(lockpath, "lock/");
X strcat(lockpath, lockfile);
X if (stat(lockpath, &statbuf) < 0) {
X log("Lockfile %s deleted???", lockpath);
X writef("\n\nSomeone futzed with the lockfile. Please tell %s IMMEDIATELY!!!\nSorry, but this means I have to log you out now.\n\n", parms.ua_sysop);
X panic("LOCKFILE DELETED");
X }
X if (unlink(lockpath) < 0) {
X log("Errno = %d, can't unlink lockfile %s", errno, lockpath);
X writes("\nI've got a lockfile problem. You won't be able to do some\nthings until it's fixed. Sorry...\n");
X }
X}
X
XCRIT() {
X alrm = 0;
X quitc = 0;
X intr = 0;
X if (critical)
X return; /* clears pending signals */
X critical = 1;
X}
X
XNOCRIT() {
X if (!critical)
X return;
X critical = 0;
X if (alrm)
X thatsall(14);
X if (quitc)
X quit(3);
X if (intr)
X intrp(2);
X alrm = 0;
X quitc = 0;
X intr = 0;
X}
X
Xrun(cmd, arg)
Xchar *cmd, *arg; {
X char cmdbuf[5120];
X
X sprintf(cmdbuf, "%s %s", cmd, (arg? arg: ""));
X execl("/bin/sh", "sh", "-c", cmdbuf, 0);
X return -1;
X}
X
Xcopylink(src, dest)
Xchar *src, *dest; {
X int srcp, destp, cnt;
X char buf[1024];
X
X if (link(src, dest) == 0) {
X unlink(src);
X return 0;
X }
X if ((srcp = open(src, 0)) < 0) {
X perror(src);
X return -1;
X }
X unlink(dest);
X if ((destp = creat(dest, 0600)) < 0) {
X perror(dest);
X return -1;
X }
X while ((cnt = read(srcp, buf, sizeof buf)) > 0)
X write(destp, buf, cnt);
X close(destp);
X close(srcp);
X return 0;
X}
X
Xs_cmp(s1, s2)
Xchar *s1, *s2; {
X for (; *s1 != '\0' && ToLower(*s1) == ToLower(*s2); s1++, s2++)
X ;
X return (!(*s1 == '\0' && *s2 == '\0'));
X}
X
Xchar *upstr(s)
Xchar *s; {
X static char sbuf[512];
X register char *cp, *dp;
X
X for (cp = s, dp = sbuf; *cp != '\0'; cp++, dp++)
X *dp = ToUpper(*cp);
X *dp = '\0';
X return sbuf;
X}
X
Xismember(word, list)
Xchar *word, *list; {
X char *cp;
X char oldch;
X
X while (*list != '\0') {
X while (*list == ' ' || *list == '\t')
X list++;
X for (cp = list; *cp != '\0' && *cp != ',' && *cp != ' ' && *cp != '\t'; cp++)
X ;
X oldch = '\0';
X if (*cp != '\0') {
X oldch = *cp;
X *cp++ = '\0';
X }
X if (strcmp(word, list) == 0) {
X *(cp - 1) = oldch;
X return 1;
X }
X *(cp - 1) = oldch;
X list = cp;
X }
X return 0;
X}
X
Xdolog() {
X if (lfp != (FILE *) 0 || __tlog)
X return;
X logon();
X __tlog = 1;
X}
X
Xnolog() {
X if (!__tlog || lfp == (FILE *) 0)
X return;
X fclose(lfp);
X __tlog = 0;
X}
X
Xalter() {
X char line[256], uname[256];
X char *p, *q, *okcmds;
X struct user ubuf;
X short crypted, not_FW;
X char cmd;
X
X if (user.u_access == A_MKUSER) {
X log("An A_MKUSER got into alter()???");
X panic("newalter");
X }
X if (user.u_access != A_WITNESS) {
X not_FW = 1;
X log("Alter by non-Witness; restricting control modes.");
X strcpy(line, user.u_name);
X }
X else {
X line[0] = '\0';
X not_FW = 0;
X writef("Examine which user: ");
X reads(line);
X log("User: %s", line);
X if (line[0] == '\0')
X return 1;
X for (p = line; *p != '\0'; p++)
X *p = ToLower(*p);
X line[32] = '\0';
X }
X if (!getuser(line, &ubuf))
X if (not_FW) {
X log("Can't locate current user in the userfile.");
X panic("user");
X }
X else {
X writef("No such user. Create him ? N\b");
X strcpy(ubuf.u_name, line);
X line[0] = readc();
X log("New user? %c", line[0]);
X if (line[0] != 'Y')
X return 1;
X ubuf.u_pass[0] = '\0';
X ubuf.u_access = A_USER;
X ubuf.u_llen = 80;
X ubuf.u_nbull = 0;
X strcpy(ubuf.u_lconf, "general");
X ubuf.u_lines = 24;
X crypted = 0;
X }
X else if (strlen(ubuf.u_pass) == 0)
X crypted = 0;
X else
X crypted = 1;
X strcpy(uname, ubuf.u_name);
X for (;;) {
X writec('\n');
X writef("Name: %s\n", ubuf.u_name);
X writef("Password: %s%s\n", ubuf.u_pass, (crypted? " (encrypted)": ""));
X writef("Access level: %s\n", ua_acl(ubuf.u_access));
X if (ubuf.u_access == A_MKUSER) {
X writef("Default access level: %s\n", ua_acl(ubuf.u_llen));
X okcmds = "NPADKQF";
X }
X else {
X writef("UNIX(R) login name: %s\n", ubuf.u_login);
X writef("Login conference: %s\n", ubuf.u_lconf);
X writef("Line size: %d\n", ubuf.u_llen);
X writef("Screen lines: %d\n", ubuf.u_lines);
X if (ubuf.u_access == A_WITNESS && s_cmp(user.u_name, parms.ua_sysop) != 0 && s_cmp(user.u_name, uname) != 0)
X okcmds = "Q";
X else if (user.u_access < A_WITNESS)
X okcmds = "PUCSLQF";
X else if (s_cmp(user.u_name, uname) == 0)
X okcmds = "NPUCSLQF";
X else
X okcmds = "NPAUCLSKQF";
X }
X writef("\nAlter command (");
X for (p = okcmds; *p != '\0'; p++)
X switch (*p) {
X case 'N':
X writef("Name, ");
X break;
X case 'P':
X writef("Password, ");
X break;
X case 'A':
X writef("Access, ");
X break;
X case 'U':
X writef("UNIX(R) login, ");
X break;
X case 'C':
X writef("Conference, ");
X break;
X case 'L':
X writef("Lines, ");
X break;
X case 'S':
X writef("Size, ");
X break;
X case 'D':
X writef("Default access, ");
X break;
X case 'K':
X writef("Kill, ");
X break;
X case 'Q':
X writef("Quit, ");
X break;
X case 'F':
X writef("Finished, ");
X break;
X default:
X log("Invalid internal alter() command: '%c'", *p);
X panic("altercmd");
X }
X writef("or ? for help): ");
X cmd = readc();
X log("Change: %c", cmd);
X if (cmd != '?' && Index(okcmds, cmd) == (char *) 0)
X cmd = ' ';
X switch (cmd) {
X case 'K':
X writef("Kill user -- are you sure? N\b");
X cmd = readc();
X log("Kill user? %c", cmd);
X if (cmd != 'Y')
X break;
X putuser(uname, (struct user *) 0);
X writef("User %s killed.\n", upstr(uname));
X return 1;
X case 'N':
X writef("Enter new name: ");
X reads(line);
X log("Name: %s", line);
X if (line[0] == '\0')
X break;
X for (p = line; *p != '\0'; p++)
X if (*p == ':') {
X log("Illegal colon in name.");
X writes("Can't put a colon in a user name.");
X break;
X }
X for (p = line, q = ubuf.u_name; *p != '\0'; p++, q++)
X *q = ToLower(*p);
X *q = '\0';
X break;
X case 'P':
X strcpy(line, getpass("Enter new password: "));
X if (line[0] == '\0')
X break;
X strcpy(ubuf.u_pass, line);
X crypted = 0; /* it's not encrypted now */
X break;
X case 'A':
X writef("Access level: Deny access, Guest, Messages, Files, System, Witness, Newuser? ");
X cmd = readc();
X log("Access: %c", cmd);
X if (cmd == 'A' && s_cmp(user.u_name, parms.ua_sysop) != 0) {
X writes("Sorry, only the sysop can administer Witness privileges.");
X log("Security violation: WITNESS administering WITNESS");
X break;
X }
X switch (cmd) {
X case 'G':
X ubuf.u_access = A_GUEST;
X break;
X case 'D':
X ubuf.u_access = A_NONE;
X break;
X case ' ':
X break;
X case 'M':
X ubuf.u_access = A_USER;
X break;
X case 'S':
X ubuf.u_access = A_SYSTEM;
X break;
X case 'W':
X ubuf.u_access = A_WITNESS;
X break;
X case 'N':
X ubuf.u_access = A_MKUSER;
X break;
X case 'F':
X ubuf.u_access = A_FILES;
X break;
X default:
X writes("What? Valid commands are D, G, M, F, S, W, and N. Access unchanged.");
X }
X break;
X case 'C':
X writef("Enter the default login conference: ");
X reads(line);
X log("Login conference: %s", line);
X if (line[0] =='\0')
X break;
X if (!isconf(line))
X writes("That conference doesn't exist.");
X else if (uisunsub(ubuf.u_name, line))
X writef("%s isn't subscribed to %s.\n", upstr(ubuf.u_name), line);
X else if (!isrcmem(ubuf.u_name, line))
X writef("%s isn't a member of that conference.\n", upstr(ubuf.u_name));
X else
X strcpy(ubuf.u_lconf, line);
X break;
X case 'S':
X writef("Enter new line size, 32-132: ");
X reads(line);
X log("Line length: %s", line);
X if (line[0] == '\0')
X break;
X ubuf.u_llen = atoi(line);
X if (ubuf.u_llen < 32 || ubuf.u_llen > 132) {
X ubuf.u_llen = 80;
X writes("Garbage line size; using 80.");
X }
X break;
X case 'U':
X writef("UNIX(R) login name? ");
X reads(line);
X log("Login name: %s", line);
X if (strlen(line) > 8) {
X writes("That name is too long.");
X break;
X }
X strcpy(ubuf.u_login, line);
X break;
X case 'D':
X writef("Default Access: Deny access, Guest, Messages, Files, System? ");
X cmd = readc();
X log("Dft Access: %c", cmd);
X switch (cmd) {
X case 'G':
X ubuf.u_llen = A_GUEST;
X break;
X case 'D':
X ubuf.u_llen = A_NONE;
X break;
X case ' ':
X break;
X case 'M':
X ubuf.u_llen = A_USER;
X break;
X case 'S':
X ubuf.u_access = A_SYSTEM;
X break;
X case 'F':
X ubuf.u_access = A_FILES;
X break;
X default:
X writes("What? Valid commands are D, G, M, F, or S. Default access unchanged.");
X }
X break;
X case 'Q':
X if (okcmds[1] != '\0') {
X writef("Abort user examine, are you sure? N\b");
X cmd = readc();
X log("Abort? %c", cmd);
X if (cmd != 'Y')
X break;
X }
X return 1;
X case 'F':
X if (!crypted) {
X writes("Encrypting password, please wait...");
X strcpy(ubuf.u_pass, crypt(ubuf.u_pass, ubuf.u_pass) + 2);
X }
X putuser(uname, &ubuf);
X if (s_cmp(uname, user.u_name) == 0)
X user = ubuf;
X return 1;
X case 'L':
X writef("Enter new lines/screen, 0-66: ");
X reads(line);
X log("Lines/screen: %s", line);
X if (line[0] == '\0')
X break;
X ubuf.u_lines = atoi(line);
X if (ubuf.u_lines < 0 || ubuf.u_lines > 66) {
X ubuf.u_lines = 24;
X writes("Garbage lines/screen; using 24.");
X }
X break;
X case '?':
X writef("\nThe commands are self-documenting. If you don't see a command, it's because you can't perform that command on the current user.\n");
X break;
X default:
X writef("What? Please enter one of ");
X for (p = okcmds; *p != '\0'; p++) {
X writec(*p);
X writec(',');
X writec(' ');
X }
X writes("or ? for help.");
X }
X }
X}
X
Xgetparms() {
X char home[512], line[512], var[20], sval[50];
X FILE *cfp;
X short cnt, pos, scnt, canon;
X
X#ifdef NOAUTOPATH
X strcpy(home, NOAUTOPATH);
X#else
X strcpy(home, getpwuid(geteuid())->pw_dir);
X#endif NOAUTOPATH
X strcpy(parms.ua_home, home);
X strcpy(line, home);
X strcat(line, "/");
X strcat(line, CONFIG);
X if ((cfp = fopen(line, "r")) == NULL) {
X fprintf(stderr, "panic: param get, %s\n", line);
X exit(1);
X }
X while (fgets(line, 512, cfp) != NULL) {
X line[strlen(line) - 1] = '\0';
X if (Index(line, '#') != NULL)
X *(Index(line, '#')) = '\0';
X scnt = 0;
X pos = 0;
X while (line[pos] != '\0' && line[pos] != ' ' && line[pos] != '\t')
X var[scnt++] = line[pos++];
X var[scnt] = '\0';
X if (var[0] == '\0')
X continue;
X for (cnt = 0; sysparms[cnt].parmname != NULL; cnt++)
X if (strcmp(sysparms[cnt].parmname, var) == 0)
X break;
X if (sysparms[cnt].parmname == NULL) {
X fprintf(stderr, "Please inform the sysop that there is an invalid parameter\n%s in the setup file.\n", var);
X continue;
X }
X while (line[pos] == ' ' || line[pos] == '\t')
X pos++;
X switch (sysparms[cnt].parmtype) {
X case NUM:
X *((char *) sysparms[cnt].parmval) = atoi(&line[pos]) & 0xff;
X break;
X case BOOL:
X if (line[pos] == '\0' || ToLower(line[pos]) == 'y')
X *((char *) sysparms[cnt].parmval) = 1;
X else
X *((char *) sysparms[cnt].parmval) = 0;
X break;
X case STR:
X canon = 0;
X if (line[pos] == '"') {
X canon = 1;
X pos++;
X }
X for (scnt = 0; (canon? line[pos] != '"': line[pos] != '\0' && line[pos] != ' ' && line[pos] != '\t'); pos++, scnt++) {
X if (canon && line[pos] == '\\') {
X switch (line[++pos]) {
X case 'n':
X sval[scnt] = '\n';
X break;
X case 't':
X sval[scnt] = '\t';
X break;
X case 'r':
X sval[scnt] = '\r';
X break;
X case 'b':
X sval[scnt] = '\b';
X break;
X case 'f':
X sval[scnt] = '\f';
X break;
X case 'e':
X case 'E':
X sval[scnt] = '\033';
X break;
X case 'a':
X sval[scnt] = '\7'; /* proposed extension of C string metasyntax */
X break;
X case '0':
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X sval[scnt] = 0;
X while (Index("01234567", line[pos]) != NULL)
X sval[scnt] = sval[scnt] * 8 + (line[pos++] - '0');
X pos--;
X break;
X default:
X sval[scnt] = line[pos];
X }
X }
X else
X sval[scnt] = line[pos];
X }
X sval[scnt] = '\0';
X strcpy(sysparms[cnt].parmval, sval);
X }
X }
X}
________This_Is_The_END________
echo 'x - system.h'
sed 's/^X//' << '________This_Is_The_END________' > system.h
X/*
X * @(#)system.h 1.1 (TDI) 2/3/87
X * @(#)Copyright (C) 1984, 85, 86, 87 by Brandon S. Allbery.
X * @(#)This file is part of UNaXcess version 1.0.2.
X *
X * Permission is hereby granted to copy and distribute this program
X * freely. Permission is NOT given to modify this program or distribute
X * it at cost, except for charging a reasonable media/copying fee.
X */
X
Xstruct sys {
X char ua_home[50]; /* UNaXcess lives here */
X char ua_roc; /* read-only conference flag */
X char ua_xrc; /* x-rated conference flag */
X char ua_shell[50]; /* the default shell */
X char ua_env; /* read environment for SHELL, EDITOR */
X char ua_bbs[32]; /* name of BBS login */
X char ua_tlimit; /* minutes until logout */
X char ua_sysop[32]; /* name of the sysop login */
X char ua_pm; /* allow private messages? */
X char ua_log; /* keep a log? */
X char ua_bnr[50]; /* path of banner file, EOS = internal */
X char ua_login[256]; /* login message, EOS = internal */
X char ua_nla; /* number of attempts to login allowed */
X char ua_auc[256]; /* ascii upload command */
X char ua_adc[256]; /* ascii download command */
X char ua_xuc[256]; /* Xmodem upload command */
X char ua_xdc[256]; /* Xmodem download command */
X char ua_kuc[256]; /* Kermit upload command */
X char ua_kdc[256]; /* Kermit download command */
X char ua_vaxs; /* validation access level */
X};
X
Xextern struct sys parms;
________This_Is_The_END________
echo 'x - ua.c'
sed 's/^X//' << '________This_Is_The_END________' > ua.c
X/*
X * @(#)ua.c 1.2 (TDI) 2/3/87
X * @(#)Copyright (C) 1984, 85, 86, 87 by Brandon S. Allbery.
X * @(#)This file is part of UNaXcess version 1.0.2.
X *
X * Permission is hereby granted to copy and distribute this program
X * freely. Permission is NOT given to modify this program or distribute
X * it at cost, except for charging a reasonable media/copying fee.
X */
X
X#ifndef lint
Xstatic char _FileID_[] = "@(#)ua.c 1.2 (TDI) 2/3/87";
Xstatic char _UAID_[] = "@(#)UNaXcess version 1.0.2";
X#endif lint
X
X#include "ua.h"
X
X/* forward references for command executives */
X
Xextern int
X readmsg(), readnew(), confidx(), enter(),
X join(), killmsg(), scanmsg(), msgmenu(),
X logout(), bulletin(), shell(), edrest(),
X alter(), userlist(), qscan(), udl(),
X unsub(), setlconf(), readmenu(), mkbull(),
X adminmenu(), validate();
X
Xstruct cmd maincmd[] = {
X 'a', "Administration menu", adminmenu,
X 'b', "Reprint login bulletins", bulletin,
X 'c', "Shell command access", shell,
X 'd', "Set default login conference", setlconf,
X 'f', "File area (Downloading)", udl,
X 'g', "Exit UNaXcess", logout,
X 'm', "UNaXcess Message Base", msgmenu,
X 'w', "List of UNaXcess users", userlist,
X '\0',"help/mainmenu", NULL
X};
X
Xstruct cmd admincmd[] = {
X 'a', "Alter or examine a user", alter,
X 'b', "Enter a bulletin", mkbull,
X 'c', "Shell command access", shell,
X 'e', "Edit conference membership", edrest,
X 'g', "Exit UNaXcess", logout,
X 'v', "Validate new users", validate,
X 'w', "List of UNaXcess users", userlist,
X 'x', "Return to the Main Menu", (int (*)()) 0,
X '\0',"help/adminmenu", NULL
X};
X
Xstruct cmd msgcmd[] = {
X 'd', "Set default login conference", setlconf,
X 'e', "Enter a message", enter,
X 'g', "Exit UNaXcess", logout,
X 'i', "Index of conferences", confidx,
X 'j', "Join a new conference", join,
X 'k', "Kill a message", killmsg,
X 'n', "Read all new messages", readnew,
X 'r', "Read commands menu", readmenu,
X 'u', "Unsubscribe from a conference", unsub,
X 'x', "Return to the Main Menu", (int (*)()) 0,
X '\0',"help/msgbase", NULL
X};
X
Xstruct cmd readcmd[] = {
X 'g', "Exit UNaXcess", logout,
X 'n', "Read all new messages", readnew,
X 'q', "Quick scan of messages", qscan,
X 'r', "Read messages in a conference", readmsg,
X 's', "Scan messages", scanmsg,
X 'x', "Return to the Message Base Menu", (int (*)()) 0,
X '\0',"help/readcmds", NULL
X};
X
Xjmp_buf cmdloop;
Xint __recurse;
X
Xmain(argc, argv)
Xchar **argv; {
X char line[256], *lp;
X short lcnt;
X FILE *tp;
X
X getparms();
X chdir(parms.ua_home);
X if (parms.ua_env && (lp = getenv("SHELL")) != NULL)
X strcpy(parms.ua_shell, lp);
X __recurse = 0;
X logon();
X io_on(1);
X signal(SIGINT, SIG_IGN);
X signal(SIGQUIT, quit);
X for (lcnt = SIGILL; lcnt <= SIGTERM; lcnt++) /* we don't muck with others */
X signal(lcnt, logsig);
X signal(SIGALRM, thatsall);
X /* OOPS! 1 lines deleted, 2 lines changed 2/3/87 ++bsa */
X writes("\nWelcome to UNaXcess Conferencing, Version 1.00.02\nCopyright (C) 1984, 1985, 1986 by Brandon S. Allbery");
X if (parms.ua_bnr[0] != 0)
X cat(parms.ua_bnr);
X if (argc > 2) {
X writes("To run UNaXcess from the shell, type `ua' or `ua username'.\nIf username has spaces or shell metacharacters in it, quote it.\n");
X log("Invoked with %d arguments. Goodbye.", argc);
X exit(1);
X }
X else
X argc--;
X if (ismember(getlogin(), parms.ua_bbs)) {
X
Xnouser:
X for (lcnt = 0;; lcnt++) {
X if (argc) {
X strcpy(line, argv[1]);
X argc--;
X writec('\n');
X }
X else {
X if (parms.ua_login[0] == 0)
X writef("\nEnter your user name, GUEST, OFF, or NEW: ");
X else
X writef("%s", parms.ua_login);
X reads(line);
X }
X log("Login: %s", line);
X if (line[0] == '\0') {
X lcnt--;
X continue;
X }
X for (lp = line; *lp != '\0'; lp++)
X *lp = ToLower(*lp);
X if (strcmp(line, "off") == 0) {
X writes("Goodbye...\n\n");
X log("Logout.");
X exit(0);
X }
X if (!getuser(line, &user)) {
X writef("No such user.\n");
X log("No such user.");
X }
X else if (user.u_pass[0] != '\0') {
X xecho();
X writef("Enter your password: ");
X reads(line);
X doecho();
X log("Password: %s", line);
X writes("\nChecking password...");
X if (strcmp(crypt(line, line) + 2, user.u_pass) == 0)
X break;
X }
X else
X break;
X }
X if (parms.ua_nla > 0 && lcnt == parms.ua_nla) {
X writes("\nSorry, you blew it.");
X log("Program aborted.");
X exit(1);
X }
X }
X else if (!getuser(getlogin(), &user))
X goto nouser;
X if (s_cmp(user.u_name, parms.ua_sysop) != 0)
X alarm(parms.ua_tlimit * 60); /* time limit */
X log("%s, access = %d, sys = %s, line = %d", user.u_name, user.u_access, user.u_login, user.u_llen);
X if (user.u_access == A_NONE) {
X writes("Your access privileges have been revoked. Goodbye...\n\n");
X log("Security violation: access revoked.");
X exit(1);
X }
X if ((tp = fopen(RIndex(ttyname(fileno(stdin)), '/') + 1, "w")) == NULL) {
X log("Error %d opening %s", errno, RIndex(ttyname(fileno(stdin)), '/') + 1);
X log("Non-interactive session not logged to terminal.");
X }
X else {
X fprintf(tp, "%s on as \"%s\" on %s\n", getlogin(), user.u_name, longdate());
X fclose(tp);
X }
X writec('\n');
X if (user.u_access != A_MKUSER)
X bulletin();
X if (user.u_lconf[0] != '\0')
X if (isconf(user.u_lconf))
X if (isrcmem(user.u_name, user.u_lconf))
X strcpy(conference, user.u_lconf);
X else {
X writef("\nYour login conference, \"%s\", has been restricted and you are not a member. I'm moving you back to \"general\".\n", user.u_lconf);
X strcpy(user.u_lconf, "general");
X strcpy(conference, "general");
X }
X else {
X writef("\n%s deleted \"%s\", your login conference. I'm setting you back to the \"general\" conference.\n", upstr(parms.ua_sysop), user.u_lconf);
X strcpy(user.u_lconf, "general");
X strcpy(conference, "general");
X }
X else
X strcpy(conference, "general");
X if (user.u_access != A_GUEST && user.u_access != A_MKUSER) {
X hicnts = readhigh(&user);
X cleanhigh(); /* kill any lingering corpses */
X }
X if (!setjmp(cmdloop))
X signal(SIGINT, intrp);
X if (user.u_access == A_MKUSER) {
X newuser();
X if (user.u_access == A_NONE) {
X writes("\nYou'll have to be validated before you can use UNaXcess.");
X return 0;
X }
X }
X pcmd("Command (? for help): ", maincmd, (char *) 0);
X writef("Goodbye");
X if (user.u_name[0] != '\0')
X writef(", %s", upstr(user.u_name));
X writef(". Call again soon!\n\n\n");
X log("Logout.");
X cleanup();
X}
X
Xcleanup() {
X char tmps[256];
X FILE *fp;
X
X sprintf(tmps, "%s/himotd", MOTD);
X if ((fp = fopen(tmps, "r")) == NULL) {
X log("Error %d opening %s", errno, tmps);
X panic("himotd");
X }
X fgets(tmps, 32, fp);
X fclose(fp);
X user.u_nbull = atoi(tmps);
X putuser(user.u_name, &user);
X unlink(RIndex(ttyname(fileno(stdin)), '/') + 1);
X io_off();
X exit(0);
X}
X
Xlogout() {
X char line[256];
X
X if (__recurse > 0) {
X __recurse--;
X return 0;
X }
X writef("Are you sure you want to log out? N\b");
X line[0] = readc();
X log("Logout? %c", line[0]);
X if (line[0] != 'Y')
X return 1;
X writef("Goodbye");
X if (user.u_name[0] != '\0')
X writef(", %s", upstr(user.u_name));
X writef(". Call again soon!\n\n\n");
X log("Logout.");
X cleanup();
X}
X
Xmsgmenu() {
X pcmd("Message Base Command (? for help, X to exit): ", msgcmd, "Message Base");
X return 1;
X}
X
Xreadmenu() {
X pcmd("Read Command (? for help, X to exit): ", readcmd, "Read Commands");
X return 1;
X}
X
Xadminmenu() {
X pcmd("Admin Command (? for help, X to exit): ", admincmd, "Administration");
X return 1;
X}
X
Xpcmd(prompt, cmdtab, previous)
Xchar *prompt, *previous;
Xstruct cmd cmdtab[]; {
X char ch;
X struct cmd *cmd;
X short fullhelp;
X unsigned int tleft;
X
X fullhelp = 0;
X for (;;) {
X if ((tleft = alarm((unsigned int) 0)) != 0) {
X alarm(tleft);
X writef("%d:%02d ", tleft / 60, tleft % 60);
X }
X writef("[%s] %s", conference, prompt);
X ch = readc();
X if (ch == '?') {
X if (fullhelp) {
X for (cmd = cmdtab; cmd->c_cmd != '\0'; cmd++)
X ;
X writec('\n');
X cat(cmd->c_desc);
X writec('\n');
X continue;
X }
X writef("\n%s Commands\n\n", (previous == (char *) 0? "Main": previous));
X for (cmd = cmdtab; cmd->c_cmd != '\0'; cmd++)
X writef(" %c - %s\n", ToUpper(cmd->c_cmd), cmd->c_desc);
X fullhelp = 1;
X writes("\nType ? for the full help file.\n");
X continue;
X }
X for (cmd = cmdtab; cmd->c_cmd != '\0'; cmd++)
X if (ToUpper(cmd->c_cmd) == ch)
X break;
X if (cmd->c_cmd == '\0') {
X writes("Unrecognized command. Type ? for help.");
X continue;
X }
X if (cmd->c_func == (int (*)()) 0)
X break;
X if ((*cmd->c_func)() == 0)
X break;
X fullhelp = 0;
X }
X}
________This_Is_The_END________
echo 'x - ua.h'
sed 's/^X//' << '________This_Is_The_END________' > ua.h
X/*
X * @(#)ua.h 1.1 (TDI) 2/3/87
X * @(#)Copyright (C) 1984, 85, 86, 87 by Brandon S. Allbery.
X * @(#)This file is part of UNaXcess version 1.0.2.
X *
X * Permission is hereby granted to copy and distribute this program
X * freely. Permission is NOT given to modify this program or distribute
X * it at cost, except for charging a reasonable media/copying fee.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <setjmp.h>
X#include <pwd.h>
X#include <signal.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <errno.h>
X#include "user.h"
X#include "dir.h"
X#include "system.h"
X#ifdef BSD
X#include <sys/time.h>
X#else
X#include <time.h>
X#endif
X
X#define SYSOP parms.ua_sysop
X#define LOG "Logfile"
X#define MOTD "motd"
X#define PASSWD "userfile"
X#define MSGBASE "msgdir"
X#define NEWMSGS "userind"
X#define NEWUSER "NewMessage"
X#define CONFIG "ua-config"
X#define MEMLIST "members"
X
Xextern jmp_buf cmdloop; /* so intrp() works */
Xextern int logsig(), quit(), intrp(), thatsall();
Xextern int doread(), doscan();
Xextern struct _himsg *readhigh();
Xextern struct tm *localtime();
Xextern struct passwd *getpwuid();
Xextern char *getowner(), *visible(), *mktemp(), *crypt(), *date(), *longdate(), *getenv(), *reads(), *fgets(), *today(), *calloc(), *ua_acl(), *upstr();
Xextern int errno, __recurse;
Xextern char conference[];
X
X#define ToLower(x) (isupper(x)?tolower(x):x) /* not all tolower() work */
X#define ToUpper(x) (islower(x)?toupper(x):x) /* not all toupper() work */
X#define uncntrl(x) (x+'@') /* beware of non-ASCII character sets! */
X
X#ifdef SYS5
X# define SYS3
X#endif SYS5
X
X#ifndef SYS3
X# ifdef XENIX3
X# define RIndex(s,c) strrchr(s, c)
X# define Index(s,c) strchr(s, c)
Xextern char *strrchr(), *strchr();
X# else XENIX3
X# ifdef XENIX5
X# define RIndex(s,c) strrchr(s, c)
X# define Index(s,c) strchr(s, c)
Xextern char *strrchr(), *strchr();
X# else XENIX5
X# define RIndex(s,c) rindex(s,c)
X# define Index(s,c) index(s,c)
Xextern char *rindex(), *index();
X# endif XENIX5
X# endif XENIX3
X#else
X# define RIndex(s,c) strrchr(s, c)
X# define Index(s,c) strchr(s, c)
Xextern char *strrchr(), *strchr();
X#endif
X
X#ifdef BSD
X# define CONFSIZE 32
X#else
X# define CONFSIZE 14
X#endif BSD
X
X#ifdef XENIX3
X# define XENIX
X# define SYS3
X#else XENIX3
X# ifdef XENIX5
X# define XENIX
X# define SYS3
X# define SYS5 /* these only make a difference in uwho.c */
X# endif XENIX5
X#endif XENIX3
X
Xstruct cmd {
X char c_cmd; /* command name */
X char *c_desc; /* short help message */
X int (*c_func)(); /* function to run, passed rest of line */
X};
________This_Is_The_END________
echo 'x - udate.c'
sed 's/^X//' << '________This_Is_The_END________' > udate.c
X/*
X * @(#)udate.c 1.1 (TDI) 2/3/87
X *
X * Permission is hereby granted to copy and distribute this program
X * freely. Permission is NOT given to modify this program or distribute
X * it at cost, except for charging a reasonable media/copying fee.
X */
X
X#ifndef lint
Xstatic char _FileID_[] = "@(#)udate.c 1.1 (TDI) 2/3/87";
Xstatic char _UAID_[] = "@(#)UNaXcess version 1.0.2";
X#endif lint
X
Xmain() {
X puts(longdate());
X}
________This_Is_The_END________
exit 0
--
++Brandon (Resident Elf @ ncoast.UUCP)
____ ______________
/ \ / __ __ __ \ Brandon S. Allbery <backbone>!ncoast!allbery
___ | /__> / \ / \ aXcess Co., Consulting ncoast!allbery at Case.CSNET
/ \ | | `--, `--, 6615 Center St. #A1-105 (... at relay.CS.NET)
| | \__/ \__/ \__/ Mentor, OH 44060-4101
\____/ \______________/ +1 216 781 6201
More information about the Mod.sources
mailing list