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
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.
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]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI"
40 static char pn
[] = "printmail";
41 int flg
, curlet
, showlet
, k
, print
, aret
, stret
, rc
;
42 int nsmbox
= 0; /* 1 ==> mailbox is in non-standard place */
47 int ttyf
= isatty(1) ? TTY
: ORDINARY
;
48 char readbuf
[LSIZE
]; /* holds user's response in interactive mode */
55 * create working directory mbox name
57 if ((hmbox
= malloc(strlen(home
) + strlen(mbox
) + 1)) == NULL
) {
61 cat(hmbox
, home
, mbox
);
64 * If we are not using an alternate mailfile, then get
65 * the $MAIL value and build the filename for the mailfile.
66 * If $MAIL is set, but is NOT the 'standard' place, then
67 * use it but set flgf to circumvent :saved processing.
70 if ((p
= malloc(strlen(maildir
) + strlen(my_name
) + 1))
75 cat(p
, maildir
, my_name
);
76 if (((mailfile
= getenv("MAIL")) == NULL
) ||
77 (strlen(mailfile
) == 0)) {
78 /* $MAIL not set, use standard path to mailfile */
81 if (strcmp(mailfile
, p
) != 0) {
84 Dout(pn
, 0, "$MAIL ('%s') != standard path\n",
86 Dout("", 0, "\tSetting flgf to 1.\n");
93 * Get ACCESS and MODIFICATION times of mailfile BEFORE we
94 * use it. This allows us to put them back when we are
95 * done. If we didn't, the shell would think NEW mail had
96 * arrived since the file times would have changed.
99 if (access(mailfile
, A_EXIST
) == A_OK
) {
100 if ((stret
= stat(mailfile
, stbufp
)) != A_OK
) {
101 errmsg(E_FILE
, "Cannot stat mailfile");
104 mf_gid
= stbufp
->st_gid
;
105 mf_uid
= stbufp
->st_uid
;
106 utimep
->actime
= stbufp
->st_atime
;
107 utimep
->modtime
= stbufp
->st_mtime
;
108 file_size
= stbufp
->st_size
;
111 /* Open the file as the real gid */
112 savedegid
= getegid();
113 (void) setegid(getgid());
114 malf
= fopen(mailfile
, "r");
115 (void) setegid(savedegid
);
117 * stat succeeded, but we cannot access the mailfile
119 if (stret
== CSUCCESS
&& malf
== NULL
) {
120 char buf
[MAXFILENAME
+50];
121 (void) snprintf(buf
, sizeof (buf
),
122 "Invalid permissions on %s", mailfile
);
127 * using an alternate mailfile, but we failed on access
129 if (!nsmbox
&& flgf
&& (malf
== NULL
)) {
130 errmsg(E_FILE
, "Cannot open mailfile");
134 * we failed to access OR the file is empty
136 else if ((malf
== NULL
) || (stbuf
.st_size
== 0)) {
137 if (!flge
&& !flgE
) {
138 printf("No mail.\n");
141 Dout(pn
, 0, "error set to %d\n", error
);
148 if (utimep
->modtime
< utimep
->actime
) {
150 Dout(pn
, 0, "error set to %d\n", error
);
155 * Secure the mailfile to guarantee integrity
160 * copy mail to temp file and mark each letter in the
161 * let array --- mailfile is still locked !!!
168 unlock(); /* All done, OK to unlock now */
169 tmpf
= doopen(lettmp
, "r+", E_TMP
);
173 while (curlet
< nlet
) {
177 showlet
= flgr
? curlet
: nlet
- curlet
- 1;
179 if (setjmp(sjbuf
) == 0 && print
!= 0) {
180 /* -h says to print the headers first */
183 flgh
= 0; /* Only once */
184 /* set letter # to invalid # */
187 flgr
? curlet
: nlet
- curlet
- 1;
189 if (showlet
!= sav_j
) {
190 /* Looking at new message. */
191 /* Reset flag to override */
192 /* non-display of binary */
198 copylet(showlet
, stdout
, ttyf
);
214 stat(mailfile
, stbufp
);
215 if (stbufp
->st_size
!= file_size
) {
217 * New mail has arrived, load it
221 malf
= doopen(mailfile
, "r", E_FILE
);
223 tmpf
= doopen(lettmp
, "a", E_TMP
);
224 fseek(malf
, let
[nlet
].adr
, 0);
226 file_size
= stbufp
->st_size
;
230 tmpf
= doopen(lettmp
, "r+", E_TMP
);
232 printf("New mail loaded into letters %d - %d\n",
235 printf("New mail loaded into letter %d\n",
239 /* read the command */
243 if (fgets(readbuf
, sizeof (readbuf
), stdin
) == NULL
) break;
245 while (*resp
== ' ' || *resp
== '\t') resp
++;
247 Dout(pn
, 0, "resp = '%s'\n", resp
);
248 if ((rc
= atoi(resp
)) != 0) {
249 if (!validmsg(rc
)) print
= 0;
250 else curlet
= flgr
? rc
- 1 : nlet
- rc
;
251 } else switch (resp
[0]) {
259 for (rc
= 0; help
[rc
]; rc
++)
260 printf("%s", help
[rc
]);
263 * print message number of current message
267 if ((showlet
== nlet
) || (showlet
< 0)) {
268 printf("No message selected yet.\n");
270 printf("Current message number is %d\n",
279 if (resp
[2] != 'd' &&
281 (rc
= getnumbr(resp
+1)) > 0) {
283 curlet
= flgr
? rc
- 1 : nlet
- rc
- 1;
285 if (rc
== -1 && resp
[2] != 'a' &&
288 if (resp
[2] == 'a') rc
= 1;
289 else if (resp
[2] == 'd') rc
= 2;
293 * if (!validmsg(showlet)) break;
295 gethead(showlet
, rc
);
320 if (--curlet
< 0) curlet
= 0;
323 * Save in file without header
328 * Save mail with header
332 if (!validmsg(curlet
)) break;
333 if (resp
[1] == '\n' || resp
[1] == '\0') {
334 cat(resp
+1, hmbox
, "");
335 } else if (resp
[1] != ' ') {
336 printf("Invalid command\n");
341 if (getarg(lfil
, resp
+ 1) == NULL
) {
342 cat(resp
+ 1, hmbox
, "");
346 while ((p
= getarg(lfil
, p
)) != NULL
) {
349 "%s: File '%s' skipped\n",
354 if ((aret
= legal(lfil
))) {
355 malf
= fopen(lfil
, "a");
357 if ((malf
== NULL
) || (aret
== 0)) {
359 "%s: Cannot append to %s\n",
362 } else if (aret
== 2) {
363 chown(lfil
, my_euid
, my_gid
);
366 copylet(showlet
, malf
, resp
[0] ==
367 's'? ORDINARY
: ZAP
) == FALSE
) {
369 "%s: Cannot save mail to '%s'\n",
373 Dout(pn
, 0, "!saved\n");
380 setletr(showlet
, resp
[0]);
390 if (!validmsg(curlet
)) break;
392 for (k
= 1; resp
[k
] == ' ' || resp
[k
] == '\t';
394 resp
[strlen(resp
)-1] = '\0';
395 (void) strlcpy(m_sendto
, resp
+k
,
399 setletr(showlet
, resp
[0]);
406 if ((k
= getnumbr(resp
+1)) <= 0) k
= showlet
;
408 if (!validmsg(k
)) break;
412 * Mail letter to someone else
418 if (!validmsg(curlet
)) break;
419 new_reciplist(&list
);
422 if (substr(resp
, " -") != -1 ||
423 substr(resp
, "\t-") != -1) {
424 printf("Only users may be specified\n");
428 while ((p
= getarg(lfil
, p
)) != NULL
) {
430 if (lfil
[0] == '$') {
431 if (!(env
= getenv(&lfil
[1]))) {
433 "%s: %s has no value or is not exported.\n",
437 add_recip(&list
, env
,
440 } else if (lfil
[0] != '\0') {
441 add_recip(&list
, lfil
, FALSE
);
445 (void) strlcpy(Rpath
, my_name
, sizeof (Rpath
));
447 flg
+= sendlist(&list
, showlet
, 0);
451 setletr(showlet
, 'm');
456 printf("Invalid command\n");
457 del_reciplist(&list
);
465 printf("No new mail\n");
486 if (strncmp("dq", resp
, 2) != SAME
&&
487 strncmp("dp", resp
, 2) != SAME
)
488 if ((k
= getnumbr(resp
+1)) == -1) break;
491 if (!validmsg(curlet
)) break;
497 if (resp
[1] == 'p') print
= 1;
498 else if (resp
[1] == 'q') goto donep
;
503 * Copy updated mailfile back