src/server/util/pblock.c

branch
cpp-ports
changeset 363
7f0f5c03666a
parent 77
f1cff81e425a
child 365
2ea1ed291e9f
equal deleted inserted replaced
362:e45f218628cd 363:7f0f5c03666a
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5 *
6 * THE BSD LICENSE
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
13 * Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * Neither the name of the nor the names of its contributors may be
18 * used to endorse or promote products derived from this software without
19 * specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /*
35 * pblock.c: Handles Parameter Blocks
36 *
37 * See pblock.h for public documentation.
38 *
39 * Rob McCool
40 *
41 * This code uses property lists to implement pblocks.
42 */
43
44
45 #include "pblock.h"
46 #include "plist_pvt.h"
47 #include "plist.h"
48 #include "util.h" /* util_itoa */
49 #include "pool.h"
50 #include "systhr.h"
51
52 #define MALLOC_POOL_HANDLE (thread_malloc_key != -1 ? (pool_handle_t *)systhread_getdata(thread_malloc_key) : getThreadMallocPool())
53
54 static int thread_malloc_key = -1;
55 static int _pblock_str2pblock(const char* str, pblock* pb, PRBool lowerCase);
56
57 static pool_handle_t *getThreadMallocPool()
58 {
59 pool_handle_t *thread_malloc_pool = 0;
60
61 thread_malloc_key = getThreadMallocKey();
62 if (thread_malloc_key != -1) {
63 thread_malloc_pool = (pool_handle_t *)systhread_getdata(thread_malloc_key);
64 }
65
66 return thread_malloc_pool;
67 }
68
69 /* ---------------------- pb_key static initializers ---------------------- */
70
71 /*
72 * pb_key
73 *
74 * Contains a precomputed hash value for a specific pblock variable name.
75 */
76 typedef struct pb_key pb_key;
77 struct pb_key {
78 const char *name;
79 int namelen;
80 unsigned int hashval;
81 int sizendx;
82 int hashndx;
83 };
84
85 #define PB_KEY_LIST_BUCKET_COUNT 0x7f // has to be (2^n - 1)
86
87 struct pb_key_list_bucket {
88 pb_key *elements;
89 unsigned size;
90 };
91
92 struct pb_key_list {
93 struct pb_key_list_bucket buckets[PB_KEY_LIST_BUCKET_COUNT + 1];
94 };
95
96 static const pb_key *_pb_key_list_insert(struct pb_key_list *hashList, unsigned int hashval, pb_key* element) {
97 struct pb_key_list_bucket *bucket = &hashList->buckets[hashval & PB_KEY_LIST_BUCKET_COUNT];
98 size_t idx = bucket->size;
99 bucket->size++;
100 bucket->elements = realloc(bucket->elements, sizeof(pb_key) * bucket->size);
101 if (bucket->elements == NULL) abort();
102 bucket->elements[idx] = *element;
103 return &bucket->elements[idx];
104 }
105
106 static struct pb_key_list _pbKeys;
107
108 static const pb_key *_create_key(const char *name)
109 {
110 /* Create a the new pb_key */
111 pb_key key;
112 key.name = STRDUP(name);
113 key.namelen = strlen(name);
114 key.hashval = PListHash(name);
115 key.sizendx = 0;
116 key.hashndx = key.hashval % PLSIZENDX(0);
117
118 /* Group pb_keys by hashval for later retrieval */
119 return _pb_key_list_insert(&_pbKeys, key.hashval, &key);
120 }
121
122 const pb_key *pb_key_accept;
123 const pb_key *pb_key_accept_charset;
124 const pb_key *pb_key_accept_encoding;
125 const pb_key *pb_key_accept_language;
126 const pb_key *pb_key_accept_ranges;
127 const pb_key *pb_key_actual_route;
128 const pb_key *pb_key_age;
129 const pb_key *pb_key_always_allow_chunked;
130 const pb_key *pb_key_always_use_keep_alive;
131 const pb_key *pb_key_auth_cert;
132 const pb_key *pb_key_auth_expiring;
133 const pb_key *pb_key_auth_group;
134 const pb_key *pb_key_auth_type;
135 const pb_key *pb_key_auth_user;
136 const pb_key *pb_key_authorization;
137 const pb_key *pb_key_browser;
138 const pb_key *pb_key_c2p_cl;
139 const pb_key *pb_key_c2p_hl;
140 const pb_key *pb_key_cache_info;
141 const pb_key *pb_key_charset;
142 const pb_key *pb_key_check_http_server;
143 const pb_key *pb_key_ChunkedRequestBufferSize;
144 const pb_key *pb_key_ChunkedRequestTimeout;
145 const pb_key *pb_key_cipher;
146 const pb_key *pb_key_clf_request;
147 const pb_key *pb_key_cli_status;
148 const pb_key *pb_key_client_cert_nickname;
149 const pb_key *pb_key_client_ip;
150 const pb_key *pb_key_close;
151 const pb_key *pb_key_connect_timeout;
152 const pb_key *pb_key_connection;
153 const pb_key *pb_key_cont;
154 const pb_key *pb_key_content_encoding;
155 const pb_key *pb_key_content_language;
156 const pb_key *pb_key_content_length;
157 const pb_key *pb_key_content_location;
158 const pb_key *pb_key_content_md5;
159 const pb_key *pb_key_content_range;
160 const pb_key *pb_key_content_type;
161 const pb_key *pb_key_cookie;
162 const pb_key *pb_key_date;
163 const pb_key *pb_key_DATE_GMT;
164 const pb_key *pb_key_DATE_LOCAL;
165 const pb_key *pb_key_dir;
166 const pb_key *pb_key_Directive;
167 const pb_key *pb_key_dns;
168 const pb_key *pb_key_DOCUMENT_NAME;
169 const pb_key *pb_key_DOCUMENT_URI;
170 const pb_key *pb_key_domain;
171 const pb_key *pb_key_enc;
172 const pb_key *pb_key_engine;
173 const pb_key *pb_key_error_action;
174 const pb_key *pb_key_error_desc;
175 const pb_key *pb_key_error_fn;
176 const pb_key *pb_key_escape;
177 const pb_key *pb_key_escaped;
178 const pb_key *pb_key_etag;
179 const pb_key *pb_key_expect;
180 const pb_key *pb_key_expires;
181 const pb_key *pb_key_expr;
182 const pb_key *pb_key_filter;
183 const pb_key *pb_key_find_pathinfo_forward;
184 const pb_key *pb_key_flushTimer;
185 const pb_key *pb_key_fn;
186 const pb_key *pb_key_from;
187 const pb_key *pb_key_full_headers;
188 const pb_key *pb_key_hdr;
189 const pb_key *pb_key_host;
190 const pb_key *pb_key_hostname;
191 const pb_key *pb_key_if_match;
192 const pb_key *pb_key_if_modified_since;
193 const pb_key *pb_key_if_none_match;
194 const pb_key *pb_key_if_range;
195 const pb_key *pb_key_if_unmodified_since;
196 const pb_key *pb_key_ip;
197 const pb_key *pb_key_iponly;
198 const pb_key *pb_key_issuer_dn;
199 const pb_key *pb_key_jroute;
200 const pb_key *pb_key_keep_alive;
201 const pb_key *pb_key_keep_alive_timeout;
202 const pb_key *pb_key_keysize;
203 const pb_key *pb_key_lang;
204 const pb_key *pb_key_last_modified;
205 const pb_key *pb_key_level;
206 const pb_key *pb_key_location;
207 const pb_key *pb_key_lock_owner;
208 const pb_key *pb_key_magnus_charset;
209 const pb_key *pb_key_magnus_internal;
210 const pb_key *pb_key_magnus_internal_dav_src;
211 const pb_key *pb_key_magnus_internal_default_acls_only;
212 const pb_key *pb_key_magnus_internal_error_j2ee;
213 const pb_key *pb_key_magnus_internal_j2ee_nsapi;
214 const pb_key *pb_key_magnus_internal_preserve_srvhdrs;
215 const pb_key *pb_key_magnus_internal_set_request_status;
216 const pb_key *pb_key_magnus_internal_set_response_status;
217 const pb_key *pb_key_magnus_internal_webapp_errordesc;
218 const pb_key *pb_key_matched_browser;
219 const pb_key *pb_key_max_age;
220 const pb_key *pb_key_max_forwards;
221 const pb_key *pb_key_message;
222 const pb_key *pb_key_method;
223 const pb_key *pb_key_name;
224 const pb_key *pb_key_nocache;
225 const pb_key *pb_key_nostat;
226 const pb_key *pb_key_ntrans_base;
227 const pb_key *pb_key_offline_origin_addr;
228 const pb_key *pb_key_offline_proxy_addr;
229 const pb_key *pb_key_origin_addr;
230 const pb_key *pb_key_p2c_cl;
231 const pb_key *pb_key_p2c_hl;
232 const pb_key *pb_key_p2r_cl;
233 const pb_key *pb_key_p2r_hl;
234 const pb_key *pb_key_parse_timeout;
235 const pb_key *pb_key_password;
236 const pb_key *pb_key_path;
237 const pb_key *pb_key_PATH_INFO;
238 const pb_key *pb_key_path_info;
239 const pb_key *pb_key_pblock;
240 const pb_key *pb_key_poll_interval;
241 const pb_key *pb_key_pool; // new
242 const pb_key *pb_key_port;
243 const pb_key *pb_key_ppath;
244 const pb_key *pb_key_pragma;
245 const pb_key *pb_key_process_request_body;
246 const pb_key *pb_key_process_response_body;
247 const pb_key *pb_key_protocol;
248 const pb_key *pb_key_proxy_addr;
249 const pb_key *pb_key_proxy_agent;
250 const pb_key *pb_key_proxy_auth_cert;
251 const pb_key *pb_key_proxy_authorization;
252 const pb_key *pb_key_proxy_cipher;
253 const pb_key *pb_key_proxy_issuer_dn;
254 const pb_key *pb_key_proxy_jroute;
255 const pb_key *pb_key_proxy_keysize;
256 const pb_key *pb_key_proxy_ping;
257 const pb_key *pb_key_proxy_request;
258 const pb_key *pb_key_proxy_secret_keysize;
259 const pb_key *pb_key_proxy_ssl_id;
260 const pb_key *pb_key_proxy_user_dn;
261 const pb_key *pb_key_query;
262 const pb_key *pb_key_QUERY_STRING;
263 const pb_key *pb_key_QUERY_STRING_UNESCAPED;
264 const pb_key *pb_key_r2p_cl;
265 const pb_key *pb_key_r2p_hl;
266 const pb_key *pb_key_range;
267 const pb_key *pb_key_referer;
268 const pb_key *pb_key_reformat_request_headers;
269 const pb_key *pb_key_remote_status;
270 const pb_key *pb_key_request_jroute;
271 const pb_key *pb_key_required_rights;
272 const pb_key *pb_key_retries;
273 const pb_key *pb_key_rewrite_content_location;
274 const pb_key *pb_key_rewrite_host;
275 const pb_key *pb_key_rewrite_location;
276 const pb_key *pb_key_rewrite_set_cookie;
277 const pb_key *pb_key_root;
278 const pb_key *pb_key_route;
279 const pb_key *pb_key_route_cookie;
280 const pb_key *pb_key_route_hdr;
281 const pb_key *pb_key_route_offline;
282 const pb_key *pb_key_script_name;
283 const pb_key *pb_key_secret_keysize;
284 const pb_key *pb_key_secure;
285 const pb_key *pb_key_server;
286 const pb_key *pb_key_set_cookie;
287 const pb_key *pb_key_socks_addr;
288 const pb_key *pb_key_ssl_id;
289 const pb_key *pb_key_ssl_unclean_shutdown;
290 const pb_key *pb_key_status;
291 const pb_key *pb_key_sticky_cookie;
292 const pb_key *pb_key_sticky_param;
293 const pb_key *pb_key_suppress_request_headers;
294 const pb_key *pb_key_svr_status;
295 const pb_key *pb_key_timeout;
296 const pb_key *pb_key_to;
297 const pb_key *pb_key_transfer_encoding;
298 const pb_key *pb_key_transmit_timeout;
299 const pb_key *pb_key_tunnel_non_http_response;
300 const pb_key *pb_key_type;
301 const pb_key *pb_key_upstream_jroute;
302 const pb_key *pb_key_uri;
303 const pb_key *pb_key_url;
304 const pb_key *pb_key_url_prefix;
305 const pb_key *pb_key_UseOutputStreamSize;
306 const pb_key *pb_key_user;
307 const pb_key *pb_key_user_agent;
308 const pb_key *pb_key_user_dn;
309 const pb_key *pb_key_validate_server_cert;
310 const pb_key *pb_key_value;
311 const pb_key *pb_key_vary;
312 const pb_key *pb_key_via;
313 const pb_key *pb_key_warning;
314
315 NSAPI_PUBLIC void pblock_init_default_keys(void) {
316 pb_key_accept = _create_key("accept");
317 pb_key_accept_charset = _create_key("accept-charset");
318 pb_key_accept_encoding = _create_key("accept-encoding");
319 pb_key_accept_language = _create_key("accept-language");
320 pb_key_accept_ranges = _create_key("accept-ranges");
321 pb_key_actual_route = _create_key("actual-route");
322 pb_key_age = _create_key("age");
323 pb_key_always_allow_chunked = _create_key("always-allow-chunked");
324 pb_key_always_use_keep_alive = _create_key("always-use-keep-alive");
325 pb_key_auth_cert = _create_key("auth-cert");
326 pb_key_auth_expiring = _create_key("auth-expiring");
327 pb_key_auth_group = _create_key("auth-group");
328 pb_key_auth_type = _create_key("auth-type");
329 pb_key_auth_user = _create_key("auth-user");
330 pb_key_authorization = _create_key("authorization");
331 pb_key_browser = _create_key("browser");
332 pb_key_c2p_cl = _create_key("c2p-cl");
333 pb_key_c2p_hl = _create_key("c2p-hl");
334 pb_key_cache_info = _create_key("cache-info");
335 pb_key_charset = _create_key("charset");
336 pb_key_check_http_server = _create_key("check-http-server");
337 pb_key_ChunkedRequestBufferSize = _create_key("ChunkedRequestBufferSize");
338 pb_key_ChunkedRequestTimeout = _create_key("ChunkedRequestTimeout");
339 pb_key_cipher = _create_key("cipher");
340 pb_key_clf_request = _create_key("clf-request");
341 pb_key_cli_status = _create_key("cli-status");
342 pb_key_client_cert_nickname = _create_key("client-cert-nickname");
343 pb_key_client_ip = _create_key("client-ip");
344 pb_key_close = _create_key("close");
345 pb_key_connect_timeout = _create_key("connect-timeout");
346 pb_key_connection = _create_key("connection");
347 pb_key_cont = _create_key("cont");
348 pb_key_content_encoding = _create_key("content-encoding");
349 pb_key_content_language = _create_key("content-language");
350 pb_key_content_length = _create_key("content-length");
351 pb_key_content_location = _create_key("content-location");
352 pb_key_content_md5 = _create_key("content-md5");
353 pb_key_content_range = _create_key("content-range");
354 pb_key_content_type = _create_key("content-type");
355 pb_key_cookie = _create_key("cookie");
356 pb_key_date = _create_key("date");
357 pb_key_DATE_GMT = _create_key("DATE_GMT");
358 pb_key_DATE_LOCAL = _create_key("DATE_LOCAL");
359 pb_key_dir = _create_key("dir");
360 pb_key_Directive = _create_key("Directive");
361 pb_key_dns = _create_key("dns");
362 pb_key_DOCUMENT_NAME = _create_key("DOCUMENT_NAME");
363 pb_key_DOCUMENT_URI = _create_key("DOCUMENT_URI");
364 pb_key_domain = _create_key("domain");
365 pb_key_enc = _create_key("enc");
366 pb_key_engine = _create_key("engine");
367 pb_key_error_action = _create_key("error-action");
368 pb_key_error_desc = _create_key("error-desc");
369 pb_key_error_fn = _create_key("error-fn");
370 pb_key_escape = _create_key("escape");
371 pb_key_escaped = _create_key("escaped");
372 pb_key_etag = _create_key("etag");
373 pb_key_expect = _create_key("expect");
374 pb_key_expires = _create_key("expires");
375 pb_key_expr = _create_key("expr");
376 pb_key_filter = _create_key("filter");
377 pb_key_find_pathinfo_forward = _create_key("find-pathinfo-forward");
378 pb_key_flushTimer = _create_key("flushTimer");
379 pb_key_fn = _create_key("fn");
380 pb_key_from = _create_key("from");
381 pb_key_full_headers = _create_key("full-headers");
382 pb_key_hdr = _create_key("hdr");
383 pb_key_host = _create_key("host");
384 pb_key_hostname = _create_key("hostname");
385 pb_key_if_match = _create_key("if-match");
386 pb_key_if_modified_since = _create_key("if-modified-since");
387 pb_key_if_none_match = _create_key("if-none-match");
388 pb_key_if_range = _create_key("if-range");
389 pb_key_if_unmodified_since = _create_key("if-unmodified-since");
390 pb_key_ip = _create_key("ip");
391 pb_key_iponly = _create_key("iponly");
392 pb_key_issuer_dn = _create_key("issuer_dn");
393 pb_key_jroute = _create_key("jroute");
394 pb_key_keep_alive = _create_key("keep-alive");
395 pb_key_keep_alive_timeout = _create_key("keep-alive-timeout");
396 pb_key_keysize = _create_key("keysize");
397 pb_key_lang = _create_key("lang");
398 pb_key_last_modified = _create_key("last-modified");
399 pb_key_level = _create_key("level");
400 pb_key_location = _create_key("location");
401 pb_key_lock_owner = _create_key("lock-owner");
402 pb_key_magnus_charset = _create_key("magnus-charset");
403 pb_key_magnus_internal = _create_key("magnus-internal");
404 pb_key_magnus_internal_dav_src = _create_key("magnus-internal/dav-src");
405 pb_key_magnus_internal_default_acls_only = _create_key("magnus-internal/default-acls-only");
406 pb_key_magnus_internal_error_j2ee = _create_key("magnus-internal/error-j2ee");
407 pb_key_magnus_internal_j2ee_nsapi = _create_key("magnus-internal/j2ee-nsapi");
408 pb_key_magnus_internal_preserve_srvhdrs = _create_key("magnus-internal/preserve-srvhdrs-after-req-restart");
409 pb_key_magnus_internal_set_request_status = _create_key("magnus-internal/set-request-status");
410 pb_key_magnus_internal_set_response_status = _create_key("magnus-internal/set-response-status");
411 pb_key_magnus_internal_webapp_errordesc = _create_key("magnus-internal/webapp-errordesc");
412 pb_key_matched_browser = _create_key("matched-browser");
413 pb_key_max_age = _create_key("max-age");
414 pb_key_max_forwards = _create_key("max-forwards");
415 pb_key_message = _create_key("message");
416 pb_key_method = _create_key("method");
417 pb_key_name = _create_key("name");
418 pb_key_nocache = _create_key("nocache");
419 pb_key_nostat = _create_key("nostat");
420 pb_key_ntrans_base = _create_key("ntrans-base");
421 pb_key_offline_origin_addr = _create_key("offline-origin-addr");
422 pb_key_offline_proxy_addr = _create_key("offline-proxy-addr");
423 pb_key_origin_addr = _create_key("origin-addr");
424 pb_key_p2c_cl = _create_key("p2c-cl");
425 pb_key_p2c_hl = _create_key("p2c-hl");
426 pb_key_p2r_cl = _create_key("p2r-cl");
427 pb_key_p2r_hl = _create_key("p2r-hl");
428 pb_key_parse_timeout = _create_key("parse-timeout");
429 pb_key_password = _create_key("password");
430 pb_key_path = _create_key("path");
431 pb_key_PATH_INFO = _create_key("PATH_INFO");
432 pb_key_path_info = _create_key("path-info");
433 pb_key_pblock = _create_key("pblock");
434 pb_key_poll_interval = _create_key("poll-interval");
435 pb_key_pool = _create_key("pool"); // new
436 pb_key_port = _create_key("port");
437 pb_key_ppath = _create_key("ppath");
438 pb_key_pragma = _create_key("pragma");
439 pb_key_process_request_body = _create_key("process-request-body");
440 pb_key_process_response_body = _create_key("process-response-body");
441 pb_key_protocol = _create_key("protocol");
442 pb_key_proxy_addr = _create_key("proxy-addr");
443 pb_key_proxy_agent = _create_key("proxy-agent");
444 pb_key_proxy_auth_cert = _create_key("proxy-auth-cert");
445 pb_key_proxy_authorization = _create_key("proxy-authorization");
446 pb_key_proxy_cipher = _create_key("proxy-cipher");
447 pb_key_proxy_issuer_dn = _create_key("proxy-issuer-dn");
448 pb_key_proxy_jroute = _create_key("proxy-jroute");
449 pb_key_proxy_keysize = _create_key("proxy-keysize");
450 pb_key_proxy_ping = _create_key("proxy-ping");
451 pb_key_proxy_request = _create_key("proxy-request");
452 pb_key_proxy_secret_keysize = _create_key("proxy-secret-keysize");
453 pb_key_proxy_ssl_id = _create_key("proxy-ssl-id");
454 pb_key_proxy_user_dn = _create_key("proxy-user-dn");
455 pb_key_query = _create_key("query");
456 pb_key_QUERY_STRING = _create_key("QUERY_STRING");
457 pb_key_QUERY_STRING_UNESCAPED = _create_key("QUERY_STRING_UNESCAPED");
458 pb_key_r2p_cl = _create_key("r2p-cl");
459 pb_key_r2p_hl = _create_key("r2p-hl");
460 pb_key_range = _create_key("range");
461 pb_key_referer = _create_key("referer");
462 pb_key_reformat_request_headers = _create_key("reformat-request-headers");
463 pb_key_remote_status = _create_key("remote-status");
464 pb_key_request_jroute = _create_key("request-jroute");
465 pb_key_required_rights = _create_key("required-rights");
466 pb_key_retries = _create_key("retries");
467 pb_key_rewrite_content_location = _create_key("rewrite-content-location");
468 pb_key_rewrite_host = _create_key("rewrite-host");
469 pb_key_rewrite_location = _create_key("rewrite-location");
470 pb_key_rewrite_set_cookie = _create_key("rewrite-set-cookie");
471 pb_key_root = _create_key("root");
472 pb_key_route = _create_key("route");
473 pb_key_route_cookie = _create_key("route-cookie");
474 pb_key_route_hdr = _create_key("route-hdr");
475 pb_key_route_offline = _create_key("route-offline");
476 pb_key_script_name = _create_key("script-name");
477 pb_key_secret_keysize = _create_key("secret-keysize");
478 pb_key_secure = _create_key("secure");
479 pb_key_server = _create_key("server");
480 pb_key_set_cookie = _create_key("set-cookie");
481 pb_key_socks_addr = _create_key("socks_addr");
482 pb_key_ssl_id = _create_key("ssl-id");
483 pb_key_ssl_unclean_shutdown = _create_key("ssl-unclean-shutdown");
484 pb_key_status = _create_key("status");
485 pb_key_sticky_cookie = _create_key("sticky-cookie");
486 pb_key_sticky_param = _create_key("sticky-param");
487 pb_key_suppress_request_headers = _create_key("suppress-request-headers");
488 pb_key_svr_status = _create_key("svr-status");
489 pb_key_timeout = _create_key("timeout");
490 pb_key_to = _create_key("to");
491 pb_key_transfer_encoding = _create_key("transfer-encoding");
492 pb_key_transmit_timeout = _create_key("transmit-timeout");
493 pb_key_tunnel_non_http_response = _create_key("tunnel-non-http-response");
494 pb_key_type = _create_key("type");
495 pb_key_upstream_jroute = _create_key("upstream-jroute");
496 pb_key_uri = _create_key("uri");
497 pb_key_url = _create_key("url");
498 pb_key_url_prefix = _create_key("url-prefix");
499 pb_key_UseOutputStreamSize = _create_key("UseOutputStreamSize");
500 pb_key_user = _create_key("user");
501 pb_key_user_agent = _create_key("user-agent");
502 pb_key_user_dn = _create_key("user_dn");
503 pb_key_validate_server_cert = _create_key("validate-server-cert");
504 pb_key_value = _create_key("value");
505 pb_key_vary = _create_key("vary");
506 pb_key_via = _create_key("via");
507 pb_key_warning = _create_key("warning");
508 }
509
510 NSAPI_PUBLIC void pblock_free_default_keys(void) {
511 for (unsigned i = 0 ; i < PB_KEY_LIST_BUCKET_COUNT ; i++) {
512 // free(NULL) is defined, so don't worry here
513 free(_pbKeys.buckets[i].elements);
514 }
515 }
516
517 /* ------------------------------ _find_key ------------------------------- */
518
519 static inline const pb_key *_find_key(const char *name, unsigned int hashval)
520 {
521 /* Check to see if name corresponds to a pb_key */
522 struct pb_key_list_bucket *bucket = &_pbKeys.buckets[hashval & PB_KEY_LIST_BUCKET_COUNT];
523 for (unsigned i = 0 ; i < bucket->size ; i++) {
524 pb_key *key = &bucket->elements[i];
525 if (key->hashval == hashval && !strcmp(key->name, name)) {
526 return key;
527 }
528 }
529 return NULL;
530 }
531
532
533 /* --------------------------- _get_hash_index ---------------------------- */
534
535 static inline int _get_hash_index(const PListStruct_t *pl, const pb_key *key)
536 {
537 /* Get the hash index from the key. Requires a symbol table. */
538 int i;
539 if (key->sizendx == pl->pl_symtab->pt_sizendx)
540 i = key->hashndx;
541 else
542 i = key->hashval % PLSIZENDX(pl->pl_symtab->pt_sizendx);
543 return i;
544 }
545
546
547 /* ---------------------------- _param_create ----------------------------- */
548
549 static inline pb_param *_param_create(pool_handle_t *pool_handle, const char *name, int namelen, const char *value, int valuelen)
550 {
551 PLValueStruct_t *ret;
552
553 ret = (PLValueStruct_t *)pool_malloc(pool_handle, sizeof(PLValueStruct_t));
554
555 ret->pv_pbentry.param = &ret->pv_pbparam;
556 ret->pv_pbentry.next = 0;
557 ret->pv_next = 0;
558 ret->pv_type = 0;
559 ret->pv_mempool = pool_handle;
560
561 if (name || namelen) {
562 ret->pv_name = (char*)pool_malloc(pool_handle, namelen + 1);
563 if (name) {
564 memcpy(ret->pv_name, name, namelen);
565 ret->pv_name[namelen] = '\0';
566 } else {
567 ret->pv_name[0] = '\0';
568 }
569 } else {
570 ret->pv_name = 0;
571 }
572
573 if (value || valuelen) {
574 ret->pv_value = (char*)pool_malloc(pool_handle, valuelen + 1);
575 if (value) {
576 memcpy(ret->pv_value, value, valuelen);
577 ret->pv_value[valuelen] = '\0';
578 } else {
579 ret->pv_value[0] = '\0';
580 }
581 } else {
582 ret->pv_value = 0;
583 }
584
585 return &ret->pv_pbparam;
586 }
587
588
589 /* ----------------------- pblock_key_param_create ----------------------- */
590
591 NSAPI_PUBLIC pb_param *pblock_key_param_create(pblock *pb, const pb_key *key, const char *value, int valuelen)
592 {
593 /*
594 * Allocate a PLValueStruct_t from the property list's memory pool.
595 */
596 PListStruct_t *pl = PBTOPL(pb);
597 return _param_create(pl->pl_mempool, key->name, key->namelen, value, valuelen);
598 }
599
600
601 /* ------------------------- pblock_param_create -------------------------- */
602
603 NSAPI_PUBLIC pb_param *pblock_param_create(pblock *pb, const char *name, const char *value)
604 {
605 /*
606 * Allocate a PLValueStruct_t from the property list's memory pool.
607 */
608 PListStruct_t *pl = PBTOPL(pb);
609 return _param_create(pl->pl_mempool, name, name ? strlen(name) : 0, value, value ? strlen(value) : 0);
610 }
611
612
613 /* ----------------------------- param_create ----------------------------- */
614
615 NSAPI_PUBLIC pb_param *param_create(const char *name, const char *value)
616 {
617 /*
618 * Allocate a PLValueStruct_t containing the pb_param that will
619 * be returned. Normally PLValueStruct_ts are allocated from the
620 * memory pool associated with a property list, but we don't have
621 * that here, so we just use the thread's pool and indicate we were
622 * allocated from a specific pool.
623 */
624 return _param_create(system_pool(), name, name ? strlen(name) : 0, value, value ? strlen(value) : 0);
625 }
626
627
628 /* ------------------------------ param_free ------------------------------ */
629
630 NSAPI_PUBLIC int param_free(pb_param *pp)
631 {
632 if (pp) {
633 PLValueStruct_t *pv = PATOPV(pp);
634
635 /* Don't bother if the pblock was allocated from a pool */
636 if (!pv->pv_mempool) {
637 pool_free(pv->pv_mempool, pv->pv_name);
638 pool_free(pv->pv_mempool, pv->pv_value);
639 pool_free(pv->pv_mempool, pv);
640 }
641
642 return 1;
643 }
644
645 return 0;
646 }
647
648
649 /* -------------------------- pblock_create_pool -------------------------- */
650
651 NSAPI_PUBLIC pblock *pblock_create_pool(pool_handle_t *pool_handle, int n)
652 {
653 /* Create a property list with n property indices */
654 PListStruct_t *plist = (PListStruct_t *)PListCreate(pool_handle, n, 0, 0);
655 if (!plist)
656 return NULL;
657
658 plist->pl_resvpi = 0;
659
660 return &plist->pl_pb;
661 }
662
663
664 /* ----------------------------- pblock_pool ------------------------------ */
665
666 NSAPI_PUBLIC pool_handle_t *pblock_pool(pblock *pb)
667 {
668 PListStruct_t *pl = PBTOPL(pb);
669 return pl->pl_mempool;
670 }
671
672
673 /* ---------------------------- pblock_create ----------------------------- */
674
675 NSAPI_PUBLIC pblock *pblock_create(int n)
676 {
677 return pblock_create_pool(MALLOC_POOL_HANDLE, n);
678 }
679
680
681 /* ----------------------------- pblock_free ------------------------------ */
682
683 NSAPI_PUBLIC void pblock_free(pblock *pb)
684 {
685 PListStruct_t *pl = PBTOPL(pb);
686 PLValueStruct_t **ppval;
687 PLValueStruct_t *pv;
688 int i;
689
690 if (!pb) {
691 return;
692 }
693
694 /* If the pools are enabled, this routine has no effect anyway, so
695 * just return.
696 */
697 if (pl->pl_mempool || pool_enabled()) {
698 return;
699 }
700
701 /* Free the property name symbol table if any */
702 if (pl->pl_symtab) {
703 pool_free(pl->pl_mempool, (void *)(pl->pl_symtab));
704 }
705
706 ppval = (PLValueStruct_t **)(pl->pl_ppval);
707
708 /* Loop over the initialized property indices */
709 for (i = 0; i < pl->pl_initpi; ++i) {
710
711 /* Got a property here? */
712 pv = ppval[i];
713 if (pv) {
714
715 param_free(&pv->pv_pbparam);
716 }
717 }
718
719 /* Free the array of pointers to property values */
720 pool_free(pl->pl_mempool, (void *)ppval);
721
722 /* Free the property list head */
723 pool_free(pl->pl_mempool, (void *)pl);
724 }
725
726
727 /* ------------------------------ pblock_key ------------------------------ */
728
729 NSAPI_PUBLIC const pb_key *pblock_key(const char *name)
730 {
731 if (!name)
732 return NULL;
733
734 return _find_key(name, PListHash(name));
735 }
736
737
738 /* --------------------------- pblock_kpinsert ---------------------------- */
739
740 NSAPI_PUBLIC void pblock_kpinsert(const pb_key *key, pb_param *pp, pblock *pb)
741 {
742 PListStruct_t *pl = PBTOPL(pb);
743 PLValueStruct_t *pv = PATOPV(pp);
744
745 //PR_ASSERT(pv->pv_mempool == pl->pl_mempool); // TODO
746
747 /* Check to see if the name corresponds to a pb_key */
748 unsigned int hashval;
749 if (!key) {
750 hashval = PListHash(pv->pv_name);
751 key = _find_key(pv->pv_name, hashval);
752 }
753
754 /* Find property index */
755 int pindex = PListGetFreeIndex(pl);
756 if (pindex < 1) {
757 /* Error - invalid property index */
758 printf("Error - invalid property index\n");
759 return;
760 }
761
762 /* Allocate/grow the symbol table as needed */
763 PLSymbolTable_t *pt = PListSymbolTable(pl);
764 if (!pt) {
765 printf("!pt\n");
766 return;
767 }
768
769 /* Add PLValueStruct_t to the property list */
770 PLValueStruct_t **ppval = (PLValueStruct_t **)(pl->pl_ppval);
771 pv->pv_pbkey = key;
772 pv->pv_pi = pindex;
773 ppval[pv->pv_pi - 1] = pv;
774
775 /* Add name to symbol table */
776 int i = key ? _get_hash_index(pl, key) : (hashval % PLSIZENDX(pt->pt_sizendx));
777 pv->pv_next = pt->pt_hash[i];
778 pt->pt_hash[i] = pv;
779 pt->pt_nsyms++;
780
781 //PR_ASSERT(param_key(pp) == key); // TODO
782 }
783
784
785 /* ---------------------------- pblock_pinsert ---------------------------- */
786
787 NSAPI_PUBLIC void pblock_pinsert(pb_param *pp, pblock *pb)
788 {
789 pblock_kpinsert(NULL, pp, pb);
790 }
791
792
793 /* --------------------------- pblock_nvinsert ---------------------------- */
794
795 NSAPI_PUBLIC pb_param *pblock_nvinsert(const char *name, const char *value, pblock *pb)
796 {
797 pb_param *pp = pblock_param_create(pb, name, value);
798 if (pp)
799 pblock_kpinsert(NULL, pp, pb);
800 return pp;
801 }
802
803
804 /* --------------------------- pblock_kvinsert ---------------------------- */
805
806 NSAPI_PUBLIC pb_param *pblock_kvinsert(const pb_key *key, const char *value, int valuelen, pblock *pb)
807 {
808 pb_param *pp = pblock_key_param_create(pb, key, value, valuelen);
809 if (pp)
810 pblock_kpinsert(key, pp, pb);
811 return pp;
812 }
813
814
815 /* --------------------------- pblock_nninsert ---------------------------- */
816
817 NSAPI_PUBLIC pb_param *pblock_nninsert(const char *name, int value, pblock *pb)
818 {
819 char num[UTIL_ITOA_SIZE];
820
821 util_itoa(value, num);
822 return pblock_nvinsert(name, num, pb);
823 }
824
825
826 /* --------------------------- pblock_kninsert ---------------------------- */
827
828 NSAPI_PUBLIC pb_param *pblock_kninsert(const pb_key *key, int value, pblock *pb)
829 {
830 pb_param *pp = pblock_key_param_create(pb, key, NULL, UTIL_ITOA_SIZE);
831 if (pp) {
832 util_itoa(value, pp->value);
833 pblock_kpinsert(key, pp, pb);
834 }
835 return pp;
836 }
837
838
839 /* --------------------------- pblock_kllinsert --------------------------- */
840
841 NSAPI_PUBLIC pb_param *pblock_kllinsert(const pb_key *key, int64_t value, pblock *pb)
842 {
843 pb_param *pp = pblock_key_param_create(pb, key, NULL, UTIL_I64TOA_SIZE);
844 if (pp) {
845 util_i64toa(value, pp->value);
846 pblock_kpinsert(key, pp, pb);
847 }
848 return pp;
849 }
850
851
852 /* ---------------------------pblock_nvlinsert ---------------------------- */
853
854 NSAPI_PUBLIC pb_param *pblock_nvlinsert(const char *name, int namelen, const char *value, int valuelen, pblock *pb)
855 {
856 PListStruct_t *pl = PBTOPL(pb);
857
858 pb_param *pp = _param_create(pl->pl_mempool, name, namelen, value, valuelen);
859
860 if(pp) {
861 pblock_kpinsert(NULL, pp, pb);
862 }
863
864 return pp;
865 }
866
867
868 /* ---------------------------- pblock_findkey ---------------------------- */
869
870 NSAPI_PUBLIC pb_param *pblock_findkey(const pb_key *key, const pblock *pb)
871 {
872 PListStruct_t *pl = PBTOPL(pb);
873
874 /* Lookup key by examining symbol table */
875 if (pl->pl_symtab) {
876 int i = _get_hash_index(pl, key);
877 PLValueStruct_t *pv;
878
879 /* Search hash collision list for matching name */
880 for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {
881 if (pv->pv_pbkey == key)
882 return &pv->pv_pbparam;
883 }
884 }
885
886 return NULL;
887 }
888
889
890 /* -------------------------- pblock_findkeyval --------------------------- */
891
892 NSAPI_PUBLIC char *pblock_findkeyval(const pb_key *key, const pblock *pb)
893 {
894 pb_param *pp = pblock_findkey(key, pb);
895 return pp ? pp->value : NULL;
896 }
897
898
899 /* ---------------------------- pblock_findval ---------------------------- */
900
901 NSAPI_PUBLIC char *pblock_findval(const char *name, const pblock *pb)
902 {
903 void *pvalue = 0;
904
905 (void)PListFindValue((PList_t)(PBTOPL(pb)), name, &pvalue, 0);
906
907 return (char *)pvalue;
908 }
909
910
911 /* ------------------------------ pblock_fr ------------------------------ */
912
913 NSAPI_PUBLIC pb_param *pblock_fr(const char *name, pblock *pb, int remove)
914 {
915 PListStruct_t *pl = PBTOPL(pb);
916 PLValueStruct_t **ppval;
917 PLValueStruct_t **pvp;
918 PLValueStruct_t *pv = NULL;
919 int pindex;
920 int i;
921
922 if (pl->pl_symtab) {
923
924 /* Compute hash index of specified property name */
925 i = PListHashName(pl->pl_symtab, name);
926
927 /* Search hash collision list for matching name */
928 for (pvp = &pl->pl_symtab->pt_hash[i];
929 (pv = *pvp); pvp = &(*pvp)->pv_next) {
930
931 if (!strcmp(name, pv->pv_name)) {
932
933 if (remove) {
934 /* Remove PLValueStruct_t from symbol table */
935 *pvp = pv->pv_next;
936 pl->pl_symtab->pt_nsyms--;
937
938 /* Remove it from pl_ppval too */
939 ppval = (PLValueStruct_t **)(pl->pl_ppval);
940 pindex = pv->pv_pi;
941 ppval[pindex - 1] = 0;
942 }
943 break;
944 }
945 }
946 }
947
948 return (pv) ? &pv->pv_pbparam : NULL;
949 }
950
951
952 /* --------------------------- pblock_removekey --------------------------- */
953
954 NSAPI_PUBLIC pb_param *pblock_removekey(const pb_key *key, pblock *pb)
955 {
956 PListStruct_t *pl = PBTOPL(pb);
957 PLValueStruct_t **ppval;
958 PLValueStruct_t **pvp;
959 PLValueStruct_t *pv = NULL;
960 int pindex;
961 int i;
962
963 if (pl->pl_symtab) {
964 /* Lookup hash index for specified property key */
965 i = _get_hash_index(pl, key);
966
967 /* Search hash collision list for matching key */
968 for (pvp = &pl->pl_symtab->pt_hash[i]; (pv = *pvp); pvp = &pv->pv_next) {
969 /* If this value has the requested key... */
970 if (pv->pv_pbkey == key) {
971 /* Remove PLValueStruct_t from symbol table */
972 *pvp = pv->pv_next;
973 pl->pl_symtab->pt_nsyms--;
974
975 /* Remove it from pl_ppval too */
976 ppval = (PLValueStruct_t **)(pl->pl_ppval);
977 pindex = pv->pv_pi;
978 ppval[pindex - 1] = 0;
979
980 break;
981 }
982 }
983 }
984
985 return (pv) ? &pv->pv_pbparam : NULL;
986 }
987
988
989 /* -------------------------- pblock_removeone --------------------------- */
990
991 NSAPI_PUBLIC pb_param *pblock_removeone(pblock *pb)
992 {
993 PListStruct_t *pl = PBTOPL(pb);
994
995 if (pl && pl->pl_symtab) {
996 /* Search hash buckets */
997 for (int i = 0; i < PLSIZENDX(pl->pl_symtab->pt_sizendx); i++) {
998 /* Search hash collision list */
999 PLValueStruct_t *pv = pl->pl_symtab->pt_hash[i];
1000 if (pv) {
1001 /* Remove PLValueStruct_t from symbol table */
1002 pl->pl_symtab->pt_hash[i] = pv->pv_next;
1003 pl->pl_symtab->pt_nsyms--;
1004
1005 /* Remove it from pl_ppval too */
1006 PLValueStruct_t **ppval = (PLValueStruct_t**)pl->pl_ppval;
1007 ppval[pv->pv_pi - 1] = 0;
1008
1009 return &pv->pv_pbparam;
1010 }
1011 }
1012 }
1013
1014 return NULL;
1015 }
1016
1017
1018 /* -------------------------- pblock_str2pblock --------------------------- */
1019
1020
1021 int _verify_pbstr(const char *str)
1022 {
1023 const char *cp;
1024 const char *scp;
1025 int np;
1026 int state;
1027 int quote;
1028
1029 for(cp = str, np = 0, state = 0; *cp; ) {
1030 switch (state) {
1031 case 0: /* skipping leading spaces */
1032
1033 while (*cp && isspace(*cp)) ++cp;
1034 if (*cp == '=') {
1035 return -1;
1036 }
1037 if (*cp) state = 1;
1038 break;
1039
1040 case 1: /* scanning parameter name */
1041
1042 scp = cp;
1043 while (*cp && (*cp != '=') && !isspace(*cp)) ++cp;
1044 if (*cp == '=') ++cp;
1045 else cp = scp;
1046 state = 2;
1047 break;
1048
1049 case 2: /* scanning parameter value */
1050 quote = 0;
1051 if (*cp == '\"') {
1052 quote = 1;
1053 ++cp;
1054 }
1055 for (;;) {
1056 if (*cp == '\\') {
1057 ++cp;
1058 if (*cp == 0) {
1059 return -1;
1060 }
1061 }
1062 else if (*cp == '\"') {
1063 if (!quote) {
1064 return -1;
1065 }
1066 ++np;
1067 ++cp;
1068 quote = 0;
1069 state = 0;
1070 break;
1071 }
1072 else if (!quote && (!*cp || isspace(*cp))) {
1073 ++np;
1074 if (*cp) ++cp;
1075 state = 0;
1076 break;
1077 }
1078 else if (*cp == 0) {
1079 return -1;
1080 }
1081 ++cp;
1082 }
1083 if (quote) {
1084 return -1;
1085 }
1086 break;
1087 }
1088 }
1089
1090 return (state == 0) ? np : -1;
1091 }
1092
1093 NSAPI_PUBLIC int
1094 INTpblock_str2pblock_lowercasename(const char *str, pblock *pb)
1095 {
1096 return _pblock_str2pblock(str, pb, PR_TRUE);
1097 }
1098
1099 NSAPI_PUBLIC int pblock_str2pblock(const char *str, pblock *pb)
1100 {
1101 return _pblock_str2pblock(str, pb, PR_FALSE);
1102 }
1103
1104 int
1105 _pblock_str2pblock(const char* str, pblock* pb, PRBool lowerCase)
1106 {
1107 char *cpy;
1108 char *cp;
1109 char *dp;
1110 char *pname;
1111 char *pvalue;
1112 int np;
1113 int quote;
1114 int state;
1115 char numbuf[UTIL_ITOA_SIZE];
1116
1117 if((np = _verify_pbstr(str)) < 1)
1118 return -1;
1119
1120 while (*str && isspace(*str)) ++str;
1121
1122 cpy = STRDUP(str);
1123
1124 for (np = 0, cp = cpy, state = 0; *cp; ) {
1125 switch (state) {
1126
1127 case 0: /* skipping leading spaces */
1128
1129 while (*cp && isspace(*cp)) ++cp;
1130 if (*cp) state = 1;
1131 break;
1132
1133 case 1: /* scanning parameter name */
1134
1135 pname = cp;
1136 while (*cp && (*cp != '=') && !isspace(*cp)) ++cp;
1137 if (*cp == '=') {
1138 *cp++ = 0;
1139 }
1140 else {
1141 cp = pname;
1142 pname = numbuf;
1143 util_itoa(np+1, numbuf);
1144 }
1145 state = 2;
1146 break;
1147
1148 case 2: /* scanning parameter value */
1149 quote = 0;
1150 if (*cp == '\"') {
1151 quote = 1;
1152 ++cp;
1153 }
1154 for (pvalue = cp, dp = cp; ; ++cp, ++dp) {
1155 if (*cp == '\\') {
1156 ++cp;
1157 }
1158 else if (*cp == '\"') {
1159 ++np;
1160 ++cp;
1161 *dp = 0;
1162 quote = 0;
1163 state = 0;
1164 break;
1165 }
1166 else if (!quote && ((*cp == 0) || isspace(*cp))) {
1167 ++np;
1168 if (*cp != 0) {
1169 ++cp;
1170 }
1171 *dp = 0;
1172 state = 0;
1173 break;
1174 }
1175 if (cp != dp) *dp = *cp;
1176 }
1177 if (lowerCase == PR_TRUE) {
1178 for (char* p = pname; *p; p++) {
1179 *p = tolower(*p);
1180 }
1181 }
1182 pblock_nvinsert(pname, pvalue, pb);
1183 break;
1184 }
1185 }
1186
1187 FREE(cpy);
1188
1189 return np;
1190 }
1191
1192
1193 /* -------------------------- pblock_pblock2str --------------------------- */
1194
1195
1196 NSAPI_PUBLIC char *pblock_pblock2str(const pblock *pb, char *str)
1197 {
1198 char *s = str, *t, *u;
1199 PListStruct_t *pl = PBTOPL(pb);
1200 PLValueStruct_t **ppval;
1201 PLValueStruct_t *pv;
1202 int i;
1203 int sl;
1204 int xlen;
1205
1206 ppval = (PLValueStruct_t **)(pl->pl_ppval);
1207
1208 /* Loop over the initialized property indices */
1209 for (i = 0, xlen = 0; i < pl->pl_initpi; ++i) {
1210
1211 /* Got a property here? */
1212 pv = ppval[i];
1213 if (pv && pv->pv_name) {
1214
1215 int ln = strlen(pv->pv_name);
1216 int lv = strlen((char *)(pv->pv_value));
1217
1218 /* Check for " or \ because we'll have to escape them */
1219 for (t = (char *)(pv->pv_value); *t; ++t) {
1220 if ((*t == '\"') || (*t == '\\')) ++lv;
1221 }
1222
1223 /* 4: two quotes, =, and a null */
1224 xlen += (ln + lv + 4);
1225 }
1226 }
1227
1228 /* Allocate string to hold parameter settings, or increase size */
1229 if (!s) {
1230 s = (char *)MALLOC(xlen);
1231 s[0] = '\0';
1232 t = &s[0];
1233 sl = xlen;
1234 }
1235 else {
1236 sl = strlen(s);
1237 t = &s[sl];
1238 sl += xlen;
1239 s = (char *)REALLOC(s, sl);
1240 }
1241
1242 /* Loop over the initialized property indices */
1243 for (i = 0; i < pl->pl_initpi; ++i) {
1244
1245 /* Got a property here? */
1246 pv = ppval[i];
1247 if (pv && pv->pv_name) {
1248
1249 if (t != s) *t++ = ' ';
1250
1251 for (u = pv->pv_name; *u; ) *t++ = *u++;
1252
1253 *t++ = '=';
1254 *t++ = '\"';
1255
1256 for (u = (char *)(pv->pv_value); *u; ) {
1257 if ((*u == '\\') || (*u == '\"')) *t++ = '\\';
1258 *t++ = *u++;
1259 }
1260
1261 *t++ = '\"';
1262 *t = '\0';
1263 }
1264 }
1265
1266 return s;
1267 }
1268
1269
1270 /* ----------------------------- pblock_copy ------------------------------ */
1271
1272
1273 NSAPI_PUBLIC int pblock_copy(const pblock *src, pblock *dst)
1274 {
1275 PListStruct_t *pl = PBTOPL(src);
1276 PLValueStruct_t **ppval;
1277 PLValueStruct_t *pv;
1278 int rv = 0;
1279 int i;
1280
1281 ppval = (PLValueStruct_t **)(pl->pl_ppval);
1282
1283 for (i = 0; i < pl->pl_initpi; ++i) {
1284 pv = ppval[i];
1285 if (pv) {
1286 if (pv->pv_pbkey) {
1287 if (pv->pv_pbkey != pb_key_magnus_internal) {
1288 if (!pblock_kvinsert(pv->pv_pbkey, (char *)(pv->pv_value), strlen(pv->pv_value), dst))
1289 rv = -1;
1290 }
1291 } else {
1292 if (!pblock_nvinsert(pv->pv_name, (char *)(pv->pv_value), dst))
1293 rv = -1;
1294 }
1295 }
1296 }
1297
1298 return rv;
1299 }
1300
1301 /* ---------------------------- pblock_dup -------------------------------- */
1302
1303 NSAPI_PUBLIC pblock *pblock_dup(const pblock *src)
1304 {
1305 pblock *dst;
1306
1307 if (!src)
1308 return NULL;
1309
1310 if ( (dst = pblock_create(src->hsize)) )
1311 pblock_copy(src, dst);
1312
1313 return dst;
1314 }
1315
1316
1317 /* ---------------------------- pblock_pb2env ----------------------------- */
1318
1319
1320 NSAPI_PUBLIC char **pblock_pb2env(const pblock *pb, char **env)
1321 {
1322 PListStruct_t *pl = PBTOPL(pb);
1323 PLValueStruct_t **ppval;
1324 PLValueStruct_t *pv;
1325 int i;
1326 int nval;
1327 int pos;
1328
1329 /* Find out how many there are. */
1330
1331 ppval = (PLValueStruct_t **)(pl->pl_ppval);
1332
1333 for (i = 0, nval = 0; i < pl->pl_initpi; ++i) {
1334 if (ppval[i]) ++nval;
1335 }
1336
1337 env = util_env_create(env, nval, &pos);
1338
1339 for (i = 0; i < pl->pl_initpi; ++i) {
1340 pv = ppval[i];
1341 if (pv) {
1342 env[pos++] = util_env_str(pv->pv_name, (char *)(pv->pv_value));
1343 }
1344 }
1345 env[pos] = NULL;
1346
1347 return env;
1348 }
1349
1350
1351 /* ---------------------------- pblock_replace ---------------------------- */
1352
1353 NSAPI_PUBLIC char * pblock_replace(const char *name,
1354 char * new_value, pblock *pb)
1355 {
1356 PListStruct_t *pl = PBTOPL(pb);
1357
1358 /* Replace an existing value */
1359 pb_param *pp = pblock_find(name, pb);
1360 if (!pp)
1361 return NULL;
1362 pool_free(pl->pl_mempool, pp->value);
1363 pp->value = new_value;
1364
1365 return new_value;
1366 }
1367
1368
1369 /* --------------------------- pblock_nvreplace --------------------------- */
1370
1371 NSAPI_PUBLIC void pblock_nvreplace (const char *name, const char *value, pblock *pb)
1372 {
1373 PListStruct_t *pl = PBTOPL(pb);
1374
1375 /* Replace an existing value or insert a new value */
1376 pb_param *pp = pblock_find(name, pb);
1377 if (pp) {
1378 pool_free(pl->pl_mempool, pp->value);
1379 pp->value = pool_strdup(pl->pl_mempool, value);
1380 } else {
1381 pblock_nvinsert(name, value, pb);
1382 }
1383 }
1384
1385
1386 /* --------------------------- pblock_kvreplace --------------------------- */
1387
1388 NSAPI_PUBLIC void pblock_kvreplace(const pb_key *key, const char *value, int valuelen, pblock *pb)
1389 {
1390 PListStruct_t *pl = PBTOPL(pb);
1391
1392 /* Replace an existing value or insert a new value */
1393 pb_param *pp = pblock_findkey(key, pb);
1394 if (pp) {
1395 pool_free(pl->pl_mempool, pp->value);
1396 pp->value = (char*)pool_malloc(pl->pl_mempool, valuelen + 1);
1397 memcpy(pp->value, value, valuelen + 1);
1398 } else {
1399 pblock_kvinsert(key, value, valuelen, pb);
1400 }
1401 }

mercurial