]> git.ozlabs.org Git - ppp.git/blobdiff - chat/chat.c
CI: Updated the 'checkout' actions that were using Node.js 16 to Node.js 20. (#489)
[ppp.git] / chat / chat.c
index 64d96c230bfcd943c28e9182711c7fbaee7d20ad..336c0f4995f4ab3dadd1612673d251ec0d3507d5 100644 (file)
@@ -182,7 +182,7 @@ int n_aborts = 0, abort_next = 0, timeout_next = 0, echo_next = 0;
 int clear_abort_next = 0;
 
 char *report_string[MAX_REPORTS] ;
-char  report_buffer[256] ;
+char  report_buffer[4096] ;
 int n_reports = 0, report_next = 0, report_gathering = 0 ; 
 int clear_report_next = 0;
 
@@ -198,7 +198,7 @@ SIGTYPE sigalrm (int signo);
 SIGTYPE sigint (int signo);
 SIGTYPE sigterm (int signo);
 SIGTYPE sighup (int signo);
-void unalarm (void);
+void checksigs(void);
 void init (void);
 void set_tty_parameters (void);
 int  echo_stderr (int);
@@ -215,7 +215,6 @@ char *character (int c);
 void chat_expect (register char *s);
 char *clean (register char *s, int sending);
 void break_sequence (void);
-void terminate (int status);
 void pack_array (char **array, int end);
 char *expect_strtok (char *, char *);
 int vfmtmsg (char *, int, const char *, va_list);      /* vsprintf++ */
@@ -347,16 +346,12 @@ main(int argc, char **argv)
        report_fp = stderr;
 
     if (to_log) {
-#ifdef ultrix
-       openlog("chat", LOG_PID);
-#else
        openlog("chat", LOG_PID | LOG_NDELAY, LOG_LOCAL2);
 
        if (verbose)
            setlogmask(LOG_UPTO(LOG_INFO));
        else
            setlogmask(LOG_UPTO(LOG_WARNING));
-#endif
     }
 
     init();
@@ -373,6 +368,7 @@ main(int argc, char **argv)
 
            if ((arg = ARG(argc, argv)) != NULL)
                chat_send(arg);
+           checksigs();
        }
     }
 
@@ -444,8 +440,10 @@ void do_file (char *chat_file)
            else
                chat_expect (arg);
            sendflg = !sendflg;
+           checksigs();
        }
     }
+    checksigs();
     fclose (cfp);
 }
 
@@ -499,59 +497,68 @@ void fatal(int code, const char *fmt, ...)
 }
 
 int alarmed = 0;
+int alarmsig = 0;
 
 SIGTYPE sigalrm(int signo)
 {
     int flags;
 
     alarm(1);
-    alarmed = 1;               /* Reset alarm to avoid race window */
-    signal(SIGALRM, sigalrm);  /* that can cause hanging in read() */
-
-    if ((flags = fcntl(0, F_GETFL, 0)) == -1)
-       fatal(2, "Can't get file mode flags on stdin: %m");
-
-    if (fcntl(0, F_SETFL, flags | O_NONBLOCK) == -1)
-       fatal(2, "Can't set file mode flags on stdin: %m");
-
-    if (verbose)
-       msgf("alarm");
+    alarmed = 1;
+    alarmsig = 1;
 }
 
-void unalarm(void)
-{
-    int flags;
-
-    if ((flags = fcntl(0, F_GETFL, 0)) == -1)
-       fatal(2, "Can't get file mode flags on stdin: %m");
-
-    if (fcntl(0, F_SETFL, flags & ~O_NONBLOCK) == -1)
-       fatal(2, "Can't set file mode flags on stdin: %m");
-}
+const char *fatalsig = NULL;
 
 SIGTYPE sigint(int signo)
 {
-    fatal(2, "SIGINT");
+    fatalsig = "SIGINT";
 }
 
 SIGTYPE sigterm(int signo)
 {
-    fatal(2, "SIGTERM");
+    fatalsig = "SIGTERM";
 }
 
 SIGTYPE sighup(int signo)
 {
-    fatal(2, "SIGHUP");
+    fatalsig = "SIGHUP";
+}
+
+void checksigs(void)
+{
+    int err;
+    const char *signame;
+
+    if (fatalsig) {
+       signame = fatalsig;
+       fatalsig = NULL;
+       alarmsig = 0;
+       fatal(2, signame);
+    }
+    if (alarmsig && verbose) {
+       err = errno;
+       msgf("alarm");
+       errno = err;
+       alarmsig = 0;
+    }
 }
 
 void init(void)
 {
-    signal(SIGINT, sigint);
-    signal(SIGTERM, sigterm);
-    signal(SIGHUP, sighup);
+    struct sigaction sa;
+
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_handler = sigint;
+    sigaction(SIGINT, &sa, NULL);
+    sa.sa_handler = sigterm;
+    sigaction(SIGTERM, &sa, NULL);
+    sa.sa_handler = sighup;
+    sigaction(SIGHUP, &sa, NULL);
 
     set_tty_parameters();
-    signal(SIGALRM, sigalrm);
+    sa.sa_handler = sigalrm;
+    sigaction(SIGALRM, &sa, NULL);
     alarm(0);
     alarmed = 0;
 }
@@ -602,7 +609,7 @@ void terminate(int status)
        int c, rep_len;
 
        rep_len = strlen(report_buffer);
