DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T s

⟦19613bc86⟧ TextFile

    Length: 8666 (0x21da)
    Types: TextFile
    Names: »save.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/save.c« 

TextFile

/**************************************************************************\
* 									   *
* 	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;
}