|
|
1.1 ! root 1: /* ! 2: * subroutines that weren't worth their own files ! 3: */ ! 4: #include <stdio.h> ! 5: #include <signal.h> ! 6: #include <sys/param.h> ! 7: #include "mail.h" ! 8: #include "string.h" ! 9: ! 10: /* configuration */ ! 11: #define FRWRD "Forward to " ! 12: #define PIPE "Pipe to " ! 13: #define WHOAMI "/etc/whoami" /* file containing system name */ ! 14: #define MAILROOT "/usr/spool/mail/" /* root of mail system */ ! 15: #define UPASROOT "/usr/lib/upas/" /* root of upas system */ ! 16: ! 17: /* imported */ ! 18: int rmail; /* true if started as rmail (init if undefined) */ ! 19: int onatty; /* true if on a tty (init if undefined) */ ! 20: extern unsigned int alarm(); ! 21: ! 22: /* return a pointer to last element of a pathname */ ! 23: extern char * ! 24: basename(file) ! 25: char *file; ! 26: { ! 27: char *base; ! 28: char *strrchr(); ! 29: ! 30: if ((base = strrchr(file, '/')) != 0) ! 31: base++; /* past '/' */ ! 32: else ! 33: base = file; ! 34: return (base); ! 35: } ! 36: ! 37: /* get the next whitespace delimited token from a string */ ! 38: extern char * ! 39: getarg(s, p) /* copy p... into s, update p */ ! 40: register char *s, *p; ! 41: { ! 42: while (*p == ' ' || *p == '\t') ! 43: p++; ! 44: if (*p == '\n' || *p == '\0') ! 45: return(NULL); ! 46: while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') ! 47: *s++ = *p++; ! 48: *s = '\0'; ! 49: return(p); ! 50: } ! 51: ! 52: /* a path to a mail file */ ! 53: extern char * ! 54: mailpath(relp) ! 55: char *relp; /* relative path name */ ! 56: { ! 57: static char pathname[128]; ! 58: ! 59: if (*relp == '/') ! 60: *pathname = '\0'; ! 61: else ! 62: (void)strcpy(pathname, MAILROOT); ! 63: (void)strcat(pathname, relp); ! 64: return pathname; ! 65: } ! 66: ! 67: /* a path to a special upas file */ ! 68: extern char * ! 69: upaspath(relp) ! 70: char *relp; /* relative path name */ ! 71: { ! 72: static char pathname[128]; ! 73: ! 74: if (*relp == '/') ! 75: *pathname = '\0'; ! 76: else ! 77: (void)strcpy(pathname, UPASROOT); ! 78: (void)strcat(pathname, relp); ! 79: return pathname; ! 80: } ! 81: ! 82: /* get the system's name */ ! 83: extern char * ! 84: getsysname() ! 85: { ! 86: int f; ! 87: char *strchr(); ! 88: static char wsysname[33]; ! 89: ! 90: f = open(WHOAMI, 0); ! 91: if (f>=0) { ! 92: wsysname[0] = '\0'; ! 93: read(f, wsysname, 32); ! 94: if (strchr(wsysname, '\n')) { ! 95: *strchr(wsysname, '\n') = '\0'; ! 96: } ! 97: close(f); ! 98: } ! 99: return wsysname; ! 100: } ! 101: ! 102: /* ! 103: * Return: ! 104: * 0 if no special action is requested ! 105: * 1 if fowarding (new address in param) ! 106: * 2 if mail is to be piped to a comand (command in param) ! 107: */ ! 108: extern int ! 109: delivery_status(s, param) ! 110: char *s, *param; ! 111: { ! 112: FILE *fp; ! 113: char fbuf[CMDSIZE], *p, *sp; ! 114: int rv = MF_NORMAL; ! 115: extern char *stringin(); ! 116: ! 117: ! 118: fp = fopen(s, "r"); ! 119: if(fp == NULL) ! 120: return MF_NORMAL; ! 121: fbuf[0] = '\0'; ! 122: fgets(fbuf, sizeof(fbuf), fp); ! 123: if (p = stringin(FRWRD, fbuf)) ! 124: rv = MF_FORWARD; ! 125: else if (p = stringin(PIPE, fbuf)) ! 126: rv = MF_PIPE; ! 127: if (rv != 0) { ! 128: while (*p == ' ') ! 129: p++; ! 130: sp = param; ! 131: while (*p && *p!='\n') ! 132: *sp++ = *p++; ! 133: *sp = '\0'; ! 134: if (fgets(fbuf, sizeof(fbuf), fp) != NULL) ! 135: rv |= MFEXTRA; ! 136: } ! 137: fclose(fp); ! 138: return (*param != 0) ? rv : MF_NORMAL; ! 139: } ! 140: ! 141: /* ! 142: * Find one string within another. ! 143: * Return: NULL if line doesn't contain str ! 144: * a pointer to the first byte following str in line otherwise ! 145: */ ! 146: extern char * ! 147: stringin(str, line) ! 148: char *str, *line; ! 149: { ! 150: register char *sp, *lp; ! 151: ! 152: while (*line) { ! 153: sp = str; ! 154: lp = line++; ! 155: for (;;) { ! 156: if (*sp != *lp) { ! 157: if (*sp=='\0') ! 158: return(lp); ! 159: break; ! 160: } ! 161: sp++; ! 162: lp++; ! 163: } ! 164: } ! 165: return(NULL); ! 166: } ! 167: ! 168: /* print error and core dump */ ! 169: extern int ! 170: panic(s) ! 171: char *s; ! 172: { ! 173: fprintf(stderr, "mail: %s\n", s); ! 174: signal(SIGQUIT, SIG_DFL); ! 175: kill(getpid(), SIGQUIT); ! 176: exit(-1); ! 177: } ! 178: ! 179: /* global to from parsing */ ! 180: static char rmtlist[ADDRSIZE]; ! 181: ! 182: /* output a unix header with remote from blurb */ ! 183: extern void ! 184: putrfunix(sender, date, sys, fp) ! 185: char *date, *sys, *sender; ! 186: FILE *fp; ! 187: { ! 188: fprintf(fp, "From %s %s%s%s\n", sender, date, REMFROM, sys); ! 189: } ! 190: ! 191: /* output a unix header */ ! 192: extern void ! 193: putunix(sender, date, fp) ! 194: char *sender, *date; ! 195: FILE *fp; ! 196: { ! 197: fprintf(fp, "From %s %s\n", sender, date); ! 198: } ! 199: ! 200: /* start the unix parse */ ! 201: extern void ! 202: initgetunix() ! 203: { ! 204: rmtlist[0] = '\0'; ! 205: } ! 206: ! 207: /* get/parse unix from line */ ! 208: extern int ! 209: getunix(line, sender, date) ! 210: char *line; /* line to parse */ ! 211: char *sender; /* filled by parseline */ ! 212: char *date; /* filled by parseline */ ! 213: { ! 214: char *rp, *dp, *sp; ! 215: ! 216: /* look for a from */ ! 217: if ((sp = stringin(FROM, line))!=NULL ! 218: || (sp = stringin(ALTFROM, line))!=NULL) { ! 219: ! 220: /* do we have a remote from? */ ! 221: if ((rp = stringin(REMFROM, line))!=NULL) { ! 222: ! 223: /* add to remote list */ ! 224: line[strlen(line)-1] = '\0'; ! 225: *(rp - (sizeof(REMFROM)-1)) = '\0'; ! 226: if ((dp = strchr(sp, ' ')) != NULL) { ! 227: strcpy(date, dp+1); ! 228: *dp = '\0'; ! 229: } ! 230: (void)strcpy(sender, sp); ! 231: (void)strcat(rmtlist, rp); ! 232: (void)strcat(rmtlist, "!"); ! 233: return -1; ! 234: } ! 235: } ! 236: ! 237: /* Not a from line */ ! 238: /* Use what we've found so far */ ! 239: (void)strcat(rmtlist, sender); ! 240: (void)strcpy(sender, rmtlist); ! 241: return 0; ! 242: } ! 243: ! 244: /* ! 245: * a paranoid's version of popen ! 246: */ ! 247: #define RDR 0 ! 248: #define WTR 1 ! 249: ! 250: static int ppid; ! 251: static int perrfd; ! 252: static char *envp[] = { ! 253: "IFS= \n", ! 254: "PATH=/bin:/usr/bin:/usr/lib/upas", ! 255: 0 ! 256: }; ! 257: ! 258: static char perrbuf[CMDSIZE]; /* where to put standard error */ ! 259: static int forked; /* true if we've already forked */ ! 260: ! 261: /* here if popen times out */ ! 262: static ! 263: ptimeout() ! 264: { ! 265: fprintf(stderr, "time out - possbile mail problem\n"); ! 266: exit(1); ! 267: } ! 268: ! 269: extern FILE * ! 270: popen(cmd, uid, gid) ! 271: char *cmd; ! 272: int uid, gid; ! 273: { ! 274: register i; ! 275: int p[2], perr[2]; ! 276: ! 277: /* do mail in background to keep user from getting bored */ ! 278: if (onatty && !rmail && !forked) { ! 279: switch(fork()) { ! 280: case 0: ! 281: signal(SIGHUP, SIG_IGN); ! 282: signal(SIGINT, SIG_IGN); ! 283: signal(SIGQUIT, SIG_IGN); ! 284: signal(SIGTERM, SIG_IGN); ! 285: forked = 1; ! 286: break; ! 287: case -1: ! 288: break; ! 289: default: ! 290: exit(0); ! 291: } ! 292: } ! 293: ! 294: if(pipe(p) < 0) ! 295: return NULL; ! 296: if(pipe(perr) < 0) { ! 297: close(p[RDR]); ! 298: close(p[WTR]); ! 299: return NULL; ! 300: } ! 301: if((ppid = fork()) == 0) { ! 302: (void)setgid(gid); ! 303: (void)setuid(uid); ! 304: (void)dup2(p[RDR], 0); ! 305: (void)dup2(perr[WTR], 2); ! 306: (void)close(1); ! 307: for (i=3; i<NOFILE; i++) ! 308: close(i); ! 309: execle("/bin/sh", "sh", "-c", cmd, 0, envp); ! 310: _exit(1); ! 311: } ! 312: if(ppid == -1) ! 313: return NULL; ! 314: ! 315: signal(SIGALRM, ptimeout); ! 316: signal(SIGPIPE, SIG_IGN); ! 317: alarm(1200); /* in case of deadly embrace twixt stdin and stderr */ ! 318: ! 319: close(perr[WTR]); ! 320: perrfd = perr[RDR]; ! 321: close(p[RDR]); ! 322: return(fdopen(p[WTR], "w")); ! 323: } ! 324: ! 325: extern int ! 326: pclose(ptr, perrbuf, perrlen) ! 327: FILE *ptr; ! 328: char *perrbuf; ! 329: unsigned int perrlen; ! 330: { ! 331: register r, (*hstat)(), (*istat)(), (*qstat)(); ! 332: int status, len, i; ! 333: ! 334: fclose(ptr); ! 335: istat = signal(SIGINT, SIG_IGN); ! 336: qstat = signal(SIGQUIT, SIG_IGN); ! 337: hstat = signal(SIGHUP, SIG_IGN); ! 338: if (perrlen > 0) { ! 339: for (i = 0; i < perrlen; i += len) { ! 340: len = read(perrfd, perrbuf+i, perrlen-i); ! 341: if (len <= 0) ! 342: break; ! 343: } ! 344: perrbuf[i] = '\0'; ! 345: } ! 346: close(perrfd); ! 347: alarm(0); /* see alarm in popen */ ! 348: signal(SIGALRM, SIG_IGN); ! 349: while((r = wait(&status)) != ppid && r != -1) ! 350: ; ! 351: if(r == -1) ! 352: status = 0; ! 353: signal(SIGINT, istat); ! 354: signal(SIGQUIT, qstat); ! 355: signal(SIGHUP, hstat); ! 356: return(status); ! 357: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.