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 */
29 #pragma ident "%Z%%M% %I% %E% SMI"
34 * sendlist - send copy to specified users
37 * int sendlist(reciplist *list, int letnum, int level)
40 * sendlist() will traverse the current recipient list and
41 * send a copy of the given letter to each user specified,
42 * invoking send() to do the sending. It returns
43 * 1 if the sending fails, 0 otherwise.
48 * mailx and mailtool read the SENDMAIL from an environment, since few
49 * people use /bin/mail as their user agent and since /bin/mail is often
50 * called as root or made setuid it's safer to leave this hardwired.
53 static char *sendmail_prog
= SENDMAIL
;
55 static void notifybiff(char *);
58 sendlist(reciplist
*list
, int letnum
, int level
)
63 int nargs
= 4; /* "sendmail", "-oi", "--", .. NULL */
67 /* Deliver mail directly to a mailbox */
70 * Note failure to deliver to any one of the recipients
71 * should be considered a failure, so that the user
72 * get's an indication of that failure.
74 for (to
= &(list
->recip_list
); to
; to
= to
->next
) {
76 if (!send_mbox(to
->name
, letnum
))
83 * build argv list, allowing for arbitrarily long deliver lists
84 * and then hand the message off to sendmail
88 nargs
+= 2; /* for "-f", "Rpath" */
90 for (to
= &(list
->recip_list
); to
; to
= to
->next
)
94 argv
= malloc(nargs
* sizeof (char *));
101 *p
++ = sendmail_prog
;
103 /* If we're rmail add "-f", "Rpath" to the the command line */
110 *p
++ = "--"; /* extra protection: end of argument list */
112 for (to
= &(list
->recip_list
); to
; to
= to
->next
)
118 fp
= popenvp(sendmail_prog
, argv
, "w", 0);
125 copylet(letnum
, fp
, ORDINARY
);
134 * send_mbox(user, letnum) Sends the letter specified by letnum to the
135 * "user"'s mailbox. It returns 1 if the sending fails;
142 send_mbox(char *mbox
, int letnum
)
145 char biffmsg
[PATH_MAX
];
149 uid_t useruid
, saved_uid
;
150 void (*istat
)(), (*qstat
)(), (*hstat
)();
152 if (!islocal(mbox
, &useruid
))
154 (void) strlcpy(file
, maildir
, sizeof (file
));
155 if (strlcat(file
, mbox
, sizeof (file
)) >= sizeof (file
)) {
161 * We need to setgid and seteuid here since the users's mail box
162 * might be NFS mounted and since root can't write across NFS.
163 * Note this won't work with Secure NFS/RPC's. Since delivering to
164 * NFS mounted directories isn't really supported that's OK for now.
167 saved_uid
= geteuid();
172 istat
= signal(SIGINT
, SIG_IGN
);
173 qstat
= signal(SIGQUIT
, SIG_IGN
);
174 hstat
= signal(SIGHUP
, SIG_IGN
);
175 /* now access mail box */
176 mbfd
= accessmf(file
);
177 if (mbfd
== -1) { /* mail box access failed, bail out */
183 /* mail box is ok, now do append */
184 if ((malf
= fdopen(mbfd
, "a")) != NULL
) {
185 (void) snprintf(biffmsg
, sizeof (biffmsg
),
186 "%s@%d\n", mbox
, ftell(malf
));
187 rc
= copylet(letnum
, malf
, ORDINARY
);
193 fprintf(stderr
, "%s: Cannot append to %s\n", program
, file
);
199 (void) signal(SIGINT
, istat
);
200 (void) signal(SIGQUIT
, qstat
);
201 (void) signal(SIGHUP
, hstat
);
207 #include <sys/socket.h>
208 #include <netinet/in.h>
211 notifybiff(char *msg
)
213 static struct sockaddr_in addr
;
216 if (addr
.sin_family
== 0) {
217 addr
.sin_family
= AF_INET
;
218 addr
.sin_addr
.s_addr
= INADDR_LOOPBACK
;
219 addr
.sin_port
= htons(IPPORT_BIFFUDP
);
222 f
= socket(AF_INET
, SOCK_DGRAM
, 0);
223 sendto(f
, msg
, strlen(msg
)+1, 0, (struct sockaddr
*)&addr
,