bug-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-inetutils] Patches for submission -- ping


From: Debarshi 'Rishi' Ray
Subject: [bug-inetutils] Patches for submission -- ping
Date: Sun, 27 May 2007 00:44:21 +0530

Here (both attached and inline) is the patch to argpify ping.

diff -urNp inetutils/ping/Makefile.am inetutils-build/ping/Makefile.am
--- inetutils/ping/Makefile.am  2007-03-30 14:41:05.000000000 +0530
+++ inetutils-build/ping/Makefile.am    2007-04-14 14:53:12.000000000 +0530
@@ -25,7 +25,8 @@ EXTRA_DIST = $(man_MANS)

ping_LDADD = -L../libinetutils -linetutils -L../libicmp -licmp -L../lib -lgnu
ping6_LDADD = -L../lib -lgnu -L../libinetutils -linetutils
-INCLUDES = -I$(top_srcdir)/lib -I../lib -I$(top_srcdir)/libicmp
+INCLUDES = -I$(top_srcdir)/lib -I../lib -I$(top_srcdir)/libicmp \
+  -I$(top_srcdir)/libinetutils

ping_SOURCES = ping.c ping_common.c ping_echo.c ping_address.c \
  ping_router.c ping_timestamp.c ping_common.h  ping_impl.h
diff -urNp inetutils/ping/ping.c inetutils-build/ping/ping.c
--- inetutils/ping/ping.c       2006-11-17 19:27:29.000000000 +0530
+++ inetutils-build/ping/ping.c 2007-04-19 03:07:25.000000000 +0530
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998,2001, 2002, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1998,2001, 2002, 2005, 2006, 2007
+   Free Software Foundation, Inc.

   This file is part of GNU Inetutils.

@@ -46,40 +47,12 @@
#include <errno.h>
#include <limits.h>

-#include <getopt.h>
+#include <argp.h>
#include <icmp.h>
#include <ping.h>
#include "ping_common.h"
#include "ping_impl.h"
-
-static char short_options[] = "VLhc:dfi:l:np:qRrs:t:v";
-static struct option long_options[] = {
-  /* Help options */
-  {"version", no_argument, NULL, 'V'},
-  {"license", no_argument, NULL, 'L'},
-  {"help", no_argument, NULL, 'h'},
-  /* Common options */
-  {"count", required_argument, NULL, 'c'},
-  {"debug", no_argument, NULL, 'd'},
-  {"ignore-routing", no_argument, NULL, 'r'},
-  {"size", required_argument, NULL, 's'},
-  {"interval", required_argument, NULL, 'i'},
-  {"numeric", no_argument, NULL, 'n'},
-  {"verbose", no_argument, NULL, 'v'},
-  /* Packet types */
-  {"type", required_argument, NULL, 't'},
-  {"echo", no_argument, NULL, ICMP_ECHO},
-  {"timestamp", no_argument, NULL, ICMP_TIMESTAMP},
-  {"address", no_argument, NULL, ICMP_ADDRESS},
-  {"router", no_argument, NULL, ICMP_ROUTERDISCOVERY},
-  /* echo-specific options */
-  {"flood", no_argument, NULL, 'f'},
-  {"preload", required_argument, NULL, 'l'},
-  {"pattern", required_argument, NULL, 'p'},
-  {"quiet", no_argument, NULL, 'q'},
-  {"route", no_argument, NULL, 'R'},
-  {NULL, no_argument, NULL, 0}
-};
+#include "libinetutils.h"

