1*1392Seric # include <stdio.h> 2*1392Seric # include <ctype.h> 3*1392Seric # include "dlvrmail.h" 4*1392Seric 5*1392Seric static char SccsId[] = "@(#)collect.c 1.2 10/11/80"; 6*1392Seric 7*1392Seric /* 8*1392Seric ** MAKETEMP -- read & parse message header & make temp file. 9*1392Seric ** 10*1392Seric ** Creates a temporary file name and copies the standard 11*1392Seric ** input to that file. While it is doing it, it looks for 12*1392Seric ** "From:" and "Sender:" fields to use as the from-person 13*1392Seric ** (but only if the -a flag is specified). It prefers to 14*1392Seric ** to use the "Sender:" field. 15*1392Seric ** 16*1392Seric ** MIT seems to like to produce "Sent-By:" fields instead 17*1392Seric ** of "Sender:" fields. We used to catch this, but it turns 18*1392Seric ** out that the "Sent-By:" field doesn't always correspond 19*1392Seric ** to someone real ("___057", for instance), as required by 20*1392Seric ** the protocol. So we limp by..... 21*1392Seric ** 22*1392Seric ** Parameters: 23*1392Seric ** none 24*1392Seric ** 25*1392Seric ** Returns: 26*1392Seric ** Name of temp file. 27*1392Seric ** 28*1392Seric ** Side Effects: 29*1392Seric ** Temp file is created and filled. 30*1392Seric ** 31*1392Seric ** Called By: 32*1392Seric ** main 33*1392Seric ** 34*1392Seric ** Notes: 35*1392Seric ** This is broken off from main largely so that the 36*1392Seric ** temp buffer can be deallocated. 37*1392Seric */ 38*1392Seric 39*1392Seric char * 40*1392Seric maketemp() 41*1392Seric { 42*1392Seric register FILE *tf; 43*1392Seric char buf[MAXFIELD+1]; 44*1392Seric static char fbuf[sizeof buf]; 45*1392Seric extern char *prescan(); 46*1392Seric extern char *matchhdr(); 47*1392Seric register char *p; 48*1392Seric register bool inheader; 49*1392Seric bool firstline; 50*1392Seric char c; 51*1392Seric 52*1392Seric /* 53*1392Seric ** Create the temp file name and create the file. 54*1392Seric */ 55*1392Seric 56*1392Seric mktemp(InFileName); 57*1392Seric close(creat(InFileName, 0600)); 58*1392Seric if ((tf = fopen(InFileName, "w")) == NULL) 59*1392Seric { 60*1392Seric syserr("Cannot create %s", InFileName); 61*1392Seric return (NULL); 62*1392Seric } 63*1392Seric 64*1392Seric /* 65*1392Seric ** Copy stdin to temp file & do message editting. 66*1392Seric ** From person gets copied into fbuf. At the end of 67*1392Seric ** this loop, if fbuf[0] == '\0' then there was no 68*1392Seric ** recognized from person in the message. We also 69*1392Seric ** save the message id in MsgId. The 70*1392Seric ** flag 'inheader' keeps track of whether we are 71*1392Seric ** in the header or in the body of the message. 72*1392Seric ** The flag 'firstline' is only true on the first 73*1392Seric ** line of a message. 74*1392Seric ** To keep certain mailers from getting confused, 75*1392Seric ** and to keep the output clean, lines that look 76*1392Seric ** like UNIX "From" lines are deleted in the header, 77*1392Seric ** and prepended with ">" in the body. 78*1392Seric */ 79*1392Seric 80*1392Seric inheader = TRUE; 81*1392Seric firstline = TRUE; 82*1392Seric fbuf[0] = '\0'; 83*1392Seric while (fgets(buf, sizeof buf, stdin) != NULL) 84*1392Seric { 85*1392Seric if (inheader && isalnum(buf[0])) 86*1392Seric { 87*1392Seric /* get the rest of this field */ 88*1392Seric while ((c = getc(stdin)) == ' ' || c == '\t') 89*1392Seric { 90*1392Seric p = &buf[strlen(buf)]; 91*1392Seric *p++ = c; 92*1392Seric if (fgets(p, sizeof buf - (p - buf), stdin) == NULL) 93*1392Seric break; 94*1392Seric } 95*1392Seric ungetc(c, stdin); 96*1392Seric } 97*1392Seric 98*1392Seric if (!IgnrDot && buf[0] == '.' && (buf[1] == '\n' || buf[1] == '\0')) 99*1392Seric break; 100*1392Seric 101*1392Seric /* are we still in the header? */ 102*1392Seric if ((buf[0] == '\n' || buf[0] == '\0') && inheader) 103*1392Seric { 104*1392Seric inheader = FALSE; 105*1392Seric if (MsgId[0] == '\0') 106*1392Seric { 107*1392Seric makemsgid(); 108*1392Seric if (UseMsgId) 109*1392Seric fprintf(tf, "Message-Id: <%s>\n", MsgId); 110*1392Seric } 111*1392Seric # ifdef DEBUG 112*1392Seric if (Debug) 113*1392Seric printf("EOH\n"); 114*1392Seric # endif DEBUG 115*1392Seric } 116*1392Seric 117*1392Seric /* Hide UNIX-like From lines */ 118*1392Seric if (buf[0] == 'F' && buf[1] == 'r' && buf[2] == 'o' && 119*1392Seric buf[3] == 'm' && buf[4] == ' ') 120*1392Seric { 121*1392Seric if (firstline && !SaveFrom) 122*1392Seric continue; 123*1392Seric fputs(">", tf); 124*1392Seric } 125*1392Seric 126*1392Seric if (inheader && !isspace(buf[0])) 127*1392Seric { 128*1392Seric /* find out if this is really a header */ 129*1392Seric for (p = buf; *p != ':' && *p != '\0' && !isspace(*p); p++) 130*1392Seric continue; 131*1392Seric while (*p != ':' && isspace(*p)) 132*1392Seric p++; 133*1392Seric if (*p != ':') 134*1392Seric { 135*1392Seric inheader = FALSE; 136*1392Seric # ifdef DEBUG 137*1392Seric if (Debug) 138*1392Seric printf("EOH?\n"); 139*1392Seric # endif DEBUG 140*1392Seric } 141*1392Seric } 142*1392Seric 143*1392Seric if (inheader) 144*1392Seric { 145*1392Seric /* find the sender */ 146*1392Seric p = matchhdr(buf, "sender"); 147*1392Seric if (p == NULL && fbuf[0] == '\0') 148*1392Seric p = matchhdr(buf, "from"); 149*1392Seric if (p != NULL) 150*1392Seric prescan(p, fbuf, &fbuf[sizeof fbuf - 1], '\0'); 151*1392Seric 152*1392Seric /* find the message id */ 153*1392Seric p = matchhdr(buf, "message-id"); 154*1392Seric if (p != NULL && MsgId[0] == '\0') 155*1392Seric prescan(p, MsgId, &MsgId[sizeof MsgId - 1], '\0'); 156*1392Seric } 157*1392Seric fputs(buf, tf); 158*1392Seric firstline = FALSE; 159*1392Seric if (ferror(tf)) 160*1392Seric { 161*1392Seric syserr("Cannot write %s", InFileName); 162*1392Seric clearerr(tf); 163*1392Seric break; 164*1392Seric } 165*1392Seric } 166*1392Seric fclose(tf); 167*1392Seric if (MsgId[0] == '\0') 168*1392Seric makemsgid(); 169*1392Seric if (freopen(InFileName, "r", stdin) == NULL) 170*1392Seric syserr("Cannot reopen %s", InFileName); 171*1392Seric return (ArpaFmt && fbuf[0] != '\0' ? fbuf : NULL); 172*1392Seric } 173*1392Seric /* 174*1392Seric ** MAKEMSGID -- Compute a message id for this process. 175*1392Seric ** 176*1392Seric ** This routine creates a message id for a message if 177*1392Seric ** it did not have one already. If the MESSAGEID compile 178*1392Seric ** flag is set, the messageid will be added to any message 179*1392Seric ** that does not already have one. Currently it is more 180*1392Seric ** of an artifact, but I suggest that if you are hacking, 181*1392Seric ** you leave it in -- I may want to use it someday if 182*1392Seric ** duplicate messages turn out to be a problem. 183*1392Seric ** 184*1392Seric ** Parameters: 185*1392Seric ** none. 186*1392Seric ** 187*1392Seric ** Returns: 188*1392Seric ** none. 189*1392Seric ** 190*1392Seric ** Side Effects: 191*1392Seric ** Stores a message-id into MsgId. 192*1392Seric ** 193*1392Seric ** Called By: 194*1392Seric ** maketemp 195*1392Seric */ 196*1392Seric 197*1392Seric makemsgid() 198*1392Seric { 199*1392Seric auto long t; 200*1392Seric extern char *MyLocName; 201*1392Seric extern char *ArpaHost; 202*1392Seric 203*1392Seric time(&t); 204*1392Seric sprintf(MsgId, "%ld.%d.%s@%s", t, getpid(), MyLocName, ArpaHost); 205*1392Seric } 206