sources-request@mirror.UUCP (02/07/87)
Submitted by: Kyle Jones <xanth!kyle> Mod.sources: Volume 8, Issue 44 Archive-name: mcp/Part04 #! /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 4 (of 8)." # Contents: src/bind.c src/build.c src/ckp.c src/date.c src/disable.c # src/edit.c src/errmsg.c src/exists.c src/exit.c src/exits.c # src/freeze.c src/groupmap.c src/groupmap.h src/history.h src/job.h # Wrapped by rs@mirror on Fri Feb 6 15:55:57 1987 PATH=/bin:/usr/bin:/usr/ucb; export PATH echo shar: extracting "'src/bind.c'" '(12012 characters)' if test -f 'src/bind.c' ; then echo shar: will not over-write existing file "'src/bind.c'" else sed 's/^X//' >src/bind.c <<'@//E*O*F src/bind.c//' X/***************************************************************************\ X* * X* bind.c * X* * X* Herein lie most of the user interface routines to bind classes, sigs and * X* groups to sendmail aliases. The idea behind the bindings is that * X* accurate e-mail mailing lists can be maintained most easily be * X* integrating their maintenance into the same software that creates and * X* deletes accounts. * X* * X\***************************************************************************/ X X#include <stdio.h> X#include <sys/types.h> X#include <lastlog.h> X#include "sysdep.h" X X#ifdef SENDMAIL X#include "macros.h" X#include "mem.h" X#include "gpa.h" X#include "lists.h" X#include "account.h" X#include "alias.h" X#include "class.h" X#include "groupmap.h" X#include "sig.h" X#include "sort.h" X#include "save.h" X Xextern struct list AccountList, Aliases, AliasList; Xextern int ModBits; X Xbindgroup(c, v) Xint c; Xaddr *v; X X{ X struct alias *al; X struct account *ac; X struct groupmap *gm; X addr *aliasv; X int cc, bound = 0; X register int i, j; 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 X aliasv = get_gpa(17); X GetLine("To-Aliases: ", 16, &cc, aliasv, &Aliases); X if (cc == 0) { X err("no change"); X return; X } X X for (i=0; i < cc; i++) { X al = getalnam((char *)aliasv[i]); X if (!al) { X err1("%s: no such alias", (char *)aliasv[i]); X continue; X } X if (instrlist(&al->al_groups, (char *)v[1])) { X err2("%s: already bound to %s", (char *)v[1], al->al_name); X continue; X } X strlistadd(&al->al_groups, (char *)v[1]); X strlistadd(&gm->gm_aliases, al->al_name); X sort_list(&al->al_groups, pstrcmp); X sort_list(&gm->gm_aliases, pstrcmp); 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 !instrlist(&ac->ac_groups, (char *)v[1])) X continue; X if (instrlist(&al->al_addresses, (char *)ac->ac_name)) X continue; X strlistadd(&al->al_addresses, (char *)ac->ac_name); X sort_list(&al->al_addresses, pstrcmp); X } X bound++; X } X if (bound) { X ModBits |= AL; X (void) printf("%d bound\n", bound); X } X non_critical(); X X return; X} X Xbindclass(c, v) Xint c; Xaddr *v; X X{ X struct alias *al; X struct account *ac; X struct class *cs; X addr *aliasv; X int cc, bound = 0; X register int i, j; 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 X aliasv = get_gpa(17); X GetLine("To-Aliases: ", 16, &cc, aliasv, &Aliases); X if (cc == 0) { X err("no change"); X return; X } X X for (i=0; i < cc; i++) { X al = getalnam((char *)aliasv[i]); X if (!al) { X err1("%s: no such alias", (char *)aliasv[i]); X continue; X } X if (instrlist(&al->al_classes, (char *)v[1])) { X err2("%s: already bound to %s", (char *)v[1], al->al_name); X continue; X } X strlistadd(&al->al_classes, (char *)v[1]); X strlistadd(&cs->cs_aliases, al->al_name); X sort_list(&al->al_classes, pstrcmp); X sort_list(&cs->cs_aliases, pstrcmp); X for (j=0; j < AccountList.l_count; j++) { X ac = (struct account *) AccountList.l_list[j]; X if (!instrlist(&ac->ac_classes, (char *)v[1])) X continue; X if (instrlist(&al->al_addresses, (char *)ac->ac_name)) X continue; X strlistadd(&al->al_addresses, (char *)ac->ac_name); X sort_list(&al->al_addresses, pstrcmp); X } X bound++; X } X if (bound) { X ModBits |= AL; X (void) printf("%d bound\n", bound); X } X non_critical(); X X return; X} X Xbindsig(c, v) Xint c; Xaddr *v; X X{ X struct alias *al; X struct account *ac; X struct sig *sg; X addr *aliasv; X int cc, bound = 0; X register int i, j; 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 X aliasv = get_gpa(17); X GetLine("To-Aliases: ", 16, &cc, aliasv, &Aliases); X if (cc == 0) { X err("no change"); X return; X } X X for (i=0; i < cc; i++) { X al = getalnam((char *)aliasv[i]); X if (!al) { X err1("%s: no such alias", (char *)aliasv[i]); X continue; X } X if (instrlist(&al->al_sigs, (char *)v[1])) { X err2("%s: already bound to %s", (char *)v[1], al->al_name); X continue; X } X strlistadd(&al->al_sigs, (char *)v[1]); X strlistadd(&sg->sg_aliases, al->al_name); X sort_list(&al->al_sigs, pstrcmp); X sort_list(&sg->sg_aliases, pstrcmp); X for (j=0; j < AccountList.l_count; j++) { X ac = (struct account *) AccountList.l_list[j]; X if (!instrlist(&ac->ac_sigs, (char *)v[1])) X continue; X if (instrlist(&al->al_addresses, (char *)ac->ac_name)) X continue; X strlistadd(&al->al_addresses, (char *)ac->ac_name); X sort_list(&al->al_addresses, pstrcmp); X } X bound++; X } X if (bound) { X ModBits |= AL; X (void) printf("%d bound\n", bound); X } X non_critical(); X X return; X} X Xubindgroup(c, v) Xint c; Xaddr *v; X X{ X struct account *ac; X struct alias *al; X struct groupmap *gm; X addr *aliasv; X register int i, j; X int unbound = 0, cc; X X if (c > 2) { X err1("%s: too many arguements", (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 if (gm->gm_aliases.l_count) { X err1("%s: not bound to any aliases", gm->gm_name); X return; X } X X aliasv = get_gpa(17); X GetLine("From-Aliases: ", 16, &cc, aliasv, &Aliases); X if (cc == 0) { X err("no change"); X return; X } X X critical(); X for (i=0; i < cc; i++) { X al = getalnam((char *)aliasv[i]); X if (!al) { X err1("%s: no such alias", (char *)aliasv[i]); X continue; X } X if (!instrlist(&al->al_groups, (char *)v[1])) { X err2("%s: not bound to %s", (char *)v[1], al->al_name); X continue; X } X strlistdel(&al->al_groups, (char *)v[1]); X strlistdel(&gm->gm_aliases, al->al_name); X for (j=0; j < AccountList.l_count; j++) { X ac = (struct account *) AccountList.l_list[j]; X if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) X continue; X if (LegalAKA(ac, al)) X continue; X strlistdel(&al->al_addresses, (char *)ac->ac_name); X } X unbound++; X } X if (unbound) { X (void) printf("%d unbound\n", unbound); X ModBits |= AL; X } X non_critical(); X X return; X} X Xubindclass(c, v) Xint c; Xaddr *v; X X{ X struct account *ac; X struct alias *al; X struct class *cs; X addr *aliasv; X register int i, j; X int unbound = 0, cc; X X if (c > 2) { X err1("%s: too many arguements", (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 if (cs->cs_aliases.l_count) { X err1("%s: not bound to any aliases", cs->cs_name); X return; X } X X aliasv = get_gpa(17); X GetLine("From-Aliases: ", 16, &cc, aliasv, &Aliases); X if (cc == 0) { X err("no change"); X return; X } X X critical(); X for (i=0; i < cc; i++) { X al = getalnam((char *)aliasv[i]); X if (!al) { X err1("%s: no such alias", (char *)aliasv[i]); X continue; X } X if (!instrlist(&al->al_classes, (char *)v[1])) { X err2("%s: not bound to %s", (char *)v[1], al->al_name); X continue; X } X strlistdel(&al->al_classes, (char *)v[1]); X strlistdel(&cs->cs_aliases, al->al_name); X for (j=0; j < AccountList.l_count; j++) { X ac = (struct account *) AccountList.l_list[j]; X if (!instrlist(&ac->ac_classes, (char *)v[1])) X continue; X if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) X continue; X if (LegalAKA(ac, al)) X continue; X strlistdel(&al->al_addresses, (char *)ac->ac_name); X } X unbound++; X } X if (unbound) { X (void) printf("%d unbound\n", unbound); X ModBits |= AL; X } X non_critical(); X X return; X} X Xubindsig(c, v) Xint c; Xaddr *v; X X{ X struct account *ac; X struct alias *al; X struct sig *sg; X addr *aliasv; X register int i, j; X int unbound = 0, cc; X X if (c > 2) { X err1("%s: too many arguements", (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 if (sg->sg_aliases.l_count) { X err1("%s: not bound to any aliases", sg->sg_name); X return; X } X X aliasv = get_gpa(17); X GetLine("From-Aliases: ", 16, &cc, aliasv, &Aliases); X if (cc == 0) { X err("no change"); X return; X } X X critical(); X for (i=0; i < cc; i++) { X al = getalnam((char *)aliasv[i]); X if (!al) { X err1("%s: no such alias", (char *)aliasv[i]); X continue; X } X if (!instrlist(&al->al_sigs, (char *)v[1])) { X err2("%s: not bound to %s", (char *)v[1], al->al_name); X continue; X } X strlistdel(&al->al_sigs, (char *)v[1]); X strlistdel(&sg->sg_aliases, al->al_name); X for (j=0; j < AccountList.l_count; j++) { X ac = (struct account *) AccountList.l_list[j]; X if (!instrlist(&ac->ac_sigs, (char *)v[1])) X continue; X if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) X continue; X if (LegalAKA(ac, al)) X continue; X strlistdel(&al->al_addresses, (char *)ac->ac_name); X } X unbound++; X } X if (unbound) { X (void) printf("%d unbound\n", unbound); X ModBits |= AL; X } X non_critical(); X X return; X} X X/* X * Routine to determine if a user should be left in an alias after X * his class, sig, or group memberships have changed. If the user is still X * a member of another class, sig or group that is bound to the given aliasm X * then the user should remain in the alias. Also if the user a member of X * the alias above and beyond any class, sig or group bindings he should be X * allowed to remain. X */ Xint XLegalAKA(ac, al) Xstruct account *ac; Xstruct alias *al; X X{ X char *name; X struct groupmap *gm; X register int i; X X /* X * REMEMBER: X * ac_aliases always contains the list of aliasses that the user is X * in, even if he were not member of classes, sig, etc. that X * are bound to aliases. Thus class, sig, or group membership X * changes have no bearing on this so we return 1 immediately. X */ X if (instrlist(&ac->ac_aliases, al->al_name)) X return 1; X /* X * Check for membership via group being bound. X */ X gm = getgmgid(ac->ac_gid); X if (gm && instrlist(&al->al_groups, (char *)gm->gm_name)) X return 1; X for (i=0; i < ac->ac_groups.l_count; i++) { X name = (char *) ac->ac_groups.l_list[i]; X if (instrlist(&al->al_groups, name)) X return 1; X } X /* X * Are any of this user's classes bound to this alias? X */ X for (i=0; i < ac->ac_classes.l_count; i++) { X name = (char *) ac->ac_classes.l_list[i]; X if (instrlist(&al->al_classes, name)) X return 1; X } X /* X * Are any of this user's sigs bound to this alias? X */ X for (i=0; i < ac->ac_sigs.l_count; i++) { X name = (char *) ac->ac_sigs.l_list[i]; X if (instrlist(&al->al_sigs, name)) X return 1; X } X return 0; X} X X/* X * Patch up aliases. X * Should be used right after removing users from classes, X * sigs, or groups, to be sure that if these are bound the changes are X * reflected in the aliases. X */ XRXBindings(ac) Xstruct account *ac; X X{ X register struct alias *al; X register int i; X X critical(); 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 if (LegalAKA(ac, al) == 0) { X strlistdel(&al->al_addresses, (char *)ac->ac_name); X ModBits |= AL; X } X } X } X non_critical(); X return; X} X X#endif SENDMAIL @//E*O*F src/bind.c// if test 12012 -ne "`wc -c <'src/bind.c'`"; then echo shar: error transmitting "'src/bind.c'" '(should have been 12012 characters)' fi fi # end of overwriting check echo shar: extracting "'src/build.c'" '(5892 characters)' if test -f 'src/build.c' ; then echo shar: will not over-write existing file "'src/build.c'" else sed 's/^X//' >src/build.c <<'@//E*O*F src/build.c//' X/***************************************************************************\ X* * X* build.c * X* * X* Routines to build the accounts file from the existing passwd and group * X* files, i.e. the -I option to mcp. All information about who is in what * X* class and what sig is destroyed by this process. If the class, sig, vig * X* or range files do not exist, mcp will attempt to create them, otherwise * X* these are untouched. * X* * X\***************************************************************************/ X X#include <stdio.h> X#include <sys/file.h> X#include <sys/types.h> X#include <strings.h> X#include <pwd.h> X#include <grp.h> X#include <lastlog.h> X#include "sysdep.h" X#include "macros.h" X#include "mem.h" X#include "lists.h" X#ifdef SENDMAIL X#include "alias.h" X#endif X#include "account.h" X#include "groupmap.h" X#include "sort.h" X#include "save.h" X#ifdef SENDMAIL X#include <ctype.h> X#endif X Xextern struct list AccountList, GroupMapList, Groups, Users; Xextern int ModBits, root, acck(); X XBuild() X X{ X#ifdef SENDMAIL X struct alias *al; X char line[BUFSIZ]; X#endif X struct account a, *ac, *ac2; X struct passwd *pw; X struct group *gr; X struct groupmap gm; X register int indx; X char *cp; X X ShowVersion(); X msg("Building accounting files..."); X#ifdef SENDMAIL X zerolist(&a.ac_aliases); X#endif X zerolist(&a.ac_groups); X zerolist(&a.ac_classes); zerolist(&a.ac_sigs); X (void) setpwent(); X while (pw = getpwent()) { X a.ac_uid = pw->pw_uid; X a.ac_gid = pw->pw_gid; X savestr((char **)&a.ac_name, pw->pw_name); X savestr((char **)&a.ac_gecos, pw->pw_gecos); X cp = index(pw->pw_gecos, ','); if (cp) *cp = '\0'; X savestr((char **)&a.ac_realname, pw->pw_gecos); X savestr((char **)&a.ac_passwd, pw->pw_passwd); X savestr((char **)&a.ac_dir, pw->pw_dir); X savestr((char **)&a.ac_shell, pw->pw_shell); X savestr((char **)&a.ac_id, "exception"); X genlistadd(&AccountList, (addr)&a, sizeof (struct account)); X strlistadd(&Users, pw->pw_name); X } X sort_list(&AccountList, acctcmp); X sort_list(&Users, pstrcmp); X (void) endpwent(); X (void) setgrent(); X while (gr = getgrent()) { X zerolist(&gm.gm_mem); 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 ac = getacnam(gr->gr_mem[indx]); X if (ac) { X strlistadd(&ac->ac_groups, gr->gr_name); X sort_list(&ac->ac_groups, pstrcmp); X } X else X continue; X strlistadd(&gm.gm_mem, gr->gr_mem[indx]); X } 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 /* X * If an accounts file already exists get the unchanged X * information from it before overwriting it. X */ X if (!fileexists(ACFILE)) goto finish; X if (acck() == 0) { X err("I can't get the class and sig membership info"); X err("nor the ID's or real names of current users"); X err("nor the non-binding alias memberships"); X err1("from the old %s because the file format is bad.", X ACFILE); X err(""); X if (yesno("Overwrite it anyway? ") == 0) X fatal("aborted"); X } X (void) setacent(); X while (ac2 = getacent()) { X ac = getacnam((char *)ac2->ac_name); X if (!ac) { X(void) printf("accounts line for nonexistent user \"%s\" removed\n", X ac2->ac_name); X continue; X } X FREEMEM((char *)ac->ac_realname); X savestr((char **)&ac->ac_realname, (char *)ac2->ac_realname); X FREEMEM((char *)ac->ac_id); X savestr((char **)&ac->ac_id, (char *)ac2->ac_id); 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 } Xfinish: X !fileexists(CSFILE) && createfile(CSFILE); X !fileexists(RANGEFILE) && createfile(RANGEFILE); X !fileexists(SIGFILE) && createfile(SIGFILE); X !fileexists(VIGFILE) && createfile(VIGFILE); X !fileexists(SHELLFILE) && createfile(SHELLFILE); X !fileexists(ACFILE) && createfile(ACFILE); X#ifdef SENDMAIL X !fileexists(ALIASFILE) && createfile(ALIASFILE); X#endif X X critical(); X#ifdef SENDMAIL X /* X * Check to see if an alias bindings file needs to be created X * to represent the current aliases file. Also if no alias bindings X * file exists we must assume that all users that are currently in X * aliases are not there because of bindings, hence updating X * ac_aliases for each user where appropriate. X */ X if (!fileexists(ALBIND)) { X FILE *bindf = fopen(ALBIND, "w"); X FILE *alf = fopen(ALIASFILE, "r"); X X if (alf == NULL) { X err1("can't open %s (read)", ALIASFILE); X fatal("mcp: -B aborted"); X } X if (bindf == NULL) { X (void) fclose(alf); X err1("can't open %s (write)", ALBIND); X fatal("mcp: -B aborted"); X } X while (fgets(line, BUFSIZ, alf) != NULL) { X if (isspace(line[0]) || line[0] == '#') X continue; X cp = index(line, '#'); X if (cp) *cp = '\0'; X cp = index(line, ':'); X if (cp) *cp = '\0'; X if (line[0] == '\n') X continue; X cp = index(line, '\n'); X if (cp) *cp = '\0'; X (void) fprintf(bindf, "%s:::\n", line); X } X (void) fchmod(fileno(bindf), 0644); X (void) fclose(bindf); X (void) fclose(alf); X setalent(); X while (al = getalent()) { X for (indx=0; indx < al->al_addresses.l_count; indx++) { X cp = (char *) al->al_addresses.l_list[indx]; X ac = getacnam(cp); X if (ac && !instrlist(&ac->ac_aliases, cp)) { X strlistadd(&ac->ac_aliases, al->al_name); X sort_list(&ac->ac_aliases, pstrcmp); X } X } X } X endalent(); X } X#endif X if (backup(PW) == 0 || backup(AC) == 0) X fatal("mcp: -B aborted"); X msg(""); X save_pw(); X save_ac(); X non_critical(); X X goodbye(0); X} X Xstatic Xcreatefile(file) Xchar *file; X X{ X int d; X X d = open(file, O_WRONLY|O_CREAT); X if (d == -1) { X perr(file); X return; X } X (void) write(d, "Toto IV", 7); X (void) ftruncate(d, (off_t)0); X (void) fchmod(d, 0644); X (void) fsync(d); X (void) close(d); X} @//E*O*F src/build.c// if test 5892 -ne "`wc -c <'src/build.c'`"; then echo shar: error transmitting "'src/build.c'" '(should have been 5892 characters)' fi fi # end of overwriting check echo shar: extracting "'src/ckp.c'" '(6255 characters)' if test -f 'src/ckp.c' ; then echo shar: will not over-write existing file "'src/ckp.c'" else sed 's/^X//' >src/ckp.c <<'@//E*O*F src/ckp.c//' X/****************************************************************************\ X* * X* ckp.c * X* * X* These are the routines that put changes that have not been saved, into * X* the .mcp checkpoint files. An important thing to remember here is that * X* checkpointing should not be interupted by anything, particularly not by * X* another checkpoint, or chaos will ensue. There are only one set ot temp * X* files shared by save and the checkpoint routines. This was done for the * X* sake of simplicity and also since the tempfiles are in the same * X* filesystem as their accounting counterparts, these can be rename()'d into * X* place without the possibility of being caught by a system crash with a * X* file copy partially completed. * X* * X\****************************************************************************/ X X#include <stdio.h> X#include <sys/types.h> X#include <signal.h> X#include <lastlog.h> X#include "sysdep.h" X#include "macros.h" X#include "mem.h" X#include "lists.h" X#ifdef SENDMAIL X#include "alias.h" X#endif X#include "account.h" X#include "class.h" X#include "sig.h" X#include "range.h" X#include "groupmap.h" X#include "save.h" X Xextern int ModBits; X X#ifdef SENDMAIL Xextern struct list AliasList; X#endif Xextern struct list AccountList, GroupMapList, SigList, ClassList, RangeList; Xextern struct list Vigs, Jobs; X Xckp_pw() X X{ X FILE *pwf; X register int i; X struct account *ac; X X pwf = fopen(PWDTMP, "w"); X if (pwf == NULL) { X perr(PWDTMP); X return; X } X for (i=0; i < AccountList.l_count; i++) { X ac = (struct account *) AccountList.l_list[i]; X (void) fprintf(pwf, "%s:%s:%d:%d:%s:%s:%s\n", X ac->ac_name, X ac->ac_passwd, X ac->ac_uid, X ac->ac_gid, X ac->ac_gecos, X ac->ac_dir, X ac->ac_shell); X } X (void) fclose(pwf); X if (rename(PWDTMP, PWDCKP) == -1) { X perr(PWDTMP); X return; X } X return; X} X X#ifdef SENDMAIL Xckp_al() X X{ X FILE *alf, *bindf; X struct alias *al; X register int i; X X alf = fopen(ALIASTMP, "w"); X if (alf == NULL) { X perr(ALIASTMP); X return; X } X bindf = fopen(ALBINDTMP, "w"); X if (bindf == NULL) { X perr(ALBINDTMP); X (void) fclose(alf); X return; X } X for (i=0; i < AliasList.l_count; i++) { X al = (struct alias *) AliasList.l_list[i]; X (void) fprintf(alf, "%s:", al->al_name); X listout(&al->al_addresses, alf); X fputs("\n", alf); X (void) fprintf(bindf, "%s:", al->al_name); X listout(&al->al_groups, bindf); X fputs(":", bindf); X listout(&al->al_classes, bindf); X fputs(":", bindf); X listout(&al->al_sigs, bindf); X fputs("\n", bindf); X } X (void) fclose(alf); X (void) fclose(bindf); X if (rename(ALIASTMP, ALIASCKP) == -1) { X perr(ALIASTMP); X return; X } X if (rename(ALBINDTMP, ALBINDCKP) == -1) { X perr(ALBINDTMP); X return; X } X return; X} X#endif X Xckp_ac() X X{ X FILE *acf; X register int i; X struct account *ac; X X acf = fopen(ACTMP, "w"); X if (acf == NULL) { X perr(ACTMP); X return; X } X for (i=0; i < AccountList.l_count; i++) { X ac = (struct account *) AccountList.l_list[i]; X (void) fprintf(acf, "%s:%s:%s:%d:%d:", X ac->ac_name, X ac->ac_realname, X ac->ac_id, X ac->ac_uid, X ac->ac_gid); X listout(&ac->ac_groups, acf); X fputs(":", acf); X listout(&ac->ac_classes, acf); X fputs(":", acf); X listout(&ac->ac_sigs, acf); X fputs(":", acf); X#ifdef SENDMAIL X listout(&ac->ac_aliases, acf); X#endif X fputs("\n", acf); X } X (void) fclose(acf); X if (rename(ACTMP, ACCKP) == -1) { X perr(ACTMP); X return; X } X return; X} X Xckp_gr() X X{ X FILE *grf; X register int i; X struct groupmap *gm; X X grf = fopen(GRPTMP, "w"); X if (grf == NULL) { X perr(GRPTMP); X return; X } X for (i=0; i < GroupMapList.l_count; i++) { X gm = (struct groupmap *) GroupMapList.l_list[i]; X (void) fprintf(grf, "%s:%s:%d:", X gm->gm_name, X gm->gm_passwd, X gm->gm_gid); X listout(&gm->gm_mem, grf); X fputs("\n", grf); X } X (void) fclose(grf); X if (rename(GRPTMP, GRPCKP) == -1) { X perr(GRPTMP); X return; X } X return; X} X Xckp_cs() X X{ X struct class *cs; X register int i; X FILE *csf; X X csf = fopen(CSTMP, "w"); X if (csf == NULL) { X perr(CSTMP); X return; X } X for (i=0; i < ClassList.l_count; i++) { X cs = (struct class *) ClassList.l_list[i]; X (void) fprintf(csf, "%s %d %d\n", cs->cs_name, cs->cs_dsize, X cs->cs_exptime); X (void) fprintf(csf, "%s", cs->cs_desc); X } X (void) fclose(csf); X if (rename(CSTMP, CSCKP) == -1) { X perr(CSTMP); X return; X } X return; X} X Xckp_sg() X X{ X struct sig *sg; X register int i; X FILE *sgf; X X sgf = fopen(SIGTMP, "w"); X if (sgf == NULL) { X perr(SIGTMP); X return; X } X for (i=0; i < SigList.l_count; i++) { X sg = (struct sig *) SigList.l_list[i]; X (void) fprintf(sgf, "%s %d %d\n", sg->sg_name, sg->sg_dsize, X sg->sg_exptime); X (void) fprintf(sgf, "%s", sg->sg_desc); X } X (void) fclose(sgf); X if (rename(SIGTMP, SIGCKP) == -1) { X perr(SIGTMP); X return; X } X return; X} X Xckp_rg() X X{ X struct range *rg; X register int i; X FILE *rgf; X X rgf = fopen(RANGETMP, "w"); X if (rgf == NULL) { X perr(RANGETMP); X return; X } X for (i=0; i < RangeList.l_count; i++) { X rg = (struct range *) RangeList.l_list[i]; X (void) fprintf(rgf, "%s\t%d\t%d\t%s\n", X rg->rg_name, X rg->rg_from, X rg->rg_to, X (rg->rg_mode == RG_SHARED ? "shared" : "exclusive")); X } X (void) fclose(rgf); X if (rename(RANGETMP, RANGECKP) == -1) { X perr(RANGETMP); X return; X } X return; X} X Xckp_vg() X X{ X register int i; X FILE *vgf; X X vgf = fopen(VIGTMP, "w"); X if (vgf == NULL) { X perr(VIGTMP); X return; X } X for (i=0; i < Vigs.l_count; i++) X (void) fprintf(vgf, "%s\n", Vigs.l_list[i]); X (void) fclose(vgf); X if (rename(VIGTMP, VIGCKP) == -1) { X perr(VIGTMP); X return; X } X return; X} X Xpanic(reason) Xchar *reason; X X{ X err(""); X err(reason); X if (ModBits) { X msg("Checkpointing..."); X ckpchanges(); X err("All changes made to the accounting files"); X err("have been checkpointed."); X } X goodbye(1); X} X Xckpchanges() X X{ X /* X * All signals that could cause an unwanted checkpoint are blocked X * here lest file collisions and choas ensue. X */ X critical(); X X (ModBits&PW) && ckp_pw(); X (ModBits&AC) && ckp_ac(); X#ifdef SENDMAIL X (ModBits&AL) && ckp_al(); X#endif X (ModBits&CS) && ckp_cs(); X (ModBits&GR) && ckp_gr(); X (ModBits&RG) && ckp_rg(); X (ModBits&SG) && ckp_sg(); X (ModBits&VG) && ckp_vg(); X sync(); X X non_critical(); X return; X} @//E*O*F src/ckp.c// if test 6255 -ne "`wc -c <'src/ckp.c'`"; then echo shar: error transmitting "'src/ckp.c'" '(should have been 6255 characters)' fi fi # end of overwriting check echo shar: extracting "'src/date.c'" '(8068 characters)' if test -f 'src/date.c' ; then echo shar: will not over-write existing file "'src/date.c'" else sed 's/^X//' >src/date.c <<'@//E*O*F src/date.c//' X#include <sys/types.h> X#include <sys/time.h> X#include <setjmp.h> X#include <signal.h> X#include <strings.h> X#include "macros.h" X#include "mem.h" X X#define DOOMYEAR 2010 X#define STONEAGES 1975 X#define DAY (4*21600) X#define ISLEAPYEAR(y) (((y)%4==0) && (((y)%100!=0) || ((y)%400==0))) X Xchar *sprintf(), GET(); X X#ifdef sun X#define sighandler (void (*)()) X#else X#define sighandler (int (*)()) X#endif X Xextern jmp_buf in_continue; X#ifdef sun Xvoid tstp_cleanup(), input_continue(); X#else Xint tstp_cleanup(), input_continue(); X#endif X Xstatic char *days[] = { X "Sunday", "Monday", "Tuesday", "Wednesday", X "Thursday", "Friday", "Saturday" X}; X Xstatic char *how_many[] = { X "zero", "one", "two", "three", X "four", "five", "six", "seven", X "eigth", "nine", "ten", "eleven", X "twelve" X}; X Xstatic char *Months[12] = { X "January", "February", "March", "April", X "May", "June", "July", "August", X "September", "October", "November", "December" X}; X Xstatic int DaysInMonths[12] = { X 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 X}; X Xtime_t tmtotime_t(); X Xtime_t Xchoosedate(starttime) Xtime_t starttime; X X{ X struct tm *t, newt; X time_t time(); X char prompt[MEDIUM_BUF], line[MEDIUM_BUF]; X register int indx; X int leapday; X char c; X X err("Use SPACE to go forward, ^H or DELETE to go backwards."); X err("Hit RETURN to select."); X err(""); X X if (starttime == (time_t) 0) X starttime = time((time_t *)0); X t = localtime(&starttime); X bcopy(&newt, t, sizeof (struct tm)); X prompt[0] = '\0'; X /* X * Choose month X */ X indx = t->tm_mon; X (void) strcpy(line, Months[indx]); X cbreak(); X (void) signal(SIGTSTP, tstp_cleanup); X (void) signal(SIGCONT, input_continue); X (void) setjmp(in_continue); X redraw(prompt, line); X while ((c = GET()) != '\r') { X if (setjmp(in_continue) == SIGCONT) { X redraw(prompt, line); X continue; X } X switch (c) { X case ' ': X indx = (indx+1) % 12; X (void) sprintf(line, "%-9s", Months[indx]); X redraw(prompt, line); X break; X case '\b': X case '\177': X if (--indx < 0) X indx = 11; X (void) sprintf(line, "%-9s", Months[indx]); X redraw(prompt, line); X break; X default: X break; X } X } X (void) strcpy(prompt, Months[indx]); X (void) strcat(prompt, " "); X newt.tm_mon = indx; X indx = t->tm_mday; X if (indx > DaysInMonths[newt.tm_mon]) X indx = DaysInMonths[newt.tm_mon]; X (void) sprintf(line, "%2d", indx); X (void) setjmp(in_continue); X redraw(prompt, line); X /* X * Choose day of the month. X */ X while ((c = GET()) != '\r') { X if (setjmp(in_continue) == SIGCONT) { X redraw(prompt, line); X continue; X } X switch (c) { X case ' ': X if (++indx > DaysInMonths[newt.tm_mon]) X indx = 1; X (void) sprintf(line, "%2d", indx); X redraw(prompt, line); X break; X case '\b': X case '\177': X if (--indx < 1) X indx = DaysInMonths[newt.tm_mon]; X (void) sprintf(line, "%2d", indx); X redraw(prompt, line); X break; X default: X break; X } X } X (void) strcat(prompt, line); X (void) strcat(prompt, ", "); X newt.tm_mday = indx; X leapday = (newt.tm_mon == 1 && newt.tm_mday == 29); X indx = t->tm_year + 1900; X if (leapday) X indx = nextleapyear(indx); X (void) sprintf(line, "%4d", indx); X /* X * Choose year X */ X (void) setjmp(in_continue); X redraw(prompt, line); X while ((c = GET()) != '\r') { X if (setjmp(in_continue) == SIGCONT) { X redraw(prompt, line); X continue; X } X switch (c) { X case ' ': X if (leapday) X indx = nextleapyear(indx); X else if (++indx > DOOMYEAR) X indx = DOOMYEAR; X (void) sprintf(line, "%4d", indx); X redraw(prompt, line); X break; X case '\b': X case '\177': X if (leapday) X indx = lastleapyear(indx); X else if (--indx < STONEAGES) X indx = STONEAGES; X (void) sprintf(line, "%4d", indx); X redraw(prompt, line); X break; X default: X break; X } X } X newt.tm_year = indx - 1900; X newt.tm_hour = 0; X newt.tm_min = 0; X newt.tm_sec = 0; X (void) signal(SIGCONT, sighandler SIG_DFL); X (void) signal(SIGTSTP, sighandler SIG_DFL); X nocbreak(); X err(""); X return tmtotime_t(&newt); X} X Xtime_t Xtmtotime_t(t) Xregister struct tm *t; X X{ X time_t newtime; X struct timezone tz; X struct timeval tv; X int year, newyear, i; X X newtime = (t->tm_year - 70) * 365 * DAY; X for (i=0; i<t->tm_mon; i++) X newtime += (DaysInMonths[i] * DAY); X newtime += (t->tm_mday * DAY); X newyear = t->tm_year + 1900; X year = 1970; X for (; year < newyear; year++) X if (ISLEAPYEAR(year)) X newtime += DAY; X if (!ISLEAPYEAR(newyear) && t->tm_mon > 1) X newtime -= DAY; X /* set for midnight in this timezone and correct for dst shifts */ X (void) gettimeofday(&tv, &tz); X newtime += tz.tz_minuteswest * 60 - DAY; X t = localtime(&newtime); X switch (t->tm_hour) { X case 23: newtime += 3600; break; X case 1: newtime -= 3600; break; X default: break; X } X return newtime; X} X Xint Xnextleapyear(startyear) Xint startyear; X X{ X register int year; X X year = startyear; X while (++year <= DOOMYEAR) { X if (ISLEAPYEAR(year)) X return year; X } X return startyear; X} X Xint Xlastleapyear(startyear) Xint startyear; X X{ X register int year; X X year = startyear; X while (--year >= STONEAGES) X if (ISLEAPYEAR(year)) X return year; X return startyear; X} X Xchar * Xwhen(then) Xtime_t then; X X{ X static char tstr[LONG_BUF], descbuf[MEDIUM_BUF]; X char *cp, *description, *ampm; X struct tm *tt, tn, *localtime(); X time_t time(), now, tilthen, indx, remainder; X X now = time((time_t *)0); X tt = localtime(&now); X bcopy(&tn, tt, sizeof (struct tm)); X tt = localtime(&then); X tilthen = then - now; X if (then == 0) X return "never"; X if (tilthen >= 365 * DAY) X description = "sometime in the distant future"; X else if (tilthen >= 30 * DAY) { X indx = tilthen / (30*DAY); X remainder = (tilthen - indx * 30 * DAY) / DAY; X description = sprintf(descbuf, X "%smore than %s month%s hence", X (remainder < 5) ? "a little " : "", X how_many[indx], S(indx)); X } X else if (tilthen >= 7 * DAY) { X indx = tilthen / (7*DAY); X remainder = (tilthen - indx * 7 * DAY) / DAY; X description = sprintf(descbuf, X "%smore than %s week%s hence", X (remainder < 3) ? "a little " : "", X how_many[indx], S(indx)); X } X else if (tilthen > DAY) X description = sprintf(descbuf, "this %s", X days[tt->tm_wday]); X else if (tilthen > -DAY) { X if (tn.tm_wday == tt->tm_wday) X if (tt->tm_hour < 7) X description = "early this morning"; X else if (tt->tm_hour < 12) X description = "this morning"; X else if (tt->tm_hour < 17) X description = "this afternoon"; X else if (tt->tm_hour < 22) X description = "tonight"; X else X description = "late tonight"; X else if (tilthen > 0) X if (tt->tm_hour < 7) X description = "early tomorrow morning"; X else if (tt->tm_hour < 12) X description = "tomorrow morning"; X else if (tt->tm_hour < 17) X description = "tomorrow afternoon"; X else if (tt->tm_hour < 22) X description = "tomorrow night"; X else X description = "late tomorrow night"; X else X if (tt->tm_hour < 7) X description = "early yesterday morning"; X else if (tt->tm_hour < 12) X description = "yesterday morning"; X else if (tt->tm_hour < 17) X description = "yesterday afternoon"; X else if (tt->tm_hour < 22) X description = "last night"; X else X description = "late last night"; X } X else if (tilthen > -7 * DAY) { X description = sprintf(descbuf, "last %s", X days[tt->tm_wday]); X } X else if (tilthen > -30 * DAY) { X indx = -tilthen / (7*DAY); X remainder = (-tilthen % (7*DAY)) / DAY; X description = sprintf(descbuf, X "%sover %s week%s ago", X remainder < 3 ? "a little " : "", X how_many[indx], X S(indx)); X } X else if (tilthen > -365 * DAY) { X indx = -tilthen / (30*DAY); X description = sprintf(descbuf, X "over %s month%s ago", how_many[indx], X S(indx)); X } X else X description = "sometime during the Triassic..."; X#ifdef sun X cp = ctime((long *)&then); X#else X cp = ctime(&then); X#endif X X ampm = (tt->tm_hour < 12) ? "am" : "pm"; X if (tt->tm_hour > 12) X tt->tm_hour -= 12; X else if (tt->tm_hour == 0) X tt->tm_hour = 12; X X (void) sprintf(tstr, "%d:%02d%s %.3s. %d, %.4s (%s)", X tt->tm_hour, tt->tm_min, ampm, X cp+4, tt->tm_mday, X cp+20, description); X return tstr; X} @//E*O*F src/date.c// if test 8068 -ne "`wc -c <'src/date.c'`"; then echo shar: error transmitting "'src/date.c'" '(should have been 8068 characters)' fi fi # end of overwriting check echo shar: extracting "'src/disable.c'" '(621 characters)' if test -f 'src/disable.c' ; then echo shar: will not over-write existing file "'src/disable.c'" else sed 's/^X//' >src/disable.c <<'@//E*O*F src/disable.c//' X#include <sys/types.h> X#include <lastlog.h> X#include "sysdep.h" X#include "mem.h" X#include "lists.h" X#include "account.h" X#include "save.h" X Xextern int ModBits; X Xdisableuser(c, v) Xint c; Xaddr *v; X X{ X struct account *ac; 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 critical(); X FREEMEM((char *)ac->ac_shell); X savestr((char **)&ac->ac_shell, DISABLED_SH); X ModBits |= PW; X puts("disabled"); X non_critical(); X X return; X} @//E*O*F src/disable.c// if test 621 -ne "`wc -c <'src/disable.c'`"; then echo shar: error transmitting "'src/disable.c'" '(should have been 621 characters)' fi fi # end of overwriting check echo shar: extracting "'src/edit.c'" '(613 characters)' if test -f 'src/edit.c' ; then echo shar: will not over-write existing file "'src/edit.c'" else sed 's/^X//' >src/edit.c <<'@//E*O*F src/edit.c//' X#include <strings.h> X#include "sysdep.h" X#include "macros.h" X#include "mem.h" X Xchar *getenv(); X Xedit(file) Xchar *file; X X{ X char *av[4]; X char *term = getenv("TERM"); X char *visual = getenv("VISUAL"); X char *editor = getenv("EDITOR"); X char *which; X X if (!visual) X visual = DEF_VISUAL; X if (!editor) X editor = DEF_EDITOR; X if (!term) X term = "dumb"; X X if (eq(term, "dialup") || eq(term, "dumb")) X which = editor; X else if (eq(term, "network")) X which = editor; X else X which = visual; X X av[0] = "shell-escape"; X av[1] = which; X av[2] = file; X av[3] = (char *)0; X (void) shellescape(3, (addr *)av); X return; X} @//E*O*F src/edit.c// if test 613 -ne "`wc -c <'src/edit.c'`"; then echo shar: error transmitting "'src/edit.c'" '(should have been 613 characters)' fi fi # end of overwriting check echo shar: extracting "'src/errmsg.c'" '(1741 characters)' if test -f 'src/errmsg.c' ; then echo shar: will not over-write existing file "'src/errmsg.c'" else sed 's/^X//' >src/errmsg.c <<'@//E*O*F src/errmsg.c//' X/**********************************************************************\ X* * X* errmsg.c * X* * X* Mcp eschews stderr and instead dumps things not wanted on stdout to * X* /dev/tty. These routines should not be used while in cbreak mode * X* because they change the mode without regard to its previous state. * X* * X\**********************************************************************/ X X#include <stdio.h> X#include <strings.h> X#include "mem.h" X Xextern int errno, DevTty; Xextern char *sys_errlist[]; Xchar *sprintf(); X Xchar_scr(c) Xchar c; X X{ X (void) write(DevTty, &c, 1); X return; X} X Xstr_scr(s) Xregister char *s; X X{ X (void) write(DevTty, s, strlen(s)); X} X Xmsg(ss) Xchar *ss; X X{ X static int old_length; X int i, new_length, hadnewline = 0; X char s[LONG_BUF]; X X (void) strcpy(s, ss); X new_length = strlen(s); X cbreak(); X char_scr('\r'); X if (s[new_length-1] == '\n') { X s[new_length-1] = '\0'; X hadnewline++; X new_length--; X } X str_scr(s); X if (new_length < old_length) { X for (i=new_length; i<old_length; i++) X char_scr(' '); X for (i=new_length; i<old_length; i++) X char_scr('\b'); X } X if (hadnewline) str_scr("\r\n"); X nocbreak(); X old_length = (hadnewline ? 0 : new_length); X return; X} X Xerr(s) Xchar *s; X X{ X char errmsg[LONG_BUF]; X X (void) sprintf(errmsg, "%s\n", s); X msg(errmsg); X return; X} X Xerr1(fmt, s1) Xchar *fmt, *s1; X X{ X char errmsg[LONG_BUF]; X X (void) sprintf(errmsg, fmt, s1); X (void) strcat(errmsg, "\n"); X msg(errmsg); X return; X} X Xerr2(fmt, s1, s2) Xchar *fmt, *s1, *s2; X X{ X char errmsg[LONG_BUF]; X X (void) sprintf(errmsg, fmt, s1, s2); X (void) strcat(errmsg, "\n"); X msg(errmsg); X return; X} X Xperr(s) Xchar *s; X X{ X err2("%s: %s", s, sys_errlist[errno]); X return; X} @//E*O*F src/errmsg.c// if test 1741 -ne "`wc -c <'src/errmsg.c'`"; then echo shar: error transmitting "'src/errmsg.c'" '(should have been 1741 characters)' fi fi # end of overwriting check echo shar: extracting "'src/exists.c'" '(1531 characters)' if test -f 'src/exists.c' ; then echo shar: will not over-write existing file "'src/exists.c'" else sed 's/^X//' >src/exists.c <<'@//E*O*F src/exists.c//' X#include <sys/file.h> X#include <sys/types.h> X#include <strings.h> X#include <lastlog.h> X#include "sysdep.h" X#include "mem.h" X#include "lists.h" X#include "sort.h" X#include "account.h" X#include "groupmap.h" X#include "class.h" X#include "sig.h" X X#ifdef SENDMAIL Xextern struct list Aliases; X#endif Xextern struct list AccountList, GroupMapList, Groups, Users; Xextern struct list Classes, Sigs, Ranges, Vigs; X Xint userexists(s) Xchar *s; X X{ X int found; X X (void) search_list(&Users, s, strcmp, &found); X return found; X} X Xint groupexists(s) Xchar *s; X X{ X int found; X X (void) search_list(&Groups, s, strcmp, &found); X return found; X} X Xint classexists(s) Xchar *s; X X{ X int found; X X (void) search_list(&Classes, s, strcmp, &found); X return found; X} X Xint rangeexists(s) Xchar *s; X X{ X int found; X X (void) search_list(&Ranges, s, strcmp, &found); X return found; X} X Xint vigexists(s) Xchar *s; X X{ X int found; X X (void) search_list(&Vigs, s, strcmp, &found); X return found; X} X Xint uidexists(n) Xint n; X X{ X int found; X X (void) search_list(&AccountList, (char *)&n, iacctcmp, &found); X return found; X} X Xint gidexists(n) Xint n; X X{ X int found; X X (void) search_list(&GroupMapList, (char *)&n, igmapcmp, &found); X return found; X} X Xsigexists(s) Xchar *s; X X{ X int found; X X (void) search_list(&Sigs, s, strcmp, &found); X return found; X} X X#ifdef SENDMAIL Xaliasexists(name) Xchar *name; X X{ X int found; X X (void) search_list(&Aliases, name, strcmp, &found); X return found; X} X#endif SENDMAIL X Xint Xfileexists(file) Xchar *file; X X{ X return access(file, F_OK) == -1 ? 0 : 1; X} @//E*O*F src/exists.c// if test 1531 -ne "`wc -c <'src/exists.c'`"; then echo shar: error transmitting "'src/exists.c'" '(should have been 1531 characters)' fi fi # end of overwriting check echo shar: extracting "'src/exit.c'" '(211 characters)' if test -f 'src/exit.c' ; then echo shar: will not over-write existing file "'src/exit.c'" else sed 's/^X//' >src/exit.c <<'@//E*O*F src/exit.c//' X#include "mem.h" X#include "lists.h" X Xextern struct list Jobs; Xextern int ModBits; X Xexitmcp() X X{ X if (ModBits || Jobs.l_count) X if (no("There are unsaved changes, exit anyway? [no] ")) X return; X goodbye(0); X} @//E*O*F src/exit.c// if test 211 -ne "`wc -c <'src/exit.c'`"; then echo shar: error transmitting "'src/exit.c'" '(should have been 211 characters)' fi fi # end of overwriting check echo shar: extracting "'src/exits.c'" '(483 characters)' if test -f 'src/exits.c' ; then echo shar: will not over-write existing file "'src/exits.c'" else sed 's/^X//' >src/exits.c <<'@//E*O*F src/exits.c//' X#include <stdio.h> X#include <strings.h> X#include "sysdep.h" X#include "mem.h" X Xextern int root; Xchar *sprintf(); X Xgoodbye(n) Xint n; X X{ X if (root) X unlockpw(); X msg(""); X nocbreak(); X exit(n); X} X Xfatal(s) Xchar *s; X X{ X char fatalmsg[LONG_BUF]; X X (void) sprintf(fatalmsg, "%s\n", s); X msg(fatalmsg); X goodbye(1); X} X Xfatal1(fmt, s1) Xchar *fmt, *s1; X X{ X char fatalmsg[LONG_BUF]; X X (void) sprintf(fatalmsg, fmt, s1); X (void) strcat(fatalmsg, "\n"); X msg(fatalmsg); X goodbye(1); X return; X} @//E*O*F src/exits.c// if test 483 -ne "`wc -c <'src/exits.c'`"; then echo shar: error transmitting "'src/exits.c'" '(should have been 483 characters)' fi fi # end of overwriting check echo shar: extracting "'src/freeze.c'" '(3001 characters)' if test -f 'src/freeze.c' ; then echo shar: will not over-write existing file "'src/freeze.c'" else sed 's/^X//' >src/freeze.c <<'@//E*O*F src/freeze.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 "account.h" X#include "groupmap.h" X#include "save.h" X#include "sort.h" X X#ifdef BSD4_3 Xtime_t time(); X#endif X X#define DAY (4*21600) X Xextern struct list AccountList; Xextern int ModBits; Xchar *sprintf(), *when(); X Xfreezeuser(c, v) Xint c; Xchar **v; X X{ X struct account *ac; X struct groupmap *gm; X char errmsg[LONG_BUF]; 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 if (eq(ac->ac_shell, FREEZE_SH)) { X err1("%s: already frozen", (char *)ac->ac_name); X return; X } X gm = getgmgid(ac->ac_gid); X if (!gm) { X (void) sprintf(errmsg, X "no group for gid %d!", ac->ac_gid); X err(errmsg); X return; X } X if (vigexists(gm->gm_name)) { X (void) sprintf(errmsg, X "%s is in vig %s, freeze anyway? [yes] ", X ac->ac_name, gm->gm_name); X if (yes(errmsg) == 0) X return; X } X X critical(); X FREEMEM((char *)ac->ac_shell); X savestr((char **)&ac->ac_shell, FREEZE_SH); X ModBits |= PW; X puts("frozen"); X non_critical(); X X return; X} X Xfreezeinactives(c, v) Xint c; Xchar **v; X X{ X struct account *ac; X struct groupmap *gm; X time_t now, toolong, doomsday; X register int indx; X int frozen = 0; X X if (c != 2) { X err1("usage: %s <user>", (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 now = time((time_t *)0); X toolong = atoi((char *)v[1]) * DAY; X if (toolong <= 0) { X err1("%s: Not bloody likely.", (char *)v[0]);; X return; X } X doomsday = now - toolong; X (void) printf("The axe falls %s\n", when(doomsday)); X X critical(); X for (indx=0; indx < AccountList.l_count; indx++) { X ac = (struct account *) AccountList.l_list[indx]; X if (ac->ac_ll.ll_time > doomsday) X continue; X /* X * Don't freeze cryos again. X */ X if (eq(ac->ac_shell, FREEZE_SH)) X continue; X gm = getgmgid(ac->ac_gid); X if (gm && vigexists(gm->gm_name)) X continue; X FREEMEM((char *)ac->ac_shell); X savestr((char **)&ac->ac_shell, FREEZE_SH); X frozen++; X } X if (frozen) { X (void) printf("%d frozen\n", frozen); X ModBits |= PW; X } X else X err("no change"); X non_critical(); X X return; X} X Xfreezedeadbeats() X X{ X struct account *ac; X struct groupmap *gm; X register int indx; X int frozen = 0; X X critical(); X for (indx=0; indx < AccountList.l_count; indx++) { X ac = (struct account *) AccountList.l_list[indx]; X if (ac->ac_classes.l_count || ac->ac_sigs.l_count) X continue; X /* X * Don't freeze cryos again. X */ X if (eq(ac->ac_shell, FREEZE_SH)) X continue; X gm = getgmgid(ac->ac_gid); X if (gm && vigexists(gm->gm_name)) X continue; X FREEMEM((char *)ac->ac_shell); X savestr((char **)&ac->ac_shell, FREEZE_SH); X frozen++; X } X if (frozen) { X (void) printf("%d frozen\n", frozen); X ModBits |= PW; X } X else X err("no change"); X non_critical(); X X return; X} @//E*O*F src/freeze.c// if test 3001 -ne "`wc -c <'src/freeze.c'`"; then echo shar: error transmitting "'src/freeze.c'" '(should have been 3001 characters)' fi fi # end of overwriting check echo shar: extracting "'src/groupmap.c'" '(727 characters)' if test -f 'src/groupmap.c' ; then echo shar: will not over-write existing file "'src/groupmap.c'" else sed 's/^X//' >src/groupmap.c <<'@//E*O*F src/groupmap.c//' X#include "sysdep.h" X#include "macros.h" X#include "mem.h" X#include "lists.h" X#include "groupmap.h" X Xextern struct list GroupMapList; Xextern int igmapcmp(); X Xstruct groupmap * Xgetgmnam(name) Xchar *name; X X{ X register int index; X struct groupmap *g; X X if (!groupexists(name)) X return (struct groupmap *) 0; X for (index=0; index < GroupMapList.l_count; index++) { X g = (struct groupmap *) GroupMapList.l_list[index]; X if (eq(g->gm_name, name)) X return g; X } X return (struct groupmap *) 0; X} X Xstruct groupmap * Xgetgmgid(gid) Xint gid; X X{ X int index, found; X X index = search_list(&GroupMapList, (char *)&gid, igmapcmp, &found); X if (found) X return (struct groupmap *) GroupMapList.l_list[index]; X return (struct groupmap *) 0; X} @//E*O*F src/groupmap.c// if test 727 -ne "`wc -c <'src/groupmap.c'`"; then echo shar: error transmitting "'src/groupmap.c'" '(should have been 727 characters)' fi fi # end of overwriting check echo shar: extracting "'src/groupmap.h'" '(161 characters)' if test -f 'src/groupmap.h' ; then echo shar: will not over-write existing file "'src/groupmap.h'" else sed 's/^X//' >src/groupmap.h <<'@//E*O*F src/groupmap.h//' Xstruct groupmap { X int gm_gid; X char *gm_name; X char *gm_passwd; X struct list gm_mem; X struct list gm_aliases; X}; X Xstruct groupmap *getgmnam(), *getgmgid(); @//E*O*F src/groupmap.h// if test 161 -ne "`wc -c <'src/groupmap.h'`"; then echo shar: error transmitting "'src/groupmap.h'" '(should have been 161 characters)' fi fi # end of overwriting check echo shar: extracting "'src/history.h'" '(278 characters)' if test -f 'src/history.h' ; then echo shar: will not over-write existing file "'src/history.h'" else sed 's/^X//' >src/history.h <<'@//E*O*F src/history.h//' X#define MAXHIST 40 X Xstruct hist { X char *h_line; /* contents of line */ X char *h_prompt; /* prompt */ X int h_argc; /* arg count */ X int h_index; /* cursor */ X int h_windex; /* word index */ X int h_qopen; /* quote open? */ X struct list *h_list; /* completion list */ X}; X @//E*O*F src/history.h// if test 278 -ne "`wc -c <'src/history.h'`"; then echo shar: error transmitting "'src/history.h'" '(should have been 278 characters)' fi fi # end of overwriting check echo shar: extracting "'src/job.h'" '(242 characters)' if test -f 'src/job.h' ; then echo shar: will not over-write existing file "'src/job.h'" else sed 's/^X//' >src/job.h <<'@//E*O*F src/job.h//' Xstruct job { X int jb_todo; X char *jb_name; X char *jb_oldname; X int jb_uid; X int jb_olduid; X int jb_gid; X addr jb_addr; X}; X X#define JB_LASTLOG 1 X#define JB_MKDIR 2 X#define JB_MV 3 X#define JB_OMNICHOWN 4 X#define JB_RMDIR 5 X#define JB_RMMAIL 6 @//E*O*F src/job.h// if test 242 -ne "`wc -c <'src/job.h'`"; then echo shar: error transmitting "'src/job.h'" '(should have been 242 characters)' fi fi # end of overwriting check echo shar: "End of archive 4 (of 8)." cp /dev/null ark4isdone 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