2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1999
6 Copyright (C) Gerald Carter <jerry@samba.org> 2000
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /****************************************************************
24 In order to make use of the GENERIC_LIST data structure, you
25 should create wrapper functions around:
27 BOOL generic_list_insert()
28 void* generic_list_remove()
29 void* generic_list_locate()
31 The reason this is necessary is that the GENERIC_LIST uses a
32 void pointer to store your data structure. This means that
33 you get no type checking and can create a hetergenous list.
34 However, you will need to have some way to determine the type
35 of your data. If you are using a homogenous list, then
36 wrapper functions are the easiest way. If you are creating
37 a hetergenous list, then you will need to use the type field
38 for your arbitrary identifiers.
41 If neccessary, you can add a few generic_list_*() to do things
42 like grab from the front (to implement a FIFO queue) or from
43 the tail (to implement a FILO stack)
44 ****************************************************************/
52 static GENERIC_LIST hnds
;
55 /****************************************************************
56 Initialize the list. This doesn't do much currently. Just make
57 sure that you call it so we can determine wether the list is
59 ****************************************************************/
60 static void generic_list_init(GENERIC_LIST
*l
)
66 l
->initialized
= True
;
72 /*****************************************************************
73 Insert some data into the list (appended to the end of the list)
74 *****************************************************************/
75 static BOOL
generic_list_insert(GENERIC_LIST
*l
,
76 void *item
, uint8 type
)
78 /* check for an emtpy list first */
81 if ((l
->head
= malloc(sizeof(struct _list_node
))) == NULL
)
83 DEBUG(0, ("ERROR: out of memory! Cannot allocate a list node!\n"));
93 /* we already have an existing list */
96 if ((l
->tail
->next
= malloc(sizeof(struct _list_node
))) == NULL
)
98 DEBUG(0, ("ERROR: out of memory! Cannot allocate a list node!\n"));
101 l
->tail
= l
->tail
->next
;
102 l
->tail
->next
= NULL
;
103 l
->tail
->data
= item
;
104 l
->tail
->type
= type
;
108 /* return the list pointer in case this was the first node */
112 /****************************************************************
113 In order to locate an item in the list we need a pointer to
114 a compare function for the data items.
116 We will return the actual pointer to the item in the list. Not
118 ****************************************************************/
119 static void* generic_list_locate (GENERIC_LIST
*l
, void *search
,
120 BOOL(*cmp
)(const void*,const void*))
122 struct _list_node
*item
;
124 /* loop through the list in linear order */
128 if (cmp(search
, item
->data
))
140 /***************************************************************
141 In order to remove a node from the list, we will need a pointer
142 to a compare function. The function will return a pointer to
143 data in the removed node.
145 **WARNING** It is the responsibility of the caller to save
146 the pointer and destroy the data.
147 ***************************************************************/
148 static void* generic_list_remove(GENERIC_LIST
*l
, void *search
,
149 BOOL(*cmp
)(const void*,const void*))
151 struct _list_node
*item
, *tag
;
154 /* loop through the list in linear order */
159 /* did we find it? If so remove the node */
160 if (cmp(search
, item
->data
))
162 /* found, so remove the node */
164 /* remove the first item in the list */
166 l
->head
= item
->next
;
167 /* remove from the middle or the end */
169 tag
->next
= item
->next
;
171 /* check to see if we need to update the tail */
176 data_ptr
= item
->data
;
180 /* increment to the nbext node in the list */
191 /**************************************************************
193 *************************************************************/
194 BOOL
copy_policy_hnd (POLICY_HND
*dest
, const POLICY_HND
*src
)
196 /* if we have no destination, return an error */
200 /* if the src handle is NULL, then copy 0x00 to
204 /* if POLICY_HND internals ever changes,
205 this will need to be fixed */
214 /* -------------------------------------------------------------
215 Functions to implement the RpcHandle list
216 -------------------------------------------------------------- */
220 /***************************************************************
221 Return True if the to RPC_HND_NODEs are eqivalent in value.
222 Return False if they are not. Since a POLICY_HND is really
223 a UUID, two RPC_HND_NODES are considered to be the same if the
224 POLICY_HND value matches.
226 No ordering betweeen the two is attempted.
227 **************************************************************/
228 BOOL
compare_rpc_hnd_node(const RPC_HND_NODE
*x
,
229 const RPC_HND_NODE
*y
)
231 /* only compare valid nodes */
232 if (x
==NULL
|| y
==NULL
)
235 /* if the POLICY_HND field(s) are ever changed, this
236 will need to be updated. Probably should be a set of
237 support function for dealing with POLICY_HND */
238 return (memcmp(&x
->hnd
, &y
->hnd
, sizeof(POLICY_HND
)) == 0);
241 /***************************************************************
242 associate a POLICY_HND with a cli_connection
243 **************************************************************/
244 BOOL
RpcHndList_set_connection(const POLICY_HND
*hnd
,
245 struct cli_connection
*con
)
248 RPC_HND_NODE
*node
= NULL
;
250 /* initialize the list if necessary */
251 if (!hnds
.initialized
)
252 generic_list_init(&hnds
);
254 /* allocate a node to insert */
255 if ((node
=(RPC_HND_NODE
*)malloc(sizeof(RPC_HND_NODE
))) == NULL
)
257 DEBUG(0, ("ERROR: Unable to allocate memory for an RPC_HND_NODE!\n"));
261 /* fill in the RPC_HND_NODE */
262 copy_policy_hnd (&node
->hnd
, hnd
);
265 /* insert the node into the list:
266 The 3rd parameter is set to 0 since we don't care
267 anything about the type field */
268 return (generic_list_insert(&hnds
, (void*)node
, 0));
271 /************************************************************************
272 delete a POLICY_HND (and associated cli_connection) from the list
273 ***********************************************************************/
274 BOOL
RpcHndList_del_connection(const POLICY_HND
*hnd
)
276 RPC_HND_NODE node
, *located
;
278 /* return NULL if the list has not been initialized */
279 if (!hnds
.initialized
)
282 /* fill in the RPC_HND_NODE */
283 copy_policy_hnd (&node
.hnd
, hnd
);
286 /* search for the POLICY_HND */
287 located
= (RPC_HND_NODE
*)generic_list_remove(&hnds
, &node
,
288 (BOOL(*)(const void*, const void*))compare_rpc_hnd_node
);
292 /* delete the information */
293 cli_connection_free(located
->cli
);
298 /************************************************************************
299 search for a POLICY_HND and return a pointer to the associated
300 cli_connection struct in the list
301 **********************************************************************/
302 struct cli_connection
* RpcHndList_get_connection(const POLICY_HND
*hnd
)
304 RPC_HND_NODE node
, *located
;
306 /* return NULL if the list has not been initialized */
307 if (!hnds
.initialized
)
310 /* fill in the RPC_HND_NODE */
311 copy_policy_hnd (&node
.hnd
, hnd
);
314 /* search for the POLICY_HND */
315 located
= (RPC_HND_NODE
*)generic_list_locate(&hnds
, &node
,
316 (BOOL(*)(const void*, const void*))compare_rpc_hnd_node
);