-       while (rep_len + 1 <= sizeof(report_buffer)) {
+       while (rep_len + 1 < sizeof(report_buffer)) {
            alarm(1);
            c = get_char();
            alarm(0);
@@ -945,6 +952,7 @@ void chat_expect (char *s)
            break;
 
        chat_send (reply);
+       checksigs();
     }
 
 /*
@@ -987,6 +995,7 @@ int chat_send (register char *s)
 {
     char file_data[STR_LEN];
     int len, ret = 0;
+    struct sigaction sa;
 
     if (say_next) {
        say_next = 0;
@@ -999,10 +1008,13 @@ int chat_send (register char *s)
 
     if (hup_next) {
         hup_next = 0;
+       memset(&sa, 0, sizeof(sa));
+
        if (strcmp(s, "OFF") == 0)
-           signal(SIGHUP, SIG_IGN);
+           sa.sa_handler = SIG_IGN;
         else
-           signal(SIGHUP, sighup);
+           sa.sa_handler = sighup;
+       sigaction(SIGHUP, &sa, NULL);
         return 0;
     }
 
@@ -1121,7 +1133,7 @@ int chat_send (register char *s)
 
        if (verbose)
            msgf("timeout set to %d seconds", timeout);
-
+       free(s);
        return 0;
     }
 
@@ -1179,6 +1191,7 @@ int get_char(void)
     char c;
 
     status = read(0, &c, 1);
+    checksigs();
 
     switch (status) {
     case 1:
@@ -1188,12 +1201,6 @@ int get_char(void)
        msgf("warning: read() on stdin returned %d", status);
 
     case -1:
-       if ((status = fcntl(0, F_GETFL, 0)) == -1)
-           fatal(2, "Can't get file mode flags on stdin: %m");
-
-       if (fcntl(0, F_SETFL, status & ~O_NONBLOCK) == -1)
-           fatal(2, "Can't set file mode flags on stdin: %m");
-       
        return (-1);
     }
 }
@@ -1204,8 +1211,10 @@ int put_char(int c)
     char ch = c;
 
     usleep(10000);             /* inter-character typing delay (?) */
+    checksigs();
 
     status = write(1, &ch, 1);
+    checksigs();
 
     switch (status) {
     case 1:
@@ -1215,12 +1224,6 @@ int put_char(int c)
        msgf("warning: write() on stdout returned %d", status);
        
     case -1:
-       if ((status = fcntl(0, F_GETFL, 0)) == -1)
-           fatal(2, "Can't get file mode flags on stdin, %m");
-
-       if (fcntl(0, F_SETFL, status & ~O_NONBLOCK) == -1)
-           fatal(2, "Can't set file mode flags on stdin: %m");
-       
        return (-1);
     }
 }
@@ -1244,8 +1247,11 @@ int write_char(int c)
 
 int put_string(register char *s)
 {
+    char *s1;
     quiet = 0;
+
     s = clean(s, 1);
+    s1 = s;
 
     if (verbose) {
        if (quiet)
@@ -1260,8 +1266,10 @@ int put_string(register char *s)
        register char c = *s++;
 
        if (c != '\\') {
-           if (!write_char (c))
+           if (!write_char (c)) {
+               free(s1);
                return 0;
+           }
            continue;
        }
 
@@ -1280,14 +1288,18 @@ int put_string(register char *s)
            break;
 
        default:
-           if (!write_char (c))
+           if (!write_char (c)) {
+               free(s1);
                return 0;
+           }
            break;
        }
+       checksigs();
     }
 
     alarm(0);
     alarmed = 0;
+    free(s1);
     return (1);
 }
 
@@ -1320,6 +1332,7 @@ int echo_stderr(int n)
        need_lf = 1;
        break;
     }
+    checksigs();
     return ret;
 }
 
@@ -1331,10 +1344,10 @@ int get_string(register char *string)
     char temp[STR_LEN];
     int c, printed = 0, len, minlen;
     register char *s = temp, *end = s + STR_LEN;
-    char *logged = temp;
+    char *s1, *logged = temp;
 
     fail_reason = (char *)0;
-    string = clean(string, 0);
+    string = s1 = clean(string, 0);
     len = strlen(string);
     minlen = (len > sizeof(fail_buffer)? len: sizeof(fail_buffer)) - 1;
 
@@ -1344,12 +1357,14 @@ int get_string(register char *string)
     if (len > STR_LEN) {
        msgf("expect string is too long");
        exit_code = 1;
+       free(s1);
        return 0;
     }
 
     if (len == 0) {
        if (verbose)
            msgf("got it");
+       free(s1);
        return (1);
     }
 
@@ -1397,6 +1412,7 @@ int get_string(register char *string)
                    strftime (report_buffer, 20, "%b %d %H:%M:%S ", tm_now);
                    strcat (report_buffer, report_string[n]);
 
+                   free(report_string[n]);
                    report_string[n] = (char *) NULL;
                    report_gathering = 1;
                    break;
@@ -1406,8 +1422,10 @@ int get_string(register char *string)
        else {
            if (!iscntrl (c)) {
                int rep_len = strlen (report_buffer);
-               report_buffer[rep_len]     = c;
-               report_buffer[rep_len + 1] = '\0';
+               if ((rep_len + 1) < sizeof(report_buffer)) {
+                   report_buffer[rep_len]     = c;
+                   report_buffer[rep_len + 1] = '\0';
+               }
            }
            else {
                report_gathering = 0;
@@ -1426,6 +1444,7 @@ int get_string(register char *string)
 
            alarm(0);
            alarmed = 0;
+           free(s1);
            return (1);
        }
 
@@ -1442,6 +1461,7 @@ int get_string(register char *string)
                alarmed = 0;
                exit_code = n + 4;
                strcpy(fail_reason = fail_buffer, abort_string[n]);
+               free(s1);
                return (0);
            }
        }
@@ -1473,6 +1493,7 @@ int get_string(register char *string)
 
     exit_code = 3;
     alarmed   = 0;
+    free(s1);
     return (0);
 }