1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 #pragma ident "%Z%%M% %I% %E% SMI" 26 27 #include "mail.h" 28 /* 29 * generate delivery notification if required. 30 */ 31 void gendeliv(fp, rc, name) 32 FILE *fp; 33 int rc; 34 char *name; 35 { 36 static char pn[] = "gendeliv"; 37 register char *p; 38 char buf[1024], cbuf[256], ybuf[10]; 39 register int i; 40 int didafflines = 0, didrcvlines = 0, suppress = 0, svopts = 0; 41 time_t ltmp; 42 register struct hdrs *hptr; 43 FILE *outfile; 44 45 Dout(pn, 0, "at entry, fp = o%lo, rc = %d,name = '%s'\n", (long)fp, rc, name); 46 if (fp == (FILE *)NULL) { 47 /* Want to send Positive delivery notification. Need to */ 48 /* put selected header info from orig. msg aside to */ 49 /* avoid confusion with header info in Delivery Rpt. */ 50 Daffbytecnt = affbytecnt; affbytecnt = 0; 51 Daffcnt = affcnt; affcnt = 0; 52 Drcvbytecnt = rcvbytecnt; rcvbytecnt = 0; 53 54 hdrlines[H_DAFWDFROM].head = hdrlines[H_AFWDFROM].head; 55 hdrlines[H_DAFWDFROM].tail = hdrlines[H_AFWDFROM].tail; 56 hdrlines[H_AFWDFROM].head = (struct hdrs *)NULL; 57 hdrlines[H_AFWDFROM].tail = (struct hdrs *)NULL; 58 hdrlines[H_DRECEIVED].head = hdrlines[H_RECEIVED].head; 59 hdrlines[H_DRECEIVED].tail = hdrlines[H_RECEIVED].tail; 60 hdrlines[H_RECEIVED].head = (struct hdrs *)NULL; 61 hdrlines[H_RECEIVED].tail = (struct hdrs *)NULL; 62 hdrlines[H_DTCOPY].head = hdrlines[H_TCOPY].head; 63 hdrlines[H_DTCOPY].tail = hdrlines[H_TCOPY].tail; 64 hdrlines[H_TCOPY].head = (struct hdrs *)NULL; 65 hdrlines[H_TCOPY].tail = (struct hdrs *)NULL; 66 67 pushlist (H_TCOPY, HEAD, Rpath, FALSE); 68 } 69 if (rc == 0) { 70 /* Verify that positive delivery notification requested */ 71 if (ckdlivopts(H_DTCOPY, &svopts) & NODELIVERY) { 72 Dout(pn, 0, "pos. notif. not requested\n"); 73 goto rtrn; 74 } 75 } else { 76 /* Verify that negative delivery notification requested */ 77 if (ckdlivopts(H_DTCOPY, &svopts) & IGNORE) { 78 Dout(pn, 0, "neg. notif. not requested\n"); 79 goto rtrn; 80 } 81 } 82 if (fp == (FILE *)NULL) { 83 char *pargs[3]; 84 pargs[0] = "mail"; 85 pargs[1] = Rpath; 86 pargs[2] = 0; 87 if ((outfile = popenvp(pargs[0], pargs, "w", 1)) == (FILE *)NULL) { 88 /* Can't get pipe to mail. Just forget it..... */ 89 Dout(pn, 0,"popenvp() failed\n"); 90 goto rtrn; 91 } 92 } else { 93 outfile = fp; 94 } 95 96 /* get date string into buf for later...*/ 97 ltmp = time((time_t)0); 98 strcpy(buf, asctime(gmtime(<mp))); 99 /* strip year out of date string, insert 'GMT', and put year back... */ 100 p = strrchr(buf,' '); 101 strcpy(ybuf,++p); 102 *p = '\0'; 103 strcat(buf,"GMT "); 104 strcat(buf, ybuf); 105 trimnl(buf); 106 107 fprintf(outfile,"%s 2\n", header[H_RVERS].tag); 108 fprintf(outfile,"%s %s\n", header[H_TCOPY].tag, 109 hdrlines[H_TCOPY].head->value); 110 fprintf(outfile,"%s %s\n", header[H_DATE].tag, buf); 111 dumprcv(ORDINARY, -1,&didrcvlines,&suppress,outfile); 112 dumpaff(ORDINARY, -1,&didafflines,&suppress,outfile); 113 fprintf(outfile,"Original-%s ", header[H_DATE].tag); 114 if ((hptr = hdrlines[H_DATE].head) != (struct hdrs *)NULL) { 115 Dout(pn, 0,"date from H_DATE = '%s'\n", hptr->value); 116 fprintf(outfile,"%s\n", hptr->value); 117 } else { 118 /* If no H_DATE line in original message, use date */ 119 /* in last UNIX H_FROM1 or H_FROM line */ 120 if ((hptr = hdrlines[H_FROM1].tail) == (struct hdrs *)NULL) { 121 hptr = hdrlines[H_FROM].tail; 122 } 123 Dout(pn, 0,"date from H_FROM = '%s'\n", hptr->value); 124 (void) strlcpy(buf, hptr->value, sizeof (buf)); 125 /* Find date portion of line. */ 126 /* Assumes line is of form - */ 127 /* 'name_date_[remote_from_sys|forwarded_by_name]' */ 128 if ((p = strchr(buf,' ')) == (char *)NULL) { 129 strcpy(buf, "No valid datestamp in original."); 130 } else { 131 (void) strlcpy(buf, p++, sizeof (buf)); 132 /* Walk backwards from end of string to 3rd blank, */ 133 /* and then check for 'remote from' or 'forwarded by' */ 134 /* If either found, truncate there, else use entire */ 135 /* string. */ 136 p = buf + strlen(buf) - 1; 137 i = 0; 138 while (p > buf) { 139 if (*p == ' ') { 140 if (++i == 3) { 141 break; 142 } 143 } 144 p--; 145 } 146 if ((i != 3) || (p <= buf)) { 147 strcpy(buf, "No valid datestamp in original."); 148 } else { 149 if ((strncmp((p+1),"remote from", 11) == 0) || 150 (strncmp((p+1),"forwarded by", 12) == 0)) { 151 *p = '\0'; 152 } 153 } 154 } 155 fprintf(outfile,"%s\n", buf); 156 } 157 if ((hptr = hdrlines[H_SUBJ].head) != (struct hdrs *)NULL) { 158 fprintf(outfile,"Original-%s %s\n", 159 header[H_SUBJ].tag, hptr->value); 160 } 161 if ((hptr = hdrlines[H_MSVC].head) != (struct hdrs *)NULL) { 162 if ((strlen(hptr->value) != 4) || 163 (casncmp("mail", hptr->value, 4) != 0)) { 164 fprintf(outfile,"Original-%s %s\n", 165 header[H_MSVC].tag, hptr->value); 166 } 167 } 168 if ((hptr = hdrlines[H_MTSID].head) != (struct hdrs *)NULL) { 169 fprintf(outfile,"Confirming-%s <%s>\n", 170 header[H_MTSID].tag, hptr->value); 171 } 172 if ((hptr = hdrlines[H_UAID].head) != (struct hdrs *)NULL) { 173 fprintf(outfile,"Confirming-%s <%s>\n", 174 header[H_UAID].tag, hptr->value); 175 } 176 cbuf[0] = '\0'; 177 if ((hptr = hdrlines[H_DTCOPY].head) != (struct hdrs *)NULL) { 178 /* Pick comment field off of ">To:" line and put into cbuf */ 179 getcomment(hptr->value, cbuf); 180 } 181 if (rc == 0) { 182 fprintf(outfile,"Delivered-To: %s!%s %s on %s\n", 183 thissys, name, cbuf, buf); 184 } else { 185 (void) strlcpy (buf, name, sizeof (buf)); 186 if ((p = strchr(buf,'!')) != (char *)NULL) { 187 *p = '\0'; 188 } 189 fprintf(outfile,"Not-Delivered-To: %s!%s %s due to ", 190 thissys, buf, 191 /* if en-route-to, put comment there, else put it here*/ 192 ((p == (char *)NULL) ? cbuf : "")); 193 mta_ercode(outfile); 194 if (ckdlivopts(H_DTCOPY, &svopts) & RETURN) { 195 fprintf(outfile," ORIGINAL MESSAGE ATTACHED\n"); 196 } 197 198 if (error == E_FRWL) { 199 fprintf(outfile, frwlmsg, program, uval); 200 } else { 201 fprintf(outfile, " (%s: Error # %d '%s'", 202 program,error,errlist[error]); 203 if (error == E_SURG) { 204 fprintf(outfile,", rc = %d)\n",surg_rc); 205 fprintf(outfile, 206 " ======= Surrogate command =======\n"); 207 fprintf(outfile," %s\n", 208 ((SURRcmdstr == (char *)NULL) ? 209 "" : SURRcmdstr)); 210 /* Include stderr from surrogate, if any */ 211 if (SURRerrfile) { 212 fprintf(outfile, 213 " ==== Start of stdout & stderr ===\n"); 214 rewind (SURRerrfile); 215 while (fgets(buf, sizeof(buf), SURRerrfile) != 216 (char *)NULL) { 217 fprintf(outfile," %s", buf); 218 } 219 if (buf[strlen(buf)-1] != '\n') { 220 fprintf(outfile,"\n"); 221 } 222 fprintf(outfile, 223 " ==== End of stdout & stderr ===\n"); 224 } else 225 fprintf(outfile, 226 " ==== stdout & stderr unavailable ===\n"); 227 } else { 228 fprintf(outfile,")\n"); 229 } 230 } 231 if (p != (char *)NULL) { 232 fprintf(outfile, "En-Route-To: %s %s\n", name, cbuf); 233 } 234 } 235 if ((hptr = hdrlines[H_DAFWDFROM].head) != (struct hdrs *)NULL) { 236 while (hptr != (struct hdrs *)NULL) { 237 fprintf(outfile,"Original-%s %s\n", 238 header[H_DAFWDFROM].tag, hptr->value); 239 hptr = hptr->next; 240 } 241 } 242 fprintf(outfile,"%s\n", header[H_EOH].tag); 243 if (fp == (FILE *)NULL) { 244 pclosevp(outfile); 245 } 246 Dout(pn, 5, "notification sent.\n"); 247 248 rtrn: 249 /* Restore header info from original message. (see above and also */ 250 /* goback()). */ 251 clrhdr(H_TCOPY); 252 clrhdr(H_AFWDFROM); 253 clrhdr(H_RECEIVED); 254 affbytecnt = Daffbytecnt; Daffbytecnt = 0; 255 affcnt = Daffcnt; Daffcnt = 0; 256 rcvbytecnt = Drcvbytecnt; Drcvbytecnt = 0; 257 258 hdrlines[H_AFWDFROM].head = hdrlines[H_DAFWDFROM].head; 259 hdrlines[H_AFWDFROM].tail = hdrlines[H_DAFWDFROM].tail; 260 hdrlines[H_DAFWDFROM].head = (struct hdrs *)NULL; 261 hdrlines[H_DAFWDFROM].tail = (struct hdrs *)NULL; 262 hdrlines[H_RECEIVED].head = hdrlines[H_DRECEIVED].head; 263 hdrlines[H_RECEIVED].tail = hdrlines[H_DRECEIVED].tail; 264 hdrlines[H_DRECEIVED].head = (struct hdrs *)NULL; 265 hdrlines[H_DRECEIVED].tail = (struct hdrs *)NULL; 266 hdrlines[H_TCOPY].head = hdrlines[H_DTCOPY].head; 267 hdrlines[H_TCOPY].tail = hdrlines[H_DTCOPY].tail; 268 hdrlines[H_DTCOPY].head = (struct hdrs *)NULL; 269 hdrlines[H_DTCOPY].tail = (struct hdrs *)NULL; 270 271 return; 272 } 273