diff options
Diffstat (limited to 'src/global/recipient_list.c')
-rw-r--r-- | src/global/recipient_list.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/global/recipient_list.c b/src/global/recipient_list.c new file mode 100644 index 0000000..32d1fd9 --- /dev/null +++ b/src/global/recipient_list.c @@ -0,0 +1,191 @@ +/*++ +/* NAME +/* recipient_list 3 +/* SUMMARY +/* in-core recipient structures +/* SYNOPSIS +/* #include <recipient_list.h> +/* +/* typedef struct { +/* .in +4 +/* long offset; +/* char *dsn_orcpt; +/* int dsn_notify; +/* char *orig_addr; +/* char *address; +/* union { +/* .in +4 +/* int status; +/* struct QMGR_QUEUE *queue; +/* char *addr_type; +/* .in -4 +/* } +/* .in -4 +/* } RECIPIENT; +/* +/* typedef struct { +/* .in +4 +/* RECIPIENT *info; +/* private members... +/* .in -4 +/* } RECIPIENT_LIST; +/* +/* void recipient_list_init(list, variant) +/* RECIPIENT_LIST *list; +/* int variant; +/* +/* void recipient_list_add(list, offset, dsn_orcpt, dsn_notify, +/* orig_rcpt, recipient) +/* RECIPIENT_LIST *list; +/* long offset; +/* const char *dsn_orcpt; +/* int dsn_notify; +/* const char *orig_rcpt; +/* const char *recipient; +/* +/* void recipient_list_swap(a, b) +/* RECIPIENT_LIST *a; +/* RECIPIENT_LIST *b; +/* +/* void recipient_list_free(list) +/* RECIPIENT_LIST *list; +/* +/* void RECIPIENT_ASSIGN(rcpt, offset, dsn_orcpt, dsn_notify, +/* orig_rcpt, recipient) +/* RECIPIENT *rcpt; +/* long offset; +/* char *dsn_orcpt; +/* int dsn_notify; +/* char *orig_rcpt; +/* char *recipient; +/* DESCRIPTION +/* This module maintains lists of recipient structures. Each +/* recipient is characterized by a destination address and +/* by the queue file offset of its delivery status record. +/* The per-recipient status is initialized to zero, and exists +/* solely for the convenience of the application. It is not used +/* by the recipient_list module itself. +/* +/* recipient_list_init() creates an empty recipient structure list. +/* The list argument is initialized such that it can be given to +/* recipient_list_add() and to recipient_list_free(). The variant +/* argument specifies how list elements should be initialized; +/* specify RCPT_LIST_INIT_STATUS to zero the status field, and +/* RCPT_LIST_INIT_QUEUE to zero the queue field. +/* +/* recipient_list_add() adds a recipient to the specified list. +/* Recipient address information is copied with mystrdup(). +/* +/* recipient_list_swap() swaps the recipients between +/* the given two recipient lists. +/* +/* recipient_list_free() releases memory for the specified list +/* of recipient structures. +/* +/* RECIPIENT_ASSIGN() assigns the fields of a recipient structure +/* without making copies of its arguments. +/* +/* Arguments: +/* .IP list +/* Recipient list initialized by recipient_list_init(). +/* .IP offset +/* Queue file offset of a recipient delivery status record. +/* .IP dsn_orcpt +/* DSN original recipient. +/* .IP notify +/* DSN notify flags. +/* .IP recipient +/* Recipient destination address. +/* SEE ALSO +/* recipient_list(3h) data structure +/* DIAGNOSTICS +/* Fatal errors: memory allocation. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include <sys_defs.h> + +/* Utility library. */ + +#include <mymalloc.h> +#include <msg.h> + +/* Global library. */ + +#include "recipient_list.h" + +/* recipient_list_init - initialize */ + +void recipient_list_init(RECIPIENT_LIST *list, int variant) +{ + list->avail = 1; + list->len = 0; + list->info = (RECIPIENT *) mymalloc(sizeof(RECIPIENT)); + list->variant = variant; +} + +/* recipient_list_add - add rcpt to list */ + +void recipient_list_add(RECIPIENT_LIST *list, long offset, + const char *dsn_orcpt, int dsn_notify, + const char *orig_rcpt, const char *rcpt) +{ + int new_avail; + + if (list->len >= list->avail) { + new_avail = list->avail * 2; + list->info = (RECIPIENT *) + myrealloc((void *) list->info, new_avail * sizeof(RECIPIENT)); + list->avail = new_avail; + } + list->info[list->len].orig_addr = mystrdup(orig_rcpt); + list->info[list->len].address = mystrdup(rcpt); + list->info[list->len].offset = offset; + list->info[list->len].dsn_orcpt = mystrdup(dsn_orcpt); + list->info[list->len].dsn_notify = dsn_notify; + if (list->variant == RCPT_LIST_INIT_STATUS) + list->info[list->len].u.status = 0; + else if (list->variant == RCPT_LIST_INIT_QUEUE) + list->info[list->len].u.queue = 0; + else if (list->variant == RCPT_LIST_INIT_ADDR) + list->info[list->len].u.addr_type = 0; + list->len++; +} + +/* recipient_list_swap - swap recipients between the two recipient lists */ + +void recipient_list_swap(RECIPIENT_LIST *a, RECIPIENT_LIST *b) +{ + if (b->variant != a->variant) + msg_panic("recipient_lists_swap: incompatible recipient list variants"); + +#define SWAP(t, x) do { t x = b->x; b->x = a->x ; a->x = x; } while (0) + + SWAP(RECIPIENT *, info); + SWAP(int, len); + SWAP(int, avail); +} + +/* recipient_list_free - release memory for in-core recipient structure */ + +void recipient_list_free(RECIPIENT_LIST *list) +{ + RECIPIENT *rcpt; + + for (rcpt = list->info; rcpt < list->info + list->len; rcpt++) { + myfree((void *) rcpt->dsn_orcpt); + myfree((void *) rcpt->orig_addr); + myfree((void *) rcpt->address); + } + myfree((void *) list->info); +} |