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