On Sat, 2008-08-23 at 05:09 -0400, Alfred M. Szmidt wrote: 
> telnet/commands.c:
> 
>          * Changed some strcpy() to strncpy ()
>          * Defined MAX_BUF_SIZ
> 
> This should be split up into a seperate patch, since it has nothing to
> do with argp.  I am also not sure why this is needed, strcpy from a
> quick glance is just fine here.
Reverted, file is unchanged. 
> 
>    telnet/externs.h:
> 
>          * declare 'family' and 'user' as extern among other argument
>          values
> 
> Why?
Reverted, file is unchanged. Those variables moved to parse_opt(). 
> 
>    -      char *args[8], **argp = args;
>    -
>    +      char *args[8], **argptr = args;
>    +      
>    +      /* FIXME: We should proabably move all
>    +       * argument parsinsg to 'parse_opt ()'. */
>         if (argc > 2)
>    -  usage ();
>    -      *argp++ = prompt;
>    +      {
>    +  /* XXX: using this, we simulate,
>    +   * argp_usage (), without a 'state' */
>    +  argp_help (&argp, stderr, ARGP_HELP_USAGE, "telnet");
>    +  exit (argp_err_exit_status);
>    +      }
> 
> Please try to fix the two FIXME's.
> 
Fixed.


        * telnet/main.c: Include <argp.h> and
<libinetutils/libinetutils.h>.
        Remove include for <getopt.h>.
        (MAX_TLINE_BUF): New macro.
        (cmd_args): New data structure.
        (ARGP_PROGRAM_DATA): Call macro.
        (argp, args_doc, doc, argp_options): New variables.
        (parse_opt): New function.
        (help, try_help, usage): Functions removed.
        (long_options): Variables removed.
        (args, argp): Variables removed.
        (main): Use strncpy () instead of strcpy for copying command
line
        args. Use argp to parse program options. Moved all of secondary
        argumetn parsing to parse_opt.



Updated patch is attached.
Index: telnet/main.c
===================================================================
RCS file: /sources/inetutils/inetutils/telnet/main.c,v
retrieving revision 1.17
diff -u -p -r1.17 main.c
--- telnet/main.c	21 Oct 2006 18:08:45 -0000	1.17
+++ telnet/main.c	29 Aug 2008 16:23:12 -0000
@@ -30,11 +30,12 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
+#include <libinetutils.h>
 
 #include <sys/types.h>
 
-#include <getopt.h>
 #include <stdlib.h>
+#include <argp.h>
 
 #include "ring.h"
 #include "externs.h"
@@ -45,6 +46,9 @@
 #define OPTS_FORWARD_CREDS           0x00000002
 #define OPTS_FORWARDABLE_CREDS       0x00000001
 
+/* Based on buffer size for 'tline' in tn3270.c */
+#define MAX_TLINE_BUF 200
+
 #if 0
 # define FORWARD
 #endif
@@ -68,118 +72,268 @@ tninit ()
 #endif
 }
 
-#define USAGE "Usage: %s [OPTION...] [HOST [PORT]]\n"
 
-/* Print a help message describing all options to STDOUT and exit with a
-   status of 0.  */
-static void
-help ()
+struct _cmd_args
 {
-  fprintf (stdout, USAGE, prompt);
+  char *argv[8];
+  char **argptr;
+};
+typedef struct _cmd_args cmd_args;
 
