]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/utils.c
pppd: Handle SIGINT and SIGTERM during interrupted syscalls (#148)
[ppp.git] / pppd / utils.c
index fb2c6aa20b05af1cfb9be9c27b3d8f3520c87a55..23189d0ad105bd49f9c00c274ab6340cfd6ffb09 100644 (file)
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The name(s) of the authors of this software must not be used to
+ * 2. The name(s) of the authors of this software must not be used to
  *    endorse or promote products derived from this software without
  *    prior written permission.
  *
- * 4. Redistributions of any form whatsoever must retain the following
+ * 3. Redistributions of any form whatsoever must retain the following
  *    acknowledgment:
  *    "This product includes software developed by Paul Mackerras
  *     <paulus@samba.org>".
@@ -33,7 +28,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: utils.c,v 1.21 2003/03/30 08:26:56 paulus Exp $"
+#define RCSID  "$Id: utils.c,v 1.25 2008/06/03 12:06:37 paulus Exp $"
 
 #include <stdio.h>
 #include <ctype.h>
@@ -64,7 +59,6 @@
 #include "fsm.h"
 #include "lcp.h"
 
-static const char rcsid[] = RCSID;
 
 #if defined(SUNOS4)
 extern char *strerror();
@@ -73,8 +67,7 @@ extern char *strerror();
 static void logit __P((int, char *, va_list));
 static void log_write __P((int, char *));
 static void vslp_printer __P((void *, char *, ...));
-static void format_packet __P((u_char *, int, void (*) (void *, char *, ...),
-                              void *));
+static void format_packet __P((u_char *, int, printer_func, void *));
 
 struct buffer_info {
     char *ptr;
@@ -123,7 +116,7 @@ strlcat(dest, src, len)
 /*
  * slprintf - format a message into a buffer.  Like sprintf except we
  * also specify the length of the output buffer, and we handle
- * %r (recursive format), %m (error message), %v (visible string),
+ * %m (error message), %v (visible string),
  * %q (quoted string), %t (current time) and %I (IP address) formats.
  * Doesn't do floating-point formats.
  * Returns the number of chars put into buf.
@@ -173,6 +166,7 @@ vslprintf(buf, buflen, fmt, args)
     u_int32_t ip;
     static char hexchars[] = "0123456789abcdef";
     struct buffer_info bufinfo;
+    int termch;
 
     buf0 = buf;
     --buflen;
@@ -241,8 +235,8 @@ vslprintf(buf, buflen, fmt, args)
                base = 10;
                break;
            default:
-               *buf++ = '%'; --buflen;
-               *buf++ = 'l'; --buflen;
+               OUTCHAR('%');
+               OUTCHAR('l');
                --fmt;          /* so %lz outputs %lz etc. */
                continue;
            }
@@ -292,17 +286,6 @@ vslprintf(buf, buflen, fmt, args)
                     (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
            str = num;
            break;
-       case 'r':
-           f = va_arg(args, char *);
-#ifndef __powerpc__
-           n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list));
-#else
-           /* On the powerpc, a va_list is an array of 1 structure */
-           n = vslprintf(buf, buflen + 1, f, va_arg(args, void *));
-#endif
-           buf += n;
-           buflen -= n;
-           continue;
        case 't':
            time(&t);
            str = ctime(&t);
@@ -313,15 +296,21 @@ vslprintf(buf, buflen, fmt, args)
        case 'q':               /* quoted string */
            quoted = c == 'q';
            p = va_arg(args, unsigned char *);
+           if (p == NULL)
+                   p = (unsigned char *)"<NULL>";
            if (fillch == '0' && prec >= 0) {
                n = prec;
+               termch = -1;    /* matches no unsigned char value */
            } else {
-               n = strlen((char *)p);
-               if (prec >= 0 && n > prec)
+               n = buflen;
+               if (prec != -1 && n > prec)
                    n = prec;
+               termch = 0;     /* stop on null byte */
            }
            while (n > 0 && buflen > 0) {
                c = *p++;
+               if (c == termch)
+                   break;
                --n;
                if (!quoted && c >= 0x80) {
                    OUTCHAR('M');
@@ -401,9 +390,9 @@ vslprintf(buf, buflen, fmt, args)
            }
            len = num + sizeof(num) - 1 - str;
        } else {
-           len = strlen(str);
-           if (prec >= 0 && len > prec)
-               len = prec;
+           for (len = 0; len < buflen && (prec == -1 || len < prec); ++len)
+               if (str[len] == 0)
+                   break;
        }
        if (width > 0) {
            if (width > buflen)
@@ -478,7 +467,7 @@ static void
 format_packet(p, len, printer, arg)
     u_char *p;
     int len;
-    void (*printer) __P((void *, char *, ...));
+    printer_func printer;
     void *arg;
 {
     int i, n;
@@ -530,7 +519,7 @@ static int llevel;          /* level for logging */
 
 void
 init_pr_log(prefix, level)
-     char *prefix;
+     const char *prefix;
      int level;
 {
        linep = line;
@@ -616,7 +605,7 @@ void
 print_string(p, len, printer, arg)
     char *p;
     int len;
-    void (*printer) __P((void *, char *, ...));
+    printer_func printer;
     void *arg;
 {
     int c;
@@ -640,7 +629,7 @@ print_string(p, len, printer, arg)
                printer(arg, "\\t");
                break;
            default:
-               printer(arg, "\\%.3o", c);
+               printer(arg, "\\%.3o", (unsigned char) c);
            }
        }
     }
@@ -656,10 +645,9 @@ logit(level, fmt, args)
     char *fmt;
     va_list args;
 {
-    int n;
     char buf[1024];
 
-    n = vslprintf(buf, sizeof(buf), fmt, args);
+    vslprintf(buf, sizeof(buf), fmt, args);
     log_write(level, buf);
 }
 
@@ -720,6 +708,7 @@ error __V((char *fmt, ...))
 
     logit(LOG_ERR, fmt, pvar);
     va_end(pvar);
+    ++error_count;
 }
 
 /*
@@ -846,7 +835,7 @@ complete_read(int fd, void *buf, size_t count)
        for (done = 0; done < count; ) {
                nb = read(fd, ptr, count - done);
                if (nb < 0) {
-                       if (errno == EINTR)
+                       if (errno == EINTR && !got_sigterm)
                                continue;
                        return -1;
                }