1/* $NetBSD: recipient_list.c,v 1.2 2017/02/14 01:16:45 christos 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 131void 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 141void 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((void *) 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 169void 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 183void recipient_list_free(RECIPIENT_LIST *list) 184{ 185 RECIPIENT *rcpt; 186 187 for (rcpt = list->info; rcpt < list->info + list->len; rcpt++) { 188 myfree((void *) rcpt->dsn_orcpt); 189 myfree((void *) rcpt->orig_addr); 190 myfree((void *) rcpt->address); 191 } 192 myfree((void *) list->info); 193} 194