|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T s ┃
Length: 8666 (0x21da) Types: TextFile Names: »save.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/save.c«
/**************************************************************************\ * * * save.c * * * * These are the routines that save the information into the respective * * accounting files. An important thing to remember here is that the save * * and checkpointing routines USE THE SAME TEMPORARY FILES. So no * * checkpointing must be done while saving is being done, and vice versa. * * Conflicts are avoided by blocking the all signals that would trigger * * either periodic or crash checkpointing, until saving is complete. * * * * Also the tempfiles must be in the same filesystem as their associated * * accounting files or the rename() system call will fail attempting to * * link the tempfile to the accounting file with errno == EXDEV. * * * \**************************************************************************/ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <signal.h> #include <lastlog.h> #include <strings.h> #include "sysdep.h" #include "macros.h" #include "mem.h" #include "lists.h" #include "account.h" #ifdef SENDMAIL #include "alias.h" #endif #include "class.h" #include "sig.h" #include "range.h" #include "groupmap.h" #include "save.h" extern int ModBits; extern time_t PWLockTime, time(); #ifdef SENDMAIL extern struct list AliasList; #endif extern struct list AccountList, GroupMapList, SigList, ClassList, RangeList; extern struct list Vigs; save_pw() { FILE *pwf; int i; struct account *ac; #ifdef BSD4_3 char *av[4]; char tmpdotdir[MEDIUM_BUF], tmpdotpag[MEDIUM_BUF]; char dotdir[MEDIUM_BUF], dotpag[MEDIUM_BUF]; #endif pwf = fopen(PWDTMP, "w"); if (pwf == NULL) { perr(PWDTMP); return; } for (i=0; i < AccountList.l_count; i++) { ac = (struct account *) AccountList.l_list[i]; (void) fprintf(pwf, "%s:%s:%d:%d:%s:%s:%s\n", ac->ac_name, ac->ac_passwd, ac->ac_uid, ac->ac_gid, ac->ac_gecos, ac->ac_dir, ac->ac_shell); } (void) fclose(pwf); #ifdef BSD4_3 (void) strcpy(tmpdotdir, PWDTMP); (void) strcpy(tmpdotpag, PWDTMP); (void) strcpy(dotdir, PWDFILE); (void) strcpy(dotpag, PWDFILE); (void) strcat(tmpdotdir, ".dir"); (void) strcat(tmpdotpag, ".pag"); (void) strcat(dotdir, ".dir"); (void) strcat(dotpag, ".pag"); (void) unlink(tmpdotdir); (void) unlink(tmpdotpag); av[0] = "shell-escape"; av[1] = DBMPASSWORD; av[2] = PWDTMP; av[3] = (char *) 0; if (shellescape(3, (addr *)av) != 0) { err1("%s failed", DBMPASSWORD); return; } if (rename(tmpdotdir, dotdir) == -1) { perr("rename"); err2("%s -> %s rename failed", tmpdotdir, dotdir); return; } if (rename(tmpdotpag, dotpag) == -1) { perr("rename"); err2("%s -> %s rename failed", tmpdotdir, dotdir); return; } #endif if (rename(PWDTMP, PWDFILE) == -1) { perr(PWDTMP); return; } ModBits &= ~PW; (void) unlink(PWDCKP); return; } #ifdef SENDMAIL save_al() { FILE *alf, *bindf; struct alias *al; char *av[3]; register int i; alf = fopen(ALIASTMP, "w"); if (alf == NULL) { perr(ALIASTMP); return; } bindf = fopen(ALBINDTMP, "w"); if (bindf == NULL) { perr(ALBINDTMP); (void) fclose(alf); return; } for (i=0; i < AliasList.l_count; i++) { al = (struct alias *) AliasList.l_list[i]; (void) fprintf(alf, "%s:", al->al_name); listout(&al->al_addresses, alf); fputs("\n", alf); (void) fprintf(bindf, "%s:", al->al_name); listout(&al->al_groups, bindf); fputs(":", bindf); listout(&al->al_classes, bindf); fputs(":", bindf); listout(&al->al_sigs, bindf); fputs("\n", bindf); } (void) fclose(alf); (void) fclose(bindf); av[0] = "shell-escape"; av[1] = NEWALIASES; av[2] = (char *)0; if (rename(ALIASTMP, ALIASFILE) == -1) { perr(ALIASTMP); return; } if (rename(ALBINDTMP, ALBIND) == -1) { perr(ALBINDTMP); return; } if (shellescape(2, (addr *) av) != 0) { err1("newaliases seemed unhappy with %s", ALIASFILE); return; } ModBits &= ~AL; (void) unlink(ALIASCKP); (void) unlink(ALBINDCKP); } #endif save_ac() { FILE *acf; register int i; struct account *ac; acf = fopen(ACTMP, "w"); if (acf == NULL) { perr(ACTMP); return; } for (i=0; i < AccountList.l_count; i++) { ac = (struct account *) AccountList.l_list[i]; (void) fprintf(acf, "%s:%s:%s:%d:%d:", ac->ac_name, ac->ac_realname, ac->ac_id, ac->ac_uid, ac->ac_gid); listout(&ac->ac_groups, acf); fputs(":", acf); listout(&ac->ac_classes, acf); fputs(":", acf); listout(&ac->ac_sigs, acf); fputs(":", acf); #ifdef SENDMAIL listout(&ac->ac_aliases, acf); #endif fputs("\n", acf); } (void) fclose(acf); if (rename(ACTMP, ACFILE) == -1) { perr(ACTMP); return; } ModBits &= ~AC; (void) unlink(ACCKP); return; } save_gr() { FILE *grf; register int i; struct groupmap *gm; grf = fopen(GRPTMP, "w"); if (grf == NULL) { perr(GRPTMP); return; } for (i=0; i < GroupMapList.l_count; i++) { gm = (struct groupmap *) GroupMapList.l_list[i]; (void) fprintf(grf, "%s:%s:%d:", gm->gm_name, gm->gm_passwd, gm->gm_gid); listout(&gm->gm_mem, grf); fputs("\n", grf); } (void) fclose(grf); if (rename(GRPTMP, GRPFILE) == -1) { perr(GRPTMP); return; } ModBits &= ~GR; (void) unlink(GRPCKP); return; } save_cs() { struct class *cs; register int i; FILE *csf; csf = fopen(CSTMP, "w"); if (csf == NULL) { perr(CSTMP); return; } for (i=0; i < ClassList.l_count; i++) { cs = (struct class *) ClassList.l_list[i]; (void) fprintf(csf, "%s %d %d\n", cs->cs_name, cs->cs_dsize, cs->cs_exptime); (void) fprintf(csf, "%s", cs->cs_desc); } (void) fclose(csf); if (rename(CSTMP, CSFILE) == -1) { perr(CSTMP); return; } ModBits &= ~CS; (void) unlink(CSCKP); return; } save_sg() { struct sig *sg; register int i; FILE *sgf; sgf = fopen(SIGTMP, "w"); if (sgf == NULL) { perr(SIGTMP); return; } for (i=0; i < SigList.l_count; i++) { sg = (struct sig *) SigList.l_list[i]; (void) fprintf(sgf, "%s %d %d\n", sg->sg_name, sg->sg_dsize, sg->sg_exptime); (void) fprintf(sgf, "%s", sg->sg_desc); } (void) fclose(sgf); if (rename(SIGTMP, SIGFILE) == -1) { perr(SIGTMP); return; } ModBits &= ~SG; (void) unlink(SIGCKP); return; } save_rg() { struct range *rg; register int i; FILE *rgf; rgf = fopen(RANGETMP, "w"); if (rgf == NULL) { perr(RANGETMP); return; } for (i=0; i < RangeList.l_count; i++) { rg = (struct range *) RangeList.l_list[i]; (void) fprintf(rgf, "%s\t%d\t%d\t%s\n", rg->rg_name, rg->rg_from, rg->rg_to, (rg->rg_mode == RG_SHARED ? "shared" : "exclusive")); } (void) fclose(rgf); if (rename(RANGETMP, RANGEFILE) == -1) { perr(RANGETMP); return; } ModBits &= ~RG; (void) unlink(RANGECKP); return; } save_vg() { register int i; FILE *vgf; vgf = fopen(VIGTMP, "w"); if (vgf == NULL) { perr(VIGTMP); return; } for (i=0; i < Vigs.l_count; i++) (void) fprintf(vgf, "%s\n", Vigs.l_list[i]); (void) fclose(vgf); if (rename(VIGTMP, VIGFILE) == -1) { perr(VIGTMP); return; } ModBits &= ~VG; (void) unlink(VIGCKP); return; } saveandexit() { savechanges(); exitmcp(); } savechanges() { if (ModBits == 0 || lock_check() == 0) return; /* * Interrupts are disabled for obvious reasons. * SIGTERM, SIGALRM, SIGHUP, and SIGQUIT must be blocked because * the save and checkpoint routines use the same tempfiles. * If a checkpoint were to occur while files where being saved, * chaos would ensue. */ critical(); do_jobs(); (ModBits&PW) && backup(PW) && save_pw(); (ModBits&AC) && backup(AC) && save_ac(); #ifdef SENDMAIL (ModBits&AL) && backup(AL) && save_al(); #endif (ModBits&CS) && backup(CS) && save_cs(); (ModBits&GR) && backup(GR) && save_gr(); (ModBits&RG) && backup(RG) && save_rg(); (ModBits&SG) && backup(SG) && save_sg(); (ModBits&VG) && backup(VG) && save_vg(); sync(); (void) time(&PWLockTime); non_critical(); return; } static char *acctfile[] = { PWDFILE, ACFILE, #ifdef SENDMAIL ALIASFILE, ALBIND, #endif CSFILE, GRPFILE, RANGEFILE, SIGFILE, VIGFILE, (char *) 0 }; int lock_check() { register int i; struct stat s; int uhoh = 0; if (!fileexists(PWDLOCK)) { err1("My %s lockfile has been been removed!", PWDLOCK); if (yesno("Do the save anyway? ") == 0) return 0; } for (i=0; acctfile[i]; i++) { if (stat(acctfile[i], &s) == -1) continue; if (s.st_mtime > PWLockTime) { err1("%s has been modified", acctfile[i]); uhoh = 1; } } if (uhoh) { err1("My %s lock has been violated.", PWDLOCK); err(""); return yesno("Do the save anyway? "); } return 1; }