allbery@ncoast.UUCP (Brandon S. Allbery) (07/26/86)
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@csnet-relay ------------------------------------------------------------------------------- Space -- The Final Frontier