UNaXcess 0.4.4 - Part 1 of 4
Brandon S. Allbery
allbery at ncoast.UUCP
Sun Jul 27 00:50:49 AEST 1986
There was a whole sh*tload of bugs in 0.4.3, from which I have concluded that
trying to write a BBS without maintaining it was a big mistake. Here is the
latest version (save for the one I'm working on now, unready as yet) of
UNaXcess; it seems to work after testing, but I suppose I'll find out soon
enough if it's broken... :-)
---------------------------------- cut here ---------------------------------
# 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:
# ua.c date.c bull.c sys.c
# user.c param.c dir.c
#
echo 'x - ua.c'
sed 's/^X//' <<'________This_Is_The_END________' >>ua.c
X/*
X * @(#)ua.c 1.1 86/05/05 01:43:55 tdi2!brandon @(#)
X * @(#) Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved @(#)
X *
X * Permission is hereby granted to copy and freely distribute this code,
X * UNaXcess Version 0.04.04 and derivatives ONLY. Version 1.00.00 and later
X * may NOT be copied or distributed without the author's written permission.
X * You may charge only a reasonable handling/copying fee for distribution of
X * this code; you may not sell it or include it in a commercial package for
X * resale.
X */
X
X#ifndef lint
Xstatic char _SccsId[] = "@(#)ua.c 1.1 86/05/05 01:43:55 tdi2!brandon @(#)";
Xstatic char _CopyRt[] = "@(#) Copyright (C) 1985 by Brandon S. Allbery @(#)";
X#endif lint
X
X#include "ua.h"
X
Xstruct cmd
X {
X char c_ch; /* command character */
X char c_desc[33]; /* command description */
X int (*c_exec)(); /* command executive */
X }
X ; /* used for command array */
X
X/* forward references for command executives */
X
Xextern int
X readmsg(), readnew(), confidx(), enter(),
X join(), killmsg(), helpme(), scanmsg(),
X logout(), bulletin(), linelen(), shell(),
X userctl(), userlist(), qscan(), udl(),
X unsub(), setlconf();
X
Xstruct cmd cmdt[] =
X {
X '?', "Print help messages", helpme,
X 'a', "Alter or examine a user", userctl,
X 'b', "Reprint login bulletins", bulletin,
X 'c', "Shell command access", shell,
X 'd', "Set default login conference", setlconf,
X 'e', "Enter a message", enter,
X 'f', "File area (Downloading)", udl,
X 'g', "Exit UNaXcess", logout,
X 'h', "Print help messages", helpme,
X 'i', "Index of conferences", confidx,
X 'j', "Join a new conference", join,
X 'k', "Kill a message", killmsg,
X 'l', "Set line length", linelen,
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 'u', "Unsubscribe from a conference", unsub,
X 'w', "List of UNaXcess users", userlist,
X NULL,NULL, NULL
X };
X
Xint nopause;
Xjmp_buf cmdloop;
X
Xmain(argc, argv)
X char **argv;
X {
X char line[256], *lp;
X short lcnt;
X FILE *tp;
X
X getparms();
X chdir(parms.ua_home);
X logon();
X if (parms.ua_hco == 1) {
X printf("\nDo you wish me to stop every few lines to let you read messages (Y)? ");
X gets(line);
X log("Pause? %s", line);
X }
X if (parms.ua_hco == 0 || (parms.ua_hco == 1 && ToLower(line[0]) != 'n'))
X nopause = 0;
X else
X nopause = 1;
X alarm(parms.ua_tlimit * 60); /* time limit */
X signal(SIGINT, SIG_IGN);
X signal(SIGQUIT, quit);
X for (lcnt = 4; lcnt < SIGUSR1; lcnt++) /* we don't muck with others */
X signal(lcnt, logsig);
X signal(SIGALRM, thatsall);
X if (parms.ua_bnr[0] == '\0')
X puts("\nWelcome to UNaXcess Version 0.04.04\nCopyright (C) 1984, 1985 by Brandon Allbery");
X else
X cat(parms.ua_bnr);
X if (argc > 2)
X {
X puts("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 (parms.ua_bbs[0] != '\0' && strcmp(getlogin(), parms.ua_bbs) == 0) {
X
Xnouser:
X for (lcnt = 0; lcnt != 3; lcnt++) {
X if (argc) {
X strcpy(line, argv[1]);
X argc--;
X putchar('\n');
X }
X else {
X if (parms.ua_login[0] == 0)
X printf("\nEnter your user name, GUEST, OFF, or NEW: ");
X else
X fputs(parms.ua_login, stdout);
X gets(line);
X }
X log("Login: %s", line);
X if (line[0] == '\0')
X {
X lcnt--;
X continue;
X }
X for (lp = line; *lp != '\0'; lp++)
X *lp = ToLower(*lp);
X if (strcmp(line, "off") == 0)
X {
X puts("Goodbye...\n\n");
X log("Logout.");
X exit(0);
X }
X if (!getuser(line, &user))
X {
X printf("No such user.\n");
X log("No such user.");
X }
X else if (user.u_pass[0] != '\0')
X {
X strcpy(line, getpass("Enter your password: "));
X log("Password: %s", line);
X puts("\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 {
X puts("\nSorry, you blew it.");
X log("Program aborted.");
X exit(1);
X }
X }
X else if (!getuser(getlogin(), &user))
X goto nouser;
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 {
X puts("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 {
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 putchar('\n');
X if (user.u_access != A_MKUSER)
X bulletin(NULL);
X umask(0); /* so xedit() works */
X if (user.u_lconf[0] != '\0')
X if (isconf(user.u_lconf))
X strcpy(conference, user.u_lconf);
X else {
X putchar('\n');
X for (lp = parms.ua_sysop; *lp != '\0'; lp++)
X putchar(ToUpper(*lp));
X printf(" deleted \"%s\", your login conference. I'm setting you\nback to the \"general\" conference.\n", user.u_lconf);
X user.u_lconf[0] = '\0';
X strcpy(conference, "general");
X }
X else
X strcpy(conference, "general");
X hicnts = readhigh(&user);
X cleanhigh(); /* kill any lingering corpses */
X if (!setjmp(cmdloop))
X signal(SIGINT, intrp);
X while (cmd())
X ;
X printf("Goodbye, ");
X for (lp = user.u_name; *lp != '\0'; lp++)
X putchar(ToUpper(*lp));
X printf(". Call again soon!\n\n\n");
X log("Logout.");
X cleanup();
X }
X
Xcleanup()
X {
X char tmps[256];
X FILE *fp;
X
X sprintf(tmps, "%s/himotd", MOTD);
X if ((fp = fopen(tmps, "r")) == NULL)
X {
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 exit(0);
X }
X
Xcmd()
X {
X char line[256], *p;
X struct cmd *cmdp;
X
X if (user.u_access == A_MKUSER) {
X newuser();
X if (user.u_access == A_NONE) {
X puts("\nYou'll have to be validated before you can use UNaXcess.");
X return 0;
X }
X }
X printf("\n(%s) Command (? = Help): ", conference);
X gets(line);
X log("Command: %s", line);
X if (line[0] == '\0')
X return 1;
X for (p = line; *p != '\0'; p++)
X *p = ToLower(*p);
X for (cmdp = cmdt; cmdp->c_ch != NULL; cmdp++)
X if (ToLower(cmdp->c_ch) == line[0])
X return (*cmdp->c_exec)(line);
X puts("Type '?' for help.");
X log("No such command.");
X return 1;
X }
X
Xlogout()
X {
X char line[256];
X
X printf("Are you sure you want to log out (N)? ");
X gets(line);
X log("Logout? %s", line);
X return (ToLower(line[0]) != 'y');
X }
X
Xhelpme()
X {
X short lcnt;
X struct cmd *cmdp;
X
X putchar('\n');
X lcnt = 2 * ((user.u_llen < 80) + 1);
X for (cmdp = cmdt; cmdp->c_ch != NULL; cmdp++)
X {
X printf("%c - %-32.32s", ToUpper(cmdp->c_ch), cmdp->c_desc);
X lcnt++;
X if (user.u_llen < 80 || !(lcnt % 2))
X putchar('\n');
X if ((lcnt / 2) % (user.u_llen >= 80? 32: 16) == 0)
X if (!cont())
X break;
X }
X if (user.u_llen >= 80 && lcnt % 2 != 0)
X putchar('\n');
X puts("\nIf you need further help, look for (or ask for) a HELP conference.");
X return 1;
X }
X
Xlinelen(s)
X char *s;
X {
X int llen;
X char line[256], *p;
X
X p = s;
X while (*p != '\0')
X if (*p++ == ' ')
X if ((llen = atoi(p)) > 40 && llen < 132)
X {
X printf("New line length = %d.\n", llen);
X user.u_llen = llen;
X putuser(user.u_name, &user);
X return 1;
X }
X else
X break;
X llen = 0;
X while (llen < 40 || llen > 132)
X {
X printf("\nEnter new line length (40-132): ");
X gets(line);
X llen = atoi(line);
X }
X return 1;
X }
X
Xcont()
X {
X char ch;
X
X if (!isatty(0) || nopause)
X return 1;
X printf("More (Y)? ");
X silent();
X ch = getchar();
X talk();
X log("Cont? %c", ch);
X printf("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b");
X return (int) (RIndex(" Yy\r\n", ch) != NULL);
X /* the above cast is because Plexus pcc is stupid! */
X }
X
Xcat(file)
X char *file;
X {
X FILE *f;
X char ch;
X short lcnt, ccnt;
X
X if ((f = fopen(file, "r")) == NULL)
X {
X log("Error %d opening %s", errno, file);
X puts("Cannot open file.");
X return;
X }
X lcnt = ccnt = 0;
X while ((ch = getc(f)) != EOF)
X {
X if (ch == '\n')
X {
X putchar(ch);
X ccnt = 0;
X if (++lcnt % 16 == 0)
X if (!cont())
X break;
X }
X else if (ch == '\t')
X putchar('\t');
X else
X {
X if (iscntrl(ch))
X putchar('.');
X else
X putchar(ch);
X if (++ccnt == (user.u_llen<40? 80: user.u_llen) - 1)
X {
X ccnt = 0;
X putchar('\n');
X if (++lcnt % 16 == 0)
X if (!cont())
X break;
X }
X }
X }
X fclose(f);
X }
________This_Is_The_END________
echo 'x - date.c'
sed 's/^X//' <<'________This_Is_The_END________' >>date.c
X/*
X * @(#)date.c 1.1 86/05/05 01:43:38 tdi2!brandon @(#)
X * @(#) Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved @(#)
X *
X * Permission is hereby granted to copy and freely distribute this code,
X * UNaXcess Version 0.04.04 and derivatives ONLY. Version 1.00.00 and later
X * may NOT be copied or distributed without the author's written permission.
X * You may charge only a reasonable handling/copying fee for distribution of
X * this code; you may not sell it or include it in a commercial package for
X * resale.
X */
X
X#ifndef lint
Xstatic char _SccsId[] = "@(#)date.c 1.1 86/05/05 01:43:38 tdi2!brandon @(#)";
Xstatic char _CopyRt[] = "@(#) Copyright (C) 1985 by Brandon S. Allbery @(#)";
X#endif lint
X
X#ifdef BSD
X#include <sys/time.h>
X#else
X#include <time.h>
X#endif BSD
X
Xstatic char *month[] =
X {
X "January", "February", "March", "April",
X "May", "June", "July", "August",
X "September", "October", "November", "December"
X };
X
Xstatic char *wkday[] =
X {
X "Sunday", "Monday", "Tuesday", "Wednesday",
X "Thursday", "Friday", "Saturday"
X };
X
Xstruct tm *localtime();
X
Xchar *date()
X {
X long clock;
X struct tm *ltbuf;
X static char tbuf[18];
X
X time(&clock);
X ltbuf = localtime(&clock);
X sprintf(tbuf, "%02d/%02d/%02d %02d:%02d:%02d", ltbuf->tm_mon + 1, ltbuf->tm_mday, ltbuf->tm_year, ltbuf->tm_hour, ltbuf->tm_min, ltbuf->tm_sec);
X return tbuf;
X }
X
Xchar *longdate()
X {
X long clock;
X struct tm *ltbuf;
X static char tbuf[80];
X short hour;
X char ampm;
X
X time(&clock);
X ltbuf = localtime(&clock);
X if (ltbuf->tm_hour == 0)
X {
X hour = 12;
X ampm = 'A';
X }
X else if (ltbuf->tm_hour < 12)
X {
X hour = ltbuf->tm_hour;
X ampm = 'A';
X }
X else if (ltbuf->tm_hour == 12)
X {
X hour = 12;
X ampm = 'P';
X }
X else
X {
X hour = ltbuf->tm_hour - 12;
X ampm = 'P';
X }
X sprintf(tbuf, "%s, %s %d, 19%02d - %d:%02d %cM", wkday[ltbuf->tm_wday], month[ltbuf->tm_mon], ltbuf->tm_mday, ltbuf->tm_year, hour, ltbuf->tm_min, ampm);
X return tbuf;
X }
________This_Is_The_END________
echo 'x - bull.c'
sed 's/^X//' <<'________This_Is_The_END________' >>bull.c
X/*
X * @(#)bull.c 1.1 86/05/05 01:43:32 tdi2!brandon @(#)
X * @(#) Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved @(#)
X *
X * Permission is hereby granted to copy and freely distribute this code,
X * UNaXcess Version 0.04.04 and derivatives ONLY. Version 1.00.00 and later
X * may NOT be copied or distributed without the author's written permission.
X * You may charge only a reasonable handling/copying fee for distribution of
X * this code; you may not sell it or include it in a commercial package for
X * resale.
X */
X
X#ifndef lint
Xstatic char _SccsId[] = "@(#)bull.c 1.1 86/05/05 01:43:32 tdi2!brandon @(#)";
Xstatic char _CopyRt[] = "@(#) Copyright (C) 1985 by Brandon S. Allbery @(#)";
X#endif lint
X
X#include "ua.h"
X
Xbulletin(s)
X char *s;
X {
X short mcnt, himotd;
X char tmps[256];
X FILE *fp;
X
X if (user.u_access == A_MKUSER)
X return;
X sprintf(tmps, "%s/himotd", MOTD);
X if ((fp = fopen(tmps, "r")) == NULL)
X {
X log("Error %d opening %s", errno, tmps);
X panic("himotd");
X }
X fgets(tmps, 32, fp);
X fclose(fp);
X himotd = atoi(tmps);
X for (mcnt = (strcmp(user.u_name, "guest") == 0? 0: user.u_nbull + 1); mcnt <= himotd; mcnt++)
X {
X sprintf(tmps, "%s/%d", MOTD, mcnt);
X if (!readmotd(tmps, mcnt))
X break;
X }
X }
X
Xreadmotd(motd, mnum)
X char *motd;
X short mnum;
X {
X char line[256];
X
X printf("Bulletin #%d:\n", mnum);
X cat(motd);
X printf("\nContinue or Stop (C)? ");
X if (!isatty(0) || nopause)
X {
X putchar('\n');
X line[0] = '\0';
X }
X else
X gets(line);
X log("C/S? %s", line);
X return ToLower(line[0]) != 's';
X }
________This_Is_The_END________
echo 'x - sys.c'
sed 's/^X//' <<'________This_Is_The_END________' >>sys.c
X/*
X * @(#)sys.c 1.1 86/05/05 01:43:49 tdi2!brandon @(#)
X * @(#) Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved @(#)
X *
X * Permission is hereby granted to copy and freely distribute this code,
X * UNaXcess Version 0.04.04 and derivatives ONLY. Version 1.00.00 and later
X * may NOT be copied or distributed without the author's written permission.
X * You may charge only a reasonable handling/copying fee for distribution of
X * this code; you may not sell it or include it in a commercial package for
X * resale.
X */
X
X#ifndef lint
Xstatic char _SccsId[] = "@(#)sys.c 1.1 86/05/05 01:43:49 tdi2!brandon @(#)";
Xstatic char _CopyRt[] = "@(#) Copyright (C) 1985 by Brandon S. Allbery @(#)";
X#endif lint
X
X#include "ua.h"
X
Xstatic FILE *lfp;
X
Xshort critical = 0;
X
Xshort quitc = 0;
Xshort intr = 0;
Xshort alrm = 0;
X
Xshort shhh = 0;
X
Xshort warned = 0;
X
X#ifdef SYS3
X#include <sys/ioctl.h>
X#include <termio.h>
Xstruct termio mode;
X#else
X#include <sgtty.h>
X#ifndef V7
X#include <sys/ioctl.h>
X#endif
Xstruct sgttyb mode;
X#endif
X
Xlogon()
X {
X struct stat sb;
X char *cp;
X
X /* first set up ttymode structure */
X#ifdef SYS3
X ioctl(0, TCGETA, &mode);
X#else
X#ifdef V7
X gtty(0, &mode);
X#else
X ioctl(0, TIOCGETP, &mode);
X#endif
X#endif
X
X if (parms.ua_env) {
X if ((cp = getenv("SHELL")) != NULL)
X strcpy(parms.ua_shell, cp);
X if ((cp = getenv("EDITOR")) != NULL)
X strcpy(parms.ua_edit, cp);
X }
X
X if (!parms.ua_log || stat(LOG, &sb) < 0) /* no logfile => no logging */
X {
X lfp = NULL;
X return;
X }
X if ((lfp = fopen(LOG, "a")) == NULL)
X {
X perror(LOG);
X puts("panic: log");
X exit(2);
X }
X }
X
Xlog(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
X char *fmt, *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9;
X {
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)
X int sig;
X {
X log("Received signal %d.", sig);
X fprintf(stderr, "\n\nUNaXcess internal error: %d.\n", sig);
X unlink(RIndex(ttyname(fileno(stdin)), '/') + 1);
X signal(SIGIOT, SIG_DFL);
X abort();
X }
X
Xpanic(s)
X char *s;
X {
X log("panic: %s", s);
X fprintf(stderr, "panic: %s\n", s);
X unlink(RIndex(ttyname(2), '/') + 1);
X exit(1);
X }
X
Xquit()
X {
X char line[256];
X
X if (critical) {
X quitc++;
X return;
X }
X puts("\n\nFast logout\n");
X signal(SIGQUIT, quit);
X log("Signalled QUIT.");
X printf("\nDo you really want to leave UNaXcess (N)? ");
X gets(line);
X if (ToLower(line[0]) == 'y')
X {
X printf("OK, %s. See you later!\n\n\n", user.u_name);
X cleanup();
X }
X }
X
Xintrp()
X {
X if (critical) {
X intr++;
X return;
X }
X puts("\n\nAborted.");
X log("Command aborted.");
X signal(SIGINT, intrp);
X longjmp(cmdloop, 1);
X }
X
Xchar *visible(s)
X char *s;
X {
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 {
X *vp++ = '^';
X *vp++ = uncntrl(*sp);
X }
X *vp = '\0';
X return vs;
X }
X
Xshell()
X {
X short sig;
X unsigned altime;
X
X if (user.u_access == A_GUEST || user.u_access == A_USER || parms.ua_shell[0] == '\0')
X {
X puts("You don't have shell access privileges.");
X log("Security violation: Unauthorized SHELL");
X return 1;
X }
X switch (fork())
X {
X case -1:
X log("Error %d forking shell", errno);
X puts("Sorry, the system's full. Try again later.");
X return 1;
X case 0:
X for (sig = 2; sig < SIGUSR1; 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 puts("Couldn't run the shell.");
X exit(1);
X default:
X CRIT();
X for (sig = 2; sig < SIGUSR1; 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 = 4; sig < SIGUSR1; sig++)
X signal(sig, logsig);
X signal(SIGALRM, thatsall);
X NOCRIT();
X }
X return 1;
X }
X
Xthatsall()
X {
X if (critical) {
X alrm++;
X return;
X }
X if (warned) {
X log("Timeout.");
X puts("\nI'm sorry, but you're out of time.\n\n");
X cleanup();
X }
X else
X {
X log("5-minute warning.");
X puts("\nYou have only five minutes left in this session.\n\n");
X warned = 1;
X alarm(5 * 60);
X }
X }
X
X/*
X * I've had problems with this. If it breaks, delete the innards of the lock
X * functions. Hopefully, I got it right this time...
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_atime > 60) {
X unlink(lockpath);
X break;
X }
X }
X if ((lock_fd = creat(lockpath, 0600)) < 0) {
X fprintf(stderr, "Errno = %d creating lockfile %s\n", errno, lockpath);
X exit(-1);
X }
X close(lock_fd);
X}
X
Xrmlock(lockfile)
Xchar *lockfile; {
X char lockpath[50];
X struct stat statbuf;
X
X strcpy(lockpath, "lock/");
X strcat(lockpath, lockfile);
X if (stat(lockpath, &statbuf) < 0) {
X log("Lockfile %s deleted???", lockpath);
X printf("\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 puts("\nI've got a lockfile problem. You won't be able to do some\nthings until it's fixed. Sorry...\n");
X }
X}
X
Xxedit(file)
X char *file;
X {
X short sig;
X unsigned altime;
X
X if (user.u_access == A_GUEST || user.u_access == A_USER || parms.ua_edit[0] == '\0')
X {
X puts("You don't have shell access privileges.");
X log("Security violation: Unauthorized XEDIT");
X return 1;
X }
X if (strcmp(parms.ua_edit, "ua-edit") == 0) {
X edit(file);
X return 1;
X }
X switch (fork())
X {
X case -1:
X log("Error %d forking shell", errno);
X puts("Sorry, the system's full. Using the line editor...");
X edit(file);
X return 1;
X case 0:
X for (sig = 2; sig < SIGUSR1; sig++)
X signal(sig, SIG_DFL);
X setuid(getuid());
X chdir(getpwuid(getuid())->pw_dir);
X run(parms.ua_edit, file);
X log("Error %d exec'ing %s", errno, parms.ua_edit);
X puts("Couldn't run the editor; using the line editor...");
X edit(file);
X exit(0);
X default:
X CRIT();
X for (sig = 2; sig < SIGUSR1; sig++)
X signal(sig, SIG_IGN);
X signal(SIGALRM, thatsall);
X wait(NULL);
X signal(SIGINT, intrp);
X signal(SIGQUIT, quit);
X for (sig = 4; sig < SIGUSR1; sig++)
X signal(sig, logsig);
X signal(SIGALRM, thatsall);
X NOCRIT();
X }
X return 1;
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
Xsilent() {
X if (shhh)
X return;
X#ifdef SYS3
X mode.c_lflag &= ~(ICANON|ISIG|ECHO|ECHOE|ECHOK);
X mode.c_cc[VMIN] = 1;
X mode.c_cc[VTIME] = 0;
X ioctl(0, TCSETAW, &mode);
X#else
X mode.sg_flags |= CBREAK;
X mode.sg_flags &= ~ECHO;
X#ifdef V7
X stty(0, &mode);
X#else
X ioctl(0, TIOCSETP, &mode);
X#endif
X#endif
X shhh = 1;
X}
X
Xtalk() {
X if (!shhh)
X return;
X#ifdef SYS3
X mode.c_lflag |= (ICANON|ISIG|ECHO|ECHOE|ECHOK);
X mode.c_cc[VEOF] = CEOF;
X mode.c_cc[VEOL] = CNUL;
X ioctl(0, TCSETAW, &mode);
X#else
X mode.sg_flags |= ECHO;
X mode.sg_flags &= ~CBREAK;
X#ifdef V7
X stty(0, &mode);
X#else
X ioctl(0, TIOCSETP, &mode);
X#endif
X#endif
X shhh = 0;
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}
________This_Is_The_END________
echo 'x - user.c'
sed 's/^X//' <<'________This_Is_The_END________' >>user.c
X/*
X * @(#)user.c 1.1 86/05/05 01:44:07 tdi2!brandon @(#)
X * @(#) Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved @(#)
X *
X * Permission is hereby granted to copy and freely distribute this code,
X * UNaXcess Version 0.04.04 and derivatives ONLY. Version 1.00.00 and later
X * may NOT be copied or distributed without the author's written permission.
X * You may charge only a reasonable handling/copying fee for distribution of
X * this code; you may not sell it or include it in a commercial package for
X * resale.
X */
X
X#ifndef lint
Xstatic char _SccsId[] = "@(#)user.c 1.1 86/05/05 01:44:07 tdi2!brandon @(#)";
Xstatic char _CopyRt[] = "@(#) Copyright (C) 1985 by Brandon S. Allbery @(#)";
X#endif lint
X
X#include "ua.h"
X
Xstruct user user;
Xstruct _himsg *hicnts;
X
Xgetuser(name, buf)
Xchar *name;
Xstruct user *buf; {
X FILE *bfd;
X char line[1024], lcuname[33], *p, *q;
X int ncolon;
X
X if ((bfd = fopen(PASSWD, "r")) == NULL) {
X log("Error %d opening %s", errno, PASSWD);
X panic("passwd");
X }
X for (p = name, q = lcuname; *p != '\0' && p - name <= 32; p++, q++)
X *q = ToLower(*p);
X *q = '\0';
X while (fgets(line, sizeof line, bfd) != NULL)
X if (strncmp(line, lcuname, strlen(lcuname)) == 0 && line[strlen(lcuname)] == ':') {
X fclose(bfd);
X buf->u_name[0] = '\0';
X buf->u_pass[0] = '\0';
X buf->u_access = 0;
X buf->u_login[0] = '\0';
X buf->u_llen = 0;
X buf->u_nbull = 0;
X buf->u_lconf[0] = '\0';
X ncolon = 0;
X for (p = line; *p != '\0'; p++)
X if (*p == ':')
X ncolon++;
X if (ncolon < 5) {
X log("Bad userfile entry for %s", lcuname);
X return 0;
X }
X for (p = line, q = buf->u_name; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X for (p++, q = buf->u_pass; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X for (p++, q = lcuname; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X buf->u_access = atoi(lcuname);
X for (p++, q = buf->u_login; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X for (p++, q = lcuname; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X buf->u_llen = atoi(lcuname);
X for (p++, q = lcuname; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X buf->u_nbull = atoi(lcuname);
X for (p++, q = buf->u_lconf; *p != '\n'; p++, q++)
X *q = *p;
X *q = '\0';
X return 1;
X }
X fclose(bfd);
X return 0;
X}
X
Xputuser(name, ubuf)
X char *name;
X struct user *ubuf;
X {
X FILE *fd, *tfd;
X char line[1024], *tempfile = mktemp("/tmp/UptXXXXXX"), lcname[33], *p, *q;
X static char lockfile[] = "userfil.lock";
X short flag;
X
X CRIT();
X mklock(lockfile);
X if ((fd = fopen(PASSWD, "r")) == NULL)
X {
X log("Error %d opening %s", errno, PASSWD);
X panic("passwd");
X }
X if ((tfd = fopen(tempfile, "w")) == NULL)
X {
X log("Error %d opening %s", errno, tempfile);
X panic("tmp");
X }
X flag = 0;
X for (p = name, q = lcname; *p != '\0' && p - name < 33; p++, q++)
X *q = ToLower(*p);
X *q = 0;
X while (fgets(line, sizeof line, fd) != NULL)
X if (strncmp(line, lcname, strlen(lcname)) == 0 && line[strlen(lcname)] == ':')
X {
X fprintf(tfd, "%s:%s:%d:%s:%d:%d:%s\n", ubuf->u_name, ubuf->u_pass, ubuf->u_access, ubuf->u_login, ubuf->u_llen, (s_cmp(ubuf->u_name, "guest") == 0? 0: ubuf->u_nbull), (s_cmp(ubuf->u_name, "guest") == 0? "": ubuf->u_lconf));
X flag++;
X }
X else
X fputs(line, tfd);
X if (!flag)
X fprintf(tfd, "%s:%s:%d:%s:%d:%d:%s\n", ubuf->u_name, ubuf->u_pass, ubuf->u_access, ubuf->u_login, ubuf->u_llen, (s_cmp(ubuf->u_name, "guest") == 0? 0: ubuf->u_nbull), (s_cmp(ubuf->u_name, "guest") == 0? "": ubuf->u_lconf));
X fclose(fd);
X fclose(tfd);
X unlink(PASSWD);
X if (copylink(tempfile, PASSWD) < 0)
X {
X log("Error %d copylinking %s to %s", errno, tempfile, PASSWD);
X panic("copylink");
X }
X unlink(tempfile);
X rmlock(lockfile);
X NOCRIT();
X }
X
Xwritehigh(hilist)
X struct _himsg *hilist;
X {
X FILE *hp, *f;
X static char line[1024], hirec[1024]; /* 68000's have limited frames */
X char *tmpf = mktemp("/tmp/RcXXXXXX");
X char *eofflag;
X static char lockfile[] = "newmsgs.lock";
X struct _himsg *hptr;
X
X if (s_cmp(user.u_name, "guest") == 0)
X return; /* don't write GUEST hirecs! */
X CRIT();
X if ((f = fopen(tmpf, "w")) == NULL)
X {
X log("Error %d opening %s", errno, tmpf);
X panic("tmp");
X }
X if ((hp = fopen(NEWMSGS, "r")) == NULL)
X {
X log("Error %d opening %s", errno, NEWMSGS);
X fclose(f);
X unlink(tmpf);
X panic("userind");
X }
X mklock(lockfile);
X sprintf(line, "%s:", user.u_name);
X while ((eofflag = fgets(hirec, sizeof hirec, hp)) != NULL) {
X if (strncmp(hirec, line, strlen(line)) == 0)
X break;
X fputs(hirec, f);
X }
X if (eofflag != NULL)
X while ((eofflag = fgets(hirec, sizeof hirec, hp)) != NULL)
X if (hirec[0] != '\t' && hirec[0] != ' ')
X break;
X fputs(line, f);
X putc('\n', f);
X for (hptr = hilist; hptr != NULL; hptr = hptr->hi_next)
X fprintf(f, "\t%s%c %d\n", hptr->hi_conf, (hptr->hi_uns == HI_UNSUB? '!': ':'), hptr->hi_num);
X if (eofflag != NULL && hirec[0] != '\t' && hirec[0] != ' ')
X fputs(hirec, f);
X if (eofflag != NULL)
X while (fgets(hirec, sizeof hirec, hp) != NULL)
X fputs(hirec, f);
X fclose(f);
X fclose(hp);
X unlink(NEWMSGS);
X if (copylink(tmpf, NEWMSGS) < 0)
X {
X log("Error %d copylinking %s to %s", errno, tmpf, NEWMSGS);
X panic("copylink");
X }
X unlink(tmpf);
X rmlock(lockfile);
X NOCRIT();
X }
X
Xstruct _himsg *readhigh(foruser)
X struct user *foruser;
X {
X static char hirec[1024];
X char uidx[40], *p, *q;
X FILE *f;
X struct _himsg *workp, *initp, *lastp;
X
X strcpy(uidx, foruser->u_name);
X strcat(uidx, ":");
X if ((f = fopen(NEWMSGS, "r")) == NULL)
X return NULL;
X while (fgets(hirec, sizeof hirec, f) != NULL)
X if (strncmp(hirec, uidx, strlen(uidx)) == 0)
X break;
X if (feof(f))
X {
X fclose(f);
X return NULL;
X }
X workp = NULL;
X initp = NULL;
X while (fgets(hirec, sizeof hirec, f) != NULL && (hirec[0] == ' ' || hirec[0] == '\t')) {
X hirec[strlen(hirec) - 1] = '\0';
X for (p = hirec; *p == ' ' || *p == '\t'; p++)
X ;
X for (q = uidx; *p != ' ' && *p != '\t' && *p != '\0' && *p != ':' && *p != '!'; p++)
X *q++ = *p;
X *q = '\0';
X while (*p == ' ' || *p == '\t')
X p++;
X if (*p == '!') { /* unsubscribed... */
X if ((workp = (struct _himsg *) calloc((unsigned) 1, sizeof (struct _himsg))) == NULL)
X {
X log("Error %d allocating _himsg for %s", errno, uidx);
X panic("alloc");
X }
X strcpy(workp->hi_conf, uidx);
X workp->hi_num = atoi(++p);
X workp->hi_next = initp;
X workp->hi_uns = HI_UNSUB;
X initp = workp;
X continue;
X }
X if (*p != ':') {
X log("Invalid format of userind record: ``%s''", hirec);
X puts("Your index is garbled; some conference\nhigh-message counts may be lost.");
X break;
X }
X if ((workp = (struct _himsg *) calloc((unsigned) 1, sizeof (struct _himsg))) == NULL)
X {
X log("Error %d allocating _himsg for %s", errno, uidx);
X panic("alloc");
X }
X strcpy(workp->hi_conf, uidx);
X workp->hi_num = atoi(++p);
X workp->hi_next = initp;
X workp->hi_uns = HI_SUBSCR;
X initp = workp;
X }
X fclose(f);
X return initp;
X }
X
Xnewuser()
X {
X struct user nubuf, junk;
X char line[256], *p;
X
X log("Entered newuser module.");
X cat(NEWUSER);
X
XAgain:
X printf("\nDo you still want to become a user (N)? ");
X gets(line);
X log("Become user? %s", line);
X if (ToLower(line[0]) != 'y')
X return;
X do
X {
X printf("What name would you like to use on this system? It should not be\nmore than 32 letters long: ");
X gets(line);
X log("Name: %s", line);
X if (line[0] == '\0' || line[0] == ' ')
X {
X line[0] = '?';
X p = line;
X continue;
X }
X for (p = line; *p != '\0'; p++)
X if (*p == ':')
X {
X puts("Sorry, no colons allowed; they cause nasty surprises.");
X log("Illegal colon in name");
X break;
X }
X }
X while (*p != NULL);
X strncpy(nubuf.u_name, line, 32);
X nubuf.u_name[32] = '\0';
X line[0] = '\0';
X do
X {
X if (line[0] != 0)
X puts("You made a typing error.");
X strcpy(line, getpass("Please enter a password of three to eight characters.\nIt will not be displayed: "));
X log("Pass: %s", line);
X }
X while (strlen(line) < 3 || strcmp(line, getpass("Please re-enter it, just to make sure: ")) != 0);
X strcpy(nubuf.u_pass, line);
X do
X {
X printf("How many characters per line are on your terminal?\nPlease enter a number from 40 to 132, or <ENTER> for 80: ");
X gets(line);
X log("Line: %s", line);
X if (line[0] == '\0')
X nubuf.u_llen = 80;
X else
X nubuf.u_llen = atoi(line);
X }
X while (nubuf.u_llen < 40 || nubuf.u_llen > 132);
X printf("\nName:\t%s\nPass:\t%s\nLine:\t%d\n\nIs this correct (N)? ", nubuf.u_name, nubuf.u_pass, nubuf.u_llen);
X gets(line);
X log("Okay? %s", line);
X if (ToLower(line[0]) != 'y')
X goto Again;
X puts("Encrypting password, please wait...");
X strcpy(nubuf.u_pass, crypt(nubuf.u_pass, nubuf.u_pass) + 2);
X strcpy(nubuf.u_login, user.u_login);/* default login name ( guest ?) */
X nubuf.u_access = user.u_llen; /* since we don't use u_llen here */
X nubuf.u_nbull = 0; /* no bulletins read yet */
X puts("Recording user information...");
X for (p = nubuf.u_name; *p != '\0'; p++)
X *p = ToLower(*p);
X if (getuser(nubuf.u_name, &junk))
X {
X puts("Sorry, but that name's already in use. Please choose another.");
X goto Again;
X }
X putuser(nubuf.u_name, &nubuf);
X user = nubuf;
X }
X
Xuserctl(s)
X char *s;
X {
X char line[256], *p, *q;
X struct user ubuf;
X short cflag, pflag;
X
X if (user.u_access != A_WITNESS)
X {
X if (strcmp(user.u_name, "guest") == 0) {
X log("Security violation: userctl by GUEST");
X puts("Sorry, but GUEST can't change himself.");
X return 1;
X }
X pflag = 1;
X log("Userctl by non-Witness; restricting control modes.");
X puts("Since you're not a Fairwitness, you can only change some things about\nyourself, like your password.");
X strcpy(line, user.u_name);
X }
X else
X {
X line[0] = '\0';
X pflag = 0;
X for (p = s; *p != '\0'; p++)
X if (*p == ' ')
X {
X strcpy(line, ++p);
X break;
X }
X if (line[0] == '\0')
X {
X printf("Examine which user: ");
X gets(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 }
X line[32] = '\0';
X }
X if (!getuser(line, &ubuf))
X if (pflag)
X {
X log("Can't locate current user in the userfile.");
X panic("user");
X }
X else
X {
X printf("No such user. Create him (N)? ");
X strcpy(ubuf.u_name, line);
X gets(line);
X log("New user? %s", line);
X if (ToLower(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 cflag = 0;
X }
X else if (strlen(ubuf.u_pass) == 0)
X cflag = 0;
X else
X cflag = 1;
X for (;;)
X {
X printf("\nName:\t%s\nPass:\t%s%s\nAccess:\t%s\n%s:\t%d\nLogin conference: %s\n\nChange Name, Pass, Access, Login, %s,\nDefault Login Conference; Quit; or Save: ", ubuf.u_name, ubuf.u_pass,
X (cflag? " (encrypted)": ""), (ubuf.u_access==A_NONE? "None": (ubuf.u_access==A_GUEST? "Guest": (ubuf.u_access==A_USER? "Ordinary user": (ubuf.u_access==A_SYSTEM? "System": (ubuf.u_access==A_FILES? "Files":
X (ubuf.u_access==A_WITNESS? "Fairwitness": "User maker")))))), (ubuf.u_access==A_MKUSER? "DftAxs": "Width"), ubuf.u_llen, ubuf.u_lconf, (ubuf.u_access==A_MKUSER? "Default Access": "Width"));
X gets(line);
X log("Change: %s", line);
X switch (line[0])
X {
X case 'N':
X case 'n':
X if (pflag)
X {
X log("Security violation: Attempted to change name.");
X puts("You can't do that.");
X break;
X }
X printf("Enter new name: ");
X gets(line);
X log("Name: %s", line);
X if (line[0] == '\0')
X break;
X for (p = line; *p != '\0'; p++)
X if (*p == ':')
X {
X log("Illegal colon in name.");
X puts("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 case 'p':
X strcpy(line, getpass("Enter new password: "));
X if (line[0] == '\0')
X break;
X strcpy(ubuf.u_pass, line);
X cflag = 0; /* it's not encrypted now */
X break;
X case 'A':
X case 'a':
X if (pflag)
X {
X log("Security violation: Attempted to change access level.");
X puts("You can't do that.");
X break;
X }
X printf("Access: None, Guest, User, Files, System, Witness, Makeuser? ");
X gets(line);
X log("Access: %s", line);
X if ((ToLower(line[0]) == 'a' || ubuf.u_access == A_WITNESS) && strcmp(user.u_name, SYSOP) != 0)
X {
X puts("Sorry, only the sysop can administer Witness privileges.");
X log("Security violation: WITNESS administering WITNESS");
X break;
X }
X switch (line[0])
X {
X case 'g':
X case 'G':
X ubuf.u_access = A_GUEST;
X break;
X case 'n':
X case 'N':
X ubuf.u_access = A_NONE;
X break;
X case '\0':
X break;
X case 'u':
X case 'U':
X ubuf.u_access = A_USER;
X break;
X case 's':
X case 'S':
X ubuf.u_access = A_SYSTEM;
X break;
X case 'w':
X case 'W':
X ubuf.u_access = A_WITNESS;
X break;
X case 'm':
X case 'M':
X ubuf.u_access = A_MKUSER;
X break;
X case 'f':
X case 'F':
X ubuf.u_access = A_FILES;
X break;
X default:
X puts("What? Access unchanged.");
X }
X break;
X case 'D':
X case 'd':
X printf("Enter the default login conference: ");
X gets(line);
X log("Login conference: %s", line);
X if (!isconf(line))
X puts("That conference doesn't exist.");
X else if (uisunsub(ubuf.u_name, line))
X printf("%s isn't subscribed to %s.\n", ubuf.u_name, line);
X else
X strcpy(ubuf.u_lconf, line);
X break;
X case 'W':
X case 'w':
X if (ubuf.u_access == A_MKUSER) {
X printf("Default Access: None, Guest, User, Files, System? ");
X gets(line);
X log("DftAxs: %s", line);
X if (ToLower(line[0]) == 'a') {
X puts("I don't think you really want to make every user a Fairwitness.");
X log("Security violation: DftAxs == A_WITNESS?");
X break;
X }
X switch (line[0]) {
X case 'g':
X case 'G':
X ubuf.u_llen = A_GUEST;
X break;
X case 'n':
X case 'N':
X ubuf.u_llen = A_NONE;
X break;
X case '\0':
X break;
X case 'u':
X case 'U':
X ubuf.u_llen = A_USER;
X break;
X case 's':
X case 'S':
X ubuf.u_access = A_SYSTEM;
X break;
X case 'm':
X case 'M':
X puts("Default access is user maker???");
X log("Attempted to make default access == MAKEUSER?");
X break;
X case 'f':
X case 'F':
X ubuf.u_access = A_FILES;
X break;
X default:
X puts("What? Default access unchanged.");
X }
X }
X else {
X printf("Enter new line length, 40-132: ");
X gets(line);
X log("Line length: %s", line);
X if (line[0] == '\0')
X break;
X ubuf.u_llen = atoi(line);
X }
X break;
X case 'Q':
X case 'q':
X printf("Abort user examine, are you sure (N)? ");
X gets(line);
X log("Abort? %s", line);
X if (ToLower(line[0]) != 'y')
X break;
X return 1;
X case 'S':
X case 's':
X if (!cflag)
X {
X puts("Encrypting password, please wait...");
X strcpy(ubuf.u_pass, crypt(ubuf.u_pass, ubuf.u_pass) + 2);
X }
X putuser(ubuf.u_name, &ubuf);
X if (strcmp(ubuf.u_name, user.u_name) == 0)
X user = ubuf;
X return 1;
X default:
X puts("What? Please enter one of N, P, L, A, D, or S.");
X }
X }
X }
X
Xuserlist()
X {
X FILE *bfd;
X char line[1024], *p, *q, dbuf[20];
X short lcnt, ncolon;
X struct user buf;
X
X if ((bfd = fopen(PASSWD, "r")) == NULL)
X {
X log("Error %d opening %s", errno, PASSWD);
X panic("passwd");
X }
X puts("\nList of UNaXcess users:\n");
X lcnt = 0;
X while (fgets(line, 1024, bfd) != NULL)
X {
X buf.u_name[0] = '\0';
X buf.u_pass[0] = '\0';
X buf.u_access = 0;
X buf.u_login[0] = '\0';
X buf.u_llen = 0;
X buf.u_nbull = 0;
X buf.u_lconf[0] = '\0';
X ncolon = 0;
X for (p = line; *p != '\0'; p++)
X if (*p == ':')
X ncolon++;
X if (ncolon < 6) {
X log("Bad usefile entry %.*s", strlen(line) - 1, line);
X continue;
X }
X for (p = line, q = buf.u_name; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X for (p++, q = buf.u_pass; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X for (p++, q = dbuf; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X buf.u_access = atoi(dbuf);
X for (p++, q = buf.u_login; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X for (p++, q = dbuf; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X buf.u_llen = atoi(dbuf);
X for (p++, q = dbuf; *p != ':'; p++, q++)
X *q = *p;
X *q = '\0';
X buf.u_nbull = atoi(dbuf);
X for (p++, q = buf.u_lconf; *p != '\n'; p++, q++)
X *q = *p;
X *q = '\0';
X for (p = buf.u_name; *p != NULL; p++)
X *p = ToUpper(*p);
X printf("%-32.32s Access: %s\n", buf.u_name, (buf.u_access==A_NONE?
X "None": (buf.u_access==A_GUEST? "Guest": (buf.u_access==A_USER?
X "Normal": (buf.u_access==A_WITNESS? "Fairwitness": (buf.u_access==A_SYSTEM? "System": (user.u_access==A_FILES? "Files": "(make a user)")))))));
X if (++lcnt % 16 == 0)
X if (!cont())
X break;
X }
X fclose(bfd);
X return 1;
X }
________This_Is_The_END________
echo 'x - param.c'
sed 's/^X//' <<'________This_Is_The_END________' >>param.c
X/*
X * @(#)param.c 1.1 86/05/05 01:43:47 tdi2!brandon @(#)
X * @(#) Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved @(#)
X *
X * Permission is hereby granted to copy and freely distribute this code,
X * UNaXcess Version 0.04.04 and derivatives ONLY. Version 1.00.00 and later
X * may NOT be copied or distributed without the author's written permission.
X * You may charge only a reasonable handling/copying fee for distribution of
X * this code; you may not sell it or include it in a commercial package for
X * resale.
X */
X
X#ifndef lint
Xstatic char _SccsId[] = "@(#)param.c 1.1 86/05/05 01:43:47 tdi2!brandon @(#)";
Xstatic char _CopyRt[] = "@(#) Copyright (C) 1985 by Brandon S. Allbery @(#)";
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 "ua-edit",
X "/bin/sh",
X 1,
X "unaxcess",
X 30,
X "sysop",
X 1,
X 0,
X "",
X "",
X 1,
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 -rb",
X "umodem -sb",
X "kermit -iwr",
X "kermit -iws",
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 "x-rated", BOOL, &parms.ua_xrc,
X "editor", STR, parms.ua_edit,
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 "pauses", NUM, &parms.ua_hco,
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 0, 0, 0,
X};
X
X/*
X * 1. Get home directory
X * 2. Open $HOME/uaconfig
X * 3. Parse lines; # is a comment, input form is KEYWORD VALUE
X * VALUE is numeric, Y/N, "string" and backslash escapes for
X * \n \t \r \b \f \e \nnn are understood
X * 4. Assign the values to the parms structure
X */
X
Xstatic char line[512], var[20], sval[50];
X
Xgetparms() {
X char home[512];
X FILE *cfp;
X short nval, 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 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 - dir.c'
sed 's/^X//' <<'________This_Is_The_END________' >>dir.c
X/*
X *
X * N O T I C E
X *
X * This file is NOT a copyrighted part of the UNaXcess distribution. These
X * are directory-reading routines which are compatible with the Berkeley Unix
X * (4.2BSD, 4.3BSD) directory routines. They come from the Usenet news
X * distribution and are in the public domain.
X *
X * To get the best use of them: install the file "dir.h" in /usr/include
X * -- standard usage calls it "ndir.h", and make a random archive of dir.o and
X * put it in /usr/lib/libndir.a . It is then available with "-lndir".
X *
X * Bell System {III, V} sites, just make an archive -- it is only one file
X * anyway. Other sites will have to run ranlib on the archive to keep ld
X * happy.
X */
X
X#include <sys/types.h>
X#include "dir.h"
X
X#ifndef BSD
X
X/*
X * close a directory.
X */
Xclosedir(dirp)
X register DIR *dirp;
X{
X close(dirp->dd_fd);
X dirp->dd_fd = -1;
X dirp->dd_loc = 0;
X free(dirp);
X}
X
X
X
X/*
X * open a directory.
X */
XDIR *
Xopendir(name)
X char *name;
X{
X register DIR *dirp;
X register int fd;
X
X if ((fd = open(name, 0)) == -1)
X return NULL;
X if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
X close (fd);
X return NULL;
X }
X dirp->dd_fd = fd;
X dirp->dd_loc = 0;
X return dirp;
X}
X
X
X
X/*
X * read an old style directory entry and present it as a new one
X */
X#define ODIRSIZ 14
X
Xstruct olddirect {
X ino_t od_ino;
X char od_name[ODIRSIZ];
X};
X
X/*
X * get next entry in a directory.
X */
Xstruct direct *
Xreaddir(dirp)
X register DIR *dirp;
X{
X register struct olddirect *dp;
X static struct direct dir;
X
X for (;;) {
X if (dirp->dd_loc == 0) {
X dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
X DIRBLKSIZ);
X if (dirp->dd_size <= 0)
X return NULL;
X }
X if (dirp->dd_loc >= dirp->dd_size) {
X dirp->dd_loc = 0;
X continue;
X }
X dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
X dirp->dd_loc += sizeof(struct olddirect);
X if (dp->od_ino == 0)
X continue;
X dir.d_ino = dp->od_ino;
X strncpy(dir.d_name, dp->od_name, ODIRSIZ);
X dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
X dir.d_namlen = strlen(dir.d_name);
X dir.d_reclen = DIRBLKSIZ;
X return (&dir);
X }
X}
X
X#endif BSD
________This_Is_The_END________
exit
--
---------------- /--/ Brandon S. Allbery UUCP:
/ / /|\/ Tridelta Industries, Inc. decvax!cwruecmp!ncoast!
---- -------- /-++ 7350 Corporate Blvd. tdi2!brandon
/ / /---, /--/ Mentor, Ohio 44060 PHONE: (home)
/ / / / / / -- HOME -- +1 216 974 9210
/ / / / / / 6615 Center St. Apt. A1-105 ARPA: ncoast!allbery%
---- /----~ /--/ Mentor, Ohio 44060-4101 case.CSNET at csnet-relay
-------------------------------------------------------------------------------
Space -- The Final Frontier
More information about the Comp.sources.unix
mailing list