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