-  puts ("Login to remote system HOST (optionally, on service port PORT)\n\n\
-  -4, --ipv4                 Use only IPv4\n\
-  -6, --ipv6                 Use only IPv6\n\
-  -8, --binary               Use an 8-bit data path\n\
-  -a, --login                Attempt automatic login\n\
-  -c, --no-rc                Don't read the user's .telnetrc file\n\
-  -d, --debug                Turn on debugging\n\
-  -e CHAR, --escape=CHAR     Use CHAR as an escape character\n\
-  -E, --no-escape            Use no escape character\n\
-  -K, --no-login             Don't automatically login to the remote system\n\
-  -l USER, --user=USER       Attempt automatic login as USER\n\
-  -L, --binary-output        Use an 8-bit data path for output only\n\
-  -n FILE, --trace=FILE      Record trace information into FILE\n\
-  -r, --rlogin               Use a user-interface similar to rlogin\n\
-  -X ATYPE, --disable-auth=ATYPE   Disable type ATYPE authentication");
-
-#ifdef ENCRYPTION
-  puts ("\
-  -x, --encrypt              Encrypt the data stream, if possible");
-#endif
+ARGP_PROGRAM_DATA ("telnet", "2008", "FIXME unknown");
+
+const char args_doc[] = "[HOST [PORT]]";
+const char doc[] = "TELNET protocol client.";
+
+/* Define keys for long options that do not have short counterparts. */
+enum {
+  ARG_NOASYNCH = 256,
+  ARG_NOASYNCTTY,
+  ARG_NOASYNCNET
+};
+
+static struct argp_option argp_options[] = {
+#define GRP 0
+  {"debug", 'd', NULL, 0, "Turn on debugging", GRP+1},
+  {"ipv4", '4', NULL, 0, "Use only IPv4", GRP+1},
+  {"ipv6", '6', NULL, 0, "Use only IPv6", GRP+1},
+  {"binary", '8', NULL, 0, "Use an 8-bit data path", GRP+1},
+  {"login", 'a', NULL, 0, "Attempt automatic login", GRP+1},
+  {"no-rc", 'c', NULL, 0, "Don't read the user's .telnetrc file", GRP+1},
+  {"escape", 'e', "CHAR", 0, "Use CHAR as an escape character", GRP+1},
+  {"no-escape", 'E', NULL, 0, "Use no escape character", GRP+1},
+  {"no-login", 'K', NULL, 0, "Don't automatically login to the remote system",
+    GRP+1},
+  {"user", 'l', "USER", 0, "Attempt automatic login as USER", GRP+1},
+  {"binary-output", 'L', NULL, 0, "Use an 8-bit data path for output only",
+    GRP+1},
+  {"trace", 'n', "FILE", 0, "Record trace information into FILE", GRP+1},
+  {"rlogin", 'r', NULL, 0, "Use a user-interface similar to rlogin", GRP+1},
+  {"disable-auth", 'X', "ATYPE", 0, "Disable type ATYPE authentication", GRP+1},
+  {"encrypt", 'x', NULL, 0, "Encrypt the data stream, if possible", GRP+1},
+#undef GRP
+#define GRP 10
+  {NULL, 0, NULL, 0, "When using Kerberos authentication:", GRP},
+  {"fwd-credentials", 'f', NULL, 0, "Allow the the local credentials to be"
+    " forwarded", GRP+2},
+  {"realm", 'k', "REALM", 0, "Obtain tickets for the remote host in REALM"
+    " instead of the remote host's realm", GRP+2},
+#undef GRP
+#define GRP 20
+  {NULL, 0, NULL, 0, "TN3270 options:", GRP},
+  {"transcom", 't', "LINE", 0, "Encrypt the data stream, if possible", GRP+3},
+  {"noasynch", ARG_NOASYNCH, NULL, 0, NULL, GRP+3},
+  {"noasynctty", ARG_NOASYNCTTY, NULL, 0, NULL, GRP+3},
+  {"noasyncnet", ARG_NOASYNCNET, NULL, 0, NULL, GRP+3},
+#undef GRP
+  {NULL}
+};
 
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  static int family;
+  static char *user;
+  static cmd_args *c_args;
+  
+  c_args = (cmd_args*) (state->input);
+
+  switch (key)
+  {
+    case '4':
+      family = 4;
+      break;
+
+    case '6':
+      family = 6;
+      break;
+		
+    case '8':
+      eight = 3;		/* binary output and input */
+      break;
+		
+    case 'E':
+      rlogin = escape = _POSIX_VDISABLE;
+      break;
+		
+    case 'K':
 #ifdef AUTHENTICATION
-  puts ("\n\
- When using Kerberos authentication:\n\
-  -f, --fwd-credentials      Allow the the local credentials to be forwarded\n\
-  -k REALM, --realm=REALM    Obtain tickets for the remote host in REALM\n\
-                             instead of the remote host's realm");
+      autologin = 0;
+#else
+      argp_error (state, "'-%c' is currently not supported on this machine.",
+	  key);
 #endif
+      break;
+		
+    case 'L':
+      eight |= 2;		/* binary output only */
+      break;
+		
+    case 'X':
+#ifdef AUTHENTICATION
+      auth_disable_name (arg);
+#else
+      argp_error (state, "'-%c' is currently not supported on this machine.",
+	  key);
+#endif
+      break;
+		
+    case 'a':
+      autologin = 1;
+      break;
+		
+    case 'c':
+      skiprc = 1;
+      break;
+		
+    case 'd':
+      debug = 1;
+      break;
+		
+    case 'e':
+      set_escape_char (arg);
+      break;
+		
+    case 'f':
+#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
+      if (forward_flags & OPTS_FORWARD_CREDS)
+	argp_error (state, "%s: Only one of -f and -F allowed.\n", prompt);
+      forward_flags |= OPTS_FORWARD_CREDS;
+#else
+      argp_error (state, "'-%c' is currently not supported on this machine.",
+	  key);
+#endif
+      break;
 
+    case 'F':
+#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
+      if (forward_flags & OPTS_FORWARD_CREDS)
+	argp_error (state, "%s: Only one of -f and -F allowed.\n", prompt);
+      forward_flags |= OPTS_FORWARD_CREDS;
+      forward_flags |= OPTS_FORWARDABLE_CREDS;
+#else
+      argp_error (state, "'-%c' is currently not supported on this machine.",
+	  key);
+#endif
+      break;
+
+    case 'k':
+#if defined(AUTHENTICATION) && defined(KRB4)
+      {
+	extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
+	dest_realm = dst_realm_buf;
+	strncpy (dest_realm, arg, dst_realm_sz);
+      }
+#else
+      argp_error (state, "'-%c' is currently not supported on this machine.",
+	  key);
+#endif
+      break;
+
+    case 'l':
+      autologin = 1;
+      user = arg;
+      break;
+
+    case 'n':
+      SetNetTrace (arg);
+      break;
+
+    case ARG_NOASYNCH:
 #if defined(TN3270) && defined(unix)
-  puts ("\n\
- TN3270 options (note non-standard option syntax):\n\
-      -noasynch\n\
-      -noasynctty\n\
-      -noasyncnet\n\
-  -t LINE, --transcom=LINE");
+      noasynchtty = 1;
+      noasynchnet = 1;
+#else
+      argp_error (state, "'--noasynch' is currently not supported"
+	  " on this machine.");
 #endif
+      break;
 
-#if defined (ENCRYPTION) || defined (AUTHENTICATION) || defined (TN3270)
-  putc ('\n', stdout);
+    case ARG_NOASYNCTTY:
+#if defined(TN3270) && defined(unix)
+      noasynchtty = 1;
+#else
+      argp_error (state, "'--noasynctty' is currently not supported"
+	  " on this machine.");
 #endif
+      break;
 
-  puts ("\
-      --help                 Give this help list\n\
-  -V, --version              Print program version");
+    case ARG_NOASYNCNET:
+#if defined(TN3270) && defined(unix)
+      noasynchnet = 1;
+#else
+      argp_error (state, "'--noasyncnet' is currently not supported"
+	  " on this machine.");
+      break;
+#endif
 
-  fprintf (stdout, "\nSubmit bug reports to %s.\n", PACKAGE_BUGREPORT);
+    case 'r':
+      rlogin = '~';
+      break;
 
-  exit (0);
-}
+    case 't':
+#if defined(TN3270) && defined(unix)
+      transcom = tline;
+      strncpy (transcom, arg, MAX_TLINE_BUF);
+#else
+      argp_error (state, "'-%c' is currently not supported on this machine.",
+	  key);
+#endif
+      break;
 
