00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define _GNU_SOURCE
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 #include <string.h>
00026 #include <fcntl.h>
00027 #include <sys/time.h>
00028 #include <poll.h>
00029 #include <ctype.h>
00030 #include <sys/socket.h>
00031 #include <netinet/in.h>
00032 #include <arpa/inet.h>
00033 #include <netdb.h>
00034 #include <errno.h>
00035 #include <limits.h>
00036 #include "dt.h"
00037 #include "dtm.h"
00038 #include "carrier.h"
00039 #include "log.h"
00040
00041
00042
00043
00044 #define NETBUFSIZE 200
00045
00046
00047
00048
00049 typedef void (*query_func_t)(char *number, char *comment, void *data);
00050
00051
00052
00053
00054 void print_usage(char *program) {
00055 set_log_level(LOG_INFO);
00056 LINFO("Usage: %s [<option>...] <command> [<param>...]\n", program);
00057 LINFO(" %s -s <csv file> -m <mmap file> [-k <ids>] [-o] [-u <tree file>] [-l <log level>] build\n", program);
00058 LINFO(" %s (-m <mmap file>|-r <host>:<port>) [-q <timeout>] [-f <query file>] [-t <carrier text file>] [-l <log level>] query <number>...\n", program);
00059 LINFO("\n");
00060 LINFO(" Commands:\n");
00061 LINFO(" build: Build a mmap image from a csv list.\n");
00062 LINFO(" query: Query a mmap image or pdb_server.\n");
00063 LINFO(" Uses Numbers given on commandline or in a file (-f).\n");
00064 LINFO("\n");
00065 LINFO(" Options:\n");
00066 LINFO(" -s <file>: Specifies the csv list.\n");
00067 LINFO(" Use '-' as filename to read from stdin.\n");
00068 LINFO(" Line format: <number prefix>;<carrier id>\n");
00069 LINFO(" Format of carrier id: [0-9][0-9][0-9]\n");
00070 LINFO(" -m <file>: Specifies the mmap image.\n");
00071 LINFO(" -f <file>: Specifies the query file.\n");
00072 LINFO(" Use '-' as filename to read from stdin.\n");
00073 LINFO(" Each number must be in a separate line.\n");
00074 LINFO(" Numbers on the command line will not be processed.\n");
00075 LINFO(" -t <file>: Specifies the file containing carrier names.\n");
00076 LINFO(" In addition to the carrier code these names will be shown\n");
00077 LINFO(" when querying numbers.\n");
00078 LINFO(" Each carrier id and name must be in a separate line.\n");
00079 LINFO(" Format: D[0-9][0-9][0-9] <name>\n");
00080 LINFO(" -k <ids>: Keep these carrier ids.\n");
00081 LINFO(" Merge all other carrier ids into a new id.\n");
00082 LINFO(" This will save some memory.\n");
00083 LINFO(" Format: <id>[,<id>...]\n");
00084 LINFO(" -r <host>:<port>: Host and port to be used for remote server queries.\n");
00085 LINFO(" -q <timeout>: Timeout for remote server queries in milliseconds.\n");
00086 LINFO(" Default is 500 ms.\n");
00087 LINFO(" -o: Try to optimize the data structure when building a mmap image.\n");
00088 LINFO(" -u: Write (possibly optimized) tree structure in human-readable format to the given file.\n");
00089 LINFO(" -l <debug level>: %ld for debug level.\n", LOG_DEBUG);
00090 LINFO(" %ld for info level.\n", LOG_INFO);
00091 LINFO(" %ld for notice level.\n", LOG_NOTICE);
00092 LINFO(" %ld for warning level.\n", LOG_WARNING);
00093 LINFO(" %ld for error level.\n", LOG_ERR);
00094 LINFO(" %ld for critical level.\n", LOG_CRIT);
00095 LINFO(" %ld for alert level.\n", LOG_ALERT);
00096 LINFO(" %ld for emergency level.\n", LOG_EMERG);
00097 LINFO(" %ld to disable all messages.\n", LOG_EMERG-1);
00098 LINFO(" Default is info level.\n");
00099 LINFO(" -h: Print this help.\n");
00100 }
00101
00102
00103
00104
00105 void print_stats(struct dt_node_t *root) {
00106 int s;
00107 int l;
00108 int c;
00109
00110 LINFO("+----------------------------------------\n");
00111 s = dt_size(root);
00112 LINFO("| %ld nodes in tree (%ld bytes, %ld KB, %ld MB)\n", (long int)s, (long int)s*sizeof(struct dt_node_t), (long int)s*sizeof(struct dt_node_t)/1024, (long int)s*sizeof(struct dt_node_t)/1024/1024);
00113 l = dt_leaves(root);
00114 LINFO("| %ld nodes are leaves (%ld bytes, %ld KB, %ld MB)\n", (long int)l, (long int)l*sizeof(struct dt_node_t), (long int)l*sizeof(struct dt_node_t)/1024, (long int)l*sizeof(struct dt_node_t)/1024/1024);
00115 c = dt_loaded_nodes(root);
00116 LINFO("| %ld carrier nodes in tree\n", (long int)c);
00117 LINFO("| \n");
00118 LINFO("| After saving with leaf node compression:\n");
00119 LINFO("| %ld nodes in tree (%ld bytes, %ld KB, %ld MB)\n", (long int)s-l, (long int)(s-l)*sizeof(struct dtm_node_t), (long int)(s-l)*sizeof(struct dtm_node_t)/1024, (long int)(s-l)*sizeof(struct dtm_node_t)/1024/1024);
00120 LINFO("+----------------------------------------\n");
00121 }
00122
00123
00124
00125
00126 int file_query(char *filename, query_func_t query_func, void *data) {
00127 char * p;
00128 char * comment;
00129 FILE * fp;
00130 char * line = NULL;
00131 size_t len = 0;
00132 ssize_t read;
00133
00134 LINFO("\nprocessing query file '%s'...\n", filename);
00135 if (strcmp(filename, "-")==0) fp=stdin;
00136 else fp = fopen(filename, "r");
00137 if (fp == NULL) {
00138 LERR("cannot open file '%s'\n", filename);
00139 return -1;
00140 }
00141 while ((read = getline(&line, &len, fp)) != -1) {
00142 p=line;
00143 while ((*p >= '0') && (*p <= '9') && (p < line+len)) p++;
00144 *p='\0';
00145 p++;
00146 comment=p;
00147 while ((*p >= 32) && (p < line+len)) p++;
00148 *p='\0';
00149 query_func(line, comment, data);
00150 }
00151 if (line) free(line);
00152 fclose(fp);
00153 return 0;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 int import_csv(struct dt_node_t *root, char *filename) {
00166 char *prefix;
00167 char *carrier_str;
00168 carrier_t carrier;
00169 long int ret;
00170
00171 FILE * fp;
00172 char * line = NULL;
00173 size_t len = 0;
00174 ssize_t read;
00175 int i=0;
00176 int n=1;
00177
00178 if (strcmp(filename, "-")==0) fp=stdin;
00179 else fp = fopen(filename, "r");
00180 if (fp == NULL) {
00181 LERR("cannot open file '%s'\n", filename);
00182 return -1;
00183 }
00184 while ((read = getline(&line, &len, fp)) != -1) {
00185 carrier_str=line;
00186 prefix=strsep(&carrier_str, ";");
00187 ret=strtol(carrier_str, NULL, 10);
00188 if (!IS_VALID_PDB_CARRIERID(ret)) {
00189 LWARNING("invalid carrier '%s' in line %ld.\n", carrier_str, (long int)n);
00190 if (line) free(line);
00191 fclose(fp);
00192 return -1;
00193 }
00194 else {
00195 carrier=ret;
00196 i++;
00197 dt_insert(root, prefix, strlen(prefix), carrier);
00198 }
00199 n++;
00200 }
00201 if (line) free(line);
00202 fclose(fp);
00203 return i;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212 inline int dt_is_leaf(struct dt_node_t *root)
00213 {
00214 int i;
00215
00216 for (i=0; i<10; i++) {
00217 if (root->child[i]) return 0;
00218 }
00219
00220 return 1;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 int dt_write_tree_recursor(const struct dt_node_t *node, const int fd, char* number)
00232 {
00233 int i;
00234 int ret;
00235 int slen;
00236 char *buf;
00237 char *p;
00238 int bufsize;
00239
00240 if (node == NULL) return 0;
00241
00242 slen = strlen(number);
00243 if (slen > 0) {
00244
00245 bufsize = slen + 1 + 1 + 3 + 1 + 1;
00246 buf = (char *)malloc(bufsize);
00247 if (buf == NULL) {
00248 LERR("could not allocate line output buffer of size %d\n", bufsize);
00249 return -1;
00250 }
00251
00252
00253 p = strncpy(buf, number, slen);
00254 p += slen;
00255 strncpy(p, ": ", 2);
00256 p += 2;
00257 ret = snprintf(p, 5, "%d\n", node->carrier);
00258 if (ret < 1 || ret > 4) {
00259 LERR("snprintf failed to write correct number of characters\n");
00260 return -1;
00261 }
00262
00263
00264 ret = write(fd, (void *)buf, strlen(buf));
00265 if (ret != strlen(buf)) {
00266 LERR("could not write (complete) line output '%s' to file\n", number);
00267 return -1;
00268 }
00269 free(buf);
00270 }
00271
00272 for (i=0;i<10;i++) {
00273
00274 number[slen] = i + '0';
00275 number[slen+1] = '\0';
00276 ret = dt_write_tree_recursor(node->child[i], fd, number);
00277 if (ret < 0) {
00278 LERR("could not write node\n");
00279 return -1;
00280 }
00281 }
00282
00283 return 1;
00284 }
00285
00286
00287
00288
00289
00290
00291
00292 int dt_write_tree(const struct dt_node_t *root, const char* filename)
00293 {
00294 int fd;
00295 char number[25];
00296 number[0] = '\0';
00297
00298 fd = creat(filename, S_IRWXU);
00299 if (fd < 0) {
00300 LERR("cannot create file '%s'\n", filename);
00301 return -1;
00302 }
00303
00304 if (dt_write_tree_recursor(root, fd, (char *)&number) < 0) {
00305 LERR("writing tree to file '%s' failed\n", filename);
00306 return -1;
00307 }
00308
00309 close(fd);
00310 return 1;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 dtm_node_index_t save_recursor(struct dt_node_t *root, int fd, dtm_node_index_t n) {
00326 dtm_node_index_t i;
00327 dtm_node_index_t nn=n+1;
00328 struct dtm_node_t node;
00329 int offset;
00330
00331 node.carrier=root->carrier;
00332 for (i=0; i<10; i++) {
00333 if (root->child[i]) {
00334 if (dt_is_leaf(root->child[i])) {
00335 node.child[i]=-root->child[i]->carrier;
00336 }
00337 else {
00338 node.child[i]=nn;
00339 nn=save_recursor(root->child[i], fd, nn);
00340 }
00341 }
00342 else {
00343 node.child[i]=NULL_CARRIERID;
00344 }
00345 }
00346
00347 offset=lseek(fd, n*sizeof(struct dtm_node_t), SEEK_SET);
00348 if (offset < 0) {
00349 LERR("could not position file offset to address %d: errno=%d (%s)\n", n*sizeof(struct dtm_node_t), errno, strerror(errno));
00350 return -1;
00351 }
00352 if (write(fd, &node, sizeof(struct dtm_node_t)) != sizeof(struct dtm_node_t)) {
00353 LERR("could not write %d bytes of node data at file address %d: errno=%d (%s)\n", sizeof(struct dtm_node_t), offset, errno, strerror(errno));
00354 return -1;
00355 }
00356
00357 return nn;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367 int save_mmap(struct dt_node_t *root, char *filename) {
00368 int fd;
00369 int n;
00370
00371 fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU);
00372 if (fd < 0) {
00373 LERR("cannot create file '%s'\n", filename);
00374 return -1;
00375 }
00376
00377 n=save_recursor(root, fd, 0);
00378
00379 close(fd);
00380
00381 return n;
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 int keep_carrier_func(carrier_t carrier, int keep_carriers_num, carrier_t keep_carriers[])
00391 {
00392 int i;
00393
00394 for (i=0; i<keep_carriers_num; i++) {
00395 if (keep_carriers[i]==carrier) return 1;
00396 }
00397
00398 return 0;
00399 }
00400
00401
00402
00403
00404 int merge_carrier_recursor(struct dt_node_t *node, int keep_carriers_num, carrier_t keep_carriers[], carrier_t lastcarrier)
00405 {
00406 carrier_t currentcarrier;
00407 int i;
00408 int sum=0;
00409
00410 if (node==NULL) return 0;
00411
00412 if (node->carrier>0) {
00413 if (!keep_carrier_func(node->carrier, keep_carriers_num, keep_carriers)) {
00414 sum++;
00415 if (lastcarrier==0) node->carrier=0;
00416 else {
00417 node->carrier=OTHER_CARRIERID;
00418 }
00419 }
00420 }
00421
00422 if (node->carrier>0) currentcarrier=node->carrier;
00423 else currentcarrier=lastcarrier;
00424
00425
00426 for (i=0; i<10; i++) {
00427 sum+=merge_carrier_recursor(node->child[i], keep_carriers_num, keep_carriers, currentcarrier);
00428 }
00429
00430 return sum;
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 int merge_carrier(struct dt_node_t *root, int keep_carriers_num, carrier_t keep_carriers[])
00442 {
00443 return merge_carrier_recursor(root, keep_carriers_num, keep_carriers, 0);
00444 }
00445
00446
00447
00448
00452 int query_udp(char *number, int timeout, struct pollfd *pfds, struct sockaddr_in *dstaddr, socklen_t dstaddrlen)
00453 {
00454 struct timeval tstart, tnow;
00455 short int carrierid;
00456 char buf[NETBUFSIZE+1+sizeof(carrierid)];
00457 size_t reqlen;
00458 int ret, nflush;
00459 long int td;
00460
00461 if (gettimeofday(&tstart, NULL) != 0) {
00462 LERR("gettimeofday() failed with errno=%d (%s)\n", errno, strerror(errno));
00463 return -1;
00464 }
00465
00466
00467 nflush = 0;
00468 while (recv(pfds->fd, buf, NETBUFSIZE, MSG_DONTWAIT) > 0) {
00469 nflush++;
00470 if (gettimeofday(&tnow, NULL) != 0) {
00471 LERR("gettimeofday() failed with errno=%d (%s)\n", errno, strerror(errno));
00472 return -1;
00473 }
00474 td=(tnow.tv_usec-tstart.tv_usec+(tnow.tv_sec-tstart.tv_sec)*1000000) / 1000;
00475 if (td > timeout) {
00476 LWARNING("exceeded timeout while flushing recv buffer.\n");
00477 return -1;
00478 }
00479 }
00480
00481
00482 reqlen = strlen(number) + 1;
00483 if (reqlen > NETBUFSIZE) {
00484 LERR("number too long '%s'.\n", number);
00485 return -1;
00486 }
00487 strcpy(buf, number);
00488
00489
00490 ret=sendto(pfds->fd, buf, reqlen, MSG_DONTWAIT, (struct sockaddr *)dstaddr, dstaddrlen);
00491 if (ret < 0) {
00492 LERR("sendto() failed with errno=%d (%s)\n", errno, strerror(errno));
00493 return -1;
00494 }
00495
00496
00497 for (;;) {
00498 if (gettimeofday(&tnow, NULL) != 0) {
00499 LERR("gettimeofday() failed with errno=%d (%s)\n", errno, strerror(errno));
00500 return -1;
00501 }
00502 td=(tnow.tv_usec-tstart.tv_usec+(tnow.tv_sec-tstart.tv_sec)*1000000) / 1000;
00503 if (td > timeout) {
00504 LWARNING("exceeded timeout while waiting for response.\n");
00505 return -1;
00506 }
00507
00508 ret=poll(pfds, 1, timeout-td);
00509 if (pfds->revents & POLLIN) {
00510 if (recv(pfds->fd, buf, NETBUFSIZE, MSG_DONTWAIT) > 0) {
00511 buf[NETBUFSIZE] = '\0';
00512 if (strcmp(buf, number) == 0) {
00513 carrierid=ntohs(*((short int *)&(buf[reqlen])));
00514 goto found;
00515 }
00516 }
00517 }
00518 pfds->revents = 0;
00519 }
00520
00521 found:
00522 if (gettimeofday(&tnow, NULL) == 0) {
00523 LINFO("got an answer in %f ms\n", ((double)(tnow.tv_usec-tstart.tv_usec+(tnow.tv_sec-tstart.tv_sec)*1000000))/1000);
00524 }
00525 return carrierid;
00526 }
00527
00528
00529
00530
00531 struct server_query_data_t {
00532 int timeout;
00533 struct sockaddr_in dstaddr;
00534 socklen_t dstaddrlen;
00535 struct pollfd pfds;
00536 };
00537
00538
00539
00540
00541 void query_mmap(char *number, char *comment, void *data) {
00542 int nmatch;
00543 carrier_t carrierid;
00544 struct dtm_node_t *mroot = (struct dtm_node_t *)data;
00545
00546 nmatch=dtm_longest_match(mroot, number, strlen(number), &carrierid);
00547
00548 if (nmatch<=0) {
00549 LINFO("%s:%s:%ld:%s\n", number, comment, (long int)carrierid, "not allocated, probably old");
00550 }
00551 else {
00552 LINFO("%s:%s:%ld:%s\n", number, comment, (long int)carrierid, carrierid2name(carrierid));
00553
00554
00555 }
00556 }
00557
00558
00559
00560
00561 void query_server(char *number, char *comment, void *data) {
00562 carrier_t carrierid;
00563 struct server_query_data_t *sdata = (struct server_query_data_t *)data;
00564
00565 carrierid = query_udp(number, sdata->timeout, &(sdata->pfds), &(sdata->dstaddr), sdata->dstaddrlen);
00566
00567 if (carrierid<=0) {
00568 LINFO("%s: not_found: comment='%s'\n", number, comment);
00569 }
00570 else {
00571 LINFO("%s:%ld:%s\n", number, (long int)carrierid, carrierid2name(carrierid));
00572
00573
00574 }
00575 }
00576
00577
00578
00579
00580 int main(int argc, char *argv[]) {
00581 int n;
00582 struct dt_node_t root;
00583 memset(&root, 0, sizeof(root));
00584 struct dtm_node_t *mroot;
00585
00586 int opt;
00587 char *csv_file = NULL;
00588 char *mmap_file = NULL;
00589 char *query_file = NULL;
00590 char *tree_file = NULL;
00591 int optimize = 0;
00592 int keep_carriers_num = 0;
00593 carrier_t keep_carriers[MAX_PDB_CARRIERID+1];
00594 char *host_str = NULL;
00595 char *port_str = NULL;
00596 unsigned short int port = 0;
00597 char *tmp;
00598 int log_level = LOG_INFO;
00599
00600 struct hostent *hp;
00601 int sockfd;
00602
00603 struct server_query_data_t sdata;
00604
00605 char *id_str;
00606 long int ret;
00607
00608 sdata.timeout=500;
00609
00610 init_carrier_names();
00611
00612 init_log("pdbt", 0);
00613
00614 while ((opt = getopt(argc, argv, "s:m:f:u:t:r:q:k:ol:h")) != -1) {
00615 switch (opt) {
00616 case 's':
00617 csv_file = optarg;
00618 break;
00619 case 'm':
00620 mmap_file = optarg;
00621 break;
00622 case 'f':
00623 query_file = optarg;
00624 break;
00625 case 'u':
00626 tree_file = optarg;
00627 break;
00628 case 'k':
00629 while ((id_str=strsep(&optarg, ","))) {
00630 ret=strtol(id_str, NULL, 10);
00631 if (!IS_VALID_PDB_CARRIERID(ret)) {
00632 LERR("invalid carrier id '%s' specified.\n", id_str);
00633 return -1;
00634 }
00635 if (keep_carriers_num>MAX_PDB_CARRIERID) {
00636 LERR("too many carrier ids specified.\n");
00637 return -1;
00638 }
00639 keep_carriers[keep_carriers_num]=ret;
00640 keep_carriers_num++;
00641 }
00642 break;
00643 case 't':
00644 if (load_carrier_names(optarg)<0) {
00645 LERR("cannot load carrier names from '%s'.\n", optarg);
00646 return -1;
00647 }
00648 break;
00649 case 'r':
00650 host_str=optarg;
00651
00652 tmp = strchr(host_str, ':');
00653 if (tmp == NULL) {
00654 LERR("syntax error in remote host:port specification '%s'.\n", host_str);
00655 return -1;
00656 }
00657 *tmp = '\0';
00658 port_str = tmp + 1;
00659
00660 ret=strtol(port_str, NULL, 10);
00661 if ((ret<0) || (ret==LONG_MAX)) {
00662 LERR("invalid timeout '%s'\n", optarg);
00663 return -1;
00664 }
00665 port = ret;
00666
00667 break;
00668 case 'q':
00669 ret=strtol(optarg, NULL, 10);
00670 if ((ret<0) || (ret>65535)) {
00671 LERR("invalid port '%s'\n", port_str);
00672 return -1;
00673 }
00674 sdata.timeout = ret;
00675
00676 break;
00677 case 'o':
00678 optimize=1;
00679 break;
00680 case 'l':
00681 ret=strtol(optarg, NULL, 10);
00682 if ((ret<LOG_EMERG-1) || (ret>LOG_DEBUG)) {
00683 LERR("invalid log level '%s' specified.\n", optarg);
00684 return -1;
00685 }
00686 log_level=ret;
00687 break;
00688 case 'h':
00689 print_usage(argv[0]);
00690 return 0;
00691 break;
00692 default:
00693 LERR("invalid option '%c'.\n", opt);
00694 print_usage(argv[0]);
00695 return 1;
00696 }
00697 }
00698
00699 set_log_level(log_level);
00700
00701 if (optind>=argc) {
00702 LERR("no command specified.\n");
00703 return 1;
00704 }
00705
00706 if (strcmp(argv[optind], "build")==0) {
00707 if (csv_file==NULL) {
00708 LERR("no csv file specified.\n");
00709 return 1;
00710 }
00711
00712 if (mmap_file==NULL) {
00713 LERR("no mmap file specified.\n");
00714 return 1;
00715 }
00716
00717 LINFO("loading '%s'...\n", csv_file);
00718 n = import_csv(&root, csv_file);
00719 if (n < 0) {
00720 LERR("cannot import '%s'\n", csv_file);
00721 return -1;
00722 }
00723 LINFO("done.\n");
00724 LINFO("%ld lines imported\n", (long int)n);
00725
00726 LINFO("Node size is %ld bytes (%ld for dtm)\n", (long int)sizeof(struct dt_node_t), (long int)sizeof(struct dtm_node_t));
00727 print_stats(&root);
00728
00729 if (keep_carriers_num) {
00730 LINFO("merging carriers...\n");
00731 n=merge_carrier(&root, keep_carriers_num, keep_carriers);
00732 LINFO("done (modified %ld nodes).\n", (long int)n);
00733 }
00734
00735 if (optimize) {
00736 LINFO("optimizing...\n");
00737 dt_optimize(&root);
00738 LINFO("done.\n");
00739 print_stats(&root);
00740 }
00741
00742 if (tree_file != NULL) {
00743 LINFO("writing human-readable tree...\n");
00744 if (dt_write_tree(&root, tree_file) < 0) {
00745 LERR("cannot write tree\n");
00746 return -1;
00747 }
00748 LINFO("done.\n");
00749 }
00750
00751 LINFO("saving to '%s'...\n", mmap_file);
00752 n = save_mmap(&root, mmap_file);
00753 if (n < 0) {
00754 LERR("cannot save '%s'\n", mmap_file);
00755 return -1;
00756 }
00757 LINFO("done.\n");
00758 LINFO("%ld nodes saved\n", (long int)n);
00759 }
00760 else if (strcmp(argv[optind], "query")==0) {
00761 if ((mmap_file!=NULL) && (host_str!=NULL)) {
00762 LERR("you cannot query a pdb_server and a mmap file at the same time.\n");
00763 return 1;
00764 }
00765
00766 if ((mmap_file==NULL) && (host_str==NULL)) {
00767 LERR("neither a mmap file nor a remote host specified.\n");
00768 return 1;
00769 }
00770
00771 if (mmap_file==NULL) {
00772 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
00773 if (sockfd<0) {
00774 LERR("socket() failed with errno=%d (%s).\n", errno, strerror(errno));
00775 return -1;
00776 }
00777
00778 memset(&sdata.dstaddr, 0, sizeof(sdata.dstaddr));
00779 sdata.dstaddr.sin_family = AF_INET;
00780 sdata.dstaddr.sin_port = htons(port);
00781 hp = gethostbyname(host_str);
00782 if (hp == NULL) {
00783 LERR("gethostbyname(%s) failed with h_errno=%d.\n", host_str, h_errno);
00784 close(sockfd);
00785 return -1;
00786 }
00787 memcpy(&sdata.dstaddr.sin_addr.s_addr, hp->h_addr, hp->h_length);
00788 sdata.dstaddrlen=sizeof(sdata.dstaddr);
00789
00790 sdata.pfds.fd=sockfd;
00791 sdata.pfds.events=POLLIN;
00792
00793 if (query_file==NULL) {
00794 LINFO("\nprocessing command line parameters...\n");
00795 for (n=optind+1; n<argc; n++) {
00796 query_server(argv[n], "", &sdata);
00797 }
00798 }
00799 else {
00800 file_query(query_file, query_server, &sdata);
00801 }
00802 }
00803 else {
00804 mroot=dtm_load(mmap_file);
00805 if (mroot == NULL) {
00806 LERR("cannot load '%s'.\n", mmap_file);
00807 return -1;
00808 }
00809
00810 if (query_file==NULL) {
00811 LINFO("\nprocessing command line parameters...\n");
00812 for (n=optind+1; n<argc; n++) {
00813 query_mmap(argv[n], "", mroot);
00814 }
00815 }
00816 else {
00817 file_query(query_file, query_mmap, mroot);
00818 }
00819 }
00820 }
00821 else {
00822 LERR("invalid command '%s'.\n", argv[optind]);
00823 return 1;
00824 }
00825
00826 return 0;
00827 }