|
|
1.1 ! root 1: /* ! 2: * The code that passes an individual message to the mail system. ! 3: */ ! 4: ! 5: #include "mail.h" ! 6: ! 7: #define SITENAMELEN 32 /* max length of sitename */ ! 8: #define NODENAME "/etc/uucpname" ! 9: #define DOMAINNAME "/etc/domain" ! 10: char domain [64]; ! 11: ! 12: extern char *strtok(); ! 13: static char **allist; ! 14: static char **tolist; ! 15: static char **cclist = NULL; ! 16: ! 17: char mysite[SITENAMELEN]; /* this host's uucpname */ ! 18: ! 19: extern char *temp; ! 20: extern int myuid; /* User-id of mail user */ ! 21: extern int mygid; /* Group-id of mail user */ ! 22: extern char cmdname[]; /* Command for x{en,de}code filter */ ! 23: /* and for tail recursion to uumail */ ! 24: /* and for editor recursion */ ! 25: extern char *editname; /* name of editor */ ! 26: extern char *askcc; /* Ask for CC: list? (YES/NO) */ ! 27: extern int callmexmail; /* Xmail modifier present */ ! 28: extern char wrerr[]; ! 29: extern char myname[]; /* User name */ ! 30: extern char myfullname[]; /* full user name */ ! 31: extern int mflag; /* `You have mail.' message to recipient */ ! 32: extern int verbflag; /* verbose flag */ ! 33: extern char templ[]; /* Temp file name template */ ! 34: extern char mydead[]; /* $HOME/dead.letter */ ! 35: extern char mysig[]; ! 36: extern char nosave[]; ! 37: extern int callmermail; ! 38: ! 39: static int eflag; /* Edit this mail */ ! 40: static int senderr; ! 41: struct tm *tp; ! 42: char toerr[] = "Cannot create temporary file\n"; ! 43: char header[BUFSIZ]; /* Message header */ ! 44: char boxname[256]; /* Destination mailbox */ ! 45: char remotefrom [32]; /* "remote from uucp" */ ! 46: ! 47: char nosend[] = "Can't send mail to '%s'\n"; ! 48: char nopubk[] = "Can't send xmail to '%s'\n"; ! 49: static int fromtty; ! 50: ! 51: /* ! 52: * Send the message found on ! 53: * the file pointer to the list ! 54: * of people (argv style) with ! 55: * a NULL pointer at the end. ! 56: * The message is copied to a temp-file ! 57: * from position `start' to `end' (or EOF). ! 58: */ ! 59: send2(fp, users, start, end, asksubj) ! 60: FILE *fp; ! 61: register char **users; ! 62: fsize_t start, end; ! 63: int asksubj; ! 64: { ! 65: char **getcc(), **listpp; ! 66: FILE *xfp, *tfp, *sigfp; ! 67: time_t curtime; ! 68: ! 69: uucpname(); ! 70: domainname(); ! 71: senderr = 0; ! 72: temp = templ; ! 73: ! 74: fromtty = isatty(fileno(stdin)); ! 75: if ((tfp = fopen(temp, "w")) != NULL) { ! 76: fclose(tfp); ! 77: if ((tfp = fopen(temp, "r+w")) == NULL) ! 78: merr(toerr); ! 79: } else ! 80: merr(toerr); ! 81: chown(temp, myuid, mygid); ! 82: unlink(temp); ! 83: temp = NULL; ! 84: fseek(fp, start, 0); ! 85: end -= start; ! 86: ! 87: eflag = 0; ! 88: if (fromtty && asksubj && !callmermail) { ! 89: fprintf(stdout, "Subject: "); ! 90: fflush(stdout); ! 91: if (fgets(msgline, NLINE, fp) != NULL) { ! 92: if (strlen(msgline) > 1) ! 93: fprintf(tfp, "Subject: %s", msgline); ! 94: } ! 95: } ! 96: ! 97: if (intcheck()) { ! 98: fclose(tfp); ! 99: return(1); ! 100: } ! 101: ! 102: for (;;) { ! 103: if (fgets(msgline, NLINE, fp) == NULL) ! 104: break; ! 105: if (fp == stdin) ! 106: if ((strcmp(".\n", msgline)==0)) ! 107: break; ! 108: else if ((strcmp("?\n", msgline)==0)) { ! 109: eflag = 1; ! 110: break; ! 111: } ! 112: fputs(msgline, tfp); ! 113: if ( (end-=strlen(msgline)) <= 0 ) ! 114: break; ! 115: } ! 116: ! 117: if (intcheck()) { ! 118: fclose(tfp); ! 119: return(1); ! 120: } ! 121: ! 122: if (!callmermail && (sigfp = fopen(mysig, "r")) != NULL) { ! 123: fputs("\n", tfp); ! 124: while (fgets(msgline, NLINE, sigfp) != NULL) ! 125: fputs(msgline, tfp); ! 126: fclose(sigfp); ! 127: } ! 128: ! 129: /* ! 130: * Now, see if user wants to edit the message ! 131: */ ! 132: ! 133: if (eflag) { ! 134: xfp = tfp; ! 135: temp = templ; ! 136: if ((tfp = fopen(temp, "wr")) == NULL) ! 137: merr(toerr); ! 138: chown(temp, myuid, mygid); ! 139: mcopy(xfp, tfp, (fsize_t)0, (fsize_t)MAXLONG, 0); ! 140: fclose(xfp); ! 141: sprintf(cmdname, "exec %s %s", editname, templ); ! 142: system(cmdname); ! 143: unlink(temp); ! 144: temp = NULL; ! 145: } ! 146: ! 147: /* ! 148: * if empty message, bug out. ! 149: */ ! 150: ! 151: if (ftell(tfp) == 0) { ! 152: fclose(tfp); ! 153: return(1); ! 154: } ! 155: ! 156: /* ! 157: * Now see if a copy list is requested. ! 158: */ ! 159: ! 160: tolist = users; ! 161: cclist = (askcc && fromtty && !callmermail) ? getcc(): NULL; ! 162: allist = listcat(tolist, cclist); ! 163: ! 164: if ( verbflag ) { ! 165: mmsg( ! 166: "Recipient List:\n\n"); ! 167: for (listpp=allist; *listpp != NULL; listpp++) ! 168: mmsg("\t%s\n", *listpp); ! 169: } ! 170: ! 171: /* ! 172: * Now send the message. ! 173: */ ! 174: ! 175: time(&curtime); ! 176: tp = localtime(&curtime); ! 177: ! 178: if (callmexmail) ! 179: xsend(allist, tfp); ! 180: else ! 181: usend(allist, tfp); ! 182: ! 183: return( senderr ); ! 184: } ! 185: ! 186: usend(users, tfp) ! 187: char **users; ! 188: FILE *tfp; ! 189: { ! 190: FILE *xfp; ! 191: char *name; ! 192: char **ulist, **listpp; ! 193: char command[CMDLINE]; ! 194: char *arpadate(); ! 195: FILE *popen(); ! 196: ! 197: logdump("Date: %s From: %s!%s (%s)\n", ! 198: arpadate(tp), mysite, myname, myfullname); ! 199: for (ulist = users; (name=*ulist) != NULL; ulist++) ! 200: logdump("To: \"%s\"\n", name); ! 201: ! 202: /* Build the command line to the delivery program. */ ! 203: if ( callmexmail ) { ! 204: strcpy(command, XDELIVER); /* usually "/bin/rxmail" */ ! 205: } else { ! 206: strcpy(command, DELIVER); /* usually "/bin/rmail" */ ! 207: } /* if ( callmexmail ) */ ! 208: ! 209: /* Add the list of recipients to the command line. */ ! 210: for (listpp = users; *listpp != NULL; listpp++) { ! 211: strcat(command, " "); ! 212: strcat(command, *listpp); ! 213: } ! 214: ! 215: /* NB: I think there may be a security problem ! 216: here, since popen ought to exec $SHELL. Check this. */ ! 217: /* Now actually call the mail delivery agent. */ ! 218: if ( (xfp = popen(command, "w")) == NULL ) { ! 219: /* Report a send error and return. */ ! 220: } ! 221: ! 222: /* Pump the headers into the delivery agent. */ ! 223: build_header(xfp); ! 224: ! 225: /* Pump the message into the delivery agent. */ ! 226: rewind(tfp); ! 227: mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0); ! 228: ! 229: fclose(xfp); ! 230: fclose(tfp); ! 231: } ! 232: ! 233: xsend(users, tfp) char **users; FILE *tfp; ! 234: { ! 235: register char **ulist; ! 236: register char *cp; ! 237: register struct passwd *pwp; ! 238: FILE *xfp; ! 239: ! 240: for (ulist = users; *ulist!=NULL; ulist++) { ! 241: rewind(tfp); ! 242: sprintf(boxname, "%s%s", SPOOLDIR, *ulist); ! 243: sprintf(cmdname, "xencode %s >> %s", *ulist, boxname); ! 244: if (index(*ulist, '!') != NULL ! 245: || (pwp = getpwnam(*ulist)) == NULL) { ! 246: mmsg(nosend, *ulist); ! 247: continue; ! 248: } ! 249: if (xaccess(*ulist) == 0) { ! 250: mmsg(nopubk, *ulist); ! 251: continue; ! 252: } ! 253: mlock(pwp->pw_uid); ! 254: if ((xfp = fopen(boxname, "a")) == NULL) { ! 255: mmsg(nosend, *ulist); ! 256: munlock(); ! 257: continue; ! 258: } ! 259: chown(boxname, pwp->pw_uid, pwp->pw_gid); ! 260: fprintf(xfp, "From xmail %s %s\n", cp, ! 261: tzname[tp->tm_isdst ? 1 : 0]); ! 262: fclose(xfp); ! 263: if ((xfp = popen(cmdname, "w")) == NULL) { ! 264: mmsg("Can't pipe to xencode\n"); ! 265: continue; ! 266: } ! 267: if (fwrite(header, strlen(header), 1, xfp) != 1 ! 268: || mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0)) { ! 269: merr(wrerr, cmdname); ! 270: } ! 271: pclose(xfp); ! 272: munlock(); ! 273: } ! 274: fclose(tfp); ! 275: } ! 276: ! 277: uucpname() ! 278: { ! 279: FILE *uufile; ! 280: ! 281: if (NULL == (uufile = fopen(NODENAME, "r"))) { ! 282: strcpy(mysite, "<unknown>"); ! 283: return; ! 284: } ! 285: fgets(mysite, sizeof mysite, uufile); ! 286: mysite[strlen(mysite) - 1] = '\0'; /* remove '\n' */ ! 287: fclose(uufile); ! 288: return; ! 289: } ! 290: ! 291: domainname() ! 292: { ! 293: FILE *domfile; ! 294: if((domfile = fopen(DOMAINNAME, "r")) == NULL) { ! 295: strcpy(domain, ".UNKNOWN"); ! 296: return; ! 297: } ! 298: fgets(domain, sizeof domain, domfile); ! 299: domain [strlen(domain) - 1] = '\0'; ! 300: fclose (domfile); ! 301: return; ! 302: } ! 303: ! 304: char * ! 305: arpadate(tp) ! 306: struct tm *tp; ! 307: { ! 308: static char arpabuf [64]; ! 309: static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; ! 310: sprintf(arpabuf, "%d %c%c%c %d %02d:%02d:%02d", ! 311: tp->tm_mday, ! 312: months[tp->tm_mon * 3], ! 313: months[tp->tm_mon * 3 + 1], ! 314: months[tp->tm_mon * 3 + 2], ! 315: tp->tm_year, ! 316: tp->tm_hour, tp->tm_min, tp->tm_sec); ! 317: return arpabuf; ! 318: } ! 319: ! 320: char * ! 321: msgid(tp) ! 322: struct tm *tp; ! 323: { ! 324: static char msgidbuf [32]; ! 325: sprintf(msgidbuf, "%02d%02d%02d%02d%02d", ! 326: tp->tm_year, tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min); ! 327: return msgidbuf; ! 328: } ! 329: ! 330: build_header(xfp) ! 331: FILE *xfp; ! 332: { ! 333: char **ulist; ! 334: int processid; ! 335: ! 336: /* Generate a Message-Id. */ ! 337: processid = getpid(); ! 338: sprintf(header, "Message-Id: <%s.AA%d.V%s@%s.%s>\n", ! 339: msgid(tp), processid, revnop(), mysite, domain); ! 340: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 341: return 0; ! 342: ! 343: /* generate Date: and From: lines. */ ! 344: sprintf(header, "Date: %s\nFrom: %s@%s.%s (%s)\n", ! 345: arpadate(tp), myname, mysite, domain, myfullname); ! 346: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 347: return 0; ! 348: ! 349: /* Generate the full To: lines. We just spit addresses out ! 350: verbatum, with no cleanup. */ ! 351: strcpy(header, "To:"); ! 352: for (ulist=tolist; *ulist != NULL; ulist++) { ! 353: strcat(header, " "); ! 354: strcat(header, *ulist); ! 355: } ! 356: strcat(header, "\n"); ! 357: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 358: return 0; ! 359: ! 360: /* Generate a Cc: line if needed. */ ! 361: if (cclist[0] != NULL) { ! 362: strcpy(header, "Cc:"); ! 363: for (ulist=cclist; *ulist != NULL; ulist++) { ! 364: strcat(header, " "); ! 365: strcat(header, *ulist); ! 366: } ! 367: strcat(header, "\n"); ! 368: if (fwrite(header, strlen(header), 1, xfp) != 1) ! 369: return 0; ! 370: } ! 371: return 1; ! 372: } ! 373:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.