rndc.c revision 927e4c9fecf448bf3894c68fcaf9dc2f89557f3a
ebf264ea105fc78b8316a1166bae0624d488d83bMark Andrews * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 2000-2003 Internet Software Consortium.
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister * Permission to use, copy, modify, and/or distribute this software for any
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister * purpose with or without fee is hereby granted, provided that the above
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister * copyright notice and this permission notice appear in all copies.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/* $Id: rndc.c,v 1.142 2012/02/03 22:27:17 each Exp $ */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister * Principal Author: DCL
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerstatic const char *admin_conffile;
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerstatic const char *admin_keyfile;
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerstatic isc_sockaddr_t serveraddrs[SERVERADDRS];
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerstatic isc_boolean_t local4set = ISC_FALSE, local6set = ISC_FALSE;
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerstatic int currentaddr = 0;
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerstatic unsigned int remoteport = 0;
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerstatic void rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas GustafssonUsage: %s [-b address] [-c config] [-s server] [-p port]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister [-k key-file ] [-y key] [-V] command\n\
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafssoncommand is one of the following:\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister reload Reload configuration file and zones.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister reload zone [class [view]]\n\
b3e77535185043f089b346166440402d092030c3David Lawrence Reload a single zone.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister refresh zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Schedule immediate maintenance for a zone.\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence retransfer zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Retransfer a single zone without checking serial number.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister freeze Suspend updates to all dynamic zones.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister freeze zone [class [view]]\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence Suspend updates to a dynamic zone.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister thaw Enable updates to all dynamic zones and reload them.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister thaw zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Enable updates to a frozen dynamic zone and reload it.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister sync [-clean] Dump changes to all dynamic zones to disk, and optionally\n\
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson remove their journal files.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister sync [-clean] zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Dump a single zone's changes to disk, and optionally\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence remove its journal file.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister notify zone [class [view]]\n\
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson Resend NOTIFY messages for the zone.\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence reconfig Reload configuration file and new zones only.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister sign zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Update zone keys, and sign as needed.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister loadkeys zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Update keys without signing immediately.\n\
b3e77535185043f089b346166440402d092030c3David Lawrence zonestatus zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Display the current status of a zone.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister stats Write server statistics to the statistics file.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister querylog newstate\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence Enable / disable query logging.\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews dumpdb [-all|-cache|-zones] [view ...]\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews Dump cache(s) to the dump file (named_dump.db).\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews secroots [view ...]\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews Write security roots to the secroots file.\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews stop Save pending updates to master files and stop the server.\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews stop -p Save pending updates to master files and stop the server\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews reporting process id.\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews halt Stop the server without saving pending updates.\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews halt -p Stop the server without saving pending updates reporting\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews process id.\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews trace Increment debugging level by one.\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews trace level Change the debugging level.\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews notrace Set debugging level to 0.\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews flush Flushes all of the server's caches.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister flush [view] Flushes the server's cache for a view.\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence flushname name [view]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Flush the given name from the server's cache(s)\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister flushtree name [view]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Flush all names under the given name from the server's cache(s)\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister status Display status of the server.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister recursing Dump the queries that are currently recursing (named.recursing)\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister tsig-list List all currently active TSIG keys, including both statically\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence configured and TKEY-negotiated keys.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister tsig-delete keyname [view] \n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Delete a TKEY-negotiated TSIG key.\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence validation newstate [view]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Enable / disable DNSSEC validation.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister addzone zone [class [view]] { zone-options }\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews Add zone to given view. Requires new-zone-file option.\n\
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews delzone [-clean] zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Removes zone from given view. Requires new-zone-file option.\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence signing -list zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister List the private records showing the state of DNSSEC\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister signing in the given zone.\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence signing -clear <keyid>/<algorithm> zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Remove the private record that indicating the given key\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister has finished signing the given zone.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister signing -clear all zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Remove the private records for all keys that have\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister finished signing the given zone.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister signing -nsec3param none zone [class [view]]\n\
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence Remove NSEC3 chains from zone.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister signing -nsec3param hash flags iterations salt zone [class [view]]\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Add NSEC3 chain to zone if already signed.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister Prime zone with NSEC3 chain if not yet signed.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister *restart Restart the server.\n\
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister* == not yet implemented\n\
b3e77535185043f089b346166440402d092030c3David LawrenceVersion: %s\n",
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerget_addresses(const char *host, in_port_t port) {
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews result = isc_sockaddr_frompath(&serveraddrs[nserveraddrs],
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsrndc_senddone(isc_task_t *task, isc_event_t *event) {
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews isc_socketevent_t *sevent = (isc_socketevent_t *)event;
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson fatal("send failed: %s", isc_result_totext(sevent->result));
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerrndc_recvdone(isc_task_t *task, isc_event_t *event) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence "This may indicate that\n"
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister "* the remote server is using an older version of"
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister " the command protocol,\n"
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister "* this host is not authorized to connect,\n"
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson "* the clocks are not synchronized, or\n"
b3e77535185043f089b346166440402d092030c3David Lawrence "* the key is invalid.");
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister fatal("recv failed: %s", isc_result_totext(ccmsg.result));
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister source.rstart = isc_buffer_base(&ccmsg.buffer);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence source.rend = isc_buffer_used(&ccmsg.buffer);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister isccc_cc_fromwire(&source, &response, algorithm, &secret));
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister result = isccc_cc_lookupstring(data, "err", &errormsg);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister fprintf(stderr, "%s: parsing response failed: %s\n",
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister result = isccc_cc_lookupstring(data, "text", &textmsg);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister fprintf(stderr, "%s: parsing response failed: %s\n",
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencerndc_recvnonce(isc_task_t *task, isc_event_t *event) {
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister "This may indicate that\n"
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister "* the remote server is using an older version of"
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister " the command protocol,\n"
b3e77535185043f089b346166440402d092030c3David Lawrence "* this host is not authorized to connect,\n"
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister "* the clocks are not synchronized,\n"
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence "* the the key signing algorithm is incorrect, or\n"
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister "* the key is invalid.");
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence fatal("recv failed: %s", isc_result_totext(ccmsg.result));
b3e77535185043f089b346166440402d092030c3David Lawrence source.rstart = isc_buffer_base(&ccmsg.buffer);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence source.rend = isc_buffer_used(&ccmsg.buffer);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister isccc_cc_fromwire(&source, &response, algorithm, &secret));
b3e77535185043f089b346166440402d092030c3David Lawrence _ctrl = isccc_alist_lookup(response, "_ctrl");
b3e77535185043f089b346166440402d092030c3David Lawrence if (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS)
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial,
5475a2d296215b7a93bd89804dc33c36a6de7cb5James Brister if (isccc_cc_definestring(data, "type", args) == NULL)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence _ctrl = isccc_alist_lookup(request, "_ctrl");
5475a2d296215b7a93bd89804dc33c36a6de7cb5James Brister if (isccc_cc_defineuint32(_ctrl, "_nonce", nonce) == NULL)
5475a2d296215b7a93bd89804dc33c36a6de7cb5James Brister isccc_cc_towire(request, &message, algorithm, &secret));
b3e77535185043f089b346166440402d092030c3David Lawrence len = sizeof(databuf) - REGION_SIZE(message);
5475a2d296215b7a93bd89804dc33c36a6de7cb5James Brister DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task,
5475a2d296215b7a93bd89804dc33c36a6de7cb5James Brister DO("send message", isc_socket_send(sock, &r, task, rndc_senddone,
5475a2d296215b7a93bd89804dc33c36a6de7cb5James Bristerrndc_connected(isc_task_t *task, isc_event_t *event) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_socketevent_t *sevent = (isc_socketevent_t *)event;
5475a2d296215b7a93bd89804dc33c36a6de7cb5James Brister isc_sockaddr_format(&serveraddrs[currentaddr], socktext,
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellington notify("connection failed: %s: %s", socktext,
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellington rndc_startconnect(&serveraddrs[currentaddr], task);
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellington DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial,
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellington data = isccc_alist_lookup(request, "_data");
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellington if (isccc_cc_definestring(data, "type", "null") == NULL)
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellington isccc_cc_towire(request, &message, algorithm, &secret));
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellington len = sizeof(databuf) - REGION_SIZE(message);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task,
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister DO("send message", isc_socket_send(sock, &r, task, rndc_senddone,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencerndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task) {
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister isc_sockaddr_format(addr, socktext, sizeof(socktext));
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister notify("using server %s (%s)", servername, socktext);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister DO("create socket", isc_socket_create(socketmgr, pf, type, &sock));
b3e77535185043f089b346166440402d092030c3David Lawrence DO("bind socket", isc_socket_bind(sock, &local4, 0));
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister DO("bind socket", isc_socket_bind(sock, &local6, 0));
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister DO("connect", isc_socket_connect(sock, addr, task, rndc_connected,
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerrndc_start(isc_task_t *task, isc_event_t *event) {
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister rndc_startconnect(&serveraddrs[currentaddr], task);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerparse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname,
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister const cfg_type_t *conftype = &cfg_type_rndcconf;
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington fatal("%s does not exist", admin_conffile);
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington } else if (! c_flag && isc_file_exists(admin_keyfile)) {
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington fprintf(stderr, "WARNING: key file (%s) exists, but using "
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington "default configuration file (%s)\n",
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington DO("create parser", cfg_parser_create(mctx, log, pctxp));
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington * The parser will output its own errors, so DO() is not used.
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington result = cfg_parse_file(*pctxp, conffile, conftype, &config);
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington fatal("could not load rndc configuration");
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington (void)cfg_map_get(config, "options", &options);
600cbd1fcea3c9cc9706dc1ff8fc0d0034ebdeacTatuya JINMEI 神明達哉 else if (servername == NULL && options != NULL) {
600cbd1fcea3c9cc9706dc1ff8fc0d0034ebdeacTatuya JINMEI 神明達哉 (void)cfg_map_get(options, "default-server", &defserverobj);
600cbd1fcea3c9cc9706dc1ff8fc0d0034ebdeacTatuya JINMEI 神明達哉 servername = cfg_obj_asstring(defserverobj);
600cbd1fcea3c9cc9706dc1ff8fc0d0034ebdeacTatuya JINMEI 神明達哉 fatal("no server specified and no default");
600cbd1fcea3c9cc9706dc1ff8fc0d0034ebdeacTatuya JINMEI 神明達哉 (void)cfg_map_get(config, "server", &servers);
600cbd1fcea3c9cc9706dc1ff8fc0d0034ebdeacTatuya JINMEI 神明達哉 name = cfg_obj_asstring(cfg_map_getname(server));
600cbd1fcea3c9cc9706dc1ff8fc0d0034ebdeacTatuya JINMEI 神明達哉 * Look for the name of the key to use.
&defkey));
} else if (!key_only)
if (key_only)
keyname) == 0)
if (remoteport != 0)
} else if (remoteport == 0)
unsigned int myport;
const char *name;
myport == 0)
myport);
sizeof(socktext));
socktext);
int ch;
switch (ch) {
usage(0);
argslen = 0;
for (i = 0; i < argc; i++)
p = args;
for (i = 0; i < argc; i++) {
p += len;
if (nserveraddrs == 0)
if (show_final_mem)
if (failed)