static char SccsId
[] = "@(#)recipient.c 3.13 %G%";
** SENDTO -- Designate a send list.
** The parameter is a comma-separated list of people to send to.
** This routine arranges to send to all of them.
** list -- the send list.
** copyf -- the copy flag; passed to parse.
bool more
; /* set if more addresses to send to */
ADDRESS
*al
; /* list of addresses to send to */
printf("sendto: %s\n", list
);
/* find the end of this address */
while (*p
== ' ' || *p
== '\t')
while ((c
= *p
++) != '\0' && c
!= ',' && c
!= '\n')
if ((a
= parse(q
, (ADDRESS
*) NULL
, copyf
)) == NULL
)
/* put it on the local send list */
/* arrange to send to everyone on the local send list */
register ADDRESS
*a
= al
;
** RECIPIENT -- Designate a message recipient
** Saves the named person for future mailing.
** a -- the (preparsed) address header for the recipient.
register struct mailer
*m
;
printf("recipient(%s)\n", To
);
/* break aliasing loops */
if (AliasLevel
> MAXRCRSN
)
usrerr("aliasing/forwarding loop broken");
** Do sickly crude mapping for program mailing, etc.
if (a
->q_mailer
== MN_LOCAL
)
usrerr("Cannot mail directly to programs");
** Look up this person in the recipient list. If they
** are there already, return, otherwise continue.
** If the list is empty, just add it.
for (pq
= &m
->m_sendq
; (q
= *pq
) != NULL
; pq
= &q
->q_next
)
if (!ForceMail
&& sameaddr(q
, a
, FALSE
))
printf("(%s in sendq)\n", a
->q_paddr
);
if (Verbose
&& !bitset(QDONTSEND
, a
->q_flags
))
message(Arpa_Info
, "duplicate suppressed");
/* add address on list */
** Alias the name and handle :include: specs.
if (a
->q_mailer
== MN_LOCAL
)
if (strncmp(a
->q_user
, ":include:", 9) == 0)
message(Arpa_Info
, "including file %s", &a
->q_user
[9]);
include(&a
->q_user
[9], " sending");
** If the user is local and still being sent, verify that
** the address is good. If it is, try to forward.
** If the address is already good, we have a forwarding
** loop. This can be broken by just sending directly to
** the user (which is probably correct anyway).
if (!bitset(QDONTSEND
, a
->q_flags
) && a
->q_mailer
== MN_LOCAL
)
/* see if this is to a file */
if ((p
= rindex(buf
, '/')) != NULL
)
/* check if writable or creatable */
if ((stat(buf
, &stb
) >= 0) ? (!writable(&stb
)) :
(*p
= '\0', access(buf
, 3) < 0))
giveresponse(EX_CANTCREAT
, TRUE
, m
);
register struct passwd
*pw
;
extern struct passwd
*finduser();
giveresponse(EX_NOUSER
, TRUE
, m
);
a
->q_home
= newstr(pw
->pw_dir
);
if (strcmp(buf
, a
->q_user
) == 0)
** FINDUSER -- find the password entry for a user.
** This looks a lot like getpwnam, except that it may want to
** do some fancier pattern matching in /etc/passwd.
** name -- the name to match against.
** A pointer to a pw struct.
** NULL if name is unknown or ambiguous.
extern struct passwd
*getpwnam();
** WRITABLE -- predicate returning if the file is writable.
** This routine must duplicate the algorithm in sys/fio.c.
** Unfortunately, we cannot use the access call since we
** won't necessarily be the real uid when we try to
** actually open the file.
** Notice that ANY file with ANY execute bit is automatically
** not writable. This is also enforced by mailfile.
** s -- pointer to a stat struct for the file.
** TRUE -- if we will be able to write this file.
** FALSE -- if we cannot write this file.
if (bitset(0111, s
->st_mode
))
if (bitset(S_ISUID
, s
->st_mode
))
if (bitset(S_ISGID
, s
->st_mode
))
return ((s
->st_mode
& bits
) != 0);
** INCLUDE -- handle :include: specification.
** fname -- filename to include.
** msg -- message to print in verbose mode.
** reads the :include: file and sends to everyone
usrerr("Cannot open %s", fname
);
/* read the file -- each line is a comma-separated list. */
while (fgets(buf
, sizeof buf
, fp
) != NULL
)
register char *p
= index(buf
, '\n');
message(Arpa_Info
, "%s to %s", msg
, buf
);
** SENDTOARGV -- send to an argument vector.
** argv -- argument vector to send to.
** puts all addresses on the argument vector onto the
while ((p
= *argv
++) != NULL
)
if (argv
[0] != NULL
&& argv
[1] != NULL
&& sameword(argv
[0], "at"))
if (strlen(p
) + strlen(argv
[1]) + 2 > sizeof nbuf
)
usrerr("address overflow");
(void) strcat(nbuf
, "@");
(void) strcat(nbuf
, argv
[1]);