📄 host.c
字号:
#ifdef DEBUG#define assert(condition)\{\ if (!(condition))\ {\ (void) fprintf(stderr, "assertion botch: ");\ (void) fprintf(stderr, "%s(%d): ", __FILE__, __LINE__);\ (void) fprintf(stderr, "%s\n", "condition");\ exit(EX_SOFTWARE);\ }\}#else#define assert(condition)#endif/*** MAIN -- Start of program host** -----------------------------**** Exits:** EX_OK Operation successfully completed** EX_UNAVAILABLE Could not obtain requested information** EX_CANTCREAT Could not create specified logfile** EX_NOINPUT No input arguments were found** EX_NOHOST Could not lookup explicit server** EX_OSERR Could not obtain resources** EX_USAGE Improper parameter/option specified** EX_SOFTWARE Assertion botch in DEBUG mode*/intmain(argc, argv)input int argc;input char *argv[];{ register char *option; res_state_t new_res; /* new resolver database */ int result; /* result status of action taken */ char *program; /* name that host was called with */ char *servername = NULL; /* name of explicit server */ bool extended = FALSE; /* accept extended argument syntax */ assert(sizeof(u_int) == 4); /* paranoid */ assert(sizeof(u_short) == 2); /* paranoid */ assert(sizeof(ipaddr_t) == 4); /* but this is critical *//* * Synchronize stdout and stderr in case output is redirected. */ linebufmode(stdout);/* * Initialize resolver. See show_res() for details. * Pickup current values and set new defaults. * Query for optional server is also done with new defaults. * Old defaults are (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) */ (void) res_init(); /* we handle default domains ourselves, thank you */ _res.options |= RES_DEFNAMES; _res.options &= ~RES_DNSRCH; _res.options |= RES_RECURSE; _res.options &= ~RES_DEBUG; _res.options &= ~RES_USEVC; _res.retry = 2; /* number of retries, default = 4 */ _res.retrans = 5; /* timeout in seconds, default = 5 or 6 */ /* save new defaults */ new_res = _res;/* * Check if host was called with a different name. * Interpolate default options and parameters. */ option = getenv("HOST_DEFAULTS"); if (option != NULL) { set_defaults(option, argc, argv); argc = optargc; argv = optargv; } program = rindex(argv[0], '/'); if (program++ == NULL) program = argv[0]; /* check for resource record names */ querytype = parse_type(program); if (querytype < 0) querytype = T_NONE; /* check for zone listing abbreviation */ if (sameword(program, "zone")) listmode = TRUE;/* * Scan command line options and flags. */ while (argc > 1 && argv[1][0] == '-') { for (option = &argv[1][1]; *option != '\0'; option++) { switch (*option) { case 'w' : waitmode = TRUE; new_res.retry = 2; new_res.retrans = 5; break; case 's' : if (argv[2] == NULL || argv[2][0] == '-') fatal("Missing timeout value"); new_res.retry = 2; new_res.retrans = atoi(argv[2]); if (new_res.retrans <= 0) fatal("Invalid timeout value %s", argv[2]); argv++; argc--; break; case 'r' : new_res.options &= ~RES_RECURSE; break; case 'B' : bindcompat = TRUE; /* fall through */ case 'R' : new_res.options |= RES_DNSRCH; break; case 'u' : new_res.options |= RES_USEVC; break; case 'd' : new_res.options |= RES_DEBUG; debug++; /* increment debugging level */ break; case 'v' : verbose++; /* increment verbosity level */ break; case 'q' : quiet = TRUE; break; case 'i' : reverse = TRUE; break; case 'p' : primary = TRUE; break; case 'o' : suppress = TRUE; break; case 'e' : exclusive = TRUE; break; case 'S' : statistics = TRUE; break; case 'T' : ttlprint = TRUE; break; case 'A' : addrmode = TRUE; break; case 'D': case 'E': case 'G': if (*option == 'D') duplmode = TRUE; if (*option == 'E') extrmode = TRUE; if (*option == 'G') gatemode = TRUE; /* fall through */ case 'H' : hostmode = TRUE; listmode = TRUE; if (querytype == T_NONE) querytype = -1; /* suppress zone data output */ break; case 'C' : checkmode = TRUE; listmode = TRUE; if (querytype == T_NONE) querytype = -1; /* suppress zone data output */ break; case 'M' : mxrecmode = TRUE; listmode = TRUE; if (querytype == T_NONE) querytype = -1; /* suppress zone data output */ break; case 'l' : listmode = TRUE; break; case 'L' : if (argv[2] == NULL || argv[2][0] == '-') fatal("Missing recursion level"); recursive = atoi(argv[2]); if (recursive <= 0) fatal("Invalid recursion level %s", argv[2]); argv++; argc--; break; case 'F' : logexchange = TRUE; /* fall through */ case 'f' : if (argv[2] == NULL || argv[2][0] == '-') fatal("Missing logfile name"); logfilename = argv[2]; argv++; argc--; break; case 'I' : if (argv[2] == NULL || argv[2][0] == '-') fatal("Missing allowed chars"); illegal = argv[2]; argv++; argc--; break; case 'c' : if (argv[2] == NULL || argv[2][0] == '-') fatal("Missing query class"); queryclass = parse_class(argv[2]); if (queryclass < 0) fatal("Invalid query class %s", argv[2]); argv++; argc--; break; case 't' : if (argv[2] == NULL || argv[2][0] == '-') fatal("Missing query type"); querytype = parse_type(argv[2]); if (querytype < 0) fatal("Invalid query type %s", argv[2]); argv++; argc--; break; case 'a' : querytype = T_ANY; /* filter anything available */ break; case 'm' : mailmode = TRUE; querytype = T_MAILB; /* filter MINFO/MG/MR/MB data */ break;#ifdef justfun case 'g' : if (argv[2] == NULL || argv[2][0] == '-') fatal("Missing minimum length"); namelen = atoi(argv[2]); if (namelen <= 0) fatal("Invalid minimum length %s", argv[2]); argv++; argc--; break;#endif case 'X' : if (argv[2] == NULL || argv[2][0] == '-') fatal("Missing server name"); servername = argv[2]; argv++; argc--; /* fall through */ case 'x' : extended = TRUE; break; case 'V' : printf("Version %s\n", version); exit(EX_OK); default: fatal(Usage); } } argv++; argc--; }/* * Check the remaining arguments. */ /* old syntax must have at least one argument */ if (!extended && (argc < 2 || argc > 3)) fatal(Usage); /* old syntax has explicit server as second argument */ if (!extended && (argc > 2)) servername = argv[2];/* * Open log file if requested. * Exchange role of stdout and logfile if so specified. */ if (logfilename != NULL) { logfile = fopen(logfilename, "w"); if (logfile == NULL) { perror(logfilename); exit(EX_CANTCREAT); } if (logexchange) {#ifdef SWAPFILE_HACK swapfile(logfile, stdout);#else fatal("Option -F not supported");#endif } }/* * Check for possible alternative server. */ if (servername != NULL) set_server(servername); /* set new resolver values changed by command options */ _res.retry = new_res.retry; _res.retrans = new_res.retrans; _res.options = new_res.options; /* show the new resolver database */ if (debug > 1 || verbose > 1) show_res(); /* show customized default domain */ option = getenv("LOCALDOMAIN"); if (option != NULL && verbose > 1) printf("Explicit local domain %s\n\n", option);/* * Process command line argument(s) depending on syntax. */ if (!extended) /* only one argument */ result = process_name(argv[1]); else if (argc < 2) /* no arguments */ result = process_file(stdin); else /* multiple command line arguments */ result = process_argv(argc, argv); exit(result); /*NOTREACHED*/}/*** SET_DEFAULTS -- Interpolate default options and parameters in argv** ------------------------------------------------------------------**** Returns:** None.**** Outputs:** Creates new optargv vector with optargc arguments.*/voidset_defaults(option, argc, argv)input char *option; /* option string */input int argc;input char *argv[];{ register char *p, *q; register int i;/* * Allocate new argument vector. */ optargv = newlist(NULL, 2, char *); optargv[0] = argv[0]; optargc = 1;/* * Construct argument list from option string. */ for (p = newstr(option); *p != '\0'; p = q) { while (is_space(*p)) p++; if (*p == '\0') break; for (q = p; *q != '\0' && !is_space(*q); q++) continue; if (*q != '\0') *q++ = '\0'; optargv = newlist(optargv, optargc+2, char *); optargv[optargc] = p; optargc++; }/* * Append command line arguments. */ for (i = 1; i < argc; i++) { optargv = newlist(optargv, optargc+2, char *); optargv[optargc] = argv[i]; optargc++; } /* and terminate */ optargv[optargc] = NULL;}/*** PROCESS_ARGV -- Process command line arguments** ----------------------------------------------**** Returns:** EX_OK if information was obtained successfully.** Appropriate exit code otherwise.*/intprocess_argv(argc, argv)input int argc;input char *argv[];{ register int i; int result; /* result status of action taken */ int excode = EX_NOINPUT; /* overall result status */ for (i = 1; i < argc; i++) { /* process a single argument */ result = process_name(argv[i]); /* maintain overall result */ if (result != EX_OK || excode == EX_NOINPUT) excode = result; } /* return overall result */ return(excode);}/*** PROCESS_FILE -- Process arguments from input file** -------------------------------------------------**** Returns:** EX_OK if information was obtained successfully.** Appropriate exit code otherwise.*/intprocess_file(fp)input FILE *fp; /* input file with query names */{ register char *p, *q; char buf[BUFSIZ]; int result; /* result status of action taken */ int excode = EX_NOINPUT; /* overall result status */ while (fgets(buf, sizeof(buf), fp) != NULL) { p = index(buf, '\n'); if (p != NULL) *p = '\0'; /* extract names separated by whitespace */ for (p = buf; *p != '\0'; p = q) { while (is_space(*p)) p++; /* ignore comment lines */ if (*p == '\0' || *p == '#' || *p == ';') break; for (q = p; *q != '\0' && !is_space(*q); q++) continue; if (*q != '\0') *q++ = '\0'; /* process a single argument */ result = process_name(p); /* maintain overall result */ if (result != EX_OK || excode == EX_NOINPUT) excode = result; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -