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 l

⟦e610c3f07⟧ TextFile

    Length: 7238 (0x1c46)
    Types: TextFile
    Names: »load.c«

Derivation

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

TextFile

#include <stdio.h>
#include <sys/types.h>
#include <sys/file.h>
#include <lastlog.h>
#include <strings.h>
#include "sysdep.h"
#include "macros.h"
#include "mem.h"
#include "gpa.h"
#include "lists.h"
#include "account.h"
#include "groupmap.h"
#include "save.h"
#include "sort.h"

addr	makeusername(), gethomedir();
int	nlformat(), nfformat(), (*format)(), ModBits;
extern	addr DEF_SHELL;
char	*crypt(), *sprintf();

int	lineno;
addr	*filev;

loadfile(c, v)
int c;
addr *v;

{
	FILE *f;
	flexaddr p;
	char line[LONG_BUF];
	addr user, password, id, dir, *vv;
	addr *realnamev;
	addr_t shell[MEDIUM_BUF];
	struct account *ac;
	struct groupmap *gm, *gm2;
	static struct list groups, classes, sigs;
	int cc, added, gid, uid, i;
	int totaladded = 0, filesloaded = 0;

	zerolist(&groups);	tmplistadd(&groups);
	zerolist(&sigs);	tmplistadd(&sigs);
	zerolist(&classes);	tmplistadd(&classes);
	if (c == 1) {
		filev = get_gpa(8);
		GetFilenames("Files: ", 8, &cc, filev);
		if (cc == 0)
			return;
	}
	else
		filev = &v[1];
	for (; *filev; filev++) {
		added = 0;
		lineno = 1;
		if (access((char *)*filev, F_OK|R_OK) == -1) {
			perr((char *)*filev);
			err1("%s: file load aborted", (char *)*filev);
			continue;
		}
		f = fopen((char *)*filev, "r");
		if (f == NULL) {
			perr((char *)*filev);
			err1("%s: file load aborted", (char *)*filev);
			continue;
		}
		if (hascolon(f)) {
			err1("%s: file has colons in it! (load aborted)",
				(char *)*filev);
			continue;
		}
		(void) printf("%s:\n",(char *)*filev);
		/*
		 * First line should identity the file format
		 */
		if (fgets(line, BUFSIZ, f) == NULL) {
			gag("missing format line");
			gag("file load aborted");
			continue;
		}
		switch (*line) {
			/* name first format */
		case 'N':
		case 'n': format = nfformat;	break;
			/* Id first format */
		case 'I':
		case 'i': format = nlformat;	break;
		default:
			gag1("bad format token \"%.8s\"", line);
			gag("file load aborted");
			continue;
		}
		lineno++;
		/*
		 * Second line should be a list of space separated
		 * groups that the added users will be put into
		 * The first group in the list will be the users base
		 * gid group (the group for the gid in the passwd file).
		 * It is an error for this line to be empty.
		 */
		if (fgets(line, BUFSIZ, f) == NULL) {
			gag("missing groups line");
			gag("file load aborted");
			continue;
		}
		parse_line(line, &cc, &vv);
		if (cc == 0) {
			gag("groups line empty");
			gag("file load aborted");
			continue;
		}
		gm = getgmnam((char *)vv[0]);
		if (!gm) {
			gag1("%s: no such group", (char *)vv[0]);
			gag("file load aborted");
			continue;
		}
		gid = gm->gm_gid;
		for (vv++; *vv; vv++)
			if (groupexists((char *)*vv))
				strlistadd(&groups, (char *)*vv);
			else
				gag1("%s: no such group", (char *)*vv);
		lineno++;
		/*
		 * Third line should be a space separated list of
		 * classes for the users to put in.  This line must
		 * be peresent although it is permitted to be empty.
		 */
		if (fgets(line, BUFSIZ, f) == NULL) {
			gag("missing classes line");
			gag("file load aborted");
			continue;
		}
		parse_line(line, &cc, &vv);
		for (; *vv; vv++)
			if (classexists((char *)*vv))
				strlistadd(&classes, (char *)*vv);
			else
				gag1("%s: no such class", (char *)*vv);
		lineno++;
		/*
		 * Fourth line should be a space separated list of
		 * sigs for the users to put in.  This line must
		 * be present although it is permitted to be empty.
		 */
		if (fgets(line, BUFSIZ, f) == NULL) {
			gag("missing sigs line");
			gag("file load aborted");
			continue;
		}
		parse_line(line, &cc, &vv);
		for (; *vv; vv++)
			if (sigexists((char *)*vv))
				strlistadd(&sigs, (char *)*vv);
			else
				gag1("%s: no such sig", (char *)*vv);
		lineno++;
		/*
		 * Fifth line should contain the name of the shell
		 * the added users should have.  This line must be
		 * present but it may be blank.
		 */
		if (fgets(line, BUFSIZ, f) == NULL) {
			gag("missing shell line");
			gag("file load aborted");
			continue;
		}
		parse_line(line, &cc, &vv);
		if (cc && !fileexists((char *)vv[0])) {
			gag1("%s: nonexistent shell", (char *)vv[0]);
			gag("file load aborted");
		}
		else if (cc)
			(void) strcpy((char *)shell, (char *)vv[0]);
		else
			(void) strcpy((char *)shell, (char *)DEF_SHELL);
		lineno++;
		/*
		 * Lines from here on should be in the format specified
		 * above.
		 */
		while (fgets(line, LONG_BUF, f) != NULL) {
			if ((*format)(line, &cc, &realnamev, &id) == 0) {
				gag("badly formed line");
				continue;
			}
			ac = getacid((char *)id);
			if (ac) {
				user = ac->ac_name;
				(void) orstrlist(&ac->ac_groups, &groups);
				orstrlist(&ac->ac_classes, &classes)&&
					ModBits |= AC;
				orstrlist(&ac->ac_sigs, &sigs)&&
					ModBits |= AC;
				for (i=0; i<groups.l_count; i++) {
				    gm2 = getgmnam((char *)groups.l_list[i]);
				    if (instrlist(&gm2->gm_mem, (char *)user))
					continue;
				    ModBits |= (AC|GR);
				    strlistadd(&gm2->gm_mem, (char *)user);
				    sort_list(&gm2->gm_mem, pstrcmp);
				}
				(void) printf("%-12s%s\n", ac->ac_name,
					ac->ac_realname);
				continue;
			}
			uid = findnextuid(gm->gm_name);
			if (uid == NOMORE) {
				gag("no more uids");
				gag("load terminated");
				goto nextfile;
			}
			user = makeusername(cc, realnamev);
			p.p_cp = crypt((char *)id, CRYPT_SALT);
			password = p.p_ap;
			dir = gethomedir((char *)user, gm->gm_name);
			addu(uid, gid, user, glob(realnamev), password,
				id, dir, shell);
			added++;
			ac = getacnam((char *)user);
			(void) orstrlist(&ac->ac_groups, &groups);
			orstrlist(&ac->ac_classes, &classes)&&ModBits|=AC;
			orstrlist(&ac->ac_sigs, &sigs)&&ModBits|=AC;
			for (i=0; i<groups.l_count; i++) {
				gm2 = getgmnam((char *)groups.l_list[i]);
				if (instrlist(&gm2->gm_mem, (char *)user))
					continue;
				ModBits |= (AC|GR);
				strlistadd(&gm2->gm_mem, (char *)user);
				sort_list(&gm2->gm_mem, pstrcmp);
			}
			(void) printf("%-12s%s\n", ac->ac_name,
					ac->ac_realname);
		}
	nextfile:
		(void) printf("%s: %d added\n", *filev, added);
		filesloaded++;
		totaladded += added;
		freelist(&groups);
		freelist(&sigs);
		freelist(&classes);
	}
	if (totaladded) {
		(void) printf("%d file%s loaded, %d user%s added\n",
				filesloaded, S(filesloaded),
				totaladded, S(totaladded));
#ifndef	DOFILES
		err("Don't forget to create directories for these users.");
#endif
	}
	return;
}

int
hascolon(f)
FILE *f;

{
	int c;

	rewind(f);
	while ((c = getc(f)) != EOF)
		if (c == ':') {
			rewind(f);
			return 1;
		}
	rewind(f);
	return 0;
}

int
nfformat(line, cc, r, id)
char *line;
int *cc;
addr **r;
addr *id;

{
	int c;
	addr *v;

	parse_line(line, &c, &v);
	if (c < 2)
		return 0;
	*id = v[c-1];
	v[c-1] = NIL;
	*cc = c - 1;
	*r = v;
	return 1;
}

int
nlformat(line, cc, r, id)
char *line;
int *cc;
addr **r;
addr *id;

{
	int c;
	addr *v;

	parse_line(line, &c, &v);
	if (c < 2)
		return 0;
	*id = v[0];
	*cc = c - 1;
	*r = &v[1];
	return 1;
}

static
gag(msg)
char *msg;

{
	char errmsg[LONG_BUF];

	(void) sprintf(errmsg, "%s: line %d: %s", *filev, lineno, msg);
	err(errmsg);
	return;
}

static
gag1(msg, s1)
char *msg;
char *s1;

{
	char errmsg[LONG_BUF];

	(void) sprintf(errmsg, msg, s1);
	gag(errmsg);
	return;
}