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_DFL
;
73 sigemptyset(&nsig
.sa_mask
);
74 nsig
.sa_flags
= SA_RESTART
;
75 (void) sigaction(SIGCONT
, &nsig
, NULL
);
78 sigset(SIGCONT
, SIG_DFL
);
83 * Strip off path name of this command for use in messages
85 if ((program
= strrchr(argv
[0], '/')) != NULL
) {
91 /* Close all file descriptors except stdin, stdout & stderr */
92 closefrom(STDERR_FILENO
+ 1);
95 * Get group id for mail, exit if none exists
97 if ((grpptr
= getgrnam("mail")) == NULL
) {
101 mailgrp
= grpptr
->gr_gid
;
105 * Save the *id for later use.
113 * What command (rmail or mail)?
115 if (strcmp(program
, "rmail") == SAME
) {
120 * Parse the command line and adjust argc and argv
121 * to compensate for any options
123 i
= parse(argc
, argv
);
127 /* block a potential security hole */
128 if (flgT
&& (my_euid
!= 0)) {
130 Tout(pn
, "Setgid unset\n");
134 /* If not set as an invocation option, check for system-wide */
136 char *xp
= xgetenv("DEBUG");
140 /* Keep trace file even if successful */
147 strcpy(dbgfname
, "/tmp/MLDBGXXXXXX");
148 if ((tmpfd
= mkstemp(dbgfname
)) == -1) {
149 fprintf(stderr
, "%s: can't open debugging file '%s'\n",
153 if ((dbgfp
= fdopen(tmpfd
, "w")) == NULL
) {
154 fprintf(stderr
, "%s: can't open debugging file '%s'\n",
160 fprintf(dbgfp
, "main(): debugging level == %d\n", debug
);
161 fprintf(dbgfp
, "main(): trace file ='%s': kept %s\n", dbgfname
,
163 "on success or failure." : "only on failure."));
166 if (!ismail
&& (goerr
> 0 || !i
)) {
167 Dout(pn
, 11, "!ismail, goerr=%d, i=%d\n", goerr
, i
);
169 errmsg(E_SYNTAX
, "Usage: rmail [-wt] person(s)");
172 errmsg(E_SYNTAX
, "At least one user must be specified");
174 Dout(pn
, 11, "exiting!\n");
180 if ((p
= xgetenv("CLUSTER")) != NULL
) {
182 * We are not who we appear...
186 thissys
= utsn
.nodename
;
188 Dout(pn
, 11, "thissys = '%s', uname = '%s'\n", thissys
, utsn
.nodename
);
190 failsafe
= xgetenv("FAILSAFE");
192 Dout(pn
, 11, "failsafe processing enabled to %s\n", failsafe
);
195 * Use environment variables
197 home
= getenv("HOME");
198 if (!home
|| !*home
) {
203 pwd
= getpwuid(my_uid
);
205 (void) strlcpy(my_name
, pwd
->pw_name
, sizeof (my_name
));
207 /* If root, use LOGNAME if set */
209 /* If root, use LOGNAME if set */
210 if (((cptr
= getenv("LOGNAME")) != NULL
) &&
211 (strlen(cptr
) != 0)) {
212 (void) strlcpy(my_name
, cptr
, sizeof (my_name
));
215 Dout(pn
, 11, "my_name = '%s'\n", my_name
);
218 * Catch signals for cleanup
223 for (i
= SIGINT
; i
< SIGCLD
; i
++) {
226 setsig(SIGHUP
, sig_done
);
227 setsig(SIGTERM
, sig_done
);
232 * Rmail is always invoked to send mail
234 Dout(pn
, 11, "ismail=%d, argc=%d\n", ismail
, argc
);
235 if (ismail
&& (argc
== 1)) {
241 sendmail(argc
, argv
);