]> git.ozlabs.org Git - ppp.git/blobdiff - chat/chat.c
Forgot to remote *.ln files (made by lint) when doing make clean.
[ppp.git] / chat / chat.c
index 90dcc5be837cac3787c77d9fc5fe66c1bd858699..02fa4499439911ff3d39809f966c01a0f5de15fb 100644 (file)
  *     This software is in the public domain.
  *
  * -----------------
+ *     22-May-99 added environment substitutuion, enabled with -E switch.
+ *     Andreas Arens <andras@cityweb.de>.
+ *
+ *     12-May-99 added a feature to read data to be sent from a file,
+ *     if the send string starts with @.  Idea from gpk <gpk@onramp.net>.
+ *
  *     added -T and -U option and \T and \U substitution to pass a phone
  *     number into chat script. Two are needed for some ISDN TA applications.
  *     Keith Dart <kdart@cisco.com>
  *             Columbus, OH  43221
  *             (614)451-1883
  *
- *
  */
 
+#ifndef __STDC__
+#define const
+#endif
+
 #ifndef lint
-static char rcsid[] = "$Id: chat.c,v 1.18 1998/02/04 01:35:49 paulus Exp $";
+static const char rcsid[] = "$Id: chat.c,v 1.25 1999/09/06 05:10:23 paulus Exp $";
 #endif
 
 #include <stdio.h>
@@ -163,6 +172,7 @@ int to_stderr     = 0;
 int Verbose       = 0;
 int quiet         = 0;
 int report        = 0;
+int use_env       = 0;
 int exit_code     = 0;
 FILE* report_fp   = (FILE *) 0;
 char *report_file = (char *) 0;
@@ -251,7 +261,7 @@ char *s;
 }
 
 /*
- * chat [ -v ] [-T number] [-U number] [ -t timeout ] [ -f chat-file ] \
+ * chat [ -v ] [ -E ] [ -T number ] [ -U number ] [ -t timeout ] [ -f chat-file ] \
  * [ -r report-file ] \
  *             [...[[expect[-say[-expect...]] say expect[-say[-expect]] ...]]]
  *
@@ -274,6 +284,10 @@ main(argc, argv)
            ++echo;
            break;
 
+       case 'E':
+           ++use_env;
+           break;
+
        case 'v':
            ++verbose;
            break;
@@ -455,8 +469,8 @@ char *chat_file;
 void usage()
 {
     fprintf(stderr, "\
-Usage: %s [-e] [-v] [-t timeout] [-r report-file] [-T phone-number]\n\
-     [-U phone-number2] {-f chat-file | chat-script}\n", program_name);
+Usage: %s [-e] [-E] [-v] [-V] [-t timeout] [-r report-file]\n\
+     [-T phone-number] [-U phone-number2] {-f chat-file | chat-script}\n", program_name);
     exit(1);
 }
 
@@ -606,27 +620,32 @@ void break_sequence()
 void terminate(status)
 int status;
 {
+    static int terminating = 0;
+
+    if (terminating)
+       exit(status);
+    terminating = 1;
     echo_stderr(-1);
-    if (report_file != (char *) 0 && report_fp != (FILE *) NULL) {
 /*
  * Allow the last of the report string to be gathered before we terminate.
  */
