From 18ebe7795927821d4dceedeeef50268c45636e17 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 7 Mar 2008 00:01:19 +0000 Subject: [PATCH] Merge revisions 1.10 and 1.11 from DragonFly: - Use real getopt() handling instead of the hand-rolled and IOCCC-worthy "Micro getopt()" macros, plus clean up to the option handling code: * Sort the options in the switch statement; * Plug piddling memory leaks when processing repeated options by freeing strings before allocating them for a second time; * Die with a fatal error if the requested report file cannot be opened for appending; * Don't call init() before usage() (to prevent the usage message being mangled by changes to the terminal settings;) - Clean up the usage message, both in usage() and in the main program comment, both stylistically (sort and combine options) and for accuracy (following the manual page, make note of the -s and -S flags, and use the term 'send' instead of 'say' to reduce confusion (SAY is the name of a command for output to the user, not the connection.)) Obtained from: DragonFly --- usr.bin/chat/chat.c | 129 +++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 68 deletions(-) diff --git a/usr.bin/chat/chat.c b/usr.bin/chat/chat.c index c0afeaf53689..056af3749f9d 100644 --- a/usr.bin/chat/chat.c +++ b/usr.bin/chat/chat.c @@ -105,17 +105,6 @@ __FBSDID("$FreeBSD$"); #define O_NONBLOCK O_NDELAY #endif -/*************** Micro getopt() *********************************************/ -#define OPTION(c,v) (_O&2&&**v?*(*v)++:!c||_O&4?0:(!(_O&1)&& \ - (--c,++v),_O=4,c&&**v=='-'&&v[0][1]?*++*v=='-'\ - &&!v[0][1]?(--c,++v,0):(_O=2,*(*v)++):0)) -#define OPTARG(c,v) (_O&2?**v||(++v,--c)?(_O=1,--c,*v++): \ - (_O=4,(char*)0):(char*)0) -#define ARG(c,v) (c?(--c,*v++):(char*)0) - -static int _O = 0; /* Internal state */ -/*************** Micro getopt() *********************************************/ - #define MAX_ABORTS 50 #define MAX_REPORTS 50 #define DEFAULT_CHAT_TIMEOUT 45 @@ -201,32 +190,44 @@ copy_of(char *s) } /* - * chat [ -v ] [-T number] [-U number] [ -t timeout ] [ -f chat-file ] \ - * [ -r report-file ] \ - * [...[[expect[-say[-expect...]] say expect[-say[-expect]] ...]]] + * chat [-esSvV] [-f chat-file] [-r report-file] [-t timeout] + * [-T phone-number] [-U phone-number2] [chat-script] + * where chat-script has the form: + * [...[[expect[-send[-expect...]] send expect[-send[-expect]] ...]]] * - * Perform a UUCP-dialer-like chat script on stdin and stdout. + * Perform a UUCP-dialer-like chat script on stdin and stdout. */ int main(int argc, char *argv[]) { int option; - char *arg; tzset(); - while ((option = OPTION(argc, argv)) != 0) { + while ((option = getopt(argc, argv, "ef:r:sSt:T:U:vV")) != -1) { switch (option) { case 'e': ++echo; break; - case 'v': - ++verbose; + case 'f': + if (chat_file != NULL) + free(chat_file); + chat_file = copy_of(optarg); break; - case 'V': - ++Verbose; + case 'r': + if (report_fp != NULL) + fclose(report_fp); + if (report_file != NULL) + free(report_file); + report_file = copy_of(optarg); + report_fp = fopen(report_file, "a"); + if (report_fp != NULL) { + if (verbose) + fprintf(report_fp, "Opening \"%s\"...\n", report_file); + } else + fatal(2, "cannot open \"%s\" for appending", report_file); break; case 's': @@ -237,47 +238,28 @@ main(int argc, char *argv[]) to_log = 0; break; - case 'f': - if ((arg = OPTARG(argc, argv)) != NULL) - chat_file = copy_of(arg); - else - usage(); - break; - case 't': - if ((arg = OPTARG(argc, argv)) != NULL) - timeout = atoi(arg); - else - usage(); - break; - - case 'r': - arg = OPTARG (argc, argv); - if (arg) { - if (report_fp != NULL) - fclose (report_fp); - report_file = copy_of (arg); - report_fp = fopen (report_file, "a"); - if (report_fp != NULL) { - if (verbose) - fprintf (report_fp, "Opening \"%s\"...\n", - report_file); - } - } + timeout = atoi(optarg); break; case 'T': - if ((arg = OPTARG(argc, argv)) != NULL) - phone_num = copy_of(arg); - else - usage(); + if (phone_num != NULL) + free(phone_num); + phone_num = copy_of(optarg); break; case 'U': - if ((arg = OPTARG(argc, argv)) != NULL) - phone_num2 = copy_of(arg); - else - usage(); + if (phone_num2 != NULL) + free(phone_num2); + phone_num2 = copy_of(optarg); + break; + + case 'v': + ++verbose; + break; + + case 'V': + ++Verbose; break; default: @@ -285,6 +267,10 @@ main(int argc, char *argv[]) break; } } + + argc -= optind; + argv += optind; + /* * Default the report file to the stderr location */ @@ -300,20 +286,25 @@ main(int argc, char *argv[]) setlogmask(LOG_UPTO(LOG_WARNING)); } - init(); - if (chat_file != NULL) { - arg = ARG(argc, argv); - if (arg != NULL) + if (*argv != NULL) usage(); - else - do_file (chat_file); + else { + init(); + do_file(chat_file); + } } else { - while ((arg = ARG(argc, argv)) != NULL) { - chat_expect(arg); + init(); + while (*argv != NULL && argc > 0) { + chat_expect(*argv); + argv++; + argc--; - if ((arg = ARG(argc, argv)) != NULL) - chat_send(arg); + if (*argv != NULL && argc > 0) { + chat_send(*argv); + argv++; + argc--; + } } } @@ -397,9 +388,11 @@ do_file(char *chatfile) static void usage(void) { - fprintf(stderr, "\ -Usage: chat [-e] [-v] [-V] [-t timeout] [-r report-file] [-T phone-number]\n\ - [-U phone-number2] {-f chat-file | chat-script}\n"); + fprintf(stderr, + "Usage: chat [-esSvV] [-f chat-file] [-r report-file] [-t timeout]\n" + " [-T phone-number] [-U phone-number2] [chat-script]\n" + "where chat-script has the form:\n" + " [...[[expect[-send[-expect...]] send expect[-send[-expect]] ...]]]\n"); exit(1); }