Miscellaneous changes to call <a href="/cvs/aolserver/aolserver/nsd/driver.c#A_NsWaitDriversShutdown">NsWaitDriversShutdown</a> and remove unnecessary mutex init
1 | /* |
2 | * The contents of this file are subject to the AOLserver Public License |
3 | * Version 1.1 (the "License"); you may not use this file except in |
4 | * compliance with the License. You may obtain a copy of the License at |
5 | * http://aolserver.com/. |
6 | * |
7 | * Software distributed under the License is distributed on an "AS IS" |
8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
9 | * the License for the specific language governing rights and limitations |
10 | * under the License. |
11 | * |
12 | * The Original Code is AOLserver Code and related documentation |
13 | * distributed by AOL. |
14 | * |
15 | * The Initial Developer of the Original Code is America Online, |
16 | * Inc. Portions created by AOL are Copyright (C) 1999 America Online, |
17 | * Inc. All Rights Reserved. |
18 | * |
19 | * Alternatively, the contents of this file may be used under the terms |
20 | * of the GNU General Public License (the "GPL"), in which case the |
21 | * provisions of GPL are applicable instead of those above. If you wish |
22 | * to allow use of your version of this file only under the terms of the |
23 | * GPL and not to allow others to use your version of this file under the |
24 | * License, indicate your decision by deleting the provisions above and |
25 | * replace them with the notice and other provisions required by the GPL. |
26 | * If you do not delete the provisions above, a recipient may use your |
27 | * version of this file under either the License or the GPL. |
28 | */ |
29 | |
30 | |
31 | /* |
32 | * urlspace.c -- |
33 | * |
34 | * This file implements a Trie data structure. It is used |
35 | * for "UrlSpecificData"; for example, when one registers |
36 | * a handler for all GET /foo/bar/ *.html requests, the data |
37 | * structure that holds that information is implemented herein. |
38 | * For full details see the file doc/urlspace.txt. |
39 | */ |
40 | |
41 | static const char *RCSID = "@(#) $Header: /cvsroot-fuse/aolserver/aolserver/nsd/urlspace.c,v 1.11 2003/11/03 19:23:26 pkhincha Exp $, compiled: " __DATE__ " " __TIME__; |
42 | |
43 | #include "nsd.h" |
44 | |
45 | /* |
46 | * This optimization, when turned on, prevents the server from doing a |
47 | * whole lot of calls to Tcl_StringMatch on every lookup in urlspace. |
48 | * Instead, a strcmp is done. This hasn't been thoroughly tested, so |
49 | * it is off by default. |
50 | * |
51 | * #define __URLSPACE_OPTIMIZE__ |
52 | */ |
53 | |
54 | /* |
55 | * This structure defines a Node. It is the lowest-level structure in |
56 | * urlspace and contains the data the the user puts in. It holds data |
57 | * whose scope is a set of URLs, such as /foo/bar/ *.html. |
58 | * Data/cleanup functions are kept seperately for inheriting and non- |
59 | * inheriting URLs, as there could be overlap. |
60 | */ |
61 | |
62 | typedef struct { |
63 | int id; /* Handle from <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificAlloc">Ns_UrlSpecificAlloc</a> */ |
64 | void *dataInherit; /* User's data */ |
65 | void *dataNoInherit; /* User's data */ |
66 | void (*deletefuncInherit) (void *); /* Cleanup function */ |
67 | void (*deletefuncNoInherit) (void *); /* Cleanup function */ |
68 | } Node; |
69 | |
70 | /* |
71 | * This structure defines a trie. A trie is a tree whose nodes are |
72 | * branches and channels. It is an inherently recursive data structure, |
73 | * and each node is itself a trie. Each node represents one "part" of |
74 | * a URL; in this case, a "part" is server name, method, directory, or |
75 | * wildcard. |
76 | */ |
77 | |
78 | typedef struct { |
79 | Ns_Index branches; |
80 | Ns_Index *indexnode; |
81 | } Trie; |
82 | |
83 | /* |
84 | * A branch is a typical node in a Trie. The "word" is the part of the |
85 | * URL that the branch represents, and "node" is the sub-trie. |
86 | */ |
87 | |
88 | typedef struct { |
89 | char *word; |
90 | Trie node; |
91 | } Branch; |
92 | |
93 | /* |
94 | * A channel is much like a branch. It exists only at the second level |
95 | * (Channels come out of Junctions, which are top-level structures). |
96 | * The filter is a copy of the very last part of the URLs matched by |
97 | * branches coming out of this channel (only branches come out of channels). |
98 | * When looking for a URL, the filename part of the target URL is compared |
99 | * with the filter in each channel, and the channel is traversed only if |
100 | * there is a match |
101 | */ |
102 | |
103 | typedef struct { |
104 | char *filter; |
105 | Trie trie; |
106 | } Channel; |
107 | |
108 | /* |
109 | * A Junction is the top-level structure. Channels come out of a junction. |
110 | * Currently, only one junction is defined--the static global urlspace. |
111 | */ |
112 | |
113 | typedef struct { |
114 | Ns_Index byname; |
115 | /* |
116 | * We've experimented with getting rid of this index because |
117 | * it is like byname but in semi-reverse lexicographical |
118 | * order. This optimization seems to work in all cases, but |
119 | * we need a thorough way of testing all cases. |
120 | */ |
121 | #ifndef __URLSPACE_OPTIMIZE__ |
122 | Ns_Index byuse; |
123 | #endif |
124 | } Junction; |
125 | |
126 | /* |
127 | * Local functions defined in this file |
128 | */ |
129 | |
130 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDestroy">TrieDestroy</a>(Trie *trie); |
131 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_NodeDestroy">NodeDestroy</a>(Node *nodePtr); |
132 | static int <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpNodes">CmpNodes</a>(Node **leftPtrPtr, Node **rightPtrPtr); |
133 | static int <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpIdWithNode">CmpIdWithNode</a>(int id, Node **nodePtrPtr); |
134 | static Ns_Index * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_IndexNodeCreate">IndexNodeCreate</a>(void); |
135 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_IndexNodeDestroy">IndexNodeDestroy</a>(Ns_Index *indexPtr); |
136 | static int <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpBranches">CmpBranches</a>(Branch **leftPtrPtr, Branch **rightPtrPtr); |
137 | static int <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithBranch">CmpKeyWithBranch</a>(char *key, Branch **branchPtrPtr); |
138 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_BranchDestroy">BranchDestroy</a>(Branch *branchPtr); |
139 | |
140 | /* |
141 | * Utility functions |
142 | */ |
143 | |
144 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_MkSeq">MkSeq</a>(Ns_DString *dsPtr, char *server, char *method, char *url); |
145 | #ifdef DEBUG |
146 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_indentspace">indentspace</a>(int n); |
147 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintTrie">PrintTrie</a>(Trie *triePtr, int indent); |
148 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintJunction">PrintJunction</a>(Junction *junctionPtr); |
149 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintSeq">PrintSeq</a>(char *seq); |
150 | #endif |
151 | |
152 | /* |
153 | * Trie functions |
154 | */ |
155 | |
156 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieInit">TrieInit</a>(Trie *triePtr); |
157 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieAdd">TrieAdd</a>(Trie *triePtr, char *seq, int id, void *data, int flags, |
158 | void (*deletefunc) (void *)); |
159 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieTrunc">TrieTrunc</a>(Trie *triePtr, int id); |
160 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDestroy">TrieDestroy</a>(Trie *triePtr); |
161 | static int <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieBranchTrunc">TrieBranchTrunc</a>(Trie *triePtr, char *seq, int id); |
162 | static void *<a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFind">TrieFind</a>(Trie *triePtr, char *seq, int id, int *depthPtr); |
163 | static void *<a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFindExact">TrieFindExact</a>(Trie *triePtr, char *seq, int id, int flags); |
164 | static void *<a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDelete">TrieDelete</a>(Trie *triePtr, char *seq, int id, int flags); |
165 | |
166 | /* |
167 | * Channel functions |
168 | */ |
169 | |
170 | #ifndef __URLSPACE_OPTIMIZE__ |
171 | static int <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpChannels">CmpChannels</a>(Channel **leftPtrPtr, Channel **rightPtrPtr); |
172 | static int <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithChannel">CmpKeyWithChannel</a>(char *key, Channel **channelPtrPtr); |
173 | #endif |
174 | |
175 | static int <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpChannelsAsStrings">CmpChannelsAsStrings</a>(Channel **leftPtrPtr, Channel **rightPtrPtr); |
176 | static int <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithChannelAsStrings">CmpKeyWithChannelAsStrings</a>(char *key, Channel **channelPtrPtr); |
177 | |
178 | /* |
179 | * Juntion functions |
180 | */ |
181 | |
182 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionInit">JunctionInit</a>(Junction *juncPtr); |
183 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionAdd">JunctionAdd</a>(Junction *juncPtr, char *seq, int id, void *data, |
184 | int flags, void (*deletefunc) (void *)); |
185 | static void <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionBranchTrunc">JunctionBranchTrunc</a>(Junction *juncPtr, char *seq, int id); |
186 | static void *<a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionFind">JunctionFind</a>(Junction *juncPtr, char *seq, int id, int fast); |
187 | static void *<a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionFindExact">JunctionFindExact</a>(Junction *juncPtr, char *seq, int id, int flags, |
188 | int fast); |
189 | static void *<a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionDelete">JunctionDelete</a>(Junction *juncPtr, char *seq, int id, int flags); |
190 | |
191 | /* |
192 | * Static variables defined in this file |
193 | */ |
194 | |
195 | static Junction urlspace; /* All URL-specific data stored here */ |
196 | static Ns_Mutex lock; |
197 | |
198 | |
199 | /* |
200 | *---------------------------------------------------------------------- |
201 | * |
202 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_NsInitUrlSpace">NsInitUrlSpace</a> -- |
203 | * |
204 | * Initialize the urlspace API. |
205 | * |
206 | * Results: |
207 | * None. |
208 | * |
209 | * Side effects: |
210 | * None. |
211 | * |
212 | *---------------------------------------------------------------------- |
213 | */ |
214 | |
215 | void |
216 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_NsInitUrlSpace">NsInitUrlSpace</a>(void) |
217 | { |
218 | Ns_MutexSetName(&lock, "ns:urlspace"); |
219 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionInit">JunctionInit</a>(&urlspace); |
220 | } |
221 | |
222 | |
223 | /* |
224 | *---------------------------------------------------------------------- |
225 | * |
226 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificAlloc">Ns_UrlSpecificAlloc</a> -- |
227 | * |
228 | * Allocate a unique ID to create a seperate virtual URL-space. |
229 | * |
230 | * Results: |
231 | * An integer handle |
232 | * |
233 | * Side effects: |
234 | * nextid will be incremented; don't call after server startup. |
235 | * |
236 | *---------------------------------------------------------------------- |
237 | */ |
238 | |
239 | int |
240 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificAlloc">Ns_UrlSpecificAlloc</a>(void) |
241 | { |
242 | int id; |
243 | static int nextid = 0; |
244 | |
245 | Ns_MutexLock(&lock); |
246 | id = nextid++; |
247 | Ns_MutexUnlock(&lock); |
248 | return id; |
249 | } |
250 | |
251 | |
252 | /* |
253 | *---------------------------------------------------------------------- |
254 | * |
255 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificSet">Ns_UrlSpecificSet</a> -- |
256 | * |
257 | * Associate data with a set of URLs matching a wildcard, or |
258 | * that are simply sub-URLs. |
259 | * |
260 | * Flags can be NS_OP_NOINHERIT or NS_OP_NODELETE. |
261 | * |
262 | * Results: |
263 | * None |
264 | * |
265 | * Side effects: |
266 | * Will set data in the urlspace trie. |
267 | * |
268 | *---------------------------------------------------------------------- |
269 | */ |
270 | |
271 | void |
272 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificSet">Ns_UrlSpecificSet</a>(char *server, char *method, char *url, int id, void *data, |
273 | int flags, void (*deletefunc) (void *)) |
274 | { |
275 | Ns_DString ds; |
276 | |
277 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&ds); |
278 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_MkSeq">MkSeq</a>(&ds, server, method, url); |
279 | Ns_MutexLock(&lock); |
280 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionAdd">JunctionAdd</a>(&urlspace, ds.string, id, data, flags, deletefunc); |
281 | Ns_MutexUnlock(&lock); |
282 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringFree">Ns_DStringFree</a>(&ds); |
283 | } |
284 | |
285 | |
286 | /* |
287 | *---------------------------------------------------------------------- |
288 | * |
289 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGet">Ns_UrlSpecificGet</a> -- |
290 | * |
291 | * Find URL-specific data in the subspace identified by id that |
292 | * the passed-in URL matches |
293 | * |
294 | * Results: |
295 | * A pointer to user data, set with <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificSet">Ns_UrlSpecificSet</a> |
296 | * |
297 | * Side effects: |
298 | * None |
299 | * |
300 | *---------------------------------------------------------------------- |
301 | */ |
302 | |
303 | void * |
304 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGet">Ns_UrlSpecificGet</a>(char *server, char *method, char *url, int id) |
305 | { |
306 | Ns_DString ds; |
307 | void *data; |
308 | |
309 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&ds); |
310 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_MkSeq">MkSeq</a>(&ds, server, method, url); |
311 | Ns_MutexLock(&lock); |
312 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionFind">JunctionFind</a>(&urlspace, ds.string, id, 0); |
313 | Ns_MutexUnlock(&lock); |
314 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringFree">Ns_DStringFree</a>(&ds); |
315 | |
316 | return data; |
317 | } |
318 | |
319 | |
320 | /* |
321 | *---------------------------------------------------------------------- |
322 | * |
323 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGetFast">Ns_UrlSpecificGetFast</a> -- |
324 | * |
325 | * Similar to <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGet">Ns_UrlSpecificGet</a>, but doesn't support wildcards; |
326 | * on the other hand, it's a lot faster. |
327 | * |
328 | * Results: |
329 | * See <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGet">Ns_UrlSpecificGet</a> |
330 | * |
331 | * Side effects: |
332 | * None |
333 | * |
334 | *---------------------------------------------------------------------- |
335 | */ |
336 | |
337 | void * |
338 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGetFast">Ns_UrlSpecificGetFast</a>(char *server, char *method, char *url, int id) |
339 | { |
340 | Ns_DString ds; |
341 | void *data; |
342 | |
343 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&ds); |
344 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_MkSeq">MkSeq</a>(&ds, server, method, url); |
345 | Ns_MutexLock(&lock); |
346 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionFind">JunctionFind</a>(&urlspace, ds.string, id, 1); |
347 | Ns_MutexUnlock(&lock); |
348 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringFree">Ns_DStringFree</a>(&ds); |
349 | |
350 | return data; |
351 | } |
352 | |
353 | |
354 | /* |
355 | *---------------------------------------------------------------------- |
356 | * |
357 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGetExact">Ns_UrlSpecificGetExact</a> -- |
358 | * Similar to <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGet">Ns_UrlSpecificGet</a>, but does not support URL |
359 | * inheritance |
360 | * |
361 | * Results: |
362 | * See <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGet">Ns_UrlSpecificGet</a> |
363 | * |
364 | * Side effects: |
365 | * None |
366 | * |
367 | *---------------------------------------------------------------------- |
368 | */ |
369 | |
370 | void * |
371 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGetExact">Ns_UrlSpecificGetExact</a>(char *server, char *method, char *url, int id, |
372 | int flags) |
373 | { |
374 | Ns_DString ds; |
375 | void *data; |
376 | |
377 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&ds); |
378 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_MkSeq">MkSeq</a>(&ds, server, method, url); |
379 | Ns_MutexLock(&lock); |
380 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionFindExact">JunctionFindExact</a>(&urlspace, ds.string, id, flags, 0); |
381 | Ns_MutexUnlock(&lock); |
382 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringFree">Ns_DStringFree</a>(&ds); |
383 | |
384 | return data; |
385 | } |
386 | |
387 | |
388 | /* |
389 | *---------------------------------------------------------------------- |
390 | * |
391 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificDestroy">Ns_UrlSpecificDestroy</a> -- |
392 | * |
393 | * Delete some urlspecific data. |
394 | * |
395 | * flags can be NS_OP_NODELETE, NS_OP_NOINHERIT and/or NS_OP_RECURSE |
396 | * |
397 | * Results: |
398 | * None |
399 | * |
400 | * Side effects: |
401 | * Will remove data from urlspace; don't call this after server |
402 | * startup. |
403 | * |
404 | *---------------------------------------------------------------------- |
405 | */ |
406 | |
407 | void * |
408 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificDestroy">Ns_UrlSpecificDestroy</a>(char *server, char *method, char *url, int id, int flags) |
409 | { |
410 | Ns_DString ds; |
411 | void *data = NULL; |
412 | |
413 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&ds); |
414 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_MkSeq">MkSeq</a>(&ds, server, method, url); |
415 | Ns_MutexLock(&lock); |
416 | if (flags & NS_OP_RECURSE) { |
417 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionBranchTrunc">JunctionBranchTrunc</a>(&urlspace, ds.string, id); |
418 | data = NULL; |
419 | } else { |
420 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionDelete">JunctionDelete</a>(&urlspace, ds.string, id, flags); |
421 | } |
422 | Ns_MutexUnlock(&lock); |
423 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringFree">Ns_DStringFree</a>(&ds); |
424 | |
425 | return data; |
426 | } |
427 | |
428 | |
429 | /* |
430 | *---------------------------------------------------------------------- |
431 | * |
432 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_ServerSpecificAlloc">Ns_ServerSpecificAlloc</a> -- |
433 | * |
434 | * Allocate a unique integer to be used with Ns_ServerSpecific* |
435 | * calls |
436 | * |
437 | * Results: |
438 | * An integer handle |
439 | * |
440 | * Side effects: |
441 | * None |
442 | * |
443 | *---------------------------------------------------------------------- |
444 | */ |
445 | |
446 | int |
447 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_ServerSpecificAlloc">Ns_ServerSpecificAlloc</a>(void) |
448 | { |
449 | return <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificAlloc">Ns_UrlSpecificAlloc</a>(); |
450 | } |
451 | |
452 | |
453 | /* |
454 | *---------------------------------------------------------------------- |
455 | * |
456 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_ServerSpecificSet">Ns_ServerSpecificSet</a> -- |
457 | * |
458 | * Set server-specific data |
459 | * |
460 | * Results: |
461 | * None |
462 | * |
463 | * Side effects: |
464 | * See <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificSet">Ns_UrlSpecificSet</a> |
465 | * |
466 | *---------------------------------------------------------------------- |
467 | */ |
468 | |
469 | void |
470 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_ServerSpecificSet">Ns_ServerSpecificSet</a>(char *handle, int id, void *data, int flags, |
471 | void (*deletefunc) (void *)) |
472 | { |
473 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificSet">Ns_UrlSpecificSet</a>(handle, NULL, NULL, id, data, flags, deletefunc); |
474 | } |
475 | |
476 | |
477 | /* |
478 | *---------------------------------------------------------------------- |
479 | * |
480 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_ServerSpecificGet">Ns_ServerSpecificGet</a> -- |
481 | * |
482 | * Get server-specific data. |
483 | * |
484 | * Results: |
485 | * User server-specific data. |
486 | * |
487 | * Side effects: |
488 | * None. |
489 | * |
490 | *---------------------------------------------------------------------- |
491 | */ |
492 | |
493 | void * |
494 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_ServerSpecificGet">Ns_ServerSpecificGet</a>(char *handle, int id) |
495 | { |
496 | return <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificGet">Ns_UrlSpecificGet</a>(handle, NULL, NULL, id); |
497 | } |
498 | |
499 | |
500 | |
501 | /* |
502 | *---------------------------------------------------------------------- |
503 | * |
504 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_ServerSpecificDestroy">Ns_ServerSpecificDestroy</a> -- |
505 | * |
506 | * Destroy server-specific data. |
507 | * |
508 | * Results: |
509 | * None. |
510 | * |
511 | * Side effects: |
512 | * Will remove data from urlspace. |
513 | * |
514 | *---------------------------------------------------------------------- |
515 | */ |
516 | |
517 | void * |
518 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_ServerSpecificDestroy">Ns_ServerSpecificDestroy</a>(char *handle, int id, int flags) |
519 | { |
520 | return <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificDestroy">Ns_UrlSpecificDestroy</a>(handle, NULL, NULL, id, flags); |
521 | } |
522 | |
523 | |
524 | /* |
525 | *---------------------------------------------------------------------- |
526 | * |
527 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_NodeDestroy">NodeDestroy</a> -- |
528 | * |
529 | * Free a node and its data |
530 | * |
531 | * Results: |
532 | * None |
533 | * |
534 | * Side effects: |
535 | * The delete function is called and the node is freed |
536 | * |
537 | *---------------------------------------------------------------------- |
538 | */ |
539 | |
540 | static void |
541 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_NodeDestroy">NodeDestroy</a>(Node *nodePtr) |
542 | { |
543 | if (nodePtr == NULL) { |
544 | goto done; |
545 | } |
546 | if (nodePtr->deletefuncNoInherit != NULL) { |
547 | (*nodePtr->deletefuncNoInherit) (nodePtr->dataNoInherit); |
548 | } |
549 | if (nodePtr->deletefuncInherit != NULL) { |
550 | (*nodePtr->deletefuncInherit) (nodePtr->dataInherit); |
551 | } |
552 | ns_free(nodePtr); |
553 | |
554 | done: |
555 | return; |
556 | } |
557 | |
558 | |
559 | /* |
560 | *---------------------------------------------------------------------- |
561 | * |
562 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpNodes">CmpNodes</a> -- |
563 | * |
564 | * Compare two Nodes by id. Ns_Index calls use this as a callback. |
565 | * |
566 | * Results: |
567 | * 0 if equal, 1 if left is greater, -1 if left is less. |
568 | * |
569 | * Side effects: |
570 | * None |
571 | * |
572 | *---------------------------------------------------------------------- |
573 | */ |
574 | |
575 | static int |
576 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpNodes">CmpNodes</a>(Node **leftPtrPtr, Node **rightPtrPtr) |
577 | { |
578 | if ((*leftPtrPtr)->id != (*rightPtrPtr)->id) { |
579 | return ((*leftPtrPtr)->id > (*rightPtrPtr)->id) ? 1 : -1; |
580 | } else { |
581 | return 0; |
582 | } |
583 | } |
584 | |
585 | |
586 | /* |
587 | *---------------------------------------------------------------------- |
588 | * |
589 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpIdWithNode">CmpIdWithNode</a> -- |
590 | * |
591 | * Compare a node's ID to a passed-in ID; called by Ns_Index* |
592 | * |
593 | * Results: |
594 | * 0 if equal; 1 if id is too high; -1 if id is too low |
595 | * |
596 | * Side effects: |
597 | * None |
598 | * |
599 | *---------------------------------------------------------------------- |
600 | */ |
601 | |
602 | static int |
603 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpIdWithNode">CmpIdWithNode</a>(int id, Node **nodePtrPtr) |
604 | { |
605 | if (id != (*nodePtrPtr)->id) { |
606 | return (id > (*nodePtrPtr)->id) ? 1 : -1; |
607 | } else { |
608 | return 0; |
609 | } |
610 | } |
611 | |
612 | |
613 | /* |
614 | *---------------------------------------------------------------------- |
615 | * |
616 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_IndexNodeCreate">IndexNodeCreate</a> -- |
617 | * |
618 | * Initialize a trie->indexnode structure |
619 | * |
620 | * Results: |
621 | * A pointer to an appropriately initialized index |
622 | * |
623 | * Side effects: |
624 | * Memory alloacted. |
625 | * |
626 | *---------------------------------------------------------------------- |
627 | */ |
628 | |
629 | static Ns_Index * |
630 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_IndexNodeCreate">IndexNodeCreate</a>(void) |
631 | { |
632 | Ns_Index *indexPtr; |
633 | |
634 | indexPtr = ns_malloc(sizeof(Ns_Index)); |
635 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexInit">Ns_IndexInit</a>(indexPtr, 5, (int (*) (const void *, const void *)) <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpNodes">CmpNodes</a>, |
636 | (int (*) (const void *, const void *)) <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpIdWithNode">CmpIdWithNode</a>); |
637 | |
638 | return indexPtr; |
639 | } |
640 | |
641 | |
642 | /* |
643 | *---------------------------------------------------------------------- |
644 | * |
645 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_IndexNodeDestroy">IndexNodeDestroy</a> -- |
646 | * |
647 | * Wipe out a trie->indexnode structure. |
648 | * |
649 | * Results: |
650 | * None. |
651 | * |
652 | * Side effects: |
653 | * Memory freed. |
654 | * |
655 | *---------------------------------------------------------------------- |
656 | */ |
657 | |
658 | static void |
659 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_IndexNodeDestroy">IndexNodeDestroy</a>(Ns_Index *indexPtr) |
660 | { |
661 | int i; |
662 | |
663 | i = Ns_IndexCount(indexPtr); |
664 | while (i--) { |
665 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_NodeDestroy">NodeDestroy</a>(<a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(indexPtr, i)); |
666 | } |
667 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexDestroy">Ns_IndexDestroy</a>(indexPtr); |
668 | ns_free(indexPtr); |
669 | } |
670 | |
671 | |
672 | /* |
673 | *---------------------------------------------------------------------- |
674 | * |
675 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpBranches">CmpBranches</a> -- |
676 | * |
677 | * Compare two branches' word members. Called by Ns_Index* |
678 | * |
679 | * Results: |
680 | * 0 if equal, -1 if left is greater; 1 if right is greater |
681 | * |
682 | * Side effects: |
683 | * None. |
684 | * |
685 | *---------------------------------------------------------------------- |
686 | */ |
687 | |
688 | static int |
689 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpBranches">CmpBranches</a>(Branch **leftPtrPtr, Branch **rightPtrPtr) |
690 | { |
691 | return strcmp((*leftPtrPtr)->word, (*rightPtrPtr)->word); |
692 | } |
693 | |
694 | |
695 | /* |
696 | *---------------------------------------------------------------------- |
697 | * |
698 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpBranches">CmpBranches</a> -- |
699 | * |
700 | * Compare a branch's word to a passed-in key; called by |
701 | * Ns_Index*. |
702 | * |
703 | * Results: |
704 | * 0 if equal, -1 if left is greater; 1 if right is greater. |
705 | * |
706 | * Side effects: |
707 | * None. |
708 | * |
709 | *---------------------------------------------------------------------- |
710 | */ |
711 | |
712 | static int |
713 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithBranch">CmpKeyWithBranch</a>(char *key, Branch ** branchPtrPtr) |
714 | { |
715 | return strcmp(key, (*branchPtrPtr)->word); |
716 | } |
717 | |
718 | |
719 | /* |
720 | *---------------------------------------------------------------------- |
721 | * |
722 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_BranchDestroy">BranchDestroy</a> -- |
723 | * |
724 | * Free a branch structure |
725 | * |
726 | * Results: |
727 | * None. |
728 | * |
729 | * Side effects: |
730 | * Will free memory. |
731 | * |
732 | *---------------------------------------------------------------------- |
733 | */ |
734 | |
735 | static void |
736 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_BranchDestroy">BranchDestroy</a>(Branch *branchPtr) |
737 | { |
738 | ns_free(branchPtr->word); |
739 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDestroy">TrieDestroy</a>(&branchPtr->node); |
740 | ns_free(branchPtr); |
741 | } |
742 | |
743 | |
744 | /* |
745 | *---------------------------------------------------------------------- |
746 | * |
747 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieInit">TrieInit</a> -- |
748 | * |
749 | * Initialize a Trie data structure with 25 branches and set the |
750 | * Cmp functions for Ns_Index*. |
751 | * |
752 | * Results: |
753 | * None. |
754 | * |
755 | * Side effects: |
756 | * The trie is initialized and memory is allocated; memory is |
757 | * allocated. |
758 | * |
759 | *---------------------------------------------------------------------- |
760 | */ |
761 | |
762 | static void |
763 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieInit">TrieInit</a>(Trie *triePtr) |
764 | { |
765 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexInit">Ns_IndexInit</a>(&triePtr->branches, 25, |
766 | (int (*) (const void *, const void *)) <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpBranches">CmpBranches</a>, |
767 | (int (*) (const void *, const void *)) <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithBranch">CmpKeyWithBranch</a>); |
768 | triePtr->indexnode = NULL; |
769 | } |
770 | |
771 | |
772 | /* |
773 | *---------------------------------------------------------------------- |
774 | * |
775 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieAdd">TrieAdd</a> -- |
776 | * |
777 | * Add something to the Trie data structure, usually to the |
778 | * variable urlspace. |
779 | * |
780 | * seq is a null-delimited string of words, terminated with |
781 | * two nulls. |
782 | * id is allocated with <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificAlloc">Ns_UrlSpecificAlloc</a>. |
783 | * flags is a bitmask; optionally OR NS_OP_NODELETE, |
784 | * NS_OP_NOINHERIT for desired behavior. |
785 | * |
786 | * Results: |
787 | * None. |
788 | * |
789 | * Side effects: |
790 | * Memory is allocated. If a node is found and the |
791 | * NS_OP_NODELETE is not set, the current node's data is deleted. |
792 | * |
793 | *---------------------------------------------------------------------- |
794 | */ |
795 | |
796 | static void |
797 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieAdd">TrieAdd</a>(Trie *triePtr, char *seq, int id, void *data, int flags, |
798 | void (*deletefunc) (void *)) |
799 | { |
800 | if (*seq == '\0') { |
801 | Node *nodePtr; |
802 | |
803 | /* |
804 | * The entire sequence has been traversed, creating a branch |
805 | * for each word. Now it is time to make a Node. |
806 | * |
807 | * First, allocate a new node or find a matching one in existance. |
808 | */ |
809 | |
810 | if (triePtr->indexnode == NULL) { |
811 | triePtr->indexnode = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_IndexNodeCreate">IndexNodeCreate</a>(); |
812 | nodePtr = NULL; |
813 | } else { |
814 | nodePtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(triePtr->indexnode, (void *) id); |
815 | } |
816 | |
817 | if (nodePtr == NULL) { |
818 | |
819 | /* |
820 | * Create and initialize a new node. |
821 | */ |
822 | |
823 | nodePtr = ns_malloc(sizeof(Node)); |
824 | nodePtr->id = id; |
825 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexAdd">Ns_IndexAdd</a>(triePtr->indexnode, nodePtr); |
826 | nodePtr->dataInherit = NULL; |
827 | nodePtr->dataNoInherit = NULL; |
828 | nodePtr->deletefuncInherit = NULL; |
829 | nodePtr->deletefuncNoInherit = NULL; |
830 | } else { |
831 | |
832 | /* |
833 | * If NS_OP_NODELETE is NOT set, then delete the current node |
834 | * because one already exists. |
835 | */ |
836 | |
837 | if ((flags & NS_OP_NODELETE) == 0) { |
838 | if ((flags & NS_OP_NOINHERIT) != 0) { |
839 | if (nodePtr->deletefuncNoInherit != NULL) { |
840 | (*nodePtr->deletefuncNoInherit) |
841 | (nodePtr->dataNoInherit); |
842 | } |
843 | } else { |
844 | if (nodePtr->deletefuncInherit != NULL) { |
845 | (*nodePtr->deletefuncInherit) (nodePtr->dataInherit); |
846 | } |
847 | } |
848 | } |
849 | } |
850 | |
851 | if (flags & NS_OP_NOINHERIT) { |
852 | nodePtr->dataNoInherit = data; |
853 | nodePtr->deletefuncNoInherit = deletefunc; |
854 | } else { |
855 | nodePtr->dataInherit = data; |
856 | nodePtr->deletefuncInherit = deletefunc; |
857 | } |
858 | } else { |
859 | Branch *branchPtr; |
860 | |
861 | /* |
862 | * We are parsing the middle of a sequence, such as "foo" in: |
863 | * "server1\0GET\0foo\0*.html\0" |
864 | * |
865 | * Create a new branch and recurse to add the next word in the |
866 | * sequence. |
867 | */ |
868 | |
869 | branchPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(&triePtr->branches, seq); |
870 | if (branchPtr == NULL) { |
871 | branchPtr = ns_malloc(sizeof(Branch)); |
872 | branchPtr->word = ns_strdup(seq); |
873 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieInit">TrieInit</a>(&branchPtr->node); |
874 | |
875 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexAdd">Ns_IndexAdd</a>(&triePtr->branches, branchPtr); |
876 | } |
877 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieAdd">TrieAdd</a>(&branchPtr->node, seq + strlen(seq) + 1, id, data, flags, |
878 | deletefunc); |
879 | } |
880 | } |
881 | |
882 | |
883 | /* |
884 | *---------------------------------------------------------------------- |
885 | * |
886 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieTrunc">TrieTrunc</a> -- |
887 | * |
888 | * Wipes out all references to id. If id==-1 then it wipes out |
889 | * everything. |
890 | * |
891 | * Results: |
892 | * None |
893 | * |
894 | * Side effects: |
895 | * Nodes and branches may be destroyed/freed. |
896 | * |
897 | *---------------------------------------------------------------------- |
898 | */ |
899 | |
900 | static void |
901 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieTrunc">TrieTrunc</a>(Trie *triePtr, int id) |
902 | { |
903 | int n; |
904 | |
905 | n = Ns_IndexCount(&triePtr->branches); |
906 | |
907 | if (n > 0) { |
908 | /* |
909 | * Loop over each branch and recurse. |
910 | */ |
911 | |
912 | int i; |
913 | |
914 | for (i = 0; i < n; i++) { |
915 | Branch *branchPtr; |
916 | |
917 | branchPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&triePtr->branches, i); |
918 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieTrunc">TrieTrunc</a>(&branchPtr->node, id); |
919 | } |
920 | } |
921 | if (triePtr->indexnode != NULL) { |
922 | if (id != -1) { |
923 | Node *nodePtr; |
924 | |
925 | /* |
926 | * Destroy just the node for this ID |
927 | */ |
928 | |
929 | nodePtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(triePtr->indexnode, (void *) id); |
930 | if (nodePtr != NULL) { |
931 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_NodeDestroy">NodeDestroy</a>(nodePtr); |
932 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexDel">Ns_IndexDel</a>(triePtr->indexnode, nodePtr); |
933 | } |
934 | } else { |
935 | |
936 | /* |
937 | * Destroy the whole index of nodes. |
938 | */ |
939 | |
940 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_IndexNodeDestroy">IndexNodeDestroy</a>(triePtr->indexnode); |
941 | triePtr->indexnode = NULL; |
942 | } |
943 | } |
944 | } |
945 | |
946 | |
947 | /* |
948 | *---------------------------------------------------------------------- |
949 | * |
950 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDestroy">TrieDestroy</a> -- |
951 | * |
952 | * Delete an entire Trie. |
953 | * |
954 | * Results: |
955 | * None. |
956 | * |
957 | * Side effects: |
958 | * Will free all the elements of the trie. |
959 | * |
960 | *---------------------------------------------------------------------- |
961 | */ |
962 | |
963 | static void |
964 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDestroy">TrieDestroy</a>(Trie *triePtr) |
965 | { |
966 | int n; |
967 | |
968 | n = Ns_IndexCount(&triePtr->branches); |
969 | |
970 | if (n > 0) { |
971 | int i; |
972 | |
973 | /* |
974 | * Loop over each branch and delete it |
975 | */ |
976 | |
977 | for (i = 0; i < n; i++) { |
978 | Branch *branchPtr; |
979 | |
980 | branchPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&triePtr->branches, i); |
981 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_BranchDestroy">BranchDestroy</a>(branchPtr); |
982 | } |
983 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexDestroy">Ns_IndexDestroy</a>(&triePtr->branches); |
984 | } |
985 | if (triePtr->indexnode != NULL) { |
986 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_IndexNodeDestroy">IndexNodeDestroy</a>(triePtr->indexnode); |
987 | } |
988 | } |
989 | |
990 | |
991 | /* |
992 | *---------------------------------------------------------------------- |
993 | * |
994 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieBranchTrunc">TrieBranchTrunc</a> -- |
995 | * |
996 | * Cut off a branch from a trie |
997 | * |
998 | * Results: |
999 | * 0 on success, -1 on failure |
1000 | * |
1001 | * Side effects: |
1002 | * Will delete a branch. |
1003 | * |
1004 | *---------------------------------------------------------------------- |
1005 | */ |
1006 | |
1007 | static int |
1008 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieBranchTrunc">TrieBranchTrunc</a>(Trie *triePtr, char *seq, int id) |
1009 | { |
1010 | if (*seq != '\0') { |
1011 | Branch *branchPtr; |
1012 | |
1013 | branchPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(&triePtr->branches, seq); |
1014 | |
1015 | /* |
1016 | * If this sequence exists, recursively delete it; otherwise |
1017 | * return an error. |
1018 | */ |
1019 | |
1020 | if (branchPtr != NULL) { |
1021 | return <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieBranchTrunc">TrieBranchTrunc</a>(&branchPtr->node, seq + strlen(seq) + 1, |
1022 | id); |
1023 | } else { |
1024 | return -1; |
1025 | } |
1026 | } else { |
1027 | /* |
1028 | * The end of the sequence has been reached. Finish up the job |
1029 | * and return success. |
1030 | */ |
1031 | |
1032 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieTrunc">TrieTrunc</a>(triePtr, id); |
1033 | return 0; |
1034 | } |
1035 | } |
1036 | |
1037 | |
1038 | /* |
1039 | *---------------------------------------------------------------------- |
1040 | * |
1041 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFind">TrieFind</a> -- |
1042 | * |
1043 | * Find a node in a trie matching a sequence. |
1044 | * |
1045 | * Results: |
1046 | * Return the appropriate node's data. |
1047 | * |
1048 | * Side effects: |
1049 | * The depth variable will be set-by-reference to the depth of |
1050 | * the returned node. If no node is set, it will not be changed. |
1051 | * |
1052 | *---------------------------------------------------------------------- |
1053 | */ |
1054 | |
1055 | static void * |
1056 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFind">TrieFind</a>(Trie *triePtr, char *seq, int id, int *depthPtr) |
1057 | { |
1058 | void *data; |
1059 | int ldepth; |
1060 | |
1061 | data = NULL; |
1062 | ldepth = *depthPtr; |
1063 | if (triePtr->indexnode != NULL) { |
1064 | Node *nodePtr; |
1065 | |
1066 | /* |
1067 | * We've reached a trie with an indexnode, which means that our |
1068 | * data may be here. (If node is null that means that there |
1069 | * is data at this branch, but not with this particular ID). |
1070 | */ |
1071 | |
1072 | nodePtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(triePtr->indexnode, (void *) id); |
1073 | |
1074 | if (nodePtr != NULL) { |
1075 | if ((*seq == '\0') && (nodePtr->dataNoInherit != NULL)) { |
1076 | data = nodePtr->dataNoInherit; |
1077 | } else { |
1078 | data = nodePtr->dataInherit; |
1079 | } |
1080 | } |
1081 | } |
1082 | if (*seq != '\0') { |
1083 | Branch *branchPtr; |
1084 | |
1085 | /* |
1086 | * We have not yet reached the end of the sequence, so |
1087 | * recurse if there are any sub-branches |
1088 | */ |
1089 | |
1090 | branchPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(&triePtr->branches, seq); |
1091 | ldepth += 1; |
1092 | if (branchPtr != NULL) { |
1093 | void *p = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFind">TrieFind</a>(&branchPtr->node, seq + strlen(seq) + 1, id, |
1094 | &ldepth); |
1095 | |
1096 | if (p != NULL) { |
1097 | data = p; |
1098 | *depthPtr = ldepth; |
1099 | } |
1100 | } |
1101 | } |
1102 | |
1103 | return data; |
1104 | } |
1105 | |
1106 | |
1107 | /* |
1108 | *---------------------------------------------------------------------- |
1109 | * |
1110 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFindExact">TrieFindExact</a> -- |
1111 | * |
1112 | * Similar to <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFind">TrieFind</a>, but will not do inheritance. |
1113 | * if (flags & NS_OP_NOINHERIT) then data set with |
1114 | * that flag will be returned; otherwise only data set without that |
1115 | * flag will be returned. |
1116 | * |
1117 | * Results: |
1118 | * See <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFind">TrieFind</a>. |
1119 | * |
1120 | * Side effects: |
1121 | * None. |
1122 | * |
1123 | *---------------------------------------------------------------------- |
1124 | */ |
1125 | |
1126 | static void * |
1127 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFindExact">TrieFindExact</a>(Trie *triePtr, char *seq, int id, int flags) |
1128 | { |
1129 | void *data; |
1130 | |
1131 | data = NULL; |
1132 | if (*seq != '\0') { |
1133 | Branch *branchPtr; |
1134 | |
1135 | /* |
1136 | * We have not reached the end of the sequence yet, so |
1137 | * we must recurse. |
1138 | */ |
1139 | |
1140 | branchPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(&triePtr->branches, seq); |
1141 | if (branchPtr != NULL) { |
1142 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFindExact">TrieFindExact</a>(&branchPtr->node, seq + strlen(seq) + 1, id, |
1143 | flags); |
1144 | } |
1145 | } else if (triePtr->indexnode != NULL) { |
1146 | Node *nodePtr; |
1147 | |
1148 | /* |
1149 | * We reached the end of the sequence. Grab the data from |
1150 | * this node. If the flag specifies NOINHERIT, then return |
1151 | * the non-inheriting data, otherwise return the inheriting |
1152 | * data. |
1153 | */ |
1154 | |
1155 | nodePtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(triePtr->indexnode, (void *) id); |
1156 | if (nodePtr != NULL) { |
1157 | if (flags & NS_OP_NOINHERIT) { |
1158 | data = nodePtr->dataNoInherit; |
1159 | } else { |
1160 | data = nodePtr->dataInherit; |
1161 | } |
1162 | } |
1163 | } |
1164 | |
1165 | return data; |
1166 | } |
1167 | |
1168 | |
1169 | /* |
1170 | *---------------------------------------------------------------------- |
1171 | * |
1172 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDelete">TrieDelete</a> -- |
1173 | * |
1174 | * Delete a url, defined by a sequence, from a trie. |
1175 | * |
1176 | * The NS_OP_NOINHERIT bit may be set in flags to use |
1177 | * noninheriting data; NS_OP_NODELETE may be set to |
1178 | * skip calling the delete function. |
1179 | * |
1180 | * Results: |
1181 | * A pointer to the now-deleted data. |
1182 | * |
1183 | * Side effects: |
1184 | * Data may be deleted. |
1185 | * |
1186 | *---------------------------------------------------------------------- |
1187 | */ |
1188 | |
1189 | static void * |
1190 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDelete">TrieDelete</a>(Trie *triePtr, char *seq, int id, int flags) |
1191 | { |
1192 | void *data; |
1193 | |
1194 | data = NULL; |
1195 | if (*seq != '\0') { |
1196 | Branch *branchPtr; |
1197 | |
1198 | /* |
1199 | * We have not yet reached the end of the sequence. So |
1200 | * recurse. |
1201 | */ |
1202 | |
1203 | branchPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(&triePtr->branches, seq); |
1204 | if (branchPtr != NULL) { |
1205 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDelete">TrieDelete</a>(&branchPtr->node, seq + strlen(seq) + 1, id, |
1206 | flags); |
1207 | } |
1208 | } else if (triePtr->indexnode != NULL) { |
1209 | Node *nodePtr; |
1210 | |
1211 | /* |
1212 | * We've reached the end of the sequence; if a node exists for |
1213 | * this ID then delete the inheriting/noninheriting data (as |
1214 | * specified in flags) and call the delte func if requested. |
1215 | * The data will be set to null either way. |
1216 | */ |
1217 | |
1218 | nodePtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(triePtr->indexnode, (void *) id); |
1219 | if (nodePtr != NULL) { |
1220 | if (flags & NS_OP_NOINHERIT) { |
1221 | data = nodePtr->dataNoInherit; |
1222 | nodePtr->dataNoInherit = NULL; |
1223 | if (nodePtr->deletefuncNoInherit != NULL) { |
1224 | if (!(flags & NS_OP_NODELETE)) { |
1225 | (*nodePtr->deletefuncNoInherit) (data); |
1226 | } |
1227 | nodePtr->deletefuncNoInherit = NULL; |
1228 | } |
1229 | } else { |
1230 | data = nodePtr->dataInherit; |
1231 | nodePtr->dataInherit = NULL; |
1232 | if (nodePtr->deletefuncInherit != NULL) { |
1233 | if (!(flags & NS_OP_NODELETE)) { |
1234 | (*nodePtr->deletefuncInherit) (data); |
1235 | } |
1236 | nodePtr->deletefuncInherit = NULL; |
1237 | } |
1238 | } |
1239 | } |
1240 | } |
1241 | |
1242 | return data; |
1243 | } |
1244 | |
1245 | #ifndef __URLSPACE_OPTIMIZE__ |
1246 | |
1247 | /* |
1248 | *---------------------------------------------------------------------- |
1249 | * |
1250 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpChannels">CmpChannels</a> -- |
1251 | * |
1252 | * Compare the filters of two channels. |
1253 | * |
1254 | * Results: |
1255 | * 0: Not the case that one contains the other OR they both |
1256 | * contain each other; 1: left contains right; -1: right contans |
1257 | * left. |
1258 | * |
1259 | * Side effects: |
1260 | * None. |
1261 | * |
1262 | *---------------------------------------------------------------------- |
1263 | */ |
1264 | |
1265 | static int |
1266 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpChannels">CmpChannels</a>(Channel **leftPtrPtr, Channel **rightPtrPtr) |
1267 | { |
1268 | int lcontainsr, rcontainsl; |
1269 | |
1270 | lcontainsr = Tcl_StringMatch((*rightPtrPtr)->filter, |
1271 | (*leftPtrPtr)->filter); |
1272 | rcontainsl = Tcl_StringMatch((*leftPtrPtr)->filter, |
1273 | (*rightPtrPtr)->filter); |
1274 | |
1275 | if (lcontainsr && rcontainsl) { |
1276 | return 0; |
1277 | } else if (lcontainsr) { |
1278 | return 1; |
1279 | } else if (rcontainsl) { |
1280 | return -1; |
1281 | } else { |
1282 | return 0; |
1283 | } |
1284 | } |
1285 | |
1286 | |
1287 | /* |
1288 | *---------------------------------------------------------------------- |
1289 | * |
1290 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithChannel">CmpKeyWithChannel</a> -- |
1291 | * |
1292 | * Compare a key to a channel's filter |
1293 | * |
1294 | * Results: |
1295 | * 0: Not the case that one contains the other OR they both |
1296 | * contain each other; 1: key contains filter; -1: filter |
1297 | * contains key |
1298 | * |
1299 | * Side effects: |
1300 | * None |
1301 | * |
1302 | *---------------------------------------------------------------------- |
1303 | */ |
1304 | |
1305 | static int |
1306 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithChannel">CmpKeyWithChannel</a>(char *key, Channel **channelPtrPtr) |
1307 | { |
1308 | int lcontainsr, rcontainsl; |
1309 | |
1310 | lcontainsr = Tcl_StringMatch((*channelPtrPtr)->filter, key); |
1311 | rcontainsl = Tcl_StringMatch(key, (*channelPtrPtr)->filter); |
1312 | if (lcontainsr && rcontainsl) { |
1313 | return 0; |
1314 | } else if (lcontainsr) { |
1315 | return 1; |
1316 | } else if (rcontainsl) { |
1317 | return -1; |
1318 | } else { |
1319 | /* |
1320 | * Neither is the case |
1321 | */ |
1322 | |
1323 | return 0; |
1324 | } |
1325 | } |
1326 | #endif |
1327 | |
1328 | |
1329 | /* |
1330 | *---------------------------------------------------------------------- |
1331 | * |
1332 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpChannelsAsStrings">CmpChannelsAsStrings</a> -- |
1333 | * |
1334 | * Compare the filters of two channels. |
1335 | * |
1336 | * Results: |
1337 | * Same as strcmp. |
1338 | * |
1339 | * Side effects: |
1340 | * None. |
1341 | * |
1342 | *---------------------------------------------------------------------- |
1343 | */ |
1344 | |
1345 | static int |
1346 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpChannelsAsStrings">CmpChannelsAsStrings</a>(Channel **leftPtrPtr, Channel **rightPtrPtr) |
1347 | { |
1348 | return strcmp((*leftPtrPtr)->filter, (*rightPtrPtr)->filter); |
1349 | } |
1350 | |
1351 | |
1352 | /* |
1353 | *---------------------------------------------------------------------- |
1354 | * |
1355 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithChannelAsStrings">CmpKeyWithChannelAsStrings</a> -- |
1356 | * |
1357 | * Compare a string key to a channel's filter |
1358 | * |
1359 | * Results: |
1360 | * Same as strcmp. |
1361 | * |
1362 | * Side effects: |
1363 | * None. |
1364 | * |
1365 | *---------------------------------------------------------------------- |
1366 | */ |
1367 | |
1368 | static int |
1369 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithChannelAsStrings">CmpKeyWithChannelAsStrings</a>(char *key, Channel **channelPtrPtr) |
1370 | { |
1371 | return strcmp(key, (*channelPtrPtr)->filter); |
1372 | } |
1373 | |
1374 | |
1375 | /* |
1376 | *---------------------------------------------------------------------- |
1377 | * |
1378 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionInit">JunctionInit</a> -- |
1379 | * |
1380 | * Initialize a junction. |
1381 | * |
1382 | * Results: |
1383 | * None. |
1384 | * |
1385 | * Side effects: |
1386 | * Will set up the index in a junction. |
1387 | * |
1388 | *---------------------------------------------------------------------- |
1389 | */ |
1390 | |
1391 | static void |
1392 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionInit">JunctionInit</a>(Junction *juncPtr) |
1393 | { |
1394 | #ifndef __URLSPACE_OPTIMIZE__ |
1395 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexInit">Ns_IndexInit</a>(&juncPtr->byuse, 5, |
1396 | (int (*) (const void *, const void *)) <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpChannels">CmpChannels</a>, |
1397 | (int (*) (const void *, const void *)) <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithChannel">CmpKeyWithChannel</a>); |
1398 | #endif |
1399 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexInit">Ns_IndexInit</a>(&juncPtr->byname, 5, |
1400 | (int (*) (const void *, const void *)) <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpChannelsAsStrings">CmpChannelsAsStrings</a>, |
1401 | (int (*) (const void *, const void *)) <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_CmpKeyWithChannelAsStrings">CmpKeyWithChannelAsStrings</a>); |
1402 | } |
1403 | |
1404 | |
1405 | /* |
1406 | *---------------------------------------------------------------------- |
1407 | * |
1408 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionBranchTrunc">JunctionBranchTrunc</a> -- |
1409 | * |
1410 | * Truncate a branch, defined by a sequence and ID, in a |
1411 | * junction |
1412 | * |
1413 | * Results: |
1414 | * None. |
1415 | * |
1416 | * Side effects: |
1417 | * See <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieBranchTrunc">TrieBranchTrunc</a> |
1418 | * |
1419 | *---------------------------------------------------------------------- |
1420 | */ |
1421 | |
1422 | static void |
1423 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionBranchTrunc">JunctionBranchTrunc</a>(Junction *juncPtr, char *seq, int id) |
1424 | { |
1425 | int i; |
1426 | int n; |
1427 | |
1428 | /* |
1429 | * Loop over every channel in a junction and <a href="/cvs/aolserver/aolserver/nsd/nswin32.c#A_truncate">truncate</a> the sequence in |
1430 | * each. |
1431 | */ |
1432 | |
1433 | #ifndef __URLSPACE_OPTIMIZE__ |
1434 | n = Ns_IndexCount(&juncPtr->byuse); |
1435 | for (i = 0; i < n; i++) { |
1436 | Channel *channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&juncPtr->byuse, i); |
1437 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieBranchTrunc">TrieBranchTrunc</a>(&channelPtr->trie, seq, id); |
1438 | } |
1439 | #else |
1440 | n = Ns_IndexCount(&juncPtr->byname); |
1441 | for (i = (n - 1); i >= 0; i--) { |
1442 | Channel *channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&juncPtr->byname, i); |
1443 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieBranchTrunc">TrieBranchTrunc</a>(&channelPtr->trie, seq, id); |
1444 | } |
1445 | #endif |
1446 | } |
1447 | |
1448 | |
1449 | /* |
1450 | *---------------------------------------------------------------------- |
1451 | * |
1452 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionAdd">JunctionAdd</a> -- |
1453 | * |
1454 | * This function is called from <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_Ns_UrlSpecificSet">Ns_UrlSpecificSet</a> which is |
1455 | * usually called from <a href="/cvs/aolserver/aolserver/nsd/op.c#A_Ns_RegisterRequest">Ns_RegisterRequest</a>, |
1456 | * <a href="/cvs/aolserver/aolserver/nsd/op.c#A_Ns_RegisterProxyRequest">Ns_RegisterProxyRequest</a>, InitAliases for mapping aliases, and |
1457 | * the nsperm functions TribeAlloc and Ns_AddPermission for |
1458 | * adding permissions. It adds a sequence, terminating in a new |
1459 | * node, to a junction. |
1460 | * |
1461 | * Flags may be a bit-combination of NS_OP_NOINHERIT, NS_OP_NODELETE. |
1462 | * NOINHERIT sets the data as noninheriting, so only an exact sequence |
1463 | * will match in the future; NODELETE means that if a node already |
1464 | * exists with this sequence/ID it will not be deleted but replaced. |
1465 | * |
1466 | * Results: |
1467 | * None. |
1468 | * |
1469 | * Side effects: |
1470 | * Modifies seq, assuming |
1471 | * seq = "handle\0method\0urltoken\0urltoken\0..\0\0\" |
1472 | * |
1473 | *---------------------------------------------------------------------- |
1474 | */ |
1475 | |
1476 | static void |
1477 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionAdd">JunctionAdd</a>(Junction *juncPtr, char *seq, int id, void *data, int flags, |
1478 | void (*deletefunc) (void *)) |
1479 | { |
1480 | Channel *channelPtr; |
1481 | Ns_DString dsWord; |
1482 | char *p; |
1483 | int l; |
1484 | int depth; |
1485 | |
1486 | depth = 0; |
1487 | |
1488 | /* |
1489 | * Find out how deep the sequence is, and position p at the |
1490 | * beginning of the last word in the sequence. |
1491 | */ |
1492 | |
1493 | for (p = seq; p[l = strlen(p) + 1] != '\0'; p += l) { |
1494 | depth++; |
1495 | } |
1496 | |
1497 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&dsWord); |
1498 | |
1499 | /* |
1500 | * If it's a valid sequence that has a wildcard in its last element, |
1501 | * append the whole string to dsWord, then cut off the last word from |
1502 | * p. |
1503 | * Otherwise, set dsWord to "*" because there is an implicit * wildcard |
1504 | * at the end of URLs like /foo/bar |
1505 | * |
1506 | * dsWord will eventually be used to set or find&reuse a channel filter. |
1507 | */ |
1508 | |
1509 | if ((p != NULL) && (depth > 1) && (strchr(p, '*') || strchr(p, '?'))) { |
1510 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringAppend">Ns_DStringAppend</a>(&dsWord, p); |
1511 | *p = '\0'; |
1512 | } else { |
1513 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringAppend">Ns_DStringAppend</a>(&dsWord, "*"); |
1514 | } |
1515 | |
1516 | /* |
1517 | * Find a channel whose filter matches what the filter on this URL |
1518 | * should be. |
1519 | */ |
1520 | |
1521 | channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexFind">Ns_IndexFind</a>(&juncPtr->byname, dsWord.string); |
1522 | |
1523 | /* |
1524 | * If no channel is found, create a new channel and add it to the |
1525 | * list of channels in the junction. |
1526 | */ |
1527 | |
1528 | if (channelPtr == NULL) { |
1529 | channelPtr = (Channel *) ns_malloc(sizeof(Channel)); |
1530 | channelPtr->filter = ns_strdup(dsWord.string); |
1531 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieInit">TrieInit</a>(&channelPtr->trie); |
1532 | |
1533 | #ifndef __URLSPACE_OPTIMIZE__ |
1534 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexAdd">Ns_IndexAdd</a>(&juncPtr->byuse, channelPtr); |
1535 | #endif |
1536 | <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexAdd">Ns_IndexAdd</a>(&juncPtr->byname, channelPtr); |
1537 | } |
1538 | |
1539 | /* |
1540 | * Now we need to create a sequence of branches in the trie (if no |
1541 | * appropriate sequence already exists) and a node at the end of it. |
1542 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieAdd">TrieAdd</a> will do that. |
1543 | */ |
1544 | |
1545 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieAdd">TrieAdd</a>(&channelPtr->trie, seq, id, data, flags, deletefunc); |
1546 | |
1547 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringFree">Ns_DStringFree</a>(&dsWord); |
1548 | } |
1549 | |
1550 | |
1551 | |
1552 | /* |
1553 | *---------------------------------------------------------------------- |
1554 | * |
1555 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionFind">JunctionFind</a> -- |
1556 | * |
1557 | * Locate a node for a given sequence in a junction. |
1558 | * As usual sequence is "handle\0method\0urltoken\0...\0\0". |
1559 | * |
1560 | * The "fast" boolean switch makes it do strcmp instead of |
1561 | * Tcl string matches on the filters. Not useful for wildcard |
1562 | * matching. |
1563 | * |
1564 | * Results: |
1565 | * User data |
1566 | * |
1567 | * Side effects: |
1568 | * None. |
1569 | * |
1570 | *---------------------------------------------------------------------- |
1571 | */ |
1572 | |
1573 | static void * |
1574 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionFind">JunctionFind</a>(Junction *juncPtr, char *seq, int id, int fast) |
1575 | { |
1576 | char *p; |
1577 | int l; |
1578 | int i, n; |
1579 | void *data; |
1580 | int depth; |
1581 | |
1582 | n = 0; |
1583 | |
1584 | /* |
1585 | * After this loop, p will point at the last element in the sequence. |
1586 | * n will be the number of elements in the sequence. |
1587 | */ |
1588 | |
1589 | for (p = seq; p[l = strlen(p) + 1] != '\0'; p += l) { |
1590 | n++; |
1591 | } |
1592 | |
1593 | if (n < 2) { |
1594 | /* |
1595 | * If there are fewer than 2 elements then advance p to the |
1596 | * end of the string. |
1597 | */ |
1598 | p += strlen(p) + 1; |
1599 | } |
1600 | |
1601 | /* |
1602 | * Check filters from most restrictive to least restrictive |
1603 | */ |
1604 | |
1605 | data = NULL; |
1606 | #ifndef __URLSPACE_OPTIMIZE__ |
1607 | l = Ns_IndexCount(&juncPtr->byuse); |
1608 | #else |
1609 | l = Ns_IndexCount(&juncPtr->byname); |
1610 | #endif |
1611 | |
1612 | #ifdef DEBUG |
1613 | if (n >= 2) { |
1614 | fprintf(stderr, "Checking Id=%d, Seq=", id); |
1615 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintSeq">PrintSeq</a>(seq); |
1616 | fputs("\n", stderr); |
1617 | } |
1618 | #endif |
1619 | |
1620 | /* |
1621 | * For __URLSPACE_OPTIMIZE__ |
1622 | * Basically if we use the optimize, let's reverse the order |
1623 | * by which we search because the byname is in "almost" exact |
1624 | * reverse lexicographical order. |
1625 | * |
1626 | * Loop over all the channels in the index. |
1627 | */ |
1628 | |
1629 | #ifndef __URLSPACE_OPTIMIZE__ |
1630 | for (i = 0; i < l; i++) { |
1631 | Channel *channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&juncPtr->byuse, i); |
1632 | #else |
1633 | for (i = (l - 1); i >= 0; i--) { |
1634 | Channel *channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&juncPtr->byname, i); |
1635 | #endif |
1636 | int doit; |
1637 | |
1638 | if (fast) { |
1639 | doit = !strcmp(p, channelPtr->filter); |
1640 | } else { |
1641 | doit = Tcl_StringMatch(p, channelPtr->filter); |
1642 | } |
1643 | if (doit) { |
1644 | /* |
1645 | * We got here because this url matches the filter |
1646 | * (for example, it's *.adp). |
1647 | */ |
1648 | |
1649 | if (data == NULL) { |
1650 | /* |
1651 | * Nothing has been found so far. Traverse the channel |
1652 | * and find the node; set data to that. Depth will be |
1653 | * set to the level of the node. |
1654 | */ |
1655 | |
1656 | depth = 0; |
1657 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFind">TrieFind</a>(&channelPtr->trie, seq, id, &depth); |
1658 | } else { |
1659 | void *candidate; |
1660 | int cdepth; |
1661 | |
1662 | /* |
1663 | * Let's see if this channel has a node that also matches |
1664 | * the sequence but is more specific (has a greater depth) |
1665 | * that the previously found node. |
1666 | */ |
1667 | |
1668 | cdepth = 0; |
1669 | candidate = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFind">TrieFind</a>(&channelPtr->trie, seq, id, &cdepth); |
1670 | if ((candidate != NULL) && (cdepth > depth)) { |
1671 | data = candidate; |
1672 | depth = cdepth; |
1673 | } |
1674 | } |
1675 | } |
1676 | |
1677 | #ifdef DEBUG |
1678 | if (n >= 2) { |
1679 | if (data == NULL) { |
1680 | fprintf(stderr, "Channel %s: No match\n", |
1681 | channelPtr->filter); |
1682 | } else { |
1683 | fprintf(stderr, "Channel %s: depth=%d, data=%p\n", |
1684 | channelPtr->filter, depth, data); |
1685 | } |
1686 | } |
1687 | #endif |
1688 | } |
1689 | |
1690 | #ifdef DEBUG |
1691 | if (n >= 2) { |
1692 | fprintf(stderr, "Done.\n"); |
1693 | } |
1694 | #endif |
1695 | |
1696 | return data; |
1697 | } |
1698 | |
1699 | |
1700 | /* |
1701 | *---------------------------------------------------------------------- |
1702 | * |
1703 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionFindExact">JunctionFindExact</a> -- |
1704 | * |
1705 | * Find a node in a junction that exactly matches a sequence. |
1706 | * |
1707 | * Results: |
1708 | * User data. |
1709 | * |
1710 | * Side effects: |
1711 | * None. |
1712 | * |
1713 | *---------------------------------------------------------------------- |
1714 | */ |
1715 | |
1716 | static void * |
1717 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionFindExact">JunctionFindExact</a>(Junction *juncPtr, char *seq, int id, int flags, int fast) |
1718 | { |
1719 | char *p; |
1720 | int l; |
1721 | int i; |
1722 | int depth; |
1723 | void *data; |
1724 | |
1725 | depth = 0; |
1726 | |
1727 | /* |
1728 | * Set p to the last element of the sequence, and |
1729 | * depth to the number of elements in the sequence. |
1730 | */ |
1731 | |
1732 | for (p = seq; p[l = strlen(p) + 1] != '\0'; p += l) { |
1733 | depth++; |
1734 | } |
1735 | |
1736 | data = NULL; |
1737 | |
1738 | /* |
1739 | * First, loop through all the channels that have non-"*" |
1740 | * filters looking for an exact match |
1741 | */ |
1742 | |
1743 | #ifndef __URLSPACE_OPTIMIZE__ |
1744 | l = Ns_IndexCount(&juncPtr->byuse); |
1745 | |
1746 | for (i = 0; i < l; i++) { |
1747 | Channel *channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&juncPtr->byuse, i); |
1748 | #else |
1749 | l = Ns_IndexCount(&juncPtr->byname); |
1750 | |
1751 | for (i = (l - 1); i >= 0; i--) { |
1752 | Channel *channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&juncPtr->byname, i); |
1753 | #endif |
1754 | if (strcmp(p, channelPtr->filter) == 0) { |
1755 | /* |
1756 | * The last element of the sequence exactly matches the |
1757 | * filter, so this is the one. Wipe out the last word and |
1758 | * return whatever node coems out of <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFindExact">TrieFindExact</a>. |
1759 | */ |
1760 | |
1761 | *p = '\0'; |
1762 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFindExact">TrieFindExact</a>(&channelPtr->trie, seq, id, flags); |
1763 | goto done; |
1764 | } |
1765 | } |
1766 | |
1767 | /* |
1768 | * Now go to the channel with the "*" filter and look there for |
1769 | * an exact match: |
1770 | */ |
1771 | |
1772 | #ifndef __URLSPACE_OPTIMIZE__ |
1773 | for (i = 0; i < l; i++) { |
1774 | Channel *channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&juncPtr->byuse, i); |
1775 | #else |
1776 | for (i = (l - 1); i >= 0; i--) { |
1777 | Channel *channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&juncPtr->byname, i); |
1778 | #endif |
1779 | if (strcmp("*", channelPtr->filter) == 0) { |
1780 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFindExact">TrieFindExact</a>(&channelPtr->trie, seq, id, flags); |
1781 | break; |
1782 | } |
1783 | } |
1784 | |
1785 | done: |
1786 | |
1787 | return data; |
1788 | } |
1789 | |
1790 | |
1791 | /* |
1792 | *---------------------------------------------------------------------- |
1793 | * |
1794 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionDelete">JunctionDelete</a> -- |
1795 | * |
1796 | * Delete a node from a junction matching a sequence |
1797 | * |
1798 | * Results: |
1799 | * A pointer to the deleted node |
1800 | * |
1801 | * Side effects: |
1802 | * The node will be deleted if NS_OP_NODELETE isn't set in flags |
1803 | * |
1804 | *---------------------------------------------------------------------- |
1805 | */ |
1806 | |
1807 | static void * |
1808 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_JunctionDelete">JunctionDelete</a>(Junction *juncPtr, char *seq, int id, int flags) |
1809 | { |
1810 | char *p; |
1811 | int l; |
1812 | int i; |
1813 | int depth; |
1814 | void *data; |
1815 | |
1816 | /* |
1817 | * Set p to the last element of the sequence, and |
1818 | * depth to the number of elements in the sequence. |
1819 | */ |
1820 | |
1821 | depth = 0; |
1822 | for (p = seq; p[l = strlen(p) + 1] != '\0'; p += l) { |
1823 | depth++; |
1824 | } |
1825 | |
1826 | data = NULL; |
1827 | |
1828 | #ifndef __URLSPACE_OPTIMIZE__ |
1829 | l = Ns_IndexCount(&juncPtr->byuse); |
1830 | for (i = 0; (i < l) && (data == NULL); i++) { |
1831 | Channel *channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&juncPtr->byuse, i); |
1832 | #else |
1833 | l = Ns_IndexCount(&juncPtr->byname); |
1834 | for (i = (l - 1); (i >= 0) && (data == NULL); i--) { |
1835 | Channel *channelPtr = <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&juncPtr->byname, i); |
1836 | #endif |
1837 | if ((depth == 2) && (strcmp(p, channelPtr->filter) == 0)) { |
1838 | /* |
1839 | * This filter exactly matches the last element of the |
1840 | * sequence, so get the node and delete it. (This is |
1841 | * server-specific data because depth is 2). |
1842 | */ |
1843 | |
1844 | *p = '\0'; |
1845 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFindExact">TrieFindExact</a>(&channelPtr->trie, seq, id, flags); |
1846 | if (data != NULL) { |
1847 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDelete">TrieDelete</a>(&channelPtr->trie, seq, id, flags); |
1848 | } |
1849 | } else if (Tcl_StringMatch(p, channelPtr->filter)) { |
1850 | /* |
1851 | * The filter matches, so get the node and delete it. |
1852 | */ |
1853 | |
1854 | data = <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieFindExact">TrieFindExact</a>(&channelPtr->trie, seq, id, flags); |
1855 | if (data != NULL) { |
1856 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_TrieDelete">TrieDelete</a>(&channelPtr->trie, seq, id, flags); |
1857 | } |
1858 | } |
1859 | } |
1860 | |
1861 | return data; |
1862 | } |
1863 | |
1864 | |
1865 | /* |
1866 | *---------------------------------------------------------------------- |
1867 | * |
1868 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_MkSeq">MkSeq</a> -- |
1869 | * |
1870 | * Build a "sequence" out of a server/method/url; turns it into |
1871 | * "server\0method\0urltoken\0...\0\0" |
1872 | * |
1873 | * Results: |
1874 | * None |
1875 | * |
1876 | * Side effects: |
1877 | * Sequence goes into ds |
1878 | * |
1879 | *---------------------------------------------------------------------- |
1880 | */ |
1881 | |
1882 | static void |
1883 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_MkSeq">MkSeq</a>(Ns_DString *dsPtr, char *server, char *method, char *url) |
1884 | { |
1885 | if ((method != NULL) && (url != NULL)) { |
1886 | char *p; |
1887 | int done; |
1888 | |
1889 | /* |
1890 | * It is URLspecific data, not serverspecific data |
1891 | * if we get here. |
1892 | */ |
1893 | |
1894 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringNAppend">Ns_DStringNAppend</a>(dsPtr, server, (int)(strlen(server) + 1)); |
1895 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringNAppend">Ns_DStringNAppend</a>(dsPtr, method, (int)(strlen(method) + 1)); |
1896 | |
1897 | /* |
1898 | * Loop over each directory in the URL and turn the slashes |
1899 | * into nulls. |
1900 | */ |
1901 | |
1902 | done = 0; |
1903 | while (!done && *url != '\0') { |
1904 | if (*url != '/') { |
1905 | int l; |
1906 | |
1907 | p = strchr(url, '/'); |
1908 | if (p != NULL) { |
1909 | l = p - url; |
1910 | } else { |
1911 | l = strlen(url); |
1912 | done = 1; |
1913 | } |
1914 | |
1915 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringNAppend">Ns_DStringNAppend</a>(dsPtr, url, l++); |
1916 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringNAppend">Ns_DStringNAppend</a>(dsPtr, "\0", 1); |
1917 | url += l; |
1918 | } else { |
1919 | url++; |
1920 | } |
1921 | } |
1922 | |
1923 | /* |
1924 | * Put another null on the end to mark the end of the |
1925 | * string. |
1926 | */ |
1927 | |
1928 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringNAppend">Ns_DStringNAppend</a>(dsPtr, "\0", 1); |
1929 | } else { |
1930 | /* |
1931 | * This is Server-specific data, so there's only going to |
1932 | * be one element. |
1933 | */ |
1934 | |
1935 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringNAppend">Ns_DStringNAppend</a>(dsPtr, server, (int)(strlen(server) + 1)); |
1936 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringNAppend">Ns_DStringNAppend</a>(dsPtr, "\0", 1); |
1937 | } |
1938 | } |
1939 | |
1940 | #ifdef DEBUG |
1941 | |
1942 | /* |
1943 | *---------------------------------------------------------------------- |
1944 | * |
1945 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_indentspace">indentspace</a> -- |
1946 | * |
1947 | * Print n spaces. |
1948 | * |
1949 | * Results: |
1950 | * None. |
1951 | * |
1952 | * Side effects: |
1953 | * Will print to stderr. |
1954 | * |
1955 | *---------------------------------------------------------------------- |
1956 | */ |
1957 | |
1958 | static void |
1959 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_indentspace">indentspace</a>(int n) |
1960 | { |
1961 | int i; |
1962 | |
1963 | fputc('\n', stderr); |
1964 | for (i = 0; i < n; i++) { |
1965 | fputc(' ', stderr); |
1966 | } |
1967 | } |
1968 | |
1969 | |
1970 | /* |
1971 | *---------------------------------------------------------------------- |
1972 | * |
1973 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintTrie">PrintTrie</a> -- |
1974 | * |
1975 | * Output the trie to standard error. |
1976 | * |
1977 | * Results: |
1978 | * None. |
1979 | * |
1980 | * Side effects: |
1981 | * Will write to stderr. |
1982 | * |
1983 | *---------------------------------------------------------------------- |
1984 | */ |
1985 | |
1986 | static void |
1987 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintTrie">PrintTrie</a>(Trie *triePtr, int indent) |
1988 | { |
1989 | int i; |
1990 | |
1991 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_indentspace">indentspace</a>(indent); |
1992 | fprintf(stderr, "Branches:"); |
1993 | for (i = 0; i < (&(triePtr->branches))->n; i++) { |
1994 | Branch *branch; |
1995 | |
1996 | branch = (Branch *) <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&(triePtr->branches), i); |
1997 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_indentspace">indentspace</a>(indent + 2); |
1998 | fprintf(stderr, "(%s):", branch->word); |
1999 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintTrie">PrintTrie</a>(&(branch->node), indent + 4); |
2000 | } |
2001 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_indentspace">indentspace</a>(indent); |
2002 | fprintf(stderr, "IndexNodes:"); |
2003 | if (triePtr->indexnode != NULL) { |
2004 | for (i = 0; i < triePtr->indexnode->n; i++) { |
2005 | Node *nodePtr; |
2006 | |
2007 | nodePtr = (Node *) <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(triePtr->indexnode, i); |
2008 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_indentspace">indentspace</a>(indent + 2); |
2009 | if (nodePtr->dataInherit != NULL) { |
2010 | fprintf(stderr, "(Id: %d, inherit): %p", |
2011 | nodePtr->id, nodePtr->dataInherit); |
2012 | } |
2013 | if (nodePtr->dataNoInherit != NULL) { |
2014 | fprintf(stderr, "(Id: %d, noinherit): %p", |
2015 | nodePtr->id, nodePtr->dataNoInherit); |
2016 | } |
2017 | } |
2018 | } |
2019 | } |
2020 | |
2021 | |
2022 | /* |
2023 | *---------------------------------------------------------------------- |
2024 | * |
2025 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintJunction">PrintJunction</a> -- |
2026 | * |
2027 | * Print a junction to std error. |
2028 | * |
2029 | * Results: |
2030 | * None. |
2031 | * |
2032 | * Side effects: |
2033 | * Will write to stderr. |
2034 | * |
2035 | *---------------------------------------------------------------------- |
2036 | */ |
2037 | |
2038 | static void |
2039 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintJunction">PrintJunction</a>(Junction *junctionPtr) |
2040 | { |
2041 | int i; |
2042 | |
2043 | fprintf(stderr, "Junction:"); |
2044 | |
2045 | #ifndef __URLSPACE_OPTIMIZE__ |
2046 | for (i = 0; i < (&(junctionPtr->byuse))->n; i++) { |
2047 | Channel *channelPtr; |
2048 | channelPtr = (Channel *) <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&(junctionPtr->byuse), i); |
2049 | #else |
2050 | for (i = ((&(junctionPtr->byname))->n - 1); i >= 0; i--) { |
2051 | Channel *channelPtr; |
2052 | channelPtr = (Channel *) <a href="/cvs/aolserver/aolserver/nsd/index.c#A_Ns_IndexEl">Ns_IndexEl</a>(&(junctionPtr->byname), i); |
2053 | #endif |
2054 | fprintf(stderr, "\n Channel[%d]:\n", i); |
2055 | fprintf(stderr, " Filter: %s\n", channelPtr->filter); |
2056 | fprintf(stderr, " Trie:"); |
2057 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintTrie">PrintTrie</a>(&(channelPtr->trie), 4); |
2058 | } |
2059 | } |
2060 | |
2061 | |
2062 | /* |
2063 | *---------------------------------------------------------------------- |
2064 | * |
2065 | * <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintSeq">PrintSeq</a> -- |
2066 | * |
2067 | * Print a null-delimited sequence to stderr. |
2068 | * |
2069 | * Results: |
2070 | * None. |
2071 | * |
2072 | * Side effects: |
2073 | * Will write to stderr. |
2074 | * |
2075 | *---------------------------------------------------------------------- |
2076 | */ |
2077 | |
2078 | static void |
2079 | <a href="/cvs/aolserver/aolserver/nsd/urlspace.c#A_PrintSeq">PrintSeq</a>(char *seq) |
2080 | { |
2081 | char *p; |
2082 | |
2083 | for (p = seq; *p != '\0'; p += strlen(p) + 1) { |
2084 | if (p != seq) { |
2085 | fputs(", ", stderr); |
2086 | } |
2087 | fputs(p, stderr); |
2088 | } |
2089 | } |
2090 | |
2091 | #endif |
Copyright © 2010 Geeknet, Inc. All rights reserved. Terms of Use