|
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 - 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