-/* Print a message saying to use --help to STDERR, and exit with a status of
-   1.  */
-static void
-try_help ()
-{
-  fprintf (stderr, "Try `%s --help' for more information.\n", prompt);
-  exit (1);
-}
+    case 'x':
+#ifdef	ENCRYPTION
+      encrypt_auto (1);
+      decrypt_auto (1);
+#else /* ENCRYPTION */
+      argp_error (state, "'-%c' is currently not supported on this machine.",
+	  key);
+#endif /* ENCRYPTION */
+      break;
 
-/* Print a usage message to STDERR and exit with a status of 1.  */
-static void
-usage ()
-{
-  fprintf (stderr, USAGE, prompt);
-  try_help ();
+    case ARGP_KEY_ARG:
+      if (state->arg_num == 0)
+	/* More than 2 arguments */
+	if ((state->argc - state->next) > 1)
+	  argp_usage (state);
+      
+      if (user)
+      {
+	*(c_args->argptr)++ = "-l";
+	*(c_args->argptr)++ = user;
+      }
+      if (family == 4)
+	*(c_args->argptr)++ = "-4";
+      else if (family == 6)
+	*(c_args->argptr)++ = "-6";
+
+      *(c_args->argptr)++ = arg;	/* host */
+      if (state->argc - state->next)
+	*(c_args->argptr)++ = state->argv[state->next];	/* port */
+
+      *(c_args->argptr) = NULL;
+
+      /* Froce argp to stop processing remaining args,
+       * as we've got them all. */
+      state->next = state->argc;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+  }
+  
+  return 0;
 }
 
