summaryrefslogtreecommitdiffstats
path: root/src/global/recipient_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/global/recipient_list.c')
-rw-r--r--src/global/recipient_list.c191
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);
+}