Path: seismo!harvard!talcott!panda!sources-request From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: UNaXcess (3 of 3) Message-ID: <1654@panda.UUCP> Date: 13 Apr 86 02:37:01 GMT Sender: jpn@panda.UUCP Lines: 1707 Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 67 Submitted by: decvax!cwruecmp!ncoast!allbery #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # ua.c # udl.c # user.c # This archive created: Sat Apr 12 10:03:33 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'ua.c'" '(8606 characters)' if test -f 'ua.c' then echo shar: will not over-write existing file "'ua.c'" else cat << \SHAR_EOF > 'ua.c' /* * %W% %E% %U% ncoast!bsa %Z% * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z% */ #ifndef lint static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%"; static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%"; #endif lint #include "ua.h" struct cmd { char c_ch; /* command character */ char c_desc[33]; /* command description */ int (*c_exec)(); /* command executive */ } ; /* used for command array */ /* forward references for command executives */ extern int readmsg(), readnew(), confidx(), enter(), join(), killmsg(), helpme(), scanmsg(), logout(), bulletin(), linelen(), shell(), userctl(), userlist(), qscan(), udl(), unsub(), setlconf(); struct cmd cmdt[] = { '?', "Print help messages", helpme, 'a', "Alter or examine a user", userctl, 'b', "Reprint login bulletins", bulletin, 'c', "Shell command access", shell, 'd', "Set default login conference", setlconf, 'e', "Enter a message", enter, 'f', "File area (Downloading)", udl, 'g', "Exit UNaXcess", logout, 'h', "Print help messages", helpme, 'i', "Index of conferences", confidx, 'j', "Join a new conference", join, 'k', "Kill a message", killmsg, 'l', "Set line length", linelen, 'n', "Read all new messages", readnew, 'q', "Quick scan of messages", qscan, 'r', "Read messages in a conference", readmsg, 's', "Scan messages", scanmsg, 'u', "Unsubscribe from a conference", unsub, 'w', "List of UNaXcess users", userlist, NULL,NULL, NULL }; int nopause; jmp_buf cmdloop; main(argc, argv) char **argv; { char line[256], *lp; short lcnt; FILE *tp; getparms(); chdir(parms.ua_home); logon(); if (parms.ua_hco == 1) { printf("\nDo you wish me to stop every few lines to let you read messages (Y)? "); gets(line); log("Pause? %s", line); } if (parms.ua_hco == 0 || (parms.ua_hco == 1 && ToLower(line[0]) != 'n')) nopause = 0; else nopause = 1; alarm(parms.ua_tlimit * 60); /* time limit */ signal(SIGINT, SIG_IGN); signal(SIGQUIT, quit); for (lcnt = 4; lcnt < SIGUSR1; lcnt++) /* we don't muck with others */ signal(lcnt, logsig); signal(SIGALRM, thatsall); if (parms.ua_bnr[0] == '\0') puts("\nWelcome to UNaXcess Version 0.04.03 (pre-release)\nCopyright (C) 1984, 1985 by Brandon Allbery"); else cat(parms.ua_bnr); if (argc > 2) { puts("To run UNaXcess from the shell, type `ua' or `ua username'.\nIf username has spaces or shell metacharacters in it, quote it.\n"); log("Invoked with %d arguments. Goodbye.", argc); exit(1); } else argc--; if (parms.ua_bbs[0] != '\0' && strcmp(getlogin(), parms.ua_bbs) == 0) { nouser: for (lcnt = 0; lcnt != 3; lcnt++) { if (argc) { strcpy(line, argv[1]); argc--; putchar('\n'); } else { if (parms.ua_login[0] == 0) printf("\nEnter your user name, GUEST, OFF, or NEW: "); else fputs(parms.ua_login, stdout); gets(line); } log("Login: %s", line); if (line[0] == '\0') { lcnt--; continue; } for (lp = line; *lp != '\0'; lp++) *lp = ToLower(*lp); if (strcmp(line, "off") == 0) { puts("Goodbye...\n\n"); log("Logout."); exit(0); } if (!getuser(line, &user)) { printf("No such user.\n"); log("No such user."); } else if (user.u_pass[0] != '\0') { strcpy(line, getpass("Enter your password: ")); log("Password: %s", line); puts("\nChecking password..."); if (strcmp(crypt(line, line) + 2, user.u_pass) == 0) break; } else break; } if (parms.ua_nla > 0 && lcnt == parms.ua_nla) { puts("\nSorry, you blew it."); log("Program aborted."); exit(1); } } else if (!getuser(getlogin(), &user)) goto nouser; log("%s, access = %d, sys = %s, line = %d", user.u_name, user.u_access, user.u_login, user.u_llen); if (user.u_access == A_NONE) { puts("Your access privileges have been revoked. Goodbye...\n\n"); log("Security violation: access revoked."); exit(1); } if ((tp = fopen(RIndex(ttyname(fileno(stdin)), '/') + 1, "w")) == NULL) { log("Error %d opening %s", errno, RIndex(ttyname(fileno(stdin)), '/') + 1); log("Non-interactive session not logged to terminal."); } else { fprintf(tp, "%s on as \"%s\" on %s\n", getlogin(), user.u_name, longdate()); fclose(tp); } putchar('\n'); if (user.u_access != A_MKUSER) bulletin(NULL); umask(0); /* so xedit() works */ if (user.u_lconf[0] != '\0') if (isconf(user.u_lconf)) strcpy(conference, user.u_lconf); else { putchar('\n'); for (lp = parms.ua_sysop; *lp != '\0'; lp++) putchar(ToUpper(*lp)); printf(" deleted \"%s\", your login conference. I'm setting you\nback to the \"general\" conference.\n", user.u_lconf); user.u_lconf[0] = '\0'; strcpy(conference, "general"); } else strcpy(conference, "general"); hicnts = readhigh(&user); cleanhigh(); /* kill any lingering corpses */ if (!setjmp(cmdloop)) signal(SIGINT, intrp); while (cmd()) ; printf("Goodbye, "); for (lp = user.u_name; *lp != '\0'; lp++) putchar(ToUpper(*lp)); printf(". Call again soon!\n\n\n"); log("Logout."); cleanup(); } cleanup() { char tmps[256]; FILE *fp; sprintf(tmps, "%s/himotd", MOTD); if ((fp = fopen(tmps, "r")) == NULL) { log("Error %d opening %s", errno, tmps); panic("himotd"); } fgets(tmps, 32, fp); fclose(fp); user.u_nbull = atoi(tmps); putuser(user.u_name, &user); unlink(RIndex(ttyname(2), '/') + 1); exit(0); } cmd() { char line[256], *p; struct cmd *cmdp; if (user.u_access == A_MKUSER) { newuser(); if (user.u_access == A_NONE) { puts("\nYou'll have to be validated before you can use UNaXcess."); return 0; } } printf("\n(%s) Command (? = Help): ", conference); gets(line); log("Command: %s", line); if (line[0] == '\0') return 1; for (p = line; *p != '\0'; p++) *p = ToLower(*p); for (cmdp = cmdt; cmdp->c_ch != NULL; cmdp++) if (ToLower(cmdp->c_ch) == line[0]) return (*cmdp->c_exec)(line); puts("Type '?' for help."); log("No such command."); return 1; } logout() { char line[256]; printf("Are you sure you want to log out (N)? "); gets(line); log("Logout? %s", line); return (ToLower(line[0]) != 'y'); } helpme() { short lcnt; struct cmd *cmdp; putchar('\n'); lcnt = 2 * ((user.u_llen < 80) + 1); for (cmdp = cmdt; cmdp->c_ch != NULL; cmdp++) { printf("%c - %-32.32s", ToUpper(cmdp->c_ch), cmdp->c_desc); lcnt++; if (user.u_llen < 80 || !(lcnt % 2)) putchar('\n'); if ((lcnt / 2) % (user.u_llen >= 80? 32: 16) == 0) if (!cont()) break; } if (user.u_llen >= 80 && lcnt % 2 != 0) putchar('\n'); puts("\nIf you need further help, look for (or ask for) a HELP conference."); return 1; } linelen(s) char *s; { int llen; char line[256], *p; p = s; while (*p != '\0') if (*p++ == ' ') if ((llen = atoi(p)) > 40 && llen < 132) { printf("New line length = %d.\n", llen); user.u_llen = llen; putuser(user.u_name, &user); return 1; } else break; llen = 0; while (llen < 40 || llen > 132) { printf("\nEnter new line length (40-132): "); gets(line); llen = atoi(line); } return 1; } cont() { char ch; if (!isatty(0) || nopause) return 1; printf("More (Y)? "); silent(); ch = getchar(); talk(); log("Cont? %c", ch); printf("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b"); return (RIndex(" Yy\r\n", ch) != NULL); } cat(file) char *file; { FILE *f; char ch; short lcnt, ccnt; if ((f = fopen(file, "r")) == NULL) { log("Error %d opening %s", errno, file); puts("Cannot open file."); return; } lcnt = ccnt = 0; while ((ch = getc(f)) != EOF) { if (ch == '\n') { putchar(ch); ccnt = 0; if (++lcnt % 16 == 0) if (!cont()) break; } else if (ch == '\t') putchar('\t'); else { if (iscntrl(ch)) putchar('.'); else putchar(ch); if (++ccnt == (user.u_llen<40? 80: user.u_llen) - 1) { ccnt = 0; putchar('\n'); if (++lcnt % 16 == 0) if (!cont()) break; } } } fclose(f); } SHAR_EOF if test 8606 -ne "`wc -c < 'ua.c'`" then echo shar: error transmitting "'ua.c'" '(should have been 8606 characters)' fi fi echo shar: extracting "'udl.c'" '(15435 characters)' if test -f 'udl.c' then echo shar: will not over-write existing file "'udl.c'" else cat << \SHAR_EOF > 'udl.c' /* * %W% %E% %U% ncoast!bsa %Z% * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z% */ #ifndef lint static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%"; static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%"; #endif lint #include "ua.h" #ifdef BSD #include #else SYS3 #include #endif BSD #define A_UPLOAD parms.ua_auc #define A_DOWNLOAD parms.ua_adc #define X_UPLOAD parms.ua_xuc #define X_DOWNLOAD parms.ua_xdc #define K_UPLOAD parms.ua_kuc #define K_DOWNLOAD parms.ua_kdc #define LIBRARY "library" #define DIRECTORY "directory" #define STORAGE "uploads" #define UPLOG "upload-log" #define off 0 #define on 1 #define pager __col = 0, __line = 0, __Page = #define DIRFORMAT "%[^ ] %*1[Ff]%*1[Ii]%*1[Ll]%*1[Ee] %[^;]; %[^ ] %*1[Bb]%*1[Yy] %[^:]: %[^\n]" jmp_buf brchloop, fileloop; static char thisbrch[80] = ""; int __Page = on; int __line = 0; int __col = 0; int __paws = off; char *whatis(), *pgetin(), *cpmform(), *upstr(), *today(); extern struct tm *localtime(); udl(branch) char *branch; { int again(); int (*oldint)(); char *cp; if (user.u_access < A_FILES) { puts("\nYou will not be able to upload or download files.\nYou may, however, download File Lists."); log("File Section entered; access restricted"); } thisbrch[0] == '\0'; for (cp = branch; *cp != '\0'; cp++) if (*cp == ' ') { strcpy(thisbrch, ++cp); break; } oldint = signal(SIGINT, again); setjmp(brchloop); while (libmenu()) ; msg("\n"); signal(SIGINT, oldint); } again() { signal(SIGINT, again); pager on; msg("\nInterrupt\n"); fflush(stdout); log("Interrupt"); if (__paws == on) { talk(); __paws = off; } longjmp(brchloop, 1); } libmenu() { struct direct *branch; DIR *library; char cmd[512], bname[512]; int (*oldsig)(); int brch_cmd(); char *desc; if ((library = opendir(LIBRARY)) == NULL) { msg("The Library is closed\n"); return 0; } if (thisbrch[0] != '\0') { strcpy(cmd, thisbrch); thisbrch[0] == '\0'; goto gotbrch; } msg("\nThe UNaXcess File Section. Please select one of the following\nbranches, or EXIT to leave the Library.\n\n"); while ((branch = readdir(library)) != NULL) { if ((desc = whatis(branch->d_name, NULL)) == NULL) continue; msg(" %-8.8s %s\n", upstr(branch->d_name), desc); } closedir(library); msg("\nBranch: "); if (pgetin(cmd, NULL) == NULL) return 0; log("Branch: %s", cmd); if (s_cmp(cmd, "EXIT") == 0) return 0; gotbrch: if (whatis(cmd, NULL) != NULL) { library = opendir(LIBRARY); while ((branch = readdir(library)) != NULL) if (s_cmp(branch->d_name, cmd) == 0) { closedir(library); strcpy(bname, branch->d_name); oldsig = signal(SIGINT, brch_cmd); setjmp(fileloop); while (visit(bname)) ; signal(SIGINT, oldsig); return 1; } } closedir(library); msg("There is no such branch. If you wish to open a new branch,\nleave a message to %s.\n", parms.ua_sysop); return 1; } visit(branch) char *branch; { char cmd[512]; DIR *directory; sprintf(cmd, "%s/%s", LIBRARY, branch); if ((directory = opendir(cmd)) == NULL) { msg("The %s branch is closed.\n", upstr(branch)); return 0; } closedir(directory); msg("\n%s Branch\nUpload, Download, List of Files, Get File List, Exit: ", upstr(branch)); if (pgetin(cmd, NULL) == NULL) return 0; log("Branch cmd: %s", cmd); switch (cmd[0]) { case 'e': case 'E': return 0; case 'U': case 'u': upload(branch); break; case 'D': case 'd': download(branch); break; case 'L': case 'l': filelist(branch); break; case 'G': case 'g': getlist(branch); break; default: msg("Unrecognized command.\n"); } return 1; } brch_cmd() { pager on; msg("\nInterrupt\n"); log("Interrupt"); fflush(stdout); if (__paws == on) { talk(); __paws = off; } signal(SIGINT, brch_cmd); longjmp(fileloop, 1); } filelist(branch) char *branch; { char path[512]; DIR *directory; struct direct *file; char *desc; sprintf(path, "%s/%s", LIBRARY, branch); directory = opendir(path); msg("\nFile Directory for the %s Branch:\n\n", upstr(branch)); while ((file = readdir(directory)) != NULL) { if ((desc = whatis(branch, file->d_name)) == NULL) continue; msg(" %-12.12s %s\n", cpmform(file->d_name), desc); } msg("\n"); closedir(directory); } getlist(branch) char *branch; { char path[512], listfile[30], cmd[512]; DIR *directory; struct direct *file; int (*oldsig)(); char *desc; FILE *list; sprintf(listfile, "/tmp/cli%05d", getpid()); if ((list = fopen(listfile, "w")) == NULL) { msg("Can't open temporary list file???\n"); exit(5); } msg("\nDownload file listing from the %s branch\n\nSupported transfer protocols are: Ascii, Xmodem, and Kermit.\nXmodem protocol uses checksums; CCITT CRC is not supported.\n\nEnter File Transfer Protocol (XMODEM default): ", upstr(branch)); if (pgetin(cmd, NULL) == NULL) return; log("List dnld mode: %s", cmd); switch (cmd[0]) { case 'A': case 'a': if (!validudl(A_DOWNLOAD)) { msg("\nAscii Download is not supported.\n"); log("No Ascii"); return; } sprintf(cmd, A_DOWNLOAD, listfile); break; case 'K': case 'k': if (!validudl(K_DOWNLOAD)) { msg("\nKermit Download is not supported.\n"); log("No Kermit"); return; } sprintf(cmd, K_DOWNLOAD, listfile); break; case 'X': case 'x': if (!validudl(X_DOWNLOAD)) { msg("\nXModem Download is not supported.\n"); log("No Xmodem"); return; } sprintf(cmd, X_DOWNLOAD, listfile); break; case '\0': cmd[0] = 'X'; if (!validudl(X_DOWNLOAD)) { msg("\nXModem Download is not supported.\n"); log("No Xmodem"); return; } sprintf(cmd, X_DOWNLOAD, listfile); break; default: msg("Invalid protocol designation.\n"); return; } sprintf(path, "%s/%s", LIBRARY, branch); directory = opendir(path); fprintf(list, "File Directory for the %s Branch:\r\n\r\n", upstr(branch)); while ((file = readdir(directory)) != NULL) { if ((desc = whatis(branch, file->d_name)) == NULL) continue; fprintf(list, " %-12.12s %s\r\n", cpmform(file->d_name), desc); } fclose(list); closedir(directory); msg("You have 30 seconds to prepare for file transmission.\nPress BREAK to abort transmission.\n\n"); fflush(stdout); sleep(30); oldsig = signal(SIGINT, SIG_IGN); system(cmd); #ifdef SYS3 system("stty echoe"); #endif SYS3 signal(SIGINT, oldsig); unlink(listfile); } download(branch) char *branch; { char path[512], filename[512], cmd[512]; DIR *directory; struct direct *file; int (*oldsig)(); if (user.u_access < A_FILES) { log("Attempted download, access denied."); puts("You may not download files."); return; } msg("\nDownload from the %s branch\n\nEnter file to download: "); if (pgetin(filename, NULL) == NULL) return; log("Dnld file: %s", filename); if (filename[0] == '.' || Index(filename, '/') != NULL) { msg("No such file: \"%s\"\n", upstr(filename)); return; } if (whatis(branch, filename) != NULL) { sprintf(path, "%s/%s", LIBRARY, branch); directory = opendir(path); while ((file = readdir(directory)) != NULL) { if (s_cmp(file->d_name, filename) == 0) { closedir(directory); sprintf(path, "%s/%s/%s", LIBRARY, branch, file->d_name); msg("Supported transfer protocols are: Ascii, Xmodem, and Kermit.\nXmodem protocol uses checksums; CCITT CRC is not supported.\n\nEnter File Transfer Protocol (XMODEM default): ", upstr(branch)); if (pgetin(cmd, NULL) == NULL) return; switch (cmd[0]) { case 'A': case 'a': if (!validudl(A_DOWNLOAD)) { msg("\nAscii Download is not supported.\n"); log("No Ascii"); return; } sprintf(cmd, A_DOWNLOAD, path); break; case 'K': case 'k': if (!validudl(K_DOWNLOAD)) { msg("\nKermit Download is not supported.\n"); log("No Kermit"); return; } sprintf(cmd, K_DOWNLOAD, path); break; case 'X': case 'x': if (!validudl(X_DOWNLOAD)) { msg("\nXModem Download is not supported.\n"); log("No Xmodem"); return; } sprintf(cmd, X_DOWNLOAD, path); break; case '\0': cmd[0] = 'X'; if (!validudl(X_DOWNLOAD)) { msg("\nXModem Download is not supported.\n"); log("No Xmodem"); return; } sprintf(cmd, X_DOWNLOAD, path); break; default: msg("Invalid protocol designation.\n"); return; } msg("You have 30 seconds to prepare for file transmission.\nPress BREAK to abort transmission.\n\n"); fflush(stdout); sleep(30); oldsig = signal(SIGINT, SIG_IGN); system(cmd); #ifdef SYS3 system("stty echoe"); #endif SYS3 signal(SIGINT, oldsig); return; } } closedir(directory); } msg("No such file: \"%s\"\n", upstr(filename)); log("No such file"); } upload(branch) char *branch; { char path[512], filename[512], cmd[512], desc[512]; DIR *directory; struct direct *file; int (*oldsig)(); FILE *logf; if (user.u_access < A_FILES) { log("Attempted upload, access denied."); puts("You may not upload files."); return; } msg("\nUpload to the %s branch\n\nEnter the name to give the new file: "); if (pgetin(filename, NULL) == NULL) return; log("Upld file: %s", filename); if (filename[0] == '.' || Index(filename, '/') != NULL || Index(filename, ';') != NULL) { msg("Invalid filename: \"%s\"\n", upstr(filename)); log("Invalid filename"); return; } sprintf(path, "%s/%s", STORAGE, branch); if ((directory = opendir(path)) == NULL) { msg("The %s has denied upload ability for this branch.\n", parms.ua_sysop); return; } while ((file = readdir(directory)) != NULL) { if (s_cmp(file->d_name, filename) == 0) { closedir(directory); msg("That file name is used. Please try again with a different filename.\n"); log("File exists"); return; } } closedir(directory); msg("Enter a description for the file: "); if (pgetin(desc, NULL) == NULL) return; log("Description: %s", desc); if ((logf = fopen(UPLOG, "a")) == NULL) { log("Error %d opening %s", errno, UPLOG); msg("Can't log the new file.\n"); return; } fprintf(logf, "%s file %s; %s by %s: %s\n", branch, filename, today(), upstr(user.u_name), desc); fclose(logf); sprintf(path, "%s/%s/%s", STORAGE, branch, filename); msg("Supported transfer protocols are: Ascii, Xmodem, and Kermit.\nXmodem protocol uses checksums; CCITT CRC is not supported.\n\nEnter File Transfer Protocol (XMODEM default): ", upstr(branch)); if (pgetin(cmd, NULL) == NULL) return; log("Upld protocol: %s", cmd); switch (cmd[0]) { case 'A': case 'a': if (!validudl(A_UPLOAD)) { msg("\nAscii Upload is not supported.\n"); log("No Ascii"); return; } sprintf(cmd, A_UPLOAD, path); break; case 'K': case 'k': if (!validudl(K_UPLOAD)) { msg("\nKermit Upload is not supported.\n"); log("No Kermit"); return; } sprintf(cmd, K_UPLOAD, path); break; case 'X': case 'x': if (!validudl(X_UPLOAD)) { msg("\nXModem Upload is not supported.\n"); log("No Xmodem"); return; } sprintf(cmd, X_UPLOAD, path); break; case '\0': cmd[0] = 'X'; if (!validudl(X_UPLOAD)) { msg("\nXModem Upload is not supported.\n"); log("No Xmodem"); return; } sprintf(cmd, X_UPLOAD, path); break; default: msg("Invalid protocol designation.\n"); return; } msg("You have 30 seconds to prepare for file transmission.\nPress BREAK to abort transmission.\n\n"); fflush(stdout); sleep(30); oldsig = signal(SIGINT, SIG_IGN); system(cmd); #ifdef SYS3 system("stty echoe"); #endif SYS3 signal(SIGINT, oldsig); } /* * The following code is snarfed from UNaXcess V1.0, primarily as a test. * Some audacious soul may want to backport this to the rest of UA... */ msg(argp) int *argp; { int **ap; char buf[BUFSIZ]; FILE prwbuf; register int *fp; register char *cp; #ifdef USE_PRINT extern FILE *_pfile; #endif USE_PRINT ap = &argp; ap++; prwbuf._flag = _IOWRT|_IOSTRG; prwbuf._cnt = 32767; prwbuf._ptr = buf; prwbuf._base = buf; fp = *(ap - 1); #ifdef USE_PRINT _pfile = &prwbuf; _print(fp, &ap); #else USE_PRINT argp++; _doprnt(fp, &argp, &prwbuf); #endif USE_PRINT putc('\0', &prwbuf); for (cp = buf; *cp != '\0'; cp++) say(*cp); } say(ch) char ch; { ch &= 0x7f; switch (ch) { case '\t': do { say(' '); } while (__col % 8); break; case '\n': putchar('\n'); __col = 0; if (__Page == on && ++__line == 23) { paws(); __line = 0; } break; case '\177': msg("^?"); break; default: if (ch < ' ') { say('^'); say(ch + '@'); return; } if (__col == user.u_llen - 1) say('\n'); putchar(ch); __col++; } } paws() { fputs("Type any key to continue. . .", stdout); __paws = on; silent(); getchar(); talk(); __paws = off; fputs("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b", stdout); } s_cmp(s1, s2) char *s1, *s2; { for (; *s1 != '\0' && ToLower(*s1) == ToLower(*s2); s1++, s2++) ; return (!(*s1 == '\0' && *s2 == '\0')); } char *whatis(branch, file) char *branch, *file; { static FILE *directory = NULL; static char dent[512]; char tbr[512], tfi[512], date[512], who[512], desc[512]; if (directory != NULL || (directory = fopen(DIRECTORY, "r")) != NULL) { fseek(directory, 0L, 0); while (fgets(dent, sizeof dent, directory) != NULL) { if (dent[0] == '%' || dent[0] == '\n') continue; tbr[0] = '\0'; tfi[0] = '\0'; date[0] = '\0'; who[0] = '\0'; desc[0] = '\0'; sscanf(dent, DIRFORMAT, tbr, tfi, date, who, desc); if (s_cmp(tbr, branch) == 0) { if (s_cmp(tfi, (file == NULL? "branch": file)) != 0) continue; sprintf(dent, "%s [Created %s by %s]", desc, date, who); return dent; } } } log("No download directory"); return NULL; } /* this is a stub-ified version of v1.0 COMND input module */ char *pgetin(str, tab) char *str; char tab[]; { char *ch; fflush(stdout); pager off; ch = gets(str); pager on; if (ch == NULL) { msg("^D\n"); log("EOF"); fflush(stdout); } return ch; } char *cpmform(fn) char *fn; { static char buf[13]; register int cnt, scnt; for (scnt = 0, cnt = 0; cnt < 8 && fn[cnt] != '.' && fn[cnt] != '\0'; cnt++, scnt++) buf[scnt] = ToUpper(fn[cnt]); while (scnt < 8) buf[scnt++] = ' '; buf[scnt++] = '.'; while (fn[cnt] != '.' && fn[cnt] != '\0') cnt++; if (fn[cnt] == '.') cnt++; while (scnt < 12 && fn[cnt] != '\0') { buf[scnt++] = ToUpper(fn[cnt]); cnt++; } buf[scnt] = '\0'; return buf; } char *upstr(s) char *s; { static char sbuf[512]; register char *cp, *dp; for (cp = s, dp = sbuf; *cp != '\0'; cp++, dp++) *dp = ToUpper(*cp); *dp = '\0'; return sbuf; } char *today() { long now; struct tm *date; static char buf[11]; time(&now); date = localtime(&now); sprintf(buf, "%d/%d/%d", date->tm_mon + 1, date->tm_mday, date->tm_year); return buf; } validudl(cmd) char *cmd; { if (cmd[0] == '\0') return 0; if (Index(cmd, '%') != RIndex(cmd, '%')) return 0; if (Index(cmd, '%') == (char *) 0) { strcat(cmd, " %s"); return 1; } if (*(Index(cmd, '%') + 1) != 's') return 0; return 1; } SHAR_EOF if test 15435 -ne "`wc -c < 'udl.c'`" then echo shar: error transmitting "'udl.c'" '(should have been 15435 characters)' fi fi echo shar: extracting "'user.c'" '(16898 characters)' if test -f 'user.c' then echo shar: will not over-write existing file "'user.c'" else cat << \SHAR_EOF > 'user.c' /* * %W% %E% %U% ncoast!bsa %Z% * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z% */ #ifndef lint static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%"; static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%"; #endif lint #include "ua.h" struct user user; struct _himsg *hicnts; getuser(name, buf) char *name; struct user *buf; { FILE *bfd; char line[1024], lcuname[33], *p, *q; if ((bfd = fopen(PASSWD, "r")) == NULL) { log("Error %d opening %s", errno, PASSWD); panic("passwd"); } for (p = name, q = lcuname; *p != '\0' && p - name <= 32; p++, q++) *q = ToLower(*p); *q = '\0'; while (fgets(line, sizeof line, bfd) != NULL) if (strncmp(line, lcuname, strlen(lcuname)) == 0 && line[strlen(lcuname)] == ':') { fclose(bfd); buf->u_name[0] = '\0'; buf->u_pass[0] = '\0'; buf->u_access = 0; buf->u_login[0] = '\0'; buf->u_llen = 0; buf->u_nbull = 0; buf->u_lconf[0] = '\0'; #ifndef SYS3 /* jpn - this used to be a scanf that didn't work on BSD */ pwparse(line, buf); #else sscanf(line, "%[^:]:%[^:]:%hd:%[^:]:%hd:%hd:%[^:]", buf->u_name, buf->u_pass, &buf->u_access, buf->u_login, &buf->u_llen, &buf->u_nbull, buf->u_lconf); #endif buf->u_lconf[strlen(buf->u_lconf) - 1] = '\0'; return 1; } fclose(bfd); return 0; } #ifndef SYS3 pwparse(line, buf) char *line; struct user *buf; { char *index(); register char *p; /* jpn - this used to be a single scanf that didn't work on BSD */ /* because the %[ format MUST match one character to succeed */ p = line; sscanf(p, "%[^:]", buf->u_name); if ((p = index(p, ':')) == 0) return; else ++p; sscanf(p, "%[^:]", buf->u_pass); if ((p = index(p, ':')) == 0) return; else ++p; sscanf(p, "%hd", &buf->u_access); if ((p = index(p, ':')) == 0) return; else ++p; sscanf(p, "%[^:]", buf->u_login); if ((p = index(p, ':')) == 0) return; else ++p; sscanf(p, "%hd", &buf->u_llen); if ((p = index(p, ':')) == 0) return; else ++p; sscanf(p, "%hd", &buf->u_nbull); if ((p = index(p, ':')) == 0) return; else ++p; sscanf(p, "%[^:]", buf->u_lconf); } #endif putuser(name, ubuf) char *name; struct user *ubuf; { FILE *fd, *tfd; char line[1024], *tempfile = mktemp("/tmp/UptXXXXXX"), lcname[33], *p, *q; static char lockfile[] = "userfil.lock"; short flag; CRIT(); mklock(lockfile); if ((fd = fopen(PASSWD, "r")) == NULL) { log("Error %d opening %s", errno, PASSWD); panic("passwd"); } if ((tfd = fopen(tempfile, "w")) == NULL) { log("Error %d opening %s", errno, tempfile); panic("tmp"); } flag = 0; for (p = name, q = lcname; *p != '\0' && p - name < 33; p++, q++) *q = ToLower(*p); *q = 0; while (fgets(line, sizeof line, fd) != NULL) if (strncmp(line, lcname, strlen(lcname)) == 0 && line[strlen(lcname)] == ':') { 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)); flag++; } else fputs(line, tfd); if (!flag) 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)); fclose(fd); fclose(tfd); unlink(PASSWD); if (copylink(tempfile, PASSWD) < 0) { log("Error %d copylinking %s to %s", errno, tempfile, PASSWD); panic("copylink"); } unlink(tempfile); rmlock(lockfile); NOCRIT(); } writehigh(hilist) struct _himsg *hilist; { FILE *hp, *f; static char line[1024], hirec[1024]; /* 68000's have limited frames */ char *tmpf = mktemp("/tmp/RcXXXXXX"); char *eofflag; static char lockfile[] = "newmsgs.lock"; struct _himsg *hptr; if (s_cmp(user.u_name, "guest") == 0) return; /* don't write GUEST hirecs! */ CRIT(); if ((f = fopen(tmpf, "w")) == NULL) { log("Error %d opening %s", errno, tmpf); panic("tmp"); } if ((hp = fopen(NEWMSGS, "r")) == NULL) { log("Error %d opening %s", errno, NEWMSGS); fclose(f); unlink(tmpf); panic("userind"); } mklock(lockfile); sprintf(line, "%s:", user.u_name); while ((eofflag = fgets(hirec, sizeof hirec, hp)) != NULL) { if (strncmp(hirec, line, strlen(line)) == 0) break; fputs(hirec, f); } if (!eofflag) while ((eofflag = fgets(hirec, sizeof hirec, hp)) != NULL) if (hirec[0] != '\t' && hirec[0] != ' ') break; fputs(line, f); putc('\n', f); for (hptr = hilist; hptr != NULL; hptr = hptr->hi_next) fprintf(f, "\t%s%c %d\n", hptr->hi_conf, (hptr->hi_uns == HI_UNSUB? '!': ':'), hptr->hi_num); if (!eofflag && hirec[0] != '\t' && hirec[0] != ' ') fputs(hirec, f); if (!eofflag) while (fgets(hirec, sizeof hirec, hp) != NULL) fputs(hirec, f); fclose(f); fclose(hp); unlink(NEWMSGS); if (copylink(tmpf, NEWMSGS) < 0) { log("Error %d copylinking %s to %s", errno, tmpf, NEWMSGS); panic("copylink"); } unlink(tmpf); rmlock(lockfile); NOCRIT(); } struct _himsg *readhigh(foruser) struct user *foruser; { static char hirec[1024]; char uidx[40], *p, *q; FILE *f; struct _himsg *workp, *initp, *lastp; strcpy(uidx, foruser->u_name); strcat(uidx, ":"); if ((f = fopen(NEWMSGS, "r")) == NULL) return NULL; while (fgets(hirec, sizeof hirec, f) != NULL) if (strncmp(hirec, uidx, strlen(uidx)) == 0) break; if (feof(f)) { fclose(f); return NULL; } workp = NULL; initp = NULL; while (fgets(hirec, sizeof hirec, f) != NULL && (hirec[0] == ' ' || hirec[0] == '\t')) { hirec[strlen(hirec) - 1] = '\0'; for (p = hirec; *p == ' ' || *p == '\t'; p++) ; for (q = uidx; *p != ' ' && *p != '\t' && *p != '\0' && *p != ':' && *p != '!'; p++) *q++ = *p; *q = '\0'; while (*p == ' ' || *p == '\t') p++; if (*p == '!') { /* unsubscribed... */ if ((workp = (struct _himsg *) calloc((unsigned) 1, sizeof (struct _himsg))) == NULL) { log("Error %d allocating _himsg for %s", errno, uidx); panic("alloc"); } strcpy(workp->hi_conf, uidx); workp->hi_num = atoi(++p); workp->hi_next = initp; workp->hi_uns = HI_UNSUB; initp = workp; continue; } if (*p != ':') { log("Invalid format of userind record: ``%s''", hirec); puts("Your index is garbled; some conference\nhigh-message counts may be lost."); break; } if ((workp = (struct _himsg *) calloc((unsigned) 1, sizeof (struct _himsg))) == NULL) { log("Error %d allocating _himsg for %s", errno, uidx); panic("alloc"); } strcpy(workp->hi_conf, uidx); workp->hi_num = atoi(++p); workp->hi_next = initp; workp->hi_uns = HI_SUBSCR; initp = workp; } fclose(f); return initp; } newuser() { struct user nubuf, junk; char line[256], *p; log("Entered newuser module."); cat(NEWUSER); Again: printf("\nDo you still want to become a user (N)? "); gets(line); log("Become user? %s", line); if (ToLower(line[0]) != 'y') return; do { printf("What name would you like to use on this system? It should not be\nmore than 32 letters long: "); gets(line); log("Name: %s", line); if (line[0] == '\0' || line[0] == ' ') { line[0] = '?'; p = line; continue; } for (p = line; *p != '\0'; p++) if (*p == ':') { puts("Sorry, no colons allowed; they cause nasty surprises."); log("Illegal colon in name"); break; } } while (*p != NULL); strncpy(nubuf.u_name, line, 32); nubuf.u_name[32] = '\0'; line[0] = '\0'; do { if (line[0] != 0) puts("You made a typing error."); strcpy(line, getpass("Please enter a password of three to eight characters.\nIt will not be displayed: ")); log("Pass: %s", line); } while (strlen(line) < 3 || strcmp(line, getpass("Please re-enter it, just to make sure: ")) != 0); strcpy(nubuf.u_pass, line); do { printf("How many characters per line are on your terminal?\nPlease enter a number from 40 to 132, or for 80: "); gets(line); log("Line: %s", line); if (line[0] == '\0') nubuf.u_llen = 80; else nubuf.u_llen = atoi(line); } while (nubuf.u_llen < 40 || nubuf.u_llen > 132); printf("\nName:\t%s\nPass:\t%s\nLine:\t%d\n\nIs this correct (N)? ", nubuf.u_name, nubuf.u_pass, nubuf.u_llen); gets(line); log("Okay? %s", line); if (ToLower(line[0]) != 'y') goto Again; puts("Encrypting password, please wait..."); strcpy(nubuf.u_pass, crypt(nubuf.u_pass, nubuf.u_pass) + 2); strcpy(nubuf.u_login, user.u_login);/* default login name ( guest ?) */ nubuf.u_access = user.u_llen; /* since we don't use u_llen here */ nubuf.u_nbull = 0; /* no bulletins read yet */ puts("Recording user information..."); for (p = nubuf.u_name; *p != '\0'; p++) *p = ToLower(*p); if (getuser(nubuf.u_name, &junk)) { puts("Sorry, but that name's already in use. Please choose another."); goto Again; } putuser(nubuf.u_name, &nubuf); user = nubuf; } userctl(s) char *s; { char line[256], *p, *q; struct user ubuf; short cflag, pflag; if (user.u_access != A_WITNESS) { if (strcmp(user.u_name, "guest") == 0) { log("Security violation: userctl by GUEST"); puts("Sorry, but GUEST can't change himself."); return 1; } pflag = 1; log("Userctl by non-Witness; restricting control modes."); puts("Since you're not a Fairwitness, you can only change some things about\nyourself, like your password."); strcpy(line, user.u_name); } else { line[0] = '\0'; pflag = 0; for (p = s; *p != '\0'; p++) if (*p == ' ') { strcpy(line, ++p); break; } if (line[0] == '\0') { printf("Examine which user: "); gets(line); log("User: %s", line); if (line[0] == '\0') return 1; for (p = line; *p != '\0'; p++) *p = ToLower(*p); } line[32] = '\0'; } if (!getuser(line, &ubuf)) if (pflag) { log("Can't locate current user in the userfile."); panic("user"); } else { printf("No such user. Create him (N)? "); strcpy(ubuf.u_name, line); gets(line); log("New user? %s", line); if (ToLower(line[0]) != 'y') return 1; ubuf.u_pass[0] = '\0'; ubuf.u_access = A_USER; ubuf.u_llen = 80; ubuf.u_nbull = 0; cflag = 0; } else if (strlen(ubuf.u_pass) == 0) cflag = 0; else cflag = 1; for (;;) { printf("\nName:\t%s\nPass:\t%s%s\nAccess:\t%s\nLogin:\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, (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": (ubuf.u_access==A_WITNESS? "Fairwitness": "User maker")))))), ubuf.u_login, (ubuf.u_access==A_MKUSER? "DftAxs": "Width"), ubuf.u_llen, ubuf.u_lconf, (ubuf.u_access==A_MKUSER? "Default Access": "Width")); gets(line); log("Change: %s", line); switch (line[0]) { case 'N': case 'n': if (pflag) { log("Security violation: Attempted to change name."); puts("You can't do that."); break; } printf("Enter new name: "); gets(line); log("Name: %s", line); if (line[0] == '\0') break; for (p = line; *p != '\0'; p++) if (*p == ':') { log("Illegal colon in name."); puts("Can't put a colon in a user name."); break; } for (p = line, q = ubuf.u_name; *p != '\0'; p++, q++) *q = ToLower(*p); *q = '\0'; break; case 'P': case 'p': strcpy(line, getpass("Enter new password: ")); if (line[0] == '\0') break; strcpy(ubuf.u_pass, line); cflag = 0; /* it's not encrypted now */ break; case 'A': case 'a': if (pflag) { log("Security violation: Attempted to change access level."); puts("You can't do that."); break; } printf("Access: None, Guest, User, Files, System, Witness, Makeuser? "); gets(line); log("Access: %s", line); if ((ToLower(line[0]) == 'a' || ubuf.u_access == A_WITNESS) && strcmp(user.u_name, SYSOP) != 0) { puts("Sorry, only the sysop can administer Witness privileges."); log("Security violation: WITNESS administering WITNESS"); break; } switch (line[0]) { case 'g': case 'G': ubuf.u_access = A_GUEST; break; case 'n': case 'N': ubuf.u_access = A_NONE; break; case '\0': break; case 'u': case 'U': ubuf.u_access = A_USER; break; case 's': case 'S': ubuf.u_access = A_SYSTEM; break; case 'w': case 'W': ubuf.u_access = A_WITNESS; break; case 'm': case 'M': ubuf.u_access = A_MKUSER; break; case 'f': case 'F': ubuf.u_access = A_FILES; break; default: puts("What? Access unchanged."); } break; case 'L': case 'l': printf("Enter the login name to be used: "); gets(line); log("Login name: %s", line); line[8] = '\0'; strcpy(ubuf.u_login, line); break; case 'D': case 'd': printf("Enter the default login conference: "); gets(line); log("Login conference: %s", line); if (!isconf(line)) puts("That conference doesn't exist."); else if (uisunsub(ubuf.u_name, line)) printf("%s isn't subscribed to %s.\n", ubuf.u_name, line); else strcpy(ubuf.u_lconf, line); break; case 'W': case 'w': if (ubuf.u_access == A_MKUSER) { printf("Default Access: None, Guest, User, Files, System? "); gets(line); log("DftAxs: %s", line); if (ToLower(line[0]) == 'a') { puts("I don't think you really want to make every user a Fairwitness."); log("Security violation: DftAxs == A_WITNESS?"); break; } switch (line[0]) { case 'g': case 'G': ubuf.u_llen = A_GUEST; break; case 'n': case 'N': ubuf.u_llen = A_NONE; break; case '\0': break; case 'u': case 'U': ubuf.u_llen = A_USER; break; case 's': case 'S': ubuf.u_access = A_SYSTEM; break; case 'm': case 'M': puts("Default access is user maker???"); log("Attempted to make default access == MAKEUSER?"); break; case 'f': case 'F': ubuf.u_access = A_FILES; break; default: puts("What? Default access unchanged."); } } else { printf("Enter new line length, 40-132: "); gets(line); log("Line length: %s", line); if (line[0] == '\0') break; ubuf.u_llen = atoi(line); } break; case 'Q': case 'q': printf("Abort user examine, are you sure (N)? "); gets(line); log("Abort? %s", line); if (ToLower(line[0]) != 'y') break; return 1; case 'S': case 's': if (!cflag) { puts("Encrypting password, please wait..."); strcpy(ubuf.u_pass, crypt(ubuf.u_pass, ubuf.u_pass) + 2); } putuser(ubuf.u_name, &ubuf); if (strcmp(ubuf.u_name, user.u_name) == 0) user = ubuf; return 1; default: puts("What? Please enter one of N, P, L, A, D, or S."); } } } userlist() { FILE *bfd; char line[1024], *p; short lcnt; struct user buf; if ((bfd = fopen(PASSWD, "r")) == NULL) { log("Error %d opening %s", errno, PASSWD); panic("passwd"); } puts("\nList of UNaXcess users:\n"); lcnt = 0; while (fgets(line, 1024, bfd) != NULL) { #ifndef SYS3 pwparse(line, &buf); #else sscanf(line, "%[^:]:%[^:]:%hd:%[^:]:%hd", buf.u_name, buf.u_pass, &buf.u_access, buf.u_login, &buf.u_llen); #endif for (p = buf.u_name; *p != NULL; p++) *p = ToUpper(*p); printf("%-32.32s Access: %s\n", buf.u_name, (buf.u_access==A_NONE? "None": (buf.u_access==A_GUEST? "Guest": (buf.u_access==A_USER? "Normal": (buf.u_access==A_WITNESS? "Fairwitness": (buf.u_access==A_SYSTEM? "System": (user.u_access==A_FILES? "Files": "(make a user)"))))))); if (++lcnt % 16 == 0) if (!cont()) break; } fclose(bfd); return 1; } SHAR_EOF if test 16898 -ne "`wc -c < 'user.c'`" then echo shar: error transmitting "'user.c'" '(should have been 16898 characters)' fi fi exit 0 # End of shell archive