1 /*
2  * Copyright (c) 1998,1999,2000
3  *	Traakan, Inc., Los Altos, CA
4  *	All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 /*
30  * Project:  NDMJOB
31  * Ident:    $Id: $
32  *
33  * Description:
34  *
35  */
36 
37 
38 #include "ndmagents.h"
39 
40 /*
41  * Env list mgmt.
42  *
43  * Return a chunk of memory with all entries from the envlist as
44  * one big enumeration useable for rpc to use as return value.
45  * We allacate the memory and keep the pointer in the table handle
46  * which gets freed on destroy of the table.
47  */
48 ndmp9_pval *
ndma_enumerate_env_list(struct ndm_env_table * envtab)49 ndma_enumerate_env_list (struct ndm_env_table *envtab)
50 {
51 	int i;
52 	struct ndm_env_entry *	entry;
53 
54 	/*
55 	 * See if we need to allocate memory or can reuse the memory
56 	 * already allocated in an earlier call.
57 	 */
58 	if (!envtab->enumerate) {
59 		envtab->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_pval) * envtab->n_env);
60 		envtab->enumerate_length = envtab->n_env;
61 	} else if (envtab->enumerate_length != envtab->n_env) {
62 		NDMOS_API_FREE (envtab->enumerate);
63 		envtab->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_pval) * envtab->n_env);
64 		envtab->enumerate_length = envtab->n_env;
65 	}
66 
67 	if (!envtab->enumerate) {
68 		return NULL;
69 	}
70 	NDMOS_API_BZERO (envtab->enumerate, sizeof(ndmp9_pval) * envtab->n_env);
71 
72 	i = 0;
73 	for (entry = envtab->head; entry; entry = entry->next) {
74 		memcpy (&envtab->enumerate[i], &entry->pval, sizeof(ndmp9_pval));
75 		i++;
76 	}
77 
78 	return envtab->enumerate;
79 }
80 
81 /*
82  * Add a new entry to an environment list table.
83  * Return entry if caller wants to modify it.
84  */
85 struct ndm_env_entry *
ndma_store_env_list(struct ndm_env_table * envtab,ndmp9_pval * pv)86 ndma_store_env_list (struct ndm_env_table *envtab, ndmp9_pval *pv)
87 {
88 	struct ndm_env_entry *	entry;
89 
90 	if (envtab->n_env >= NDM_MAX_ENV)
91 		return NULL;
92 
93 	entry = NDMOS_API_MALLOC (sizeof(struct ndm_env_entry));
94 	if (!entry)
95 		return NULL;
96 
97 	entry->pval.name = NDMOS_API_STRDUP (pv->name);
98 	if (!entry->pval.name) {
99 		NDMOS_API_FREE (entry);
100 		return NULL;
101 	}
102 
103 	entry->pval.value = NDMOS_API_STRDUP (pv->value);
104 	if (!entry->pval.value) {
105 		NDMOS_API_FREE (entry->pval.name);
106 		NDMOS_API_FREE (entry);
107 		return NULL;
108 	}
109 
110 	entry->next = NULL;
111 	if (envtab->tail) {
112 		envtab->tail->next = entry;
113 		envtab->tail = entry;
114 	} else {
115 		envtab->head = entry;
116 		envtab->tail = entry;
117 	}
118 
119 	envtab->n_env++;
120 
121 	return entry;
122 }
123 
124 /*
125  * Update an entry in an environment list table.
126  * If it doesn't exist add a new entry.
127  * Return entry if caller want to modify it.
128  */
129 struct ndm_env_entry *
ndma_update_env_list(struct ndm_env_table * envtab,ndmp9_pval * pv)130 ndma_update_env_list (struct ndm_env_table *envtab, ndmp9_pval *pv)
131 {
132 	struct ndm_env_entry *	entry;
133 
134 	for (entry = envtab->head; entry; entry = entry->next) {
135 		if (strcmp(entry->pval.name, pv->name) == 0) {
136 			NDMOS_API_FREE (entry->pval.value);
137 			entry->pval.value = NDMOS_API_STRDUP (pv->value);
138 			return entry;
139                 }
140 	}
141 
142 	return ndma_store_env_list (envtab, pv);
143 }
144 
145 /*
146  * Destroy an environment list table including any
147  * enumerate buffers allocated for it.
148  */
149 void
ndma_destroy_env_list(struct ndm_env_table * envtab)150 ndma_destroy_env_list (struct ndm_env_table *envtab)
151 {
152 	struct ndm_env_entry *	entry;
153 	struct ndm_env_entry *	next;
154 
155 	for (entry = envtab->head; entry; entry = next) {
156 		if (entry->pval.name)
157 			NDMOS_API_FREE (entry->pval.name);
158 
159 		if (entry->pval.value)
160 			NDMOS_API_FREE (entry->pval.value);
161 
162 		next = entry->next;
163 		NDMOS_API_FREE (entry);
164 	}
165 
166 	if (envtab->enumerate) {
167 		NDMOS_API_FREE (envtab->enumerate);
168 		envtab->enumerate = NULL;
169 		envtab->enumerate_length = 0;
170 	}
171 
172 	envtab->head = NULL;
173 	envtab->tail = NULL;
174 	envtab->n_env = 0;
175 }
176 
177 /*
178  * Nlist mgmt.
179  *
180  * Return a chunk of memory with all entries from the nlist as
181  * one big enumeration useable for rpc to use as return value.
182  * We allacate the memory and keep the pointer in the table handle
183  * which gets freed on destroy of the table.
184  */
185 ndmp9_name *
ndma_enumerate_nlist(struct ndm_nlist_table * nlist)186 ndma_enumerate_nlist (struct ndm_nlist_table *nlist)
187 {
188 	int i;
189 	struct ndm_nlist_entry *	entry;
190 
191 	/*
192 	 * See if we need to allocate memory or can reuse the memory
193 	 * already allocated in an earlier call.
194 	 */
195 	if (!nlist->enumerate) {
196 		nlist->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_name) * nlist->n_nlist);
197 		nlist->enumerate_length = nlist->n_nlist;
198 	} else if (nlist->enumerate_length != nlist->n_nlist) {
199 		NDMOS_API_FREE (nlist->enumerate);
200 		nlist->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_name) * nlist->n_nlist);
201 		nlist->enumerate_length = nlist->n_nlist;
202 	}
203 
204 	if (!nlist->enumerate) {
205 		return NULL;
206 	}
207 	NDMOS_API_BZERO (nlist->enumerate, sizeof(ndmp9_name) * nlist->n_nlist);
208 
209 	i = 0;
210 	for (entry = nlist->head; entry; entry = entry->next) {
211 		memcpy (&nlist->enumerate[i], &entry->name, sizeof(ndmp9_name));
212 		i++;
213 	}
214 
215 	return nlist->enumerate;
216 }
217 
218 /*
219  * Add a new entry to a nlist list table.
220  * Return entry if caller want to modify it.
221  */
222 struct ndm_nlist_entry *
ndma_store_nlist(struct ndm_nlist_table * nlist,ndmp9_name * nl)223 ndma_store_nlist (struct ndm_nlist_table *nlist, ndmp9_name *nl)
224 {
225 	struct ndm_nlist_entry *	entry;
226 
227 	if (nlist->n_nlist >= NDM_MAX_NLIST)
228 		return NULL;
229 
230 	entry = NDMOS_API_MALLOC (sizeof(struct ndm_nlist_entry));
231 	if (!entry)
232 		return NULL;
233 
234 	NDMOS_MACRO_ZEROFILL (entry);
235 
236 	entry->name.original_path = NDMOS_API_STRDUP (nl->original_path);
237 	if (!entry->name.original_path)
238 		goto bail_out;
239 
240 	entry->name.destination_path = NDMOS_API_STRDUP (nl->destination_path);
241 	if (!entry->name.destination_path)
242 		goto bail_out;
243 
244 	entry->name.name = NDMOS_API_STRDUP (nl->name);
245 	if (!entry->name.name)
246 		goto bail_out;
247 
248 	entry->name.other_name = NDMOS_API_STRDUP (nl->other_name);
249 	if (!entry->name.other_name)
250 		goto bail_out;
251 
252 	entry->name.node = nl->node;
253 	entry->name.fh_info = nl->fh_info;
254 	entry->result_err = NDMP9_UNDEFINED_ERR;
255 	entry->result_count = 0;
256 
257 	entry->next = NULL;
258 	if (nlist->tail) {
259 		nlist->tail->next = entry;
260 		nlist->tail = entry;
261 	} else {
262 		nlist->head = entry;
263 		nlist->tail = entry;
264 	}
265 
266 	nlist->n_nlist++;
267 
268 	return entry;
269 
270 bail_out:
271 	if (entry->name.other_name)
272 		NDMOS_API_FREE (entry->name.other_name);
273 
274 	if (entry->name.name)
275 		NDMOS_API_FREE (entry->name.name);
276 
277 	if (entry->name.destination_path)
278 		NDMOS_API_FREE (entry->name.destination_path);
279 
280 	if (entry->name.original_path)
281 		NDMOS_API_FREE (entry->name.original_path);
282 
283 	NDMOS_API_FREE (entry);
284 
285 	return NULL;
286 }
287 
288 /*
289  * Destroy a nlist list table including any
290  * enumerate buffers allocated for it.
291  */
292 void
ndma_destroy_nlist(struct ndm_nlist_table * nlist)293 ndma_destroy_nlist (struct ndm_nlist_table *nlist)
294 {
295 	struct ndm_nlist_entry *	entry;
296 	struct ndm_nlist_entry *	next;
297 
298 	for (entry = nlist->head; entry; entry = next) {
299 		if (entry->name.original_path)
300 			NDMOS_API_FREE (entry->name.original_path);
301 
302 		if (entry->name.destination_path)
303 			NDMOS_API_FREE (entry->name.destination_path);
304 
305 		next = entry->next;
306 		NDMOS_API_FREE (entry);
307 	}
308 
309 	if (nlist->enumerate) {
310 		NDMOS_API_FREE (nlist->enumerate);
311 		nlist->enumerate = NULL;
312 		nlist->enumerate_length = 0;
313 	}
314 
315 	nlist->head = NULL;
316 	nlist->tail = NULL;
317 	nlist->n_nlist = 0;
318 }
319 
320 /*
321  * Media list mgmt.
322  *
323  * Create a new media entry and add it to the Media Table.
324  * Return entry if caller want to modify it.
325  */
326 struct ndmmedia *
ndma_store_media(struct ndm_media_table * mtab,uint16_t element_address)327 ndma_store_media (struct ndm_media_table *mtab, uint16_t element_address)
328 {
329 	struct ndmmedia *	me;
330 
331 	if (mtab->n_media >= NDM_MAX_MEDIA)
332 		return NULL;
333 
334 	me = NDMOS_API_MALLOC (sizeof(struct ndmmedia));
335 	if (!me) {
336 		return NULL;
337 	}
338 
339 	NDMOS_MACRO_ZEROFILL (me);
340 
341 	me->valid_slot = 1;
342 	me->slot_addr = element_address;
343 	me->index = mtab->n_media + 1;
344 
345 	me->next = NULL;
346 	if (mtab->tail) {
347 		mtab->tail->next = me;
348 		mtab->tail = me;
349 	} else {
350 		mtab->head = me;
351 		mtab->tail = me;
352 	}
353 
354 	mtab->n_media++;
355 
356 	return me;
357 }
358 
359 /*
360  * Clone an existing media entry and add it to the Media Table.
361  * Return entry if caller want to modify it.
362  */
363 struct ndmmedia *
ndma_clone_media_entry(struct ndm_media_table * mtab,struct ndmmedia * to_clone)364 ndma_clone_media_entry (struct ndm_media_table *mtab, struct ndmmedia *to_clone)
365 {
366 	struct ndmmedia *	me;
367 
368 	if (mtab->n_media >= NDM_MAX_MEDIA)
369 		return NULL;
370 
371 	me = NDMOS_API_MALLOC (sizeof(struct ndmmedia));
372 	if (!me) {
373 		return NULL;
374 	}
375 
376 	memcpy (me, to_clone, sizeof(struct ndmmedia));
377 	me->index = mtab->n_media + 1;
378 
379 	me->next = NULL;
380 	if (mtab->tail) {
381 		mtab->tail->next = me;
382 		mtab->tail = me;
383 	} else {
384 		mtab->head = me;
385 		mtab->tail = me;
386 	}
387 
388 	mtab->n_media++;
389 
390 	return me;
391 }
392 
393 /*
394  * Destroy a Media Table.
395  */
396 void
ndmca_destroy_media_table(struct ndm_media_table * mtab)397 ndmca_destroy_media_table (struct ndm_media_table *mtab)
398 {
399         struct ndmmedia *	me, *next;
400 
401         for (me = mtab->head; me; me = next) {
402                 next = me->next;
403 
404                 NDMOS_API_FREE (me);
405         }
406 
407         mtab->head = NULL;
408         mtab->tail = NULL;
409         mtab->n_media = 0;
410 }
411