|
|
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 j
Length: 8459 (0x210b)
Types: TextFile
Names: »job.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/job.c«
/****************************************************************************\
* *
* 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