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