|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <sys/types.h> ! 3: #include <sys/mdata.h> ! 4: #include <time.h> ! 5: #include <pwd.h> ! 6: #include <utmp.h> ! 7: #include <sys/stat.h> ! 8: #include "mail.h" ! 9: ! 10: #define SITENAMELEN 32 /* max length of sitename */ ! 11: #define NODENAME "/etc/uucpname" ! 12: #define DOMAINNAME "/etc/domain" ! 13: #define ALIAS "/usr/lib/mail/aliases" ! 14: char domain [64]; ! 15: ! 16: extern char *strtok(); ! 17: FILE *aliasfp; ! 18: char aliasbuf [BUFSIZ]; ! 19: char *findalias(); ! 20: static **gusers; ! 21: char mysite[SITENAMELEN]; /* this host's uucpname */ ! 22: ! 23: extern char *temp; ! 24: extern int myuid; /* User-id of mail user */ ! 25: extern int mygid; /* Group-id of mail user */ ! 26: extern char cmdname[]; /* Command for x{en,de}code filter */ ! 27: /* and for tail recursion to uumail */ ! 28: /* and for editor recursion */ ! 29: extern char *editname; /* name of editor */ ! 30: extern char *askcc; /* Ask for CC: list? (YES/NO) */ ! 31: extern int callmexmail; /* Xmail modifier present */ ! 32: extern char wrerr[]; ! 33: extern char myname[]; /* User name */ ! 34: extern char myfullname[]; /* full user name */ ! 35: extern int mflag; /* `You have mail.' message to recipient */ ! 36: extern int verbflag; /* verbose flag */ ! 37: extern char templ[]; /* Temp file name template */ ! 38: extern char mydead[]; /* $HOME/dead.letter */ ! 39: extern char mysig[]; ! 40: extern char nosave[]; ! 41: extern int callmermail; ! 42: ! 43: static int eflag; /* Edit this mail */ ! 44: static int senderr; ! 45: struct tm *tp; ! 46: char toerr[] = "Cannot create temporary file\n"; ! 47: char header[BUFSIZ]; /* Message header */ ! 48: char boxname[256]; /* Destination mailbox */ ! 49: char aftralias [BUFSIZ]; /* name after alias processing */ ! 50: char remotefrom [32]; /* "remote from uucp" */ ! 51: ! 52: char nosend[] = "Can't send mail to '%s'\n"; ! 53: char nopubk[] = "Can't send xmail to '%s'\n"; ! 54: static int fromtty; ! 55: ! 56: /* ! 57: * Send the message found on ! 58: * the file pointer to the list ! 59: * of people (argv style) with ! 60: * a NULL pointer at the end. ! 61: * The message is copied to a temp-file ! 62: * from position `start' to `end' (or EOF). ! 63: */ ! 64: send2(fp, users, start, end, asksubj) ! 65: FILE *fp; ! 66: register char **users; ! 67: fsize_t start, end; ! 68: int asksubj; ! 69: { ! 70: char **getcc(); ! 71: FILE *xfp, *tfp, *sigfp; ! 72: time_t curtime; ! 73: ! 74: uucpname(); ! 75: domainname(); ! 76: senderr = 0; ! 77: temp = templ; ! 78: /*fprintf(stderr, "send2(fp, users, %ld, %ld, %d)\n", start, end, asksubj);*/ ! 79: fromtty = isatty(fileno(fp)); ! 80: if ((tfp = fopen(temp, "w")) != NULL) { ! 81: fclose(tfp); ! 82: if ((tfp = fopen(temp, "r+w")) == NULL) ! 83: merr(toerr); ! 84: } else ! 85: merr(toerr); ! 86: chown(temp, myuid, mygid); ! 87: unlink(temp); ! 88: temp = NULL; ! 89: fseek(fp, start, 0); ! 90: end -= start; ! 91: ! 92: eflag = 0; ! 93: if (fromtty && asksubj && !callmermail) { ! 94: fprintf(stdout, "Subject: "); ! 95: fflush(stdout); ! 96: if (fgets(msgline, NLINE, fp) != NULL) { ! 97: if (strlen(msgline) > 1) ! 98: fprintf(tfp, "Subject: %s", msgline); ! 99: } ! 100: } ! 101: for (;;) { ! 102: if (fgets(msgline, NLINE, fp) == NULL) ! 103: break; ! 104: if (fp == stdin) ! 105: if ((strcmp(".\n", msgline)==0)) ! 106: break; ! 107: else if ((strcmp("?\n", msgline)==0)) { ! 108: eflag = 1; ! 109: break; ! 110: } ! 111: /* fprintf(stderr, ":%s:", msgline); */ ! 112: fputs(msgline, tfp); ! 113: end -= strlen(msgline); /* compiler bug */ ! 114: if (end <= 0) { ! 115: break; ! 116: } ! 117: } ! 118: if (!callmermail && (sigfp = fopen(mysig, "r")) != NULL) { ! 119: fputs("\n", tfp); ! 120: while (fgets(msgline, NLINE, sigfp) != NULL) { ! 121: fputs(msgline, tfp); ! 122: } ! 123: fclose(sigfp); ! 124: } ! 125: /* ! 126: * If interrupted, bug out. ! 127: */ ! 128: if (intcheck()) { ! 129: fclose(tfp); ! 130: return; ! 131: } ! 132: /* ! 133: * Now, see if user wants to edit the message ! 134: */ ! 135: if (eflag) { ! 136: xfp = tfp; ! 137: temp = templ; ! 138: if ((tfp = fopen(temp, "wr")) == NULL) ! 139: merr(toerr); ! 140: chown(temp, myuid, mygid); ! 141: mcopy(xfp, tfp, (fsize_t)0, (fsize_t)MAXLONG, 0); ! 142: fclose(xfp); ! 143: sprintf(cmdname, "%s %s", editname, templ); ! 144: system(cmdname); ! 145: unlink(temp); ! 146: temp = NULL; ! 147: } ! 148: /* ! 149: * Otherwise if empty message, bug out. ! 150: */ ! 151: else if (ftell(tfp) == 0) { ! 152: fclose(tfp); ! 153: return; ! 154: } ! 155: /* ! 156: * Now see if a copy list is requested. ! 157: */ ! 158: if (askcc) ! 159: users = getcc(users); ! 160: gusers = users; ! 161: /* ! 162: * Now send the message. ! 163: */ ! 164: time(&curtime); ! 165: tp = localtime(&curtime); ! 166: if (callmexmail) ! 167: xsend(users, tfp); ! 168: else ! 169: usend(users, tfp); ! 170: } ! 171: ! 172: usend(users, tfp) ! 173: char **users; ! 174: FILE *tfp; ! 175: { ! 176: FILE *xfp; ! 177: char *cp, *ap; ! 178: char **ulist; ! 179: register struct passwd *pwp; ! 180: ! 181: for (ulist = users; *ulist != NULL; ulist++) { ! 182: rewind(tfp); ! 183: strcpy(aftralias, *ulist); ! 184: if (index(*ulist, '!') == 0) { ! 185: ap = findalias(*ulist); ! 186: if (ap != NULL) { ! 187: strcpy(aftralias, ap); ! 188: if (verbflag && strcmp(aftralias, ap)) ! 189: fprintf(stderr, ! 190: "name %s aliased to %s\n", ! 191: *ulist, aftralias); ! 192: } ! 193: } ! 194: if ((cp = index(aftralias, '!')) != NULL) { ! 195: *cp++ = '\0'; ! 196: if (rsend(aftralias, cp, tfp) != 0) ! 197: senderr = 1; ! 198: continue; ! 199: } ! 200: sprintf(boxname, "%s%s", SPOOLDIR, aftralias); ! 201: if ((pwp = getpwnam(aftralias)) == NULL) { ! 202: mmsg(nosend, aftralias); ! 203: senderr = 1; ! 204: continue; ! 205: } ! 206: mlock(pwp->pw_uid); ! 207: if ((xfp = fopen(boxname, "a")) == NULL) { ! 208: mmsg(nosend, aftralias); ! 209: senderr = 1; ! 210: munlock(); ! 211: continue; ! 212: } ! 213: chown(boxname, pwp->pw_uid, pwp->pw_gid); ! 214: if (build_header(aftralias, NULL, tfp, xfp) != 1 ! 215: || mcopy(tfp, xfp, ftell(tfp), (fsize_t)MAXLONG, 0)) { ! 216: merr(wrerr, boxname); ! 217: senderr = 1; ! 218: } else ! 219: fprintf(xfp, "\1\1\n"); ! 220: fflush(xfp); ! 221: munlock(); ! 222: advise(aftralias); ! 223: } ! 224: if (senderr && fromtty && ! callmexmail) { ! 225: if (maccess(mydead) < 0 ! 226: || (xfp = fopen(mydead, "a")) == NULL ! 227: || mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0)) ! 228: mmsg(nosave, mydead); ! 229: else ! 230: mmsg("Letter saved in %s\n", mydead); ! 231: if (xfp != NULL) { ! 232: chown(mydead, myuid, mygid); ! 233: fclose(xfp); ! 234: } ! 235: } ! 236: fclose(tfp); ! 237: } ! 238: ! 239: rsend(system, user, tfp) ! 240: char *user; ! 241: char *system; ! 242: FILE *tfp; ! 243: { ! 244: FILE *xfp; ! 245: int i; ! 246: ! 247: sprintf(cmdname, "uux -r - %s!rmail '(%s)'", system, user); ! 248: if (verbflag) ! 249: fprintf(stderr, "Queueing remote mail to %s!%s\n", ! 250: system, user); ! 251: if ((xfp = popen(cmdname, "w")) == NULL) { ! 252: mmsg("Can't pipe to %s\n", cmdname); ! 253: return 1; ! 254: } ! 255: if (build_header(user, mysite, tfp, xfp) != 1 ! 256: || mcopy(tfp, xfp, ftell(tfp), (fsize_t)MAXLONG, 0)) { ! 257: merr(wrerr, cmdname); ! 258: return 1; ! 259: } ! 260: if (i = (pclose(xfp) != 0)) { ! 261: mmsg("uux has failed, status %d\n", i); ! 262: return 1; ! 263: } ! 264: return 0; ! 265: } ! 266: ! 267: xsend(users, tfp) char **users; FILE *tfp; ! 268: { ! 269: register char **ulist; ! 270: register char *cp; ! 271: register struct passwd *pwp; ! 272: FILE *xfp; ! 273: ! 274: for (ulist = users; *ulist!=NULL; ulist++) { ! 275: rewind(tfp); ! 276: sprintf(boxname, "%s%s", SPOOLDIR, *ulist); ! 277: sprintf(cmdname, "xencode %s >> %s", *ulist, boxname); ! 278: if (index(*ulist, '!') != NULL ! 279: || (pwp = getpwnam(*ulist)) == NULL) { ! 280: mmsg(nosend, *ulist); ! 281: continue; ! 282: } ! 283: if (xaccess(*ulist) == 0) { ! 284: mmsg(nopubk, *ulist); ! 285: continue; ! 286: } ! 287: mlock(pwp->pw_uid); ! 288: if ((xfp = fopen(boxname, "a")) == NULL) { ! 289: mmsg(nosend, *ulist); ! 290: munlock(); ! 291: continue; ! 292: } ! 293: chown(boxname, pwp->pw_uid, pwp->pw_gid); ! 294: fprintf(xfp, "From xmail %s %s\n", cp, ! 295: tzname[tp->tm_isdst ? 1 : 0]); ! 296: fclose(xfp); ! 297: if ((xfp = popen(cmdname, "w")) == NULL) { ! 298: mmsg("Can't pipe to xencode\n"); ! 299: continue; ! 300: } ! 301: if (fwrite(header, strlen(header), 1, xfp) != 1 ! 302: || mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0)) { ! 303: merr(wrerr, cmdname); ! 304: } ! 305: pclose(xfp); ! 306: munlock(); ! 307: } ! 308: fclose(tfp); ! 309: } ! 310: ! 311: /* ! 312: * If the `-m' option is specified, advise ! 313: * the recipient of the presence of mail. ! 314: */ ! 315: advise(recipient) ! 316: char *recipient; ! 317: { ! 318: register FILE *fp; ! 319: register FILE *tfp; ! 320: struct utmp ut; ! 321: char tty[30]; ! 322: struct stat sb; ! 323: ! 324: if (!mflag) ! 325: return; ! 326: if ((fp = fopen("/etc/utmp", "r")) == NULL) ! 327: return; ! 328: while (fread(&ut, sizeof ut, 1, fp) == 1) ! 329: if (strncmp(ut.ut_name, recipient, DIRSIZ) == 0) { ! 330: sprintf(tty, "/dev/%s", ut.ut_line); ! 331: if (stat(tty, &sb)<0 || (sb.st_mode&S_IEXEC)==0) ! 332: continue; ! 333: if ((tfp = fopen(tty, "w")) != NULL) { ! 334: fprintf(tfp, "\7%s: you have mail.\n", myname); ! 335: fclose(tfp); ! 336: } ! 337: } ! 338: fclose(fp); ! 339: } ! 340: ! 341: uucpname() ! 342: { ! 343: FILE *uufile; ! 344: ! 345: if (NULL == (uufile = fopen(NODENAME, "r"))) { ! 346: strcpy(mysite, "<unknown>"); ! 347: return; ! 348: } ! 349: fgets(mysite, sizeof mysite, uufile); ! 350: mysite[strlen(mysite) - 1] = '\0'; /* remove '\n' */ ! 351: fclose(uufile); ! 352: return; ! 353: } ! 354: ! 355: domainname() ! 356: { ! 357: FILE *domfile; ! 358: if((domfile = fopen(DOMAINNAME, "r")) == NULL) { ! 359: strcpy(domain, ".UNKNOWN"); ! 360: return; ! 361: } ! 362: fgets(domain, sizeof domain, domfile); ! 363: domain [strlen(domain) - 1] = '\0'; ! 364: fclose (domfile); ! 365: return; ! 366: } ! 367: ! 368: char * ! 369: findalias(who) ! 370: { ! 371: char *name, *newname; ! 372: static whobuf [64]; ! 373: int recurcount; ! 374: int hit; ! 375: ! 376: if (aliasfp == NULL) { ! 377: if ((aliasfp = fopen(ALIAS, "r")) == NULL) { ! 378: mmsg("Cannot open alias file\n"); ! 379: return who; ! 380: } ! 381: } ! 382: recurcount = 0; ! 383: strcpy(whobuf, who); ! 384: for (; ; ) { ! 385: fseek(aliasfp, 0L, 0); ! 386: hit = 0; ! 387: while (fgets(aliasbuf, BUFSIZ, aliasfp) != NULL) { ! 388: name = strtok(aliasbuf," #:\t"); ! 389: newname = strtok(NULL, "#(), \t\n"); ! 390: if (strcmp(name, whobuf) == 0) { ! 391: strcpy(whobuf, newname); ! 392: if (recurcount++ > 4) { ! 393: sprintf(whobuf, ! 394: "Too many alias recursions for %s\n", ! 395: who); ! 396: mmsg(whobuf); ! 397: return who; ! 398: } ! 399: hit = 1; ! 400: break; ! 401: } ! 402: } ! 403: if (hit == 0) ! 404: return whobuf; ! 405: } ! 406: return whobuf; ! 407: } ! 408: ! 409: char * ! 410: arpadate(tp) ! 411: struct tm *tp; ! 412: { ! 413: static char arpabuf [64]; ! 414: static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; ! 415: sprintf(arpabuf, "%d %c%c%c %d %02d:%02d:%02d", ! 416: tp->tm_mday, ! 417: months[tp->tm_mon * 3], ! 418: months[tp->tm_mon * 3 + 1], ! 419: months[tp->tm_mon * 3 + 2], ! 420: tp->tm_year, ! 421: tp->tm_hour, tp->tm_min, tp->tm_sec); ! 422: return arpabuf; ! 423: } ! 424: ! 425: char * ! 426: msgid(tp) ! 427: struct tm *tp; ! 428: { ! 429: static char msgidbuf [32]; ! 430: sprintf(msgidbuf, "%02d%02d%02d%02d%02d", ! 431: tp->tm_year, tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min); ! 432: return msgidbuf; ! 433: } ! 434: ! 435: build_header(user, site, tfp, xfp) ! 436: char *user; ! 437: char *site; ! 438: FILE *tfp; ! 439: FILE *xfp; ! 440: { ! 441: char *cp; ! 442: char **ulist; ! 443: long pos; ! 444: int processid; ! 445: ! 446: cp = asctime(tp); ! 447: cp[strlen(cp)-1] = 0; ! 448: /* if (!callmermail) { */ ! 449: sprintf(header, "From %s %s %s", myname, cp, ! 450: tzname[tp->tm_isdst ? 1 : 0]); ! 451: if (site != NULL) { ! 452: strcat(header, " remote from "); ! 453: strcat(header, site); ! 454: } ! 455: strcat(header, "\n"); ! 456: /* } */ ! 457: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 458: return 0; ! 459: pos = ftell(tfp); ! 460: /* scan to end of From_ lines */ ! 461: while (fgets(header, NLINE, tfp) != NULL) { ! 462: if ((strncmp (header, "From ", 5) != 0) && ! 463: (strncmp (header, ">From ", 6) != 0)) { ! 464: break; ! 465: } ! 466: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 467: return 0; ! 468: pos = ftell(tfp); ! 469: } ! 470: fseek(tfp, pos, 0); ! 471: processid = getpid(); ! 472: if (callmermail) { ! 473: sprintf(header, ! 474: "Received: by %s (mail v %s)\n\tid AA%d; %s\n", ! 475: mysite, revnop(), processid, arpadate(tp)); ! 476: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 477: return 0; ! 478: } else { ! 479: sprintf(header, "Message-Id: <%s.AA%d.V%s.%s@%s>\n", ! 480: msgid(tp), processid, revnop(), mysite, domain); ! 481: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 482: return 0; ! 483: sprintf(header, "Date: %s\nFrom: %s!%s (%s)\n", ! 484: arpadate(tp), mysite, myname, myfullname); ! 485: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 486: return 0; ! 487: sprintf(header, "To: %s\n", user); ! 488: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 489: return 0; ! 490: if (gusers[0] != NULL && gusers[1] != NULL) { ! 491: strcpy(header, "cc:"); ! 492: for (ulist = gusers; *ulist != NULL; ulist++) { ! 493: strcat(header, " "); ! 494: strcat(header, *ulist); ! 495: } ! 496: strcat(header, "\n"); ! 497: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 498: return 0; ! 499: } ! 500: } ! 501: return 1; ! 502: } ! 503:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.