extern int ping_echo (int argc, char **argv);
extern int ping_timestamp (int argc, char **argv);
@@ -87,200 +60,193 @@ extern int ping_address (int argc, char
extern int ping_router (int argc, char **argv);

PING *ping;
+bool is_root = false;
u_char *data_buffer;
+u_char *patptr;
+int pattern_len = 16;
+int socket_type;
+size_t count = DEFAULT_PING_COUNT;
+size_t interval;
size_t data_length = PING_DATALEN;
unsigned options;
unsigned long preload = 0;
int (*ping_type) (int argc, char **argv) = ping_echo;

-
-static void show_usage (void);
-static void decode_type (const char *optarg);
+/*static void decode_type (const char *optarg);*/
+int (*decode_type (const char *arg)) (int argc, char **argv);
static int send_echo (PING * ping);

#define MIN_USER_INTERVAL (200000/PING_PRECISION)

-char *program_name;
+ARGP_PROGRAM_DATA ("ping", "2007", "Sergey Poznyakoff");

-int
-main (int argc, char **argv)
+const char args_doc[] = "HOST";
+const char doc[] = "Send ICMP ECHO_REQUEST packets to network hosts."
+                   "\vOptions marked with (root only) are available only to "
+                   "superuser.";
+
+/* Define keys for long options that do not have short counterparts. */
+enum {
+  ARG_ECHO = 256,
+  ARG_ADDRESS,
+  ARG_TIMESTAMP,
+  ARG_ROUTERDISCOVERY
+};
+
+static struct argp_option argp_options[] = {
+#define GRP 0
+  {NULL, 0, NULL, 0, "Options controlling ICMP request types:", GRP},
+  {"address", ARG_ADDRESS, NULL, 0, "Send ICMP_ADDRESS packets (root only)",
+   GRP+1},
+  {"echo", ARG_ECHO, NULL, 0, "Send ICMP_ECHO packets (default)", GRP+1},
+  {"timestamp", ARG_TIMESTAMP, NULL, 0, "Send ICMP_TIMESTAMP packets", GRP+1},
+  {"type", 't', "TYPE", 0, "Send TYPE packets", GRP+1},
+  /* This option is not yet fully implemented, so mark it as hidden. */
+  {"router", ARG_ROUTERDISCOVERY, NULL, OPTION_HIDDEN, "Send "
+   "ICMP_ROUTERDISCOVERY packets (root only)", GRP+1},
+#undef GRP
+#define GRP 10
+  {NULL, 0, NULL, 0, "Options valid for all request types:", GRP},
+  {"count", 'c', "NUMBER", 0, "Stop after sending NUMBER packets", GRP+1},
+  {"debug", 'd', NULL, 0, "Set the SO_DEBUG option", GRP+1},
+  {"interval", 'i', "NUMBER", 0, "Wait NUMBER seconds between sending each "
+   "packet", GRP+1},
+  {"numeric", 'n', NULL, 0, "Do not resolve host addresses", GRP+1},
+  {"ignore-routing", 'r', NULL, 0, "Send directly to a host on an attached "
+   "network", GRP+1},
+  {"verbose", 'v', NULL, 0, "Verbose output", GRP+1},
+#undef GRP
+#define GRP 20
+  {NULL, 0, NULL, 0, "Options valid for --echo requests:", GRP},
+  {"flood", 'f', NULL, 0, "Flood ping (root only)", GRP+1},
+  {"preload", 'l', "NUMBER", 0, "Send NUMBER packets as fast as possible "
+   "before falling into normal mode of behavior (root only)", GRP+1},
+  {"pattern", 'p', "PATTERN", 0, "Fill ICMP packet with given pattern (hex)",
+   GRP+1},
+  {"quiet", 'q', NULL, 0, "Quiet output", GRP+1},
+  {"route", 'R', NULL, 0, "Record route", GRP+1},
+  {"size", 's', "NUMBER", 0, "Send NUMBER data octets", GRP+1},
+#undef GRP
+  {NULL}
+};
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
{
-  int c;
-  char *p;
-  int one = 1;
+  char *endptr;
  u_char pattern[16];
-  int pattern_len = 16;
-  u_char *patptr = NULL;
-  bool is_root = false;
-
-  size_t count = DEFAULT_PING_COUNT;
-  int socket_type = 0;
-  size_t interval = 0;
+  double v;

-  program_name = argv[0];
+  switch (key)
+    {
+    case 'c':
+      count = ping_cvt_number (arg, 0, 1);
+      break;
+
+    case 'd':
+      socket_type = SO_DEBUG;
+      break;
+
+    case 'i':
+      v = strtod (arg, &endptr);
+      if (*endptr)
+        argp_error (state, "invalid value (`%s' near `%s')", arg, endptr);
+      options |= OPT_INTERVAL;
+      interval = v * PING_PRECISION;
+      if (!is_root && interval < MIN_USER_INTERVAL)
+        error (EXIT_FAILURE, 0, "option value too small: %s", arg);
+      break;
+
+    case 'r':
+      socket_type = SO_DONTROUTE;
+      break;
+
+    case 's':
+      data_length = ping_cvt_number (arg, PING_MAX_DATALEN, 1);
+      break;
+
+    case 'n':
+      options |= OPT_NUMERIC;
+      break;
+
+    case 'p':
+      decode_pattern (arg, &pattern_len, pattern);
+      patptr = pattern;
+      break;
+
+    case 'q':
+      options |= OPT_QUIET;
+      break;
+
+    case 'R':
+      options |= OPT_RROUTE;
+      break;
+
+    case 'v':
+      options |= OPT_VERBOSE;
+      break;
+
+    case 'l':
+      preload = strtoul (arg, &endptr, 0);
+      if (*endptr || preload > INT_MAX)
+        error (EXIT_FAILURE, 0, "invalid preload value (%s)", arg);
+      break;
+
+    case 'f':
+      options |= OPT_FLOOD;
+      break;
+
+    case 't':
+      ping_type = decode_type (arg);
+      break;
+
+    case ARG_ECHO:
+      ping_type = decode_type ("echo");
+      break;
+
+    case ARG_TIMESTAMP:
+      ping_type = decode_type ("timestamp");
+      break;
+
+    case ARG_ADDRESS:
+      ping_type = decode_type ("address");
+      break;
+
+    case ARG_ROUTERDISCOVERY:
+      ping_type = decode_type ("router");
+      break;

-  if (getuid () == 0)
-    is_root = true;
+    case ARGP_KEY_NO_ARGS:
+      argp_error (state, "missing host operand");

-  /* Parse command line */
-  while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
-        != EOF)
-    {
-      switch (c)
-       {
-       case 'V':
-         printf ("ping - %s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
-         printf ("Copyright (C) 2005 Free Software Foundation, Inc.\n");
-         printf ("%s comes with ABSOLUTELY NO WARRANTY.\n", PACKAGE_NAME);
-         printf ("You may redistribute copies of %s\n", PACKAGE_NAME);
-         printf ("under the terms of the GNU General Public License.\n");
-         printf ("For more information about these matters, ");
-         printf ("see the files named COPYING.\n");
-         exit (0);
-         break;
-
-       case 'L':
-         show_license ();
-         exit (0);
-
-       case 'h':
-         show_usage ();
-         exit (0);
-         break;
-
-       case 'c':
-         count = ping_cvt_number (optarg, 0, 1);
-         break;
-
-       case 'd':
-         socket_type = SO_DEBUG;
-         break;
-
-       case 'r':
-         socket_type = SO_DONTROUTE;
-         break;
-
-       case 'i':
-         {
-           double v;
-
-           v = strtod (optarg, &p);
-           if (*p)
-             {
-               fprintf (stderr, "Invalid value (`%s' near `%s')\n",
-                        optarg, p);
-               exit (1);
-             }
-
-           options |= OPT_INTERVAL;
-           interval = v * PING_PRECISION;
-           if (!is_root && interval < MIN_USER_INTERVAL)
-             {
-               fprintf (stderr, "Option value too small: %s\n", optarg);
-               exit (1);
-             }
-         }
-         break;
-
-       case 'p':
-         decode_pattern (optarg, &pattern_len, pattern);
-         patptr = pattern;
-         break;
-
-       case 's':
-         data_length = ping_cvt_number (optarg, PING_MAX_DATALEN, 1);
-         break;
-
-       case 'n':
-         options |= OPT_NUMERIC;
-         break;
-
-       case 'q':
-         options |= OPT_QUIET;
-         break;
-
-       case 'R':
-         options |= OPT_RROUTE;
-         break;
-
-       case 'v':
-         options |= OPT_VERBOSE;
-         break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }

-       case 'l':
-         if (!is_root)
-           {
-             fprintf (stderr, "ping: option not allowed: --preload\n");
-             exit (1);
-           }
-         preload = strtoul (optarg, &p, 0);
-         if (*p || preload > INT_MAX)
-           {
-             fprintf (stderr, "ping: invalid preload value (%s)\n", optarg);
-             exit (1);
-           }
-         break;
+  return 0;
+}

-       case 'f':
-         if (is_root == false)
-           {
-             fprintf (stderr, "ping: option not allowed: --flood\n");
-             exit (1);
-           }
-         options |= OPT_FLOOD;
-         setbuf (stdout, (char *) NULL);
-         break;
-
-       case 't':
-         decode_type (optarg);
-         break;
-
-       case ICMP_ECHO:
-         decode_type ("echo");
-         break;
-
-       case ICMP_TIMESTAMP:
-         decode_type ("timestamp");
-         break;
+static struct argp argp = {argp_options, parse_opt, args_doc, doc};

-       case ICMP_ADDRESS:
-         if (!is_root)
-           {
-             fprintf (stderr, "ping: option not allowed: --address\n");
-             exit (1);
-           }
-         decode_type ("address");
-         break;
+int
+main (int argc, char **argv)
+{
+  int index;
+  int one = 1;

-       case ICMP_ROUTERDISCOVERY:
-         if (!is_root)
-           {
-             fprintf (stderr, "ping: option not allowed: --router\n");
-             exit (1);
-           }
-         decode_type ("router");
-         break;
+  if (getuid () == 0)
+    is_root = true;

-       default:
-         fprintf (stderr, "%c: not implemented\n", c);
-         exit (1);
-       }
-    }
+  /* Parse command line */
+  argp_parse (&argp, argc, argv, 0, &index, NULL);

-  argc -= optind;
-  argv += optind;
-  if (argc == 0)
-    {
-      show_usage ();
-      exit (0);
-    }
+  argv += index;
+  argc -= index;

  ping = ping_init (ICMP_ECHO, getpid ());
  if (ping == NULL)
-    {
-      fprintf (stderr, "can't init ping: %s\n", strerror (errno));
-      exit (1);
-    }
+    exit (1);
+
  ping_set_sockopt (ping, SO_BROADCAST, (char *) &one, sizeof (one));

  /* Reset root privileges */
@@ -297,29 +263,27 @@ main (int argc, char **argv)

  init_data_buffer (patptr, pattern_len);

-  return (*ping_type) (argc, argv);
+  return (*(ping_type)) (argc, argv);
}

-
-
-void
-decode_type (const char *optarg)
+int (*decode_type (const char *arg)) (int argc, char **argv)
{
-  if (strcasecmp (optarg, "echo") == 0)
+  int (*ping_type) (int argc, char **argv);
+
+  if (strcasecmp (arg, "echo") == 0)
    ping_type = ping_echo;
-  else if (strcasecmp (optarg, "timestamp") == 0)
+  else if (strcasecmp (arg, "timestamp") == 0)
    ping_type = ping_timestamp;
-  else if (strcasecmp (optarg, "address") == 0)
+  else if (strcasecmp (arg, "address") == 0)
    ping_type = ping_address;
#if 0
-  else if (strcasecmp (optarg, "router") == 0)
+  else if (strcasecmp (arg, "router") == 0)
    ping_type = ping_router;
#endif
  else
-    {
-      fprintf (stderr, "unsupported packet type: %s\n", optarg);
-      exit (1);
-    }
+    error (EXIT_FAILURE, 0, "unsupported packet type: %s", arg);
+
+ return ping_type;
}

int volatile stop = 0;
@@ -467,40 +431,3 @@ ping_finish ()
  printf ("\n");
  return 0;
}
-
-void
-show_usage (void)
-{
-  printf ("\
-Usage: ping [OPTION]... [ADDRESS]...\n\
-\n\
-Informational options:\n\
-  -h, --help         display this help and exit\n\
-  -L, --license      display license and exit\n\
-  -V, --version      output version information and exit\n\
-Options controlling ICMP request types:\n\
-  --echo             Send ICMP_ECHO requests (default)\n\
-* --address          Send ICMP_ADDRESS packets\n\
-  --timestamp        Send ICMP_TIMESTAMP packets\n\
-* --router           Send ICMP_ROUTERDISCOVERY packets\n\
-Options valid for all request types:\n\
-  -c, --count N      stop after sending N packets (default: %d)\n\
-  -d, --debug        set the SO_DEBUG option\n\
-  -i, --interval N   wait N seconds between sending each packet\n\
-  -n, --numeric      do not resolve host addresses\n\
-  -r, --ignore-routing  send directly to a host on an attached network\n\
-  -v, --verbose      verbose output\n\
-Options valid for --echo requests:\n\
-* -f, --flood        flood ping \n\
-* -l, --preload N    send N packets as fast as possible before falling into\n\
-                     normal mode of behavior\n\
-  -p, --pattern PAT  fill ICMP packet with given pattern (hex)\n\
-  -q, --quiet        quiet output\n\
-  -R, --route        record route\n\
-  -s, --size N       set number of data octets to send\n\
-\n\
-Options marked with an * are available only to super-user\n\
-\n\
-Report bugs to <" PACKAGE_BUGREPORT ">.\n\
-", DEFAULT_PING_COUNT);
-}
diff -urNp inetutils/ping/ping6.c inetutils-build/ping/ping6.c
--- inetutils/ping/ping6.c      2006-11-11 07:01:15.000000000 +0530
+++ inetutils-build/ping/ping6.c        2007-04-19 03:07:17.000000000 +0530
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998, 2001, 2002, 2004, 2005, 2006 Free Software
Foundation, Inc.
+/* Copyright (C) 1998, 2001, 2002, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.

   This file is part of GNU Inetutils.

@@ -32,173 +33,159 @@
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <stdio.h>
+#include <argp.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>

-#include <getopt.h>
#include <xalloc.h>
#include "ping_common.h"
#include "ping6.h"
-
-static char short_options[] = "VLhc:dfi:l:np:qRrs:t:v";
-static struct option long_options[] = {
-  /* Help options */
-  {"version", no_argument, NULL, 'V'},
-  {"license", no_argument, NULL, 'L'},
-  {"help", no_argument, NULL, 'h'},
-  /* Common options */
-  {"count", required_argument, NULL, 'c'},
-  {"debug", no_argument, NULL, 'd'},
-  {"ignore-routing", no_argument, NULL, 'r'},
-  {"size", required_argument, NULL, 's'},
-  {"interval", required_argument, NULL, 'i'},
-  {"numeric", no_argument, NULL, 'n'},
-  /* echo-specific options */
-  {"flood", no_argument, NULL, 'f'},
-  {"preload", required_argument, NULL, 'l'},
-  {"pattern", required_argument, NULL, 'p'},
-  {"quiet", no_argument, NULL, 'q'},
-  {NULL, no_argument, NULL, 0}
-};
+#include "libinetutils.h"

