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