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 j

⟦2026a1726⟧ TextFile

    Length: 8459 (0x210b)
    Types: TextFile
    Names: »job.c«

Derivation

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

TextFile

/****************************************************************************\
* 									     *
* 	job.c								     *
* 									     *
* add_job()	add a job to the job list for later execution.		     *
* do_jobs()	do the jobs in the job list.				     *
* rmmail()	remove a user's mail					     *
* rmsmail()	remove a user's secretmail				     *
* omni_chown()	change the ownership of all a user's files to another uid    *
* 									     *
* Also lastlog entries are updated here, although the actual routine that    *
* writes the file is in lastlog.c .  Directories are made and moved around   *
* here, but there are system calls that do these things.		     *
* 									     *
\****************************************************************************/

#include <stdio.h>
#include <strings.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h
#include <sys/dir.h>
#include <lastlog.h>
#include "sysdep.h"
#include "mem.h"
#include "lists.h"
#include "job.h"

#ifdef sun
# ifdef DOFILES
extern	u_short ExecTcpPort;
extern	char FileServer[], MountDirectory[], RemotePassword[];
extern	int IsRemote;
extern	char HostName[];
# endif
#endif
extern	struct list Jobs;
char	*re_comp(), *sprintf();
extern	int kids;

/* ARGSUSED */
add_job(todo, arg1, arg2, arg3)
int todo;
addr arg1, arg2, arg3;

{
	struct job jb;

	jb.jb_todo = todo;
	switch (jb.jb_todo) {
	case JB_LASTLOG:
		jb.jb_uid = (int) *arg1;
		jb.jb_addr = MEM(sizeof (struct lastlog));
		bcopy(jb.jb_addr, arg2, sizeof (struct lastlog));
		break;

#ifdef DOFILES
	case JB_MKDIR:
		savestr(&jb.jb_name, (char *) arg1);
		jb.jb_uid = (int) *arg2;
		jb.jb_gid = (int) *arg3;
		break;

	case JB_MV:
		savestr(&jb.jb_oldname, (char *) arg1);
		savestr(&jb.jb_name, (char *) arg2);
		break;
	case JB_RMDIR:
	case JB_RMMAIL:
		savestr(&jb.jb_name, (char *) arg1);
		break;

	case JB_OMNICHOWN:
		jb.jb_olduid = (int) *arg1; 
		jb.jb_uid = (int) *arg2;
		break;
#endif

	default:
		return;
	}
	genlistadd(&Jobs, (addr) &jb, sizeof (struct job));
	return;
}

do_jobs()

{
	struct job *jb;
	struct lastlog ll;
	int currjobs, success;
	char errmsg[LONG_BUF];

	currjobs = Jobs.l_count;
	while (currjobs--) {
		jb = (struct job *) listpop(&Jobs);
		success = 0;
		switch (jb->jb_todo) {
		case JB_LASTLOG:
			bcopy(&ll, jb->jb_addr, sizeof (struct lastlog));
			addllent(&ll, jb->jb_uid);
			FREEMEM((char *)jb->jb_addr);
			success++;
			break;

#ifdef DOFILES
		case JB_MKDIR:
# ifdef sun
			if (IsRemote) {
				success = makedir(jb->jb_name, 0755,
						jb->jb_uid, jb->jb_gid);
				if (success) FREEMEM(jb->jb_name);
				break;
			}
			else
# endif
			/*
			 * Here we assume if the mkdir() fails the  directory
			 * must already be there.
			 */
			if (mkdir(jb->jb_name, 0755) == 0) {
				(void) chown(jb->jb_name,
						jb->jb_uid, jb->jb_gid);
			}
			FREEMEM(jb->jb_name);
			success++;
			break;

		case JB_MV:
# ifdef sun
			if (IsRemote) {
				success=rrename(jb->jb_oldname, jb->jb_name);
				if (success) {
					FREEMEM(jb->jb_name);
					FREEMEM(jb->jb_oldname);
				}
			}
			else
# endif
			if (rename(jb->jb_oldname, jb->jb_name) == -1) {
				perr("rename");
				err2("rename %s -> %s failed.",
					jb->jb_oldname,
					jb->jb_name);
				break;
			}
			success++;
			FREEMEM(jb->jb_name);
			FREEMEM(jb->jb_oldname);
			break;

		case JB_RMDIR:
			success = purge(jb->jb_name);
			if (!success) break;
			FREEMEM(jb->jb_name);
			break;

		case JB_RMMAIL:
			success = rmmail(jb->jb_name) && rmsmail(jb->jb_name);
			if (!success) break;
			FREEMEM(jb->jb_name);
			break;

		case JB_OMNICHOWN:
			success = omni_chown(jb->jb_olduid, jb->jb_uid);
			break;
#endif
		default:
			(void) sprintf(errmsg,
				"internal error: bad todo in job list (%d)",
				jb->jb_todo);
			err(errmsg);
			success++;	/* to get it out of the list */
			break;
		}
		if (success)
			FREEMEM((char *)jb);
		else
			genlistadd(&Jobs, (addr)jb, sizeof (struct job));
	}
	return;
}

#ifdef DOFILES
char	**environ;

int
purge(path)
char *path;

