v08i044: Account creation/manipulation program, Part04/08
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Sat Feb 7 07:13:28 AEST 1987
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 at 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
More information about the Mod.sources
mailing list