|
|
1.1 ! root 1: static char *rcsrev = "$Revision: 1.1 $"; ! 2: static char *rcshdr = ! 3: "$Header: /newbits/bin/mail/mail.c,v 1.1 91/02/04 10:42:40 bin Exp $"; ! 4: /* ! 5: * $Header: /newbits/bin/mail/mail.c,v 1.1 91/02/04 10:42:40 bin Exp $ ! 6: * $Log: /newbits/bin/mail/mail.c,v $ ! 7: * Revision 1.1 91/02/04 10:42:40 bin ! 8: * Initial revision ! 9: * ! 10: * Revision 2.13 90/03/30 16:16:19 wgl ! 11: * Correct seek pointer work within readmail. ! 12: * ! 13: * Revision 2.12 90/03/12 14:19:08 wgl ! 14: * New version of send doing aliases in a different place. ! 15: * ! 16: * Revision 2.11 90/03/08 16:41:15 wgl ! 17: * Add code to get signature file. ! 18: * ! 19: * Revision 2.10 90/03/02 10:41:59 wgl ! 20: * Add the -a flag so that uucp does not look like it is coming from ! 21: * somewhere else. ! 22: * ! 23: * Revision 2.9 90/03/01 11:17:19 wgl ! 24: * Final conversion to rely soley on ^A^A as separators. ! 25: * Effectively delete concept of m_hsize. ! 26: * ! 27: * Revision 2.8 90/03/01 10:14:31 wgl ! 28: * Go buy separators, not "From_" lines. ! 29: * ! 30: * Revision 2.7 90/02/28 17:11:41 wgl ! 31: * Add version print, add some changes to the message-id field. ! 32: * ! 33: * Revision 2.6 90/02/28 16:42:09 wgl ! 34: * Version number fakeout. ! 35: * ! 36: * Revision 2.5 90/02/28 16:19:44 wgl ! 37: * Try again to get versioin number right. ! 38: * ! 39: * Revision 2.4 90/02/28 16:18:56 wgl ! 40: * Get version number right. ! 41: * ! 42: * Revision 2.3 90/02/28 16:04:59 wgl ! 43: * Many changes; ripped out send. ! 44: * Changes are to make it work with uucp and internet mail. ! 45: * ! 46: * Revision 1.6 89/02/22 05:34:00 bin ! 47: * Changes by rec to integrate with lauren's uumail. ! 48: * ! 49: * Revision 1.5 88/09/01 14:49:01 bin ! 50: * Source administration: Re-install declaration of getenv. ! 51: * It was inserted after epstein made his copy. ! 52: * ! 53: * Revision 1.4 88/09/01 14:44:49 bin ! 54: * Mark Epsteins changes for ASKCC and for message scrolling, and interrupt ! 55: * handling during processing. ! 56: * ! 57: * Revision 1.3 88/09/01 14:27:41 bin ! 58: * declare getenv to get rid of integer pointer pun error message. ! 59: * ! 60: * Revision 1.2 88/09/01 11:02:23 bin ! 61: * Remove extra declaration of header which had rcs stuff in it. ! 62: * ! 63: * Revision 1.1 88/09/01 10:55:34 bin ! 64: * Initial revision ! 65: * ! 66: */ ! 67: /* ! 68: * The mail command. ! 69: * Coherent electronic postal system. ! 70: * (NOTE: this command is written in such a way that ! 71: * it assumed that it is setuid on execution to `root'. ! 72: * All file accession is checked on this basis). ! 73: * Modifications by rec january 1986 to include xmail. ! 74: * by epstein november 1987 to include CC: ! 75: * by epstein november 1987 to allow ^C exit to leave you in ! 76: * mail command processor ! 77: * by epstein november 1987 to substitute /usr/games/fortune ! 78: * for printing encrypted messages ! 79: * by rec february 1989 to tail to lauren weinstein's ! 80: * mail for alias expansion and uucp queuing. ! 81: * by wgl January 1990 to handle uucp mail more directly. ! 82: */ ! 83: ! 84: char isummary[] = "\ ! 85: \ ! 86: Command summary:\n\ ! 87: d Delete current message and print the next message\n\ ! 88: m [user ...] Mail current message to each named 'user'\n\ ! 89: p Print current message again\n\ ! 90: q Quit and update the mailbox\n\ ! 91: r Reverse direction of scan\n\ ! 92: s [file ...] Save message in each named 'file'\n\ ! 93: t [user ...] Mail standard input to each named 'user'\n\ ! 94: w [file ...] Save message in each named 'file' without its header\n\ ! 95: x Exit without updating mailbox\n\ ! 96: newline Print the next message\n\ ! 97: . Print current message again\n\ ! 98: + Print the next message\n\ ! 99: - Print the previous message\n\ ! 100: EOF Put undeleted mail back into mailbox and quit\n\ ! 101: ? Print this command summary\n\ ! 102: !command Pass 'command' to the shell to execute\n\ ! 103: If no 'file' is specified, 'mbox' in user's home directory is default.\n\ ! 104: If no 'user' is specified, the invoking user is default.\n\ ! 105: If the 'm', 'p', 't' commands are followed by an 'x',\n\ ! 106: then the public key cryptosystem is applied to the message.\n\ ! 107: \ ! 108: "; ! 109: ! 110: #include <stdio.h> ! 111: #include <pwd.h> ! 112: #include <sys/types.h> ! 113: #include <access.h> ! 114: #include <signal.h> ! 115: #include <sys/mdata.h> ! 116: #include <sys/stat.h> ! 117: #include "mail.h" ! 118: ! 119: #define NARGS 64 /* Maximum # args to interactive command */ ! 120: ! 121: extern char *getenv(); ! 122: extern int optind; ! 123: extern char *optarg; ! 124: extern char getopt(); ! 125: char *revnop(); ! 126: ! 127: int mflag; /* `You have mail.' message to recipient */ ! 128: int rflag; /* Reverse order of print */ ! 129: int qflag; /* Exit after interrrupts */ ! 130: int pflag; /* Print mail */ ! 131: int verbflag; /* verbose */ ! 132: int callmexmail; /* Xmail modifier present */ ! 133: int callmermail; /* rmail modifier present */ ! 134: struct msg { ! 135: struct msg *m_next; /* Link to next message */ ! 136: struct msg *m_prev; /* Link to previous message */ ! 137: int m_flag; /* Flags - non-zero if deleted */ ! 138: int m_hsize; /* Size of header of message */ ! 139: fsize_t m_seek; /* Start position of message */ ! 140: fsize_t m_end; /* End of message */ ! 141: }; ! 142: struct msg *m_first = NULL; /* First message */ ! 143: struct msg *m_last = NULL; /* Last message */ ! 144: ! 145: struct tm *tp; ! 146: ! 147: char iusage[] = "Bad command--type '?' for command summary\n"; ! 148: char nombox[] = "No mailbox '%s'.\n"; ! 149: char nomail[] = "No mail.\n"; ! 150: char noperm[] = "Mailbox '%s' access denied.\n"; ! 151: char moerr[] = "Cannot open mailbox '%s'\n"; ! 152: char wrerr[] = "Write error on '%s'\n"; ! 153: char nosave[] = "Cannot save letter in '%s'\n"; ! 154: ! 155: FILE *mfp; /* Mailbox stream */ ! 156: int myuid; /* User-id of mail user */ ! 157: int mygid; /* Group-id of mail user */ ! 158: char myname[25]; /* User name */ ! 159: char myfullname[50]; ! 160: char mymbox[256]; /* $HOME/mbox */ ! 161: char mydead[256]; /* $HOME/dead.letter */ ! 162: char mysig[256]; /* $HOME/dead.letter */ ! 163: char spoolname[50] = SPOOLDIR; ! 164: char *mailbox = spoolname; ! 165: char cmdname[1024]; /* Command for x{en,de}code filter */ ! 166: /* and for tail recursion to uumail */ ! 167: /* and for editor recursion */ ! 168: ! 169: char *args[NARGS]; /* Interactive command arglist */ ! 170: char msgline[NLINE]; ! 171: char cline[NCLINE] = "+\n"; ! 172: char *temp; /* Currently open temp file */ ! 173: char templ[] = "/tmp/mailXXXXXX"; /* Temp file name template */ ! 174: char *editname; /* name of editor */ ! 175: char *askcc; /* Ask for CC: list? (YES/NO) */ ! 176: ! 177: fsize_t ftell(); ! 178: char *getlogin(); ! 179: char *mktemp(); ! 180: int catchintr(); ! 181: char *malloc(); ! 182: extern char *rindex(); ! 183: char asuser [32]; ! 184: main(argc, argv) ! 185: char *argv[]; ! 186: { ! 187: register char *ap; ! 188: char c; ! 189: ! 190: ap = argv[0]; ! 191: if (rindex (ap, '/') != NULL) ! 192: ++ap; ! 193: callmermail = (strcmp(ap, "rmail") == 0); ! 194: callmexmail = (strcmp(ap, "xmail") == 0); ! 195: asuser [0] = '\0'; ! 196: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 197: signal(SIGINT, catchintr); ! 198: while ((c = getopt(argc, argv, "a:f:mpqrv")) != EOF) { ! 199: switch(c) { ! 200: case 'f': ! 201: if (!callmermail) ! 202: mailbox = optarg; ! 203: break; ! 204: case 'a': ! 205: strcpy(asuser, optarg); ! 206: break; ! 207: case 'm': ! 208: mflag++; ! 209: break; ! 210: case 'p': ! 211: pflag++; ! 212: break; ! 213: case 'q': ! 214: qflag++; ! 215: break; ! 216: case 'r': ! 217: rflag++; ! 218: break; ! 219: case 'v': ! 220: fprintf(stderr, "mail, ver. %s\n", revnop()); ! 221: verbflag++; ! 222: break; ! 223: default: ! 224: usage(); ! 225: } ! 226: } ! 227: if (callmermail) ! 228: verbflag = mflag = pflag = rflag = 0; ! 229: setname(); ! 230: if (optind < argc) { ! 231: qflag = 1; ! 232: send2(stdin, &argv[optind], (fsize_t)0, (fsize_t)MAXLONG, 1); ! 233: } else { ! 234: if ( ! pflag) ! 235: callmexmail = 0; ! 236: commands(); ! 237: } ! 238: rmexit(0); ! 239: } ! 240: ! 241: /* ! 242: * Setup all the identities for the current user. ! 243: */ ! 244: setname() ! 245: { ! 246: register struct passwd *pwp; ! 247: register char *np; ! 248: extern struct passwd * getpwnam(); ! 249: ! 250: if (strlen(asuser) > 0) { ! 251: if((pwp = getpwnam(asuser)) == NULL) ! 252: merr("No such user %s.\n", asuser); ! 253: myuid = pwp -> pw_uid; ! 254: } else ! 255: myuid = getuid(); ! 256: if ((pwp = getpwuid(myuid)) == NULL) ! 257: merr("Who are you?\n"); ! 258: np = pwp->pw_name; ! 259: mygid = pwp->pw_gid; ! 260: strcat(spoolname, np); ! 261: strcpy(myname, np); ! 262: strcpy(myfullname, pwp->pw_gecos); ! 263: strcpy(mymbox, pwp->pw_dir); ! 264: strcat(mymbox, "/mbox"); ! 265: strcpy(mydead, pwp->pw_dir); ! 266: strcat(mydead, "/dead.letter"); ! 267: strcpy(mysig, pwp->pw_dir); ! 268: strcat(mysig, "/.sig.mail"); ! 269: mktemp(templ); ! 270: ! 271: if ((editname=getenv("EDITOR"))==NULL) ! 272: editname = "/bin/ed"; ! 273: ! 274: if ((askcc=getenv("ASKCC")) != NULL) ! 275: if ( strcmp(askcc, "YES") || !isatty(fileno(stdin)) ) ! 276: askcc = NULL; ! 277: } ! 278: ! 279: /* ! 280: * Process mail's interactive commands ! 281: * for reading/deleting/saving mail. ! 282: */ ! 283: commands() ! 284: { ! 285: register struct msg *mp; ! 286: struct msg *dest; ! 287: register char **fnp; ! 288: register FILE *fp; ! 289: fsize_t seek; ! 290: ! 291: readmail(); ! 292: mprint(mp = rflag ? m_last : m_first); ! 293: for (;;) { ! 294: readmail(); ! 295: intcheck(); ! 296: if ( ! pflag) { ! 297: callmexmail = 0; ! 298: mmsg("? "); ! 299: if (fgets(cline, sizeof cline, stdin) == NULL) { ! 300: if (intcheck()) ! 301: continue; ! 302: break; ! 303: } ! 304: } ! 305: switch (cline[0]) { ! 306: case 'd': ! 307: if (cline[1] != '\n') ! 308: goto usage; ! 309: mp->m_flag += 1; ! 310: goto advance; ! 311: ! 312: case 'm': ! 313: case 't': ! 314: if (csplit(cline, args) == 1) { ! 315: args[1] = myname; ! 316: args[2] = NULL; ! 317: } ! 318: callmexmail = (cline[1] == 'x'); ! 319: if (cline[0] == 'm') { ! 320: send2(mfp, args+1, mp->m_seek, mp->m_end - 3, 0); ! 321: fseek(mfp, mp->m_seek, 0); ! 322: } else ! 323: send2(stdin, args+1, 0L, (fsize_t)MAXLONG, 1); ! 324: break; ! 325: ! 326: case '.': ! 327: case 'p': ! 328: if (cline[1] == 'x') { ! 329: callmexmail = 1; ! 330: if (cline[2] != '\n') ! 331: goto usage; ! 332: } else if (cline[1] != '\n') ! 333: goto usage; ! 334: if (mprint(mp)) ! 335: break; ! 336: goto advance; ! 337: ! 338: case 'q': ! 339: if (cline[1] != '\n') ! 340: goto usage; ! 341: mquit(); ! 342: /* NOTREACHED */ ! 343: ! 344: case 'r': ! 345: if (cline[1] != '\n') ! 346: goto usage; ! 347: rflag = ! rflag; ! 348: break; ! 349: case 's': ! 350: case 'w': ! 351: if (csplit(cline, args) == 1) { ! 352: args[1] = mymbox; ! 353: args[2] = NULL; ! 354: } ! 355: seek = mp->m_seek; ! 356: if (cline[0] == 'w') ! 357: seek += mp->m_hsize; ! 358: for (fnp = &args[1]; *fnp != NULL; fnp++) { ! 359: fp = NULL; ! 360: if (maccess(*fnp) < 0 ! 361: || (fp = fopen(*fnp, "a")) == NULL ! 362: || mcopy(mfp, fp, seek, mp->m_end - 3, 0)) ! 363: mmsg(nosave, *fnp); ! 364: if (fp != NULL) { ! 365: fclose(fp); ! 366: chown(*fnp, myuid, mygid); ! 367: } ! 368: } ! 369: break; ! 370: ! 371: case 'x': ! 372: if (cline[1] != '\n') ! 373: goto usage; ! 374: rmexit(0); ! 375: /* NOTREACHED */ ! 376: ! 377: case '!': ! 378: if (system(cline+1) == 127) ! 379: mmsg("Try again\n"); ! 380: else ! 381: mmsg("!\n"); ! 382: break; ! 383: ! 384: case '?': ! 385: mmsg(isummary); ! 386: break; ! 387: ! 388: case '-': ! 389: if (cline[1] != '\n') ! 390: goto usage; ! 391: dest = rflag ? m_last : m_first; ! 392: goto nextmsg; ! 393: ! 394: case '+': ! 395: if (cline[1] != '\n') ! 396: goto usage; ! 397: case '\n': ! 398: advance: ! 399: dest = rflag ? m_first : m_last; ! 400: nextmsg: ! 401: do { ! 402: if (mp == dest) { ! 403: if (pflag) ! 404: return; ! 405: mmsg("No more messages.\n"); ! 406: break; ! 407: } ! 408: mp = (dest==m_last) ? mp->m_next : mp->m_prev; ! 409: } while (mprint(mp) == 0); ! 410: break; ! 411: ! 412: default: ! 413: usage: ! 414: mmsg(iusage); ! 415: break; ! 416: } ! 417: } ! 418: putc('\n', stderr); ! 419: mquit(); ! 420: } ! 421: ! 422: /* ! 423: * Read through the mail-box file ! 424: * constructing list of letters. ! 425: * On subsequent calls, append any additional mail ! 426: * and notify the user. ! 427: */ ! 428: readmail() ! 429: { ! 430: register struct msg *mp; ! 431: struct stat sb; ! 432: static long m_last_end; ! 433: fsize_t first; /* to become ffsize_t */ ! 434: int datasw; ! 435: ! 436: if (m_first == NULL) { ! 437: if (stat(mailbox, &sb) < 0) ! 438: merr(nombox, mailbox); ! 439: if (sb.st_size == 0) ! 440: merr(nomail); ! 441: if (access(mailbox, AREAD) < 0) ! 442: merr(noperm, mailbox); ! 443: if ((mfp = fopen(mailbox, "r")) == NULL) ! 444: merr(moerr, mailbox); ! 445: m_last_end = 0; ! 446: } else { ! 447: fstat(fileno(mfp), &sb); ! 448: if (sb.st_size == m_last_end) ! 449: return; ! 450: mmsg("More mail received.\n"); ! 451: } ! 452: ! 453: for(mlock(myuid);;) { ! 454: fseek(mfp, m_last_end, 0); ! 455: first = ftell(mfp); ! 456: for (datasw = 0; ! 457: fgets(msgline, sizeof msgline, mfp) != NULL; ) { ! 458: if(!(datasw = strcmp("\1\1\n", msgline))) { ! 459: /* found message seperator */ ! 460: mp = (struct msg *)malloc(sizeof(*mp)); ! 461: mp->m_next = NULL; ! 462: mp->m_prev = m_last; ! 463: mp->m_flag = mp->m_hsize = 0; ! 464: mp->m_seek = first; ! 465: mp->m_end = first = m_last_end = ftell(mfp); ! 466: if (m_first == NULL) ! 467: m_last = m_first = mp; ! 468: else ! 469: m_last = m_last->m_next = mp; ! 470: } ! 471: } ! 472: ! 473: if(!datasw) ! 474: break; ! 475: ! 476: /* unterminated data, patch and retry */ ! 477: fclose(mfp); ! 478: if ((mfp = fopen(mailbox, "a")) == NULL) ! 479: merr(moerr, mailbox); ! 480: fprintf(mfp, "\1\1\n"); /* terminate it */ ! 481: fclose(mfp); ! 482: if ((mfp = fopen(mailbox, "r")) == NULL) ! 483: merr(moerr, mailbox); ! 484: mmsg("Incomplete message found.\n"); ! 485: } ! 486: munlock(); ! 487: } ! 488: ! 489: /* ! 490: * Split a command line up into ! 491: * argv (passed) and argc (returned). ! 492: */ ! 493: int ! 494: csplit(command, args) ! 495: char *command; ! 496: char **args; ! 497: { ! 498: register char *cp; ! 499: register char **ap; ! 500: register int c; ! 501: ! 502: cp = command; ! 503: ap = args; ! 504: for (;;) { ! 505: while ((c = *cp)==' ' || c=='\t') ! 506: *cp++ = '\0'; ! 507: if (*cp == '\n') ! 508: *cp = '\0'; ! 509: if (*cp == '\0') ! 510: break; ! 511: *ap++ = cp; ! 512: while ((c = *cp)!=' ' && c!='\t' && c!='\n' && c!='\0') ! 513: cp++; ! 514: } ! 515: *ap = NULL; ! 516: return (ap - args); ! 517: } ! 518: ! 519: /* ! 520: * Lock the appropriately-numbered mailbox ! 521: * (numbered by user-number) from multiple ! 522: * accesses. There is a (small) race here ! 523: * which will be overlooked for now. ! 524: */ ! 525: char *lockname; ! 526: ! 527: mlock(uid) ! 528: int uid; ! 529: { ! 530: register int fd; ! 531: static char lock[32]; ! 532: ! 533: lockname = lock; ! 534: sprintf(lock, "/tmp/maillock%d", uid); ! 535: while (access(lockname, 0) == 0) ! 536: sleep(1); ! 537: if ((fd = creat(lockname, 0)) >= 0) ! 538: close(fd); ! 539: } ! 540: ! 541: /* ! 542: * Unlock the currently-set lock (by `mlock') ! 543: * also called from rmexit. ! 544: */ ! 545: munlock() ! 546: { ! 547: if (lockname != NULL) ! 548: unlink(lockname); ! 549: lockname = NULL; ! 550: } ! 551: ! 552: /* ! 553: * Exit, after rewriting the ! 554: * mailbox ! 555: */ ! 556: mquit() ! 557: { ! 558: register struct msg *mp; ! 559: register FILE *nfp; ! 560: struct stat sb; ! 561: ! 562: readmail(); ! 563: mlock(myuid); ! 564: if (mailbox != spoolname && maccess(mailbox) < 0) ! 565: merr(noperm, mailbox); ! 566: fstat(fileno(mfp), &sb); ! 567: signal(SIGINT, SIG_IGN); ! 568: unlink(mailbox); ! 569: if ((nfp = fopen(mailbox, "w")) == NULL) ! 570: merr("Cannot re-write '%s'\n", mailbox); ! 571: chown(mailbox, sb.st_uid, sb.st_gid); ! 572: chmod(mailbox, sb.st_mode&0777); ! 573: for (mp = m_first; mp != NULL; mp = mp->m_next) { ! 574: if (mp->m_flag == 0) { ! 575: if (mcopy(mfp, nfp, mp->m_seek, mp->m_end, 0)) ! 576: merr(wrerr, mailbox); ! 577: /* else ! 578: fprintf(nfp, "\1\1\n"); */ ! 579: } ! 580: } ! 581: fclose(nfp); ! 582: fclose(mfp); ! 583: munlock(); ! 584: rmexit(0); ! 585: } ! 586: ! 587: /* ! 588: * Print the current message, given by ! 589: * the message pointer (`mp'). ! 590: */ ! 591: mprint(mp) ! 592: register struct msg *mp; ! 593: { ! 594: FILE *xfp; ! 595: if (mp->m_flag) ! 596: return 0; ! 597: if (callmexmail) { ! 598: sprintf(cmdname, "xdecode"); ! 599: if ((xfp = popen(cmdname, "w")) == NULL) { ! 600: return 0; ! 601: } ! 602: mcopy(mfp, xfp, mp->m_seek+mp->m_hsize, mp->m_end, 1); ! 603: pclose(xfp); ! 604: } else { ! 605: fseek(mfp, mp->m_seek, 0); ! 606: if (fgets(msgline, sizeof msgline, mfp) != NULL && ! 607: strncmp(msgline, "From xmail", 10) == 0) { ! 608: printf("From xmail\n"); ! 609: system("/usr/games/fortune"); ! 610: return(1); ! 611: } ! 612: mcopy(mfp, stdout, mp->m_seek, mp->m_end - 3, 1); ! 613: } ! 614: return (1); ! 615: } ! 616: ! 617: /* ! 618: * Get additional users to receive message (CC:) ! 619: */ ! 620: ! 621: char ** ! 622: getcc(users) ! 623: register char **users; ! 624: { ! 625: register char **ulist = args; ! 626: static char names[NCLINE]; ! 627: ! 628: mmsg("CC: "); ! 629: if ( fgets(names, sizeof names, stdin) == NULL ) ! 630: return(users); ! 631: ! 632: while (*users != NULL) ! 633: *ulist++ = *users++; ! 634: ! 635: csplit(names, ulist); ! 636: return(args); ! 637: } ! 638: ! 639: ! 640: /* ! 641: * Errors, usage, and exit removing ! 642: * any tempfiles left around. ! 643: */ ! 644: mmsg(x, s) ! 645: char *x, *s; ! 646: { ! 647: fprintf(stderr, x, s); ! 648: } ! 649: ! 650: merr(x, s) ! 651: char *x, *s; ! 652: { ! 653: mmsg(x, s); ! 654: rmexit(1); ! 655: } ! 656: ! 657: rmexit(s) ! 658: int s; ! 659: { ! 660: if (temp != NULL) ! 661: unlink(temp); ! 662: munlock(); ! 663: exit(s); ! 664: } ! 665: ! 666: /* ! 667: * Catch interrupts, taking the ! 668: * appropriate action based on ! 669: * the `-q' option. ! 670: */ ! 671: int intflag; /* On when interrupt sent */ ! 672: ! 673: catchintr() ! 674: { ! 675: signal(SIGINT, SIG_IGN); ! 676: if (qflag) ! 677: rmexit(1); ! 678: intflag = 1; ! 679: signal(SIGINT, catchintr); ! 680: } ! 681: ! 682: intcheck() ! 683: { ! 684: if (intflag) { ! 685: intflag = 0; ! 686: putc('\n', stderr); ! 687: return (1); ! 688: } ! 689: return (0); ! 690: } ! 691: ! 692: /* ! 693: * Call the system to execute a command line ! 694: * which is passed as an argument. ! 695: * Change the user id and group id. ! 696: */ ! 697: system(line) ! 698: char *line; ! 699: { ! 700: int status, pid; ! 701: register wpid; ! 702: register int (*intfun)(), (*quitfun)(); ! 703: ! 704: if ((pid = fork()) < 0) ! 705: return (-1); ! 706: if (pid == 0) { /* Child */ ! 707: setuid(myuid); ! 708: setgid(mygid); ! 709: execl("/bin/sh", "sh", "-c", line, NULL); ! 710: exit(0177); ! 711: } ! 712: intfun = signal(SIGINT, SIG_IGN); ! 713: quitfun = signal(SIGQUIT, SIG_IGN); ! 714: while ((wpid = wait(&status))!=pid && wpid>=0) ! 715: ; ! 716: if (wpid < 0) ! 717: status = wpid; ! 718: signal(SIGINT, intfun); ! 719: signal(SIGQUIT, quitfun); ! 720: return (status); ! 721: } ! 722: ! 723: char * ! 724: revnop() ! 725: { ! 726: register char *cp; ! 727: register char c; ! 728: static char revnobuf[32]; ! 729: ! 730: if ((cp = index(rcsrev, ' ')) != NULL) { ! 731: while (((c = *++cp) == ' ') && (c != '\0')) ! 732: ; ! 733: strcpy(revnobuf, cp); ! 734: if ((cp = index(revnobuf, ' ')) != NULL) ! 735: *cp = '\0'; ! 736: return (revnobuf); ! 737: } else ! 738: return("OOPS"); ! 739: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.