1 | /*************************************** 2 | $Revision: 1.56 $ 3 | 4 | Query command module (qc). This is what the whois query gets stored as in 5 | memory. 6 | 7 | Status: NOT REVUED, TESTED 8 | 9 | ******************/ /****************** 10 | Filename : query_command.c 11 | Author : ottrey@ripe.net 12 | Modifications by : marek@ripe.net 13 | ******************/ /****************** 14 | Copyright (c) 1999,2000,2001,2002 RIPE NCC 15 | 16 | All Rights Reserved 17 | 18 | Permission to use, copy, modify, and distribute this software and its 19 | documentation for any purpose and without fee is hereby granted, 20 | provided that the above copyright notice appear in all copies and that 21 | both that copyright notice and this permission notice appear in 22 | supporting documentation, and that the name of the author not be 23 | used in advertising or publicity pertaining to distribution of the 24 | software without specific, written prior permission. 25 | 26 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 27 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 28 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 29 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 30 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 31 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 32 | ***************************************/ 33 | 34 | #define QC_IMPL 35 | #include "rip.h" 36 | 37 | #include <stdlib.h> 38 | #include <stdio.h> 39 | #include <string.h> 40 | #include <ctype.h> 41 | 42 | 43 | #define MAX_OPT_ARG_C 20 44 | 45 | extern char *suboptarg; 46 | extern int getsubopt(char **optionp, char * const *tokens, char **valuep); 47 | 48 | /*++++++++++++++++++++++++++++++++++++++ 49 | make a list of sources. expects list to hold source handles 50 | 51 | char * 52 | qc_sources_list_to_string returns an allocated string, must be freed 53 | 54 | GList *list list of source handles (as defined by CA) 55 | 56 | ++++++++++++++++++++++++++++++++++++++*/ 57 | char * 58 | qc_sources_list_to_string(GList *list) 59 | { 60 | GString *tmp; 61 | GList *qitem; 62 | char *result; 63 | 64 | /* use GString for the result, because it resizes magically */ 65 | tmp = g_string_sized_new(STR_L); 66 | 67 | /* loop through the list, creating a string with the names of the 68 | sources separated by commas */ 69 | qitem = g_list_first(list); 70 | if (qitem != NULL) { 71 | for (;;) { 72 | ca_dbSource_t *source_hdl = (ca_dbSource_t *) ( qitem->data ); 73 | char *srcname = ca_get_srcname( source_hdl ); 74 | g_string_append(tmp, srcname); 75 | 76 | qitem = g_list_next(qitem); 77 | if (qitem == NULL) { 78 | break; 79 | } 80 | 81 | g_string_append_c(tmp, ','); 82 | } 83 | } 84 | 85 | /* move to a new buffer for the return */ 86 | result = UT_strdup(tmp->str); 87 | g_string_free(tmp, TRUE); 88 | return result; 89 | } 90 | 91 | /* QC_environ_to_string() */ 92 | /*++++++++++++++++++++++++++++++++++++++ 93 | Convert the query_environ to a string. 94 | 95 | Query_environ *query_environ The query_environ to be converted. 96 | 97 | More: 98 | +html+ <PRE> 99 | Authors: 100 | ottrey 101 | +html+ </PRE><DL COMPACT> 102 | +html+ <DT>Online References: 103 | +html+ <DD><UL> 104 | +html+ </UL></DL> 105 | 106 | ++++++++++++++++++++++++++++++++++++++*/ 107 | char * 108 | QC_environ_to_string(Query_environ qe) 109 | { 110 | char *sources; 111 | char passed_addr[IP_ADDRSTR_MAX]; 112 | GString *tmp; 113 | char *result; 114 | 115 | /* convert the sources and the passed address (if any) to printable strings */ 116 | sources = qc_sources_list_to_string(qe.sources_list); 117 | if( IP_addr_b2a( &(qe.pIP), passed_addr, IP_ADDRSTR_MAX) != IP_OK ) { 118 | passed_addr[0] = '\0'; 119 | } 120 | 121 | /* format the environment info */ 122 | tmp = g_string_sized_new(STR_L); 123 | g_string_sprintf(tmp, 124 | "host=%s, keep_connection=%s, sources=%s, version=%s%s%s", 125 | qe.condat.ip, 126 | qe.k ? "on" : "off", 127 | sources, 128 | (qe.version == NULL) ? "?" : qe.version, 129 | passed_addr[0] == '\0' ? "" : ", passedIP=", 130 | passed_addr); 131 | 132 | /* move result to return buffer, and free up memory */ 133 | result = UT_strdup(tmp->str); 134 | g_string_free(tmp, TRUE); 135 | UT_free(sources); 136 | 137 | return result; 138 | 139 | } /* QC_environ_to_string() */ 140 | 141 | /* QC_query_command_to_string() */ 142 | /*++++++++++++++++++++++++++++++++++++++ 143 | Convert the query_command to a string. 144 | 145 | Query_command *query_command The query_command to be converted. 146 | 147 | More: 148 | +html+ <PRE> 149 | Authors: 150 | ottrey 151 | +html+ </PRE><DL COMPACT> 152 | +html+ <DT>Online References: 153 | +html+ <DD><UL> 154 | +html+ </UL></DL> 155 | 156 | ++++++++++++++++++++++++++++++++++++++*/ 157 | char *QC_query_command_to_string(Query_command *query_command) { 158 | char result_buf[STR_XL]; 159 | char *str1; 160 | char *str2; 161 | char *str3; 162 | 163 | str1 = MA_to_string(query_command->inv_attrs_bitmap, DF_get_attribute_names()); 164 | str2 = MA_to_string(query_command->object_type_bitmap, DF_get_class_names()); 165 | str3 = WK_to_string(query_command->keytypes_bitmap); 166 | 167 | sprintf(result_buf, "Query_command : inv_attrs=%s, recursive=%s, object_type=%s, (c=%s,e=%d,g=%d,l=%d,m=%d,q=%d,t=%d,v=%d,x=%d,F=%d,K=%d,L=%d,M=%d,R=%d,S=%d), possible keytypes=%s, keys=[%s]", 168 | str1, 169 | query_command->recursive?"y":"n", 170 | str2, 171 | query_command->c_irt_search ? "TRUE" : "FALSE", 172 | query_command->e, 173 | query_command->g, 174 | query_command->l, 175 | query_command->m, 176 | query_command->q, 177 | query_command->t, 178 | query_command->v, 179 | query_command->x, 180 | query_command->fast, 181 | query_command->filtered, 182 | query_command->L, 183 | query_command->M, 184 | query_command->R, 185 | query_command->S, 186 | str3, 187 | query_command->keys); 188 | UT_free(str1); 189 | UT_free(str2); 190 | UT_free(str3); 191 | 192 | return UT_strdup(result_buf); 193 | 194 | } /* QC_query_command_to_string() */ 195 | 196 | /* log_command() */ 197 | /*++++++++++++++++++++++++++++++++++++++ 198 | Log the command. 199 | This is more to do with Tracing. And should/will get merged with a tracing 200 | module (when it is finalized.) 201 | 202 | char *query_str 203 | 204 | Query_command *query_command 205 | 206 | More: 207 | +html+ <PRE> 208 | Authors: 209 | ottrey 210 | +html+ </PRE><DL COMPACT> 211 | +html+ <DT>Online References: 212 | +html+ <DD><UL> 213 | +html+ </UL></DL> 214 | 215 | ++++++++++++++++++++++++++++++++++++++*/ 216 | static void log_command(char *query_str, Query_command *query_command) { 217 | char *str; 218 | 219 | if( ER_is_traced(FAC_QC, ASP_QC_BUILD) ) { 220 | str = QC_query_command_to_string(query_command); 221 | ER_dbg_va(FAC_QC, ASP_QC_BUILD, 222 | "query=[%s] %s", query_str, str); 223 | UT_free(str); 224 | } 225 | } /* log_command() */ 226 | 227 | /* QC_environ_free() */ 228 | /*++++++++++++++++++++++++++++++++++++++ 229 | Free the query_environ. 230 | 231 | Query_command *qc query_environ to be freed. 232 | 233 | More: 234 | +html+ <PRE> 235 | Authors: 236 | ottrey 237 | +html+ </PRE><DL COMPACT> 238 | +html+ <DT>Online References: 239 | +html+ <DD><UL> 240 | +html+ </UL></DL> 241 | 242 | ++++++++++++++++++++++++++++++++++++++*/ 243 | void QC_environ_free(Query_environ *qe) { 244 | if (qe != NULL) { 245 | if (qe->version != NULL) { 246 | UT_free(qe->version); 247 | } 248 | 249 | if (qe->sources_list != NULL) { 250 | g_list_free(qe->sources_list); 251 | qe->sources_list=NULL; 252 | } 253 | UT_free(qe); 254 | } 255 | } /* QC_environ_free() */ 256 | 257 | /* QC_free() */ 258 | /*++++++++++++++++++++++++++++++++++++++ 259 | Free the query_command. 260 | 261 | Query_command *qc query_command to be freed. 262 | 263 | XXX I'm not sure the bitmaps will get freed. 264 | qc->inv_attrs_bitmap 265 | qc->object_type_bitmap 266 | qc->keytypes_bitmap 267 | 268 | More: 269 | +html+ <PRE> 270 | Authors: 271 | ottrey 272 | +html+ </PRE><DL COMPACT> 273 | +html+ <DT>Online References: 274 | +html+ <DD><UL> 275 | +html+ </UL></DL> 276 | 277 | ++++++++++++++++++++++++++++++++++++++*/ 278 | void QC_free(Query_command *qc) { 279 | if (qc != NULL) { 280 | if (qc->keys != NULL) { 281 | UT_free(qc->keys); 282 | } 283 | UT_free(qc); 284 | } 285 | } /* QC_free() */ 286 | 287 | 288 | 289 | /* QC_fill() */ 290 | /*++++++++++++++++++++++++++++++++++++++ 291 | Create a new query_command. 292 | Returns 0 when OK, -1 when query incorrect. 293 | 294 | char *query_str The garden variety whois query string. 295 | 296 | Query_environ *qe the environment 297 | 298 | More: 299 | +html+ <PRE> 300 | Authors: 301 | ottrey - original code 302 | marek - modified for my getopts, multiple sources; 303 | and generally cleaned. 304 | +html+ </PRE><DL COMPACT> 305 | +html+ <DT>Online References: 306 | +html+ <DD><UL> 307 | +html+ </UL></DL> 308 | 309 | ++++++++++++++++++++++++++++++++++++++*/ 310 | static 311 | int QC_fill(char *query_str, 312 | Query_command *query_command, 313 | Query_environ *qe) { 314 | 315 | int c; 316 | int synerrflg = 0; 317 | int badparerr = 0; 318 | int minusk = 0; 319 | char *inv_attrs_str = NULL; 320 | char *object_types_str = NULL; 321 | int opt_argc; 322 | gchar **opt_argv; 323 | char *value; 324 | /* char *tmp_query_str;*/ 325 | unsigned key_length; 326 | int i; 327 | int index; 328 | C_Type_t type; 329 | A_Type_t attr; 330 | getopt_state_t *gst = NULL; 331 | 332 | query_command->c_irt_search = FALSE; 333 | query_command->d = 0; 334 | query_command->e = 0; 335 | query_command->g = 0; 336 | query_command->inv_attrs_bitmap = MA_new(MA_END); 337 | query_command->recursive = 1; /* Recursion is on by default. */ 338 | query_command->l = 0; 339 | query_command->m = 0; 340 | query_command->q = -1; 341 | query_command->t = -1; 342 | query_command->v = -1; 343 | query_command->x = 0; 344 | query_command->fast = 0; 345 | query_command->filtered = 0; 346 | query_command->L = 0; 347 | query_command->M = 0; 348 | query_command->R = 0; 349 | query_command->S = 0; 350 | 351 | /* XXX UGLY - "all zeros" in object_type_bitmap means the same as 352 | "all ones". To limit the inconsistency, this is changed at the end 353 | of this function, so outside "all zeros" is an illegal value. */ 354 | query_command->object_type_bitmap = MA_new(MA_END); 355 | /* 356 | query_command->keytypes_bitmap = MA_new(MA_END); 357 | */ 358 | query_command->keys = NULL; 359 | 360 | /* This is so Marek can't crash me :-) */ 361 | /* Side Effect - query keys are subsequently cut short to STR_S size. */ 362 | 363 | /* tmp_query_str = (char *)UT_calloc(1, STR_S+1); 364 | strncpy(tmp_query_str, query_str, STR_S);*/ 365 | 366 | /* Create the arguments. */ 367 | /* This allows only a maximum of MAX_OPT_ARG_C words in the query. */ 368 | /* opt_argv = g_strsplit(tmp_query_str, " ", MAX_OPT_ARG_C);*/ 369 | opt_argv = g_strsplit(query_str, " ", MAX_OPT_ARG_C); 370 | 371 | /* Determine the number of arguments. */ 372 | for (opt_argc=0; opt_argv[opt_argc] != NULL; opt_argc++); 373 | 374 | dieif( (gst = mg_new(0)) == NULL ); 375 | 376 | while ((c = mg_getopt(opt_argc, opt_argv, "acdegi:klrmq:s:t:v:xFKLMRST:V:", 377 | gst)) != EOF) { 378 | switch (c) { 379 | case 'a': 380 | /* Remove any user specified sources from the sources list. */ 381 | /* free the list only, do not touch the elements */ 382 | g_list_free(qe->sources_list); 383 | qe->sources_list=NULL; 384 | 385 | /* Add all the config sources to the sources list. */ 386 | { 387 | int i; 388 | ca_dbSource_t *hdl; 389 | 390 | for (i=0; (hdl = ca_get_SourceHandleByPosition(i)) != NULL; i++) { 391 | qe->sources_list = g_list_append(qe->sources_list, (void *)hdl); 392 | } 393 | } 394 | 395 | 396 | break; 397 | 398 | case 'c': 399 | query_command->c_irt_search = TRUE; 400 | break; 401 | 402 | case 'e': 403 | query_command->e=1; 404 | break; 405 | 406 | case 'd': 407 | query_command->d=1; 408 | break; 409 | 410 | case 'g': 411 | query_command->g=1; 412 | break; 413 | 414 | case 'i': 415 | if (gst->optarg != NULL) { 416 | char *hackstr = NULL; 417 | 418 | inv_attrs_str = gst->optarg; 419 | /* 420 | Now a really stupid hard-coded hack to support "pn" being a 421 | synonym for "ac,tc,zc,ah". I particularly object to this because 422 | it references attributes that should only be defined in XML - but 423 | I don't see a simplier more robust way of doing this hack. 424 | :-( - ottrey 8/12/99 425 | 426 | ** removed a memory leak - MB, 1/08/00 427 | 428 | ** removed the use of "ro", added "person" - shane, 2002-01-23 429 | 430 | */ 431 | if ( strcmp(inv_attrs_str, "pn") == 0 432 | || strcmp(inv_attrs_str, "person") == 0) { 433 | hackstr = UT_strdup("ac,tc,zc,ah,cn"); 434 | inv_attrs_str = hackstr; 435 | } 436 | while (*inv_attrs_str) { 437 | index = getsubopt(&inv_attrs_str, DF_get_attribute_aliases(), &value); 438 | if (index == -1) { 439 | /* Unknown attribute encountered. */ 440 | char *rep = ca_get_qc_badattr ; 441 | SK_cd_puts(&(qe->condat), rep); 442 | UT_free(rep); 443 | 444 | attr = -1; 445 | badparerr++; 446 | } 447 | else { 448 | mask_t inv_attr_mask = MA_new(INV_ATTR_MASK); 449 | attr = DF_get_attribute_index(index); 450 | if ( MA_isset(inv_attr_mask, attr) == 1 ) { 451 | /* Add the attr to the bitmap. */ 452 | MA_set(&(query_command->inv_attrs_bitmap), attr, 1); 453 | } 454 | else { 455 | /* "%s" is not an inverse searchable attribute. */ 456 | char *rep = ca_get_qc_fmt_attrnotinv ; 457 | SK_cd_printf(&(qe->condat), rep, 458 | (DF_get_attribute_aliases())[index]); 459 | UT_free(rep); 460 | badparerr++; 461 | } 462 | } 463 | } /* while () */ 464 | 465 | if( hackstr != NULL) { 466 | UT_free(hackstr); 467 | } 468 | } /* if () */ 469 | break; 470 | 471 | case 'k': 472 | minusk = 1; 473 | break; 474 | 475 | case 'r': 476 | query_command->recursive=0; /* Unset recursion */ 477 | break; 478 | 479 | case 'l': 480 | query_command->l=1; 481 | break; 482 | 483 | case 'm': 484 | query_command->m=1; 485 | break; 486 | 487 | case 'q': 488 | if (gst->optarg != NULL) { 489 | index = getsubopt(&gst->optarg, DF_get_server_queries(), &value); 490 | if (index == -1) { 491 | synerrflg++; 492 | } 493 | else { 494 | query_command->q = index; 495 | } 496 | } /* if () */ 497 | break; 498 | 499 | case 's': 500 | if (gst->optarg != NULL) { 501 | char *token, *cursor = gst->optarg; 502 | ca_dbSource_t *handle; 503 | 504 | /* Remove any sources from the sources list. */ 505 | g_list_free(qe->sources_list); 506 | qe->sources_list=NULL; 507 | 508 | /* go through specified sources */ 509 | while( (token = strsep( &cursor, "," )) != NULL ) { 510 | 511 | if( (handle = ca_get_SourceHandleByName(token)) != NULL ) { 512 | /* append */ 513 | qe->sources_list 514 | = g_list_append(qe->sources_list, (void *) handle ); 515 | } 516 | else { 517 | /* bail out */ 518 | 519 | /* Unknown source %s requested. */ 520 | char *rep = ca_get_qc_fmt_badsource ; 521 | SK_cd_printf(&(qe->condat), rep, token ); 522 | UT_free(rep); 523 | 524 | /* XXX error */ 525 | badparerr++; 526 | 527 | } /* if handle not null */ 528 | } /* while sources */ 529 | } /* if argument present */ 530 | break; 531 | 532 | case 't': 533 | if (gst->optarg != NULL) { 534 | object_types_str = gst->optarg; 535 | while (*object_types_str) { 536 | index = getsubopt(&object_types_str, DF_get_class_aliases(), &value); 537 | if (index == -1) { 538 | /* Unknown object type encountered */ 539 | char *rep = ca_get_qc_badobjtype ; 540 | SK_cd_puts(&(qe->condat), rep); 541 | UT_free(rep); 542 | badparerr++; 543 | } 544 | else { 545 | type = DF_get_class_index(index); 546 | query_command->t=type; 547 | } 548 | } 549 | } 550 | break; 551 | 552 | case 'v': 553 | if (gst->optarg != NULL) { 554 | object_types_str = gst->optarg; 555 | if (*object_types_str) { 556 | index = getsubopt(&object_types_str, DF_get_class_aliases(), &value); 557 | if (index == -1) { 558 | /* Unknown object type encountered */ 559 | char *rep = ca_get_qc_badobjtype ; 560 | SK_cd_puts(&(qe->condat), rep); 561 | UT_free(rep); 562 | badparerr++; 563 | } 564 | else { 565 | type = DF_get_class_index(index); 566 | query_command->v=type; 567 | } 568 | } 569 | } 570 | break; 571 | 572 | case 'x': 573 | query_command->x=1; 574 | break; 575 | 576 | case 'F': 577 | query_command->fast=1; 578 | query_command->recursive=0; /* implies no recursion */ 579 | break; 580 | 581 | case 'K': 582 | query_command->filtered=1; 583 | query_command->recursive=0; /* implies no recursion */ 584 | break; 585 | 586 | case 'L': 587 | query_command->L=1; 588 | break; 589 | 590 | case 'M': 591 | query_command->M=1; 592 | break; 593 | 594 | case 'R': 595 | query_command->R=1; 596 | break; 597 | 598 | case 'S': 599 | query_command->S=1; 600 | break; 601 | 602 | case 'T': 603 | if (gst->optarg != NULL) { 604 | /* parse the specification */ 605 | object_types_str = gst->optarg; 606 | while (*object_types_str) { 607 | index = getsubopt(&object_types_str, DF_get_class_aliases(), &value); 608 | if (index == -1) { 609 | /* Unknown object type encountered */ 610 | char *rep = ca_get_qc_badobjtype ; 611 | SK_cd_puts(&(qe->condat), rep); 612 | UT_free(rep); 613 | badparerr++; 614 | } 615 | else { 616 | type = DF_get_class_index(index); 617 | /* Add the type to the bitmap. */ 618 | MA_set(&(query_command->object_type_bitmap), (unsigned) type, 1); 619 | } 620 | } 621 | } 622 | break; 623 | 624 | case 'V': 625 | if (qe->version != NULL) { 626 | /* free up the old client info */ 627 | UT_free(qe->version); 628 | } 629 | 630 | { 631 | char *token, *cursor = gst->optarg; 632 | while( (token = strsep( &cursor, "," )) != NULL ) { 633 | if(IP_addr_e2b( & (qe->pIP), token) 634 | != IP_OK ) { 635 | /* means it was not an IP -> it was a version */ 636 | qe->version = UT_strdup(token); 637 | } 638 | } 639 | } 640 | break; 641 | 642 | /* any other flag, including '?' and ':' errors */ 643 | default: 644 | synerrflg++; 645 | } 646 | } 647 | 648 | /* copy the key */ 649 | 650 | /* Work out the length of space needed */ 651 | key_length = 1; /* for terminal '\0' */ 652 | for (i=gst->optind ; i < opt_argc; i++) { 653 | /* length for the string + 1 for the '\0'+ 1 for the ' ' */ 654 | if (opt_argv[i] != NULL) { 655 | key_length += strlen(opt_argv[i])+1; 656 | } 657 | } 658 | /* allocate */ 659 | query_command->keys = (char *)UT_calloc(1, key_length+1); 660 | 661 | /* copy */ 662 | for (i=gst->optind; i < opt_argc; i++) { 663 | strcat(query_command->keys, opt_argv[i]); 664 | if ( (i + 1) < opt_argc) { 665 | strcat(query_command->keys, " "); 666 | } 667 | } 668 | 669 | /* if no error, process the key, otherwise don't bother */ 670 | if ( ! synerrflg && ! badparerr ) { 671 | /* convert the key to uppercase. */ 672 | for (i=0; i <= key_length; i++) { 673 | query_command->keys[i] = toupper(query_command->keys[i]); 674 | } 675 | 676 | /* make the keytypes_bitmap. */ 677 | query_command->keytypes_bitmap = WK_new(query_command->keys); 678 | 679 | /* fix the object type bitmap - turn "all zeros" into "all ones" */ 680 | if( MA_bitcount(query_command->object_type_bitmap) == 0 ) { 681 | query_command->object_type_bitmap = MA_not(query_command->object_type_bitmap); 682 | } 683 | 684 | /* -d handling: if the keytype is IPv4/v6 address/prefix/range, then 685 | exclude the domains unless -d is set 686 | XXX this must be kept in sync with new types */ 687 | if( query_command->d == 0 688 | && ( MA_isset(query_command->keytypes_bitmap, WK_IPADDRESS) 689 | || MA_isset(query_command->keytypes_bitmap, WK_IPRANGE ) 690 | || MA_isset(query_command->keytypes_bitmap, WK_IPPREFIX ) 691 | || MA_isset(query_command->keytypes_bitmap, WK_IP6PREFIX ) 692 | ) ) { 693 | 694 | MA_set(&(query_command->object_type_bitmap), C_DN , 0); 695 | } 696 | 697 | /* tracing */ 698 | /* log_command(tmp_query_str, query_command);*/ 699 | log_command(query_str, query_command); 700 | 701 | /* "keep connection" processing: 702 | when opening connection, -k may be alone or with a query 703 | later -k must appear alone (or there must be an empty line, 704 | or an error) for the connection to close. 705 | */ 706 | if( minusk ) { 707 | if( qe->k == 0 ) { /* opening */ 708 | qe->k = 1; 709 | } 710 | else { /* closing, if no key; otherwise keep open */ 711 | if( key_length <= 1 ) { 712 | qe->k = 0; 713 | } 714 | } 715 | } 716 | 717 | } /* if no error */ 718 | 719 | /* we don't need this anymore */ 720 | /* UT_free(tmp_query_str);*/ 721 | UT_free(gst); 722 | g_strfreev(opt_argv); 723 | 724 | if(synerrflg > 0) { /* severe syntax error. Usage must be printed */ 725 | return QC_SYNERR; 726 | } 727 | else if(badparerr > 0) { /* the requester has a clue. No Usage info */ 728 | return QC_PARERR; 729 | } 730 | else { 731 | return 0; 732 | } 733 | } /* QC_fill() */ 734 | 735 | /* QC_environ_new() */ 736 | /*++++++++++++++++++++++++++++++++++++++ 737 | Create a new query environment. 738 | 739 | More: 740 | +html+ <PRE> 741 | Authors: 742 | ottrey 743 | +html+ </PRE><DL COMPACT> 744 | +html+ <DT>Online References: 745 | +html+ <DD><UL> 746 | +html+ </UL></DL> 747 | 748 | ++++++++++++++++++++++++++++++++++++++*/ 749 | Query_environ *QC_environ_new(char *ip, int sock) { 750 | Query_environ *qe; 751 | 752 | qe = (Query_environ *)UT_calloc(1, sizeof(Query_environ)); 753 | qe->condat.ip = ip; 754 | qe->condat.sock = sock; 755 | 756 | /* The source is initialized to include only the deflook sources */ 757 | { 758 | int i; 759 | ca_dbSource_t *hdl; 760 | 761 | for (i=0; (hdl = ca_get_SourceHandleByPosition(i)) != NULL; i++) { 762 | char *amrmrulez = ca_get_srcdeflook(hdl); 763 | if( strcmp(amrmrulez, "y")==0 ) { 764 | qe->sources_list = g_list_append(qe->sources_list, (void *)hdl); 765 | } 766 | UT_free(amrmrulez); 767 | } 768 | } 769 | 770 | return qe; 771 | 772 | } /* QC_environ_new() */ 773 | 774 | 775 | 776 | 777 | /* QC_create() */ 778 | /*++++++++++++++++++++++++++++++++++++++ 779 | try to parse the query and fill in the QC struct, setting 780 | qc->query_type accordingly. 781 | 782 | Query_command *QC_create returns allocated structure 783 | 784 | char *input user query 785 | 786 | Query_environ *qe query environment structure 787 | 788 | Author: 789 | marek. 790 | 791 | ++++++++++++++++++++++++++++++++++++++*/ 792 | 793 | Query_command *QC_create(char *input, Query_environ *qe) 794 | { 795 | Query_command *qc; 796 | /* allocate place for a copy of the input */ 797 | char *copy = UT_calloc(1,strlen(input)+1); 798 | unsigned char *ci, *co; 799 | int qt; 800 | /* clean the string from junk - allow only known chars, something like 801 | tr/A-Za-z0-9\-\_\:\+\=\.\,\@\/ \n//cd; 802 | 803 | strip leading spaces too 804 | */ 805 | 806 | for(ci = (unsigned char *)input; *ci != 0 && isspace(*ci); ci++) { 807 | /* EMPTY */ 808 | } 809 | 810 | for(co = (unsigned char *) copy; *ci != 0; ci++) { 811 | if( strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* only those are allowed */ 812 | "abcdefghijklmnopqrstuvwxyz" 813 | "0123456789-_:+=.,@/?' \n", *ci) != NULL) { 814 | *(co++) = *ci; 815 | } 816 | } 817 | 818 | /* now delete whitespace chars at the end */ 819 | while( co != (unsigned char *)copy /* don't read past the beginning */ 820 | && isspace(*co) ) { 821 | *co = '\0'; 822 | co--; 823 | } 824 | 825 | 826 | qc = (Query_command *)UT_calloc(1, sizeof(Query_command)); 827 | 828 | if ( strlen(copy) == 0) { 829 | /* An empty query (Ie return) was sent */ 830 | qc->query_type = QC_EMPTY; 831 | } 832 | else { /* else <==> input_length > 0 ) */ 833 | /* parse query */ 834 | qt = QC_fill(copy, qc, qe); 835 | 836 | if( qt == QC_SYNERR || qt == QC_PARERR ) { 837 | qc->query_type = qt; 838 | } 839 | else { 840 | /* Update the query environment */ 841 | /* qe = QC_environ_update(qc, qe); */ 842 | 843 | /* Only do a query if there are keys. */ 844 | if (qc->keys == NULL || strlen(qc->keys) == 0 ) { 845 | if( strlen(qc->keys) == 0 846 | && ( qc->q != -1 || qc->t != -1 || qc->v != -1 ) ) { 847 | qc->query_type = QC_TEMPLATE; 848 | } 849 | else { 850 | qc->query_type = QC_NOKEY; 851 | } 852 | } 853 | else { 854 | if ( strcmp(qc->keys, "HELP") == 0 ) { 855 | qc->query_type = QC_HELP; 856 | } 857 | /* So, a real query */ 858 | else if( qc->filtered ) { 859 | qc->query_type = QC_FILTERED; 860 | } 861 | else { 862 | qc->query_type = QC_REAL; 863 | } 864 | } 865 | } 866 | } 867 | 868 | UT_free(copy); 869 | 870 | return qc; 871 | } 872 | 873 | 874 | /*++++++++++++++++++++++++++++++++++++++ 875 | 876 | Get the name of the given query type code. 877 | 878 | char *QC_get_qrytype returns a pointer to an element of array of static strings 879 | 880 | qc_qtype_t qrytype query type code 881 | 882 | ++++++++++++++++++++++++++++++++++++++*/ 883 | 884 | char *QC_get_qrytype(qc_qtype_t qrytype) { 885 | dieif(qrytype >= QC_TYPE_MAX); 886 | 887 | return qrytype_str[qrytype]; 888 | }