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  */
ndma_enumerate_env_list(struct ndm_env_table * envtab)48 ndmp9_pval* ndma_enumerate_env_list(struct ndm_env_table* envtab)
49 {
50   int i;
51   struct ndm_env_entry* entry;
52 
53   /*
54    * See if we need to allocate memory or can reuse the memory
55    * already allocated in an earlier call.
56    */
57   if (!envtab->enumerate) {
58     envtab->enumerate = NDMOS_API_MALLOC(sizeof(ndmp9_pval) * envtab->n_env);
59     envtab->enumerate_length = envtab->n_env;
60   } else if (envtab->enumerate_length != envtab->n_env) {
61     NDMOS_API_FREE(envtab->enumerate);
62     envtab->enumerate = NDMOS_API_MALLOC(sizeof(ndmp9_pval) * envtab->n_env);
63     envtab->enumerate_length = envtab->n_env;
64   }
65 
66   if (!envtab->enumerate) { return NULL; }
67   NDMOS_API_BZERO(envtab->enumerate, sizeof(ndmp9_pval) * envtab->n_env);
68 
69   i = 0;
70   for (entry = envtab->head; entry; entry = entry->next) {
71     memcpy(&envtab->enumerate[i], &entry->pval, sizeof(ndmp9_pval));
72     i++;
73   }
74 
75   return envtab->enumerate;
76 }
77 
78 /*
79  * Add a new entry to an environment list table.
80  * Return entry if caller wants to modify it.
81  */
ndma_store_env_list(struct ndm_env_table * envtab,ndmp9_pval * pv)82 struct ndm_env_entry* ndma_store_env_list(struct ndm_env_table* envtab,
83                                           ndmp9_pval* pv)
84 {
85   struct ndm_env_entry* entry;
86 
87   if (envtab->n_env >= NDM_MAX_ENV) return NULL;
88 
89   entry = NDMOS_API_MALLOC(sizeof(struct ndm_env_entry));
90   if (!entry) return NULL;
91 
92   entry->pval.name = NDMOS_API_STRDUP(pv->name);
93   if (!entry->pval.name) {
94     NDMOS_API_FREE(entry);
95     return NULL;
96   }
97 
98   entry->pval.value = NDMOS_API_STRDUP(pv->value);
99   if (!entry->pval.value) {
100     NDMOS_API_FREE(entry->pval.name);
101     NDMOS_API_FREE(entry);
102     return NULL;
103   }
104 
105   entry->next = NULL;
106   if (envtab->tail) {
107     envtab->tail->next = entry;
108     envtab->tail = entry;
109   } else {
110     envtab->head = entry;
111     envtab->tail = entry;
112   }
113 
114   envtab->n_env++;
115 
116   return entry;
117 }
118 
119 /*
120  * Update an entry in an environment list table.
121  * If it doesn't exist add a new entry.
122  * Return entry if caller want to modify it.
123  */
ndma_update_env_list(struct ndm_env_table * envtab,ndmp9_pval * pv)124 struct ndm_env_entry* ndma_update_env_list(struct ndm_env_table* envtab,
125                                            ndmp9_pval* pv)
126 {
127   struct ndm_env_entry* entry;
128 
129   for (entry = envtab->head; entry; entry = entry->next) {
130     if (strcmp(entry->pval.name, pv->name) == 0) {
131       NDMOS_API_FREE(entry->pval.value);
132       entry->pval.value = NDMOS_API_STRDUP(pv->value);
133       return entry;
134     }
135   }
136 
137   return ndma_store_env_list(envtab, pv);
138 }
139 
140 /*
141  * Destroy an environment list table including any
142  * enumerate buffers allocated for it.
143  */
ndma_destroy_env_list(struct ndm_env_table * envtab)144 void ndma_destroy_env_list(struct ndm_env_table* envtab)
145 {
146   struct ndm_env_entry* entry;
147   struct ndm_env_entry* next;
148 
149   for (entry = envtab->head; entry; entry = next) {
150     if (entry->pval.name) NDMOS_API_FREE(entry->pval.name);
151 
152     if (entry->pval.value) NDMOS_API_FREE(entry->pval.value);
153 
154     next = entry->next;
155     NDMOS_API_FREE(entry);
156   }
157 
158   if (envtab->enumerate) {
159     NDMOS_API_FREE(envtab->enumerate);
160     envtab->enumerate = NULL;
161     envtab->enumerate_length = 0;
162   }
163 
164   envtab->head = NULL;
165   envtab->tail = NULL;
166   envtab->n_env = 0;
167 }
168 
169 /*
170  * Nlist mgmt.
171  *
172  * Return a chunk of memory with all entries from the nlist as
173  * one big enumeration useable for rpc to use as return value.
174  * We allacate the memory and keep the pointer in the table handle
175  * which gets freed on destroy of the table.
176  */
ndma_enumerate_nlist(struct ndm_nlist_table * nlist)177 ndmp9_name* ndma_enumerate_nlist(struct ndm_nlist_table* nlist)
178 {
179   int i;
180   struct ndm_nlist_entry* entry;
181 
182   /*
183    * See if we need to allocate memory or can reuse the memory
184    * already allocated in an earlier call.
185    */
186   if (!nlist->enumerate) {
187     nlist->enumerate = NDMOS_API_MALLOC(sizeof(ndmp9_name) * nlist->n_nlist);
188     nlist->enumerate_length = nlist->n_nlist;
189   } else if (nlist->enumerate_length != nlist->n_nlist) {
190     NDMOS_API_FREE(nlist->enumerate);
191     nlist->enumerate = NDMOS_API_MALLOC(sizeof(ndmp9_name) * nlist->n_nlist);
192     nlist->enumerate_length = nlist->n_nlist;
193   }
194 
195   if (!nlist->enumerate) { return NULL; }
196   NDMOS_API_BZERO(nlist->enumerate, sizeof(ndmp9_name) * nlist->n_nlist);
197 
198   i = 0;
199   for (entry = nlist->head; entry; entry = entry->next) {
200     memcpy(&nlist->enumerate[i], &entry->name, sizeof(ndmp9_name));
201     i++;
202   }
203 
204   return nlist->enumerate;
205 }
206 
207 /*
208  * Add a new entry to a nlist list table.
209  * Return entry if caller want to modify it.
210  */
ndma_store_nlist(struct ndm_nlist_table * nlist,ndmp9_name * nl)211 struct ndm_nlist_entry* ndma_store_nlist(struct ndm_nlist_table* nlist,
212                                          ndmp9_name* nl)
213 {
214   struct ndm_nlist_entry* entry;
215 
216   if (nlist->n_nlist >= NDM_MAX_NLIST) return NULL;
217 
218   entry = NDMOS_API_MALLOC(sizeof(struct ndm_nlist_entry));
219   if (!entry) return NULL;
220 
221   NDMOS_MACRO_ZEROFILL(entry);
222 
223   entry->name.original_path = NDMOS_API_STRDUP(nl->original_path);
224   if (!entry->name.original_path) goto bail_out;
225 
226   entry->name.destination_path = NDMOS_API_STRDUP(nl->destination_path);
227   if (!entry->name.destination_path) goto bail_out;
228 
229   entry->name.name = NDMOS_API_STRDUP(nl->name);
230   if (!entry->name.name) goto bail_out;
231 
232   entry->name.other_name = NDMOS_API_STRDUP(nl->other_name);
233   if (!entry->name.other_name) goto bail_out;
234 
235   entry->name.node = nl->node;
236   entry->name.fh_info = nl->fh_info;
237   entry->result_err = NDMP9_UNDEFINED_ERR;
238   entry->result_count = 0;
239 
240   entry->next = NULL;
241   if (nlist->tail) {
242     nlist->tail->next = entry;
243     nlist->tail = entry;
244   } else {
245     nlist->head = entry;
246     nlist->tail = entry;
247   }
248 
249   nlist->n_nlist++;
250 
251   return entry;
252 
253 bail_out:
254   if (entry->name.other_name) NDMOS_API_FREE(entry->name.other_name);
255 
256   if (entry->name.name) NDMOS_API_FREE(entry->name.name);
257 
258   if (entry->name.destination_path)
259     NDMOS_API_FREE(entry->name.destination_path);
260 
261   if (entry->name.original_path) NDMOS_API_FREE(entry->name.original_path);
262 
263   NDMOS_API_FREE(entry);
264 
265   return NULL;
266 }
267 
268 /*
269  * Destroy a nlist list table including any
270  * enumerate buffers allocated for it.
271  */
ndma_destroy_nlist(struct ndm_nlist_table * nlist)272 void ndma_destroy_nlist(struct ndm_nlist_table* nlist)
273 {
274   struct ndm_nlist_entry* entry;
275   struct ndm_nlist_entry* next;
276 
277   for (entry = nlist->head; entry; entry = next) {
278     if (entry->name.original_path) NDMOS_API_FREE(entry->name.original_path);
279 
280     if (entry->name.destination_path)
281       NDMOS_API_FREE(entry->name.destination_path);
282 
283     next = entry->next;
284     NDMOS_API_FREE(entry);
285   }
286 
287   if (nlist->enumerate) {
288     NDMOS_API_FREE(nlist->enumerate);
289     nlist->enumerate = NULL;
290     nlist->enumerate_length = 0;
291   }
292 
293   nlist->head = NULL;
294   nlist->tail = NULL;
295   nlist->n_nlist = 0;
296 }
297 
298 /*
299  * Media list mgmt.
300  *
301  * Create a new media entry and add it to the Media Table.
302  * Return entry if caller want to modify it.
303  */
ndma_store_media(struct ndm_media_table * mtab,uint16_t element_address)304 struct ndmmedia* ndma_store_media(struct ndm_media_table* mtab,
305                                   uint16_t element_address)
306 {
307   struct ndmmedia* me;
308 
309   if (mtab->n_media >= NDM_MAX_MEDIA) return NULL;
310 
311   me = NDMOS_API_MALLOC(sizeof(struct ndmmedia));
312   if (!me) { return NULL; }
313 
314   NDMOS_MACRO_ZEROFILL(me);
315 
316   me->valid_slot = 1;
317   me->slot_addr = element_address;
318   me->index = mtab->n_media + 1;
319 
320   me->next = NULL;
321   if (mtab->tail) {
322     mtab->tail->next = me;
323     mtab->tail = me;
324   } else {
325     mtab->head = me;
326     mtab->tail = me;
327   }
328 
329   mtab->n_media++;
330 
331   return me;
332 }
333 
334 /*
335  * Clone an existing media entry and add it to the Media Table.
336  * Return entry if caller want to modify it.
337  */
ndma_clone_media_entry(struct ndm_media_table * mtab,struct ndmmedia * to_clone)338 struct ndmmedia* ndma_clone_media_entry(struct ndm_media_table* mtab,
339                                         struct ndmmedia* to_clone)
340 {
341   struct ndmmedia* me;
342 
343   if (mtab->n_media >= NDM_MAX_MEDIA) return NULL;
344 
345   me = NDMOS_API_MALLOC(sizeof(struct ndmmedia));
346   if (!me) { return NULL; }
347 
348   memcpy(me, to_clone, sizeof(struct ndmmedia));
349   me->index = mtab->n_media + 1;
350 
351   me->next = NULL;
352   if (mtab->tail) {
353     mtab->tail->next = me;
354     mtab->tail = me;
355   } else {
356     mtab->head = me;
357     mtab->tail = me;
358   }
359 
360   mtab->n_media++;
361 
362   return me;
363 }
364 
365 /*
366  * Destroy a Media Table.
367  */
ndmca_destroy_media_table(struct ndm_media_table * mtab)368 void ndmca_destroy_media_table(struct ndm_media_table* mtab)
369 {
370   struct ndmmedia *me, *next;
371 
372   for (me = mtab->head; me; me = next) {
373     next = me->next;
374 
375     NDMOS_API_FREE(me);
376   }
377 
378   mtab->head = NULL;
379   mtab->tail = NULL;
380   mtab->n_media = 0;
381 }
382