--- a/pppd/utils.c +++ b/pppd/utils.c @@ -30,6 +30,7 @@ #define RCSID "$Id: utils.c,v 1.24 2004/11/04 10:02:26 paulus Exp $" +#define _BSD_SOURCE #include #include #include @@ -67,15 +68,10 @@ 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 *)); -struct buffer_info { - char *ptr; - int len; -}; - +#ifndef __UCLIBC__ /* * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, * always leaves destination null-terminated (for len > 0). @@ -113,6 +109,7 @@ strlcat(dest, src, len) return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); } +#endif /* @@ -129,17 +126,7 @@ slprintf __V((char *buf, int buflen, cha va_list args; int n; -#if defined(__STDC__) va_start(args, fmt); -#else - char *buf; - int buflen; - char *fmt; - va_start(args); - buf = va_arg(args, char *); - buflen = va_arg(args, int); - fmt = va_arg(args, char *); -#endif n = vslprintf(buf, buflen, fmt, args); va_end(args); return n; @@ -148,7 +135,6 @@ slprintf __V((char *buf, int buflen, cha /* * vslprintf - like slprintf, takes a va_list instead of a list of args. */ -#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) int vslprintf(buf, buflen, fmt, args) @@ -157,298 +143,14 @@ vslprintf(buf, buflen, fmt, args) char *fmt; va_list args; { - int c, i, n; - int width, prec, fillch; - int base, len, neg, quoted; - unsigned long val = 0; - char *str, *f, *buf0; - unsigned char *p; - char num[32]; - time_t t; - u_int32_t ip; - static char hexchars[] = "0123456789abcdef"; - struct buffer_info bufinfo; - - buf0 = buf; - --buflen; - while (buflen > 0) { - for (f = fmt; *f != '%' && *f != 0; ++f) - ; - if (f > fmt) { - len = f - fmt; - if (len > buflen) - len = buflen; - memcpy(buf, fmt, len); - buf += len; - buflen -= len; - fmt = f; - } - if (*fmt == 0) - break; - c = *++fmt; - width = 0; - prec = -1; - fillch = ' '; - if (c == '0') { - fillch = '0'; - c = *++fmt; - } - if (c == '*') { - width = va_arg(args, int); - c = *++fmt; - } else { - while (isdigit(c)) { - width = width * 10 + c - '0'; - c = *++fmt; - } - } - if (c == '.') { - c = *++fmt; - if (c == '*') { - prec = va_arg(args, int); - c = *++fmt; - } else { - prec = 0; - while (isdigit(c)) { - prec = prec * 10 + c - '0'; - c = *++fmt; - } - } - } - str = 0; - base = 0; - neg = 0; - ++fmt; - switch (c) { - case 'l': - c = *fmt++; - switch (c) { - case 'd': - val = va_arg(args, long); - if (val < 0) { - neg = 1; - val = -val; - } - base = 10; - break; - case 'u': - val = va_arg(args, unsigned long); - base = 10; - break; - default: - *buf++ = '%'; --buflen; - *buf++ = 'l'; --buflen; - --fmt; /* so %lz outputs %lz etc. */ - continue; - } - break; - case 'd': - i = va_arg(args, int); - if (i < 0) { - neg = 1; - val = -i; - } else - val = i; - base = 10; - break; - case 'u': - val = va_arg(args, unsigned int); - base = 10; - break; - case 'o': - val = va_arg(args, unsigned int); - base = 8; - break; - case 'x': - case 'X': - val = va_arg(args, unsigned int); - base = 16; - break; - case 'p': - val = (unsigned long) va_arg(args, void *); - base = 16; - neg = 2; - break; - case 's': - str = va_arg(args, char *); - break; - case 'c': - num[0] = va_arg(args, int); - num[1] = 0; - str = num; - break; - case 'm': - str = strerror(errno); - break; - case 'I': - ip = va_arg(args, u_int32_t); - ip = ntohl(ip); - slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, - (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); - str = num; - break; -#if 0 /* not used, and breaks on S/390, apparently */ - 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; -#endif - case 't': - time(&t); - str = ctime(&t); - str += 4; /* chop off the day name */ - str[15] = 0; /* chop off year and newline */ - break; - case 'v': /* "visible" string */ - case 'q': /* quoted string */ - quoted = c == 'q'; - p = va_arg(args, unsigned char *); - if (fillch == '0' && prec >= 0) { - n = prec; - } else { - n = strlen((char *)p); - if (prec >= 0 && n > prec) - n = prec; - } - while (n > 0 && buflen > 0) { - c = *p++; - --n; - if (!quoted && c >= 0x80) { - OUTCHAR('M'); - OUTCHAR('-'); - c -= 0x80; - } - if (quoted && (c == '"' || c == '\\')) - OUTCHAR('\\'); - if (c < 0x20 || (0x7f <= c && c < 0xa0)) { - if (quoted) { - OUTCHAR('\\'); - switch (c) { - case '\t': OUTCHAR('t'); break; - case '\n': OUTCHAR('n'); break; - case '\b': OUTCHAR('b'); break; - case '\f': OUTCHAR('f'); break; - default: - OUTCHAR('x'); - OUTCHAR(hexchars[c >> 4]); - OUTCHAR(hexchars[c & 0xf]); - } - } else { - if (c == '\t') - OUTCHAR(c); - else { - OUTCHAR('^'); - OUTCHAR(c ^ 0x40); - } - } - } else - OUTCHAR(c); - } - continue; - case 'P': /* print PPP packet */ - bufinfo.ptr = buf; - bufinfo.len = buflen + 1; - p = va_arg(args, unsigned char *); - n = va_arg(args, int); - format_packet(p, n, vslp_printer, &bufinfo); - buf = bufinfo.ptr; - buflen = bufinfo.len - 1; - continue; - case 'B': - p = va_arg(args, unsigned char *); - for (n = prec; n > 0; --n) { - c = *p++; - if (fillch == ' ') - OUTCHAR(' '); - OUTCHAR(hexchars[(c >> 4) & 0xf]); - OUTCHAR(hexchars[c & 0xf]); - } - continue; - default: - *buf++ = '%'; - if (c != '%') - --fmt; /* so %z outputs %z etc. */ - --buflen; - continue; - } - if (base != 0) { - str = num + sizeof(num); - *--str = 0; - while (str > num + neg) { - *--str = hexchars[val % base]; - val = val / base; - if (--prec <= 0 && val == 0) - break; - } - switch (neg) { - case 1: - *--str = '-'; - break; - case 2: - *--str = 'x'; - *--str = '0'; - break; - } - len = num + sizeof(num) - 1 - str; - } else { - len = strlen(str); - if (prec >= 0 && len > prec) - len = prec; - } - if (width > 0) { - if (width > buflen) - width = buflen; - if ((n = width - len) > 0) { - buflen -= n; - for (; n > 0; --n) - *buf++ = fillch; - } - } - if (len > buflen) - len = buflen; - memcpy(buf, str, len); - buf += len; - buflen -= len; - } - *buf = 0; - return buf - buf0; -} + int ret; -/* - * vslp_printer - used in processing a %P format - */ -static void -vslp_printer __V((void *arg, char *fmt, ...)) -{ - int n; - va_list pvar; - struct buffer_info *bi; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - void *arg; - char *fmt; - va_start(pvar); - arg = va_arg(pvar, void *); - fmt = va_arg(pvar, char *); -#endif - - bi = (struct buffer_info *) arg; - n = vslprintf(bi->ptr, bi->len, fmt, pvar); - va_end(pvar); - - bi->ptr += n; - bi->len -= n; + ret = vsnprintf(buf, buflen, fmt, args); + buf[buflen - 1] = 0; + return ret; } + #ifdef unused /* * log_packet - format a packet and log it.