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
recipient_list_init(RECIPIENT_LIST * list,int variant)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
recipient_list_add(RECIPIENT_LIST * list,long offset,const char * dsn_orcpt,int dsn_notify,const char * orig_rcpt,const char * rcpt)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((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
recipient_list_swap(RECIPIENT_LIST * a,RECIPIENT_LIST * b)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
recipient_list_free(RECIPIENT_LIST * list)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((void *) rcpt->dsn_orcpt);
189 myfree((void *) rcpt->orig_addr);
190 myfree((void *) rcpt->address);
191 }
192 myfree((void *) list->info);
193 }
194