11392Seric # include <stdio.h> 21392Seric # include <ctype.h> 3*1439Seric # include <errno.h> 41392Seric # include "dlvrmail.h" 51392Seric 6*1439Seric static char SccsId[] = "@(#)collect.c 1.4 10/15/80"; 71392Seric 81392Seric /* 91392Seric ** MAKETEMP -- read & parse message header & make temp file. 101392Seric ** 111392Seric ** Creates a temporary file name and copies the standard 121392Seric ** input to that file. While it is doing it, it looks for 131392Seric ** "From:" and "Sender:" fields to use as the from-person 141392Seric ** (but only if the -a flag is specified). It prefers to 151392Seric ** to use the "Sender:" field. 161392Seric ** 171392Seric ** MIT seems to like to produce "Sent-By:" fields instead 181392Seric ** of "Sender:" fields. We used to catch this, but it turns 191392Seric ** out that the "Sent-By:" field doesn't always correspond 201392Seric ** to someone real ("___057", for instance), as required by 211392Seric ** the protocol. So we limp by..... 221392Seric ** 231392Seric ** Parameters: 241392Seric ** none 251392Seric ** 261392Seric ** Returns: 271392Seric ** Name of temp file. 281392Seric ** 291392Seric ** Side Effects: 301392Seric ** Temp file is created and filled. 311392Seric ** 321392Seric ** Called By: 331392Seric ** main 341392Seric ** 351392Seric ** Notes: 361392Seric ** This is broken off from main largely so that the 371392Seric ** temp buffer can be deallocated. 381392Seric */ 391392Seric 401397Seric char MsgId[MAXNAME]; 411397Seric 421392Seric char * 431392Seric maketemp() 441392Seric { 451392Seric register FILE *tf; 461392Seric char buf[MAXFIELD+1]; 471392Seric static char fbuf[sizeof buf]; 481392Seric extern char *prescan(); 491392Seric extern char *matchhdr(); 501392Seric register char *p; 511392Seric register bool inheader; 521392Seric bool firstline; 531392Seric char c; 54*1439Seric extern int errno; 551392Seric 561392Seric /* 571392Seric ** Create the temp file name and create the file. 581392Seric */ 591392Seric 601392Seric mktemp(InFileName); 611392Seric close(creat(InFileName, 0600)); 621392Seric if ((tf = fopen(InFileName, "w")) == NULL) 631392Seric { 641392Seric syserr("Cannot create %s", InFileName); 651392Seric return (NULL); 661392Seric } 671392Seric 681392Seric /* 691392Seric ** Copy stdin to temp file & do message editting. 701392Seric ** From person gets copied into fbuf. At the end of 711392Seric ** this loop, if fbuf[0] == '\0' then there was no 721392Seric ** recognized from person in the message. We also 731392Seric ** save the message id in MsgId. The 741392Seric ** flag 'inheader' keeps track of whether we are 751392Seric ** in the header or in the body of the message. 761392Seric ** The flag 'firstline' is only true on the first 771392Seric ** line of a message. 781392Seric ** To keep certain mailers from getting confused, 791392Seric ** and to keep the output clean, lines that look 801392Seric ** like UNIX "From" lines are deleted in the header, 811392Seric ** and prepended with ">" in the body. 821392Seric */ 831392Seric 841392Seric inheader = TRUE; 851392Seric firstline = TRUE; 861392Seric fbuf[0] = '\0'; 871392Seric while (fgets(buf, sizeof buf, stdin) != NULL) 881392Seric { 891392Seric if (inheader && isalnum(buf[0])) 901392Seric { 911392Seric /* get the rest of this field */ 921392Seric while ((c = getc(stdin)) == ' ' || c == '\t') 931392Seric { 941392Seric p = &buf[strlen(buf)]; 951392Seric *p++ = c; 961392Seric if (fgets(p, sizeof buf - (p - buf), stdin) == NULL) 971392Seric break; 981392Seric } 991392Seric ungetc(c, stdin); 1001392Seric } 1011392Seric 1021392Seric if (!IgnrDot && buf[0] == '.' && (buf[1] == '\n' || buf[1] == '\0')) 1031392Seric break; 1041392Seric 1051392Seric /* are we still in the header? */ 1061392Seric if ((buf[0] == '\n' || buf[0] == '\0') && inheader) 1071392Seric { 1081392Seric inheader = FALSE; 1091392Seric if (MsgId[0] == '\0') 1101392Seric { 1111392Seric makemsgid(); 1121392Seric if (UseMsgId) 1131392Seric fprintf(tf, "Message-Id: <%s>\n", MsgId); 1141392Seric } 1151392Seric # ifdef DEBUG 1161392Seric if (Debug) 1171392Seric printf("EOH\n"); 1181392Seric # endif DEBUG 1191392Seric } 1201392Seric 1211392Seric /* Hide UNIX-like From lines */ 1221392Seric if (buf[0] == 'F' && buf[1] == 'r' && buf[2] == 'o' && 1231392Seric buf[3] == 'm' && buf[4] == ' ') 1241392Seric { 1251392Seric if (firstline && !SaveFrom) 1261392Seric continue; 1271392Seric fputs(">", tf); 1281392Seric } 1291392Seric 1301392Seric if (inheader && !isspace(buf[0])) 1311392Seric { 1321392Seric /* find out if this is really a header */ 1331392Seric for (p = buf; *p != ':' && *p != '\0' && !isspace(*p); p++) 1341392Seric continue; 1351392Seric while (*p != ':' && isspace(*p)) 1361392Seric p++; 1371392Seric if (*p != ':') 1381392Seric { 1391392Seric inheader = FALSE; 1401392Seric # ifdef DEBUG 1411392Seric if (Debug) 1421392Seric printf("EOH?\n"); 1431392Seric # endif DEBUG 1441392Seric } 1451392Seric } 1461392Seric 1471392Seric if (inheader) 1481392Seric { 1491392Seric /* find the sender */ 1501392Seric p = matchhdr(buf, "sender"); 1511392Seric if (p == NULL && fbuf[0] == '\0') 1521392Seric p = matchhdr(buf, "from"); 1531392Seric if (p != NULL) 1541392Seric prescan(p, fbuf, &fbuf[sizeof fbuf - 1], '\0'); 1551392Seric 1561392Seric /* find the message id */ 1571392Seric p = matchhdr(buf, "message-id"); 1581392Seric if (p != NULL && MsgId[0] == '\0') 1591392Seric prescan(p, MsgId, &MsgId[sizeof MsgId - 1], '\0'); 1601392Seric } 1611392Seric fputs(buf, tf); 1621392Seric firstline = FALSE; 1631392Seric if (ferror(tf)) 1641392Seric { 165*1439Seric if (errno == ENOSPC) 166*1439Seric { 167*1439Seric freopen(InFileName, "w", tf); 168*1439Seric fputs("\nMAIL DELETED BECAUSE OF LACK OF DISK SPACE\n\n", tf); 169*1439Seric syserr("Out of disk space for temp file"); 170*1439Seric } 171*1439Seric else 172*1439Seric syserr("Cannot write %s", InFileName); 173*1439Seric freopen("/dev/null", "w", tf); 1741392Seric } 1751392Seric } 1761392Seric fclose(tf); 1771392Seric if (MsgId[0] == '\0') 1781392Seric makemsgid(); 1791392Seric if (freopen(InFileName, "r", stdin) == NULL) 1801392Seric syserr("Cannot reopen %s", InFileName); 1811392Seric return (ArpaFmt && fbuf[0] != '\0' ? fbuf : NULL); 1821392Seric } 1831392Seric /* 1841392Seric ** MAKEMSGID -- Compute a message id for this process. 1851392Seric ** 1861392Seric ** This routine creates a message id for a message if 1871392Seric ** it did not have one already. If the MESSAGEID compile 1881392Seric ** flag is set, the messageid will be added to any message 1891392Seric ** that does not already have one. Currently it is more 1901392Seric ** of an artifact, but I suggest that if you are hacking, 1911392Seric ** you leave it in -- I may want to use it someday if 1921392Seric ** duplicate messages turn out to be a problem. 1931392Seric ** 1941392Seric ** Parameters: 1951392Seric ** none. 1961392Seric ** 1971392Seric ** Returns: 1981392Seric ** none. 1991392Seric ** 2001392Seric ** Side Effects: 2011392Seric ** Stores a message-id into MsgId. 2021392Seric ** 2031392Seric ** Called By: 2041392Seric ** maketemp 2051392Seric */ 2061392Seric 2071392Seric makemsgid() 2081392Seric { 2091392Seric auto long t; 2101392Seric extern char *MyLocName; 2111392Seric extern char *ArpaHost; 2121392Seric 2131392Seric time(&t); 2141392Seric sprintf(MsgId, "%ld.%d.%s@%s", t, getpid(), MyLocName, ArpaHost); 2151392Seric } 216