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