Index: telnet/commands.c =================================================================== RCS file: /sources/inetutils/inetutils/telnet/commands.c,v retrieving revision 1.26 diff -u -p -r1.26 commands.c --- telnet/commands.c 21 May 2008 04:49:00 -0000 1.26 +++ telnet/commands.c 22 Aug 2008 13:14:09 -0000 @@ -94,6 +94,8 @@ # include #endif +#define MAX_BUF_SIZ 256 + char *hostname = 0; extern char *getenv (const char *); @@ -113,8 +115,8 @@ typedef struct int needconnect; /* Do we need to be connected to execute? */ } Command; -static char line[256]; -static char saveline[256]; +static char line[MAX_BUF_SIZ]; +static char saveline[MAX_BUF_SIZ]; static int margc; static char *margv[20]; @@ -128,7 +130,7 @@ makeargv (void) cp = line; if (*cp == '!') { /* Special case shell escape */ - strcpy (saveline, line); /* save for shell command */ + strncpy (saveline, line, MAX_BUF_SIZ); /* save for shell command */ *argp++ = "!"; /* No room in string to get this */ margc++; cp++; @@ -2448,7 +2450,7 @@ tn (int argc, char *argv[]) } if (argc < 2) { - strcpy (line, "open "); + strncpy (line, "open ", MAX_BUF_SIZ); printf ("(to) "); fgets (&line[strlen (line)], sizeof (line) - strlen (line), stdin); makeargv (); @@ -3012,14 +3014,14 @@ cmdrc (char *m1, char *m2) if (skiprc) return; - strcpy (m1save, m1); + strncpy (m1save, m1, 64); m1 = m1save; if (rcname == 0) { rcname = getenv ("HOME"); if (rcname) - strcpy (rcbuf, rcname); + strncpy (rcbuf, rcname, 128); else rcbuf[0] = '\0'; strcat (rcbuf, "/.telnetrc"); Index: telnet/externs.h =================================================================== RCS file: /sources/inetutils/inetutils/telnet/externs.h,v retrieving revision 1.13 diff -u -p -r1.13 externs.h --- telnet/externs.h 21 Oct 2006 15:24:19 -0000 1.13 +++ telnet/externs.h 22 Aug 2008 13:14:10 -0000 @@ -114,6 +114,7 @@ extern int errno; /* outside this world #endif /* !CRAY */ extern int autologin, /* Autologin enabled */ + family, /* IP family */ skiprc, /* Don't process the ~/.telnetrc file */ eight, /* use eight bit mode (binary in and/or out */ flushout, /* flush output */ @@ -152,6 +153,8 @@ extern cc_t echoc; /* Toggle local echo extern char *prompt; /* Prompt for command. */ +extern char *user; /* User for login. */ + extern char doopt[], dont[], will[], wont[], options[], /* All the little options */ *hostname; /* Who are we connected to? */ #ifdef ENCRYPTION 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 22 Aug 2008 13:14:14 -0000 @@ -30,11 +30,12 @@ #ifdef HAVE_CONFIG_H # include #endif +#include #include -#include #include +#include #include "ring.h" #include "externs.h" @@ -45,10 +46,17 @@ #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 +/* Exported from externs.h for argument parsing */ +int family; +char *user; + /* * Initialize variables. */ @@ -68,118 +76,226 @@ 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 () -{ - fprintf (stdout, USAGE, prompt); +ARGP_PROGRAM_DATA ("telnet", "2008", "FIXME unknown"); + +const char args_doc[] = "[HOST [PORT]]"; +const char doc[] = "TELNET protocol client."; - 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"); +/* 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}, #ifdef ENCRYPTION - puts ("\ - -x, --encrypt Encrypt the data stream, if possible"); + {"encrypt", 'x', NULL, 0, "Encrypt the data stream, if possible", GRP+1}, #endif - #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"); +#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}, #endif - #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"); +#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", 0, NULL, 0, NULL, GRP+3}, + {"noasynctty", 0, NULL, 0, NULL, GRP+3}, + {"noasyncnet", 0, NULL, 0, NULL, GRP+3}, #endif +#undef GRP + {NULL} +}; -#if defined (ENCRYPTION) || defined (AUTHENTICATION) || defined (TN3270) - putc ('\n', stdout); +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + 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 + autologin = 0; +#endif + break; + + case 'L': + eight |= 2; /* binary output only */ + break; + + case 'X': +#ifdef AUTHENTICATION + auth_disable_name (arg); #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) + { + fprintf (stderr, + "%s: Only one of -f and -F allowed.\n", prompt); + exit (0); + } + forward_flags |= OPTS_FORWARD_CREDS; +#else + fprintf (stderr, + "%s: Warning: -f ignored, no Kerberos V5 support.\n", + prompt); +#endif + break; - puts ("\ - --help Give this help list\n\ - -V, --version Print program version"); + 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); + exit (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; - fprintf (stdout, "\nSubmit bug reports to %s.\n", PACKAGE_BUGREPORT); + 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 + fprintf (stderr, + "%s: Warning: -k ignored, no Kerberos V4 support.\n", + prompt); +#endif + break; + + case 'l': + autologin = 1; + user = arg; + break; + + case 'n': + SetNetTrace (arg); + break; - exit (0); -} +#if defined(TN3270) && defined(unix) + case ARG_NOASYNCH: + noasynchtty = 1; + noasynchnet = 1; + break; + + case ARG_NOASYNCTTY: + noasynchtty = 1; + break; + + case ARG_NOASYNCNET: + noasynchnet = 1; + break; +#endif /* defined(TN3270) && defined(unix) */ -/* 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 'r': + rlogin = '~'; + break; -/* Print a usage message to STDERR and exit with a status of 1. */ -static void -usage () -{ - fprintf (stderr, USAGE, prompt); - try_help (); + case 't': +#if defined(TN3270) && defined(unix) + transcom = tline; + strncpy (transcom, arg, MAX_TLINE_BUF); +#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; + + 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; + int index = 0; #ifndef strrchr char *strrchr (); #endif @@ -203,185 +319,48 @@ main (int argc, char *argv[]) rlogin = (strncmp (prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE; autologin = -1; + + /* Parse command line */ + argp_parse (&argp, argc, argv, 0, &index, NULL); - 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; - - 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; + argc -= index; + argv += index; if (argc) { - 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); + } + *argptr++ = prompt; if (user) { - *argp++ = "-l"; - *argp++ = user; + *argptr++ = "-l"; + *argptr++ = user; } if (family == 4) - *argp++ = "-4"; + *argptr++ = "-4"; else if (family == 6) - *argp++ = "-6"; + *argptr++ = "-6"; - *argp++ = argv[0]; /* host */ + *argptr++ = argv[0]; /* host */ if (argc > 1) - *argp++ = argv[1]; /* port */ - *argp = 0; + *argptr++ = argv[1]; /* port */ + *argptr = 0; if (setjmp (toplevel) != 0) Exit (0); - if (tn (argp - args, args) == 1) + if (tn (argptr - args, args) == 1) return (0); else return (1);