{
	char command[LONG_BUF];
	addr *v;
	int c, pid;
#ifdef sun
	int n;

	n = strlen(USERDIR)-1;
	if (IsRemote && strncmp(path, USERDIR, n) == 0 && path[n] == '/') {
		(void) strcpy(command, RM);
		(void) strcat(command, " -rf ");
		(void) strcat(command, MountDirectory);
		(void) strcat(command, &path[n]);
		return (DoRemote(command) && !fileexists(path));
	}
#endif
	(void) strcpy(command, RM);
	(void) strcat(command, " -rf ");
	(void) strcat(command, path);
	c = cut(command);
	v = mkargv(command, c);
	pid = vfork();
	if (pid == -1) {
		err1("can't vfork to remove %s", path);
		return 0;
	}
	if (pid == 0) {
		execve((char *)v[0], (char **)v, environ);
		perr((char *)v[0]);
		_exit(1);
	}
	while (wait((union wait *)0) != pid)
		kids--;
	return !fileexists(path);
}

int
rmmail(user)
char *user;

{
	if (chdir(MAILSPOOL) == -1) {
		perr(SMAILSPOOL);
		return 0;
	}
	(void) unlink(user);
	return 1;
}

int
rmsmail(user)
char *user;

{
	DIR *dirp;
	char buf[MEDIUM_BUF];
	struct direct *dp;

	if (chdir(SMAILSPOOL) == -1) {
		perr(SMAILSPOOL);
		return 0;
	}
	dirp = opendir(".");
	if (dirp == NULL) {
		err1("can't open %s (read)", SMAILSPOOL);
		return 0;
	}
	(void) sprintf(buf, "%s\\..*", user);
	(void) re_comp(buf);
	for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
		if (re_exec(dp->d_name) == 1)
			(void) unlink(dp->d_name);
	closedir(dirp);
	return 1;
}

#define OMNIFMT "%s -15 %s %s -user %d -exec %s %d {} ;"

/*
 * When changing file ownerships on Sun's distributed filesystem, we
 * must be careful not to disturb files belonging to a user with the same
 * uid but on another machine!
 */
int
omni_chown(ouid, nuid)
int ouid, nuid;

{
	char command[LONG_BUF];
# ifdef sun
	char dirbuf[MEDIUM_BUF];

	if (IsRemote) {
(void)sprintf(command, OMNIFMT, NICE, FIND, MountDirectory, ouid, CHOWN,nuid);
		(void) strcat(command, " &");
		if (DoRemote(command) == 0) return 0;
	}
	else {
		(void) sprintf(dirbuf, "%s/%s", USERDIR, HostName);
(void) sprintf(command, OMNIFMT, NICE, FIND, dirbuf, ouid, CHOWN, nuid);
		if (BackGround(command) == 0) return 0;
	}
(void) sprintf(command, OMNIFMT, NICE, FIND, SMAILSPOOL, ouid, CHOWN, nuid);
	if (BackGround(command) == 0) return 0;
(void) sprintf(command, OMNIFMT, NICE, FIND, MAILSPOOL, ouid, CHOWN, nuid);
	if (BackGround(command) == 0) return 0;
# else
	(void) sprintf(command, OMNIFMT, NICE, FIND, "/", ouid, CHOWN, nuid);
	if (BackGround(command) == 0) return 0;
# endif
	return 1;
}

BackGround(command)
char *command;

{
	int c, pid;
	addr *v;

	c = cut(command);
	v = mkargv(command, c);

	pid = vfork();
	if (pid == -1) {
		perr("can't vfork");
		return 0;
	}
	kids++;
	if (pid == 0) {
		(void) setpgrp(0, getpid());
		execve((char *)*v, (char **)v, environ);
		perr((char *)*v);
		_exit(1);
	}
	(void) setpriority(PRIO_PROCESS, pid, 15);
	return 1;
}

# ifdef sun

rrename(from, to)
char *from, *to;

{
	int n;
	char command[LONG_BUF];

	n = strlen(USERDIR)-1;
	if (strncmp(from, USERDIR, n) || from[n] != '/') {
		err2("rrename: %s not in %s", from, USERDIR);
		return 0;
	}
	if (strncmp(to, USERDIR, n) || from[n] != '/') {
		err2("rrename: %s not in %s", from, USERDIR);
		return 0;
	}
	(void) sprintf(command, "%s %s%s %s%s", MV, MountDirectory,
			&from[n], MountDirectory, &to[n]);
	return ((!DoRemote(command)) || fileexists(from) || !fileexists(to))
		? 0 : 1;
}

makedir(path, mode, uid, gid)
char *path;
int mode, uid, gid;

{
	int n;
	char command[LONG_BUF];

	n = strlen(USERDIR);
	if (strncmp(path, USERDIR, n) || path[n] != '/') {
		err2("makedir: %s not in %s", path, USERDIR);
		return 0;
	}
(void)	sprintf(command, "%s %s%s", MKDIR, MountDirectory, &path[n]);
	(void) DoRemote(command);
(void)	sprintf(command, "%s %d %s%s", CHOWN, uid, MountDirectory, &path[n]);
	(void) DoRemote(command);
(void)	sprintf(command, "%s %d %s%s", CHGRP, gid, MountDirectory, &path[n]);
	(void) DoRemote(command);
(void)	sprintf(command, "%s %o %s%s", CHMOD, mode, MountDirectory, &path[n]);
	(void) DoRemote(command);
	return 1;
}

static
Tweedle(d)
int d;

{
	char c;

	(void) shutdown(d, 1);
	while (read(d, &c, 1) == 1)
		(void) write(1, &c, 1);
	(void) fsync(1);
	return;
}

int
DoRemote(command)
char *command;

{
	char f[MEDIUM_BUF], *h[1];
	int d;

	(void) strcpy(f, FileServer);
	*h = f;
	d = rexec(h, ExecTcpPort, "root", RemotePassword, command, (int *)0);
	if (d == -1) return 0;
	Tweedle(d);
	(void) close(d);
	return 1;
}

# endif
#endif