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
26*7c478bd9Sstevel@tonic-gate /*
27*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
29*7c478bd9Sstevel@tonic-gate */
30*7c478bd9Sstevel@tonic-gate
31*7c478bd9Sstevel@tonic-gate /*
32*7c478bd9Sstevel@tonic-gate * All global externs defined in mail.h. All variables are initialized
33*7c478bd9Sstevel@tonic-gate * here!
34*7c478bd9Sstevel@tonic-gate *
35*7c478bd9Sstevel@tonic-gate * !!!!!IF YOU CHANGE (OR ADD) IT HERE, DO IT THERE ALSO !!!!!!!!
36*7c478bd9Sstevel@tonic-gate *
37*7c478bd9Sstevel@tonic-gate */
38*7c478bd9Sstevel@tonic-gate #include "mail.h"
39*7c478bd9Sstevel@tonic-gate
40*7c478bd9Sstevel@tonic-gate int ac; /* argument list count */
41*7c478bd9Sstevel@tonic-gate char **av; /* argument list */
42*7c478bd9Sstevel@tonic-gate int affbytecnt; /* Total bytes of Auto-Fwd. info in msg. */
43*7c478bd9Sstevel@tonic-gate int affcnt; /* Number of Auto-Fwd.-From: lines in msg. */
44*7c478bd9Sstevel@tonic-gate int Daffbytecnt; /* Hold affbytecnt when sending Delivery Notification */
45*7c478bd9Sstevel@tonic-gate int Daffcnt; /* Hold affcnt when sending Delivery Notification */
46*7c478bd9Sstevel@tonic-gate char binmsg[] = "*** Message content is not printable: delete, write or save it to a file ***";
47*7c478bd9Sstevel@tonic-gate int changed; /* > 0 says mailfile has changed */
48*7c478bd9Sstevel@tonic-gate char datestring[60]; /* Today's date and time */
49*7c478bd9Sstevel@tonic-gate char dbgfname[20];
50*7c478bd9Sstevel@tonic-gate FILE *dbgfp;
51*7c478bd9Sstevel@tonic-gate char dead[] = "/dead.letter"; /* name of dead.letter */
52*7c478bd9Sstevel@tonic-gate int debug; /* Controls debugging level. 0 ==> no debugging */
53*7c478bd9Sstevel@tonic-gate int delflg = 1;
54*7c478bd9Sstevel@tonic-gate int dflag = 0; /* 1 says returning unsendable mail */
55*7c478bd9Sstevel@tonic-gate char *errlist[]= {
56*7c478bd9Sstevel@tonic-gate "",
57*7c478bd9Sstevel@tonic-gate "Unknown system",
58*7c478bd9Sstevel@tonic-gate "Problem with mailfile",
59*7c478bd9Sstevel@tonic-gate "Space problem",
60*7c478bd9Sstevel@tonic-gate "Unable to forward mail, check permissions and group",
61*7c478bd9Sstevel@tonic-gate "Syntax error",
62*7c478bd9Sstevel@tonic-gate "Forwarding loop",
63*7c478bd9Sstevel@tonic-gate "Invalid sender",
64*7c478bd9Sstevel@tonic-gate "Invalid recipient",
65*7c478bd9Sstevel@tonic-gate "Too many From lines",
66*7c478bd9Sstevel@tonic-gate "Invalid permissions",
67*7c478bd9Sstevel@tonic-gate "Cannot open mbox",
68*7c478bd9Sstevel@tonic-gate "Temporary file problem",
69*7c478bd9Sstevel@tonic-gate "Cannot create dead.letter",
70*7c478bd9Sstevel@tonic-gate "Unbounded forwarding",
71*7c478bd9Sstevel@tonic-gate "Cannot create lock file",
72*7c478bd9Sstevel@tonic-gate "No group id of 'mail'",
73*7c478bd9Sstevel@tonic-gate "Problem allocating memory",
74*7c478bd9Sstevel@tonic-gate "Could not fork",
75*7c478bd9Sstevel@tonic-gate "Cannot pipe",
76*7c478bd9Sstevel@tonic-gate "Must be owner to modify mailfile",
77*7c478bd9Sstevel@tonic-gate "Permission denied by /etc/mail/mailsurr file",
78*7c478bd9Sstevel@tonic-gate "Surrogate command failed"
79*7c478bd9Sstevel@tonic-gate };
80*7c478bd9Sstevel@tonic-gate int error = 0; /* Local value for error */
81*7c478bd9Sstevel@tonic-gate char *failsafe; /* $FAILSAFE */
82*7c478bd9Sstevel@tonic-gate int file_size;
83*7c478bd9Sstevel@tonic-gate int flge = 0; /* 1 ==> 'e' option specified */
84*7c478bd9Sstevel@tonic-gate int flgE = 0; /* 1 ==> 'E' option specified */
85*7c478bd9Sstevel@tonic-gate int flgF = 0; /* 1 ==> Installing/Removing Forwarding */
86*7c478bd9Sstevel@tonic-gate int flgf = 0; /* 1 ==> 'f' option specified */
87*7c478bd9Sstevel@tonic-gate int flgh = 0; /* 1 ==> 'h' option specified */
88*7c478bd9Sstevel@tonic-gate int flgm;
89*7c478bd9Sstevel@tonic-gate int flgp = 0; /* 1 ==> 'p' option specified */
90*7c478bd9Sstevel@tonic-gate int flgP = 0; /* 1 ==> 'P' option specified */
91*7c478bd9Sstevel@tonic-gate int flgr = 0; /* 1 ==> 'r' option -- print in fifo order */
92*7c478bd9Sstevel@tonic-gate int flgt = 0; /* 1 ==> 't' option -- add To: line to letter */
93*7c478bd9Sstevel@tonic-gate int flgT = 0; /* 1 ==> 'T' option specified */
94*7c478bd9Sstevel@tonic-gate int flgw = 0; /* 1 ==> 'w' option specified */
95*7c478bd9Sstevel@tonic-gate int fnuhdrtype = 0; /* type of first non-UNIX header line */
96*7c478bd9Sstevel@tonic-gate char forwmsg[] = " forwarded by %s\n";
97*7c478bd9Sstevel@tonic-gate char fromS[1024]; /* stored here by sendmail for sendsurg */
98*7c478bd9Sstevel@tonic-gate char fromU[1024]; /* stored here by sendmail for sendsurg */
99*7c478bd9Sstevel@tonic-gate char frwlmsg[] = " %s: Forwarding loop detected in %s's mailfile.\n";
100*7c478bd9Sstevel@tonic-gate char frwrd[] = "Forward to "; /* forwarding sentinel */
101*7c478bd9Sstevel@tonic-gate char fwdFrom[1024];
102*7c478bd9Sstevel@tonic-gate int goerr = 0; /* counts parsing errors */
103*7c478bd9Sstevel@tonic-gate struct group *grpptr; /* pointer to struct group */
104*7c478bd9Sstevel@tonic-gate struct hdrlines hdrlines[H_CONT];
105*7c478bd9Sstevel@tonic-gate /* Default_display indicates whether to display this header line to the TTY */
106*7c478bd9Sstevel@tonic-gate /* when in default mode. Can be overridden via 'P' command at ? prompt */
107*7c478bd9Sstevel@tonic-gate struct hdr header[] = {
108*7c478bd9Sstevel@tonic-gate "", FALSE,
109*7c478bd9Sstevel@tonic-gate "Auto-Forward-Count:", FALSE,
110*7c478bd9Sstevel@tonic-gate "Auto-Forwarded-From:", FALSE,
111*7c478bd9Sstevel@tonic-gate "Content-Length:", TRUE,
112*7c478bd9Sstevel@tonic-gate "Content-Type:", FALSE,
113*7c478bd9Sstevel@tonic-gate "Date:", TRUE,
114*7c478bd9Sstevel@tonic-gate "Default-Options:", FALSE,
115*7c478bd9Sstevel@tonic-gate "End-of-Header:", FALSE,
116*7c478bd9Sstevel@tonic-gate "From ", TRUE,
117*7c478bd9Sstevel@tonic-gate ">From ", TRUE,
118*7c478bd9Sstevel@tonic-gate "From:", TRUE,
119*7c478bd9Sstevel@tonic-gate "MIME-Version:", FALSE,
120*7c478bd9Sstevel@tonic-gate "MTS-Message-ID:", FALSE,
121*7c478bd9Sstevel@tonic-gate "Message-Type:", FALSE,
122*7c478bd9Sstevel@tonic-gate "Message-Version:", FALSE,
123*7c478bd9Sstevel@tonic-gate "Message-Service:", TRUE,
124*7c478bd9Sstevel@tonic-gate "Received:", FALSE,
125*7c478bd9Sstevel@tonic-gate "Report-Version:", FALSE,
126*7c478bd9Sstevel@tonic-gate "Subject:", TRUE,
127*7c478bd9Sstevel@tonic-gate "To:", TRUE,
128*7c478bd9Sstevel@tonic-gate ">To:", FALSE,
129*7c478bd9Sstevel@tonic-gate "Transport-Options:", FALSE,
130*7c478bd9Sstevel@tonic-gate "UA-Content-ID:", FALSE,
131*7c478bd9Sstevel@tonic-gate
132*7c478bd9Sstevel@tonic-gate /*Dummy place holders for H_DAFWDFROM,*/
133*7c478bd9Sstevel@tonic-gate /*H_DTCOPY and H_RECEIVED. Should */
134*7c478bd9Sstevel@tonic-gate /* match above first...*/
135*7c478bd9Sstevel@tonic-gate "Hold-Auto-Forwarded-From:", FALSE,
136*7c478bd9Sstevel@tonic-gate "Hold->To:", FALSE,
137*7c478bd9Sstevel@tonic-gate "Hold-Received:", FALSE,
138*7c478bd9Sstevel@tonic-gate "Continue:", FALSE,
139*7c478bd9Sstevel@tonic-gate "Name-Value:", FALSE,
140*7c478bd9Sstevel@tonic-gate };
141*7c478bd9Sstevel@tonic-gate char *help[] = {
142*7c478bd9Sstevel@tonic-gate "?\t\tprint this help message\n",
143*7c478bd9Sstevel@tonic-gate "#\t\tdisplay message number #\n",
144*7c478bd9Sstevel@tonic-gate "-\t\tprint previous\n",
145*7c478bd9Sstevel@tonic-gate "+\t\tnext (no delete)\n",
146*7c478bd9Sstevel@tonic-gate "! cmd\t\texecute cmd\n",
147*7c478bd9Sstevel@tonic-gate "<CR>\t\tnext (no delete)\n",
148*7c478bd9Sstevel@tonic-gate "a\t\tposition at and read newly arrived mail\n",
149*7c478bd9Sstevel@tonic-gate "d [#]\t\tdelete message # (default current message)\n",
150*7c478bd9Sstevel@tonic-gate "dp\t\tdelete current message and print the next\n",
151*7c478bd9Sstevel@tonic-gate "dq\t\tdelete current message and exit\n",
152*7c478bd9Sstevel@tonic-gate "h a\t\tdisplay all headers\n",
153*7c478bd9Sstevel@tonic-gate "h d\t\tdisplay headers of letters scheduled for deletion\n",
154*7c478bd9Sstevel@tonic-gate "h [#]\t\tdisplay headers around # (default current message)\n",
155*7c478bd9Sstevel@tonic-gate "m user \tmail (and delete) current message to user\n",
156*7c478bd9Sstevel@tonic-gate "n\t\tnext (no delete)\n",
157*7c478bd9Sstevel@tonic-gate "p\t\tprint (override any warnings of binary content)\n",
158*7c478bd9Sstevel@tonic-gate "P\t\toverride default 'brief' mode and display ALL header lines\n",
159*7c478bd9Sstevel@tonic-gate "q, ^D\t\tquit\n",
160*7c478bd9Sstevel@tonic-gate "r [args]\treply to (and delete) current letter via mail [args]\n",
161*7c478bd9Sstevel@tonic-gate "s [files]\tsave (and delete) current message (default mbox)\n",
162*7c478bd9Sstevel@tonic-gate "u [#]\t\tundelete message # (default current message)\n",
163*7c478bd9Sstevel@tonic-gate "w [files]\tsave (and delete) current message without header\n",
164*7c478bd9Sstevel@tonic-gate "x\t\texit without changing mail\n",
165*7c478bd9Sstevel@tonic-gate "y [files]\tsave (and delete) current message (default mbox)\n",
166*7c478bd9Sstevel@tonic-gate 0
167*7c478bd9Sstevel@tonic-gate };
168*7c478bd9Sstevel@tonic-gate char *hmbox; /* pointer to $HOME/mbox */
169*7c478bd9Sstevel@tonic-gate char *hmdead; /* pointer to $HOME/dead.letter */
170*7c478bd9Sstevel@tonic-gate char *home; /* pointer to $HOME */
171*7c478bd9Sstevel@tonic-gate time_t iop;
172*7c478bd9Sstevel@tonic-gate int interactive = 0; /* 1 says user is interactive */
173*7c478bd9Sstevel@tonic-gate int ismail = TRUE; /* default to program=mail */
174*7c478bd9Sstevel@tonic-gate int deliverflag = FALSE; /* -d flag, skip sendmail
175*7c478bd9Sstevel@tonic-gate * deliver directly to mailbox
176*7c478bd9Sstevel@tonic-gate */
177*7c478bd9Sstevel@tonic-gate int fromflag = FALSE; /* -f from_user, set a user
178*7c478bd9Sstevel@tonic-gate * when going into a mailbox
179*7c478bd9Sstevel@tonic-gate */
180*7c478bd9Sstevel@tonic-gate int keepdbgfile;
181*7c478bd9Sstevel@tonic-gate struct let let[MAXLET];
182*7c478bd9Sstevel@tonic-gate char *lettmp; /* pointer to tmp filename */
183*7c478bd9Sstevel@tonic-gate char lfil[MAXFILENAME];
184*7c478bd9Sstevel@tonic-gate char line[LSIZE]; /* holds a line of a letter in many places */
185*7c478bd9Sstevel@tonic-gate char *mailfile; /* pointer to mailfile */
186*7c478bd9Sstevel@tonic-gate char mailcnfg[] = MAILCNFG; /* configuration file */
187*7c478bd9Sstevel@tonic-gate char maildir[] = MAILDIR; /* directory for mail files */
188*7c478bd9Sstevel@tonic-gate gid_t mailgrp; /* numeric id of group 'mail' */
189*7c478bd9Sstevel@tonic-gate char mailsave[] = SAVEDIR; /* dir for save files */
190*7c478bd9Sstevel@tonic-gate char *mailsurr = MAILSURR; /* surrogate file name */
191*7c478bd9Sstevel@tonic-gate FILE *malf; /* File pointer for mailfile */
192*7c478bd9Sstevel@tonic-gate int maxerr = 0; /* largest value of error */
193*7c478bd9Sstevel@tonic-gate char mbox[] = "/mbox"; /* name for mbox */
194*7c478bd9Sstevel@tonic-gate uid_t mf_uid; /* uid of users mailfile */
195*7c478bd9Sstevel@tonic-gate gid_t mf_gid; /* gid of users mailfile */
196*7c478bd9Sstevel@tonic-gate char *msgtype;
197*7c478bd9Sstevel@tonic-gate char my_name[1024]; /* user's name who invoked this command */
198*7c478bd9Sstevel@tonic-gate char from_user[1024]; /* user's name specified w/ -f when sending */
199*7c478bd9Sstevel@tonic-gate uid_t my_euid; /* user's euid */
200*7c478bd9Sstevel@tonic-gate gid_t my_egid; /* user's egid */
201*7c478bd9Sstevel@tonic-gate uid_t my_uid; /* user's uid */
202*7c478bd9Sstevel@tonic-gate gid_t my_gid; /* user's gid */
203*7c478bd9Sstevel@tonic-gate int nlet = 0; /* current number of letters in mailfile */
204*7c478bd9Sstevel@tonic-gate int onlet = 0; /* number of letters in mailfile at startup*/
205*7c478bd9Sstevel@tonic-gate int optcnt = 0; /* Number of options specified */
206*7c478bd9Sstevel@tonic-gate int orig_aff = 0; /* orig. msg. contained H_AFWDFROM lines */
207*7c478bd9Sstevel@tonic-gate int orig_dbglvl; /* argument to -x invocation option */
208*7c478bd9Sstevel@tonic-gate int orig_rcv = 0; /* orig. msg. contained H_RECEIVED lines */
209*7c478bd9Sstevel@tonic-gate int orig_tcopy = 0; /* orig. msg. contained H_TCOPY lines */
210*7c478bd9Sstevel@tonic-gate struct passwd *pwd; /* holds passwd entry for this user */
211*7c478bd9Sstevel@tonic-gate int pflg = 0; /* binary message display override flag */
212*7c478bd9Sstevel@tonic-gate int Pflg = 0; /* Selective display flag; 1 ==> display all */
213*7c478bd9Sstevel@tonic-gate char *program; /* program name */
214*7c478bd9Sstevel@tonic-gate int rcvbytecnt; /* Total bytes of Received: info in msg. */
215*7c478bd9Sstevel@tonic-gate int Drcvbytecnt; /* Hold rcvbytecnt when sending Delivery Notification */
216*7c478bd9Sstevel@tonic-gate char *recipname; /* full recipient name/address */
217*7c478bd9Sstevel@tonic-gate int replying = 0; /* 1 says we are replying to a letter */
218*7c478bd9Sstevel@tonic-gate char RFC822datestring[60];/* Date in RFC822 date format */
219*7c478bd9Sstevel@tonic-gate char Rpath[1024]; /* return path to sender of message */
220*7c478bd9Sstevel@tonic-gate char rmtmsg[] = " remote from %s\n";
221*7c478bd9Sstevel@tonic-gate char rtrnmsg[] = "***** UNDELIVERABLE MAIL sent to %s, being returned by %s *****\n";
222*7c478bd9Sstevel@tonic-gate int sav_errno;
223*7c478bd9Sstevel@tonic-gate char savefile[MAXFILENAME]; /* holds filename of save file */
224*7c478bd9Sstevel@tonic-gate void (*saveint)();
225*7c478bd9Sstevel@tonic-gate /* Any header line prefixes listed here WILL be displayed in default mode */
226*7c478bd9Sstevel@tonic-gate /* If it's not here, it won't be shown. Can be overridden via 'P' command */
227*7c478bd9Sstevel@tonic-gate /* at ? prompt */
228*7c478bd9Sstevel@tonic-gate char *seldisp[] = {
229*7c478bd9Sstevel@tonic-gate "Cc:",
230*7c478bd9Sstevel@tonic-gate "Bcc:",
231*7c478bd9Sstevel@tonic-gate "Paper-",
232*7c478bd9Sstevel@tonic-gate "Phone:",
233*7c478bd9Sstevel@tonic-gate "Message-",
234*7c478bd9Sstevel@tonic-gate "Original-",
235*7c478bd9Sstevel@tonic-gate "Confirming-",
236*7c478bd9Sstevel@tonic-gate "Delivered-",
237*7c478bd9Sstevel@tonic-gate "Deliverable-",
238*7c478bd9Sstevel@tonic-gate "Not-",
239*7c478bd9Sstevel@tonic-gate "En-Route-To:",
240*7c478bd9Sstevel@tonic-gate 0
241*7c478bd9Sstevel@tonic-gate };
242*7c478bd9Sstevel@tonic-gate int sending; /* TRUE==>sending mail; FALSE==>printing mail */
243*7c478bd9Sstevel@tonic-gate char m_sendto[1024];
244*7c478bd9Sstevel@tonic-gate jmp_buf sjbuf;
245*7c478bd9Sstevel@tonic-gate int surg_rc = 0; /* exit code of surrogate command */
246*7c478bd9Sstevel@tonic-gate int surr_len = 0;
247*7c478bd9Sstevel@tonic-gate char *SURRcmdstr = (char *)NULL; /* save in case of FAILURE */
248*7c478bd9Sstevel@tonic-gate FILE *SURRerrfile; /* stderr from surrogate in case of FAILURE */
249*7c478bd9Sstevel@tonic-gate char *thissys; /* Holds name of the system we are on */
250*7c478bd9Sstevel@tonic-gate FILE *tmpf; /* file pointer for temporary files */
251*7c478bd9Sstevel@tonic-gate mode_t umsave;
252*7c478bd9Sstevel@tonic-gate struct utsname utsn;
253*7c478bd9Sstevel@tonic-gate static struct utimbuf utims;
254*7c478bd9Sstevel@tonic-gate struct utimbuf *utimep = &utims;
255*7c478bd9Sstevel@tonic-gate char uval[1024];
256*7c478bd9Sstevel@tonic-gate
init()257*7c478bd9Sstevel@tonic-gate int init()
258*7c478bd9Sstevel@tonic-gate {
259*7c478bd9Sstevel@tonic-gate utims.actime = utims.modtime = -1;
260*7c478bd9Sstevel@tonic-gate return (xsetenv(mailcnfg));
261*7c478bd9Sstevel@tonic-gate }
262