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