1 | /* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. |
---|
2 | See the COPYRIGHT file for more information. */ |
---|
3 | |
---|
4 | #include "config.h" |
---|
5 | #ifdef HAVE_UNISTD_H |
---|
6 | #include <unistd.h> |
---|
7 | #endif |
---|
8 | #include <stdio.h> |
---|
9 | #include <stdlib.h> |
---|
10 | #include <string.h> |
---|
11 | |
---|
12 | #include "ocinternal.h" |
---|
13 | #include "ocdebug.h" |
---|
14 | #include "ocdata.h" |
---|
15 | #include "occontent.h" |
---|
16 | #include "oclog.h" |
---|
17 | |
---|
18 | #include "ocrc.h" |
---|
19 | |
---|
20 | #define RTAG ']' |
---|
21 | #define LTAG '[' |
---|
22 | |
---|
23 | #define TRIMCHARS " \t\r\n" |
---|
24 | |
---|
25 | #define TRIM(x) rctrimright(rctrimleft((x),TRIMCHARS),TRIMCHARS) |
---|
26 | |
---|
27 | #define HTTPPREFIXDEPRECATED "CURL." |
---|
28 | #define HTTPPREFIX "HTTP." |
---|
29 | |
---|
30 | /* the .dodsrc triple store */ |
---|
31 | struct OCTriplestore* ocdodsrc = NULL; |
---|
32 | |
---|
33 | static int parseproxy(OCstate* state, char* v); |
---|
34 | static int rcreadline(FILE* f, char* more, int morelen); |
---|
35 | static char* rctrimright(char* more, char* trimchars); |
---|
36 | static char* rctrimleft(char* more, char* trimchars); |
---|
37 | |
---|
38 | static void ocdodsrcdump(char* msg, struct OCTriple*, int ntriples); |
---|
39 | |
---|
40 | static char* curllookup(char* suffix,char* url); |
---|
41 | |
---|
42 | /* The Username and password are in the URL if the URL is of the form: |
---|
43 | * http://<name>:<passwd>@<host>/.... |
---|
44 | */ |
---|
45 | int |
---|
46 | occredentials_in_url(const char *url) |
---|
47 | { |
---|
48 | char *pos = strstr(url, "http://"); |
---|
49 | if (!pos) |
---|
50 | return 0; |
---|
51 | pos += 7; |
---|
52 | if (strchr(pos, '@') && strchr(pos, ':')) |
---|
53 | return 1; |
---|
54 | |
---|
55 | return 0; |
---|
56 | } |
---|
57 | |
---|
58 | int |
---|
59 | ocextract_credentials(const char *url, char **name, char **pw, char **result_url) |
---|
60 | { |
---|
61 | char *pos; |
---|
62 | char *end; |
---|
63 | char *middle; |
---|
64 | int up_len = 0; |
---|
65 | int mid_len = 0; |
---|
66 | int midpas_len = 0; |
---|
67 | int url_len = 0; |
---|
68 | |
---|
69 | if (strchr(url, '@')) { |
---|
70 | pos = strstr(url, "http://"); |
---|
71 | if (pos) |
---|
72 | pos += 7; |
---|
73 | middle = strchr(pos, ':'); |
---|
74 | mid_len = middle - pos; |
---|
75 | *name = malloc(sizeof(char) * (mid_len + 1)); |
---|
76 | strncpy(*name, pos, mid_len); |
---|
77 | (*name)[mid_len] = '\0'; |
---|
78 | |
---|
79 | if (middle) |
---|
80 | middle += 1; |
---|
81 | |
---|
82 | end = strchr(middle, '@'); |
---|
83 | midpas_len = end - middle; |
---|
84 | *pw = malloc(sizeof(char) * (midpas_len + 1)); |
---|
85 | strncpy(*pw, middle, midpas_len); |
---|
86 | (*pw)[midpas_len] = '\0'; |
---|
87 | |
---|
88 | up_len = end - pos; |
---|
89 | url_len = strlen(url) - up_len; |
---|
90 | |
---|
91 | *result_url = malloc(sizeof(char) * (url_len + 1)); |
---|
92 | if (!result_url) |
---|
93 | return OC_ENOMEM; |
---|
94 | |
---|
95 | strncpy(*result_url, url, pos - url); |
---|
96 | strncpy(*result_url + (pos - url), end + 1, url_len - (pos - url)); |
---|
97 | |
---|
98 | #if 0 |
---|
99 | fprintf(stderr, "URL without username and password: %s:%d\n", sURL, url_len ); |
---|
100 | fprintf(stderr, "URL username and password: %s:%d\n", sUP, up_len); |
---|
101 | fprintf(stderr, "URL username: %s:%d\n", sUser, mid_len); |
---|
102 | fprintf(stderr, "URL password: %s:%d\n", sPassword, midpas_len); |
---|
103 | #endif |
---|
104 | (*result_url)[url_len] = '\0'; |
---|
105 | |
---|
106 | return OC_NOERR; |
---|
107 | } |
---|
108 | else { |
---|
109 | return OC_EIO; |
---|
110 | } |
---|
111 | } |
---|
112 | |
---|
113 | static int |
---|
114 | rcreadline(FILE* f, char* more, int morelen) |
---|
115 | { |
---|
116 | int i = 0; |
---|
117 | int c = getc(f); |
---|
118 | if(c < 0) return 0; |
---|
119 | for(;;) { |
---|
120 | if(i < morelen) /* ignore excess characters */ |
---|
121 | more[i++]=c; |
---|
122 | c = getc(f); |
---|
123 | if(c < 0) break; /* eof */ |
---|
124 | if(c == '\n') break; /* eol */ |
---|
125 | } |
---|
126 | /* null terminate more */ |
---|
127 | more[i] = '\0'; |
---|
128 | return 1; |
---|
129 | } |
---|
130 | |
---|
131 | /* Trim specified characters from front/left */ |
---|
132 | static char* |
---|
133 | rctrimleft(char* more, char* trimchars) |
---|
134 | { |
---|
135 | char* p = more; |
---|
136 | int c; |
---|
137 | while((c=*p) != '\0') {if(strchr(trimchars,c) != NULL) p++; else break;} |
---|
138 | return p; |
---|
139 | } |
---|
140 | |
---|
141 | /* Trim specified characters from end/right */ |
---|
142 | static char* |
---|
143 | rctrimright(char* more, char* trimchars) |
---|
144 | { |
---|
145 | int len = strlen(more); |
---|
146 | char* p = more + (len - 1); |
---|
147 | while(p != more) {if(strchr(trimchars,*p) != NULL) p--; else break;} |
---|
148 | /* null terminate */ |
---|
149 | p[1] = '\0'; |
---|
150 | return more; |
---|
151 | } |
---|
152 | |
---|
153 | static int |
---|
154 | parseproxy(OCstate* state, char* v) |
---|
155 | { |
---|
156 | char *host_pos = NULL; |
---|
157 | char *port_pos = NULL; |
---|
158 | |
---|
159 | if(strlen(v) == 0) return OC_NOERR; /* nothing there*/ |
---|
160 | if (occredentials_in_url(v)) { |
---|
161 | char *result_url = NULL; |
---|
162 | ocextract_credentials(v, &state->creds.username, |
---|
163 | &state->creds.password, |
---|
164 | &result_url); |
---|
165 | v = result_url; |
---|
166 | } |
---|
167 | /* allocating a bit more than likely needed ... */ |
---|
168 | host_pos = strstr(v, "http://"); |
---|
169 | if (host_pos) |
---|
170 | host_pos += strlen("http://"); |
---|
171 | else |
---|
172 | host_pos = v; |
---|
173 | port_pos = strchr(host_pos, ':'); |
---|
174 | if (port_pos) { |
---|
175 | int host_len; |
---|
176 | char *port_sep = port_pos; |
---|
177 | port_pos++; |
---|
178 | *port_sep = '\0'; |
---|
179 | host_len = strlen(host_pos); |
---|
180 | state->proxy.host = malloc(sizeof(char) * host_len + 1); |
---|
181 | if (!state->proxy.host) |
---|
182 | return OC_ENOMEM; |
---|
183 | |
---|
184 | strncpy(state->proxy.host, host_pos, host_len); |
---|
185 | state->proxy.host[host_len + 1] = '\0'; |
---|
186 | |
---|
187 | state->proxy.port = atoi(port_pos); |
---|
188 | } else { |
---|
189 | int host_len = strlen(host_pos); |
---|
190 | state->proxy.host = malloc(sizeof(char) * host_len + 1); |
---|
191 | if (!state->proxy.host) |
---|
192 | return OC_ENOMEM; |
---|
193 | |
---|
194 | strncpy(state->proxy.host, host_pos, host_len); |
---|
195 | state->proxy.host[host_len + 1] = '\0'; |
---|
196 | |
---|
197 | state->proxy.port = 80; |
---|
198 | } |
---|
199 | #if 0 |
---|
200 | state->proxy.host[v_len] = '\0'; |
---|
201 | state->proxy.port = atoi(v); |
---|
202 | s_len = strlen(v); |
---|
203 | state->proxy.user = malloc(sizeof(char) * s_len + 1); |
---|
204 | if (!state->proxy.user) |
---|
205 | return OC_ENOMEM; |
---|
206 | strncpy(state->proxy.user, v, s_len); |
---|
207 | state->proxy.user[s_len] = '\0'; |
---|
208 | p_len = strlen(v); |
---|
209 | state->proxy.password = malloc(sizeof(char) * p_len + 1); |
---|
210 | if (!state->proxy.password) |
---|
211 | return OC_ENOMEM; |
---|
212 | strncpy(state->proxy.password, v, p_len); |
---|
213 | state->proxy.password[p_len] = '\0'; |
---|
214 | #endif /*0*/ |
---|
215 | if (ocdebug > 1) { |
---|
216 | oc_log(LOGNOTE,"host name: %s", state->proxy.host); |
---|
217 | oc_log(LOGNOTE,"user name: %s", state->creds.username); |
---|
218 | #ifdef INSECURE |
---|
219 | oc_log(LOGNOTE,"password: %s", state->creds.password); |
---|
220 | #endif |
---|
221 | oc_log(LOGNOTE,"port number: %d", state->proxy.port); |
---|
222 | } |
---|
223 | if(v) free(v); |
---|
224 | return OC_NOERR; |
---|
225 | } |
---|
226 | |
---|
227 | /* insertion sort the triplestore based on url */ |
---|
228 | static void |
---|
229 | sorttriplestore(void) |
---|
230 | { |
---|
231 | int i, nsorted; |
---|
232 | struct OCTriple* sorted = NULL; |
---|
233 | |
---|
234 | if(ocdodsrc->ntriples <= 1) return; /* nothing to sort */ |
---|
235 | if(ocdebug > 2) |
---|
236 | ocdodsrcdump("initial:",ocdodsrc->triples,ocdodsrc->ntriples); |
---|
237 | |
---|
238 | sorted = (struct OCTriple*)malloc(sizeof(struct OCTriple)*ocdodsrc->ntriples); |
---|
239 | if(sorted == NULL) { |
---|
240 | oc_log(LOGERR,"sorttriplestore: out of memory"); |
---|
241 | return; |
---|
242 | } |
---|
243 | |
---|
244 | nsorted = 0; |
---|
245 | while(nsorted < ocdodsrc->ntriples) { |
---|
246 | int largest; |
---|
247 | /* locate first non killed entry */ |
---|
248 | for(largest=0;largest<ocdodsrc->ntriples;largest++) { |
---|
249 | if(ocdodsrc->triples[largest].key[0] != '\0') break; |
---|
250 | } |
---|
251 | OCASSERT(ocdodsrc->triples[largest].key[0] != '\0'); |
---|
252 | for(i=0;i<ocdodsrc->ntriples;i++) { |
---|
253 | if(ocdodsrc->triples[i].key[0] != '\0') { /* avoid empty slots */ |
---|
254 | int lexorder = strcmp(ocdodsrc->triples[i].url,ocdodsrc->triples[largest].url); |
---|
255 | int leni = strlen(ocdodsrc->triples[i].url); |
---|
256 | int lenlarge = strlen(ocdodsrc->triples[largest].url); |
---|
257 | /* this defines the ordering */ |
---|
258 | if(leni == 0 && lenlarge == 0) continue; /* if no urls, then leave in order */ |
---|
259 | if(leni != 0 && lenlarge == 0) largest = i; |
---|
260 | else if(lexorder > 0) largest = i; |
---|
261 | } |
---|
262 | } |
---|
263 | /* Move the largest entry */ |
---|
264 | OCASSERT(ocdodsrc->triples[largest].key[0] != 0); |
---|
265 | sorted[nsorted] = ocdodsrc->triples[largest]; |
---|
266 | ocdodsrc->triples[largest].key[0] = '\0'; /* kill entry */ |
---|
267 | nsorted++; |
---|
268 | if(ocdebug > 2) |
---|
269 | ocdodsrcdump("pass:",sorted,nsorted); |
---|
270 | } |
---|
271 | |
---|
272 | memcpy((void*)ocdodsrc->triples,(void*)sorted,sizeof(struct OCTriple)*nsorted); |
---|
273 | free(sorted); |
---|
274 | |
---|
275 | if(ocdebug > 0) |
---|
276 | ocdodsrcdump("final .dodsrc order:",ocdodsrc->triples,ocdodsrc->ntriples); |
---|
277 | } |
---|
278 | |
---|
279 | /* Create a triple store from a file */ |
---|
280 | int |
---|
281 | ocdodsrc_read(char* basename, char* path) |
---|
282 | { |
---|
283 | char line0[MAXRCLINESIZE]; |
---|
284 | FILE *in_file = NULL; |
---|
285 | int linecount = 0; |
---|
286 | |
---|
287 | if(ocdodsrc == NULL) { |
---|
288 | ocdodsrc = (struct OCTriplestore*)malloc(sizeof(struct OCTriplestore)); |
---|
289 | if(ocdodsrc == NULL) { |
---|
290 | oc_log(LOGERR,"ocdodsrc_read: out of memory"); |
---|
291 | return 0; |
---|
292 | } |
---|
293 | } |
---|
294 | ocdodsrc->ntriples = 0; |
---|
295 | |
---|
296 | in_file = fopen(path, "r"); /* Open the file to read it */ |
---|
297 | if (in_file == NULL) { |
---|
298 | oc_log(LOGERR, "Could not open configuration file: %s",basename); |
---|
299 | return OC_EPERM; |
---|
300 | } |
---|
301 | |
---|
302 | for(;;) { |
---|
303 | char *line,*key,*value; |
---|
304 | if(!rcreadline(in_file,line0,sizeof(line0))) break; |
---|
305 | linecount++; |
---|
306 | if(linecount >= MAXRCLINES) { |
---|
307 | oc_log(LOGERR, ".dodsrc has too many lines"); |
---|
308 | return 0; |
---|
309 | } |
---|
310 | line = line0; |
---|
311 | /* check for comment */ |
---|
312 | if (line[0] == '#') continue; |
---|
313 | /* trim leading blanks */ |
---|
314 | line = rctrimleft(line,TRIMCHARS); |
---|
315 | if(strlen(line) >= MAXRCLINESIZE) { |
---|
316 | oc_log(LOGERR, "%s line too long: %s",basename,line0); |
---|
317 | return 0; |
---|
318 | } |
---|
319 | /* parse the line */ |
---|
320 | ocdodsrc->triples[ocdodsrc->ntriples].url[0] = '\0'; /*assume no url*/ |
---|
321 | if(line[0] == LTAG) { |
---|
322 | char* url = ++line; |
---|
323 | char* rtag = strchr(line,RTAG); |
---|
324 | if(rtag == NULL) { |
---|
325 | oc_log(LOGERR, "Malformed [url] in %s entry: %s",basename,line); |
---|
326 | continue; |
---|
327 | } |
---|
328 | line = rtag + 1; |
---|
329 | *rtag = '\0'; |
---|
330 | /* trim again */ |
---|
331 | line = rctrimleft(line,TRIMCHARS); |
---|
332 | /* save the url */ |
---|
333 | strcpy(ocdodsrc->triples[ocdodsrc->ntriples].url,TRIM(url)); |
---|
334 | } |
---|
335 | if(strlen(line)==0) continue; /* empty line */ |
---|
336 | /* split off key and value */ |
---|
337 | key=line; |
---|
338 | value = strchr(line, '='); |
---|
339 | if(value == NULL) { |
---|
340 | /* add fake '=1' */ |
---|
341 | if(strlen(line) + strlen("=1") >= MAXRCLINESIZE) { |
---|
342 | oc_log(LOGERR, "%s entry too long: %s",basename,line); |
---|
343 | continue; |
---|
344 | } |
---|
345 | strcat(line,"=1"); |
---|
346 | value = strchr(line,'='); |
---|
347 | } |
---|
348 | *value = '\0'; |
---|
349 | value++; |
---|
350 | strcpy(ocdodsrc->triples[ocdodsrc->ntriples].key,TRIM(key)); |
---|
351 | strcpy(ocdodsrc->triples[ocdodsrc->ntriples].value,TRIM(value)); |
---|
352 | ocdodsrc->ntriples++; |
---|
353 | } |
---|
354 | fclose(in_file); |
---|
355 | sorttriplestore(); |
---|
356 | return 1; |
---|
357 | } |
---|
358 | |
---|
359 | |
---|
360 | int |
---|
361 | ocdodsrc_process(OCstate* state) |
---|
362 | { |
---|
363 | int stat = 0; |
---|
364 | char* value; |
---|
365 | char* url = ocuribuild(state->uri,NULL,NULL,OCURIENCODE); |
---|
366 | if(ocdodsrc == NULL) goto done; |
---|
367 | value = curllookup("DEFLATE",url); |
---|
368 | if(value != NULL) { |
---|
369 | if(atoi(value)) state->curlflags.compress = 1; |
---|
370 | if(ocdebug > 0) |
---|
371 | oc_log(LOGNOTE,"Compression: %ld", state->curlflags.compress); |
---|
372 | } |
---|
373 | if((value = curllookup("VERBOSE",url)) != NULL) { |
---|
374 | if(atoi(value)) state->curlflags.verbose = 1; |
---|
375 | if(ocdebug > 0) |
---|
376 | oc_log(LOGNOTE,"curl.verbose: %ld", state->curlflags.verbose); |
---|
377 | } |
---|
378 | if((value = curllookup("TIMEOUT",url)) != NULL) { |
---|
379 | if(atoi(value)) state->curlflags.timeout = atoi(value); |
---|
380 | if(ocdebug > 0) |
---|
381 | oc_log(LOGNOTE,"curl.timeout: %ld", state->curlflags.timeout); |
---|
382 | } |
---|
383 | |
---|
384 | if((value = curllookup("COOKIEFILE",url)) != NULL) { |
---|
385 | state->curlflags.cookiefile = strdup(TRIM(value)); |
---|
386 | if(!state->curlflags.cookiefile) {stat = OC_ENOMEM; goto done;} |
---|
387 | if(ocdebug > 0) |
---|
388 | oc_log(LOGNOTE,"COOKIEFILE: %s", state->curlflags.cookiefile); |
---|
389 | } |
---|
390 | if((value = curllookup("COOKIEJAR",url)) |
---|
391 | || (value = curllookup("COOKIE_JAR",url))) { |
---|
392 | state->curlflags.cookiejar = strdup(TRIM(value)); |
---|
393 | if(!state->curlflags.cookiejar) {stat = OC_ENOMEM; goto done;} |
---|
394 | if(ocdebug > 0) |
---|
395 | oc_log(LOGNOTE,"COOKIEJAR: %s", state->curlflags.cookiejar); |
---|
396 | } |
---|
397 | |
---|
398 | /* Some servers (e.g. thredds) appear to require a place |
---|
399 | to put cookies in order for some security functions to work |
---|
400 | */ |
---|
401 | if(state->curlflags.cookiejar == NULL |
---|
402 | && state->curlflags.cookiefile == NULL) { |
---|
403 | state->curlflags.cookiefile = strdup(""); |
---|
404 | } |
---|
405 | |
---|
406 | if((value = curllookup("PROXY_SERVER",url)) != NULL) { |
---|
407 | stat = parseproxy(state,TRIM(value)); |
---|
408 | if(stat != OC_NOERR) goto done; |
---|
409 | } |
---|
410 | |
---|
411 | if((value = curllookup("SSL.VALIDATE",url)) != NULL) { |
---|
412 | if(atoi(value)) state->ssl.validate = 1; |
---|
413 | if(ocdebug > 0) |
---|
414 | oc_log(LOGNOTE,"CURL.SSL.VALIDATE: %ld", state->ssl.validate); |
---|
415 | } |
---|
416 | |
---|
417 | if((value = curllookup("SSL.CERTIFICATE",url)) != NULL) { |
---|
418 | state->ssl.certificate = strdup(TRIM(value)); |
---|
419 | if(!state->ssl.certificate) {stat = OC_ENOMEM; goto done;} |
---|
420 | if(ocdebug > 0) |
---|
421 | oc_log(LOGNOTE,"CREDENTIALS.SSL.CERTIFICATE: %s", state->ssl.certificate); |
---|
422 | } |
---|
423 | |
---|
424 | if((value = curllookup("SSL.KEY",url)) != NULL) { |
---|
425 | state->ssl.key = strdup(TRIM(value)); |
---|
426 | if(!state->ssl.key) {stat = OC_ENOMEM; goto done;} |
---|
427 | if(ocdebug > 0) |
---|
428 | oc_log(LOGNOTE,"CREDENTIALS.SSL.KEY: %s", state->ssl.key); |
---|
429 | } |
---|
430 | |
---|
431 | if((value = curllookup("SSL.KEYPASSWORD",url)) != NULL) { |
---|
432 | state->ssl.keypasswd = strdup(TRIM(value)); |
---|
433 | if(!state->ssl.keypasswd) {stat = OC_ENOMEM; goto done;} |
---|
434 | #ifdef INSECURE |
---|
435 | if(ocdebug > 0) |
---|
436 | oc_log(LOGNOTE,"CREDENTIALS.SSL.KEYPASSWORD: %s", state->ssl.keypasswd); |
---|
437 | #endif |
---|
438 | } |
---|
439 | |
---|
440 | if((value = curllookup("SSL.CAINFO",url)) != NULL) { |
---|
441 | state->ssl.cainfo = strdup(TRIM(value)); |
---|
442 | if(!state->ssl.cainfo) {stat = OC_ENOMEM; goto done;} |
---|
443 | if(ocdebug > 0) |
---|
444 | oc_log(LOGNOTE,"SSL.CAINFO: %s", state->ssl.cainfo); |
---|
445 | } |
---|
446 | |
---|
447 | if((value = curllookup("SSL.CAPATH",url)) != NULL) { |
---|
448 | state->ssl.capath = strdup(TRIM(value)); |
---|
449 | if(!state->ssl.capath) {stat = OC_ENOMEM; goto done;} |
---|
450 | if(ocdebug > 0) |
---|
451 | oc_log(LOGNOTE,"SSL.CAPATH: %s", state->ssl.capath); |
---|
452 | } |
---|
453 | |
---|
454 | if((value = curllookup("SSL.VERIFYPEER",url)) != NULL) { |
---|
455 | char* s = strdup(TRIM(value)); |
---|
456 | int tf = 0; |
---|
457 | if(s == NULL || strcmp(s,"0")==0 || strcasecmp(s,"false")==0) |
---|
458 | tf = 0; |
---|
459 | else if(strcmp(s,"1")==0 || strcasecmp(s,"true")==0) |
---|
460 | tf = 1; |
---|
461 | else |
---|
462 | tf = 1; /* default if not null */ |
---|
463 | state->ssl.verifypeer = tf; |
---|
464 | if(ocdebug > 0) |
---|
465 | oc_log(LOGNOTE,"SSL.VERIFYPEER: %d", state->ssl.verifypeer); |
---|
466 | } |
---|
467 | |
---|
468 | if((value = curllookup("CREDENTIALS.USER",url)) != NULL) { |
---|
469 | state->creds.username = strdup(TRIM(value)); |
---|
470 | if(!state->creds.username) {stat = OC_ENOMEM; goto done;} |
---|
471 | if(ocdebug > 0) |
---|
472 | oc_log(LOGNOTE,"CREDENTIALS.USER: %s", state->creds.username); |
---|
473 | } |
---|
474 | |
---|
475 | if((value = curllookup("CREDENTIALS.PASSWORD",url)) != NULL) { |
---|
476 | state->creds.password = strdup(TRIM(value)); |
---|
477 | if(!state->creds.password) {stat = OC_ENOMEM; goto done;} |
---|
478 | } |
---|
479 | /* else ignore */ |
---|
480 | |
---|
481 | done: |
---|
482 | if(url != NULL) free(url); |
---|
483 | return stat; |
---|
484 | } |
---|
485 | |
---|
486 | char* |
---|
487 | ocdodsrc_lookup(char* key, char* url) |
---|
488 | { |
---|
489 | int i,found; |
---|
490 | struct OCTriple* triple = ocdodsrc->triples; |
---|
491 | if(key == NULL || ocdodsrc == NULL) return NULL; |
---|
492 | if(url == NULL) url = ""; |
---|
493 | /* Assume that the triple store has been properly sorted */ |
---|
494 | for(found=0,i=0;i<ocdodsrc->ntriples;i++,triple++) { |
---|
495 | int triplelen = strlen(triple->url); |
---|
496 | int t; |
---|
497 | if(strcmp(key,triple->key) != 0) continue; /* keys do not match */ |
---|
498 | /* If the triple entry has no url, then use it (because we have checked all other cases)*/ |
---|
499 | if(triplelen == 0) {found=1;break;} |
---|
500 | /* do url prefix comparison */ |
---|
501 | t = ocstrncmp(url,triple->url,triplelen); |
---|
502 | if(t == 0) {found=1; break;} |
---|
503 | } |
---|
504 | if(ocdebug > 2) |
---|
505 | { |
---|
506 | if(found) { |
---|
507 | fprintf(stderr,"lookup %s: [%s]%s = %s\n",url,triple->url,triple->key,triple->value); |
---|
508 | } |
---|
509 | } |
---|
510 | return (found ? triple->value : NULL); |
---|
511 | } |
---|
512 | |
---|
513 | |
---|
514 | static void |
---|
515 | ocdodsrcdump(char* msg, struct OCTriple* triples, int ntriples) |
---|
516 | { |
---|
517 | int i; |
---|
518 | if(msg != NULL) fprintf(stderr,"%s\n",msg); |
---|
519 | if(ocdodsrc == NULL) { |
---|
520 | fprintf(stderr,"<EMPTY>\n"); |
---|
521 | return; |
---|
522 | } |
---|
523 | if(triples == NULL) triples= ocdodsrc->triples; |
---|
524 | if(ntriples < 0 ) ntriples= ocdodsrc->ntriples; |
---|
525 | for(i=0;i<ntriples;i++) { |
---|
526 | fprintf(stderr,"\t%s\t%s\t%s\n", |
---|
527 | (strlen(triples[i].url)==0?"--":triples[i].url), |
---|
528 | triples[i].key, |
---|
529 | triples[i].value); |
---|
530 | } |
---|
531 | } |
---|
532 | |
---|
533 | /* Isolate the "CURL." prefix to allow changing to something else */ |
---|
534 | static char* |
---|
535 | curllookup(char* suffix, char* url) |
---|
536 | { |
---|
537 | char key[2048]; |
---|
538 | char* value = NULL; |
---|
539 | strcpy(key,HTTPPREFIX); |
---|
540 | strcat(key,suffix); |
---|
541 | value = ocdodsrc_lookup(key,url); |
---|
542 | if(value == NULL) { |
---|
543 | strcpy(key,HTTPPREFIXDEPRECATED); |
---|
544 | strcat(key,suffix); |
---|
545 | value = ocdodsrc_lookup(key,url); |
---|
546 | } |
---|
547 | return value; |
---|
548 | } |
---|