static char *SccsId
= "@(#)names.c 1.2 %G%";
* Allocate a single element of a name list,
* initialize its name field to the passed
register struct name
*np
;
np
= (struct name
*) salloc(sizeof *np
);
np
->n_name
= savestr(str
);
* Find the tail of a list and return it.
register struct name
*np
;
while (np
->n_flink
!= NIL
)
* Extract a list of names from a line,
* and make a list of names from it.
* Return the list or NIL if none found.
register struct name
*top
, *np
, *t
;
char nbuf
[BUFSIZ
], abuf
[BUFSIZ
];
if (line
== NOSTR
|| strlen(line
) == 0)
while ((cp
= yankword(cp
, nbuf
)) != NOSTR
) {
if (np
!= NIL
&& equal(nbuf
, "at")) {
if ((cp
= yankword(cp
, nbuf
)) == NOSTR
) {
strcpy(abuf
, np
->n_name
);
np
->n_name
= savestr(abuf
);
* Turn a list of names into a string of the same names.
register struct name
*np
;
fprintf(stderr
, "detract asked to insert commas\n");
for (p
= np
; p
!= NIL
; p
= p
->n_flink
) {
if (ntype
&& (p
->n_type
& GMASK
) != ntype
)
s
+= strlen(p
->n_name
) + 1;
for (p
= np
; p
!= NIL
; p
= p
->n_flink
) {
if (ntype
&& (p
->n_type
& GMASK
) != ntype
)
cp
= copy(p
->n_name
, cp
);
if (comma
&& p
->n_flink
!= NIL
)
if (comma
&& *--cp
== ',')
* Grab a single word (liberal word)
* Throw away things between ()'s.
for (cp
= ap
; *cp
&& any(*cp
, " \t,"); cp
++)
while (*cp
&& *cp
!= ')')
} while (any(*cp
, " \t,("));
for (cp2
= wbuf
; *cp
&& !any(*cp
, " \t,("); *cp2
++ = *cp
++)
* Verify that all the users in the list of names are
* legitimate. Bitch about and delink those who aren't.
register struct name
*np
, *top
, *t
, *x
;
for (cp
= "!:@^"; *cp
; cp
++)
if (any(*cp
, np
->n_name
))
fprintf(stderr
, "Can't send to %s\n", np
->n_name
);
* For each recipient in the passed name list with a /
* in the name, append the message to the end of the named file
* and remove him from the recipient list.
* Recipients whose name begins with | are piped through the given
register struct name
*np
, *top
, *t
, *x
;
char *date
, *fname
, *shell
, *ctime();
if (!any('/', np
->n_name
) && np
->n_name
[0] != '|') {
ispipe
= np
->n_name
[0] == '|';
fname
= expand(np
->n_name
);
* See if we have copied the complete message out yet.
if ((fout
= fopen(tempEdit
, "a")) == NULL
) {
image
= open(tempEdit
, 2);
fprintf(fout
, "From %s %s", myname
, date
);
puthead(hp
, fout
, GTO
|GSUBJECT
|GCC
|GNL
);
while ((c
= getc(fo
)) != EOF
)
* Now either copy "image" to the desired file
* or give it as the standard input to the desired
* program as appropriate.
sigsys(SIGQUIT
, SIG_IGN
);
if ((shell
= value("SHELL")) == NOSTR
)
execl(shell
, shell
, "-c", fname
, 0);
if ((fout
= fopen(fname
, "a")) == NULL
) {
fin
= Fdopen(image
, "r");
fprintf(stderr
, "Can't reopen image\n");
while ((c
= getc(fin
)) != EOF
)
senderr
++, perror(fname
);
* In days of old we removed the entry from the
* the list; now for sake of header expansion
* we leave it in and mark it as deleted.
* Map all of the aliased users in the invoker's mailrc
* file and insert them into the list.
* Changed after all these months of service to recursively
* expand names (2/14/80).
register struct name
*new, *np
, *cp
;
metoo
= (value("metoo") != NOSTR
);
if (np
->n_name
[0] == '\\') {
gh
= findgroup(np
->n_name
);
new = gexpand(new, gh
, metoo
, np
->n_type
);
* Recursively expand a group name. We limit the expansion to some
* fixed level to keep things from going haywire.
* Direct recursion is not expanded for convenience.
gexpand(nlist
, gh
, metoo
, ntype
)
printf("Expanding alias to depth larger than %d\n", MAXEXP
);
for (gp
= gh
->g_list
; gp
!= NOGE
; gp
= gp
->ge_link
) {
if (strcmp(cp
, gh
->g_name
) == 0)
if ((ngh
= findgroup(cp
)) != NOGRP
) {
nlist
= gexpand(nlist
, ngh
, metoo
, ntype
);
* At this point should allow to expand
* to self if only person in group
if (gp
== gh
->g_list
&& gp
->ge_link
== NOGE
)
if (!metoo
&& strcmp(cp
, myname
) == 0)
* Compute the length of the passed name list and
register struct name
*np
;
for (c
= 0, np
= name
; np
!= NIL
; c
++, np
= np
->n_flink
)
* Concatenate the two passed name lists, return the result.
register struct name
*tail
;
* Unpack the name list onto a vector of strings.
* Return an error if the name list won't fit.
register char **ap
, **top
;
if ((t
= lengthof(n
)) == 0)
panic("No names to unpack");
* Compute the number of extra arguments we will need.
* We need at least two extra -- one for "mail" and one for
* the terminating 0 pointer. Additional spots may be needed
* to pass along -r and -f to the host mailer.
metoo
= value("metoo") != NOSTR
;
top
= (char **) salloc((t
+ extra
) * sizeof cp
);
sprintf(hbuf
, "%d", hflag
);
* See if the user named himself as a destination
* for outgoing mail. If so, set the global flag
* selfsent so that we avoid removing his mailbox.
register struct name
*np
;
for (np
= names
; np
!= NIL
; np
= np
->n_flink
)
if ((np
->n_type
& GDEL
) == 0 && equal(myname
, np
->n_name
)) {
* Remove all of the duplicates from the passed name list by
* insertion sorting them, then checking for dups.
* Return the head of the new list.
register struct name
*np
, *t
, *new;
while (nstrcmp(t
->n_name
, np
->n_name
) < 0) {
* If we ran out of t's, put the new entry after
* the current value of t.
if (nstrcmp(t
->n_name
, np
->n_name
) < 0) {
* Otherwise, put the new entry in front of the
* current t. If at the front of the list,
* the new guy becomes the new head of the list.
* The normal case -- we are inserting into the
* Now the list headed up by new is sorted.
* Go through it and remove duplicates.
while (t
->n_flink
!=NIL
&&
icequal(np
->n_name
,t
->n_flink
->n_name
))
if (t
== np
|| t
== NIL
) {
* Now t points to the last entry with the same name
* as np. Make np point beyond t.
np
->n_flink
= t
->n_flink
;
t
->n_flink
->n_blink
= np
;
* Version of strcmp which ignores case differences.
} while (c1
&& c1
== c2
);
* Put another node onto a list of names and return
struct name
*list
, *node
;
* Determine the number of elements in
* a name list and return it.
register struct name
*np
;
* Delete the given name from a namelist.
register struct name
*np
;
for (p
= np
; p
!= NIL
; p
= p
->n_flink
)
if (equal(p
->n_name
, name
)) {
p
->n_flink
->n_blink
= NIL
;
p
->n_blink
->n_flink
= NIL
;
p
->n_blink
->n_flink
= p
->n_flink
;
p
->n_flink
->n_blink
= p
->n_blink
;
* Call the given routine on each element of the name
* list, replacing said value if need be.
register struct name
*np
;
for (p
= np
; p
!= NIL
; p
= p
->n_flink
)
p
->n_name
= netmap(p
->n_name
, from
);
* Pretty print a name list
* Uncomment it if you need it.
register struct name
*np
;
fprintf(stderr
, "%s(%d) ", np
->n_name
, np
->n_type
);