-static struct option long_options[] = {
-  {"ipv4", no_argument, 0, '4'},
-  {"ipv6", no_argument, 0, '6'},
-  {"binary", no_argument, 0, '8'},
-  {"login", no_argument, 0, 'a'},
-  {"no-rc", no_argument, 0, 'c'},
-  {"debug", no_argument, 0, 'd'},
-  {"escape", required_argument, 0, 'e'},
-  {"no-escape", no_argument, 0, 'E'},
-  {"no-login", no_argument, 0, 'K'},
-  {"user", required_argument, 0, 'l'},
-  {"binary-output", no_argument, 0, 'L'},
-  {"trace", required_argument, 0, 'n'},
-  {"rlogin", no_argument, 0, 'r'},
-  {"disable-auth", required_argument, 0, 'X'},
-  {"encrypt", no_argument, 0, 'x'},
-  {"fwd-credentials", no_argument, 0, 'f'},
-  {"realm", required_argument, 0, 'k'},
-  {"transcom", required_argument, 0, 't'},
-  {"help", no_argument, 0, '&'},
-  {"version", no_argument, 0, 'V'},
-  {0}
-};
-
+static struct argp argp = {argp_options, parse_opt, args_doc, doc};
+
 /*
  * main.  Parse arguments, invoke the protocol or command parser.
  */
 int
 main (int argc, char *argv[])
 {
-  extern char *optarg;
-  extern int optind;
-  int ch;
-  int family = 0;
-  char *user;
+  cmd_args c_args = {0};
 #ifndef strrchr
   char *strrchr ();
 #endif
@@ -199,189 +353,23 @@ main (int argc, char *argv[])
   else
     prompt = argv[0];
 
-  user = NULL;
-
   rlogin = (strncmp (prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
   autologin = -1;
 
-  while ((ch = getopt_long (argc, argv, "468EKLS:X:acde:fFk:l:n:rt:x",
-			    long_options, 0)) != EOF)
-    {
-      switch (ch)
-	{
-	case '4':
-	  family = 4;
-	  break;
-
-	case '6':
-	  family = 6;
-	  break;
-
-	case '8':
-	  eight = 3;		/* binary output and input */
-	  break;
-	case 'E':
-	  rlogin = escape = _POSIX_VDISABLE;
-	  break;
-	case 'K':
-#ifdef	AUTHENTICATION
-	  autologin = 0;
-#endif
-	  break;
-	case 'L':
-	  eight |= 2;		/* binary output only */
-	  break;
-	case 'X':
-#ifdef	AUTHENTICATION
-	  auth_disable_name (optarg);
-#endif
-	  break;
-	case 'a':
-	  autologin = 1;
-	  break;
-	case 'c':
-	  skiprc = 1;
-	  break;
-	case 'd':
-	  debug = 1;
-	  break;
-	case 'e':
-	  set_escape_char (optarg);
-	  break;
-	case 'f':
-#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
-	  if (forward_flags & OPTS_FORWARD_CREDS)
-	    {
-	      fprintf (stderr,
-		       "%s: Only one of -f and -F allowed.\n", prompt);
-	      help (0);
-	    }
-	  forward_flags |= OPTS_FORWARD_CREDS;
-#else
-	  fprintf (stderr,
-		   "%s: Warning: -f ignored, no Kerberos V5 support.\n",
-		   prompt);
-#endif
-	  break;
-	case 'F':
-#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
-	  if (forward_flags & OPTS_FORWARD_CREDS)
-	    {
-	      fprintf (stderr,
-		       "%s: Only one of -f and -F allowed.\n", prompt);
-	      help (0);
-	    }
-	  forward_flags |= OPTS_FORWARD_CREDS;
-	  forward_flags |= OPTS_FORWARDABLE_CREDS;
-#else
-	  fprintf (stderr,
-		   "%s: Warning: -F ignored, no Kerberos V5 support.\n",
-		   prompt);
-#endif
-	  break;
-	case 'k':
-#if defined(AUTHENTICATION) && defined(KRB4)
-	  {
-	    extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
-	    dest_realm = dst_realm_buf;
-	    strncpy (dest_realm, optarg, dst_realm_sz);
-	  }
-#else
-	  fprintf (stderr,
-		   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
-		   prompt);
-#endif
-	  break;
-	case 'l':
-	  autologin = 1;
-	  user = optarg;
-	  break;
-	case 'n':
-#if defined(TN3270) && defined(unix)
-	  /* distinguish between "-n oasynch" and "-noasynch" */
-	  if (argv[optind - 1][0] == '-' && argv[optind - 1][1]
-	      == 'n' && argv[optind - 1][2] == 'o')
-	    {
-	      if (!strcmp (optarg, "oasynch"))
-		{
-		  noasynchtty = 1;
-		  noasynchnet = 1;
-		}
-	      else if (!strcmp (optarg, "oasynchtty"))
-		noasynchtty = 1;
-	      else if (!strcmp (optarg, "oasynchnet"))
-		noasynchnet = 1;
-	    }
-	  else
-#endif /* defined(TN3270) && defined(unix) */
-	    SetNetTrace (optarg);
-	  break;
-	case 'r':
-	  rlogin = '~';
-	  break;
-	case 't':
-#if defined(TN3270) && defined(unix)
-	  transcom = tline;
-	  strcpy (transcom, optarg);
-#else
-	  fprintf (stderr,
-		   "%s: Warning: -t ignored, no TN3270 support.\n", prompt);
-#endif
-	  break;
-	case 'x':
-#ifdef	ENCRYPTION
-	  encrypt_auto (1);
-	  decrypt_auto (1);
-#else /* ENCRYPTION */
-	  fprintf (stderr,
-		   "%s: Warning: -x ignored, no ENCRYPT support.\n", prompt);
-#endif /* ENCRYPTION */
-	  break;
+  c_args.argptr = c_args.argv;
+  *(c_args.argptr)++ = prompt;
+  /* Parse command line */
+  argp_parse (&argp, argc, argv, 0, NULL, &c_args);
 
-	case '&':
-	  help ();
-	case 'V':
-	  printf ("telnet (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
-	  exit (0);
-
-	case '?':
-	  try_help ();
-
-	default:
-	  usage ();
-	}
-    }
   if (autologin == -1)
     autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
 
-  argc -= optind;
-  argv += optind;
-
-  if (argc)
+  /* We have command line args */
+  if ((c_args.argptr - c_args.argv) > 1)
     {
-      char *args[8], **argp = args;
-
-      if (argc > 2)
-	usage ();
-      *argp++ = prompt;
-      if (user)
-	{
-	  *argp++ = "-l";
-	  *argp++ = user;
-	}
-      if (family == 4)
-	*argp++ = "-4";
-      else if (family == 6)
-	*argp++ = "-6";
-
-      *argp++ = argv[0];	/* host */
-      if (argc > 1)
-	*argp++ = argv[1];	/* port */
-      *argp = 0;
-
       if (setjmp (toplevel) != 0)
 	Exit (0);
-      if (tn (argp - args, args) == 1)
+      if (tn (c_args.argptr - c_args.argv, c_args.argv) == 1)
 	return (0);
       else
 	return (1);
_______________________________________________
bug-inetutils mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-inetutils

Reply via email to