diff options
Diffstat (limited to 'args.c')
-rw-r--r-- | args.c | 68 |
1 files changed, 58 insertions, 10 deletions
@@ -21,9 +21,14 @@ #include <limits.h> #include <unistd.h> #include <error.h> +#include <stdio.h> #include <argp.h> #include <argz.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> + #include <hurd/netfs.h> #include "gopherfs.h" @@ -34,8 +39,8 @@ const char *argp_program_bug_address = "ja2morri@uwaterloo.ca"; char args_doc[] = "SERVER [REMOTE_FS]"; char doc[] = "Hurd gopher filesystem translator"; static const struct argp_option options[] = { - {"debug", 'D', 0, 0, "enable debug output"}, {"port", 'P', "NUMBER", 0, "Specify a non-standard port"}, + {"debug", 'D', "FILE", 0, "Print debug output to FILE"}, {0} }; /* the function that groks the arguments and fills @@ -44,38 +49,82 @@ static const struct argp_option options[] = { static error_t parse_opt (int key, char *arg, struct argp_state *state) { + struct gopherfs_params *params = state->input; + error_t err = 0; + + FILE *debug_stream = NULL; char *tail; switch (key) { case 'D': - debug_flag = 1; + if (arg) + { + debug_stream = fopen (arg, "w+"); + if (! debug_stream) + { + err = errno; + argp_failure (state, 0, errno, "Cannot open debugging file %s", arg); + } + } + else + debug_stream = stderr; + + if (!err) + debug_init (debug_stream); + break; + case 'P': - gopherfs_root_port = (unsigned short) strtol (arg, &tail, 10); - if (tail == arg || gopherfs_root_port > USHRT_MAX) + params->port = (unsigned short) strtol (arg, &tail, 10); + if (tail == arg || params->port > USHRT_MAX) { /* XXX bad integer conversion */ error (1, errno, "bad port number"); } break; + case ARGP_KEY_ARG: if (state->arg_num == 0) { - gopherfs_root_port = 70; - gopherfs_root_server = arg; + params->dir = ""; + params->server = arg; } else if (state->arg_num == 1) { - gopherfs_server_dir = arg; + params->dir = arg; } else return ARGP_ERR_UNKNOWN; break; + + case ARGP_KEY_SUCCESS: + if (state->arg_num == 0) + argp_error (state, "No remote filesystem specified"); + else + { + /* No port was provided. Get gopher default port. */ + if (params->port == 0) + { + struct servent *se = getservbyname ("gopher", "tcp"); + if (! se) + argp_error (state, "Couldn't get gopher port"); + + params->port = ntohs(se->s_port); + } + + /* Check if the given address resolves. */ + error_t err; + struct addrinfo *addr; + err = lookup_host (params->server, params->port, &addr); + if (err) + argp_failure (state, 10, 0, "%s: %s", params->server, gai_strerror (err)); + } default: return ARGP_ERR_UNKNOWN; } return 0; } + static struct argp_child argp_children[] = { {&netfs_std_startup_argp}, {0} }; static struct argp parser = { options, parse_opt, args_doc, doc, argp_children }; @@ -88,8 +137,7 @@ error_t netfs_append_args (char **argz, size_t * argz_len); /* handle all initial parameter parsing */ error_t -gopherfs_parse_args (int argc, char **argv) +gopherfs_parse_args (int argc, char **argv, struct gopherfs_params *params) { - /* XXX: handle command line arguments properly */ - return argp_parse (&parser, argc, argv, 0, 0, /*&conf */ 0); + return argp_parse (&parser, argc, argv, 0, 0, params); } |