v08i046: Account creation/manipulation program, Part06/08
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Sat Feb 7 07:18:08 AEST 1987
Submitted by: Kyle Jones <xanth!kyle>
Mod.sources: Volume 8, Issue 46
Archive-name: mcp/Part06
#! /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 6 (of 8)."
# Contents: src/gpa.c src/init.c src/job.c src/lastlog.c src/list.c
# src/lists.c src/macros.h src/mem.c src/mem.h MANIFEST
# Wrapped by rs at mirror on Fri Feb 6 15:56:07 1987
PATH=/bin:/usr/bin:/usr/ucb; export PATH
echo shar: extracting "'src/gpa.c'" '(2500 characters)'
if test -f 'src/gpa.c' ; then
echo shar: will not over-write existing file "'src/gpa.c'"
else
sed 's/^X//' >src/gpa.c <<'@//E*O*F src/gpa.c//'
X/***************************************************************************\
X* *
X* gpa.c *
X* *
X* These are the support routines for the global_pointer_array that all *
X* routines that get input from the tty use, excluding main(). *
X* *
X* Routines needing an argv like array to store pointers call get_gpa() *
X* which returns a pointer to chunk of the global_pointer_array of the *
X* requested size. Such a central array is needed to insure that all *
X* allocations via savestr() in get_line() are freed by a call to *
X* free_gpa(). This is insured even from interrupts by always calling *
X* free_gpa() in main() before getting the next command line. *
X* *
X* clear_gpa() is used by routines that already have made a call to *
X* get_gpa() and want to reuse the space provided, but need to be sure that *
X* any leftover pointers freed before they are overwritten. *
X* *
X* ---------- *
X* *
X* get_gpa() get a chunk of the global_pointer_array *
X* *
X* clear_gpa() free the pointers stored in a certian part *
X* of the array for reuse. *
X* *
X* free_gpa() free all pointers in the global_pointer_array *
X* and reset the array index to zero. *
X* *
X* pop_gpa() used to free last allocated part of the *
X* global_pointer_array. Designed for use by routines *
X* in yesno.c. No other routines should need call this. *
X* *
X\***************************************************************************/
X
X#include "sysdep.h"
X#include "mem.h"
X#include "gpa.h"
X
Xstatic addr global_pointer_array[G_P_A__SIZE];
Xstatic int gpaindex;
X
Xaddr *
Xget_gpa(n)
Xint n;
X
X{
X gpaindex += n;
X return &global_pointer_array[gpaindex-n];
X}
X
Xfree_gpa()
X
X{
X int i;
X
X critical();
X for (i=0; i<G_P_A__SIZE; i++)
X if (global_pointer_array[i]) {
X FREEMEM((char *)global_pointer_array[i]);
X global_pointer_array[i] = NIL;
X }
X gpaindex = 0;
X non_critical();
X return;
X}
X
Xint clear_gpa(p, n)
Xaddr *p;
Xint n;
X
X{
X register int i;
X
X for (i=0; i<n; i++)
X if (p[i]) {
X /*
X * Can't let user interrupt between the FREEMEM
X * and zeroing the pointer.
X */
X critical();
X FREEMEM((char *)p[i]);
X p[i] = NIL;
X non_critical();
X }
X return 1; /* used as do-while constant */
X}
X
Xpop_gpa(n)
Xint n;
X
X{
X (void) clear_gpa(&global_pointer_array[gpaindex-n], n);
X gpaindex -= n;
X return;
X}
@//E*O*F src/gpa.c//
if test 2500 -ne "`wc -c <'src/gpa.c'`"; then
echo shar: error transmitting "'src/gpa.c'" '(should have been 2500 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'src/init.c'" '(16005 characters)'
if test -f 'src/init.c' ; then
echo shar: will not over-write existing file "'src/init.c'"
else
sed 's/^X//' >src/init.c <<'@//E*O*F src/init.c//'
X#include <stdio.h>
X#include <sys/file.h>
X#include <sys/types.h>
X#include <pwd.h>
X#include <grp.h>
X#include <lastlog.h>
X#include <strings.h>
X#include <errno.h>
X#include "sysdep.h"
X#include "macros.h"
X#include "mem.h"
X#include "sort.h"
X#include "lists.h"
X#include "save.h"
X#include "sig.h"
X#include "class.h"
X#include "account.h"
X#include "command.h"
X#include "groupmap.h"
X#include "range.h"
X#ifdef SENDMAIL
X#include "alias.h"
X#endif
X
X#ifdef sun
X# ifdef DOFILES
X/*
X * Lint complains about all the unused functions declared in netdb.h
X * and mntent.h... but these functions are >>declared<< NOT
X * >>defined<< so lint should SHUT UP about this!! Since it doesn't,
X * we work around its ignorance.
X */
X# ifndef lint
X# include <mntent.h>
X# include <netdb.h>
X# else
Xstruct servent {
X char *s_name; /* official service name */
X char **s_aliases; /* alias list */
X int s_port; /* port # */
X char *s_proto; /* protocol to use */
X};
Xstruct servent *getservbyname();
X
X# define MNTTAB "/etc/fstab"
Xstruct mntent{
X char *mnt_fsname; /* name of mounted file system */
X char *mnt_dir; /* file system path prefix */
X char *mnt_type; /* MNTTYPE_* */
X char *mnt_opts; /* MNTOPT* */
X int mnt_freq; /* dump frequency, in days */
X int mnt_passno; /* pass number on parallel fsck */
X};
Xstruct mntent *getmntent();
XFILE *setmntent();
X# endif lint
X# endif DOFILES
X#endif sun
X
Xstatic char *e1 = "password file has more lines than accounts file.";
Xstatic char *e2 = "accounts file has more lines than password file.";
Xstatic char *e3 = "line %d: login name not the same in accounts/passwd.";
X
Xextern struct lastlog *getlluid(), *getllent();
Xextern struct list YesNo, Titles, Suffixes, History;
Xextern char *sprintf(), *getpass();
X
X#ifdef BSD4_3
Xuid_t geteuid(), getuid();
Xchar *getwd();
Xtime_t time();
X#endif
X
X#ifdef SENDMAIL
Xextern addalias(), addtoalias(), bindclass(), bindgroup(), bindsig();
Xextern desalias();
Xextern rmalias(), rmfromalias(), ubindclass(), ubindgroup(), ubindsig();
Xextern updalias();
X#endif
X#ifdef HELPDIR
Xextern descommand(), whatis();
X#endif
Xextern addclass(), addgroup(), addrange(), addsig();
Xextern addtoclass(), addtogroup();
Xextern addtosig(), adduser(), addvig();
Xextern ckpchanges();
Xextern deschanges(), desclass();
Xextern descryos(), desdeadbeats(), desgroup(), desinactives(), desrange();
Xextern dessig(), desuser(), disableuser(), exitmcp();
Xextern freezedeadbeats(), freezeinactives(), freezeuser();
Xextern listgeneric(), listcryos();
Xextern listdeadbeats(), listinactives();
Xextern loadfile(), pausemcp(), rmclass();
Xextern rmcryos(), rmfromclass(), rmfromgroup(), rmfromsig();
Xextern rmgroup();
Xextern rmrange(), rmsig(), rmuser(), rmvig(), savechanges(), saveandexit();
Xextern shellescape();
Xextern updclass(), updgroup(), updrange(), updsig(), upduser();
X
Xstruct command Ctable[] = {
X#ifdef SENDMAIL
X { "add-alias", addalias, 1 },
X#endif
X { "add-class", addclass, 1 },
X { "add-group", addgroup, 1 },
X { "add-range", addrange, 1 },
X { "add-sig", addsig, 1 },
X#ifdef SENDMAIL
X { "add-to-alias", addtoalias, 1 },
X#endif
X { "add-to-class", addtoclass, 1 },
X { "add-to-group", addtogroup, 1 },
X { "add-to-sig", addtosig, 1 },
X { "add-user", adduser, 1 },
X { "add-vig", addvig, 1 },
X#ifdef SENDMAIL
X { "bind-group", bindgroup, 1 },
X { "bind-class", bindclass, 1 },
X { "bind-sig", bindsig, 1 },
X#endif
X { "checkpoint-changes", ckpchanges, 1 },
X#ifdef SENDMAIL
X { "describe-alias", desalias, 0 },
X#endif
X { "describe-class", desclass, 0 },
X { "describe-changes", deschanges, 1 },
X#ifdef HELPDIR
X { "describe-command", descommand, 0 },
X#endif
X { "describe-cryos", descryos, 0 },
X { "describe-deadbeats", desdeadbeats, 0 },
X { "describe-group", desgroup, 0 },
X { "describe-inactives", desinactives, 0 },
X { "describe-range", desrange, 0 },
X { "describe-sig", dessig, 0 },
X { "describe-user", desuser, 0 },
X { "disable-user", disableuser, 1 },
X { "exit-mcp", exitmcp, 0 },
X { "freeze-deadbeats", freezedeadbeats, 1 },
X { "freeze-inactives", freezeinactives, 1 },
X { "freeze-user", freezeuser, 1 },
X#ifdef SENDMAIL
X { "list-aliases", listgeneric, 0 },
X#endif
X { "list-classes", listgeneric, 0 },
X { "list-commands", listgeneric, 0 },
X { "list-cryos", listcryos, 0 },
X { "list-deadbeats", listdeadbeats, 0 },
X { "list-groups", listgeneric, 0 },
X { "list-inactives", listinactives, 0 },
X { "list-ranges", listgeneric, 0 },
X { "list-sigs", listgeneric, 0 },
X { "list-users", listgeneric, 0 },
X { "list-vigs", listgeneric, 0 },
X { "load-file", loadfile, 1 },
X { "pause-mcp", pausemcp, 0 },
X#ifdef SENDMAIL
X { "remove-alias", rmalias, 1 },
X#endif
X { "remove-class", rmclass, 1 },
X { "remove-cryos", rmcryos, 1 },
X#ifdef SENDMAIL
X { "remove-from-alias", rmfromalias, 1 },
X#endif
X { "remove-from-class", rmfromclass, 1 },
X { "remove-from-group", rmfromgroup, 1 },
X { "remove-from-sig", rmfromsig, 1 },
X { "remove-group", rmgroup, 1 },
X { "remove-range", rmrange, 1 },
X { "remove-sig", rmsig, 1 },
X { "remove-user", rmuser, 1 },
X { "remove-vig", rmvig, 1 },
X { "save-and-exit", saveandexit, 1 },
X { "save-changes", savechanges, 1 },
X { "shell-escape", shellescape, 0 },
X#ifdef SENDMAIL
X { "unbind-group", ubindgroup, 1 },
X { "unbind-class", ubindclass, 1 },
X { "unbind-sig", ubindsig, 1 },
X { "update-alias", updalias, 1 },
X#endif
X { "update-class", updclass, 1 },
X { "update-group", updgroup, 1 },
X { "update-range", updrange, 1 },
X { "update-sig", updsig, 1 },
X { "update-user", upduser, 1 },
X#ifdef HELPDIR
X { "what-is", whatis, 0 },
X#endif
X { (char *) 0, (int (*)())0, 0 }
X};
X
X#ifdef HELPDIR
Xstatic char *TermTable[] = {
X# ifdef SENDMAIL
X "alias",
X# endif
X "class",
X "cryo",
X "deadbeat",
X "gid",
X "inactive",
X "range",
X "sig",
X "uid",
X "vig",
X (char *)0
X};
X#endif
X
Xstruct list TempLists; /* list of lists to freed */
X#ifdef SENDMAIL
Xstruct list Aliases; /* alias name completion list */
Xstruct list AliasList; /* list of alias structures */
X#endif
Xstruct list AllCommands; /* complete list of mcp commands */
Xstruct list Commands; /* commands this user is allowed */
Xstruct list Users; /* user name completion list */
Xstruct list AccountList; /* list of account structures */
Xstruct list Classes; /* class name completion list */
Xstruct list ClassList; /* list of class structures */
Xstruct list Groups; /* group name completion list */
Xstruct list GroupMapList; /* list of groupmap structures */
Xstruct list Ranges; /* range name completion list */
Xstruct list RangeList; /* list of range structures */
Xstruct list Sigs; /* sig name completion list */
Xstruct list SigList; /* list of sig structures */
Xstruct list Jobs; /* list of job structures */
X#ifdef HELPDIR
Xstruct list Terms; /* list of terms mcp can define */
X#endif
Xstruct list Shells; /* list of shells (from SHELLFILE) */
Xstruct list Vigs; /* vig completion list */
Xstruct list Null_List; /* empty list */
X
Xint ModBits; /* flags denoting modified files */
Xint DevTty; /* descriptor for diagnostic output
X and prompts. DevTty = 2 for non-
X interactive runs. */
Xtime_t PWLockTime; /* last modify time for /etc/passwd */
Xint root; /* is this the super-user? */
Xint kids; /* current # of child processes */
Xint NCommands; /* # of commands user can execute */
X
Xaddr DEF_SHELL; /* default shell */
Xchar Working_Directory[LONG_BUF]; /* current working driectory */
X#ifdef sun
Xint IsRemote; /* must we use remote commands */
Xchar HostName[MEDIUM_BUF]; /* current hostname */
X# ifdef DOFILES
Xchar FileServer[MEDIUM_BUF]; /* hostname of file server */
Xchar MountDirectory[MEDIUM_BUF]; /* remote mount point */
Xchar RemotePassword[SHORT_BUF]; /* root password of fileserver */
Xu_short ExecTcpPort; /* port for exec/tcp service */
X# endif
X#endif
X
X
Xinit_lists(interactive)
Xint interactive;
X
X{
X FILE *fp;
X flexaddr p;
X#ifdef SENDMAIL
X struct alias al, *al2;
X struct groupmap *gm2;
X#endif
X struct account ac, *ac2;
X struct passwd *pw;
X struct group *gr;
X struct groupmap gm;
X struct sig sg, *sg2;
X struct class cs, *cs2;
X struct range rg, *rg2;
X struct lastlog *ll;
X char buf[LONG_BUF], errmsg[LONG_BUF], sh[MEDIUM_BUF], *cp;
X int indx, lineno = 0;
X
X if (interactive) msg("Loading password and accounts...");
X (void) setpwent();
X (void) setacent();
X (void) setllent();
X while ((pw = getpwent()) != (struct passwd *)0) {
X ac2 = getacent();
X if (!ac2)
X fatal(e1);
X lineno++;
X if (!eq((char *)ac2->ac_name, pw->pw_name)) {
X (void) sprintf(errmsg, e3, lineno);
X fatal(errmsg);
X }
X ac.ac_uid = pw->pw_uid;
X ac.ac_gid = pw->pw_gid;
X savestr((char **)&ac.ac_name, pw->pw_name);
X savestr((char **)&ac.ac_gecos, pw->pw_gecos);
X savestr((char **)&ac.ac_passwd, pw->pw_passwd);
X savestr((char **)&ac.ac_dir, pw->pw_dir);
X savestr((char **)&ac.ac_shell, pw->pw_shell);
X savestr((char **)&ac.ac_realname, (char *)ac2->ac_realname);
X savestr((char **)&ac.ac_id, (char *)ac2->ac_id);
X duplist(&ac.ac_groups, &ac2->ac_groups);
X duplist(&ac.ac_classes, &ac2->ac_classes);
X duplist(&ac.ac_sigs, &ac2->ac_sigs);
X#ifdef SENDMAIL
X duplist(&ac.ac_aliases, &ac2->ac_aliases);
X#endif
X ll = getlluid(ac.ac_uid);
X bcopy(&ac.ac_ll, ll, sizeof (struct lastlog));
X genlistadd(&AccountList, (addr)&ac, sizeof (struct account));
X strlistadd(&Users, pw->pw_name);
X }
X (void) endpwent();
X endllent();
X if (getacent()) fatal(e2);
X (void) endacent();
X
X if (interactive) msg("Loading groups...");
X zerolist(&gm.gm_aliases);
X (void) setgrent();
X while ((gr = getgrent()) != (struct group *)0) {
X zerolist(&gm.gm_mem);
X#ifdef SENDMAIL
X zerolist(&gm.gm_aliases);
X#endif
X gm.gm_gid = gr->gr_gid;
X savestr(&gm.gm_name, gr->gr_name);
X savestr(&gm.gm_passwd, gr->gr_passwd);
X for (indx=0; gr->gr_mem[indx]; indx++)
X strlistadd(&gm.gm_mem, gr->gr_mem[indx]);
X sort_list(&gm.gm_mem, pstrcmp);
X genlistadd(&GroupMapList, (addr)&gm, sizeof(struct groupmap));
X strlistadd(&Groups, gr->gr_name);
X }
X (void) endgrent();
X if (interactive) msg("Loading classes...");
X#ifdef SENDMAIL
X zerolist(&cs.cs_aliases);
X#endif
X setcsent();
X while (cs2 = getcsent()) {
X savestr(&cs.cs_name, cs2->cs_name);
X savestr(&cs.cs_desc, cs2->cs_desc);
X cs.cs_dsize = cs2->cs_dsize;
X cs.cs_exptime = cs2->cs_exptime;
X genlistadd(&ClassList, (addr)&cs, sizeof (struct class));
X strlistadd(&Classes, cs.cs_name);
X }
X endcsent();
X if (interactive) msg("Loading sigs...");
X#ifdef SENDMAIL
X zerolist(&sg.sg_aliases);
X#endif
X setsgent();
X while (sg2 = getsgent()) {
X savestr(&sg.sg_name, sg2->sg_name);
X savestr(&sg.sg_desc, sg2->sg_desc);
X sg.sg_dsize = sg2->sg_dsize;
X sg.sg_exptime = sg2->sg_exptime;
X genlistadd(&SigList, (addr)&sg, sizeof (struct sig));
X strlistadd(&Sigs, sg.sg_name);
X }
X endsgent();
X if (interactive) msg("Loading range table...");
X setrgent();
X while (rg2 = getrgent()) {
X savestr(&rg.rg_name, rg2->rg_name);
X rg.rg_mode = rg2->rg_mode;
X rg.rg_from = rg2->rg_from;
X rg.rg_to = rg2->rg_to;
X genlistadd(&RangeList, (addr)&rg, sizeof (struct range));
X strlistadd(&Ranges, rg.rg_name);
X }
X endrgent();
X
X if (interactive) msg("Loading vigs...");
X fp = fopen(VIGFILE, "r");
X if (fp != NULL) {
X while (fscanf(fp, "%s", buf) != EOF)
X strlistadd(&Vigs, buf);
X (void) fclose(fp);
X }
X
X#ifdef SENDMAIL
X /*
X * Must sort here so that get{cs,gm,sg}nam() calls will work.
X */
X if (interactive) msg("Loading and binding sendmail aliases...");
X sort_list(&Groups, pstrcmp);
X sort_list(&ClassList, classcmp);
X sort_list(&SigList, sigcmp);
X setalent();
X while (al2 = getalent()) {
X savestr(&al.al_name, al2->al_name);
X duplist(&al.al_addresses, &al2->al_addresses);
X duplist(&al.al_groups, &al2->al_groups);
X duplist(&al.al_classes, &al2->al_classes);
X duplist(&al.al_sigs, &al2->al_sigs);
X genlistadd(&AliasList, (addr)&al, sizeof (struct alias));
X strlistadd(&Aliases, al.al_name);
X for (indx=0; indx < al.al_groups.l_count; indx++) {
X cp = (char *)al.al_groups.l_list[indx];
X gm2 = getgmnam(cp);
X if (!gm2)
X continue;
X strlistadd(&gm2->gm_aliases, al.al_name);
X sort_list(&gm2->gm_aliases, pstrcmp);
X }
X for (indx=0; indx < al.al_classes.l_count; indx++) {
X cp = (char *)al.al_classes.l_list[indx];
X cs2 = getcsnam(cp);
X if (!cs2)
X continue;
X strlistadd(&cs2->cs_aliases, al.al_name);
X sort_list(&cs2->cs_aliases, pstrcmp);
X }
X for (indx=0; indx < al.al_sigs.l_count; indx++) {
X cp = (char *)al.al_sigs.l_list[indx];
X sg2 = getsgnam(cp);
X if (!sg2)
X continue;
X strlistadd(&sg2->sg_aliases, al.al_name);
X sort_list(&sg2->sg_aliases, pstrcmp);
X }
X }
X endalent();
X#endif
X /*
X * If this is not an interactive session there is no need
X * to initialize the lists that are only used when mcp
X * is running interactively.
X */
X if (!interactive) goto sort_em;
X
X msg("Commands...");
X for (indx=0; Ctable[indx].c_name; indx++) {
X if (root || !Ctable[indx].c_su)
X strlistadd(&Commands, Ctable[indx].c_name);
X strlistadd(&AllCommands, Ctable[indx].c_name);
X }
X NCommands = indx;
X qsort((char *)Ctable, NCommands, sizeof (struct command), commcmp);
X
X#ifdef HELPDIR
X msg("Building term table...");
X for (indx=0; TermTable[indx]; indx++)
X strlistadd(&Terms, TermTable[indx]);
X#endif
X msg("Loading shell table...");
X fp = fopen(SHELLFILE, "r");
X if (fp != NULL) {
X while (fgets(buf, LONG_BUF, fp) != NULL) {
X cp = index(buf, '#');
X if (cp) *cp = '\0';
X if (sscanf(buf, "%s", sh) != 1)
X continue;
X strlistadd(&Shells, sh);
X }
X (void) fclose(fp);
X }
X p.p_cp = (Shells.l_count ? (char *) Shells.l_list[0] : "/bin/sh");
X DEF_SHELL = p.p_ap;
X
Xsort_em:
X if (interactive) msg("Sorting lists...");
X sort_list(&AccountList, acctcmp);
X sort_list(&GroupMapList, gmapcmp);
X sort_list(&Users, pstrcmp);
X sort_list(&Classes, pstrcmp);
X sort_list(&Sigs, pstrcmp);
X sort_list(&Ranges, pstrcmp);
X sort_list(&RangeList, rangecmp);
X sort_list(&Vigs, pstrcmp);
X#ifdef SENDMAIL
X sort_list(&AliasList, aliascmp);
X sort_list(&Aliases, pstrcmp);
X#else
X sort_list(&Groups, pstrcmp);
X sort_list(&ClassList, classcmp);
X sort_list(&SigList, sigcmp);
X#endif
X if (interactive) {
X sort_list(&Titles, pstrcmp);
X sort_list(&Suffixes, pstrcmp);
X sort_list(&YesNo, pstrcmp);
X sort_list(&Shells, pstrcmp);
X sort_list(&Commands, pstrcmp);
X sort_list(&AllCommands, pstrcmp);
X#ifdef HELPDIR
X sort_list(&Terms, pstrcmp);
X#endif
X msg("and...");
X zerolist(&History);
X zerolist(&TempLists);
X msg("");
X }
X return;
X}
X
Xinit_tty(interactive)
Xint interactive;
X
X{
X extern int errno;
X long lseek();
X
X if (!interactive) {
X DevTty = 2;
X return;
X }
X if ((DevTty = open("/dev/tty", O_RDWR)) < 0) {
X perror("/dev/tty");
X goodbye(1);
X }
X if (lseek(0, 0L, L_INCR) == -1) {
X if (errno == ESPIPE)
X err("mcp reading from a pipe...");
X }
X else if (!isatty(0))
X err("mcp reading from a file...");
X return;
X}
X
Xinit_identities()
X
X{
X#ifdef sun
X# ifdef DOFILES
X FILE *mnf;
X struct mntent *mn;
X struct servent *sv;
X char *cp, prompt[MEDIUM_BUF];
X# endif
X#endif
X root = !(getuid() && geteuid());
X if (!getwd(Working_Directory))
X fatal1("getwd() failed!?: %s", Working_Directory);
X srandom(getpid() + getppid() + time((time_t *)0));
X#ifdef sun
X if (gethostname(HostName, MEDIUM_BUF) == -1) {
X perr("gethostname");
X fatal("mcp: Sorry, but I must have a hostname.");
X }
X# ifdef DOFILES
X if (!root) return;
X mnf = setmntent(MNTTAB, "r");
X if (mnf == NULL) {
X fatal1("can't open %s", MNTTAB);
X goodbye(1);
X }
X while (mn = getmntent(mnf))
X if (eq(mn->mnt_dir, USERDIR))
X break;
X if (mn && eq(mn->mnt_type, "nfs")) {
X cp = index(mn->mnt_fsname, ':');
X *cp++ = '\0';
X (void) strcpy(FileServer, mn->mnt_fsname);
X (void) strcpy(MountDirectory, cp);
X sv = getservbyname("exec", "tcp");
X if (!sv)
X fatal("mcp: can't find service exec/tcp");
X ExecTcpPort = sv->s_port;
X /* root is not trusted over the network */
X (void) sprintf(prompt, "Root password on %s:", FileServer);
X cp = getpass(prompt);
X (void) strcpy(RemotePassword, cp);
X if (DoRemote("/bin/true") == 0)
X fatal("Sorry");
X IsRemote = 1;
X }
X (void) endmntent(mnf);
X# endif
X#endif
X return;
X}
@//E*O*F src/init.c//
if test 16005 -ne "`wc -c <'src/init.c'`"; then
echo shar: error transmitting "'src/init.c'" '(should have been 16005 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'src/job.c'" '(8459 characters)'
if test -f 'src/job.c' ; then
echo shar: will not over-write existing file "'src/job.c'"
else
sed 's/^X//' >src/job.c <<'@//E*O*F src/job.c//'
X/****************************************************************************\
X* *
X* job.c *
X* *
X* add_job() add a job to the job list for later execution. *
X* do_jobs() do the jobs in the job list. *
X* rmmail() remove a user's mail *
X* rmsmail() remove a user's secretmail *
X* omni_chown() change the ownership of all a user's files to another uid *
X* *
X* Also lastlog entries are updated here, although the actual routine that *
X* writes the file is in lastlog.c . Directories are made and moved around *
X* here, but there are system calls that do these things. *
X* *
X\****************************************************************************/
X
X#include <stdio.h>
X#include <strings.h>
X#include <sys/wait.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include <sys/resource.h
X#include <sys/dir.h>
X#include <lastlog.h>
X#include "sysdep.h"
X#include "mem.h"
X#include "lists.h"
X#include "job.h"
X
X#ifdef sun
X# ifdef DOFILES
Xextern u_short ExecTcpPort;
Xextern char FileServer[], MountDirectory[], RemotePassword[];
Xextern int IsRemote;
Xextern char HostName[];
X# endif
X#endif
Xextern struct list Jobs;
Xchar *re_comp(), *sprintf();
Xextern int kids;
X
X/* ARGSUSED */
Xadd_job(todo, arg1, arg2, arg3)
Xint todo;
Xaddr arg1, arg2, arg3;
X
X{
X struct job jb;
X
X jb.jb_todo = todo;
X switch (jb.jb_todo) {
X case JB_LASTLOG:
X jb.jb_uid = (int) *arg1;
X jb.jb_addr = MEM(sizeof (struct lastlog));
X bcopy(jb.jb_addr, arg2, sizeof (struct lastlog));
X break;
X
X#ifdef DOFILES
X case JB_MKDIR:
X savestr(&jb.jb_name, (char *) arg1);
X jb.jb_uid = (int) *arg2;
X jb.jb_gid = (int) *arg3;
X break;
X
X case JB_MV:
X savestr(&jb.jb_oldname, (char *) arg1);
X savestr(&jb.jb_name, (char *) arg2);
X break;
X case JB_RMDIR:
X case JB_RMMAIL:
X savestr(&jb.jb_name, (char *) arg1);
X break;
X
X case JB_OMNICHOWN:
X jb.jb_olduid = (int) *arg1;
X jb.jb_uid = (int) *arg2;
X break;
X#endif
X
X default:
X return;
X }
X genlistadd(&Jobs, (addr) &jb, sizeof (struct job));
X return;
X}
X
Xdo_jobs()
X
X{
X struct job *jb;
X struct lastlog ll;
X int currjobs, success;
X char errmsg[LONG_BUF];
X
X currjobs = Jobs.l_count;
X while (currjobs--) {
X jb = (struct job *) listpop(&Jobs);
X success = 0;
X switch (jb->jb_todo) {
X case JB_LASTLOG:
X bcopy(&ll, jb->jb_addr, sizeof (struct lastlog));
X addllent(&ll, jb->jb_uid);
X FREEMEM((char *)jb->jb_addr);
X success++;
X break;
X
X#ifdef DOFILES
X case JB_MKDIR:
X# ifdef sun
X if (IsRemote) {
X success = makedir(jb->jb_name, 0755,
X jb->jb_uid, jb->jb_gid);
X if (success) FREEMEM(jb->jb_name);
X break;
X }
X else
X# endif
X /*
X * Here we assume if the mkdir() fails the directory
X * must already be there.
X */
X if (mkdir(jb->jb_name, 0755) == 0) {
X (void) chown(jb->jb_name,
X jb->jb_uid, jb->jb_gid);
X }
X FREEMEM(jb->jb_name);
X success++;
X break;
X
X case JB_MV:
X# ifdef sun
X if (IsRemote) {
X success=rrename(jb->jb_oldname, jb->jb_name);
X if (success) {
X FREEMEM(jb->jb_name);
X FREEMEM(jb->jb_oldname);
X }
X }
X else
X# endif
X if (rename(jb->jb_oldname, jb->jb_name) == -1) {
X perr("rename");
X err2("rename %s -> %s failed.",
X jb->jb_oldname,
X jb->jb_name);
X break;
X }
X success++;
X FREEMEM(jb->jb_name);
X FREEMEM(jb->jb_oldname);
X break;
X
X case JB_RMDIR:
X success = purge(jb->jb_name);
X if (!success) break;
X FREEMEM(jb->jb_name);
X break;
X
X case JB_RMMAIL:
X success = rmmail(jb->jb_name) && rmsmail(jb->jb_name);
X if (!success) break;
X FREEMEM(jb->jb_name);
X break;
X
X case JB_OMNICHOWN:
X success = omni_chown(jb->jb_olduid, jb->jb_uid);
X break;
X#endif
X default:
X (void) sprintf(errmsg,
X "internal error: bad todo in job list (%d)",
X jb->jb_todo);
X err(errmsg);
X success++; /* to get it out of the list */
X break;
X }
X if (success)
X FREEMEM((char *)jb);
X else
X genlistadd(&Jobs, (addr)jb, sizeof (struct job));
X }
X return;
X}
X
X#ifdef DOFILES
Xchar **environ;
X
Xint
Xpurge(path)
Xchar *path;
X
X{
X char command[LONG_BUF];
X addr *v;
X int c, pid;
X#ifdef sun
X int n;
X
X n = strlen(USERDIR)-1;
X if (IsRemote && strncmp(path, USERDIR, n) == 0 && path[n] == '/') {
X (void) strcpy(command, RM);
X (void) strcat(command, " -rf ");
X (void) strcat(command, MountDirectory);
X (void) strcat(command, &path[n]);
X return (DoRemote(command) && !fileexists(path));
X }
X#endif
X (void) strcpy(command, RM);
X (void) strcat(command, " -rf ");
X (void) strcat(command, path);
X c = cut(command);
X v = mkargv(command, c);
X pid = vfork();
X if (pid == -1) {
X err1("can't vfork to remove %s", path);
X return 0;
X }
X if (pid == 0) {
X execve((char *)v[0], (char **)v, environ);
X perr((char *)v[0]);
X _exit(1);
X }
X while (wait((union wait *)0) != pid)
X kids--;
X return !fileexists(path);
X}
X
Xint
Xrmmail(user)
Xchar *user;
X
X{
X if (chdir(MAILSPOOL) == -1) {
X perr(SMAILSPOOL);
X return 0;
X }
X (void) unlink(user);
X return 1;
X}
X
Xint
Xrmsmail(user)
Xchar *user;
X
X{
X DIR *dirp;
X char buf[MEDIUM_BUF];
X struct direct *dp;
X
X if (chdir(SMAILSPOOL) == -1) {
X perr(SMAILSPOOL);
X return 0;
X }
X dirp = opendir(".");
X if (dirp == NULL) {
X err1("can't open %s (read)", SMAILSPOOL);
X return 0;
X }
X (void) sprintf(buf, "%s\\..*", user);
X (void) re_comp(buf);
X for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
X if (re_exec(dp->d_name) == 1)
X (void) unlink(dp->d_name);
X closedir(dirp);
X return 1;
X}
X
X#define OMNIFMT "%s -15 %s %s -user %d -exec %s %d {} ;"
X
X/*
X * When changing file ownerships on Sun's distributed filesystem, we
X * must be careful not to disturb files belonging to a user with the same
X * uid but on another machine!
X */
Xint
Xomni_chown(ouid, nuid)
Xint ouid, nuid;
X
X{
X char command[LONG_BUF];
X# ifdef sun
X char dirbuf[MEDIUM_BUF];
X
X if (IsRemote) {
X(void)sprintf(command, OMNIFMT, NICE, FIND, MountDirectory, ouid, CHOWN,nuid);
X (void) strcat(command, " &");
X if (DoRemote(command) == 0) return 0;
X }
X else {
X (void) sprintf(dirbuf, "%s/%s", USERDIR, HostName);
X(void) sprintf(command, OMNIFMT, NICE, FIND, dirbuf, ouid, CHOWN, nuid);
X if (BackGround(command) == 0) return 0;
X }
X(void) sprintf(command, OMNIFMT, NICE, FIND, SMAILSPOOL, ouid, CHOWN, nuid);
X if (BackGround(command) == 0) return 0;
X(void) sprintf(command, OMNIFMT, NICE, FIND, MAILSPOOL, ouid, CHOWN, nuid);
X if (BackGround(command) == 0) return 0;
X# else
X (void) sprintf(command, OMNIFMT, NICE, FIND, "/", ouid, CHOWN, nuid);
X if (BackGround(command) == 0) return 0;
X# endif
X return 1;
X}
X
XBackGround(command)
Xchar *command;
X
X{
X int c, pid;
X addr *v;
X
X c = cut(command);
X v = mkargv(command, c);
X
X pid = vfork();
X if (pid == -1) {
X perr("can't vfork");
X return 0;
X }
X kids++;
X if (pid == 0) {
X (void) setpgrp(0, getpid());
X execve((char *)*v, (char **)v, environ);
X perr((char *)*v);
X _exit(1);
X }
X (void) setpriority(PRIO_PROCESS, pid, 15);
X return 1;
X}
X
X# ifdef sun
X
Xrrename(from, to)
Xchar *from, *to;
X
X{
X int n;
X char command[LONG_BUF];
X
X n = strlen(USERDIR)-1;
X if (strncmp(from, USERDIR, n) || from[n] != '/') {
X err2("rrename: %s not in %s", from, USERDIR);
X return 0;
X }
X if (strncmp(to, USERDIR, n) || from[n] != '/') {
X err2("rrename: %s not in %s", from, USERDIR);
X return 0;
X }
X (void) sprintf(command, "%s %s%s %s%s", MV, MountDirectory,
X &from[n], MountDirectory, &to[n]);
X return ((!DoRemote(command)) || fileexists(from) || !fileexists(to))
X ? 0 : 1;
X}
X
Xmakedir(path, mode, uid, gid)
Xchar *path;
Xint mode, uid, gid;
X
X{
X int n;
X char command[LONG_BUF];
X
X n = strlen(USERDIR);
X if (strncmp(path, USERDIR, n) || path[n] != '/') {
X err2("makedir: %s not in %s", path, USERDIR);
X return 0;
X }
X(void) sprintf(command, "%s %s%s", MKDIR, MountDirectory, &path[n]);
X (void) DoRemote(command);
X(void) sprintf(command, "%s %d %s%s", CHOWN, uid, MountDirectory, &path[n]);
X (void) DoRemote(command);
X(void) sprintf(command, "%s %d %s%s", CHGRP, gid, MountDirectory, &path[n]);
X (void) DoRemote(command);
X(void) sprintf(command, "%s %o %s%s", CHMOD, mode, MountDirectory, &path[n]);
X (void) DoRemote(command);
X return 1;
X}
X
Xstatic
XTweedle(d)
Xint d;
X
X{
X char c;
X
X (void) shutdown(d, 1);
X while (read(d, &c, 1) == 1)
X (void) write(1, &c, 1);
X (void) fsync(1);
X return;
X}
X
Xint
XDoRemote(command)
Xchar *command;
X
X{
X char f[MEDIUM_BUF], *h[1];
X int d;
X
X (void) strcpy(f, FileServer);
X *h = f;
X d = rexec(h, ExecTcpPort, "root", RemotePassword, command, (int *)0);
X if (d == -1) return 0;
X Tweedle(d);
X (void) close(d);
X return 1;
X}
X
X# endif
X#endif
@//E*O*F src/job.c//
if test 8459 -ne "`wc -c <'src/job.c'`"; then
echo shar: error transmitting "'src/job.c'" '(should have been 8459 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'src/lastlog.c'" '(1294 characters)'
if test -f 'src/lastlog.c' ; then
echo shar: will not over-write existing file "'src/lastlog.c'"
else
sed 's/^X//' >src/lastlog.c <<'@//E*O*F src/lastlog.c//'
X#include <sys/file.h>
X#include <stdio.h>
X#include <sys/types.h>
X#include <lastlog.h>
X#include "sysdep.h"
X#include "mem.h"
X#include "save.h"
X
Xstatic struct lastlog zero;
Xstruct lastlog ll;
Xlong lseek();
X
Xint LL_FileDes = UNDEFINED;
X
Xsetllent()
X
X{
X if (LL_FileDes == UNDEFINED) {
X LL_FileDes = open(LASTLOG, O_RDONLY);
X if (LL_FileDes < 0) {
X perr(LASTLOG);
X goodbye(1);
X }
X }
X lseek(LL_FileDes, (long)0, L_SET)<0&&perr("setllent: lseek failed?!");
X return;
X}
X
Xendllent()
X
X{
X if (LL_FileDes == UNDEFINED)
X return;
X (void) close(LL_FileDes);
X LL_FileDes = UNDEFINED;
X return;
X}
X
Xstruct lastlog *
Xgetllent()
X
X{
X if (LL_FileDes == UNDEFINED)
X setllent();
X if (read(LL_FileDes, (char *)&ll, sizeof ll) != sizeof ll)
X return(&zero);
X else
X return(&ll);
X}
X
Xstruct lastlog *
Xgetlluid(uid)
Xint uid;
X
X{
X if (LL_FileDes == UNDEFINED)
X setllent();
X lseek(LL_FileDes, (long)(uid * sizeof(struct lastlog)), L_SET)<0
X && perr("getlluid: lseek failed!?");
X return(getllent());
X}
X
Xaddllent(lp, uid)
Xstruct lastlog *lp;
Xint uid;
X
X{
X int fd;
X
X fd = open(LASTLOG, O_WRONLY);
X if (fd < 0) {
X perr(LASTLOG);
X return;
X }
X lseek(fd, (long)(uid * sizeof(struct lastlog)), L_SET)<0&&
X panic("addllent: lseek failed!?");
X (void) write(fd, (char *)lp, sizeof(struct lastlog));
X (void) close(fd);
X return;
X}
@//E*O*F src/lastlog.c//
if test 1294 -ne "`wc -c <'src/lastlog.c'`"; then
echo shar: error transmitting "'src/lastlog.c'" '(should have been 1294 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'src/list.c'" '(3995 characters)'
if test -f 'src/list.c' ; then
echo shar: will not over-write existing file "'src/list.c'"
else
sed 's/^X//' >src/list.c <<'@//E*O*F src/list.c//'
X/****************************************************************************\
X* *
X* list.c *
X* *
X* Code for the list- commands. listgeneric() just chooses and prints the *
X* appropriate completion list. The other routines handle special cases for *
X* which there are no completion lists kept. *
X* *
X\****************************************************************************/
X
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 "account.h"
X#ifdef SENDMAIL
X#include "alias.h"
X#endif
X#include "groupmap.h"
X#include "job.h"
X
X#ifdef BSD4_3
Xtime_t time();
X#endif
X
X#ifdef SENDMAIL
Xextern struct list Aliases;
X#endif
Xextern struct list Users, Groups, Vigs, Ranges, Classes, Sigs;
Xextern struct list AccountList, AllCommands;
Xchar *sprintf();
Xstruct list *picklist();
Xstatic char *allv[2] = { ".*", 0 };
X
Xlistgeneric(c, v)
Xint c;
Xaddr *v;
X
X{
X int count;
X struct list *List;
X
X List = picklist((char *)v[0]);
X c--; v++;
X if (c == 0) {
X (void) showlist(List, (addr *)allv);
X count = List->l_count;
X }
X else
X count = showlist(List, v);
X if (count)
X (void) printf("%d listed\n", count);
X return;
X}
X
Xlistcryos(c, v)
Xint c;
Xaddr *v;
X
X{
X static struct list cryos;
X struct account *ac;
X int indx, count;
X
X zerolist(&cryos);
X tmplistadd(&cryos);
X for (indx=0; indx < AccountList.l_count; indx++) {
X ac = (struct account *) AccountList.l_list[indx];
X if (eq((char *)ac->ac_shell, FREEZE_SH))
X strlistadd(&cryos, (char *)ac->ac_name);
X }
X c--; v++;
X if (c == 0) {
X (void) showlist(&cryos, (addr *)allv);
X count = cryos.l_count;
X }
X else
X count = showlist(&cryos, v);
X if (count)
X (void) printf("%d listed\n", count);
X return;
X}
X
Xlistdeadbeats(c, v)
Xint c;
Xaddr *v;
X
X{
X static struct list deadbeats;
X struct account *ac;
X struct groupmap *gm;
X int indx, count;
X char errmsg[LONG_BUF];
X
X zerolist(&deadbeats);
X tmplistadd(&deadbeats);
X for (indx=0; indx < AccountList.l_count; indx++) {
X ac = (struct account *) AccountList.l_list[indx];
X if (ac->ac_classes.l_count)
X continue;
X if (ac->ac_sigs.l_count)
X continue;
X /*
X * Cryos are not deadbeats.
X */
X if (eq(ac->ac_shell, FREEZE_SH))
X continue;
X gm = getgmgid(ac->ac_gid);
X if (!gm) {
X (void) sprintf(errmsg,
X "no group for gid %d!",
X ac->ac_gid);
X err(errmsg);
X return;
X }
X if (vigexists(gm->gm_name))
X continue;
X strlistadd(&deadbeats, (char *)ac->ac_name);
X }
X c--; v++;
X if (c == 0) {
X (void) showlist(&deadbeats, (addr *)allv);
X count = deadbeats.l_count;
X }
X else
X count = showlist(&deadbeats, v);
X if (count)
X (void) printf("%d listed\n", count);
X return;
X}
X
Xlistinactives(c, v)
Xint c;
Xaddr *v;
X
X{
X static struct list inactives;
X struct account *ac;
X struct groupmap *gm;
X int indx, count;
X time_t now;
X long toolong;
X char errmsg[LONG_BUF];
X
X if ( c < 2 ) {
X err1("usage: %s <days> [expr ...]", (char *)v[0]);
X return;
X }
X if (!validint((char *)v[1])) {
X err2("%s: %s doesn't make sense as a number", (char *)v[0],
X (char *)v[1]);
X return;
X }
X toolong = atoi((char *)v[1]) * 86400;
X
X zerolist(&inactives);
X tmplistadd(&inactives);
X now = time((time_t *)0);
X for (indx=0; indx < AccountList.l_count; indx++) {
X ac = (struct account *) AccountList.l_list[indx];
X if ((long)(now - ac->ac_ll.ll_time) < toolong)
X continue;
X /*
X * Cryos are not inactive.
X */
X if (eq(ac->ac_shell, FREEZE_SH))
X continue;
X /*
X * Vig members are not inactive.
X */
X gm = getgmgid(ac->ac_gid);
X if (!gm) {
X (void) sprintf(errmsg,
X "no group for gid %d!",
X ac->ac_gid);
X err(errmsg);
X return;
X }
X if (vigexists(gm->gm_name))
X continue;
X strlistadd(&inactives, (char *)ac->ac_name);
X }
X c -= 2;
X v += 2;
X if (c == 0) {
X (void) showlist(&inactives, (addr *)allv);
X count = inactives.l_count;
X }
X else
X count = showlist(&inactives, v);
X if (count)
X (void) printf("%d listed\n", count);
X return;
X}
@//E*O*F src/list.c//
if test 3995 -ne "`wc -c <'src/list.c'`"; then
echo shar: error transmitting "'src/list.c'" '(should have been 3995 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'src/lists.c'" '(9337 characters)'
if test -f 'src/lists.c' ; then
echo shar: will not over-write existing file "'src/lists.c'"
else
sed 's/^X//' >src/lists.c <<'@//E*O*F src/lists.c//'
X/************************************************************************\
X* *
X* lists.c *
X* *
X* Routines to maintain, scan and manipulate the generic list structures *
X* that permeate the program. Some of the most oft used routines: *
X* *
X* strlistadd() add to a list of strings *
X* genlistadd() add an abitrary object to a list *
X* strlistdel() delete a string from a list *
X* genlistdel() delete an abitrary object from a list *
X* search_list() search a list for a particular item *
X* tmplistadd() add a list pointer to the queue of string lists *
X* that is freed just before mcp prompt for another *
X* command *
X* freelist() free all memory associated with a list structure *
X* listpop() pop the first pointer from a list *
X* orstrlist() make the union of two string lists *
X* *
X\************************************************************************/
X
X#include <stdio.h>
X#include <strings.h>
X#include <ctype.h>
X#include "sysdep.h"
X#include "macros.h"
X#include "mem.h"
X#include "gpa.h"
X#include "lists.h"
X#include "sort.h"
X
Xextern struct list TempLists;
X
Xchar *
Xskipspace(s)
Xchar *s;
X
X{
X while (*s && isspace(*s))
X s++;
X return(s);
X}
X
X/*
X * Cuts a string of space separated words into a series of null separated
X * words. Spaces may be imbedded in words only when the word is surround
X * ed by double quotes [""]. Returns the number of words in the string.
X */
Xint cut(line)
Xchar *line;
X
X{
X int wc = 0;
X register char *cp;
X
X cp = line;
X if (*line == '\0')
X return(0);
X while ( *line != '\0' ) {
X if ( isspace(*line) ) {
X *cp++ = '\0';
X line++;
X line = skipspace(line);
X }
X else {
X wc++;
X while ( *line ) {
X if (*line == '"') {
X *cp++ = *line++;
X while (*line && *line != '"')
X *cp++ = *line++;
X if (*line == '\0')
X break;
X }
X else if (isspace(*line))
X break;
X *cp++ = *line++;
X }
X }
X }
X return(wc);
X}
X
X/*
X * Makes a vector of pointers to the null separated strings pointed
X * to by line. The number count is needed to keep the thing from
X * going on forever. Note the arg vector is in a static area, and
X * is overwritten by subsequent calls.
X */
Xaddr *
Xmkargv(line, n)
Xchar *line;
Xint n;
X
X{
X static addr argv[G_P_A__SIZE];
X int i;
X flexaddr p;
X
X i = 0;
X p.p_cp = line;
X while ( i < n && i < 128) {
X argv[i] = p.p_ap;
X p.p_cp += strlen(p.p_cp) + 1;
X i++;
X }
X argv[i] = NIL;
X return(argv);
X}
X
X/*
X * Globs the arguments of an argv-like vector into a single string.
X */
Xaddr
Xglob(v)
Xaddr *v;
X
X{
X static addr_t gob[LONG_BUF];
X flexaddr p;
X
X p.p_ap = gob;
X p.p_cp[0] = '\0';
X while ( *v ) {
X (void) strcat(p.p_cp, (char *)*v++);
X (void) strcat(p.p_cp, " ");
X }
X p.p_cp[strlen(p.p_cp)-1] = '\0'; /* remove trailing blank */
X return(gob);
X}
X
Xparse_line(line, cc, vv)
Xchar *line;
Xint *cc;
Xaddr **vv;
X
X{
X *cc = cut(line);
X *vv = mkargv(line, *cc);
X return;
X}
X
Xfreeargv(v)
Xaddr *v;
X
X{
X critical();
X while (*v) {
X FREEMEM((char *)*v);
X *v++ = NIL;
X }
X non_critical();
X}
X
Xint
Xsearch_list(l, s, compfunc, found)
Xstruct list *l;
Xchar *s;
Xint (*compfunc)(), *found;
X
X{
X int lo = 0, hi = l->l_count - 1, middle, compval;
X
X *found = 0;
X while (lo < hi) {
X middle = (lo + hi) / 2;
X if ((compval = (*compfunc)(s, l->l_list[middle])) == 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 (l->l_count && ((*compfunc)(s, l->l_list[lo])) == 0)
X *found = 1;
X return lo;
X}
X
Xfreelist(l)
Xstruct list *l;
X
X{
X register int i;
X
X critical();
X for (i=0; i<l->l_count; i++)
X FREEMEM((char *)l->l_list[i]);
X if (l->l_spacefor > 0)
X FREEMEM((char *)l->l_list);
X l->l_count = l->l_spacefor = 0;
X non_critical();
X return;
X}
X
Xstrlistadd(l, s)
Xstruct list *l;
Xchar *s;
X
X{
X critical();
X if (l->l_spacefor == 0) {
X l->l_list = (addr *) MEM(STARTSIZE * sizeof (addr));
X l->l_spacefor = STARTSIZE;
X }
X else if (l->l_count == l->l_spacefor) {
X l->l_list = (addr *) DELTAMEM((addr)l->l_list,
X 2 * l->l_spacefor * sizeof(addr));
X l->l_spacefor *= 2;
X }
X savestr((char **)&l->l_list[l->l_count], s);
X l->l_count++;
X non_critical();
X return;
X}
X
Xgenlistadd(l, p, n)
Xregister struct list *l;
Xregister addr p;
Xint n;
X
X{
X critical();
X if (l->l_spacefor == 0) {
X l->l_list = (addr *) MEM(STARTSIZE * sizeof (addr));
X l->l_spacefor = STARTSIZE;
X }
X else if (l->l_count == l->l_spacefor) {
X l->l_list = (addr *) DELTAMEM((addr)l->l_list,
X 2 * l->l_spacefor * sizeof (addr));
X l->l_spacefor *= 2;
X }
X l->l_list[l->l_count] = MEM(n);
X bcopy(l->l_list[l->l_count], p, n);
X l->l_count++;
X non_critical();
X return;
X}
X
Xlistadd(l, p)
Xstruct list *l;
Xaddr p;
X
X{
X critical();
X if (l->l_spacefor == 0) {
X l->l_list = (addr *) MEM(STARTSIZE * sizeof (addr));
X l->l_spacefor = STARTSIZE;
X }
X else if (l->l_count == l->l_spacefor) {
X l->l_list = (addr *) DELTAMEM((addr)l->l_list,
X 2 * l->l_spacefor * sizeof (addr));
X l->l_spacefor *= 2;
X }
X l->l_list[l->l_count] = p;
X l->l_count++;
X non_critical();
X return;
X}
X
Xstrlistdel(l, s)
Xstruct list *l;
Xchar *s;
X
X{
X register int i;
X int found, indx, halfavail;
X
X critical();
X indx = search_list(l, s, strcmp, &found);
X if (found) {
X FREEMEM((char *)l->l_list[indx]);
X for (i=indx; i<l->l_count-1; i++)
X l->l_list[i] = l->l_list[i+1];
X l->l_count--;
X halfavail = l->l_spacefor / 2;
X if (l->l_count < halfavail && l->l_spacefor > STARTSIZE) {
X l->l_list = (addr *) DELTAMEM((addr)l->l_list,
X halfavail * sizeof (addr));
X l->l_spacefor = halfavail;
X }
X }
X non_critical();
X return;
X}
X
Xgenlistdel(l, p, compfunc)
Xstruct list *l;
Xaddr p;
Xint (*compfunc)();
X
X{
X register int i;
X int found, indx, halfavail;
X
X critical();
X indx = search_list(l, (char *)p, compfunc, &found);
X if (found) {
X FREEMEM((char *)l->l_list[indx]);
X for (i=indx; i<l->l_count-1; i++)
X l->l_list[i] = l->l_list[i+1];
X l->l_count--;
X halfavail = l->l_spacefor / 2;
X if (l->l_count < halfavail && l->l_spacefor > STARTSIZE) {
X l->l_list = (addr *) DELTAMEM((addr)l->l_list,
X halfavail * sizeof (addr));
X l->l_spacefor = halfavail;
X }
X }
X non_critical();
X return;
X}
X
Xint
Xstrlistchg(l, old, new)
Xstruct list *l;
Xchar *old, *new;
X
X{
X int found, indx;
X
X indx = search_list(l, old, strcmp, &found);
X if (!found)
X return 0;
X FREEMEM((char *)l->l_list[indx]);
X savestr((char **)&l->l_list[indx], new);
X sort_list(l, pstrcmp);
X return 1;
X}
X
Xaddr
Xlistpop(l)
Xstruct list *l;
X
X{
X register int i;
X addr first;
X int halfavail;
X
X critical();
X first = l->l_list[0];
X for (i=0; i<l->l_count-1; i++)
X l->l_list[i] = l->l_list[i+1];
X l->l_count--;
X halfavail = l->l_spacefor / 2;
X if (l->l_count < halfavail && l->l_spacefor > STARTSIZE) {
X l->l_list = (addr *) DELTAMEM((addr)l->l_list,
X halfavail * sizeof (addr));
X l->l_spacefor = halfavail;
X }
X non_critical();
X return first;
X}
X
Xint
Xinstrlist(l, s)
Xstruct list *l;
Xchar *s;
X
X{
X int found;
X
X (void) search_list(l, s, strcmp, &found);
X return found;
X}
X
Xzerolist(l)
Xstruct list *l;
X
X{
X l->l_count = 0;
X l->l_spacefor = 0;
X}
X
Xduplist(new, old)
Xstruct list *new, *old;
X
X{
X critical();
X new->l_count = old->l_count;
X new->l_spacefor = old->l_spacefor;
X new->l_list = old->l_list;
X non_critical();
X return;
X}
X
X/*
X**copylist(dest, src, objsize)
X**struct list *dest, *src;
X**int objsize;
X**
X**{
X** register int i;
X**
X** zerolist(dest);
X** for (i=0; i<src->l_count; i++)
X** genlistadd(dest, src->l_list[i], objsize);
X** return;
X**}
X */
X
Xint
Xorstrlist(l, ll)
Xstruct list *l, *ll;
X
X{
X register int indx;
X int changed = 0;
X
X for (indx=0; indx<ll->l_count; indx++) {
X if (instrlist(l, (char *)ll->l_list[indx]))
X continue;
X changed++;
X strlistadd(l, (char *)ll->l_list[indx]);
X sort_list(l, pstrcmp);
X }
X return changed;
X}
X
Xtmplistadd(l)
Xstruct list *l;
X
X{
X critical();
X listadd(&TempLists, (addr)l);
X non_critical();
X return;
X}
X
Xfreetmplists()
X
X{
X while (TempLists.l_count)
X freelist((struct list *) listpop(&TempLists));
X return;
X}
X
X#define COLUMNS 80
X#define SEPDIST 3
X
Xchar *re_comp();
X
Xshowlist(l, regexv)
Xstruct list *l;
Xaddr *regexv;
X
X{
X register int i, k;
X int tabs, h, j, longest, n;
X static struct list matches;
X char *errmsg;
X register char *cp;
X
X if (l->l_count == 0)
X return 0;
X longest = 0;
X zerolist(&matches);
X tmplistadd(&matches);
X for (h=0; regexv[h]; h++) {
X errmsg = re_comp((char *)regexv[h]);
X if (errmsg) {
X err(errmsg);
X continue;
X }
X for (i=0; i < l->l_count; i++) {
X cp = (char *)l->l_list[i];
X if (re_exec(cp) == 0)
X continue;
X if (instrlist(&matches, cp))
X continue;
X longest = max(longest, strlen(cp));
X strlistadd(&matches, cp);
X }
X }
X n = matches.l_count;
X if (n == 0)
X return n;
X sort_list(&matches, pstrcmp);
X tabs = n / ((COLUMNS-1) / (longest + SEPDIST));
X tabs += ( n % ((COLUMNS-1) / (longest + SEPDIST)) ? 1 : 0 );
X for (j = 1; j <= tabs; j++) {
X for (k = j - 1; k < n; k += tabs) {
X (void) fputs((char *)matches.l_list[k], stdout);
X space(longest - strlen((char *)matches.l_list[k])
X + SEPDIST);
X }
X puts("");
X }
X return n;
X}
X
Xlistlist(l)
Xstruct list *l;
X
X{
X int indx;
X
X for (indx=0; indx < l->l_count; indx++)
X (void) printf("%s ", l->l_list[indx]);
X puts("");
X}
X
Xlistout(l, fp)
Xstruct list *l;
XFILE *fp;
X
X{
X int i;
X
X for (i=0; i < l->l_count; i++) {
X if (i > 0)
X fputs(",", fp);
X fputs((char *)l->l_list[i], fp);
X }
X return;
X}
@//E*O*F src/lists.c//
if test 9337 -ne "`wc -c <'src/lists.c'`"; then
echo shar: error transmitting "'src/lists.c'" '(should have been 9337 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'src/macros.h'" '(345 characters)'
if test -f 'src/macros.h' ; then
echo shar: will not over-write existing file "'src/macros.h'"
else
sed 's/^X//' >src/macros.h <<'@//E*O*F src/macros.h//'
X#define eq(a, b) !strcmp(((char *)a), ((char *)b))
X#define space(n) { int ii; for(ii=0;ii<n;ii++) fputs(" ", stdout); }
X#define decr(a) (a) = ((a)>0 ? (a)-1 : (a))
X#define mask(i) (1 << (i - 1))
X#define S(n) ((n)!=1 ? "s" : "")
X#define ES(n) ((n)!=1 ? "es" : "")
X
X#define INRANGE(n, f, t) ((f)<(t) ? (f)<=(n)&&(n)<=(t) : (t)<=(n)&&(n)<=(f))
@//E*O*F src/macros.h//
if test 345 -ne "`wc -c <'src/macros.h'`"; then
echo shar: error transmitting "'src/macros.h'" '(should have been 345 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'src/mem.c'" '(522 characters)'
if test -f 'src/mem.c' ; then
echo shar: will not over-write existing file "'src/mem.c'"
else
sed 's/^X//' >src/mem.c <<'@//E*O*F src/mem.c//'
X#include "mem.h"
X
Xchar *realloc(), *malloc();
X
Xaddr
XMEM(n)
Xint n;
X
X{
X flexaddr m;
X
X critical();
X m.p_cp = malloc( (unsigned) n );
X if (!m.p_cp)
X panic("MEM internal error: out of memory");
X non_critical();
X return m.p_ap;
X}
X
Xaddr
XDELTAMEM(p, n)
Xaddr p;
Xint n;
X
X{
X flexaddr m;
X
X critical();
X m.p_cp = realloc((char *)p, (unsigned) n);
X if (!m.p_cp)
X panic("DELTAMEM internal error: out of memory");
X non_critical();
X return m.p_ap;
X}
X
XFREEMEM(cp)
Xchar *cp;
X
X{
X critical();
X free((char *) cp);
X non_critical();
X return;
X}
@//E*O*F src/mem.c//
if test 522 -ne "`wc -c <'src/mem.c'`"; then
echo shar: error transmitting "'src/mem.c'" '(should have been 522 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'src/mem.h'" '(544 characters)'
if test -f 'src/mem.h' ; then
echo shar: will not over-write existing file "'src/mem.h'"
else
sed 's/^X//' >src/mem.h <<'@//E*O*F src/mem.h//'
X#define SHORT_BUF 16
X#define MEDIUM_BUF 48
X#define LONG_BUF 256
X#define NIL ((addr)0)
X#define NOMORE -1
X#define UNDEFINED -1
X
X#define bcopy(dest, source, n) \
X { \
X register char *from = (char *)source; \
X register char *to = (char *) dest; \
X register int ii; \
X int nn = n; \
X for (ii=0; ii<nn; ii++) \
X *to++ = *from++; \
X }
X
Xtypedef int addr_t;
Xtypedef addr_t * addr; /* general purpose pointer type */
Xtypedef union {
X addr p_ap;
X char *p_cp;
X } flexaddr; /* to make lint shut UP! */
X
Xaddr MEM(), DELTAMEM();
@//E*O*F src/mem.h//
if test 544 -ne "`wc -c <'src/mem.h'`"; then
echo shar: error transmitting "'src/mem.h'" '(should have been 544 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'MANIFEST'" '(4939 characters)'
if test -f 'MANIFEST' ; then
echo shar: will not over-write existing file "'MANIFEST'"
else
sed 's/^X//' >MANIFEST <<'@//E*O*F MANIFEST//'
X File Name Kit # Description
X-----------------------------------------------------------
X Copyright 1
X Futuribles 1
X Installation 1
X MANIFEST 6 This shipping list
X Makefile 1
X PATCHED 1
X README 1
X help 1
X help/Copyright 1
X help/Makefile 1
X help/add-alias.n 1
X help/add-class.n 1
X help/add-group.n 1
X help/add-range.n 1
X help/add-sig.n 1
X help/add-to-alias.n 1
X help/add-to-class.n 1
X help/add-to-group.n 1
X help/add-to-sig.n 1
X help/add-user.n 1
X help/add-vig.n 1
X help/alias.n 1
X help/bind-class.n 1
X help/bind-group.n 1
X help/bind-sig.n 1
X help/checkpoint-changes.n 1
X help/class.n 1
X help/cryo.n 1
X help/deadbeat.n 1
X help/describe-alias.n 1
X help/describe-changes.n 1
X help/describe-class.n 1
X help/describe-command.n 1
X help/describe-cryos.n 1
X help/describe-deadbeats.n 1
X help/describe-group.n 1
X help/describe-inactives.n 1
X help/describe-range.n 1
X help/describe-sig.n 1
X help/describe-user.n 1
X help/disable-user.n 1
X help/exit-mcp.n 1
X help/freeze-deadbeats.n 1
X help/freeze-inactives.n 1
X help/freeze-user.n 1
X help/gid.n 1
X help/inactive.n 1
X help/list-aliases.n 1
X help/list-classes.n 1
X help/list-commands.n 1
X help/list-cryos.n 1
X help/list-deadbeats.n 1
X help/list-groups.n 1
X help/list-inactives.n 1
X help/list-ranges.n 1
X help/list-sigs.n 1
X help/list-users.n 1
X help/list-vigs.n 1
X help/load-file.n 2
X help/pause-mcp.n 1
X help/range.n 2
X help/remove-alias.n 2
X help/remove-class.n 2
X help/remove-cryos.n 2
X help/remove-from-alias.n 2
X help/remove-from-class.n 2
X help/remove-from-group.n 2
X help/remove-from-sig.n 2
X help/remove-group.n 2
X help/remove-range.n 2
X help/remove-sig.n 2
X help/remove-user.n 2
X help/remove-vig.n 2
X help/save-and-exit.n 2
X help/save-changes.n 2
X help/shell-escape.n 2
X help/sig.n 2
X help/uid.n 2
X help/unbind-class.n 2
X help/unbind-group.n 2
X help/unbind-sig.n 2
X help/update-alias.n 2
X help/update-class.n 2
X help/update-group.n 2
X help/update-range.n 2
X help/update-sig.n 2
X help/update-user.n 2
X help/vig.n 2
X help/what-is.n 2
X man 1
X man/Copyright 2
X man/Makefile 2
X man/accounts.n 2
X man/classes.n 2
X man/mcp.n 2
X man/ranges.n 2
X man/shells.n 2
X man/sigs.n 3
X man/vigs.n 3
X misc 1
X misc/freeze 3
X misc/sorry 3
X src 1
X src/Copyright 3
X src/Makefile 3
X src/account.c 3
X src/account.h 3
X src/add.c 3
X src/alias.c 3
X src/alias.h 2
X src/backup.c 3
X src/bind.c 4
X src/build.c 4
X src/ckp.c 4
X src/class.c 3
X src/class.h 3
X src/command.h 3
X src/complete.c 5
X src/date.c 4
X src/describe.c 5
X src/disable.c 4
X src/edit.c 4
X src/errmsg.c 4
X src/exists.c 4
X src/exit.c 4
X src/exits.c 4
X src/freeze.c 4
X src/gpa.c 6
X src/gpa.h 3
X src/groupmap.c 4
X src/groupmap.h 4
X src/history.h 4
X src/init.c 6
X src/job.c 6
X src/job.h 4
X src/lastlog.c 6
X src/lastlog.h 5
X src/list.c 6
X src/lists.c 6
X src/lists.h 5
X src/load.c 7
X src/macros.h 6
X src/main.c 7
X src/mem.c 6
X src/mem.h 6
X src/misc.c 7
X src/nitpick 7
X src/pause.c 5
X src/pwlock.c 7
X src/range.c 7
X src/range.h 7
X src/remove.c 7
X src/report.c 7
X src/save.c 8
X src/save.h 8
X src/shell.c 8
X src/sig.c 8
X src/sig.h 8
X src/signals.c 8
X src/sort.c 8
X src/sort.h 8
X src/sysdep.h 8
X src/tty.c 8
X src/update.c 9
X src/version.c 8
X src/yesno.c 8
@//E*O*F MANIFEST//
if test 4939 -ne "`wc -c <'MANIFEST'`"; then
echo shar: error transmitting "'MANIFEST'" '(should have been 4939 characters)'
fi
fi # end of overwriting check
echo shar: "End of archive 6 (of 8)."
cp /dev/null ark6isdone
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
More information about the Mod.sources
mailing list