V10/cmd/nupas/send/dest.c
#include "mail.h"
#include "string.h"
#include "dest.h"
/* imports */
extern char *malloc();
extern void exit();
/* exports */
dest *dlist;
extern dest*
d_new(addr)
string *addr;
{
dest *dp;
dp = (dest *)malloc(sizeof(dest));
if (dp == NULL) {
perror("destnew");
exit(1);
}
dp->same = dp;
dp->nsame = 1;
dp->nchar = 0;
dp->next = dp;
dp->addr = addr;
dp->parent = NULL;
dp->repl1 = dp->repl2 = NULL;
dp->status = d_undefined;
dp->uid = dp->gid = -1;
return dp;
}
extern void
d_free(dp)
dest *dp;
{
if (dp != NULL) {
s_free(dp->addr);
s_free(dp->repl1);
s_free(dp->repl2);
free((char *)dp);
}
}
/* The following routines manipulate an ordered list of items. Insertions
* are always to the end of the list. Deletions are from the beginning.
*
* The list are circular witht the `head' of the list being the last item
* added.
*/
/* Get first element from a circular list linked via 'next'. */
extern dest *
d_rm(listp)
dest **listp;
{
dest *dp;
if (*listp == NULL)
return NULL;
dp = (*listp)->next;
if (dp == *listp)
*listp = NULL;
else
(*listp)->next = dp->next;
dp->next = dp;
return dp;
}
/* Insert a new entry at the end of the list linked via 'next'. */
extern void
d_insert(listp, new)
dest **listp; /* pointer to current list */
dest *new; /* list to be added */
{
dest *head;
if (*listp == NULL) {
*listp = new;
return;
}
if (new == NULL)
return;
head = new->next;
new->next = (*listp)->next;
(*listp)->next = head;
return;
}
/* Get first element from a circular list linked via 'same'. */
extern dest *
d_rm_same(listp)
dest **listp;
{
dest *dp;
if (*listp == NULL)
return NULL;
dp = (*listp)->same;
if (dp == *listp)
*listp = NULL;
else
(*listp)->same = dp->same;
dp->same = dp;
return dp;
}
/* Insert an entry into the corresponding list linked by 'same'. Note that
* the basic structure is a list of lists.
*/
extern void
d_same_insert(listp, new)
dest **listp; /* pointer to current list */
dest *new; /* new dest (or null terminated list of dests) */
{
dest *dp;
int len;
if(new->status == d_pipe) {
len = new->repl2 ? strlen(s_to_c(new->repl2)) : 0;
if(*listp != NULL){
dp = (*listp)->next;
do {
if(dp->status == new->status
&& dp->nsame < MAXSAME
&& dp->nchar + len < MAXSAMECHAR
&& strcmp(s_to_c(dp->repl1), s_to_c(new->repl1))==0
&& dp->uid == new->uid && dp->gid == new->gid){
new->same = dp->same;
dp->same = new;
dp->nchar += len + 1;
dp->nsame++;
return;
}
dp = dp->next;
} while (dp != (*listp)->next);
}
new->nchar = strlen(s_to_c(new->repl1)) + len + 1;
}
new->next = new;
d_insert(listp, new);
}
/* expand a string of destinations into a linked list of destiniations */
extern dest *
s_to_dest(sp, parent)
string *sp;
dest *parent; /* parent of new destinations */
{
string *addr;
dest *list=NULL;
dest *new;
if (sp == NULL)
return NULL;
addr = s_new();
while (s_parse(sp, addr)!=NULL) {
if(shellchars(s_to_c(addr))){
while(new = d_rm(&list))
d_free(new);
break;
}
new = d_new(addr);
new->parent = parent;
new->authorized = parent->authorized;
d_insert(&list, new);
addr = s_new();
}
s_free(addr);
return list;
}