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]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
37 * mail [ -ehpPqrtw ] [-x debuglevel] [ -f file ] [ -F user(s) ]
38 * mail -T file persons
39 * mail [ -tw ] [ -m messagetype ] persons
40 * rmail [ -tw ] persons
43 main(int argc
, char **argv
)
48 static char pn
[] = "main";
49 extern char **environ
;
50 int env_var_idx
, next_slot_idx
;
54 (void) setlocale(LC_ALL
, "");
56 /* fix here for bug #1086130 - security hole */
57 /* skip over the LD_* env variable */
58 env_var_idx
= 0; next_slot_idx
= 0;
59 while (environ
[env_var_idx
] != NULL
) {
60 environ
[next_slot_idx
] = environ
[env_var_idx
];
61 if (strncmp(environ
[env_var_idx
], "LD_", 3)) {
66 environ
[next_slot_idx
] = NULL
;
71 struct sigaction nsig
;
72 nsig
.sa_handler
= SIG_IGN
;
73 (void) sigaction(SIGPIPE
, &nsig
, NULL
);
75 nsig
.sa_handler
= SIG_DFL
;
76 sigemptyset(&nsig
.sa_mask
);
77 nsig
.sa_flags
= SA_RESTART
;
78 (void) sigaction(SIGCONT
, &nsig
, NULL
);
81 sigset(SIGCONT
, SIG_DFL
);
86 * Strip off path name of this command for use in messages
88 if ((program
= strrchr(argv
[0], '/')) != NULL
) {
94 /* Close all file descriptors except stdin, stdout & stderr */
95 closefrom(STDERR_FILENO
+ 1);
98 * Get group id for mail, exit if none exists
100 if ((grpptr
= getgrnam("mail")) == NULL
) {
104 mailgrp
= grpptr
->gr_gid
;
108 * Save the *id for later use.
116 * What command (rmail or mail)?
118 if (strcmp(program
, "rmail") == SAME
) {
123 * Parse the command line and adjust argc and argv
124 * to compensate for any options
126 i
= parse(argc
, argv
);
130 /* block a potential security hole */
131 if (flgT
&& (my_euid
!= 0)) {
133 Tout(pn
, "Setgid unset\n");
137 /* If not set as an invocation option, check for system-wide */
139 char *xp
= xgetenv("DEBUG");
143 /* Keep trace file even if successful */
150 strcpy(dbgfname
, "/tmp/MLDBGXXXXXX");
151 if ((tmpfd
= mkstemp(dbgfname
)) == -1) {
152 fprintf(stderr
, "%s: can't open debugging file '%s'\n",
156 if ((dbgfp
= fdopen(tmpfd
, "w")) == NULL
) {
157 fprintf(stderr
, "%s: can't open debugging file '%s'\n",
163 fprintf(dbgfp
, "main(): debugging level == %d\n", debug
);
164 fprintf(dbgfp
, "main(): trace file ='%s': kept %s\n", dbgfname
,
166 "on success or failure." : "only on failure."));
169 if (!ismail
&& (goerr
> 0 || !i
)) {
170 Dout(pn
, 11, "!ismail, goerr=%d, i=%d\n", goerr
, i
);
172 errmsg(E_SYNTAX
, "Usage: rmail [-wt] person(s)");
175 errmsg(E_SYNTAX
, "At least one user must be specified");
177 Dout(pn
, 11, "exiting!\n");
183 if ((p
= xgetenv("CLUSTER")) != NULL
) {
185 * We are not who we appear...
189 thissys
= utsn
.nodename
;
191 Dout(pn
, 11, "thissys = '%s', uname = '%s'\n", thissys
, utsn
.nodename
);
193 failsafe
= xgetenv("FAILSAFE");
195 Dout(pn
, 11, "failsafe processing enabled to %s\n", failsafe
);
198 * Use environment variables
200 home
= getenv("HOME");
201 if (!home
|| !*home
) {
206 pwd
= getpwuid(my_uid
);
208 (void) strlcpy(my_name
, pwd
->pw_name
, sizeof (my_name
));
210 /* If root, use LOGNAME if set */
212 /* If root, use LOGNAME if set */
213 if (((cptr
= getenv("LOGNAME")) != NULL
) &&
214 (strlen(cptr
) != 0)) {
215 (void) strlcpy(my_name
, cptr
, sizeof (my_name
));
218 Dout(pn
, 11, "my_name = '%s'\n", my_name
);
221 * Catch signals for cleanup
226 for (i
= SIGINT
; i
< SIGCLD
; i
++) {
229 setsig(SIGHUP
, sig_done
);
230 setsig(SIGTERM
, sig_done
);
235 * Rmail is always invoked to send mail
237 Dout(pn
, 11, "ismail=%d, argc=%d\n", ismail
, argc
);
238 if (ismail
&& (argc
== 1)) {
244 sendmail(argc
, argv
);