1/*++ 2/* NAME 3/* recipient_list 3 4/* SUMMARY 5/* in-core recipient structures 6/* SYNOPSIS 7/* #include <recipient_list.h> 8/* 9/* typedef struct { 10/* .in +4 11/* long offset; 12/* char *dsn_orcpt; 13/* int dsn_notify; 14/* char *orig_addr; 15/* char *address; 16/* union { 17/* .in +4 18/* int status; 19/* struct QMGR_QUEUE *queue; 20/* char *addr_type; 21/* .in -4 22/* } 23/* .in -4 24/* } RECIPIENT; 25/* 26/* typedef struct { 27/* .in +4 28/* RECIPIENT *info; 29/* private members... 30/* .in -4 31/* } RECIPIENT_LIST; 32/* 33/* void recipient_list_init(list, variant) 34/* RECIPIENT_LIST *list; 35/* int variant; 36/* 37/* void recipient_list_add(list, offset, dsn_orcpt, dsn_notify, 38/* orig_rcpt, recipient) 39/* RECIPIENT_LIST *list; 40/* long offset; 41/* const char *dsn_orcpt; 42/* int dsn_notify; 43/* const char *orig_rcpt; 44/* const char *recipient; 45/* 46/* void recipient_list_swap(a, b) 47/* RECIPIENT_LIST *a; 48/* RECIPIENT_LIST *b; 49/* 50/* void recipient_list_free(list) 51/* RECIPIENT_LIST *list; 52/* 53/* void RECIPIENT_ASSIGN(rcpt, offset, dsn_orcpt, dsn_notify, 54/* orig_rcpt, recipient) 55/* RECIPIENT *rcpt; 56/* long offset; 57/* char *dsn_orcpt; 58/* int dsn_notify; 59/* char *orig_rcpt; 60/* char *recipient; 61/* DESCRIPTION 62/* This module maintains lists of recipient structures. Each 63/* recipient is characterized by a destination address and 64/* by the queue file offset of its delivery status record. 65/* The per-recipient status is initialized to zero, and exists 66/* solely for the convenience of the application. It is not used 67/* by the recipient_list module itself. 68/* 69/* recipient_list_init() creates an empty recipient structure list. 70/* The list argument is initialized such that it can be given to 71/* recipient_list_add() and to recipient_list_free(). The variant 72/* argument specifies how list elements should be initialized; 73/* specify RCPT_LIST_INIT_STATUS to zero the status field, and 74/* RCPT_LIST_INIT_QUEUE to zero the queue field. 75/* 76/* recipient_list_add() adds a recipient to the specified list. 77/* Recipient address information is copied with mystrdup(). 78/* 79/* recipient_list_swap() swaps the recipients between 80/* the given two recipient lists. 81/* 82/* recipient_list_free() releases memory for the specified list 83/* of recipient structures. 84/* 85/* RECIPIENT_ASSIGN() assigns the fields of a recipient structure 86/* without making copies of its arguments. 87/* 88/* Arguments: 89/* .IP list 90/* Recipient list initialized by recipient_list_init(). 91/* .IP offset 92/* Queue file offset of a recipient delivery status record. 93/* .IP dsn_orcpt 94/* DSN original recipient. 95/* .IP notify 96/* DSN notify flags. 97/* .IP recipient 98/* Recipient destination address. 99/* SEE ALSO 100/* recipient_list(3h) data structure 101/* DIAGNOSTICS 102/* Fatal errors: memory allocation. 103/* LICENSE 104/* .ad 105/* .fi 106/* The Secure Mailer license must be distributed with this software. 107/* AUTHOR(S) 108/* Wietse Venema 109/* IBM T.J. Watson Research 110/* P.O. Box 704 111/* Yorktown Heights, NY 10598, USA 112/*--*/ 113 114/* System library. */ 115 116#include <sys_defs.h> 117 118/* Utility library. */ 119 120#include <mymalloc.h> 121#include <msg.h> 122 123/* Global library. */ 124 125#include "recipient_list.h" 126 127/* recipient_list_init - initialize */ 128 129void recipient_list_init(RECIPIENT_LIST *list, int variant) 130{ 131 list->avail = 1; 132 list->len = 0; 133 list->info = (RECIPIENT *) mymalloc(sizeof(RECIPIENT)); 134 list->variant = variant; 135} 136 137/* recipient_list_add - add rcpt to list */ 138 139void recipient_list_add(RECIPIENT_LIST *list, long offset, 140 const char *dsn_orcpt, int dsn_notify, 141 const char *orig_rcpt, const char *rcpt) 142{ 143 int new_avail; 144 145 if (list->len >= list->avail) { 146 new_avail = list->avail * 2; 147 list->info = (RECIPIENT *) 148 myrealloc((char *) list->info, new_avail * sizeof(RECIPIENT)); 149 list->avail = new_avail; 150 } 151 list->info[list->len].orig_addr = mystrdup(orig_rcpt); 152 list->info[list->len].address = mystrdup(rcpt); 153 list->info[list->len].offset = offset; 154 list->info[list->len].dsn_orcpt = mystrdup(dsn_orcpt); 155 list->info[list->len].dsn_notify = dsn_notify; 156 if (list->variant == RCPT_LIST_INIT_STATUS) 157 list->info[list->len].u.status = 0; 158 else if (list->variant == RCPT_LIST_INIT_QUEUE) 159 list->info[list->len].u.queue = 0; 160 else if (list->variant == RCPT_LIST_INIT_ADDR) 161 list->info[list->len].u.addr_type = 0; 162 list->len++; 163} 164 165/* recipient_list_swap - swap recipients between the two recipient lists */ 166 167void recipient_list_swap(RECIPIENT_LIST *a, RECIPIENT_LIST *b) 168{ 169 if (b->variant != a->variant) 170 msg_panic("recipient_lists_swap: incompatible recipient list variants"); 171 172#define SWAP(t, x) do { t x = b->x; b->x = a->x ; a->x = x; } while (0) 173 174 SWAP(RECIPIENT *, info); 175 SWAP(int, len); 176 SWAP(int, avail); 177} 178 179/* recipient_list_free - release memory for in-core recipient structure */ 180 181void recipient_list_free(RECIPIENT_LIST *list) 182{ 183 RECIPIENT *rcpt; 184 185 for (rcpt = list->info; rcpt < list->info + list->len; rcpt++) { 186 myfree((char *) rcpt->dsn_orcpt); 187 myfree((char *) rcpt->orig_addr); 188 myfree((char *) rcpt->address); 189 } 190 myfree((char *) list->info); 191} 192