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
recipient_list_init(RECIPIENT_LIST * list,int variant)129 void 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
recipient_list_add(RECIPIENT_LIST * list,long offset,const char * dsn_orcpt,int dsn_notify,const char * orig_rcpt,const char * rcpt)139 void 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((void *) 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
recipient_list_swap(RECIPIENT_LIST * a,RECIPIENT_LIST * b)167 void 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
recipient_list_free(RECIPIENT_LIST * list)181 void recipient_list_free(RECIPIENT_LIST *list)
182 {
183 RECIPIENT *rcpt;
184
185 for (rcpt = list->info; rcpt < list->info + list->len; rcpt++) {
186 myfree((void *) rcpt->dsn_orcpt);
187 myfree((void *) rcpt->orig_addr);
188 myfree((void *) rcpt->address);
189 }
190 myfree((void *) list->info);
191 }
192