|
|
1.1 ! root 1: static char *rcsrev = "$Revision: 1.3 $"; ! 2: static char *rcshdr = ! 3: "$Header: /src386/bin/lmail/RCS/lmail.c,v 1.3 92/11/03 09:06:26 bin Exp Locker: bin $"; ! 4: /* ! 5: * $Header: /src386/bin/lmail/RCS/lmail.c,v 1.3 92/11/03 09:06:26 bin Exp Locker: bin $ ! 6: * $Log: lmail.c,v $ ! 7: * Revision 1.3 92/11/03 09:06:26 bin ! 8: * Bob H: restructures routines to lock and write mailboxes and wait for mailbox to become available. ! 9: * ! 10: * Revision 1.1 92/03/13 12:19:15 bin ! 11: * Initial revision ! 12: * ! 13: * Revision 1.2 92/01/07 08:46:20 bin ! 14: * Piggy changes for so that if an all caps sitename fails, it will try ! 15: * lower case. ! 16: * ! 17: * Revision 2.13 90/03/30 16:16:19 wgl ! 18: * Correct seek pointer work within readmail. ! 19: * ! 20: * Revision 2.12 90/03/12 14:19:08 wgl ! 21: * New version of send doing aliases in a different place. ! 22: * ! 23: * Revision 2.11 90/03/08 16:41:15 wgl ! 24: * Add code to get signature file. ! 25: * ! 26: * Revision 2.10 90/03/02 10:41:59 wgl ! 27: * Add the -a flag so that uucp does not look like it is coming from ! 28: * somewhere else. ! 29: * ! 30: * Revision 2.9 90/03/01 11:17:19 wgl ! 31: * Final conversion to rely soley on ^A^A as separators. ! 32: * Effectively delete concept of m_hsize. ! 33: * ! 34: * Revision 2.8 90/03/01 10:14:31 wgl ! 35: * Go buy separators, not "From_" lines. ! 36: * ! 37: * Revision 2.7 90/02/28 17:11:41 wgl ! 38: * Add version print, add some changes to the message-id field. ! 39: * ! 40: * Revision 2.6 90/02/28 16:42:09 wgl ! 41: * Version number fakeout. ! 42: * ! 43: * Revision 2.5 90/02/28 16:19:44 wgl ! 44: * Try again to get versioin number right. ! 45: * ! 46: * Revision 2.4 90/02/28 16:18:56 wgl ! 47: * Get version number right. ! 48: * ! 49: * Revision 2.3 90/02/28 16:04:59 wgl ! 50: * Many changes; ripped out send. ! 51: * Changes are to make it work with uucp and internet mail. ! 52: * ! 53: * Revision 1.6 89/02/22 05:34:00 bin ! 54: * Changes by rec to integrate with lauren's uumail. ! 55: * ! 56: * Revision 1.5 88/09/01 14:49:01 bin ! 57: * Source administration: Re-install declaration of getenv. ! 58: * It was inserted after epstein made his copy. ! 59: * ! 60: * Revision 1.4 88/09/01 14:44:49 bin ! 61: * Mark Epsteins changes for ASKCC and for message scrolling, and interrupt ! 62: * handling during processing. ! 63: * ! 64: * Revision 1.3 88/09/01 14:27:41 bin ! 65: * declare getenv to get rid of integer pointer pun error message. ! 66: * ! 67: * Revision 1.2 88/09/01 11:02:23 bin ! 68: * Remove extra declaration of header which had rcs stuff in it. ! 69: * ! 70: * Revision 1.1 88/09/01 10:55:34 bin ! 71: * Initial revision ! 72: * ! 73: */ ! 74: /* ! 75: * The mail command. ! 76: * Coherent electronic postal system. ! 77: * (NOTE: this command is written in such a way that ! 78: * it assumed that it is setuid on execution to `root'. ! 79: * All file accession is checked on this basis). ! 80: * Modifications by rec january 1986 to include xmail. ! 81: * by epstein november 1987 to include CC: ! 82: * by epstein november 1987 to allow ^C exit to leave you in ! 83: * mail command processor ! 84: * by epstein november 1987 to substitute /usr/games/fortune ! 85: * for printing encrypted messages ! 86: * by rec february 1989 to tail to lauren weinstein's ! 87: * mail for alias expansion and uucp queuing. ! 88: * by wgl January 1990 to handle uucp mail more directly. ! 89: */ ! 90: ! 91: char isummary[] = "\ ! 92: \ ! 93: Command summary:\n\ ! 94: d Delete current message and print the next message\n\ ! 95: m [user ...] Mail current message to each named 'user'\n\ ! 96: p Print current message again\n\ ! 97: q Quit and update the mailbox\n\ ! 98: r Reverse direction of scan\n\ ! 99: s [file ...] Save message in each named 'file'\n\ ! 100: t [user ...] Mail standard input to each named 'user'\n\ ! 101: w [file ...] Save message in each named 'file' without its header\n\ ! 102: x Exit without updating mailbox\n\ ! 103: newline Print the next message\n\ ! 104: . Print current message again\n\ ! 105: + Print the next message\n\ ! 106: - Print the previous message\n\ ! 107: EOF Put undeleted mail back into mailbox and quit\n\ ! 108: ? Print this command summary\n\ ! 109: !command Pass 'command' to the shell to execute\n\ ! 110: If no 'file' is specified, 'mbox' in user's home directory is default.\n\ ! 111: If no 'user' is specified, the invoking user is default.\n\ ! 112: If the 'm', 'p', 't' commands are followed by an 'x',\n\ ! 113: then the public key cryptosystem is applied to the message.\n\ ! 114: \ ! 115: "; ! 116: ! 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: char BOBerrmsg[50]; ! 128: ! 129: int mflag; /* `You have mail.' message to recipient */ ! 130: int rflag; /* Reverse order of print */ ! 131: int qflag; /* Exit after interrrupts */ ! 132: int pflag; /* Print mail */ ! 133: int verbflag; /* verbose */ ! 134: int callmexmail; /* Xmail modifier present */ ! 135: int callmermail; /* rmail modifier present */ ! 136: struct msg { ! 137: struct msg *m_next; /* Link to next message */ ! 138: struct msg *m_prev; /* Link to previous message */ ! 139: int m_flag; /* Flags - non-zero if deleted */ ! 140: int m_hsize; /* Size of header of message */ ! 141: fsize_t m_seek; /* Start position of message */ ! 142: fsize_t m_end; /* End of message */ ! 143: }; ! 144: struct msg *m_first = NULL; /* First message */ ! 145: struct msg *m_last = NULL; /* Last message */ ! 146: ! 147: struct tm *tp; ! 148: ! 149: char iusage[] = "Bad command--type '?' for command summary\n"; ! 150: char nombox[] = "No mailbox '%s'.\n"; ! 151: char nomail[] = "No mail.\n"; ! 152: char noperm[] = "Mailbox '%s' access denied.\n"; ! 153: char moerr[] = "Cannot open mailbox '%s'\n"; ! 154: char wrerr[] = "Write error on '%s'\n"; ! 155: char nosave[] = "Cannot save letter in '%s'\n"; ! 156: ! 157: FILE *mfp; /* Mailbox stream */ ! 158: int myuid; /* User-id of mail user */ ! 159: int mygid; /* Group-id of mail user */ ! 160: char myname[25]; /* User name */ ! 161: char myfullname[50]; ! 162: char mymbox[256]; /* $HOME/mbox */ ! 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 *scatname; /* name of scat filter */ ! 176: char *askcc; /* Ask for CC: list? (YES/NO) */ ! 177: ! 178: fsize_t ftell(); ! 179: char *getlogin(); ! 180: char *mktemp(); ! 181: int catchintr(); ! 182: int catchpipe(); ! 183: void catchchild(); ! 184: int close_fds(); ! 185: char asuser [32]; ! 186: ! 187: main(argc, argv) ! 188: char *argv[]; ! 189: { ! 190: register char *ap; ! 191: char c, *foo; ! 192: ! 193: close_fds(); ! 194: logopen(); ! 195: ! 196: ap = argv[0]; ! 197: if ( (foo=rindex(ap, '/')) != NULL ) ! 198: ap = foo+1; ! 199: callmermail = (strcmp(ap, "rmail") == 0); ! 200: callmexmail = (strcmp(ap, "xmail") == 0); ! 201: ! 202: if (callmermail) ! 203: logdump("argv0 = rmail\n"); ! 204: ! 205: asuser [0] = '\0'; ! 206: signal(SIGCLD, catchchild); ! 207: signal(SIGINT, catchintr); ! 208: signal(SIGPIPE, catchpipe); ! 209: while ((c = getopt(argc, argv, "a:f:mpqrv")) != EOF) { ! 210: switch(c) { ! 211: case 'f': ! 212: if (!callmermail) ! 213: mailbox = optarg; ! 214: break; ! 215: case 'a': ! 216: strcpy(asuser, optarg); ! 217: break; ! 218: case 'm': ! 219: mflag++; ! 220: break; ! 221: case 'p': ! 222: pflag++; ! 223: break; ! 224: case 'q': ! 225: qflag++; ! 226: break; ! 227: case 'r': ! 228: rflag++; ! 229: break; ! 230: case 'v': ! 231: fprintf(stderr, "mail, ver. %s\n", revnop()); ! 232: verbflag++; ! 233: break; ! 234: default: ! 235: usage(); ! 236: } ! 237: } ! 238: if (callmermail) ! 239: verbflag = mflag = pflag = rflag = 0; ! 240: setname(); ! 241: if (optind < argc) { ! 242: qflag = 1; ! 243: if ( send2(stdin, &argv[optind], (fsize_t)0, ! 244: (fsize_t)MAXLONG, 1) != 0 ) ! 245: rmexit(1); ! 246: } else { ! 247: if ( ! pflag) ! 248: callmexmail = 0; ! 249: } ! 250: rmexit(0); ! 251: } ! 252: ! 253: /* ! 254: * Setup all the identities for the current user. ! 255: */ ! 256: setname() ! 257: { ! 258: register struct passwd *pwp; ! 259: register char *np; ! 260: extern struct passwd * getpwnam(); ! 261: ! 262: if (strlen(asuser) > 0) { ! 263: if((pwp = getpwnam(asuser)) == NULL) ! 264: merr("No such user %s.\n", asuser); ! 265: myuid = pwp -> pw_uid; ! 266: } else ! 267: myuid = getuid(); ! 268: if ((pwp = getpwuid(myuid)) == NULL) ! 269: merr("Who are you?\n"); ! 270: np = pwp->pw_name; ! 271: mygid = pwp->pw_gid; ! 272: strcat(spoolname, np); ! 273: strcpy(myname, np); ! 274: strcpy(myfullname, pwp->pw_gecos); ! 275: strcpy(mymbox, pwp->pw_dir); ! 276: strcat(mymbox, "/mbox"); ! 277: mktemp(templ); ! 278: ! 279: if ((editname=getenv("EDITOR"))==NULL) ! 280: editname = "/bin/ed"; ! 281: ! 282: if ( ((scatname=getenv("PAGER")) != NULL) && ! 283: (strlen(scatname) == 0) ) ! 284: scatname = NULL; ! 285: ! 286: if ((askcc=getenv("ASKCC")) != NULL) ! 287: if ( strcmp(askcc, "YES") ) ! 288: askcc = NULL; ! 289: } ! 290: ! 291: /* ! 292: * Lock the appropriately-numbered mailbox ! 293: * (numbered by user-number) from multiple ! 294: * accesses. There is a (small) race here ! 295: * which will be overlooked for now. ! 296: */ ! 297: char *lockname; ! 298: ! 299: mlock(uid) ! 300: int uid; ! 301: { ! 302: register int fd; ! 303: static char lock[32]; ! 304: ! 305: lockname = lock; ! 306: sprintf(lock, "/tmp/maillock%d", uid); ! 307: ! 308: while ( (access(lockname, AEXISTS)) == 0 ){ ! 309: sprintf(BOBerrmsg, "{%d} sleeping(1)\n",getpid()); ! 310: logdump(BOBerrmsg); ! 311: sleep(1); ! 312: } ! 313: ! 314: if ((fd = creat(lockname, 0)) >= 0){ ! 315: close(fd); ! 316: return(0); ! 317: }else{ ! 318: return(1); ! 319: } ! 320: } ! 321: ! 322: /* ! 323: * Unlock the currently-set lock (by `mlock') ! 324: * also called from rmexit. ! 325: */ ! 326: munlock() ! 327: { ! 328: if (lockname != NULL) ! 329: unlink(lockname); ! 330: lockname = NULL; ! 331: } ! 332: ! 333: /* ! 334: * Errors, usage, and exit removing ! 335: * any tempfiles left around. ! 336: */ ! 337: mmsg(x) ! 338: { ! 339: fprintf(stderr, "%r", &x); ! 340: } ! 341: ! 342: merr(x, s) ! 343: char *x, *s; ! 344: { ! 345: mmsg(x, s); ! 346: logdump("merr: "); ! 347: logdump(x, s); ! 348: rmexit(1); ! 349: } ! 350: ! 351: rmexit(s) ! 352: int s; ! 353: { ! 354: if (temp != NULL) ! 355: unlink(temp); ! 356: ! 357: /* only unlock the mailbox if we are exiting normally. Remember, ! 358: * the box may have been locked by another process. ! 359: */ ! 360: ! 361: if(s == 0) ! 362: munlock(); ! 363: ! 364: sprintf(BOBerrmsg,"{%d} About to exit, status = 0x%04x\n", getpid(),s); ! 365: logdump(BOBerrmsg); ! 366: logclose(); ! 367: ! 368: exit(s); ! 369: } ! 370: ! 371: /* ! 372: * Catch interrupts, taking the ! 373: * appropriate action based on ! 374: * the `-q' option. ! 375: */ ! 376: int intrflag; /* On when interrupt sent */ ! 377: int pipeflag; /* On when broken pipe caught */ ! 378: ! 379: catchintr() ! 380: { ! 381: logdump("Caught SIGINT\n"); ! 382: if (qflag) ! 383: rmexit(1); ! 384: intrflag = 1; ! 385: signal(SIGINT, catchintr); ! 386: } ! 387: ! 388: void catchchild() ! 389: { ! 390: logdump("Caught SIGCLD\n"); ! 391: signal(SIGCLD, catchchild); ! 392: } ! 393: ! 394: catchpipe() ! 395: { ! 396: logdump("Caught SIGPIPE\n"); ! 397: pipeflag = 1; ! 398: signal(SIGPIPE, catchpipe); ! 399: } ! 400: ! 401: intcheck() ! 402: { ! 403: if (intrflag || pipeflag) { ! 404: if (intrflag){ ! 405: putc('\n', stdout); ! 406: sprintf(BOBerrmsg,"{%d} lmail caught interrupt signal\n", ! 407: getpid()); ! 408: }else{ ! 409: sprintf(BOBerrmsg,"{%d} lmail caught broken pipe signal", ! 410: getpid()); ! 411: } ! 412: ! 413: logdump(BOBerrmsg); ! 414: ! 415: intrflag = pipeflag = 0; ! 416: return (1); ! 417: } ! 418: return (0); ! 419: } ! 420: ! 421: char * ! 422: revnop() ! 423: { ! 424: register char *cp; ! 425: register char c; ! 426: static char revnobuf[32]; ! 427: ! 428: if ((cp = index(rcsrev, ' ')) != NULL) { ! 429: while (((c = *++cp) == ' ') && (c != '\0')) ! 430: ; ! 431: strcpy(revnobuf, cp); ! 432: if ((cp = index(revnobuf, ' ')) != NULL) ! 433: *cp = '\0'; ! 434: return (revnobuf); ! 435: } else ! 436: return("OOPS"); ! 437: } ! 438: ! 439: ! 440: /* close any unwanted file descriptors that we may have inheritted */ ! 441: ! 442: close_fds() ! 443: { ! 444: ! 445: int i; ! 446: ! 447: for(i = fileno(stderr) +1 ; i < _NFILE ; i++){ ! 448: close(i); ! 449: } ! 450: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.