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