/* ************************************************************* RWhois Software Copyright (c) 1996-2000 Network Solutions, Inc. See the file LICENSE for conditions of use and distribution. **************************************************************** */ #include "rwhois.h" #include "conf.h" #include "strutils.h" #include "whoisquery.h" #define MAX_QUERY_LEN 1024 typedef struct { rw_query_args_struct query_args; rw_recurse_mode_enum recurse_mode; rw_recurse_mode_enum whois_recurse_mode; char *host; int port; int debug_level; } rwhois_cl_opts_struct; void display_query_records(dl_list_type *record_list) { int not_done_records; int not_done_pairs; rw_record_struct *cur_rec; rw_avpair_struct *cur_av; if (!record_list || dl_list_empty(record_list)) { return; } not_done_records = dl_list_first(record_list); /* display the actual records */ while (not_done_records) { cur_rec = (rw_record_struct *) dl_list_value(record_list); /* skip broken records and referrals (they should be in the set) */ if (!cur_rec || cur_rec->referral != NULL) { not_done_records = dl_list_next(record_list); continue; } if (cur_rec->text) { fputs(cur_rec->text, stdout); fputs("\n", stdout); } /* display the rwhois record */ not_done_pairs = dl_list_first(cur_rec->av_pair_list); while (not_done_pairs) { cur_av = (rw_avpair_struct *) dl_list_value(cur_rec->av_pair_list); printf("%-30s%s\n", cur_av->attribute, cur_av->value); not_done_pairs = dl_list_next(cur_rec->av_pair_list); } not_done_records = dl_list_next(record_list); if (not_done_records) { fputs("\n", stdout); } } } void display_query_referrals(rw_referral_group_struct *referral_group) { int not_done; rw_referral_struct *cur_ref; dl_list_type *ref_list; if (!referral_group) return; ref_list = referral_group->referrals; if (!ref_list) return; not_done = dl_list_first(ref_list); while (not_done) { cur_ref = (rw_referral_struct *) dl_list_value(ref_list); if (!cur_ref) { not_done = dl_list_next(ref_list); continue; } if (STR_EXISTS(cur_ref->url)) { printf("referral: %s\n", cur_ref->url); } else { printf("referral: %s://%s:%d\n", SAFE_STR(cur_ref->scheme, ""), SAFE_STR(cur_ref->host, ""), cur_ref->port); } not_done = dl_list_next(ref_list); } } void display_all_query_referrals(dl_list_type *referral_group_list) { int not_done; rw_referral_group_struct *group; if (!referral_group_list) return; not_done = dl_list_first(referral_group_list); while (not_done) { group = (rw_referral_group_struct *) dl_list_value(referral_group_list); display_query_referrals(group); not_done = dl_list_next(referral_group_list); } } void display_query_results(dl_list_type *record_list, dl_list_type *referral_group_list) { if (record_list) { display_query_records(record_list); } if (referral_group_list) { if (record_list) { fputs("\n", stdout); } display_all_query_referrals(referral_group_list); } } void display_whois_result(rw_whois_result_struct *whoisres) { if (whoisres->disclaimer) { fputs(whoisres->disclaimer, stdout); } if (whoisres->text) { fputs(whoisres->text, stdout); } } void follow_whois_referrals(dl_list_type *ref_group_list, char *query, int debug_level, rw_response_struct *response) { rw_referral_group_struct *cur_group; rw_referral_struct *cur_ref; rw_whois_result_struct *whois_result; int not_done_groups; int not_done_refs; assert(response); if (!ref_group_list || dl_list_empty(ref_group_list)) { return; } not_done_groups = dl_list_first(ref_group_list); while (not_done_groups) { cur_group = (rw_referral_group_struct *) dl_list_value(ref_group_list); if (!cur_group || !cur_group->referrals || dl_list_empty(cur_group->referrals)) { not_done_groups = dl_list_next(ref_group_list); continue; } not_done_refs = dl_list_first(cur_group->referrals); while (not_done_refs) { cur_ref = (rw_referral_struct *) dl_list_value(cur_group->referrals); if (!cur_ref || NOT_STR_EXISTS(cur_ref->scheme) || !STR_EQ(cur_ref->scheme, "whois")) { not_done_refs = dl_list_next(cur_group->referrals); continue; } whois_result = rwhois_query_whois_referral(cur_ref, query, debug_level, response); if (whois_result) { display_whois_result(whois_result); destroy_rw_whois_result_struct(whois_result); whois_result = NULL; } /* delete this referral, as we have followed it, and deal with the advance logic */ if (dl_list_at_tail(cur_group->referrals)) { not_done_refs = FALSE; } else { not_done_refs = TRUE; } dl_list_delete(cur_group->referrals); } not_done_groups = dl_list_next(ref_group_list); } } void usage(char *prog_name) { fprintf(stderr, "usage: %s [-l limit] [-s host] [-p port] [-rRv] query\n", prog_name); fprintf(stderr, " -l limit: set the result limit on the rwhois server.\n"); fprintf(stderr, " -s host: query the rwhois server at this host [default: %s]\n", DEFAULT_RWHOIS_SERVER); fprintf(stderr, " -p port: query the rwhois server at this port [default: %d]\n", DEFAULT_RWHOIS_PORT); fprintf(stderr, " -r: follow referrals [default]\n"); fprintf(stderr, " -R: do not follow referrals\n"); fprintf(stderr, " -v: verbose\n"); fprintf(stderr, " -h: help; this text\n"); exit(64); } rwhois_cl_opts_struct * parse_command_line(int argc, char *argv[]) { char c; int i; rwhois_cl_opts_struct *opts = NULL; opts = (rwhois_cl_opts_struct *) CALLOC(1, sizeof(*opts)); /* set defaults */ opts->host = DEFAULT_RWHOIS_SERVER; opts->port = DEFAULT_RWHOIS_PORT; opts->recurse_mode = RW_RECURSE; opts->whois_recurse_mode = RW_RECURSE; /* parse the command line */ while ((c = getopt(argc, argv, "hl:s:p:rRWv")) > 0) { switch (c) { case 'h': usage(argv[0]); break; case 'l': opts->query_args.limit = atoi(optarg); opts->query_args.limit_changed_flag = TRUE; break; case 's': opts->host = optarg; break; case 'p': opts->port = atoi(optarg); break; case 'r': opts->recurse_mode = RW_RECURSE; break; case 'R': opts->recurse_mode = RW_NO_RECURSE; break; case 'W': opts->whois_recurse_mode = RW_NO_RECURSE; break; case 'v': opts->debug_level++; break; default: usage(argv[0]); break; } } if (optind >= argc) { usage(argv[0]); } /* join the rest of the arguments together into a query */ opts->query_args.query = (char *) CALLOC(MAX_QUERY_LEN, sizeof(char)); for (i = optind; i < argc; i++) { strcat(opts->query_args.query, argv[i]); strcat(opts->query_args.query, " "); } trim(opts->query_args.query); return opts; } int main(int argc, char *argv[]) { rwhois_cl_opts_struct *opts; dl_list_type *record_list = NULL; dl_list_type *referral_group_list = NULL; rw_response_struct response; rw_server_struct server; opts = parse_command_line(argc, argv); if (!opts) abort(); referral_group_list = dl_list_create(destroy_rw_referral_group_struct); server.host = opts->host; server.port = opts->port; server.debug_level = opts->debug_level; record_list = recursive_query_rwhois(&(opts->query_args), &server, SPEC_VERSION, IMP_VERSION, opts->recurse_mode, referral_group_list, NULL, &response); if ( (!record_list || dl_list_empty(record_list)) && (!referral_group_list || dl_list_empty(referral_group_list)) ) { if (response.status >= RW_OK) { printf("No results found for '%s'.\n", opts->query_args.query); } } else { printf("Results:\n\n"); } display_query_results(record_list, NULL); if (opts->whois_recurse_mode == RW_RECURSE) { follow_whois_referrals(referral_group_list, opts->query_args.query, opts->debug_level, &response); } display_query_results(NULL, referral_group_list); if (response.status < RW_OK) { printf("error querying rwhois server: %s\n", response.msg); exit(1); } /* free the results */ dl_list_destroy(record_list); dl_list_destroy(referral_group_list); /* free the command line args */ if (opts->query_args.query) FREE(opts->query_args.query); FREE(opts); exit(0); }