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