-       if (report_gathering) {
-           int c, rep_len;
+    if (report_gathering) {
+       int c, rep_len;
 
-           rep_len = strlen(report_buffer);
-           while (rep_len + 1 <= sizeof(report_buffer)) {
-               alarm(1);
-               c = get_char();
-               alarm(0);
-               if (c < 0 || iscntrl(c))
-                   break;
-               report_buffer[rep_len] = c;
-               ++rep_len;
-           }
-           report_buffer[rep_len] = 0;
-           fprintf (report_fp, "chat:  %s\n", report_buffer);
+       rep_len = strlen(report_buffer);
+       while (rep_len + 1 <= sizeof(report_buffer)) {
+           alarm(1);
+           c = get_char();
+           alarm(0);
+           if (c < 0 || iscntrl(c))
+               break;
+           report_buffer[rep_len] = c;
+           ++rep_len;
        }
+       report_buffer[rep_len] = 0;
+       fprintf (report_fp, "chat:  %s\n", report_buffer);
+    }
+    if (report_file != (char *) 0 && report_fp != (FILE *) NULL) {
        if (verbose)
            fprintf (report_fp, "Closing \"%s\".\n", report_file);
        fclose (report_fp);
@@ -650,10 +669,14 @@ char *clean(s, sending)
 register char *s;
 int sending;  /* set to 1 when sending (putting) this string. */
 {
-    char temp[STR_LEN], cur_chr;
+    char temp[STR_LEN], env_str[STR_LEN], cur_chr;
     register char *s1, *phchar;
     int add_return = sending;
-#define isoctal(chr) (((chr) >= '0') && ((chr) <= '7'))
+#define isoctal(chr)   (((chr) >= '0') && ((chr) <= '7'))
+#define isalnumx(chr)  ((((chr) >= '0') && ((chr) <= '9')) \
+                        || (((chr) >= 'a') && ((chr) <= 'z')) \
+                        || (((chr) >= 'A') && ((chr) <= 'Z')) \
+                        || (chr) == '_')
 
     s1 = temp;
     while (*s) {
@@ -670,6 +693,18 @@ int sending;  /* set to 1 when sending (putting) this string. */
            }
            continue;
        }
+       
+       if (use_env && cur_chr == '$') {                /* ARI */
+           phchar = env_str;
+           while (isalnumx(*s))
+               *phchar++ = *s++;
+           *phchar = '\0';
+           phchar = getenv(env_str);
+           if (phchar)
+               while (*phchar)
+                   *s1++ = *phchar++;
+           continue;
+       }
 
        if (cur_chr != '\\') {
            *s1++ = cur_chr;
@@ -703,13 +738,12 @@ int sending;  /* set to 1 when sending (putting) this string. */
        case 'd':
            if (sending)
                *s1++ = '\\';
-
            *s1++ = cur_chr;
            break;
 
        case 'T':
            if (sending && phone_num) {
-               for ( phchar = phone_num; *phchar != '\0'; phchar++) 
+               for (phchar = phone_num; *phchar != '\0'; phchar++) 
                    *s1++ = *phchar;
            }
            else {
@@ -720,7 +754,7 @@ int sending;  /* set to 1 when sending (putting) this string. */
 
        case 'U':
            if (sending && phone_num2) {
-               for ( phchar = phone_num2; *phchar != '\0'; phchar++) 
+               for (phchar = phone_num2; *phchar != '\0'; phchar++) 
                    *s1++ = *phchar;
            }
            else {
@@ -758,6 +792,13 @@ int sending;  /* set to 1 when sending (putting) this string. */
                *s1++ = 'N';
            break;
            
+       case '$':                       /* ARI */
+           if (use_env) {
+               *s1++ = cur_chr;
+               break;
+           }
+           /* FALL THROUGH */
+
        default:
            if (isoctal (cur_chr)) {
                cur_chr &= 0x07;
@@ -966,9 +1007,11 @@ int c;
 void chat_send (s)
 register char *s;
 {
+    char file_data[STR_LEN];
+
     if (say_next) {
        say_next = 0;
-       s = clean(s,0);
+       s = clean(s, 1);
        write(2, s, strlen(s));
         free(s);
        return;
@@ -1104,6 +1147,43 @@ register char *s;
        return;
     }
 
+    /*
+     * The syntax @filename means read the string to send from the
+     * file `filename'.
+     */
+    if (s[0] == '@') {
+       /* skip the @ and any following white-space */
+       char *fn = s;
+       while (*++fn == ' ' || *fn == '\t')
+           ;
+
+       if (*fn != 0) {
+           FILE *f;
+           int n = 0;
+
+           /* open the file and read until STR_LEN-1 bytes or end-of-file */
+           f = fopen(fn, "r");
+           if (f == NULL)
+               fatal(1, "%s -- open failed: %m", fn);
+           while (n < STR_LEN - 1) {
+               int nr = fread(&file_data[n], 1, STR_LEN - 1 - n, f);
+               if (nr < 0)
+                   fatal(1, "%s -- read error", fn);
+               if (nr == 0)
+                   break;
+               n += nr;
+           }
+           fclose(f);
+
+           /* use the string we got as the string to send,
+              but trim off the final newline if any. */
+           if (n > 0 && file_data[n-1] == '\n')
+               --n;
+           file_data[n] = 0;
+           s = file_data;
+       }
+    }
+
     if (strcmp(s, "EOT") == 0)
        s = "^D\\c";
     else if (strcmp(s, "BREAK") == 0)
@@ -1414,6 +1494,16 @@ register char *string;
     return (0);
 }
 
+/*
+ * Gross kludge to handle Solaris versions >= 2.6 having usleep.
+ */
+#ifdef SOL2
+#include <sys/param.h>
+#if MAXUID > 65536             /* then this is Solaris 2.6 or later */
+#undef NO_USLEEP
+#endif
+#endif /* SOL2 */
+
 #ifdef NO_USLEEP
 #include <sys/types.h>
 #include <sys/time.h>