I have been trying to replace getopt with argp in ping.c. Since I am
new to both inetutils and argp, I am curious to know whether I am
proceeding in the right direction or not.
Please find attached a 'diff -uNp' of ping.c showing what I have done
till now. This is not yet finished.
Happy hacking,
Debarshi
--
GPG key ID: 63D4A5A7
Key server: pgp.mit.edu
--- ../inetutils/ping/ping.c 2006-11-17 19:27:29.000000000 +0530
+++ ping/ping.c 2007-03-28 02:43:08.000000000 +0530
@@ -46,6 +46,7 @@
#include <errno.h>
#include <limits.h>
+#include <argp.h>
#include <getopt.h>
#include <icmp.h>
#include <ping.h>
@@ -100,7 +101,175 @@ static int send_echo (PING * ping);
#define MIN_USER_INTERVAL (200000/PING_PRECISION)
-char *program_name;
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+const char *argp_program_version = "ping (" PACKAGE_NAME ") " PACKAGE_VERSION;
+
+const char args_doc[] = "ADDRESS";
+const char doc[] = "Send ICMP ECHO_REQUEST packets to network hosts.";
+
+static struct argp_option options[] = {
+ {"", '', 0, OPTION_DOC, "Options controlling ICMP request types:"},
+ {"echo", ICMP_ECHO, 0, 0, "Send ICMP_ECHO requests (default)"},
+ {"address*", ICMP_ADDRESS, 0, 0, "Send ICMP_ADDRESS packets"},
+ {"timestamp", ICMP_TIMESTAMP, 0, 0, "Send ICMP_TIMESTAMP packets"},
+ {"router", ICMP_ROUTERDISCOVERY, 0, 0, "Send ICMP_ROUTERDISCOVERY packets"},
+ {"", '', 0, OPTION_DOC, "Options valid for all request types:"},
+ {"count", 'c', "N", 0, "Stop after sending N packets (default: %d)"},
+ {"debug", 'd', 0, 0, "Set the SO_DEBUG option"},
+ {"interval", 'i', "N", 0, "Wait N seconds between sending each packet"},
+ {"numeric", 'n', 0, 0, "Do not resolve host addresses"},
+ {"ignore-routing", 'r', 0, 0, "Send directly to a host on an attached network"},
+ {"verbose", 'v', 0, 0, "Verbose output"},
+ {"", '', 0, OPTION_DOC, "Options valid for --echo requests:"},
+ {"flood*", 'f', 0, 0, "Flood ping"},
+ {"preload", 'l', "N", 0, "Send N packets as fast as possible before falling into\n
+ normal mode of behavior"},
+ {"pattern", 'p', "PAT", 0, "Fill ICMP packet with given pattern (hex)"},
+ {"quiet", 'q', 0, 0, "Quiet output"},
+ {"route", 'r', 0, 0, "Record route"},
+ {"size", 's', "N", 0, "Set number of data octets to send"},
+ {0}
+};
+
+struct arguments
+{
+ char *args[1];
+ u_char *patptr;
+ int count;
+ int socket_type;
+ int pattern;
+ int size;
+ unsigned int options;
+ unsigned long preload;
+ size_t interval;
+ int (*ping_type) (int argc, char **argv);
+};
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ char *endptr;
+ struct arguments *arguments = state->input;
+
+ arguments->patptr = NULL;
+ arguments->size = PING_DATALEN;
+ arguments->preload = 0;
+ arguments->interval = 0;
+ arguments->ping_type = ping_echo;
+ switch (key)
+ {
+ case 'c':
+ arguments->count = ping_cvt_number (arg, 0, 1);
+ break;
+
+ case 'd':
+ arguments->socket_type = SO_DEBUG;
+ break;
+
+ case 'r':
+ arguments->socket_type = SO_DONTROUTE;
+ break;
+
+ case 'i':
+ arguments->interval = strtod (arg, &endptr);
+ if (*endptr)
+ {
+ fprintf (stderr, "Invalid value (`%s' near `%s')\n",
+ arg, endptr);
+ exit (1);
+ }
+
+ if ((arguments->interval *= PING_PRECISION) < MIN_USER_INTERVAL)
+ {
+ fprintf (stderr, "Option value too small: %s\n", arg);
+ exit (1);
+ }
+ arguments->options |= OPT_INTERVAL;
+ break;
+
+ case 'p':
+ decode_pattern (arg, &pattern_len, pattern);
+ arguments->patptr = pattern;
+ break;
+
+ case 's':
+ arguments->size = ping_cvt_number (arg, PING_MAX_DATALEN, 1);
+ break;
+
+ case 'n':
+ arguments->options |= OPT_NUMERIC;
+ break;
+
+ case 'q':
+ arguments->options |= OPT_QUIET;
+ break;
+
+ case 'R':
+ arguments->options |= OPT_RROUTE;
+ break;
+
+ case 'v':
+ arguments->options |= OPT_VERBOSE;
+ break;
+
+ case 'l':
+ arguments->preload = strtoul (arg, &endptr, 0);
+ if (*endptr || arguments->preload > INT_MAX)
+ {
+ fprintf (stderr, "ping: invalid preload value (%s)\n", arg);
+ exit (1);
+ }
+ break;
+
+ case 'f':
+ arguments->options |= OPT_FLOOD;
+ break;
+
+ case 't':
+ arguments->ping_type = decode_type (arg);
+ break;
+
+ case ICMP_ECHO:
+ arguments->ping_type = decode_type ("echo");
+ break;
+
+ case ICMP_TIMESTAMP:
+ arguments->ping_type = decode_type ("timestamp");
+ break;
+
+ case ICMP_ADDRESS:
+ arguments->ping_type = decode_type ("address");
+ break;
+
+ case ICMP_ROUTERDISCOVERY:
+ arguments->ping_type = decode_type ("router");
+ break;
+
+ case ARGP_KEY_NO_ARGS:
+ argp_usage (state);
+ break;
+
+ case ARGP_KEY_ARG:
+ if (state->arg_num >= 1)
+ /* Too many arguments. */
+ argp_usage (state);
+ arguments->args[state->arg_num] = arg;
+ break;
+
+ case ARGP_KEY_END:
+ if (state->arg_num < 1)
+ /* Not enough arguments. */
+ argp_usage (state);
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+
+ return 0;
+}
+
+static struct argp argp = {options, parse_opt, args_doc, doc};
int
main (int argc, char **argv)
@@ -117,8 +286,6 @@ main (int argc, char **argv)
int socket_type = 0;
size_t interval = 0;
- program_name = argv[0];
-
if (getuid () == 0)
is_root = true;
@@ -302,9 +469,11 @@ main (int argc, char **argv)
-void
+int (*) (int argc, char **argv)
decode_type (const char *optarg)
{
+ int (*ping_type) (int argc, char **argv);
+
if (strcasecmp (optarg, "echo") == 0)
ping_type = ping_echo;
else if (strcasecmp (optarg, "timestamp") == 0)
@@ -320,6 +489,8 @@ decode_type (const char *optarg)
fprintf (stderr, "unsupported packet type: %s\n", optarg);
exit (1);
}
+
+ return ping_type;
}
int volatile stop = 0;
_______________________________________________
bug-inetutils mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-inetutils