home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i047: Account creation/manipulation program, Part07/08
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: Kyle Jones <xanth!kyle>
- Mod.sources: Volume 8, Issue 47
- Archive-name: mcp/Part07
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # If all goes well, you will see the message "End of archive 7 (of 8)."
- # Contents: src/load.c src/main.c src/misc.c src/nitpick src/pwlock.c
- # src/range.c src/range.h src/remove.c src/report.c
- # Wrapped by rs@mirror on Fri Feb 6 15:56:11 1987
- PATH=/bin:/usr/bin:/usr/ucb; export PATH
- echo shar: extracting "'src/load.c'" '(7238 characters)'
- if test -f 'src/load.c' ; then
- echo shar: will not over-write existing file "'src/load.c'"
- else
- sed 's/^X//' >src/load.c <<'@//E*O*F src/load.c//'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/file.h>
- X#include <lastlog.h>
- X#include <strings.h>
- X#include "sysdep.h"
- X#include "macros.h"
- X#include "mem.h"
- X#include "gpa.h"
- X#include "lists.h"
- X#include "account.h"
- X#include "groupmap.h"
- X#include "save.h"
- X#include "sort.h"
- X
- Xaddr makeusername(), gethomedir();
- Xint nlformat(), nfformat(), (*format)(), ModBits;
- Xextern addr DEF_SHELL;
- Xchar *crypt(), *sprintf();
- X
- Xint lineno;
- Xaddr *filev;
- X
- Xloadfile(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X FILE *f;
- X flexaddr p;
- X char line[LONG_BUF];
- X addr user, password, id, dir, *vv;
- X addr *realnamev;
- X addr_t shell[MEDIUM_BUF];
- X struct account *ac;
- X struct groupmap *gm, *gm2;
- X static struct list groups, classes, sigs;
- X int cc, added, gid, uid, i;
- X int totaladded = 0, filesloaded = 0;
- X
- X zerolist(&groups); tmplistadd(&groups);
- X zerolist(&sigs); tmplistadd(&sigs);
- X zerolist(&classes); tmplistadd(&classes);
- X if (c == 1) {
- X filev = get_gpa(8);
- X GetFilenames("Files: ", 8, &cc, filev);
- X if (cc == 0)
- X return;
- X }
- X else
- X filev = &v[1];
- X for (; *filev; filev++) {
- X added = 0;
- X lineno = 1;
- X if (access((char *)*filev, F_OK|R_OK) == -1) {
- X perr((char *)*filev);
- X err1("%s: file load aborted", (char *)*filev);
- X continue;
- X }
- X f = fopen((char *)*filev, "r");
- X if (f == NULL) {
- X perr((char *)*filev);
- X err1("%s: file load aborted", (char *)*filev);
- X continue;
- X }
- X if (hascolon(f)) {
- X err1("%s: file has colons in it! (load aborted)",
- X (char *)*filev);
- X continue;
- X }
- X (void) printf("%s:\n",(char *)*filev);
- X /*
- X * First line should identity the file format
- X */
- X if (fgets(line, BUFSIZ, f) == NULL) {
- X gag("missing format line");
- X gag("file load aborted");
- X continue;
- X }
- X switch (*line) {
- X /* name first format */
- X case 'N':
- X case 'n': format = nfformat; break;
- X /* Id first format */
- X case 'I':
- X case 'i': format = nlformat; break;
- X default:
- X gag1("bad format token \"%.8s\"", line);
- X gag("file load aborted");
- X continue;
- X }
- X lineno++;
- X /*
- X * Second line should be a list of space separated
- X * groups that the added users will be put into
- X * The first group in the list will be the users base
- X * gid group (the group for the gid in the passwd file).
- X * It is an error for this line to be empty.
- X */
- X if (fgets(line, BUFSIZ, f) == NULL) {
- X gag("missing groups line");
- X gag("file load aborted");
- X continue;
- X }
- X parse_line(line, &cc, &vv);
- X if (cc == 0) {
- X gag("groups line empty");
- X gag("file load aborted");
- X continue;
- X }
- X gm = getgmnam((char *)vv[0]);
- X if (!gm) {
- X gag1("%s: no such group", (char *)vv[0]);
- X gag("file load aborted");
- X continue;
- X }
- X gid = gm->gm_gid;
- X for (vv++; *vv; vv++)
- X if (groupexists((char *)*vv))
- X strlistadd(&groups, (char *)*vv);
- X else
- X gag1("%s: no such group", (char *)*vv);
- X lineno++;
- X /*
- X * Third line should be a space separated list of
- X * classes for the users to put in. This line must
- X * be peresent although it is permitted to be empty.
- X */
- X if (fgets(line, BUFSIZ, f) == NULL) {
- X gag("missing classes line");
- X gag("file load aborted");
- X continue;
- X }
- X parse_line(line, &cc, &vv);
- X for (; *vv; vv++)
- X if (classexists((char *)*vv))
- X strlistadd(&classes, (char *)*vv);
- X else
- X gag1("%s: no such class", (char *)*vv);
- X lineno++;
- X /*
- X * Fourth line should be a space separated list of
- X * sigs for the users to put in. This line must
- X * be present although it is permitted to be empty.
- X */
- X if (fgets(line, BUFSIZ, f) == NULL) {
- X gag("missing sigs line");
- X gag("file load aborted");
- X continue;
- X }
- X parse_line(line, &cc, &vv);
- X for (; *vv; vv++)
- X if (sigexists((char *)*vv))
- X strlistadd(&sigs, (char *)*vv);
- X else
- X gag1("%s: no such sig", (char *)*vv);
- X lineno++;
- X /*
- X * Fifth line should contain the name of the shell
- X * the added users should have. This line must be
- X * present but it may be blank.
- X */
- X if (fgets(line, BUFSIZ, f) == NULL) {
- X gag("missing shell line");
- X gag("file load aborted");
- X continue;
- X }
- X parse_line(line, &cc, &vv);
- X if (cc && !fileexists((char *)vv[0])) {
- X gag1("%s: nonexistent shell", (char *)vv[0]);
- X gag("file load aborted");
- X }
- X else if (cc)
- X (void) strcpy((char *)shell, (char *)vv[0]);
- X else
- X (void) strcpy((char *)shell, (char *)DEF_SHELL);
- X lineno++;
- X /*
- X * Lines from here on should be in the format specified
- X * above.
- X */
- X while (fgets(line, LONG_BUF, f) != NULL) {
- X if ((*format)(line, &cc, &realnamev, &id) == 0) {
- X gag("badly formed line");
- X continue;
- X }
- X ac = getacid((char *)id);
- X if (ac) {
- X user = ac->ac_name;
- X (void) orstrlist(&ac->ac_groups, &groups);
- X orstrlist(&ac->ac_classes, &classes)&&
- X ModBits |= AC;
- X orstrlist(&ac->ac_sigs, &sigs)&&
- X ModBits |= AC;
- X for (i=0; i<groups.l_count; i++) {
- X gm2 = getgmnam((char *)groups.l_list[i]);
- X if (instrlist(&gm2->gm_mem, (char *)user))
- X continue;
- X ModBits |= (AC|GR);
- X strlistadd(&gm2->gm_mem, (char *)user);
- X sort_list(&gm2->gm_mem, pstrcmp);
- X }
- X (void) printf("%-12s%s\n", ac->ac_name,
- X ac->ac_realname);
- X continue;
- X }
- X uid = findnextuid(gm->gm_name);
- X if (uid == NOMORE) {
- X gag("no more uids");
- X gag("load terminated");
- X goto nextfile;
- X }
- X user = makeusername(cc, realnamev);
- X p.p_cp = crypt((char *)id, CRYPT_SALT);
- X password = p.p_ap;
- X dir = gethomedir((char *)user, gm->gm_name);
- X addu(uid, gid, user, glob(realnamev), password,
- X id, dir, shell);
- X added++;
- X ac = getacnam((char *)user);
- X (void) orstrlist(&ac->ac_groups, &groups);
- X orstrlist(&ac->ac_classes, &classes)&&ModBits|=AC;
- X orstrlist(&ac->ac_sigs, &sigs)&&ModBits|=AC;
- X for (i=0; i<groups.l_count; i++) {
- X gm2 = getgmnam((char *)groups.l_list[i]);
- X if (instrlist(&gm2->gm_mem, (char *)user))
- X continue;
- X ModBits |= (AC|GR);
- X strlistadd(&gm2->gm_mem, (char *)user);
- X sort_list(&gm2->gm_mem, pstrcmp);
- X }
- X (void) printf("%-12s%s\n", ac->ac_name,
- X ac->ac_realname);
- X }
- X nextfile:
- X (void) printf("%s: %d added\n", *filev, added);
- X filesloaded++;
- X totaladded += added;
- X freelist(&groups);
- X freelist(&sigs);
- X freelist(&classes);
- X }
- X if (totaladded) {
- X (void) printf("%d file%s loaded, %d user%s added\n",
- X filesloaded, S(filesloaded),
- X totaladded, S(totaladded));
- X#ifndef DOFILES
- X err("Don't forget to create directories for these users.");
- X#endif
- X }
- X return;
- X}
- X
- Xint
- Xhascolon(f)
- XFILE *f;
- X
- X{
- X int c;
- X
- X rewind(f);
- X while ((c = getc(f)) != EOF)
- X if (c == ':') {
- X rewind(f);
- X return 1;
- X }
- X rewind(f);
- X return 0;
- X}
- X
- Xint
- Xnfformat(line, cc, r, id)
- Xchar *line;
- Xint *cc;
- Xaddr **r;
- Xaddr *id;
- X
- X{
- X int c;
- X addr *v;
- X
- X parse_line(line, &c, &v);
- X if (c < 2)
- X return 0;
- X *id = v[c-1];
- X v[c-1] = NIL;
- X *cc = c - 1;
- X *r = v;
- X return 1;
- X}
- X
- Xint
- Xnlformat(line, cc, r, id)
- Xchar *line;
- Xint *cc;
- Xaddr **r;
- Xaddr *id;
- X
- X{
- X int c;
- X addr *v;
- X
- X parse_line(line, &c, &v);
- X if (c < 2)
- X return 0;
- X *id = v[0];
- X *cc = c - 1;
- X *r = &v[1];
- X return 1;
- X}
- X
- Xstatic
- Xgag(msg)
- Xchar *msg;
- X
- X{
- X char errmsg[LONG_BUF];
- X
- X (void) sprintf(errmsg, "%s: line %d: %s", *filev, lineno, msg);
- X err(errmsg);
- X return;
- X}
- X
- Xstatic
- Xgag1(msg, s1)
- Xchar *msg;
- Xchar *s1;
- X
- X{
- X char errmsg[LONG_BUF];
- X
- X (void) sprintf(errmsg, msg, s1);
- X gag(errmsg);
- X return;
- X}
- @//E*O*F src/load.c//
- if test 7238 -ne "`wc -c <'src/load.c'`"; then
- echo shar: error transmitting "'src/load.c'" '(should have been 7238 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'src/main.c'" '(4050 characters)'
- if test -f 'src/main.c' ; then
- echo shar: will not over-write existing file "'src/main.c'"
- else
- sed 's/^X//' >src/main.c <<'@//E*O*F src/main.c//'
- X#include <stdio.h>
- X#include <sys/time.h>
- X#include <sys/resource.h>
- X#include <sys/wait.h>
- X#include <setjmp.h>
- X#include <signal.h>
- X#include "sysdep.h"
- X#include "macros.h"
- X#include "mem.h"
- X#include "command.h"
- X
- X#define ROOT_PROMPT "\r(mcp) "
- X#define PROMPT "\r( ) "
- X#define CARGS 32 /* # command line args allowed */
- X
- X#ifdef sun
- X#define sighandler (void (*)())
- X#else
- X#define sighandler (int (*)())
- X#endif
- X
- Xextern int scommcmp(), kids, root, ModBits, NCommands, goodbye(), DevTty;
- Xextern struct command Ctable[];
- Xextern char Working_Directory[];
- Xextern int ReportGoop();
- Xextern Summarize();
- Xextern char *sprintf();
- X
- Xjmp_buf interrupt, in_continue; /* setjmp vectors */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X
- X{
- X static char *prompt;
- X static addr v[CARGS+1];
- X int sjval, index, c, found, goop = 0;
- X int buildit, checkem, summary, listem, printversion;
- X char errmsg[MEDIUM_BUF];
- X
- X (void) umask(022);
- X
- X /*
- X * Find out if this is the superuser, what the current working
- X * directory is, seed random number generator.
- X * For Sun systems, also find out about file server, etc.
- X */
- X init_identities();
- X
- X buildit = checkem = summary = listem = printversion = 0;
- X while (--argc && **++argv == '-')
- X for (++*argv; **argv; ++*argv)
- X switch (**argv) {
- X case 'v':
- X printversion++; break;
- X case 'l':
- X listem++; break;
- X case 'B':
- X buildit++; break;
- X case 'c':
- X checkem++; break;
- X case 's':
- X summary++; break;
- X default:
- X (void) sprintf(errmsg, "mcp: bad option '%c' (ignored)",
- X **argv);
- X err(errmsg);
- X break;
- X }
- X /*
- X * Set up descriptor for /dev/tty or just attached to stderr
- X * if not running interactively.
- X */
- X init_tty(buildit || (!checkem && !summary && !listem));
- X
- X if (buildit && (checkem || summary || listem))
- X fatal("mcp: can't use -B with any other option.");
- X if (buildit && !root)
- X fatal("mcp: must be the super-user to use -B");
- X if (argc)
- X err("mcp: extra arguments ignored");
- X if (printversion && !buildit) {
- X ShowVersion();
- X if (!(checkem || summary || listem))
- X goodbye(0);
- X }
- X /*
- X * Must set up some sort of quick 'n dirty signal handling lest
- X * an interrupt cause the program to exit with the password
- X * file locked. So we block all signals except SIGINT, and trap
- X * SIGINT to goodbye().
- X */
- X (void) sigsetmask(~mask(SIGINT));
- X (void) signal(SIGINT, sighandler goodbye);
- X
- X if ( root && !(checkem || summary || listem)) {
- X msg("Locking password file...");
- X if (!lockpw())
- X fatal("mcp: password file busy");
- X prompt = ROOT_PROMPT;
- X }
- X else
- X prompt = PROMPT;
- X
- X if (buildit) Build(); /* Build() doesn't return */
- X
- X /*
- X * Pass a flag to init_lists() to indicate whether all or
- X * or only some of the global lists need be initialized.
- X */
- X init_lists(!(checkem || summary || listem));
- X
- X if (checkem) goop = ReportGoop();
- X if (listem) ListThemThangs();
- X if (summary) Summarize();
- X if (checkem || summary || listem) goodbye(goop ? 1 : 0);
- X
- X#if CKPTIME > 0
- X if (root)
- X (void) alarm(CKPTIME * 60); /* start checkpointing timer */
- X#endif
- X /*
- X * Trap interrupts back to the main command interpreter.
- X */
- X sjval = setjmp(interrupt);
- X if (sjval)
- X msg("\r\n");
- X
- X setsignals(); /* connect signal handlers */
- X
- X /*
- X * Main command line interpreting loop
- X */
- X for (;;) {
- X if (kids) reapchild();
- X closefiles();
- X freeargv(v);
- X free_gpa();
- X freetmplists();
- X (void) chdir(Working_Directory);
- X GetCommandLine(prompt, CARGS, &c, v);
- X if (c == 0)
- X continue;
- X index = search_array((char *)Ctable, (char *)v[0], NCommands,
- X sizeof (struct command), scommcmp, &found);
- X if (!found) {
- X err1("%s: unknown command", (char *)v[0]);
- X continue;
- X }
- X (*Ctable[index].c_func)(c, v);
- X }
- X}
- X
- Xreapchild()
- X
- X{
- X if (wait3((union wait *)0, WNOHANG, (struct rusage *)0) > 0)
- X kids--;
- X return;
- X}
- X
- X#if CKPTIME > 0
- Xwakeup()
- X
- X{
- X kids && reapchild();
- X ModBits && ckpchanges();
- X (void) alarm(CKPTIME * 60);
- X return;
- X}
- X#endif
- X
- Xclosefiles()
- X
- X{
- X register int i, nd = getdtablesize();
- X
- X for (i=3; i < nd; i++)
- X if (i != DevTty)
- X (void) close(i);
- X return;
- X}
- @//E*O*F src/main.c//
- if test 4050 -ne "`wc -c <'src/main.c'`"; then
- echo shar: error transmitting "'src/main.c'" '(should have been 4050 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'src/misc.c'" '(8013 characters)'
- if test -f 'src/misc.c' ; then
- echo shar: will not over-write existing file "'src/misc.c'"
- else
- sed 's/^X//' >src/misc.c <<'@//E*O*F src/misc.c//'
- X/**********************************************************************\
- X* *
- X* misc.c *
- X* *
- X* Miscellaneous routines ranging from password generators to word *
- X* capitalizers to a routine that scrubs untoward characters from user *
- X* names. *
- X* *
- X\**********************************************************************/
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/time.h>
- X#include <sys/dir.h>
- X#include <strings.h>
- X#include <ctype.h>
- X#include "sysdep.h"
- X#include "macros.h"
- X#include "mem.h"
- X#include "lists.h"
- X#include "range.h"
- X#include "sort.h"
- X
- X#define DAY 86400 /* no. of seconds in a day */
- X
- Xextern struct list RangeList;
- Xchar *ctime(), *sprintf();
- Xlong random();
- X
- Xcoloncount(s)
- Xregister char *s;
- X
- X{
- X register int n = 0;
- X
- X while (*s)
- X if (*s++ == ':')
- X n++;
- X return n;
- X}
- X
- Xcapitalize(s)
- Xchar *s;
- X
- X{
- X strlower(s);
- X if (isalpha(*s) && islower(*s))
- X *s = toupper(*s);
- X}
- X
- Xstrlower(s)
- Xchar *s;
- X
- X{
- X while (*s) {
- X if (isalpha(*s) && isupper(*s))
- X *s = tolower(*s);
- X s++;
- X }
- X return;
- X}
- X
- X
- Xint
- Xsearch_array(a, s, nelem, elemsize, compfunc, found)
- Xchar *a, *s;
- Xint nelem, elemsize, (*compfunc)(), *found;
- X
- X{
- X int lo = 0, hi = nelem - 1 , middle, compval;
- X int offset;
- X
- X *found = 0;
- X while (lo < hi) {
- X middle = (lo + hi) / 2;
- X offset = middle*elemsize;
- X if ((compval = (*compfunc)(s, a+offset)) == 0) {
- X *found = 1;
- X return middle;
- X }
- X else if (compval < 0) {
- X decr(middle);
- X hi = middle;
- X }
- X else
- X lo = middle + 1;
- X }
- X if (nelem && (*compfunc)(s, a+lo*elemsize) == 0)
- X *found = 1;
- X return lo;
- X}
- X
- Xsavestr(cpp, s)
- Xchar **cpp, *s;
- X
- X{
- X *cpp = (char *) MEM(strlen(s)+1);
- X (void) strcpy(*cpp, s);
- X return;
- X}
- X
- Xstatic char *suf[13] = {
- X "Jr.", "Sr.", "I",
- X "II", "III", "IV",
- X "V", "VI", "VII",
- X "VIII", "IX", "X",
- X "Esq."
- X};
- X
- Xstatic char *ttl[6] = { "Prof.", "Dr.", "Mr.", "Ms.", "Mrs.", "Rev." };
- X
- Xstruct list Suffixes = { 13, 13, (addr *)suf };
- Xstruct list Titles = { 6, 6, (addr *)ttl };
- X
- Xaddr
- Xmakeusername(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X static addr_t user[SHORT_BUF];
- X int found, tail;
- X flexaddr up;
- X
- X up.p_ap = user;
- X (void) search_list(&Titles, (char *)v[0], strcmp, &found);
- X if (found) {
- X v++;
- X c--;
- X }
- X (void) search_list(&Suffixes, (char *)v[c-1], strcmp, &found);
- X if (found)
- X c--;
- X /*
- X * If last name is seven characters or less and the
- X * case-lowered version of this isn't taken, use it.
- X */
- X if (strlen((char *)v[c-1]) < 8) {
- X (void) strcpy((char *)user, (char *)v[c-1]);
- X strlower((char *)user);
- X if (!userexists((char *)user)) {
- X scrub((char *)user);
- X return user;
- X }
- X }
- X /*
- X * If we have three initials and they aren't already taken, use them.
- X */
- X if (c == 3) {
- X up.p_cp[0] = ((char *)v[0])[0];
- X up.p_cp[1] = ((char *)v[1])[0];
- X up.p_cp[2] = ((char *)v[2])[0];
- X up.p_cp[3] = '\0';
- X strlower((char *)user);
- X if (!userexists((char *)user)) {
- X scrub((char *)user);
- X return user;
- X }
- X }
- X /*
- X * Oh, well. Chop off last name at five characters, append '_' and
- X * first initial. If the resulting name is unused, use it.
- X * If not increment the first initial through the collating
- X * sequence until we find a name that isn't used. The latter should
- X * happen rarely.
- X */
- X (void) strcpy((char *)user, (char *)v[c-1]);
- X up.p_cp[5] = '\0';
- X tail = strlen((char *)user);
- X up.p_cp[tail++] = '_';
- X up.p_cp[tail++] = ((char *)v[0])[0];
- X up.p_cp[tail--] = '\0';
- X strlower((char *)user);
- X while (userexists((char *)user))
- X up.p_cp[tail]++;
- X scrub((char *)user);
- X return user;
- X}
- X
- X/*
- X * Change all unsavory characters in a username to '_'
- X */
- Xscrub(username)
- Xchar *username;
- X
- X{
- X for (; *username; username++) {
- X if (isalpha(*username) || isdigit(*username))
- X continue;
- X if (*username == '-')
- X continue;
- X *username = '_';
- X }
- X return;
- X}
- X
- X/*
- X * This function is used to shut lint up about long to int conversions
- X * that I don't CARE about when getting a tiny random number.
- X */
- Xint rnd()
- X{
- X union a { int a_i; long a_l; } il;
- X
- X il.a_l = random();
- X return il.a_i;
- X}
- X
- X#define UPPER (char)(rnd() % 26) + 'A'
- X#define LOWER (char)(rnd() % 26) + 'a'
- X#define NUMBER (char)(rnd() % 10) + '0'
- X#define ODD (rnd() % 2 == 1)
- X#define EVEN !ODD
- X
- Xchar *
- Xmakepass()
- X
- X{
- X static char password[SHORT_BUF];
- X char *cp;
- X
- X cp = password;
- X if (ODD) *cp++ = UPPER; else *cp++ = LOWER;
- X if (EVEN) *cp++ = NUMBER; else *cp++ = UPPER;
- X if (EVEN) *cp++ = LOWER; else *cp++ = NUMBER;
- X if (ODD) *cp++ = LOWER; else *cp++ = NUMBER;
- X if (ODD) *cp++ = NUMBER; else *cp++ = UPPER;
- X if (EVEN) *cp++ = UPPER; else *cp++ = LOWER;
- X return password;
- X}
- X
- Xchar *
- Xrsalt()
- X
- X{
- X static char salt[3];
- X
- X if (EVEN) salt[0] = UPPER; else salt[0] = LOWER;
- X if (ODD) salt[1] = LOWER; else salt[1] = NUMBER;
- X salt[2] = '\0';
- X return salt;
- X}
- X
- Xchar *re_comp();
- X
- X/* ARGSUSED1 */
- Xaddr
- Xgethomedir(user, group)
- Xchar *user, *group;
- X
- X#ifdef xanth
- X{
- X static addr_t dbuf[LONG_BUF], defbuf[LONG_BUF+1];
- X char expr[LONG_BUF+1];
- X struct direct *dp;
- X DIR *dirp;
- X
- X (void) sprintf((char *)defbuf, "/tmp/U%s", user);
- X dirp = opendir(USERDIR);
- X if (dirp == NULL) {
- X err1("cannot open %s (read)", USERDIR);
- X return(defbuf);
- X }
- X for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- X if (dp->d_name[0] == '.')
- X continue;
- X (void) sprintf(expr, "^%s%c%c", dp->d_name, '.', '*');
- X (void) re_comp(expr);
- X if (re_exec(group) == 1) {
- X (void) sprintf((char *)dbuf, "%s/%s/%s", USERDIR,
- X dp->d_name, user);
- X closedir(dirp);
- X return(dbuf);
- X }
- X }
- X closedir(dirp);
- X return(defbuf);
- X}
- X#else
- X{
- X static addr_t dbuf[LONG_BUF];
- X
- X (void) sprintf((char *)dbuf, "%s/%s", USERDIR, user);
- X return dbuf;
- X}
- X#endif
- X
- X/*
- X * Figger out where the next free uid is, taking into
- X * consideration the range tables
- X */
- Xint findnextuid(group)
- Xchar *group;
- X
- X{
- X struct range *rg;
- X int uid, indx;
- X int maxu, minu;
- X
- X maxu = minu = 0;
- X uid = NOMORE;
- X for (indx=0; indx < RangeList.l_count; indx++) {
- X rg = (struct range *) RangeList.l_list[indx];
- X if (!eq(group, rg->rg_name))
- X continue;
- X if (rg->rg_from > rg->rg_to)
- X uid = rnextuid(rg->rg_from, rg->rg_to);
- X else
- X uid = nextuid(rg->rg_from, rg->rg_to);
- X if (uid != NOMORE)
- X return(uid);
- X maxu = max(maxu, rg->rg_from);
- X maxu = max(maxu, rg->rg_to);
- X minu = min(minu, rg->rg_from);
- X minu = min(minu, rg->rg_to);
- X }
- X /*
- X * No preference or no space available so now we look for space
- X * in shared ranges.
- X */
- X for (indx=0; indx < RangeList.l_count; indx++) {
- X rg = (struct range *) RangeList.l_list[indx];
- X if (rg->rg_mode == RG_EXCLUSIVE || eq(rg->rg_name, group))
- X continue;
- X if (rg->rg_from > rg->rg_to)
- X uid = rnextuid(rg->rg_from, rg->rg_to);
- X else
- X uid = nextuid(rg->rg_from, rg->rg_to);
- X if (uid != NOMORE)
- X break;
- X maxu = max(maxu, rg->rg_from);
- X maxu = max(maxu, rg->rg_to);
- X minu = min(minu, rg->rg_from);
- X minu = min(minu, rg->rg_to);
- X }
- X uid = nextuid(0, minu-1);
- X if (uid == -1) uid = nextuid(maxu+1, 1000);
- X return(uid);
- X}
- X
- Xint nextuid(lo, hi)
- Xint lo, hi;
- X
- X{
- X int i;
- X
- X for (i=lo; i<=hi; i++)
- X if (!uidexists(i))
- X return(i);
- X return(NOMORE);
- X}
- X
- Xint rnextuid(hi, lo)
- Xint hi, lo;
- X
- X{
- X int i;
- X
- X for (i=hi; i>=lo; i--)
- X if (!uidexists(i))
- X return(i);
- X return(NOMORE);
- X}
- X
- X/*
- X * Max is a function here, because it is used in places where macro side
- X * effects are not desired.
- X */
- Xint
- Xmax(a, b)
- Xint a, b;
- X
- X{
- X return (a > b ? a : b);
- X}
- X
- Xint
- Xmin(a, b)
- Xint a, b;
- X
- X{
- X return (a < b ? a : b);
- X}
- X
- Xdirscan(dir, l)
- Xchar *dir;
- Xregister struct list *l;
- X
- X{
- X struct direct *dp;
- X DIR *dirp;
- X
- X zerolist(l);
- X dirp = opendir(dir);
- X if (dirp == NULL)
- X return;
- X for (dp=readdir(dirp); dp != NULL; dp=readdir(dirp)) {
- X if (eq(dp->d_name, ".") || eq(dp->d_name, ".."))
- X continue;
- X strlistadd(l, dp->d_name);
- X }
- X closedir(dirp);
- X sort_list(l, pstrcmp);
- X return;
- X}
- X
- Xint
- Xisdir(name)
- Xchar *name;
- X
- X{
- X struct stat sb;
- X
- X if (stat(name, &sb) == -1)
- X return 0;
- X return ((sb.st_mode&S_IFMT) == S_IFDIR) ? 1 : 0;
- X}
- X
- Xvalidint(str)
- Xchar *str;
- X
- X{
- X if (!str || !*str)
- X return 0;
- X while (*str)
- X if (!isdigit(*str))
- X return 0;
- X else
- X str++;
- X return 1;
- X}
- @//E*O*F src/misc.c//
- if test 8013 -ne "`wc -c <'src/misc.c'`"; then
- echo shar: error transmitting "'src/misc.c'" '(should have been 8013 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'src/nitpick'" '(606 characters)'
- if test -f 'src/nitpick' ; then
- echo shar: will not over-write existing file "'src/nitpick'"
- else
- sed 's/^X//' >src/nitpick <<'@//E*O*F src/nitpick//'
- X#! /bin/sh
- X
- X#
- X# Script to lint individual source modules and maintain lint
- X# dependencies.
- X#
- X# Is invoked through 'make lintbrush'
- X#
- X# Works great if you have jove. Works even better if you can use
- X# jove. |-)
- X#
- X
- Xfor file
- Xdo
- X if test ! -f Lint/$file ; then
- X touch Lint/$file
- X # if the lint marker is younger than the source don't lint
- X elif test `ls -t $file Lint/$file | head -1` != $file ; then
- X continue;
- X fi
- X while test `lint -a -b -h -u $file | tee LintErrors | wc -l` != "1"
- X do
- X echo Uh, oh. Trouble with $file...
- X jove -p LintErrors $file
- X done
- X echo $file ok.
- X touch Lint/$file
- Xdone
- X
- Xexit 0
- @//E*O*F src/nitpick//
- if test 606 -ne "`wc -c <'src/nitpick'`"; then
- echo shar: error transmitting "'src/nitpick'" '(should have been 606 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'src/pwlock.c'" '(712 characters)'
- if test -f 'src/pwlock.c' ; then
- echo shar: will not over-write existing file "'src/pwlock.c'"
- else
- sed 's/^X//' >src/pwlock.c <<'@//E*O*F src/pwlock.c//'
- X#include <sys/types.h>
- X#include <sys/file.h>
- X#include "sysdep.h"
- X
- Xextern time_t PWLockTime;
- Xstatic int pwlocked;
- X
- Xlockpw()
- X
- X{
- X int fd, i;
- X time_t time();
- X
- X for (i=1; i<5; i++) {
- X if ((fd=open(PWDLOCK, O_WRONLY|O_CREAT|O_EXCL, 0644)) >= 0) {
- X (void) time(&PWLockTime);
- X (void) close(fd);
- X pwlocked++;
- X return(1);
- X }
- X else switch (i) {
- X case 2: msg("Waiting for passwd lock..."); break;
- X case 3: msg("Still waiting..."); break;
- X case 4: msg("Pacing angrily..."); break;
- X default: break;
- X }
- X sleep(2 * (unsigned)i);
- X }
- X return(0);
- X}
- X
- Xunlockpw()
- X
- X{
- X if (!pwlocked) return;
- X if (unlink(PWDLOCK) == -1) {
- X perr("Warning: unable to unlock password file");
- X return;
- X }
- X pwlocked = 0;
- X return;
- X}
- @//E*O*F src/pwlock.c//
- if test 712 -ne "`wc -c <'src/pwlock.c'`"; then
- echo shar: error transmitting "'src/pwlock.c'" '(should have been 712 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'src/range.c'" '(1138 characters)'
- if test -f 'src/range.c' ; then
- echo shar: will not over-write existing file "'src/range.c'"
- else
- sed 's/^X//' >src/range.c <<'@//E*O*F src/range.c//'
- X#include <stdio.h>
- X#include "sysdep.h"
- X#include "mem.h"
- X#include "lists.h"
- X#include "range.h"
- X
- Xextern struct list RangeList;
- Xextern int srangecmp();
- X
- Xstatic FILE *rgf = NULL;
- Xstatic char line[BUFSIZ];
- Xstatic char namebuf[SHORT_BUF+1], modebuf[SHORT_BUF+1];
- Xstatic struct range rg;
- X
- Xsetrgent()
- X
- X{
- X rg.rg_name = namebuf;
- X if( rgf == NULL ) {
- X rgf = fopen( RANGEFILE, "r" );
- X if (rgf == NULL) {
- X perr(RANGEFILE);
- X goodbye(1);
- X }
- X rewind(rgf);
- X }
- X else
- X rewind( rgf );
- X}
- X
- Xendrgent()
- X
- X{
- X if( rgf != NULL ){
- X (void) fclose( rgf );
- X rgf = NULL;
- X }
- X}
- X
- Xstruct range *
- Xgetrgent()
- X
- X{
- X register char *p;
- X int n;
- X
- X if (rgf == NULL)
- X setrgent();
- X p = fgets(line, BUFSIZ, rgf);
- X if (p==NULL)
- X return(0);
- X n = sscanf(line, "%s%d%d%s",rg.rg_name,
- X &rg.rg_from,
- X &rg.rg_to,
- X modebuf);
- X if (n != 4) fatal("badly formatted range file line!");
- X rg.rg_mode = (modebuf[0] == 'e' ? RG_EXCLUSIVE : RG_SHARED);
- X return(&rg);
- X}
- X
- Xstruct range *
- Xgetrgnam(name)
- Xchar *name;
- X
- X{
- X int indx, found;
- X
- X indx = search_list(&RangeList, name, srangecmp, &found);
- X if (found)
- X return (struct range *) RangeList.l_list[indx];
- X return (struct range *) 0;
- X}
- @//E*O*F src/range.c//
- if test 1138 -ne "`wc -c <'src/range.c'`"; then
- echo shar: error transmitting "'src/range.c'" '(should have been 1138 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'src/range.h'" '(158 characters)'
- if test -f 'src/range.h' ; then
- echo shar: will not over-write existing file "'src/range.h'"
- else
- sed 's/^X//' >src/range.h <<'@//E*O*F src/range.h//'
- Xstruct range {
- X char *rg_name;
- X int rg_from;
- X int rg_to;
- X int rg_mode;
- X};
- X
- X#define RG_EXCLUSIVE 1
- X#define RG_SHARED 2
- X
- Xstruct range *getrgent(), *getrgnam();
- @//E*O*F src/range.h//
- if test 158 -ne "`wc -c <'src/range.h'`"; then
- echo shar: error transmitting "'src/range.h'" '(should have been 158 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'src/remove.c'" '(14203 characters)'
- if test -f 'src/remove.c' ; then
- echo shar: will not over-write existing file "'src/remove.c'"
- else
- sed 's/^X//' >src/remove.c <<'@//E*O*F src/remove.c//'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <lastlog.h>
- X#include "sysdep.h"
- X#include "macros.h"
- X#include "mem.h"
- X#include "lists.h"
- X#include "gpa.h"
- X#include "sort.h"
- X#include "account.h"
- X#ifdef SENDMAIL
- X#include "alias.h"
- X#endif
- X#include "groupmap.h"
- X#include "class.h"
- X#include "job.h"
- X#include "range.h"
- X#include "sig.h"
- X#include "save.h"
- X
- X#ifdef SENDMAIL
- Xextern struct list AliasList, Aliases;
- X#endif SENDMAIL
- Xextern struct list AccountList, Classes, ClassList;
- Xextern struct list GroupMapList, Groups, SigList, Sigs, RangeList, Ranges;
- Xextern struct list Users, Vigs;
- Xextern int ModBits;
- Xchar *sprintf();
- X
- X#ifdef SENDMAIL
- Xrmalias(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X struct alias *al;
- X struct class *cs;
- X struct sig *sg;
- X struct groupmap *gm;
- X struct account *ac;
- X char *name;
- X register int i;
- X
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if ( c != 2 ) {
- X err1("usage: %s <alias>", (char *)v[0]);
- X return;
- X }
- X
- X al = getalnam((char *)v[1]);
- X if (!al) {
- X err1("%s: no such alias", (char *)v[1]);
- X return;
- X }
- X
- X critical();
- X name = al->al_name;
- X freelist(&al->al_addresses);
- X freelist(&al->al_groups);
- X freelist(&al->al_classes);
- X freelist(&al->al_sigs);
- X strlistdel(&Aliases, (char *)v[1]);
- X genlistdel(&AliasList, v[1], saliascmp);
- X FREEMEM(name);
- X for (i=0; i < AliasList.l_count; i++) {
- X al = (struct alias *) AliasList.l_list[i];
- X if (instrlist(&al->al_addresses, (char *)v[1]))
- X strlistdel(&al->al_addresses, (char *)v[1]);
- X }
- X for (i=0; i < GroupMapList.l_count; i++) {
- X gm = (struct groupmap *) GroupMapList.l_list[i];
- X if (instrlist(&gm->gm_aliases, (char *)v[1]))
- X strlistdel(&gm->gm_aliases, (char *)v[1]);
- X }
- X for (i=0; i < ClassList.l_count; i++) {
- X cs = (struct class *) ClassList.l_list[i];
- X if (instrlist(&cs->cs_aliases, (char *)v[1]))
- X strlistdel(&cs->cs_aliases, (char *)v[1]);
- X }
- X for (i=0; i < SigList.l_count; i++) {
- X sg = (struct sig *) SigList.l_list[i];
- X if (instrlist(&sg->sg_aliases, (char *)v[1]))
- X strlistdel(&sg->sg_aliases, (char *)v[1]);
- X }
- X for (i=0; i < AccountList.l_count; i++) {
- X ac = (struct account *) AccountList.l_list[i];
- X if (instrlist(&ac->ac_aliases, (char *)v[1])) {
- X strlistdel(&ac->ac_aliases, (char *)v[1]);
- X ModBits |= AC;
- X }
- X }
- X ModBits |= AL;
- X puts("removed");
- X non_critical();
- X
- X return;
- X}
- X#endif
- X
- Xrmclass(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X struct class *cs;
- X#ifdef SENDMAIL
- X struct alias *al;
- X#endif
- X struct account *ac;
- X char *name;
- X int i;
- X
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if ( c != 2 ) {
- X err1("usage: %s <class>", (char *)v[0]);
- X return;
- X }
- X
- X cs = getcsnam((char *)v[1]);
- X if (!cs) {
- X err1("%s: no such class", (char *)v[1]);
- X return;
- X }
- X
- X critical();
- X
- X#ifdef SENDMAIL
- X for (i=0; i < AliasList.l_count; i++) {
- X al = (struct alias *) AliasList.l_list[i];
- X if (instrlist(&al->al_classes, (char *)v[1])) {
- X strlistdel(&al->al_classes, (char *)v[1]);
- X ModBits |= AL;
- X }
- X }
- X#endif
- X for (i=0; i < AccountList.l_count; i++) {
- X ac = (struct account *) AccountList.l_list[i];
- X if (instrlist(&ac->ac_classes, (char *)v[1])) {
- X strlistdel(&ac->ac_classes, (char *)v[1]);
- X#ifdef SENDMAIL
- X if (cs->cs_aliases.l_count)
- X RXBindings(ac);
- X#endif
- X ModBits |= AC;
- X }
- X }
- X
- X name = cs->cs_name;
- X FREEMEM(cs->cs_desc);
- X genlistdel(&ClassList, v[1], sclasscmp);
- X strlistdel(&Classes, (char *)v[1]);
- X FREEMEM(name);
- X
- X ModBits |= CS;
- X
- X puts("removed");
- X non_critical();
- X return;
- X}
- X
- Xrmcryos(c, v)
- Xint c;
- Xchar **v;
- X
- X{
- X register struct account *ac;
- X register int indx;
- X int removed = 0;
- X
- X if ( c > 1 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X critical();
- X for (indx=0; indx < AccountList.l_count; indx++) {
- X ac = (struct account *) AccountList.l_list[indx];
- X if (eq(ac->ac_shell, FREEZE_SH)) {
- X rmu(ac, 1);
- X removed++;
- X /* someone else is in this spot now */
- X indx--;
- X }
- X }
- X if (removed) {
- X (void) printf("%d removed\n", removed);
- X#ifndef DOFILES
- X err("Do not forget to remove the user directories.");
- X#endif
- X }
- X else
- X puts("No cryos.");
- X non_critical();
- X return;
- X}
- X
- X#ifdef SENDMAIL
- Xrmfromalias(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X struct alias *al;
- X struct account *ac;
- X addr *addressv;
- X int cc, removed = 0;
- X register int indx;
- X
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if (c != 2) {
- X err1("usage: %s <alias>", (char *)v[0]);
- X return;
- X }
- X al = getalnam((char *)v[1]);
- X if (!al) {
- X err1("%s: no such alias", (char *)v[1]);
- X return;
- X }
- X
- X addressv = get_gpa(65);
- X GetLine("Addresses: ", 64, &cc, addressv, &al->al_addresses);
- X if (cc == 0) {
- X err("no change");
- X return;
- X }
- X
- X critical();
- X for (indx=0; indx < cc; indx++) {
- X if (!instrlist(&al->al_addresses, (char *)addressv[indx])) {
- X err1("%s: not in alias", (char *)addressv[indx]);
- X continue;
- X }
- X strlistdel(&al->al_addresses, (char *)addressv[indx]);
- X ac = getacnam((char *)addressv[indx]);
- X if (ac&&instrlist(&ac->ac_aliases, (char *)addressv[indx])) {
- X strlistdel(&ac->ac_aliases, al->al_name);
- X ModBits |= AC;
- X }
- X removed++;
- X }
- X if (removed) {
- X ModBits |= AL;
- X (void) printf("%d removed\n", removed);
- X }
- X else
- X err("no change");
- X non_critical();
- X
- X return;
- X}
- X#endif SENDMAIL
- X
- Xrmfromclass(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X struct class *cs;
- X struct account *ac;
- X addr *userv;
- X int cc;
- X register int i, removed = 0;
- X
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if (c != 2) {
- X err1("usage: %s <class>", (char *)v[0]);
- X return;
- X }
- X cs = getcsnam((char *)v[1]);
- X if (!cs) {
- X err1("%s: no such class", (char *)v[1]);
- X return;
- X }
- X userv = get_gpa(65);
- X GetLine("Users: ", 64, &cc, userv, &Users);
- X if (cc == 0) {
- X err("no change");
- X return;
- X }
- X
- X critical();
- X
- X for (i=0; i < cc; i++) {
- X ac = getacnam((char *)userv[i]);
- X if (!ac) {
- X err1("%s: no such user", (char *)userv[i]);
- X continue;
- X }
- X if (!instrlist(&ac->ac_classes, (char *)v[1])) {
- X err1("%s: not in class", (char *)userv[i]);
- X continue;
- X }
- X strlistdel(&ac->ac_classes, (char *)v[1]);
- X#ifdef SENDMAIL
- X if (cs->cs_aliases.l_count)
- X RXBindings(ac);
- X#endif
- X removed++;
- X }
- X if (removed) {
- X (void) printf("%d removed\n");
- X ModBits |= AC;
- X }
- X else
- X err("no change");
- X
- X non_critical();
- X return;
- X}
- X
- Xrmfromgroup(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X struct groupmap *gm;
- X struct account *ac;
- X addr *userv;
- X int cc;
- X register int i, removed = 0;
- X
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if (c != 2) {
- X err1("usage: %s <group>", (char *)v[0]);
- X return;
- X }
- X gm = getgmnam((char *)v[1]);
- X if (!gm) {
- X err1("%s: no such group", (char *)v[1]);
- X return;
- X }
- X userv = get_gpa(65);
- X GetLine("Users: ", 64, &cc, userv, &gm->gm_mem);
- X if (cc == 0) {
- X err("no change");
- X return;
- X }
- X
- X critical();
- X for (i=0; i < cc; i++) {
- X ac = getacnam((char *)userv[i]);
- X if (!ac) {
- X err1("%s: no such user", (char *)userv[i]);
- X continue;
- X }
- X if (!instrlist(&gm->gm_mem, (char *)userv[i])) {
- X err1("%s: not in group", (char *)userv[i]);
- X continue;
- X }
- X strlistdel(&ac->ac_groups, (char *)v[1]);
- X strlistdel(&gm->gm_mem, (char *)userv[i]);
- X#ifdef SENDMAIL
- X if (gm->gm_aliases.l_count)
- X RXBindings(ac);
- X#endif
- X removed++;
- X }
- X if (removed) {
- X (void) printf("%d removed\n");
- X ModBits |= AC|GR;
- X }
- X else
- X err("no change");
- X non_critical();
- X
- X return;
- X}
- X
- Xrmfromsig(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X struct sig *sg;
- X struct account *ac;
- X addr *userv;
- X int cc;
- X register int i, removed = 0;
- X
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if (c != 2) {
- X err1("usage: %s <sig>", (char *)v[0]);
- X return;
- X }
- X sg = getsgnam((char *)v[1]);
- X if (!sg) {
- X err1("%s: no such sig", (char *)v[1]);
- X return;
- X }
- X userv = get_gpa(65);
- X GetLine("Users: ", 64, &cc, userv, &Users);
- X if (cc == 0) {
- X err("no change");
- X return;
- X }
- X
- X critical();
- X for (i=0; i < cc; i++) {
- X ac = getacnam((char *)userv[i]);
- X if (!ac) {
- X err1("%s: no such user", (char *)userv[i]);
- X continue;
- X }
- X if (!instrlist(&ac->ac_sigs, (char *)v[1])) {
- X err1("%s: not in sig", (char *)userv[i]);
- X continue;
- X }
- X strlistdel(&ac->ac_sigs, (char *)v[1]);
- X#ifdef SENDMAIL
- X if (sg->sg_aliases.l_count)
- X RXBindings(ac);
- X#endif
- X removed++;
- X }
- X if (removed) {
- X (void) printf("%d removed\n");
- X ModBits |= AC;
- X }
- X else
- X err("no change");
- X non_critical();
- X
- X return;
- X}
- X
- Xrmgroup(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X struct groupmap *gm;
- X struct account *ac;
- X#ifdef SENDMAIL
- X struct alias *al;
- X#endif
- X char *name;
- X int i, removed = 0;
- X
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if ( c != 2 ) {
- X err1("usage: %s <group>", (char *)v[0]);
- X return;
- X }
- X
- X gm = getgmnam((char *)v[1]);
- X if (!gm) {
- X err1("%s: no such group", (char *)v[1]);
- X return;
- X }
- X
- X critical();
- X
- X#ifdef SENDMAIL
- X for (i=0; i < AliasList.l_count; i++) {
- X al = (struct alias *) AliasList.l_list[i];
- X if (instrlist(&al->al_groups, (char *)v[1])) {
- X strlistdel(&al->al_groups, (char *)v[1]);
- X ModBits |= AL;
- X }
- X }
- X#endif
- X for (i=0; i < gm->gm_mem.l_count; i++) {
- X ac = getacnam((char *)gm->gm_mem.l_list[i]);
- X if (!ac) continue;
- X if (instrlist(&ac->ac_groups, (char *)v[1])) {
- X strlistdel(&ac->ac_groups, (char *)v[1]);
- X#ifdef SENDMAIL
- X if (gm->gm_aliases.l_count)
- X RXBindings(ac);
- X#endif
- X removed++;
- X }
- X }
- X
- X if (removed) ModBits |= AC;
- X
- X if (rangeexists((char *)v[1])) {
- X ModBits |= RG;
- X genlistdel(&RangeList, v[1], srangecmp);
- X strlistdel(&Ranges, (char *)v[1]);
- X }
- X if (vigexists((char *)v[1])) {
- X ModBits |= VG;
- X strlistdel(&Vigs, (char *)v[1]);
- X }
- X
- X ModBits |= GR;
- X
- X name = gm->gm_name;
- X freelist(&gm->gm_mem);
- X genlistdel(&GroupMapList, (addr)&gm->gm_gid, igmapcmp);
- X strlistdel(&Groups, (char *)v[1]);
- X FREEMEM(name);
- X puts("removed");
- X non_critical();
- X
- X return;
- X}
- X
- Xrmrange(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X struct range *rg;
- X char *name;
- X
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if ( c != 2 ) {
- X err1("usage: %s <group>", (char *)v[0]);
- X return;
- X }
- X
- X rg = getrgnam((char *)v[1]);
- X if (!rg) {
- X err1("%s: no such range", (char *)v[1]);
- X return;
- X }
- X
- X critical();
- X name = rg->rg_name;
- X genlistdel(&RangeList, v[1], srangecmp);
- X strlistdel(&Ranges, (char *)v[1]);
- X FREEMEM(name);
- X ModBits |= RG;
- X puts("removed");
- X non_critical();
- X
- X return;
- X}
- X
- Xrmsig(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X struct sig *sg;
- X struct account *ac;
- X#ifdef SENDMAIL
- X struct alias *al;
- X#endif
- X char *name;
- X int i;
- X
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if ( c != 2 ) {
- X err1("usage: %s <sig>\n", (char *)v[0]);
- X return;
- X }
- X
- X sg = getsgnam((char *)v[1]);
- X if (!sg) {
- X err1("%s: no such sig", (char *)v[1]);
- X return;
- X }
- X
- X critical();
- X
- X#ifdef SENDMAIL
- X for (i=0; i < AliasList.l_count; i++) {
- X al = (struct alias *) AliasList.l_list[i];
- X if (instrlist(&al->al_sigs, (char *)v[1])) {
- X strlistdel(&al->al_sigs, (char *)v[1]);
- X ModBits |= AL;
- X }
- X }
- X#endif
- X for (i=0; i < AccountList.l_count; i++) {
- X ac = (struct account *) AccountList.l_list[i];
- X if (instrlist(&ac->ac_sigs, (char *)v[1])) {
- X strlistdel(&ac->ac_sigs, (char *)v[1]);
- X#ifdef SENDMAIL
- X if (sg->sg_aliases.l_count)
- X RXBindings(ac);
- X#endif
- X ModBits |= AC;
- X }
- X }
- X
- X name = sg->sg_name;
- X FREEMEM(sg->sg_desc);
- X genlistdel(&SigList, v[1], ssigcmp);
- X strlistdel(&Sigs, (char *)v[1]);
- X FREEMEM(name);
- X
- X ModBits |= SG;
- X
- X puts("removed");
- X non_critical();
- X
- X return;
- X}
- X
- Xrmuser(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X struct account *ac;
- X int zapdir;
- X#ifdef DOFILES
- X char prompt[LONG_BUF];
- X#endif
- X
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if ( c != 2 ) {
- X err1("usage: %s <user>", (char *)v[0]);
- X return;
- X }
- X ac = getacnam((char *)v[1]);
- X if (!ac) {
- X err1("%s: no such user", (char *)v[1]);
- X return;
- X }
- X
- X#ifdef DOFILES
- X if (fileexists((char *)ac->ac_dir)) {
- X (void) sprintf(prompt, "Home directory is %s, remove it? ",
- X ac->ac_dir);
- X zapdir = yesno(prompt);
- X }
- X else
- X err1("hmmm... home directory %s non-existent", (char *)ac->ac_dir);
- X#else
- X err("Do not forget to remove the user's home directory.");
- X zapdir = 0;
- X#endif
- X rmu(ac, zapdir);
- X
- X (void) printf("%s removed\n", v[1]);
- X return;
- X}
- X
- Xrmvig(c, v)
- Xint c;
- Xaddr *v;
- X
- X{
- X if ( c > 2 ) {
- X err1("%s: too many arguments", (char *)v[0]);
- X return;
- X }
- X if ( c != 2 ) {
- X err1("usage: %s <vig>", (char *)v[0]);
- X return;
- X }
- X
- X if (!vigexists((char *)v[1])) {
- X err1("%s: no such vig", (char *)v[1]);
- X return;
- X }
- X
- X critical();
- X
- X strlistdel(&Vigs, (char *)v[1]);
- X ModBits |= VG;
- X
- X puts("removed");
- X non_critical();
- X return;
- X}
- X
- X/*
- X * This is the routine that actually removes a user from the data
- X * structures. rmuser() is just a front end to this routine.
- X */
- X/* ARGSUSED */
- Xrmu(ac, zapdir)
- Xstruct account *ac;
- Xint zapdir;
- X
- X{
- X register int i, j;
- X register struct groupmap *gm;
- X#ifdef SENDMAIL
- X struct alias *al;
- X#endif
- X
- X critical();
- X
- X#ifdef DOFILES
- X zapdir && add_job(JB_RMDIR, ac->ac_dir, NIL, NIL);
- X add_job(JB_RMMAIL, ac->ac_name, NIL, NIL);
- X#endif
- X
- X for (i=0; i < GroupMapList.l_count; i++) {
- X gm = (struct groupmap *) GroupMapList.l_list[i];
- X if (instrlist(&gm->gm_mem, (char *)ac->ac_name)) {
- X strlistdel(&gm->gm_mem, (char *)ac->ac_name);
- X ModBits |= GR;
- X }
- X }
- X strlistdel(&Users, (char *)ac->ac_name);
- X
- X#ifdef SENDMAIL
- X for (i=0; i < AliasList.l_count; i++) {
- X al = (struct alias *) AliasList.l_list[i];
- X if (instrlist(&al->al_addresses, (char *)ac->ac_name)) {
- X strlistdel(&al->al_addresses, (char *)ac->ac_name);
- X ModBits |= AL;
- X }
- X }
- X#endif
- X
- X FREEMEM((char *)ac->ac_name);
- X FREEMEM((char *)ac->ac_realname);
- X FREEMEM((char *)ac->ac_gecos);
- X FREEMEM((char *)ac->ac_passwd);
- X FREEMEM((char *)ac->ac_id);
- X FREEMEM((char *)ac->ac_dir);
- X FREEMEM((char *)ac->ac_shell);
- X freelist(&ac->ac_groups);
- X freelist(&ac->ac_classes);
- X freelist(&ac->ac_sigs);
- X#ifdef SENDMAIL
- X freelist(&ac->ac_aliases);
- X#endif
- X
- X /*
- X * Cannot use genlistdel() because AccountList is sorted by uid, and
- X * not by name.
- X */
- X for (i=0; i < AccountList.l_count; i++)
- X if (ac == (struct account *) AccountList.l_list[i])
- X break;
- X for (j=i; j < AccountList.l_count-1; j++)
- X AccountList.l_list[j] = AccountList.l_list[j+1];
- X AccountList.l_count--;
- X FREEMEM((char *)ac);
- X
- X ModBits |= AC|PW;
- X
- X non_critical();
- X
- X return;
- X}
- @//E*O*F src/remove.c//
- if test 14203 -ne "`wc -c <'src/remove.c'`"; then
- echo shar: error transmitting "'src/remove.c'" '(should have been 14203 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'src/report.c'" '(6824 characters)'
- if test -f 'src/report.c' ; then
- echo shar: will not over-write existing file "'src/report.c'"
- else
- sed 's/^X//' >src/report.c <<'@//E*O*F src/report.c//'
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/time.h>
- X#include <lastlog.h>
- X#include "sysdep.h"
- X#include "macros.h"
- X#include "mem.h"
- X#include "lists.h"
- X#include "account.h"
- X#ifdef SENDMAIL
- X#include "alias.h"
- X#endif
- X#include "class.h"
- X#include "groupmap.h"
- X#include "range.h"
- X#include "sig.h"
- X#include "sort.h"
- X
- X#ifdef BSD4_3
- Xtime_t time();
- X#endif
- X
- X#ifdef SENDMAIL
- Xextern struct list AliasList;
- X#endif
- Xextern struct list AccountList, ClassList, GroupMapList, RangeList, SigList;
- Xextern int root;
- Xextern char *when();
- X
- XSummarize()
- X
- X{
- X (void) printf("%d user%s, %d group%s, %d class%s, %d sig%s",
- X AccountList.l_count, S(AccountList.l_count),
- X GroupMapList.l_count, S(GroupMapList.l_count),
- X ClassList.l_count, ES(ClassList.l_count),
- X SigList.l_count, S(SigList.l_count));
- X#ifdef SENDMAIL
- X (void) printf(", %d alias%s\n", AliasList.l_count,
- X ES(AliasList.l_count));
- X#else
- X (void) puts("");
- X#endif
- X return;
- X}
- X
- Xint
- XReportGoop()
- X
- X{
- X struct account *ac;
- X struct groupmap *gm;
- X struct class *cs;
- X struct sig *sg;
- X struct stat sb;
- X struct list c, s;
- X#ifdef SENDMAIL
- X struct alias *al;
- X char *cp;
- X#endif
- X time_t now;
- X int goop = 0;
- X register int indx, i;
- X
- X zerolist(&c); zerolist(&s);
- X for (indx=0; indx < AccountList.l_count; indx++) {
- X ac = (struct account *) AccountList.l_list[indx];
- X /*
- X * For root and vig members, howl if no password.
- X */
- X if (ac->ac_passwd[0] == '\0') {
- X if (ac->ac_uid == 0) {
- X (void) printf("user \"%s\" has no password!\n", ac->ac_name);
- X continue;
- X }
- X gm = getgmgid(ac->ac_gid);
- X if (gm && vigexists((char *)gm->gm_name))
- X (void) printf("user \"%s\" has no password\n", ac->ac_name);
- X }
- X /*
- X * Report users with base gids that do not correspond
- X * to a group in /etc/group.
- X */
- X if (!gidexists(ac->ac_gid))
- X (void) printf("user \"%s\" has nonexistent gid of (%d)\n",
- X ac->ac_name, ac->ac_gid);
- X /*
- X * Report references to non-existent classes
- X */
- X for (i=0; i < ac->ac_classes.l_count; i++) {
- X if (!classexists((char *)ac->ac_classes.l_list[i])) {
- X(void) printf("user \"%s\" is member of nonexistent class \"%s\"\n",
- X ac->ac_name, ac->ac_classes.l_list[i]);
- X goop++;
- X continue;
- X }
- X if (!instrlist(&c, (char *)ac->ac_classes.l_list[i]))
- X strlistadd(&c, (char *)ac->ac_classes.l_list[i]);
- X }
- X /*
- X * Report references to non-existent sigs
- X */
- X for (i=0; i < ac->ac_sigs.l_count; i++) {
- X if (!sigexists((char *)ac->ac_sigs.l_list[i])) {
- X(void) printf("user \"%s\" is member of nonexistent sig \"%s\"\n",
- X ac->ac_name, ac->ac_sigs.l_list[i]);
- X goop++;
- X continue;
- X }
- X if (!instrlist(&s, (char *)ac->ac_sigs.l_list[i]))
- X strlistadd(&s, (char *)ac->ac_sigs.l_list[i]);
- X }
- X /*
- X * Skip home directory and shell check if not the super-user,
- X * since not some shells may not be accessible to non
- X * super-users.
- X */
- X if (!root)
- X continue;
- X if (!fileexists((char *)ac->ac_dir))
- X(void) printf("user \"%s\"'s home directory (%s) not found\n",
- X ac->ac_name, ac->ac_dir);
- X if (stat((char *)ac->ac_dir, &sb) == 0)
- X if (sb.st_uid != ac->ac_uid)
- X(void) printf("user \"%s\" does not own his home directory (%s)\n", ac->ac_name, ac->ac_dir);
- X if (!fileexists((char *)ac->ac_shell))
- X(void) printf("user \"%s\" login shell (%s) not found\n",
- X ac->ac_name, ac->ac_shell);
- X }
- X sort_list(&s, pstrcmp);
- X sort_list(&c, pstrcmp);
- X for (indx=0; indx < GroupMapList.l_count; indx++) {
- X gm = (struct groupmap *) GroupMapList.l_list[indx];
- X for (i=0; i < gm->gm_mem.l_count; i++) {
- X if (!userexists((char *)gm->gm_mem.l_list[i])) {
- X(void) printf("group \"%s\" contains nonexistent user \"%s\"\n",
- X gm->gm_name, gm->gm_mem.l_list[i]);
- X goop++;
- X }
- X }
- X }
- X (void) time(&now);
- X for (indx=0; indx < ClassList.l_count; indx++) {
- X cs = (struct class *) ClassList.l_list[indx];
- X if (!instrlist(&c, (char *)cs->cs_name)) {
- X (void) printf("class \"%s\" is empty\n", cs->cs_name);
- X goop++;
- X }
- X if (cs->cs_exptime && (now >= cs->cs_exptime)) {
- X (void) printf("class \"%s\" expired %s\n", cs->cs_name,
- X when(cs->cs_exptime));
- X goop++;
- X }
- X }
- X for (indx=0; indx < SigList.l_count; indx++) {
- X sg = (struct sig *) SigList.l_list[indx];
- X if (!instrlist(&s, (char *)sg->sg_name)) {
- X (void) printf("sig \"%s\" is empty\n", sg->sg_name);
- X goop++;
- X }
- X if (sg->sg_exptime && (now >= sg->sg_exptime)) {
- X (void) printf("sig \"%s\" expired %s\n", sg->sg_name,
- X when(sg->sg_exptime));
- X goop++;
- X }
- X }
- X#ifdef SENDMAIL
- X for (indx=0; indx < AliasList.l_count; indx++) {
- X al = (struct alias *) AliasList.l_list[indx];
- X for (i=0; i < al->al_groups.l_count; i++) {
- X cp = (char *)al->al_groups.l_list[i];
- X if (!groupexists(cp)) {
- X(void) printf("alias \"%s\" bound to nonexistent group \"%s\"\n", al->al_name, cp);
- X goop++;
- X }
- X }
- X for (i=0; i < al->al_classes.l_count; i++) {
- X cp = (char *)al->al_classes.l_list[i];
- X if (!classexists(cp)) {
- X(void) printf("alias \"%s\" bound to nonexistent class \"%s\"\n", al->al_name, cp);
- X goop++;
- X }
- X }
- X for (i=0; i < al->al_sigs.l_count; i++) {
- X cp = (char *)al->al_sigs.l_list[i];
- X if (!sigexists(cp)) {
- X(void) printf("alias \"%s\" bound to nonexistent sig \"%s\"\n", al->al_name, cp);
- X goop++;
- X }
- X }
- X }
- X#endif
- X return goop;
- X}
- X
- XListThemThangs()
- X
- X{
- X struct groupmap *gm;
- X struct class *cs;
- X struct sig *sg;
- X struct account *ac;
- X register int i, j;
- X int memcount;
- X
- X if (GroupMapList.l_count) puts("== Groups ==");
- X for (i=0; i < GroupMapList.l_count; i++) {
- X gm = (struct groupmap *) GroupMapList.l_list[i];
- X memcount = gm->gm_mem.l_count;
- X for (j=0; j < AccountList.l_count; j++) {
- X ac = (struct account *) AccountList.l_list[j];
- X if (ac->ac_gid == gm->gm_gid)
- X memcount++;
- X }
- X printf("\"%s\", %d member%s, %d groupie%s\n", gm->gm_name,
- X memcount - gm->gm_mem.l_count, S(memcount - gm->gm_mem.l_count),
- X gm->gm_mem.l_count, S(gm->gm_mem.l_count));
- X }
- X if (ClassList.l_count) puts("== Classes ==");
- X for (i=0; i < ClassList.l_count; i++) {
- X memcount = 0;
- X cs = (struct class *) ClassList.l_list[i];
- X for (j=0; j < AccountList.l_count; j++) {
- X ac = (struct account *) AccountList.l_list[j];
- X if (instrlist(&ac->ac_classes, cs->cs_name))
- X memcount++;
- X }
- X printf("\"%s\", %d member%s, ends %s\n", cs->cs_name,
- X memcount, S(memcount), when(cs->cs_exptime));
- X }
- X if (SigList.l_count) puts("== Sigs ==");
- X for (i=0; i < SigList.l_count; i++) {
- X memcount = 0;
- X sg = (struct sig *) SigList.l_list[i];
- X for (j=0; j < AccountList.l_count; j++) {
- X ac = (struct account *) AccountList.l_list[j];
- X if (instrlist(&ac->ac_sigs, sg->sg_name))
- X memcount++;
- X }
- X printf("\"%s\", %d member%s, ends %s\n", sg->sg_name,
- X memcount, S(memcount), when(sg->sg_exptime));
- X }
- X return;
- X}
- @//E*O*F src/report.c//
- if test 6824 -ne "`wc -c <'src/report.c'`"; then
- echo shar: error transmitting "'src/report.c'" '(should have been 6824 characters)'
- fi
- fi # end of overwriting check
- echo shar: "End of archive 7 (of 8)."
- cp /dev/null ark7isdone
- DONE=true
- for I in 1 2 3 4 5 6 7 8; do
- if test -! f ark${I}isdone; then
- echo "You still need to run archive ${I}."
- DONE=false
- fi
- done
- case $DONE in
- true)
- echo "You have run all 8 archives."
- echo 'See the README file'
- ;;
- esac
- ## End of shell archive.
- exit 0
-