|
|
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 - metrics - 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;
}