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
This commit is contained in:
Xin LI 2008-03-07 00:01:19 +00:00
parent e5ad5f4d70
commit 18ebe77959
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=176888

View file

@ -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);
}