static PING *ping;
+bool is_root;
unsigned char *data_buffer;
+u_char *patptr;
+int one = 1;
+int pattern_len = 16;
size_t data_length = PING_DATALEN;
static unsigned int options;
static unsigned long preload = 0;

static int ping_echo (int argc, char **argv);

-static void show_usage (void);
static int send_echo (PING * ping);

-char *program_name;
+ARGP_PROGRAM_DATA ("ping6", "2007", "Jeroen Dekkers");

-int
-main (int argc, char **argv)
+const char args_doc[] = "HOST";
+const char doc[] = "Send ICMP ECHO_REQUEST packets to network hosts."
+                   "\vOptions marked with (root only) are available only to "
+                   "superuser.";
+
+static struct argp_option argp_options[] = {
+#define GRP 0
+  {NULL, 0, NULL, 0, "Options valid for all request types:", GRP},
+  {"count", 'c', "NUMBER", 0, "Stop after sending NUMBER packets", GRP+1},
+  {"debug", 'd', NULL, 0, "Set the SO_DEBUG option", GRP+1},
+  {"interval", 'i', "NUMBER", 0, "Wait NUMBER seconds between sending each "
+   "packet", GRP+1},
+  {"numeric", 'n', NULL, 0, "Do not resolve host addresses", GRP+1},
+  {"ignore-routing", 'r', NULL, 0, "Send directly to a host on an attached "
+   "network", GRP+1},
+#undef GRP
+#define GRP 10
+  {NULL, 0, NULL, 0, "Options valid for --echo requests:", GRP},
+  {"flood", 'f', NULL, 0, "Flood ping (root only)", GRP+1},
+  {"preload", 'l', "NUMBER", 0, "Send NUMBER packets as fast as possible "
+   "before falling into normal mode of behavior (root only)", GRP+1},
+  {"pattern", 'p', "PATTERN", 0, "Fill ICMP packet with given pattern (hex)",
+   GRP+1},
+  {"quiet", 'q', NULL, 0, "Quiet output", GRP+1},
+  {"size", 's', "NUMBER", 0, "Send NUMBER data octets", GRP+1},
+#undef GRP
+  {NULL}
+};
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
{
-  int c;
-  char *p;
-  int one = 1;
+  char *endptr;
  u_char pattern[16];
-  int pattern_len = 16;
-  u_char *patptr = NULL;
-  int is_root = getuid () == 0;

-  program_name = argv[0];
-  if ((ping = ping_init (0, getpid ())) == NULL)
+  switch (key)
    {
-      fprintf (stderr, "can't init ping: %s\n", strerror (errno));
-      exit (1);
-    }
-  setsockopt (ping->ping_fd, SOL_SOCKET, SO_BROADCAST, (char *) &one,
-             sizeof (one));
+    case 'c':
+      ping->ping_count = ping_cvt_number (arg, 0, 0);
+      break;

-  /* Reset root privileges */
-  setuid (getuid ());
+    case 'd':
+      setsockopt (ping->ping_fd, SOL_SOCKET, SO_DEBUG, &one, sizeof (one));
+      break;

-  /* Parse command line */
-  while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
-        != EOF)
-    {
-      switch (c)
-       {
-       case 'V':
-         printf ("ping - %s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
-         printf ("Copyright (C) 2005 Free Software Foundation, Inc.\n");
-         printf ("%s comes with ABSOLUTELY NO WARRANTY.\n", PACKAGE_NAME);
-         printf ("You may redistribute copies of %s\n", PACKAGE_NAME);
-         printf ("under the terms of the GNU General Public License.\n");
-         printf ("For more information about these matters, ");
-         printf ("see the files named COPYING.\n");
-         exit (0);
-         break;
+    case 'f':
+      if (!is_root)
+        error (EXIT_FAILURE, errno, NULL);

-       case 'L':
-         show_license ();
-         exit (0);
-
-       case 'h':
-         show_usage ();
-         exit (0);
-         break;
+      options |= OPT_FLOOD;
+      setbuf (stdout, (char *) NULL);
+      break;

-       case 'c':
-         ping->ping_count = ping_cvt_number (optarg, 0, 0);
-         break;
+    case 'i':
+      options |= OPT_INTERVAL;
+      ping->ping_interval = ping_cvt_number (arg, 0, 0);
+      break;

-       case 'd':
-         setsockopt (ping->ping_fd, SOL_SOCKET, SO_DEBUG, &one,
-                     sizeof (one));
-         break;
+    case 'l':
+      if (!is_root)
+        error (EXIT_FAILURE, errno, NULL);

-       case 'r':
-         setsockopt (ping->ping_fd, SOL_SOCKET, SO_DONTROUTE, &one,
-                     sizeof (one));
-         break;
+      preload = strtoul (arg, &endptr, 0);
+      if (*endptr || preload > INT_MAX)
+        error (EXIT_FAILURE, errno, NULL);

-       case 'i':
-         options |= OPT_INTERVAL;
-         ping->ping_interval = ping_cvt_number (optarg, 0, 0);
-         break;
+      break;

-       case 'p':
-         decode_pattern (optarg, &pattern_len, pattern);
-         patptr = pattern;
-         break;
+    case 'n':
+      options |= OPT_NUMERIC;
+      break;

-       case 's':
-         data_length = ping_cvt_number (optarg, PING_MAX_DATALEN, 1);
-         break;
+    case 'p':
+      decode_pattern (arg, &pattern_len, pattern);
+      patptr = pattern;
+      break;

-       case 'n':
-         options |= OPT_NUMERIC;
-         break;
+    case 'q':
+      options |= OPT_QUIET;
+      break;

-       case 'q':
-         options |= OPT_QUIET;
-         break;
+    case 'r':
+      setsockopt (ping->ping_fd, SOL_SOCKET, SO_DONTROUTE, &one, sizeof (one));
+      break;

-       case 'l':
-         if (!is_root)
-           {
-             fprintf (stderr, "ping: option not allowed: --preload\n");
-             exit (1);
-           }
-         preload = strtoul (optarg, &p, 0);
-         if (*p || preload > INT_MAX)
-           {
-             fprintf (stderr, "ping: invalid preload value (%s)\n", optarg);
-             exit (1);
-           }
-         break;
+    case 's':
+      data_length = ping_cvt_number (arg, PING_MAX_DATALEN, 1);
+      break;

-       case 'f':
-         if (!is_root)
-           {
-             fprintf (stderr, "ping: option not allowed: --flood\n");
-             exit (1);
-           }
-         options |= OPT_FLOOD;
-         setbuf (stdout, (char *) NULL);
-         break;
+    case ARGP_KEY_NO_ARGS:
+      argp_error (state, "missing host operand");

-       default:
-         fprintf (stderr, "%c: not implemented\n", c);
-         exit (1);
-       }
+    default:
+      return ARGP_ERR_UNKNOWN;
    }

-  argc -= optind;
-  argv += optind;
-  if (argc == 0)
-    {
-      show_usage ();
-      exit (0);
-    }
+  return 0;
+}
+
+static struct argp argp = {argp_options, parse_opt, args_doc, doc};
+
+int
+main (int argc, char **argv)
+{
+  int index;
+  u_char pattern[16];
+
+  if (getuid () == 0)
+    is_root = true;
+
+  if ((ping = ping_init (0, getpid ())) == NULL)
+    error (EXIT_FAILURE, errno, NULL);
+
+  setsockopt (ping->ping_fd, SOL_SOCKET, SO_BROADCAST, (char *) &one,
+             sizeof (one));
+
+  /* Reset root privileges */
+  setuid (getuid ());
+
+  /* Parse command line */
+  argp_parse (&argp, argc, argv, 0, &index, NULL);
+
+  argc -= index;
+  argv += index;

  init_data_buffer (patptr, pattern_len);

@@ -410,10 +397,7 @@ ping_echo (int argc, char **argv)
  struct ping_stat ping_stat;

  if (options & OPT_FLOOD && options & OPT_INTERVAL)
-    {
-      fprintf (stderr, "ping: -f and -i incompatible options.\n");
-      return 2;
-    }
+    error (EXIT_FAILURE, 0, "-f and -i incompatible options");

  memset (&ping_stat, 0, sizeof (ping_stat));
  ping_stat.tmin = 999999999.0;
@@ -422,10 +406,7 @@ ping_echo (int argc, char **argv)
  ping->ping_closure = &ping_stat;

  if (ping_set_dest (ping, *argv))
-    {
-      fprintf (stderr, "ping: unknown host\n");
-      exit (1);
-    }
+    error (EXIT_FAILURE, 0, "unknown host %s", *argv);

  err = getnameinfo ((struct sockaddr *) &ping->ping_dest,
                     sizeof (ping->ping_dest), buffer,
@@ -439,9 +420,7 @@ ping_echo (int argc, char **argv)
      else
        errmsg = gai_strerror (err);

-      fprintf (stderr, "ping: getnameinfo: %s\n", errmsg);
-
-      exit (1);
+      error (EXIT_FAILURE, 0, "getnameinfo: %s", errmsg);
    }

  printf ("PING %s (%s): %d data bytes\n",
@@ -669,36 +648,6 @@ echo_finish ()
  exit (ping->ping_num_recv == 0);
}

-static void
-show_usage (void)
-{
-  printf ("\
-Usage: ping6 [OPTION]... [ADDRESS]...\n\
-\n\
-Informational options:\n\
-  -h, --help         display this help and exit\n\
-  -L, --license      display license and exit\n\
-  -V, --version      output version information and exit\n\
-Options valid for all request types:\n\
-  -c, --count N      stop after sending N packets (default: %d)\n\
-  -d, --debug        set the SO_DEBUG option\n\
-  -i, --interval N   wait N seconds between sending each packet\n\
-  -n, --numeric      do not resolve host addresses\n\
-  -r, --ignore-routing  send directly to a host on an attached network\n\
-Options valid for --echo requests:\n\
-* -f, --flood        flood ping \n\
-* -l, --preload N    send N packets as fast as possible before falling into\n\
-                     normal mode of behavior\n\
-  -p, --pattern PAT  fill ICMP packet with given pattern (hex)\n\
-  -q, --quiet        quiet output\n\
-  -s, --size N       set number of data octets to send\n\
-\n\
-Options marked with an * are available only to super-user\n\
-\n\
-report bugs to " PACKAGE_BUGREPORT ".\n\
-", DEFAULT_PING_COUNT);
-}
-
static PING *
ping_init (int type, int ident)
{
@@ -712,9 +661,8 @@ ping_init (int type, int ident)
  if (fd < 0)
    {
      if (errno == EPERM)
-       {
-         fprintf (stderr, "ping: ping must run as root\n");
-       }
+        error (EXIT_FAILURE, errno, NULL);
+
      return NULL;
    }

diff -urNp inetutils/ping/ping_address.c inetutils-build/ping/ping_address.c
--- inetutils/ping/ping_address.c       2006-10-21 20:54:20.000000000 +0530
+++ inetutils-build/ping/ping_address.c 2007-04-18 00:30:02.000000000 +0530
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2007 Free Software Foundation, Inc.

   This file is part of GNU Inetutils.

@@ -45,11 +45,12 @@
#include <ctype.h>
#include <errno.h>

-#include "getopt.h"
#include <icmp.h>
#include <ping.h>
#include <ping_impl.h>

+#include "ping_common.h"
+
static int recv_address (int code, void *closure,
                         struct sockaddr_in *dest, struct sockaddr_in *from,
                         struct ip *ip, icmphdr_t * icmp, int datalen);
@@ -70,10 +71,7 @@ ping_address (int argc, char **argv)
  ping_set_count (ping, 1);

  if (ping_set_dest (ping, *argv))
-    {
-      fprintf (stderr, "ping: unknown host\n");
-      exit (1);
-    }
+    error (EXIT_FAILURE, 0, "unknown host");

  printf ("PING %s (%s): sending address mask request\n",
          ping->ping_hostname, inet_ntoa (ping->ping_dest.sin_addr));
diff -urNp inetutils/ping/ping_common.c inetutils-build/ping/ping_common.c
--- inetutils/ping/ping_common.c        2006-10-21 20:54:20.000000000 +0530
+++ inetutils-build/ping/ping_common.c  2007-04-18 00:31:40.000000000 +0530
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2001, 2002, 2004, 2005, 2007
+   Free Software Foundation, Inc.

   This file is part of GNU Inetutils.

@@ -27,31 +28,27 @@
#include <stdio.h>
#include <xalloc.h>

+#include "ping_common.h"
+
extern unsigned char *data_buffer;
extern size_t data_length;

size_t
-ping_cvt_number (const char *optarg, size_t maxval, int allow_zero)
+ping_cvt_number (const char *arg, size_t maxval, int allow_zero)
{
  char *p;
  unsigned long int n;

-  n = strtoul (optarg, &p, 0);
+  n = strtoul (arg, &p, 0);
  if (*p)
-    {
-      fprintf (stderr, "Invalid value (`%s' near `%s')\n", optarg, p);
-      exit (1);
-    }
+    error (EXIT_FAILURE, 0, "invalid value (`%s' near `%s')", arg, p);
+
  if (n == 0 && !allow_zero)
-    {
-      fprintf (stderr, "Option value too small: %s\n", optarg);
-      exit (1);
-    }
+    error (EXIT_FAILURE, 0, "option value too small: %s", arg);
+
  if (maxval && n > maxval)
-    {
-      fprintf (stderr, "Option value too big: %s\n", optarg);
-      exit (1);
-    }
+    error (EXIT_FAILURE, 0, "option value too big: %s", arg);
+
  return n;
}

@@ -91,10 +88,8 @@ decode_pattern (const char *text, int *p
  for (i = 0; *text && i < *pattern_len; i++)
    {
      if (sscanf (text, "%2x%n", &c, &off) != 1)
-       {
-         fprintf (stderr, "ping: error in pattern near %s\n", text);
-         exit (1);
-       }
+        error (EXIT_FAILURE, 0, "error in pattern near %s", text);
+
      text += off;
    }
  *pattern_len = i;
@@ -142,23 +137,3 @@ nsqrt (double a, double prec)

  return x1;
}
-
-void
-show_license (void)
-{
-  static char license_text[] =
-    "   This program is free software; you can redistribute it and/or modify\n"
-    "   it under the terms of the GNU General Public License as published by\n"
-    "   the Free Software Foundation; either version 2, or (at your option)\n"
-    "   any later version.\n"
-    "\n"
-    "   This program is distributed in the hope that it will be useful,\n"
-    "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
-    "   GNU General Public License for more details.\n"
-    "\n"
-    "   You should have received a copy of the GNU General Public License\n"
-    "   along with this program; if not, write to the Free Software\n"
-    "   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n";
-  printf ("%s", license_text);
-}
diff -urNp inetutils/ping/ping_common.h inetutils-build/ping/ping_common.h
--- inetutils/ping/ping_common.h        2006-11-11 07:01:15.000000000 +0530
+++ inetutils-build/ping/ping_common.h  2007-04-18 00:42:31.000000000 +0530
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.

   This file is part of GNU Inetutils.

@@ -23,9 +23,7 @@ void tvsub (struct timeval *out, struct
double nabs (double a);
double nsqrt (double a, double prec);

-void show_license (void);
-
-size_t ping_cvt_number (const char *optarg, size_t maxval, int allow_zero);
+size_t ping_cvt_number (const char *arg, size_t maxval, int allow_zero);

void init_data_buffer (unsigned char *pat, int len);

diff -urNp inetutils/ping/ping_echo.c inetutils-build/ping/ping_echo.c
--- inetutils/ping/ping_echo.c  2006-10-21 20:54:20.000000000 +0530
+++ inetutils-build/ping/ping_echo.c    2007-04-18 00:33:07.000000000 +0530
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2004, 2007 Free Software Foundation, Inc.

   This file is part of GNU Inetutils.

@@ -78,10 +78,7 @@ ping_echo (int argc, char **argv)
  struct ping_stat ping_stat;

  if (options & OPT_FLOOD && options & OPT_INTERVAL)
-    {
-      fprintf (stderr, "ping: -f and -i incompatible options.\n");
-      return 2;
-    }
+    error (EXIT_FAILURE, 0, "-f and -i incompatible options");

  memset (&ping_stat, 0, sizeof (ping_stat));
  ping_stat.tmin = 999999999.0;
@@ -91,10 +88,7 @@ ping_echo (int argc, char **argv)
  ping_set_event_handler (ping, handler, &ping_stat);

  if (ping_set_dest (ping, *argv))
-    {
-      fprintf (stderr, "ping: unknown host\n");
-      exit (1);
-    }
+    error (EXIT_FAILURE, 0, "unknown host");

  if (options & OPT_RROUTE)
    {
@@ -105,14 +99,10 @@ ping_echo (int argc, char **argv)
      rspace[IPOPT_OFFSET] = IPOPT_MINOFF;
      if (setsockopt (ping->ping_fd, IPPROTO_IP,
                      IP_OPTIONS, rspace, sizeof (rspace)) < 0)
-       {
-         perror ("ping: record route");
-         exit (2);
-       }
+        error (EXIT_FAILURE, errno, NULL);
#else
-      fprintf (stderr,
-              "ping: record route not available in this implementation.\n");
-      exit (2);
+      error (EXIT_FAILURE, 0, "record route not available in this "
+             "implementation.");
#endif /* IP_OPTIONS */
    }

diff -urNp inetutils/ping/ping_impl.h inetutils-build/ping/ping_impl.h
--- inetutils/ping/ping_impl.h  2006-10-21 20:54:20.000000000 +0530
+++ inetutils-build/ping/ping_impl.h    2007-03-31 01:40:43.000000000 +0530
@@ -24,8 +24,6 @@ struct ping_stat

extern unsigned options;
extern PING *ping;
-extern int is_root;
-extern unsigned long preload;
extern u_char *data_buffer;
extern size_t data_length;

diff -urNp inetutils/ping/ping_timestamp.c inetutils-build/ping/ping_timestamp.c
--- inetutils/ping/ping_timestamp.c     2006-10-21 20:54:20.000000000 +0530
+++ inetutils-build/ping/ping_timestamp.c       2007-04-18 00:34:04.000000000 
+0530
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2002, 2007 Free Software Foundation, Inc.

   This file is part of GNU Inetutils.

@@ -44,11 +44,12 @@
#include <ctype.h>
#include <errno.h>

-#include "getopt.h"
#include <icmp.h>
#include <ping.h>
#include <ping_impl.h>

+#include "ping_common.h"
+
static int recv_timestamp (int code, void *closure,
                           struct sockaddr_in *dest, struct sockaddr_in *from,
                           struct ip *ip, icmphdr_t * icmp, int datalen);
@@ -66,11 +67,7 @@ ping_timestamp (int argc, char **argv)
  ping_set_packetsize (ping, 20);

  if (ping_set_dest (ping, *argv))
-    {
-      fprintf (stderr, "ping: unknown host\n");
-      exit (1);
-    }
-
+    error (EXIT_FAILURE, 0, "unknown host");

  printf ("PING %s (%s): sending timestamp requests\n",
          ping->ping_hostname, inet_ntoa (ping->ping_dest.sin_addr));


Happy hacking,
Debarshi
--
GPG key ID: 63D4A5A7
Key server: pgp.mit.edu

Attachment: ping-argp.diff
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]