1 | /*************************************** 2 | $Revision: 1.22 $ 3 | 4 | Query command module (qc). This is what the whois query gets stored as in 5 | memory. 6 | 7 | Status: NOT REVUED, NOT TESTED 8 | 9 | ******************/ /****************** 10 | Filename : query_command.c 11 | Author : ottrey@ripe.net 12 | OSs Tested : Solaris 13 | To Do : Write some kind of options parser (to check for valid 14 | combinations of options.) 15 | Comments : 16 | ******************/ /****************** 17 | Copyright (c) 1999 RIPE NCC 18 | 19 | All Rights Reserved 20 | 21 | Permission to use, copy, modify, and distribute this software and its 22 | documentation for any purpose and without fee is hereby granted, 23 | provided that the above copyright notice appear in all copies and that 24 | both that copyright notice and this permission notice appear in 25 | supporting documentation, and that the name of the author not be 26 | used in advertising or publicity pertaining to distribution of the 27 | software without specific, written prior permission. 28 | 29 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 30 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 31 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 32 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 33 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 34 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 35 | ***************************************/ 36 | #include <stdlib.h> 37 | #include <stdio.h> 38 | #include <string.h> 39 | #include <ctype.h> 40 | 41 | #include "query_command.h" 42 | #include "defs.h" 43 | #include "constants.h" 44 | #include "which_keytypes.h" 45 | #include "memwrap.h" 46 | 47 | #define MAX_OPT_ARG_C 20 48 | 49 | /*+ String sizes +*/ 50 | #define STR_S 63 51 | #define STR_M 255 52 | #define STR_L 1023 53 | #define STR_XL 4095 54 | #define STR_XXL 16383 55 | 56 | /* XXX These probably wont get used. I'm using a switch statement instead. -ottrey 5/7/99 */ 57 | /* 58 | mask_t Inv_attr_mask; 59 | mask_t Object_mask; 60 | */ 61 | 62 | #ifdef HAVE_STRSEP 63 | /* good */ 64 | #else 65 | # if defined(HAVE_STRTOK_R) && !defined(HAVE_STRSEP) 66 | /* emulate strsep with strtok_r 67 | by making first arg to strtok_r point to the last 68 | */ 69 | char * 70 | strsep(char **stringp, const char *delim) 71 | { 72 | return strtok_r( *stringp, delim, stringp); 73 | } 74 | # else 75 | # error "must have strsep or strtok_r" 76 | # endif 77 | #endif 78 | 79 | 80 | /* my_getopt() */ 81 | /*++++++++++++++++++++++++++++++++++++++ 82 | A thread safe version of getopt, used to get the options from the whois 83 | query. 84 | 85 | int opt_argc The number of query arguments. 86 | 87 | char **opt_argv The query arguments. 88 | 89 | char *optstring The string containing valid options. 90 | 91 | int *my_optind_ptr A pointer to the index into the options of the option 92 | returned. 93 | 94 | char **my_optarg_ptr A pointer to the arguments to be returned. 95 | 96 | More: 97 | +html+ <PRE> 98 | Authors: 99 | ottrey 100 | +html+ </PRE><DL COMPACT> 101 | +html+ <DT>Online References: 102 | +html+ <DD><UL> 103 | +html+ <LI>man getopt 104 | +html+ </UL></DL> 105 | 106 | ++++++++++++++++++++++++++++++++++++++*/ 107 | static int my_getopt(int opt_argc, char **opt_argv, char *optstring, int *my_optind_ptr, char **my_optarg_ptr) { 108 | int c='?'; 109 | int i, j; 110 | int no_options; 111 | int optind = *my_optind_ptr; 112 | char option[3]; 113 | int option_matched=0; 114 | 115 | /* Get the number of options in the option string */ 116 | for(i=0, no_options=0; i < strlen(optstring) ; i++) { 117 | if (optstring[i] != ':') { 118 | no_options++; 119 | } 120 | } 121 | 122 | /* Iterate through all the option until it matches the current opt_argv */ 123 | /* Ie. opt_argv[optind] */ 124 | for (i=0, j=0; i <= no_options; i++, j++) { 125 | /* Construct one option from the optstring */ 126 | option[0] = '-'; 127 | if (optstring[j] == ':') { 128 | j++; 129 | } 130 | option[1] = optstring[j]; 131 | if ( optstring[j+1] == ':' ) { 132 | option[2] = ':'; 133 | } 134 | else { 135 | option[2] = '\0'; 136 | } 137 | option[3] = '\0'; 138 | 139 | if (optind < opt_argc) { 140 | if (strlen(opt_argv[optind]) > 0) { 141 | /* 142 | printf("opt_argv[%d] == option <==> %s == %s\n", optind, opt_argv[optind], option); 143 | */ 144 | if (strncmp(opt_argv[optind], option, 2) == 0) { 145 | /* Does the option have arguments. */ 146 | if (option[2] == ':') { 147 | /* If the option has arguments */ 148 | if (strlen(opt_argv[optind]) > 2) { 149 | /* If the arguments are in this token */ 150 | *my_optarg_ptr = (opt_argv[optind])+2; 151 | } 152 | else { 153 | /* If the arguments are in the next token */ 154 | *my_optarg_ptr = opt_argv[optind+1]; 155 | optind++; 156 | } 157 | } 158 | else { 159 | /* There are no arguments to this token */ 160 | *my_optarg_ptr = NULL; 161 | } 162 | /* Option matched - break out of the search */ 163 | option_matched = 1; 164 | break; 165 | } 166 | } 167 | } 168 | } /* for() */ 169 | 170 | if ( option_matched == 1 ) { 171 | /* This option was matched, return it. */ 172 | c = option[1]; 173 | 174 | /* Move to the next opt_argv */ 175 | optind++; 176 | *my_optind_ptr = optind; 177 | } 178 | else { 179 | /* Discontinue search */ 180 | c = EOF; 181 | } 182 | 183 | return c; 184 | 185 | } /* my_getopt() */ 186 | 187 | /* QC_environ_to_string() */ 188 | /*++++++++++++++++++++++++++++++++++++++ 189 | Convert the query_environ to a string. 190 | 191 | Query_environ *query_environ The query_environ to be converted. 192 | 193 | More: 194 | +html+ <PRE> 195 | Authors: 196 | ottrey 197 | +html+ </PRE><DL COMPACT> 198 | +html+ <DT>Online References: 199 | +html+ <DD><UL> 200 | +html+ </UL></DL> 201 | 202 | ++++++++++++++++++++++++++++++++++++++*/ 203 | char *QC_environ_to_string(Query_environ qe) { 204 | char *result; 205 | char *str1; 206 | char str2[IP_ADDRSTR_MAX]; 207 | char result_buf[STR_XL]; 208 | 209 | str1 = DF_sources_list_to_string(qe.sources_list); 210 | 211 | if( IP_addr_b2a( &(qe.pIP), str2, IP_ADDRSTR_MAX) != IP_OK ) { 212 | *str2 = '\0'; 213 | } 214 | 215 | sprintf(result_buf, "host=%s, keep_connection=%s, sources=%s, version=%s%s%s", qe.condat.ip, 216 | qe.k?"on":"off", 217 | str1, 218 | (qe.version == NULL) ? "?" : qe.version, 219 | *str2 == '\0' ? "" : ", passedIP=", 220 | *str2 == '\0' ? "" : str2 221 | ); 222 | 223 | wr_free(str1); 224 | 225 | //result = (char *)calloc(1, strlen(result_buf)+1); 226 | dieif( wr_malloc((void **)&result, strlen(result_buf)+1) != UT_OK); 227 | 228 | strcpy(result, result_buf); 229 | 230 | return result; 231 | 232 | } /* QC_environ_to_string() */ 233 | 234 | /* QC_query_command_to_string() */ 235 | /*++++++++++++++++++++++++++++++++++++++ 236 | Convert the query_command to a string. 237 | 238 | Query_command *query_command The query_command to be converted. 239 | 240 | More: 241 | +html+ <PRE> 242 | Authors: 243 | ottrey 244 | +html+ </PRE><DL COMPACT> 245 | +html+ <DT>Online References: 246 | +html+ <DD><UL> 247 | +html+ </UL></DL> 248 | 249 | ++++++++++++++++++++++++++++++++++++++*/ 250 | char *QC_query_command_to_string(Query_command *query_command) { 251 | char *result; 252 | char result_buf[STR_XL]; 253 | char *str1; 254 | char *str2; 255 | char *str3; 256 | 257 | str1 = MA_to_string(query_command->inv_attrs_bitmap, DF_get_attribute_names()); 258 | str2 = MA_to_string(query_command->object_type_bitmap, DF_get_class_names()); 259 | str3 = WK_to_string(query_command->keytypes_bitmap); 260 | 261 | sprintf(result_buf, "Query_command : inv_attrs=%s, recursive=%s, object_type=%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]\n", 262 | str1, 263 | query_command->recursive?"y":"n", 264 | str2, 265 | query_command->e, 266 | query_command->g, 267 | query_command->l, 268 | query_command->m, 269 | query_command->q, 270 | query_command->t, 271 | query_command->v, 272 | query_command->x, 273 | query_command->fast, 274 | query_command->filtered, 275 | query_command->L, 276 | query_command->M, 277 | query_command->R, 278 | query_command->S, 279 | str3, 280 | query_command->keys); 281 | wr_free(str1); 282 | wr_free(str2); 283 | wr_free(str3); 284 | 285 | // result = (char *)calloc(1, strlen(result_buf)+1); 286 | dieif( wr_malloc((void **)&result, strlen(result_buf)+1) != UT_OK); 287 | strcpy(result, result_buf); 288 | 289 | return result; 290 | 291 | } /* QC_query_command_to_string() */ 292 | 293 | /* log_command() */ 294 | /*++++++++++++++++++++++++++++++++++++++ 295 | Log the command. 296 | This is more to do with Tracing. And should/will get merged with a tracing 297 | module (when it is finalized.) 298 | 299 | char *query_str 300 | 301 | Query_command *query_command 302 | 303 | More: 304 | +html+ <PRE> 305 | Authors: 306 | ottrey 307 | +html+ </PRE><DL COMPACT> 308 | +html+ <DT>Online References: 309 | +html+ <DD><UL> 310 | +html+ </UL></DL> 311 | 312 | ++++++++++++++++++++++++++++++++++++++*/ 313 | static void log_command(char *query_str, Query_command *query_command) { 314 | FILE *logf; 315 | char *str; 316 | 317 | if (CO_get_comnd_logging() == 1) { 318 | str = QC_query_command_to_string(query_command); 319 | if (strcmp(CO_get_comnd_logfile(), "stdout") == 0) { 320 | printf("query=[%s]\n%s", query_str, str); 321 | } 322 | else { 323 | logf = fopen(CO_get_comnd_logfile(), "a"); 324 | fprintf(logf, "query=[%s]\n%s", query_str, str); 325 | fclose(logf); 326 | } 327 | wr_free(str); 328 | } 329 | 330 | } /* log_command() */ 331 | 332 | /* QC_environ_free() */ 333 | /*++++++++++++++++++++++++++++++++++++++ 334 | Free the query_environ. 335 | 336 | Query_command *qc query_environ to be freed. 337 | 338 | More: 339 | +html+ <PRE> 340 | Authors: 341 | ottrey 342 | +html+ </PRE><DL COMPACT> 343 | +html+ <DT>Online References: 344 | +html+ <DD><UL> 345 | +html+ </UL></DL> 346 | 347 | ++++++++++++++++++++++++++++++++++++++*/ 348 | void QC_environ_free(Query_environ *qe) { 349 | if (qe != NULL) { 350 | if (qe->sources_list != NULL) { 351 | g_list_free(qe->sources_list); 352 | } 353 | wr_free(qe); 354 | } 355 | } /* QC_environ_free() */ 356 | 357 | /* QC_free() */ 358 | /*++++++++++++++++++++++++++++++++++++++ 359 | Free the query_command. 360 | 361 | Query_command *qc query_command to be freed. 362 | 363 | XXX I'm not sure the bitmaps will get freed. 364 | qc->inv_attrs_bitmap 365 | qc->object_type_bitmap 366 | qc->keytypes_bitmap 367 | 368 | More: 369 | +html+ <PRE> 370 | Authors: 371 | ottrey 372 | +html+ </PRE><DL COMPACT> 373 | +html+ <DT>Online References: 374 | +html+ <DD><UL> 375 | +html+ </UL></DL> 376 | 377 | ++++++++++++++++++++++++++++++++++++++*/ 378 | void QC_free(Query_command *qc) { 379 | if (qc != NULL) { 380 | if (qc->keys != NULL) { 381 | wr_free(qc->keys); 382 | } 383 | wr_free(qc); 384 | } 385 | } /* QC_free() */ 386 | 387 | 388 | 389 | /* QC_fill() */ 390 | /*++++++++++++++++++++++++++++++++++++++ 391 | Create a new query_command. 392 | 393 | char *query_str The garden variety whois query string. 394 | 395 | Query_environ *qe the environment 396 | 397 | Pre-condition: 398 | 399 | More: 400 | +html+ <PRE> 401 | Authors: 402 | ottrey 403 | +html+ </PRE><DL COMPACT> 404 | +html+ <DT>Online References: 405 | +html+ <DD><UL> 406 | +html+ </UL></DL> 407 | 408 | ++++++++++++++++++++++++++++++++++++++*/ 409 | static 410 | void QC_fill(char *query_str, 411 | Query_command *query_command, 412 | Query_environ *qe) { 413 | char *my_optarg; 414 | int my_optind = 0; 415 | int c; 416 | int errflg = 0; 417 | char *inv_attrs_str = NULL; 418 | char *object_types_str = NULL; 419 | char *sources_str = NULL; 420 | int opt_argc; 421 | gchar **opt_argv; 422 | char *value; 423 | char *tmp_query_str; 424 | int key_length; 425 | int i; 426 | int index; 427 | int type; 428 | int attr; 429 | 430 | char str_buf[STR_XL]; 431 | 432 | GList *first_source; 433 | 434 | query_command->e = 0; 435 | query_command->g = 0; 436 | query_command->inv_attrs_bitmap = MA_new(MA_END); 437 | query_command->recursive = 1; /* Recursion is on by default. */ 438 | query_command->l = 0; 439 | query_command->m = 0; 440 | query_command->q = 0; 441 | query_command->t = 0; 442 | query_command->v = 0; 443 | query_command->x = 0; 444 | query_command->fast = 0; 445 | query_command->filtered = 0; 446 | query_command->L = 0; 447 | query_command->M = 0; 448 | query_command->R = 0; 449 | query_command->S = 0; 450 | query_command->object_type_bitmap = MA_new(MA_END); 451 | /* 452 | query_command->keytypes_bitmap = MA_new(MA_END); 453 | */ 454 | query_command->keys = NULL; 455 | 456 | /* This is so Marek can't crash me :-) */ 457 | /* Side Effect - query keys are subsequently cut short to STR_S size. */ 458 | //tmp_query_str = (char *)calloc(1, STR_S+1); 459 | dieif( wr_calloc((void **)&tmp_query_str, 1, STR_S+1) != UT_OK); 460 | strncpy(tmp_query_str, query_str, STR_S); 461 | 462 | /* Create the arguments. */ 463 | /* This allows only a maximum of MAX_OPT_ARG_C words in the query. */ 464 | opt_argv = g_strsplit(tmp_query_str, " ", MAX_OPT_ARG_C); 465 | 466 | /* Determine the number of arguments. */ 467 | for (opt_argc=0; opt_argv[opt_argc] != NULL; opt_argc++); 468 | 469 | while ((c = my_getopt(opt_argc, opt_argv, "aegi:klrmq:s:t:v:xFKLMRST:V:", &my_optind, &my_optarg)) != EOF) { 470 | switch (c) { 471 | case 'a': 472 | /* Remove any user specified sources from the sources list. */ 473 | while ((first_source = g_list_first(qe->sources_list)) != NULL) { 474 | qe->sources_list = g_list_remove(qe->sources_list, first_source->data); 475 | } 476 | /* Add all the config sources to the sources list. */ 477 | for (i=0; DF_get_source(i) != NULL; i++) { 478 | qe->sources_list = g_list_append(qe->sources_list, (void *)DF_get_database(i)); 479 | } 480 | break; 481 | 482 | case 'e': 483 | query_command->e=1; 484 | break; 485 | 486 | case 'g': 487 | query_command->g=1; 488 | break; 489 | 490 | case 'i': 491 | if (my_optarg != NULL) { 492 | inv_attrs_str = my_optarg; 493 | /* Now a really stupid hard-coded hack to support "pn" being a synonym for "ac,tc,zc,ah" */ 494 | /* I particularly object to this because it references attributes that should only be 495 | defined in XML - but I don't see a simplier more robust way of doing this hack. 496 | :-( - ottrey 8/12/99 */ 497 | if (strcmp(inv_attrs_str, "pn") == 0) { 498 | //inv_attrs_str = (char *)malloc(12); 499 | dieif( wr_malloc((void **)&inv_attrs_str, 12) != UT_OK); 500 | strcpy(inv_attrs_str, "ac,tc,zc,ah"); 501 | } 502 | else if (strcmp(inv_attrs_str, "ro") == 0) { 503 | //inv_attrs_str = (char *)malloc(12); 504 | dieif( wr_malloc((void **)&inv_attrs_str, 12) != UT_OK); 505 | strcpy(inv_attrs_str, "ac,tc,zc,ah"); 506 | } 507 | while (*inv_attrs_str) { 508 | index = getsubopt(&inv_attrs_str, DF_get_attribute_aliases(), &value); 509 | if (index == -1) { 510 | attr = -1; 511 | strcpy(str_buf, ""); 512 | sprintf(str_buf, "Unknown attribute encountered.\n"); 513 | SK_cd_puts(&(qe->condat), str_buf); 514 | errflg++; 515 | } 516 | else { 517 | mask_t inv_attr_mask = MA_new(INV_ATTR_MASK); 518 | attr = DF_get_attribute_index(index); 519 | if ( MA_isset(inv_attr_mask, attr) == 1 ) { 520 | /* Add the attr to the bitmap. */ 521 | MA_set(&(query_command->inv_attrs_bitmap), attr, 1); 522 | } 523 | else { 524 | strcpy(str_buf, ""); 525 | sprintf(str_buf, "\"%s\" does not belong to inv_attr.\n", (DF_get_attribute_aliases())[index]); 526 | SK_cd_puts(&(qe->condat), str_buf); 527 | errflg++; 528 | } 529 | /* 530 | MA_free(&inv_attr_mask); 531 | */ 532 | } 533 | } /* while () */ 534 | } /* if () */ 535 | break; 536 | 537 | case 'k': 538 | /* This is a tricky XOR operation.... ;-) 539 | State transition for k_flag: 540 | 0 -> 0 then k flag = 0, connected = 0 541 | 0 -> 1 then k flag = 1, connected = 1 542 | 1 -> 0 then k flag = 1, connected = 1 543 | 1 -> 1 then k flag = 0, connected = 0 544 | */ 545 | qe->k ^= 1; 546 | break; 547 | 548 | case 'r': 549 | query_command->recursive=0; /* Unset recursion */ 550 | break; 551 | 552 | case 'l': 553 | query_command->l=1; 554 | break; 555 | 556 | case 'm': 557 | query_command->m=1; 558 | break; 559 | 560 | case 'q': 561 | if (my_optarg != NULL) { 562 | index = getsubopt(&my_optarg, DF_get_server_queries(), &value); 563 | if (index == -1) { 564 | errflg++; 565 | } 566 | else { 567 | query_command->q=index; 568 | } 569 | } /* if () */ 570 | break; 571 | 572 | case 's': 573 | if (my_optarg != NULL) { 574 | sources_str = my_optarg; 575 | /* Remove any sources from the sources list. */ 576 | while ((first_source = g_list_first(qe->sources_list)) != NULL) { 577 | qe->sources_list = g_list_remove(qe->sources_list, first_source->data); 578 | } 579 | while (*sources_str) { 580 | index = getsubopt(&sources_str, DF_get_sources(), &value); 581 | if (index == -1) { 582 | strcpy(str_buf, ""); 583 | sprintf(str_buf, "Unknown source encountered.\nNot one of: %s\n", DF_sources_to_string()); 584 | SK_cd_puts(&(qe->condat), str_buf); 585 | 586 | /* Put the default source back in. */ 587 | SK_cd_puts(&(qe->condat), "Reverting to default source - "); 588 | SK_cd_puts(&(qe->condat), CO_get_database()); 589 | SK_cd_puts(&(qe->condat), "\n"); 590 | qe->sources_list = g_list_append(qe->sources_list, (void *)CO_get_database()); 591 | errflg++; 592 | } 593 | else { 594 | qe->sources_list = g_list_append(qe->sources_list, (void *)DF_get_database(index)); 595 | } 596 | } /* while () */ 597 | } /* if () */ 598 | break; 599 | 600 | case 't': 601 | if (my_optarg != NULL) { 602 | object_types_str = my_optarg; 603 | while (*object_types_str) { 604 | index = getsubopt(&object_types_str, DF_get_class_aliases(), &value); 605 | if (index == -1) { 606 | strcpy(str_buf, ""); 607 | sprintf(str_buf, "Unknown object encountered.\n"); 608 | SK_cd_puts(&(qe->condat), str_buf); 609 | errflg++; 610 | } 611 | else { 612 | type = DF_get_class_index(index); 613 | query_command->t=type; 614 | } 615 | } 616 | } 617 | break; 618 | 619 | case 'v': 620 | if (my_optarg != NULL) { 621 | object_types_str = my_optarg; 622 | if (*object_types_str) { 623 | index = getsubopt(&object_types_str, DF_get_class_aliases(), &value); 624 | if (index == -1) { 625 | strcpy(str_buf, ""); 626 | sprintf(str_buf, "Unknown object encountered.\n"); 627 | SK_cd_puts(&(qe->condat), str_buf); 628 | errflg++; 629 | } 630 | else { 631 | type = DF_get_class_index(index); 632 | query_command->v=type; 633 | } 634 | } 635 | } 636 | break; 637 | 638 | case 'x': 639 | query_command->x=1; 640 | break; 641 | 642 | case 'F': 643 | query_command->fast=1; 644 | break; 645 | 646 | case 'K': 647 | query_command->filtered=1; 648 | break; 649 | 650 | case 'L': 651 | query_command->L=1; 652 | break; 653 | 654 | case 'M': 655 | query_command->M=1; 656 | break; 657 | 658 | case 'R': 659 | query_command->R=1; 660 | break; 661 | 662 | case 'S': 663 | query_command->S=1; 664 | break; 665 | 666 | case 'T': 667 | if (my_optarg != NULL) { 668 | object_types_str = my_optarg; 669 | while (*object_types_str) { 670 | index = getsubopt(&object_types_str, DF_get_class_aliases(), &value); 671 | if (index == -1) { 672 | strcpy(str_buf, ""); 673 | sprintf(str_buf, "Unknown class encountered.\n"); 674 | SK_cd_puts(&(qe->condat), str_buf); 675 | errflg++; 676 | } 677 | else { 678 | type = DF_get_class_index(index); 679 | /* Add the type to the bitmap. */ 680 | MA_set(&(query_command->object_type_bitmap), type, 1); 681 | } 682 | } 683 | } 684 | break; 685 | 686 | case 'V': 687 | if (qe->version != NULL) { 688 | /* free up the old client info */ 689 | wr_free(qe->version); 690 | } 691 | 692 | { 693 | char *token, *cursor = my_optarg; 694 | while( (token = strsep( &cursor, "," )) != NULL ) { 695 | if(IP_addr_e2b( & (qe->pIP), token) 696 | != IP_OK ) { 697 | /* means it was not an IP -> it was a version */ 698 | //qe->version = (char *)malloc(strlen(token)+1); 699 | dieif( wr_malloc( (void **)&(qe->version), 700 | strlen(token)+1) != UT_OK); 701 | strcpy(qe->version, token); 702 | } 703 | } 704 | } 705 | break; 706 | 707 | case '?': 708 | errflg++; 709 | break; 710 | 711 | default: 712 | errflg++; 713 | } 714 | } 715 | 716 | /* XXX Report the error. This could be improved. */ 717 | if (opt_argv[my_optind] != NULL) { 718 | if ( (errflg) || (strncmp(opt_argv[my_optind], "-", 1) == 0) ) { 719 | strncpy(str_buf, USAGE, STR_XL-1); 720 | SK_cd_puts(&(qe->condat), str_buf); 721 | } 722 | } 723 | else { 724 | if (errflg) { 725 | strncpy(str_buf, USAGE, STR_XL-1); 726 | SK_cd_puts(&(qe->condat), str_buf); 727 | } 728 | } 729 | 730 | 731 | /* Work out the length of space needed */ 732 | key_length = 0; 733 | for (i=my_optind ; i < opt_argc; i++) { 734 | /* length for the string + 1 for the '\0'+ 1 for the ' ' 735 | [MB removed: + 1 for good luck.] */ 736 | if (opt_argv[i] != NULL) { 737 | key_length += strlen(opt_argv[i])+2; 738 | } 739 | } 740 | 741 | //query_command->keys = (char *)calloc(1, key_length+1); 742 | 743 | dieif( wr_calloc((void **)&(query_command->keys), 1, key_length+1) != UT_OK); 744 | strcpy(query_command->keys, ""); 745 | if (errflg == 0) { 746 | for (i=my_optind; i < opt_argc; i++) { 747 | strcat(query_command->keys, opt_argv[i]); 748 | if ( (i + 1) < opt_argc) { 749 | strcat(query_command->keys, " "); 750 | } 751 | } 752 | } /* XXX - Be careful about where this brace goes. */ 753 | 754 | /* Now convert the key to uppercase. */ 755 | for (i=0; i <= key_length; i++) { 756 | query_command->keys[i] = toupper(query_command->keys[i]); 757 | } 758 | 759 | /* Now make the keytypes_bitmap. */ 760 | query_command->keytypes_bitmap = WK_new(query_command->keys); 761 | 762 | if ( CO_get_comnd_logging() == 1 ) { 763 | log_command(tmp_query_str, query_command); 764 | } 765 | 766 | /* Now we don't need this anymore */ 767 | wr_free(tmp_query_str); 768 | 769 | } /* QC_fill() */ 770 | 771 | /* QC_environ_new() */ 772 | /*++++++++++++++++++++++++++++++++++++++ 773 | Create a new query environment. 774 | 775 | More: 776 | +html+ <PRE> 777 | Authors: 778 | ottrey 779 | +html+ </PRE><DL COMPACT> 780 | +html+ <DT>Online References: 781 | +html+ <DD><UL> 782 | +html+ </UL></DL> 783 | 784 | ++++++++++++++++++++++++++++++++++++++*/ 785 | Query_environ *QC_environ_new(char *ip, unsigned sock) { 786 | Query_environ *qe; 787 | 788 | //qe = (Query_environ *)calloc(1, sizeof(Query_environ)+1); 789 | dieif( wr_calloc((void **)&qe, 1, sizeof(Query_environ)+1 ) != UT_OK); 790 | qe->condat.ip = ip; 791 | qe->condat.sock = sock; 792 | 793 | /* The source is initialized to be the one defined in the config by default. */ 794 | qe->sources_list = g_list_append(qe->sources_list, (void *)CO_get_database()); 795 | 796 | return qe; 797 | 798 | } /* QC_environ_new() */ 799 | 800 | Query_command *QC_create(char *input, Query_environ *qe) 801 | { 802 | Query_command *qc; 803 | 804 | // query_command = (Query_command *)calloc(1, sizeof(Query_command)+1); 805 | dieif( wr_calloc((void **)&qc, 1, sizeof(Query_command)+1) != UT_OK); 806 | 807 | if ( strlen(input) == 0) { 808 | /* An empty query (Ie return) was sent */ 809 | qc->query_type = PW_EMPTY; 810 | } 811 | else { /* else <==> input_length > 0 ) */ 812 | /* parse query */ 813 | 814 | QC_fill(input, qc, qe); 815 | 816 | /* Update the query environment */ 817 | // qe = QC_environ_update(qc, qe); 818 | 819 | /* Only do a query if there are keys. */ 820 | if (qc->keys == NULL || strlen(qc->keys) == 0 ) { 821 | qc->query_type = PW_NOKEY; 822 | } 823 | else { 824 | if( strlen(qc->keys) == 0 ) { 825 | qc->query_type = PW_TEMPLATE; 826 | } 827 | else if ( strcmp(qc->keys, "help") == 0 ) { 828 | qc->query_type = PW_HELP; 829 | } 830 | else { 831 | /* Some real query */ 832 | qc->query_type = PW_REAL; 833 | } 834 | } 835 | } 836 | return qc; 837 | }