There are no available options for this view.

Parent Directory Parent Directory | Revision <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Log">Log</a> Revision <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Log">Log</a>

Revision 1.11 - (show annotations) (download) (as text)
Mon Nov 3 19:23:26 2003 UTC (14 years, 2 months ago) by pkhincha
Branch: MAIN
CVS Tags: aolserver_v4_r0_beta_21, aolserver_v45_r0, aolserver_v40_r10, aolserver_v40_r9, aolserver_v40_r8, aolserver_v40_r7, aolserver_v40_r6, aolserver_v40_r5, aolserver_v40_r3, aolserver_v40_r2, aolserver_v40_r1, aolserver_v40_r0, aolserver_v45_r2_rc0, aolserver_v40_r9_b2, HEAD
Branch point for: aolserver_v45_r1, aolserver_v45_r2, aolserver_v45_bp, aolserver_v40_bp
Changes since 1.10: +1 -2 lines
File MIME type: text/x-chdr
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