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