|
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 l
Length: 10902 (0x2a96) Types: TextFile Names: »loc_proto.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Chans/slocal/loc_proto.c«
/* loc_proto.c: subroutines to help with local delivery */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/slocal/RCS/loc_proto.c,v 5.0 90/09/20 15:53:58 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Chans/slocal/RCS/loc_proto.c,v 5.0 90/09/20 15:53:58 pp Exp Locker: pp $ * * $Log: loc_proto.c,v $ * Revision 5.0 90/09/20 15:53:58 pp * rcsforce : 5.0 public release * */ #include "util.h" #include "retcode.h" #include <sys/wait.h> #include <sys/file.h> #include "loc_user.h" #include <isode/usr.dirent.h> #include <sys/stat.h> #define P_READ 0 #define P_WRITE 1 #define NULLDIR ((DIR*)0) #define NULLDCT ((struct dirent *)0) static char *next_message(); static int fdin = NOTOK, fdout = NOTOK; static int pid, sysreply; static FILE *cur_fp = NULL; static DIR *mb_dp = NULL; static int copy(); static struct loc_packet { int command; #define LP_OPEN 1 #define LP_CLOSE 2 #define LP_CD 3 #define LP_WRITE 4 #define LP_MOVE 5 #define LP_MKDIR 6 #define LP_OPENDIR 7 #define LP_CLOSEDIR 8 #define LP_SYSTEM 9 #define LP_NEXTMESS 10 #define LP_ISDIR 11 char s1 [FILNSIZE]; char s2 [FILNSIZE]; int size; }; /* ------------------- Begin Routines ------------------------------------- */ loc_init (loc) LocUser *loc; { int p1[2], p2[2]; if (fdin != NOTOK || fdout != NOTOK) loc_end(); if (pipe(p1) == NOTOK) return RP_BAD; if (pipe (p2) == NOTOK) { (void) close (p1[P_READ]); (void) close (p1[P_WRITE]); return RP_BAD; } ll_close (pp_log_norm); if ((pid = tryfork()) == NOTOK) { (void) close (p1[P_READ]); (void) close (p1[P_WRITE]); (void) close (p2[P_READ]); (void) close (p2[P_WRITE]); return RP_BAD; } if (pid) { (void) close (p1[P_READ]); fdout = p1[P_WRITE]; (void) close (p2[P_WRITE]); fdin = p2[P_READ]; return RP_OK; } (void) close (p1[P_WRITE]); (void) close (p2[P_READ]); fdin = p1[P_READ]; fdout = p2[P_WRITE]; if ((loc -> username && initgroups (loc -> username, loc -> gid) == -1) || setregid (loc -> gid, loc -> gid) == -1 || setreuid (loc -> uid, loc -> uid) == -1) { PP_SLOG (LLOG_EXCEPTIONS, "user", ("Can't set uid/gid")); _exit(1); } if (chdir (loc -> directory) == NOTOK) { PP_SLOG (LLOG_EXCEPTIONS, "chdir", ("Can't change directory to %s", loc -> directory)); _exit (1); } do_child_stuff(); /* NOTREACHED */ } int loc_cd (dir, rp) char *dir; RP_Buf *rp; { struct loc_packet packet; packet.command = LP_CD; (void) strcpy (packet.s1, dir); return send_pac (&packet, rp); } int loc_mkdir (dir, mode, rp) char *dir; int mode; RP_Buf *rp; { struct loc_packet packet; packet.command = LP_MKDIR; (void) strcpy (packet.s1, dir); packet.size = mode; return send_pac (&packet, rp); } int loc_write (buf, size, rp) char *buf; int size; RP_Buf *rp; { struct loc_packet packet; packet.command = LP_WRITE; packet.size = size; if (write (fdout, (char *)&packet, sizeof packet) != sizeof packet) return loc_set (rp, RP_FIO, "Can't write"); if (write (fdout, buf, size) != size) return loc_set (rp, RP_FIO, "Can't write"); if (read (fdin, (char *)rp, sizeof *rp) != sizeof *rp) return loc_set (rp, RP_LIO, "Can't get response"); return loc_set (rp, RP_OK, "OK"); } int loc_close (rp) RP_Buf *rp; { struct loc_packet packet; packet.command = LP_CLOSE; return send_pac (&packet, rp); } int loc_open (file, mode, flag, rp) char *file; char *mode; int flag; RP_Buf *rp; { struct loc_packet packet; packet.command = LP_OPEN; (void) strcpy (packet.s1, file); (void) strcpy (packet.s2, mode); packet.size = flag; return send_pac (&packet, rp); } loc_move (s1, s2, rp) char *s1, *s2; RP_Buf *rp; { struct loc_packet packet; packet.command = LP_MOVE; (void) strcpy (packet.s1, s1); (void) strcpy (packet.s2, s2); return send_pac (&packet, rp); } int loc_opendir (dir, rp) char *dir; RP_Buf *rp; { struct loc_packet packet; packet.command = LP_OPENDIR; (void) strcpy (packet.s1, dir); return send_pac (&packet, rp); } int loc_closedir (rp) /* Close previous OPENDIR */ RP_Buf *rp; { struct loc_packet packet; packet.command = LP_CLOSEDIR; return send_pac (&packet, rp); } int loc_system (str, rp) char *str; RP_Buf *rp; { struct loc_packet packet; packet.command = LP_SYSTEM; (void) strcpy (packet.s1, str); return send_pac (&packet, rp); } int loc_isdir (dir, rp) char *dir; RP_Buf *rp; { struct loc_packet packet; packet.command = LP_ISDIR; (void) strcpy (packet.s1, dir); return send_pac (&packet, rp); } int loc_nextmess (dir, rp) char *dir; RP_Buf *rp; { struct loc_packet packet; packet.command = LP_NEXTMESS; (void) strcpy (packet.s1, dir); return send_pac (&packet, rp); } loc_end() { int cpid; if (fdout != NOTOK) { (void) close (fdout); fdout = NOTOK; } if (fdin != NOTOK) { (void) close (fdin); fdin = NOTOK; } while ((cpid = wait ( (union wait *)0 )) != pid && cpid != -1) continue; return RP_OK; } /* ------------------- Static Routines ------------------------------------ */ static int loc_set (rp, val, str) RP_Buf *rp; int val; char *str; { rp -> rp_val = val; (void) strcpy (rp -> rp_line, str); return val; } static int send_pac (pp, rp) struct loc_packet *pp; RP_Buf *rp; { if (write (fdout, (char *)pp, sizeof *pp) != sizeof *pp) return loc_set (rp, RP_FIO, "Can't write"); if (read (fdin, (char *)rp, sizeof *rp) != sizeof *rp) return loc_set (rp, RP_LIO, "Can't get response"); return rp -> rp_val; } static do_child_stuff() { struct loc_packet packet; struct loc_packet *pp = &packet; RP_Buf rps, *rp = &rps; while (read (fdin, (char *)pp, sizeof (*pp)) == sizeof (*pp)) { (void) do_packet (pp, rp); if (write (fdout, (char *)rp, sizeof *rp) != sizeof *rp) { PP_SLOG (LLOG_EXCEPTIONS, "write", ("Write error on packet")); exit (1); } } exit (0); } static int do_packet (pp, rp) struct loc_packet *pp; RP_Buf *rp; { switch (pp->command) { case LP_OPEN: if (cur_fp != NULL) (void) fclose (cur_fp); if ((cur_fp = fopen(pp -> s1, pp -> s2)) == NULL) { PP_SLOG (LLOG_EXCEPTIONS, "fopen", ("Can't open file %s mode %s", pp -> s1, pp -> s2)); return loc_set (rp, RP_FOPN, "Can't open file"); } if (pp -> size) { if (flock (fileno (cur_fp), LOCK_EX) == NOTOK) { PP_SLOG (LLOG_EXCEPTIONS, "flock", ("Can't lock file %s", pp -> s1)) (void) fclose (cur_fp); cur_fp = NULL; return loc_set (rp, RP_LOCK, "Can't lock file"); } } return loc_set (rp, RP_OK, "OK"); case LP_CLOSE: if (cur_fp != NULL) { (void) fclose (cur_fp); cur_fp = NULL; } return loc_set (rp, RP_OK, "OK"); case LP_CD: if (chdir (pp -> s1) == NOTOK) { PP_SLOG (LLOG_EXCEPTIONS, "chdir", ("Can't change directory to %s", pp -> s1)); return loc_set (rp, RP_LIO, "Can't chdir"); } return loc_set (rp, RP_OK, "OK"); case LP_WRITE: if (cur_fp == NULL) return loc_set (rp, RP_FIO, "No file open"); return copy (fdin, cur_fp, pp -> size, rp); case LP_MOVE: if (rename (pp -> s1, pp-> s2) == NOTOK) { PP_SLOG (LLOG_EXCEPTIONS, "rename", ("Can't move %s to %s", pp -> s1, pp -> s2)); return loc_set (rp, RP_LIO, "Can't move file"); } return loc_set (rp, RP_OK, "OK"); case LP_MKDIR: if (mkdir (pp -> s1, pp -> size) == NOTOK) { PP_SLOG (LLOG_EXCEPTIONS, "mkdir", ("Can't make directory %s mode %o", pp->s1, pp->size)); return loc_set (rp, RP_LIO, "Can't make directory"); } return loc_set (rp, RP_OK, "OK"); case LP_OPENDIR: if (mb_dp != NULL) (void) closedir (mb_dp); if ((mb_dp = opendir(pp -> s1)) == NULL) { PP_SLOG (LLOG_EXCEPTIONS, "opendir", ("Can't open directory %s", pp->s1)); return loc_set (rp, RP_LIO, "Can't open directory"); } return loc_set (rp, RP_OK, "OK"); case LP_CLOSEDIR: if (mb_dp != NULL) { (void) closedir (mb_dp); mb_dp = NULL; } return loc_set (rp, RP_OK, "OK"); case LP_SYSTEM: if ((sysreply = system(pp -> s1)) ) { PP_SLOG (LLOG_EXCEPTIONS, "system", ("system() call returns value %d",sysreply)); } /* I'm not sure if I should do this */ return loc_set (rp, sysreply, "OK"); case LP_NEXTMESS: if (mb_dp == NULL) { return loc_set (rp, RP_FIO, "No directory open"); } return loc_set (rp, RP_OK, next_message (mb_dp, pp -> s1) ); case LP_ISDIR: if (!isdir (pp -> s1)) { return loc_set (rp, RP_MECH, "Not a directory"); } return loc_set (rp, RP_OK, "OK"); default: PP_LOG (LLOG_EXCEPTIONS, ("Unknown command %d")); return loc_set (rp, RP_PARM, "Unknown command"); } } static int copy (in, out, size, rp) int in; FILE *out; int size; RP_Buf *rp; { char buffer[BUFSIZ]; int n; (void) loc_set (rp, RP_OK, "OK"); while (size > 0) { n = read (in, buffer, size > sizeof buffer ? sizeof buffer : size); if (n <= 0) return loc_set (rp, RP_FIO, "Read error"); if (out) if (fwrite (buffer, 1, n, out) != n) (void) loc_set (rp, RP_FIO, "Write error"); size -= n; } return rp -> rp_val; } /* --- generate next message number for this directory --- */ static char* next_message(mb_dp,dir) DIR *mb_dp; char *dir; { struct dirent *dp; int i,biggest=0; char fullname[FILNSIZE]; for(dp = readdir(mb_dp); dp != NULLDCT; dp = readdir(mb_dp)) { sprintf(fullname,"%s/%s",dir,dp->d_name); if (isdir(fullname)) { i = val(dp->d_name); if (i > biggest) biggest=i; } } PP_DBG (("loc_proto/next_message number in %s = %d",dir,biggest+1)); sprintf(fullname,"%d", (biggest + 1) ); return(fullname); } /* return value of s iff composed of digits, else 0 */ static val(s) char *s; { int i,n; for(i=0,n=0; s[i] != NULL ; ++i) { if (s[i] >= '0' && s[i] <= '9') n = 10 * n + s[i] - '0'; else { n=0; break; } } PP_DBG (("loc_proto/val(%s)=%d", s,n)); return(n); } static isdir (name) char *name; { struct stat st_rec; if (!isstr (name)) return (FALSE); if (stat (name, &st_rec) == NOTOK) { PP_SLOG (LLOG_EXCEPTIONS, name, ("isdir: Unable to stat")); return (FALSE); } switch (st_rec.st_mode & S_IFMT) { case S_IFDIR: PP_DBG (("loc_proto/isdir (%s = TRUE)", name)); return (TRUE); default: PP_DBG (("loc_proto/isdir (%s = FALSE)", name)); return (FALSE); } }