4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright (c) 2016 by Delphix. All rights reserved.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
47 * mailx -- a modified version of a University of California at Berkeley
50 * Startup -- interface with user.
53 static void hdrstop(int);
55 static jmp_buf hdrjmp
;
57 const char *const version
= "mailx version 5.0";
60 * Find out who the user is, copy their mail file (if exists) into
61 * /tmp/Rxxxxx and set up the message pointers. Then, print out the
62 * message headers and read user commands.
64 * Command line syntax:
65 * mailx [ -i ] [ -r address ] [ -h number ] [ -f [ name ] ]
67 * mailx [ -i ] [ -r address ] [ -h number ] people ...
69 * and a bunch of other options.
73 main(int argc
, char **argv
)
77 int mustsend
, f
, goerr
= 0;
86 * Set up a reasonable environment.
87 * Figure out whether we are being run interactively, set up
88 * all the temporary files, buffer standard output, and so forth.
92 (void)setlocale(LC_ALL
, "");
94 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
95 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
97 (void) textdomain(TEXT_DOMAIN
);
100 sigset(SIGCONT
, SIG_DFL
);
102 rpterr
= 0; /* initialize; set when we output to stderr */
104 if (progname
[strlen(progname
) - 1] != 'x') {
105 assign("bsdcompat", "");
116 if (ioctl(1, TCGETS
, &tbufs
) < 0) {
117 if (ioctl(1, TCGETA
, &tbuf
)==0) {
119 baud
= tbuf
.c_cflag
& CBAUD
;
124 baud
= cfgetospeed(&tbufs
);
129 * Now, determine how we are being used.
130 * We successively pick off instances of -r, -h, -f, and -i.
131 * If called as "rmail" we note this fact for letter sending.
132 * If there is anything left, it is the base of the list
133 * of users to mail to. Argp will be set to point to the
134 * first of these users.
140 if (argc
> 0 && **argv
== 'r')
142 while ((c
= getopt(argc
, argv
, "b:Bc:defFh:HiInNr:s:u:UtT:vV~")) != EOF
)
153 * Next argument is address to be sent along
162 * Next argument is temp file to write which
163 * articles have been read/deleted for netnews.
166 if ((f
= creat(Tflag
, TEMPPERM
)) < 0) {
171 /* fall through for -I too */
176 * print newsgroup in header summary
183 * Next argument is person's mailbox to use.
184 * Treated the same as "-f /var/mail/user".
187 static char u
[PATHSIZE
];
188 snprintf(u
, sizeof (u
), "%s%s", maildir
, optarg
);
195 * User wants to ignore interrupts.
196 * Set the variable "ignore"
198 assign("ignore", "");
211 * Specified sequence number for network.
212 * This is the number of "hops" made so
213 * far (count of times message has been
214 * forwarded) to help avoid infinite mail loops.
217 hflag
= atoi(optarg
);
220 gettext("-h needs non-zero number\n"));
227 * Give a subject field for sending from
234 case 'c': /* Cc: from command line */
239 case 'b': /* Bcc: from command line */
246 * User is specifying file to "edit" with mailx,
247 * as opposed to reading system mailbox.
248 * If no argument is given after -f, we read their
249 * $MBOX file or mbox in their home directory.
251 ef
= (argc
== optind
|| *argv
[optind
] == '-')
252 ? "" : argv
[optind
++];
253 if (*ef
&& *ef
!= '/' && *ef
!= '+')
254 cwd
= getcwd(NOSTR
, PATHSIZE
);
264 * User doesn't want to source
272 * Avoid initial header printing.
279 * Print headers and exit
290 * Permit tildas no matter where
291 * the input is coming from.
293 assign("escapeok", "");
298 * Send mailer verbose flag
300 assign("verbose", "");
305 * Don't buffer output
306 * (Line buffered is good enough)
308 setvbuf(stdout
, NULL
, _IOLBF
, BUFSIZ
);
309 setvbuf(stderr
, NULL
, _IOLBF
, BUFSIZ
);
314 * Like sendmail -t, read headers from text
330 * Check for inconsistent arguments.
333 if (newsflg
&& ef
==NOSTR
) {
334 fprintf(stderr
, gettext("Need -f with -I flag\n"));
337 if (ef
!= NOSTR
&& argp
!= -1) {
339 gettext("Cannot give -f and people to send to.\n"));
342 if (exitflg
&& (mustsend
|| argp
!= -1))
343 exit(1); /* nonsense flags involving -e simply exit */
344 if (tflag
&& argp
!= -1) {
346 gettext("Ignoring recipients on command line with -t\n"));
348 } else if (!tflag
&& mustsend
&& argp
== -1) {
350 gettext("The flags you gave are used only when sending mail.\n"));
355 gettext("Usage: %s -eiIUdFntBNHvV~ -T FILE -u USER -h hops -r address\n"),
358 gettext("\t\t-s SUBJECT -f FILE users\n"));
363 rcvmode
= !tflag
&& argp
== -1;
368 load(Getf("MAILRC"));
373 exit(senderr
? senderr
: rpterr
);
377 * Ok, we are reading mail.
378 * Decide whether we are editing a mailbox or reading
379 * the system mailbox, and open up the right stuff.
381 * Do this before sourcing the MAILRC, because there might be
382 * a 'chdir' there that breaks the -f option. But if the
383 * file specified with -f is a folder name, go ahead and
384 * source the MAILRC anyway so that "folder" will be defined.
387 nstrcpy(origname
, PATHSIZE
, mailname
);
391 if (ef
== NOSTR
|| *ef
== '\0' || *ef
== '+') {
392 load(Getf("MAILRC"));
395 ef
= *ef
? safeexpand(ef
) : Getf("MBOX");
396 nstrcpy(origname
, PATHSIZE
, ef
);
399 cwd
= getcwd(NOSTR
, PATHSIZE
);
400 nstrcat(cwd
, PATHSIZE
, "/");
401 nstrcat(cwd
, PATHSIZE
, ef
);
408 if (setfile(editfile
, edit
) < 0)
412 load(Getf("MAILRC"));
413 if (msgCount
> 0 && !noheader
&& value("header") != NOSTR
) {
414 if (setjmp(hdrjmp
) == 0) {
415 if ((prevint
= sigset(SIGINT
, SIG_IGN
)) != SIG_IGN
)
416 sigset(SIGINT
, hdrstop
);
419 sigset(SIGINT
, prevint
);
422 if (Hflag
|| (!edit
&& msgCount
== 0)) {
424 fprintf(stderr
, gettext("No mail for %s\n"), myname
);
431 sigset(SIGHUP
, SIG_IGN
);
432 sigset(SIGINT
, SIG_IGN
);
433 sigset(SIGQUIT
, SIG_IGN
);
435 sigset(SIGPIPE
, SIG_IGN
);
446 * Interrupt printing of the headers.
458 fprintf(stderr
, gettext("\nInterrupt\n"));