dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / mail / main.c
blob27d3c2656307cccdedc791cec87f840b55282cf7
1 /*
2 * CDDL HEADER START
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
7 * with the License.
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]
20 * CDDL HEADER END
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"
32 #include "mail.h"
33 #ifdef SVR4
34 #include <locale.h>
35 #endif
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
42 int
43 main(int argc, char **argv)
45 register int i;
46 char *cptr, *p;
47 struct stat statb;
48 static char pn[] = "main";
49 extern char **environ;
50 int env_var_idx, next_slot_idx;
51 int tmpfd = -1;
53 #ifdef SVR4
54 (void) setlocale(LC_ALL, "");
55 #endif
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)) {
62 next_slot_idx++;
64 env_var_idx++;
66 environ[next_slot_idx] = NULL;
68 #ifdef SIGCONT
69 #ifdef SVR4
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);
77 #else
78 sigset(SIGCONT, SIG_DFL);
79 #endif
80 #endif
83 * Strip off path name of this command for use in messages
85 if ((program = strrchr(argv[0], '/')) != NULL) {
86 program++;
87 } else {
88 program = argv[0];
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) {
98 errmsg(E_GROUP, "");
99 exit(1);
100 } else {
101 mailgrp = grpptr->gr_gid;
105 * Save the *id for later use.
107 my_uid = getuid();
108 my_gid = getgid();
109 my_euid = geteuid();
110 my_egid = getegid();
113 * What command (rmail or mail)?
115 if (strcmp(program, "rmail") == SAME) {
116 ismail = FALSE;
120 * Parse the command line and adjust argc and argv
121 * to compensate for any options
123 i = parse(argc, argv);
124 argv += (i - 1);
125 argc -= (i - 1);
127 /* block a potential security hole */
128 if (flgT && (my_euid != 0)) {
129 setgid(my_gid);
130 Tout(pn, "Setgid unset\n");
133 if (debug == 0) {
134 /* If not set as an invocation option, check for system-wide */
135 /* global flag */
136 char *xp = xgetenv("DEBUG");
137 if (xp != NULL) {
138 debug = atoi(xp);
139 if (debug < 0) {
140 /* Keep trace file even if successful */
141 keepdbgfile = -1;
142 debug = -debug;
146 if (debug > 0) {
147 strcpy(dbgfname, "/tmp/MLDBGXXXXXX");
148 if ((tmpfd = mkstemp(dbgfname)) == -1) {
149 fprintf(stderr, "%s: can't open debugging file '%s'\n",
150 program, dbgfname);
151 exit(13);
153 if ((dbgfp = fdopen(tmpfd, "w")) == NULL) {
154 fprintf(stderr, "%s: can't open debugging file '%s'\n",
155 program, dbgfname);
156 (void) close(tmpfd);
157 exit(13);
159 setbuf(dbgfp, NULL);
160 fprintf(dbgfp, "main(): debugging level == %d\n", debug);
161 fprintf(dbgfp, "main(): trace file ='%s': kept %s\n", dbgfname,
162 ((keepdbgfile < 0) ?
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);
168 if (goerr > 0) {
169 errmsg(E_SYNTAX, "Usage: rmail [-wt] person(s)");
171 if (!i) {
172 errmsg(E_SYNTAX, "At least one user must be specified");
174 Dout(pn, 11, "exiting!\n");
175 done(0);
178 umsave = umask(7);
179 uname(&utsn);
180 if ((p = xgetenv("CLUSTER")) != NULL) {
182 * We are not who we appear...
184 thissys = p;
185 } else {
186 thissys = utsn.nodename;
188 Dout(pn, 11, "thissys = '%s', uname = '%s'\n", thissys, utsn.nodename);
190 failsafe = xgetenv("FAILSAFE");
191 if (failsafe)
192 Dout(pn, 11, "failsafe processing enabled to %s\n", failsafe);
195 * Use environment variables
197 home = getenv("HOME");
198 if (!home || !*home) {
199 home = ".";
202 my_name[0] = '\0';
203 pwd = getpwuid(my_uid);
204 if (pwd)
205 (void) strlcpy(my_name, pwd->pw_name, sizeof (my_name));
207 /* If root, use LOGNAME if set */
208 if (my_uid == 0) {
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
220 if (setjmp(sjbuf)) {
221 done(0);
223 for (i = SIGINT; i < SIGCLD; i++) {
224 setsig(i, delete);
226 setsig(SIGHUP, sig_done);
227 setsig(SIGTERM, sig_done);
229 cksaved(my_name);
232 * Rmail is always invoked to send mail
234 Dout(pn, 11, "ismail=%d, argc=%d\n", ismail, argc);
235 if (ismail && (argc == 1)) {
236 sending = FALSE;
237 printmail();
239 } else {
240 sending = TRUE;
241 sendmail(argc, argv);
243 done(0);