|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <pwd.h> ! 3: #include <signal.h> ! 4: #include "mail.h" ! 5: #include "string.h" ! 6: #include "process.h" ! 7: ! 8: /* ! 9: * the following is pretty safe because upas is very stingy ! 10: * in its file descriptor use. system V fanatics should ! 11: * use the approriate system V system call to get the number ! 12: * of file descriptors ! 13: */ ! 14: #ifndef NOFILE ! 15: #define NOFILE 20 ! 16: #endif ! 17: #ifndef NSYSFILE ! 18: #define NSYSFILE 3 ! 19: #endif ! 20: ! 21: extern char *malloc(); ! 22: extern void exit(); ! 23: extern char *getenv(); ! 24: ! 25: /* make a stream to a child process */ ! 26: extern stream * ! 27: instream() ! 28: { ! 29: stream *rv; ! 30: int pfd[2]; ! 31: ! 32: if ((rv = (stream *)malloc(sizeof(stream))) == NULL) ! 33: return NULL; ! 34: if (pipe(pfd) < 0) ! 35: return NULL; ! 36: if ((rv->fp = fdopen(pfd[1], "w")) == NULL){ ! 37: close(pfd[0]); ! 38: close(pfd[1]); ! 39: return NULL; ! 40: } ! 41: rv->fd = pfd[0]; ! 42: return rv; ! 43: } ! 44: ! 45: /* make a stream from a child process */ ! 46: extern stream * ! 47: outstream() ! 48: { ! 49: stream *rv; ! 50: int pfd[2]; ! 51: ! 52: if ((rv = (stream *)malloc(sizeof(stream))) == NULL) ! 53: return NULL; ! 54: if (pipe(pfd) < 0) ! 55: return NULL; ! 56: if ((rv->fp = fdopen(pfd[0], "r")) == NULL){ ! 57: close(pfd[0]); ! 58: close(pfd[1]); ! 59: return NULL; ! 60: } ! 61: rv->fd = pfd[1]; ! 62: return rv; ! 63: } ! 64: ! 65: extern void ! 66: stream_free(sp) ! 67: stream *sp; ! 68: { ! 69: close(sp->fd); ! 70: fclose(sp->fp); ! 71: free((char *)sp); ! 72: } ! 73: ! 74: static char *env[] = { "IFS= \t\n", 0, 0, 0, 0 }; ! 75: static string *spath; ! 76: static string *home; ! 77: static string *tz; ! 78: ! 79: /* start a new process */ ! 80: extern process * ! 81: proc_start(cmd, inp, outp, errp, uid) ! 82: char *cmd; /* command to run */ ! 83: stream *inp, *outp, *errp; /* streams to be used */ ! 84: { ! 85: struct passwd *pw; ! 86: process *pp; ! 87: int i; ! 88: char *tzp; ! 89: ! 90: if ((pp = (process *)malloc(sizeof(process))) == NULL) { ! 91: if (inp != NULL) ! 92: stream_free(inp); ! 93: if (outp != NULL) ! 94: stream_free(outp); ! 95: if (errp != NULL) ! 96: stream_free(errp); ! 97: return NULL; ! 98: } ! 99: pp->std[0] = inp; ! 100: pp->std[1] = outp; ! 101: pp->std[2] = errp; ! 102: switch (pp->pid = fork()) { ! 103: case -1: ! 104: proc_free(pp); ! 105: return NULL; ! 106: case 0: ! 107: fflush(stdout); ! 108: if (spath==NULL) { ! 109: spath = s_new(); ! 110: s_append(spath, "PATH="); ! 111: s_append(spath, UPASROOT); ! 112: s_append(spath, ":/bin:/usr/bin"); ! 113: home = s_new(); ! 114: env[1] = s_to_c(spath); ! 115: } ! 116: uid=(uid<0)?getuid():uid; ! 117: pw = getpwuid(uid); ! 118: if (pw != NULL){ ! 119: setlogname(pw->pw_name); ! 120: s_append(s_restart(home), "HOME="); ! 121: s_append(home, pw->pw_dir); ! 122: env[2] = s_to_c(home); ! 123: } else ! 124: env[2] = "HOME=/"; ! 125: if (tz==NULL) { ! 126: if(tzp = getenv("TZ")){ ! 127: tz = s_new(); ! 128: s_append(tz, "TZ="); ! 129: s_append(tz, tzp); ! 130: env[3] = s_to_c(tz); ! 131: } ! 132: } ! 133: setgid(-1); ! 134: setuid(uid); ! 135: for (i=0; i<3; i++) ! 136: if (pp->std[i] != NULL) ! 137: fclose(pp->std[i]->fp); ! 138: for (i=0; i<NSYSFILE; i++) ! 139: if (pp->std[i] != NULL) ! 140: dup2(pp->std[i]->fd, i); ! 141: for (i = NSYSFILE; i < NOFILE; i++) ! 142: close(i); ! 143: execle("/bin/sh", "sh", "-c", cmd, 0, env); ! 144: perror("proc_start"); ! 145: exit(1); ! 146: default: ! 147: for (i=0; i<3; i++) ! 148: if (pp->std[i] != NULL) { ! 149: close(pp->std[i]->fd); ! 150: pp->std[i]->fd = -1; ! 151: } ! 152: return pp; ! 153: } ! 154: } ! 155: ! 156: /* wait for a process to stop */ ! 157: extern int ! 158: proc_wait(pp) ! 159: process *pp; /* description of process */ ! 160: { ! 161: int status=0; ! 162: int pid; ! 163: ! 164: while((pid = wait(&status))>=0) { ! 165: if (pid==pp->pid) ! 166: break; ! 167: } ! 168: pp->pid = -1; ! 169: pp->status = status; ! 170: return status; ! 171: } ! 172: ! 173: /* free a process */ ! 174: extern int ! 175: proc_free(pp) ! 176: process *pp; ! 177: { ! 178: int i; ! 179: ! 180: for (i = 0; i < 3; i++) ! 181: if (pp->std[i]) ! 182: stream_free(pp->std[i]); ! 183: if (pp->pid >= 0){ ! 184: kill(pp->pid, SIGKILL); ! 185: (void)proc_wait(pp); ! 186: } ! 187: free((char *)pp); ! 188: return 0; ! 189: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.