Unified the locking code, added relock().
Revert strlcpy to strncpy when filling in utmp structs.
Fixed some bugs in DNS addr option handling.
Set PPPLOGNAME with login name of user.
Moved daemon() logic into detach().
Fix bug where errno was clobbered by seteuid().
Use pty in sys-linux.c when making a ppp unit.
# pppd makefile for NeXT
#
# $Orignial: Makefile.ultrix,v 1.4 1994/09/01 00:40:40 paulus Exp $
-# $Id: Makefile.NeXT,v 1.5 1998/03/25 01:26:57 paulus Exp $
+# $Id: Makefile.NeXT,v 1.6 1999/04/12 06:24:44 paulus Exp $
#
ARCHFLAGS =
MANDIR = /usr/local/ppp/man
OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
- auth.o options.o demand.o sys-NeXT.o
+ auth.o options.o demand.o utils.o sys-NeXT.o
#
# For HPPA and SPARC, define FIXSIGS to get around posix bugs in
#
COMPILE_FLAGS = -DNO_DRAND48 \
- -DFIXSIGS -DHAS_BROKEN_IOCTL \
- -DDEBUGUPAP -DDEBUGCHAP -DDEBUGLCP -DDEBUGIPCP
+ -DFIXSIGS -DHAS_BROKEN_IOCTL -DLOCK_BINARY \
+ -DLOCK_DIR=\"/usr/spool/uucp/LCK\"
#
# If you want to use MSCHAP, see the README.MSCHAP80 file.
#
# pppd makefile for AIX 4.1
-# $Id: Makefile.aix4,v 1.3 1998/03/25 01:26:59 paulus Exp $
+# $Id: Makefile.aix4,v 1.4 1999/04/12 06:24:44 paulus Exp $
#
#ifndef BINDIR
BINDIR = /usr/sbin
#ENDIF
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
- auth.c options.c demand.c sys-aix4.c \
+ auth.c options.c demand.c utils.c sys-aix4.c \
gencode.c grammar.c scanner.c nametoaddr.c optimize.c
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
- auth.o options.o demand.o sys-aix4.o \
+ auth.o options.o demand.o utils.o sys-aix4.o \
gencode.o grammar.o scanner.o nametoaddr.o optimize.o
CC = xlc
-# $Id: Makefile.bsd,v 1.14 1998/03/25 01:27:00 paulus Exp $
+# $Id: Makefile.bsd,v 1.15 1999/04/12 06:24:44 paulus Exp $
BINDIR?= /usr/sbin
# -D_BITYPES is for FreeBSD, which doesn't define anything to
PROG= pppd
SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
- demand.c auth.c options.c sys-bsd.c
+ demand.c auth.c options.c utils.c sys-bsd.c
MAN= pppd.cat8
MAN8= pppd.8
BINMODE=4555
#
# pppd makefile for Linux
-# $Id: Makefile.linux,v 1.29 1999/03/31 06:07:58 paulus Exp $
+# $Id: Makefile.linux,v 1.30 1999/04/12 06:24:44 paulus Exp $
#
# Default installation locations
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c cbcp.c \
- demand.c
+ demand.c utils.c
HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h chap_ms.h md4.h \
ipxcp.h cbcp.h
MANPAGES = pppd.8
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
- auth.o options.o demand.o sys-linux.o ipxcp.o
+ auth.o options.o demand.o utils.o sys-linux.o ipxcp.o
all: pppd
#
# pppd makefile for OSF/1 on DEC Alpha
-# $Id: Makefile.osf,v 1.8 1998/03/25 01:27:04 paulus Exp $
+# $Id: Makefile.osf,v 1.9 1999/04/12 06:24:44 paulus Exp $
#
BINDIR = /usr/local/etc
MANDIR = /usr/local/man
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
- auth.c options.c demand.c sys-osf.c md4.c chap_ms.c
+ auth.c options.c demand.c utils.c sys-osf.c md4.c chap_ms.c
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
- auth.o options.o demand.o sys-osf.o md4.o chap_ms.o
+ auth.o options.o demand.o utils.o sys-osf.o md4.o chap_ms.o
CC = cc
-DEBUG_FLAGS = -DDEBUGALL
-COMPILE_FLAGS = -DSTREAMS -DGIDSET_TYPE=int -D_SOCKADDR_LEN -DCHAPMS -DUSE_CRYPT $(DEBUG_FLAGS)
+#DEBUG_FLAGS = -DDEBUGALL
+COMPILE_FLAGS = -DSTREAMS -DGIDSET_TYPE=int -D_SOCKADDR_LEN -DCHAPMS \
+ -DUSE_CRYPT $(DEBUG_FLAGS) -DLOCK_DIR=\"/usr/spool/locks\"
#COPTS = -O2
COPTS = -g
LIBS =
#
# Makefile for pppd under Solaris 2.
-# $Id: Makefile.sol2,v 1.10 1998/03/25 01:27:05 paulus Exp $
+# $Id: Makefile.sol2,v 1.11 1999/04/12 06:24:44 paulus Exp $
#
include ../svr4/Makedefs
all: pppd
OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
- auth.o options.o demand.o sys-svr4.o
+ auth.o options.o demand.o utils.o sys-svr4.o
pppd: $(OBJS)
$(CC) -o pppd $(OBJS) $(LIBS)
#
# Makefile for pppd under SunOS 4.
-# $Id: Makefile.sunos4,v 1.9 1999/03/12 06:07:14 paulus Exp $
+# $Id: Makefile.sunos4,v 1.10 1999/04/12 06:24:44 paulus Exp $
#
include ../sunos4/Makedefs
LIBS =
-CFLAGS = $(COPTS) -I../include -DSUNOS4 -DGIDSET_TYPE=int
+CFLAGS = $(COPTS) -I../include -DSUNOS4 -DGIDSET_TYPE=int \
+ -DLOCK_DIR=\"/usr/spool/locks\"
all: pppd
OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
- auth.o options.o demand.o sys-sunos4.o
+ auth.o options.o demand.o utils.o sys-sunos4.o
pppd: $(OBJS)
$(CC) -o pppd $(OBJS) $(LIBS)
#
# Makefile for pppd under Solaris 2.
-# $Id: Makefile.svr4,v 1.13 1998/03/25 01:27:08 paulus Exp $
+# $Id: Makefile.svr4,v 1.14 1999/04/12 06:24:44 paulus Exp $
#
include ../svr4/Makedefs
all: pppd
OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
- auth.o options.o demand.o sys-svr4.o
+ auth.o options.o demand.o utils.o sys-svr4.o
pppd: $(OBJS)
$(CC) -o pppd $(OBJS) $(LIBS)
#
# pppd makefile for Ultrix
-# $Id: Makefile.ultrix,v 1.10 1998/03/25 01:27:09 paulus Exp $
+# $Id: Makefile.ultrix,v 1.11 1999/04/12 06:24:44 paulus Exp $
#
BINDIR = /usr/local/etc
MANDIR = /usr/local/man
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
- auth.c options.c demand.c sys-ultrix.c
+ auth.c options.c demand.c utils.c sys-ultrix.c
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
- auth.o options.o demand.o sys-ultrix.o
+ auth.o options.o demand.o utils.o sys-ultrix.o
# CC = gcc
DEBUG_FLAGS =
-COMPILE_FLAGS = -DNO_DRAND48 -DGIDSET_TYPE=int -DULTRIX
+COMPILE_FLAGS = -DNO_DRAND48 -DGIDSET_TYPE=int -DULTRIX \
+ -DLOCK_BINARY -DLOCK_DIR=\"/usr/spool/uucp\"
COPTS = -O
LIBS =
*/
#ifndef lint
-static char rcsid[] = "$Id: auth.c,v 1.50 1999/04/01 07:08:47 paulus Exp $";
+static char rcsid[] = "$Id: auth.c,v 1.51 1999/04/12 06:24:44 paulus Exp $";
#endif
#include <stdio.h>
(void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET);
memset((void *)&ll, 0, sizeof(ll));
(void)time(&ll.ll_time);
- (void)strlcpy(ll.ll_line, tty, sizeof(ll.ll_line));
+ (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
(void)write(fd, (char *)&ll, sizeof(ll));
(void)close(fd);
}
*/
#ifndef lint
-static char rcsid[] = "$Id: ipcp.c,v 1.43 1999/03/19 04:23:39 paulus Exp $";
+static char rcsid[] = "$Id: ipcp.c,v 1.44 1999/04/12 06:24:45 paulus Exp $";
#endif
/*
neg = 0; \
}
-#define ADDCIDNS(opt, neg) \
+#define ADDCIDNS(opt, neg, addr) \
if (neg) { \
- int addrlen = CILEN_ADDR; \
- if (len >= addrlen) { \
+ if (len >= CILEN_ADDR) { \
u_int32_t l; \
PUTCHAR(opt, ucp); \
- PUTCHAR(addrlen, ucp); \
- l = ntohl(0); \
+ PUTCHAR(CILEN_ADDR, ucp); \
+ l = ntohl(addr); \
PUTLONG(l, ucp); \
- len -= addrlen; \
+ len -= CILEN_ADDR; \
} else \
neg = 0; \
}
ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
go->maxslotindex, go->cflag);
- ADDCIDNS(CI_MS_DNS1, go->req_dns1);
+ ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
- ADDCIDNS(CI_MS_DNS2, go->req_dns2);
+ ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
*lenp -= len;
}
} \
}
+#define ACKCIDNS(opt, neg, addr) \
+ if (neg) { \
+ u_int32_t l; \
+ if ((len -= CILEN_ADDR) < 0) \
+ goto bad; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_ADDR || citype != opt) \
+ goto bad; \
+ GETLONG(l, p); \
+ cilong = htonl(l); \
+ if (addr != cilong) \
+ goto bad; \
+ }
+
ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
go->old_addrs, go->ouraddr, go->hisaddr);
ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
go->maxslotindex, go->cflag);
+ ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
+
+ ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
+
/*
* If there are any remaining CIs, then this packet is bad.
*/
code \
}
-/*
- * Peer returns DNS address in a NAK packet
- */
#define NAKCIDNS(opt, neg, code) \
if (go->neg && \
((cilen = p[1]) == CILEN_ADDR) && \
NAKCIDNS(CI_MS_DNS1, req_dns1,
try.dnsaddr[0] = cidnsaddr;
- try.req_dns1 = 0;
);
NAKCIDNS(CI_MS_DNS2, req_dns2,
try.dnsaddr[1] = cidnsaddr;
- try.req_dns2 = 0;
);
/*
#define REJCIDNS(opt, neg, dnsaddr) \
if (go->neg && \
- ((cilen = p[1]) == CI_MS_DNS1) && \
+ ((cilen = p[1]) == CILEN_ADDR) && \
len >= cilen && \
p[0] == opt) { \
u_int32_t l; \
*/
#ifndef lint
-static char rcsid[] = "$Id: main.c,v 1.73 1999/04/01 07:19:59 paulus Exp $";
+static char rcsid[] = "$Id: main.c,v 1.74 1999/04/12 06:24:46 paulus Exp $";
#endif
#include <stdio.h>
static void holdoff_end __P((void *));
static int device_script __P((char *, int, int, int));
static void reap_kids __P((int waitfor));
-static void pr_log __P((void *, char *, ...));
-static void logit __P((int, char *, va_list));
-static void vslp_printer __P((void *, char *, ...));
-static void format_packet __P((u_char *, int, void (*) (void *, char *, ...),
- void *));
static void record_child __P((int, char *, void (*) (void *), void *));
static int start_charshunt __P((int, int));
static void charshunt_done __P((void *));
}
syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %d",
VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid);
-
+ script_setenv("PPPLOGNAME", p);
+
/*
* Compute mask of all interesting signals and install signal handlers
* for each. Only one signal handler may be active at a time. Therefore,
for (;;) {
/* If the user specified the device name, become the
user before opening it. */
+ int err;
if (!devnam_info.priv && !default_device)
seteuid(uid);
ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0);
+ err = errno;
if (!devnam_info.priv && !default_device)
seteuid(0);
if (ttyfd >= 0)
break;
- if (errno != EINTR)
+ errno = err;
+ if (err != EINTR)
error("Failed to open %s: %m", devnam);
- if (!persist || errno != EINTR)
+ if (!persist || err != EINTR)
goto fail;
}
if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1
void
detach()
{
+ int pid;
+
if (detached)
return;
- if (daemon(0, 0) < 0) {
- perror("Couldn't detach from controlling terminal");
- die(1);
+ if ((pid = fork()) < 0) {
+ error("Couldn't detach (fork failed: %m)");
+ die(1); /* or just return? */
+ }
+ if (pid != 0) {
+ /* parent */
+ if (locked)
+ relock(pid);
+ exit(0); /* parent dies */
}
+ setsid();
+ chdir("/");
+ close(0); /* XXX we should make sure that none */
+ close(1); /* of the fds we need are <= 2 */
+ close(2);
detached = 1;
log_to_fd = -1;
pid = getpid();
}
-/*
- * log_packet - format a packet and log it.
- */
-
-char line[256]; /* line to be logged accumulated here */
-char *linep;
-
-void
-log_packet(p, len, prefix, level)
- u_char *p;
- int len;
- char *prefix;
- int level;
-{
- strlcpy(line, prefix, sizeof(line));
- linep = line + strlen(line);
- format_packet(p, len, pr_log, NULL);
- if (linep != line)
- syslog(level, "%s", line);
-}
-
-/*
- * format_packet - make a readable representation of a packet,
- * calling `printer(arg, format, ...)' to output it.
- */
-static void
-format_packet(p, len, printer, arg)
- u_char *p;
- int len;
- void (*printer) __P((void *, char *, ...));
- void *arg;
-{
- int i, n;
- u_short proto;
- struct protent *protp;
-
- if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
- p += 2;
- GETSHORT(proto, p);
- len -= PPP_HDRLEN;
- for (i = 0; (protp = protocols[i]) != NULL; ++i)
- if (proto == protp->protocol)
- break;
- if (protp != NULL) {
- printer(arg, "[%s", protp->name);
- n = (*protp->printpkt)(p, len, printer, arg);
- printer(arg, "]");
- p += n;
- len -= n;
- } else {
- for (i = 0; (protp = protocols[i]) != NULL; ++i)
- if (proto == (protp->protocol & ~0x8000))
- break;
- if (protp != 0 && protp->data_name != 0) {
- printer(arg, "[%s data]", protp->data_name);
- if (len > 8)
- printer(arg, "%.8B ...", p);
- else
- printer(arg, "%.*B", len, p);
- len = 0;
- } else
- printer(arg, "[proto=0x%x]", proto);
- }
- }
-
- if (len > 32)
- printer(arg, "%.32B ...", p);
- else
- printer(arg, "%.*B", len, p);
-}
-
-static void
-pr_log __V((void *arg, char *fmt, ...))
-{
- int n;
- va_list pvar;
- char buf[256];
-
-#if __STDC__
- va_start(pvar, fmt);
-#else
- void *arg;
- char *fmt;
- va_start(pvar);
- arg = va_arg(pvar, void *);
- fmt = va_arg(pvar, char *);
-#endif
-
- n = vslprintf(buf, sizeof(buf), fmt, pvar);
- va_end(pvar);
-
- if (linep + n + 1 > line + sizeof(line)) {
- syslog(LOG_DEBUG, "%s", line);
- linep = line;
- }
- strlcpy(linep, buf, line + sizeof(line) - linep);
- linep += n;
-}
-
-/*
- * vslp_printer - used in processing a %P format
- */
-struct buffer_info {
- char *ptr;
- int len;
-};
-
-static void
-vslp_printer __V((void *arg, char *fmt, ...))
-{
- int n;
- va_list pvar;
- struct buffer_info *bi;
-
-#if __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;
-}
-
-/*
- * print_string - print a readable representation of a string using
- * printer.
- */
-void
-print_string(p, len, printer, arg)
- char *p;
- int len;
- void (*printer) __P((void *, char *, ...));
- void *arg;
-{
- int c;
-
- printer(arg, "\"");
- for (; len > 0; --len) {
- c = *p++;
- if (' ' <= c && c <= '~') {
- if (c == '\\' || c == '"')
- printer(arg, "\\");
- printer(arg, "%c", c);
- } else {
- switch (c) {
- case '\n':
- printer(arg, "\\n");
- break;
- case '\r':
- printer(arg, "\\r");
- break;
- case '\t':
- printer(arg, "\\t");
- break;
- default:
- printer(arg, "\\%.3o", c);
- }
- }
- }
- printer(arg, "\"");
-}
-
/*
* novm - log an error message saying we ran out of memory, and die.
*/
fatal("Virtual memory exhausted allocating %s\n", msg);
}
-/*
- * 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),
- * %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.
- */
-int
-slprintf __V((char *buf, int buflen, char *fmt, ...))
-{
- va_list args;
- int n;
-
-#if __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;
-}
-
-/*
- * 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)
- char *buf;
- int buflen;
- 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 = prec = 0;
- 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 {
- while (isdigit(c)) {
- prec = prec * 10 + c - '0';
- c = *++fmt;
- }
- }
- }
- str = 0;
- base = 0;
- neg = 0;
- ++fmt;
- switch (c) {
- case 'd':
- i = va_arg(args, int);
- if (i < 0) {
- neg = 1;
- val = -i;
- } else
- val = i;
- 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;
- 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);
- 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 && prec < n)
- 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;
-}
-
/*
* script_setenv - set an environment variable value to be used
* for scripts that we run (e.g. ip-up, auth-up, etc.)
}
}
-/*
- * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer,
- * always leaves destination null-terminated (for len > 0).
- */
-size_t
-strlcpy(dest, src, len)
- char *dest;
- const char *src;
- size_t len;
-{
- size_t ret = strlen(src);
-
- if (len != 0) {
- if (ret < len)
- strcpy(dest, src);
- else {
- strncpy(dest, src, len - 1);
- dest[len-1] = 0;
- }
- }
- return ret;
-}
-
-/*
- * strlcat - like strcat/strncat, doesn't overflow destination buffer,
- * always leaves destination null-terminated (for len > 0).
- */
-size_t
-strlcat(dest, src, len)
- char *dest;
- const char *src;
- size_t len;
-{
- size_t dlen = strlen(dest);
-
- return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0));
-}
-
-/*
- * logit - does the hard work for fatal et al.
- */
-static void
-logit(level, fmt, args)
- int level;
- char *fmt;
- va_list args;
-{
- int n;
- char buf[256];
-
- n = vslprintf(buf, sizeof(buf), fmt, args);
- syslog(level, "%s", buf);
- if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) {
- if (buf[n-1] != '\n')
- buf[n++] = '\n';
- if (write(log_to_fd, buf, n) != n)
- log_to_fd = -1;
- }
-}
-
-/*
- * fatal - log an error message and die horribly.
- */
-void
-fatal __V((char *fmt, ...))
-{
- va_list pvar;
-
-#if __STDC__
- va_start(pvar, fmt);
-#else
- char *fmt;
- va_start(pvar);
- fmt = va_arg(pvar, char *);
-#endif
-
- logit(LOG_ERR, fmt, pvar);
- va_end(pvar);
-
- die(1); /* as promised */
-}
-
-/*
- * error - log an error message.
- */
-void
-error __V((char *fmt, ...))
-{
- va_list pvar;
-
-#if __STDC__
- va_start(pvar, fmt);
-#else
- char *fmt;
- va_start(pvar);
- fmt = va_arg(pvar, char *);
-#endif
-
- logit(LOG_ERR, fmt, pvar);
- va_end(pvar);
-}
-
-/*
- * warn - log a warning message.
- */
-void
-warn __V((char *fmt, ...))
-{
- va_list pvar;
-
-#if __STDC__
- va_start(pvar, fmt);
-#else
- char *fmt;
- va_start(pvar);
- fmt = va_arg(pvar, char *);
-#endif
-
- logit(LOG_WARNING, fmt, pvar);
- va_end(pvar);
-}
-
-/*
- * notice - log a notice-level message.
- */
-void
-notice __V((char *fmt, ...))
-{
- va_list pvar;
-
-#if __STDC__
- va_start(pvar, fmt);
-#else
- char *fmt;
- va_start(pvar);
- fmt = va_arg(pvar, char *);
-#endif
-
- logit(LOG_NOTICE, fmt, pvar);
- va_end(pvar);
-}
-
-/*
- * info - log an informational message.
- */
-void
-info __V((char *fmt, ...))
-{
- va_list pvar;
-
-#if __STDC__
- va_start(pvar, fmt);
-#else
- char *fmt;
- va_start(pvar);
- fmt = va_arg(pvar, char *);
-#endif
-
- logit(LOG_INFO, fmt, pvar);
- va_end(pvar);
-}
-
-/*
- * dbglog - log a debug message.
- */
-void
-dbglog __V((char *fmt, ...))
-{
- va_list pvar;
-
-#if __STDC__
- va_start(pvar, fmt);
-#else
- char *fmt;
- va_start(pvar);
- fmt = va_arg(pvar, char *);
-#endif
-
- logit(LOG_DEBUG, fmt, pvar);
- va_end(pvar);
-}
-
/*
* start_charshunt - create a child process to run the character shunt.
*/
*/
#ifndef lint
-static char rcsid[] = "$Id: options.c,v 1.56 1999/03/30 06:33:08 paulus Exp $";
+static char rcsid[] = "$Id: options.c,v 1.57 1999/04/12 06:24:47 paulus Exp $";
#endif
#include <ctype.h>
int priv;
{
FILE *f;
- int i, newline, ret;
+ int i, newline, ret, err;
option_t *opt;
int oldpriv;
char *oldsource;
if (check_prot)
seteuid(getuid());
f = fopen(filename, "r");
+ err = errno;
if (check_prot)
seteuid(0);
if (f == NULL) {
- if (!must_exist && errno == ENOENT)
+ if (!must_exist && err == ENOENT)
return 1;
+ errno = err;
option_error("Can't open options file %s: %m", filename);
return 0;
}
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: pppd.h,v 1.37 1999/03/31 05:39:43 paulus Exp $
+ * $Id: pppd.h,v 1.38 1999/04/12 06:24:47 paulus Exp $
*/
/*
extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */
extern int link_stats_valid; /* set if link_stats is valid */
extern int using_pty; /* using pty as device (notty or pty opt.) */
+extern int log_to_fd; /* logging to this fd as well as syslog */
+extern char *no_ppp_msg; /* message to print if ppp not in kernel */
/*
* Variables set by command-line options.
/* Delete proxy ARP entry for peer */
u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */
int lock __P((char *)); /* Create lock file for device */
+int relock __P((int)); /* Rewrite lock file with new pid */
void unlock __P((void)); /* Delete previously-created lock file */
-int daemon __P((int, int)); /* Detach us from terminal session */
void logwtmp __P((const char *, const char *, const char *));
/* Write entry to wtmp file */
int get_host_seed __P((void)); /* Get host-dependent random number seed */
*/
#ifndef lint
-static char rcsid[] = "$Id: sys-NeXT.c,v 1.17 1999/03/22 05:55:36 paulus Exp $";
+static char rcsid[] = "$Id: sys-NeXT.c,v 1.18 1999/04/12 06:24:48 paulus Exp $";
#endif
#include <stdio.h>
static int restore_term; /* 1 => we've munged the terminal */
static struct termios inittermios; /* Initial TTY termios */
-static char *lock_file;
-
static int sockfd; /* socket for doing interface ioctls */
static int pppdev; /* +++ */
return -1;
}
-
+#if 0
/*
* daemon - Detach us from the terminal session.
*/
}
return 0;
}
-
+#endif
char *
strdup(s)
if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
return;
if (!fstat(fd, &buf)) {
- strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
- strlcpy(ut.ut_name, name, sizeof(ut.ut_name));
- strlcpy(ut.ut_host, host, sizeof(ut.ut_host));
+ strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+ strncpy(ut.ut_host, host, sizeof(ut.ut_host));
(void)time(&ut.ut_time);
if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
(void)ftruncate(fd, buf.st_size);
close(fd);
}
+#if 0
/*
* Routines for locking and unlocking the serial device, moved here
* from chat.c.
#define LOCK_PREFIX "/usr/spool/uucp/LCK/LCK.."
+static char *lock_file;
+
/*
* lock - create a lock file for the named device
*/
lock_file = NULL;
}
}
+#endif
#if defined(i386) && defined(HAS_BROKEN_IOCTL)
int
*/
#ifndef lint
-static char rcsid[] = "$Id: sys-aix4.c,v 1.19 1999/03/19 04:23:46 paulus Exp $";
+static char rcsid[] = "$Id: sys-aix4.c,v 1.20 1999/04/12 06:24:48 paulus Exp $";
#endif
/*
return -1;
}
-
+#if 0
/*
* daemon - Detach us from the terminal session.
*/
}
return 0;
}
-
+#endif
/*
* ppp_available - check if this kernel supports PPP.
if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
return;
if (!fstat(fd, &buf)) {
- strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
- strlcpy(ut.ut_name, name, sizeof(ut.ut_name));
- strlcpy(ut.ut_host, host, sizeof(ut.ut_host));
+ strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+ strncpy(ut.ut_host, host, sizeof(ut.ut_host));
(void)time(&ut.ut_time);
if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
(void)ftruncate(fd, buf.st_size);
*/
#ifndef lint
-static char rcsid[] = "$Id: sys-bsd.c,v 1.42 1999/04/01 07:20:10 paulus Exp $";
+static char rcsid[] = "$Id: sys-bsd.c,v 1.43 1999/04/12 06:24:49 paulus Exp $";
/* $NetBSD: sys-bsd.c,v 1.1.1.3 1997/09/26 18:53:04 christos Exp $ */
#endif
static struct termios inittermios; /* Initial TTY termios */
static struct winsize wsinfo; /* Initial window size info */
-static char *lock_file; /* name of lock file created */
-
static int loop_slave = -1;
static int loop_master;
static char loop_name[20];
return gethostid();
}
+#if 0
/*
* lock - create a lock file for the named lock device
*/
#define LOCK_PREFIX "/var/spool/lock/LCK.."
+static char *lock_file; /* name of lock file created */
+
int
lock(dev)
char *dev;
lock_file = NULL;
}
}
+#endif
static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
static char proxy_arp_dev[16]; /* Device for proxy arp entry */
-static char *lock_file;
-
static struct utsname utsname; /* for the kernel version */
static int kernel_version;
#define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
extern int hungup;
-#ifndef LOCK_PREFIX
-#define LOCK_PREFIX "/var/lock/LCK.."
-#endif
-
static void set_ppp_fd (int new_fd)
{
SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd));
ppp_registered(void)
{
int local_fd;
- int init_disc = -1;
int mfd = -1;
int ret = 0;
-
- if (devnam[0] == 0) {
- /* running with notty or pty option */
- char slave[16];
- if (!get_pty(&mfd, &local_fd, slave, 0))
- return 0;
- } else {
- local_fd = open(devnam, O_NONBLOCK | O_RDWR, 0);
- if (local_fd < 0) {
- error("Failed to open %s: %m(%d)", devnam, errno);
- return 0;
- }
+ char slave[16];
+
+ /*
+ * We used to open the serial device and set it to the ppp line
+ * discipline here, in order to create a ppp unit. But that is
+ * not a good idea - the user might have specified a device that
+ * they can't open (permission, or maybe it doesn't really exist).
+ * So we grab a pty master/slave pair and use that.
+ */
+ if (!get_pty(&mfd, &local_fd, slave, 0)) {
+ no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
+ return 0;
}
-/*
- * Read the initial line discipline and try to put the device into the
- * PPP dicipline.
- */
- if (ioctl(local_fd, TIOCGETD, &init_disc) < 0) {
- error("ioctl(TIOCGETD): %m(%d)", errno);
- } else if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
+ /*
+ * Try to put the device into the PPP discipline.
+ */
+ if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
error("ioctl(TIOCSETD(PPP)): %m(%d)", errno);
- } else if (ioctl(local_fd, TIOCSETD, &init_disc) < 0) {
- error("ioctl(TIOCSETD(%d)): %m(%d)", init_disc, errno);
} else
ret = 1;
- close (local_fd);
- if (mfd >= 0)
- close(mfd);
+ close(local_fd);
+ close(mfd);
return ret;
}
struct ifreq ifr;
int size;
int my_version, my_modification, my_patch;
- extern char *no_ppp_msg;
+
+ no_ppp_msg =
+ "This system lacks kernel support for PPP. This could be because\n"
+ "the PPP kernel module is not loaded, or because the kernel is\n"
+ "not configured for PPP. See the README.linux file in the\n"
+ "ppp-2.3.7 distribution.\n";
+
/*
* Open a socket for doing the ioctl operations.
*/
if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
ok = 0;
- if (!ok)
- no_ppp_msg =
- "This system lacks kernel support for PPP. This could be because\n"
- "the PPP kernel module is not loaded, or because the kernel is\n"
- "not configured for PPP. See the README.linux file in the\n"
- "ppp-2.3.7 distribution.\n";
-
/*
* This is the PPP device. Validate the version of the driver at this
* point to ensure that this program will work with the driver.
*/
- else {
+ if (ok) {
char abBuffer [1024];
ifr.ifr_data = abBuffer;
memset(&ut, 0, sizeof(ut));
if (ut.ut_id[0] == 0)
- strlcpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
+ strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
- strlcpy(ut.ut_user, name, sizeof(ut.ut_user));
- strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
+ strncpy(ut.ut_user, name, sizeof(ut.ut_user));
+ strncpy(ut.ut_line, line, sizeof(ut.ut_line));
time(&ut.ut_time);
/* Insert the host name if one is supplied */
if (*host)
- strlcpy (ut.ut_host, host, sizeof(ut.ut_host));
+ strncpy (ut.ut_host, host, sizeof(ut.ut_host));
/* Insert the IP address of the remote system if IP is enabled */
if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
}
}
+#if 0
/********************************************************************
* Code for locking/unlocking the serial device.
* This code is derived from chat.c.
*/
+#ifndef LOCK_PREFIX
+#define LOCK_PREFIX "/var/lock/LCK.."
+#endif
+
+static char *lock_file;
+
/*
* lock - create a lock file for the named device
*/
lock_file = NULL;
}
}
+#endif
/********************************************************************
*
return result;
}
+#if 0
/*
* daemon - Detach us from controlling terminal session.
*/
}
return 0;
}
+#endif
/*
* Use the hostname as part of the random number seed.
*/
#ifndef lint
-static char rcsid[] = "$Id: sys-osf.c,v 1.24 1999/04/01 07:20:10 paulus Exp $";
+static char rcsid[] = "$Id: sys-osf.c,v 1.25 1999/04/12 06:24:50 paulus Exp $";
#endif
#include <stdio.h>
return 1;
}
-
+#if 0
/*
* daemon - Detach us from controlling terminal session.
*/
}
return 0;
}
+#endif
/*
* ppp_available - check whether the system has any ppp interfaces
if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
return;
if (!fstat(fd, &buf)) {
- strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
- strlcpy(ut.ut_name, name, sizeof(ut.ut_name));
- strlcpy(ut.ut_host, host, sizeof(ut.ut_host));
+ strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+ strncpy(ut.ut_host, host, sizeof(ut.ut_host));
(void)time(&ut.ut_time);
if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
(void)ftruncate(fd, buf.st_size);
return 1;
}
+#if 0
/*
* Code for locking/unlocking the serial device.
* This code is derived from chat.c.
lock_file = NULL;
}
}
+#endif
int
set_filters(pass, active)
*/
#ifndef lint
-static char rcsid[] = "$Id: sys-sunos4.c,v 1.19 1999/04/01 07:20:11 paulus Exp $";
+static char rcsid[] = "$Id: sys-sunos4.c,v 1.20 1999/04/12 06:24:51 paulus Exp $";
#endif
#include <stdio.h>
return 1;
}
-
+#if 0
/*
* daemon - Detach us from controlling terminal session.
*/
}
return 0;
}
+#endif
/*
* ppp_available - check whether the system has any ppp interfaces
if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
return;
if (!fstat(fd, &buf)) {
- strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
- strlcpy(ut.ut_name, name, sizeof(ut.ut_name));
- strlcpy(ut.ut_host, host, sizeof(ut.ut_host));
+ strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+ strncpy(ut.ut_host, host, sizeof(ut.ut_host));
(void)time(&ut.ut_time);
if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
(void)ftruncate(fd, buf.st_size);
*/
#ifndef lint
-static char rcsid[] = "$Id: sys-svr4.c,v 1.29 1999/03/22 05:55:39 paulus Exp $";
+static char rcsid[] = "$Id: sys-svr4.c,v 1.30 1999/04/12 06:24:51 paulus Exp $";
#endif
#include <limits.h>
return 1;
}
-
+#if 0
/*
* daemon - Detach us from controlling terminal session.
*/
}
return 0;
}
+#endif
/*
* ppp_available - check whether the system has any ppp interfaces
#ifdef B57600
{ 57600, B57600 },
#endif
+#ifdef B76800
+ { 76800, B76800 },
+#endif
#ifdef B115200
{ 115200, B115200 },
#endif
if (name[0] != 0) {
/* logging in */
- strlcpy(utmpx.ut_user, name, sizeof(utmpx.ut_user));
- strlcpy(utmpx.ut_id, ifname, sizeof(utmpx.ut_id));
- strlcpy(utmpx.ut_line, line, sizeof(utmpx.ut_line));
+ strncpy(utmpx.ut_user, name, sizeof(utmpx.ut_user));
+ strncpy(utmpx.ut_id, ifname, sizeof(utmpx.ut_id));
+ strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line));
utmpx.ut_pid = getpid();
utmpx.ut_type = USER_PROCESS;
} else {
return 0;
}
+#if 0
/*
* lock - create a lock file for the named lock device
*/
lock_file[0] = 0;
}
}
-
+#endif
/*
* cifroute - delete a route through the addresses given.
*/
#ifndef lint
-static char rcsid[] = "$Id: sys-ultrix.c,v 1.30 1999/03/22 05:55:40 paulus Exp $";
+static char rcsid[] = "$Id: sys-ultrix.c,v 1.31 1999/04/12 06:24:52 paulus Exp $";
#endif
/*
return 1;
}
-
+#if 0
/*
* daemon - Detach us from the terminal session.
*/
}
return 0;
}
+#endif
/*
* ppp_available - check whether the system has any ppp interfaces
if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
return;
if (!fstat(fd, &buf)) {
- strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
- strlcpy(ut.ut_name, name, sizeof(ut.ut_name));
- strlcpy(ut.ut_host, host, sizeof(ut.ut_host));
+ strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+ strncpy(ut.ut_host, host, sizeof(ut.ut_host));
(void)time(&ut.ut_time);
if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
(void)ftruncate(fd, buf.st_size);
close(fd);
}
+#if 0
/*
* Routines for locking and unlocking the serial device, moved here
* from chat.c.
lock_file = NULL;
}
}
+#endif
--- /dev/null
+/*
+ * utils.c - various utility functions used in pppd.
+ *
+ * Copyright (c) 1999 The Australian National University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the Australian National University. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static char rcsid[] = "$Id: utils.c,v 1.1 1999/04/12 06:24:53 paulus Exp $";
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <netdb.h>
+#include <utmp.h>
+#include <pwd.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "pppd.h"
+
+static void pr_log __P((void *, char *, ...));
+static void logit __P((int, char *, va_list));
+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;
+};
+
+/*
+ * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer,
+ * always leaves destination null-terminated (for len > 0).
+ */
+size_t
+strlcpy(dest, src, len)
+ char *dest;
+ const char *src;
+ size_t len;
+{
+ size_t ret = strlen(src);
+
+ if (len != 0) {
+ if (ret < len)
+ strcpy(dest, src);
+ else {
+ strncpy(dest, src, len - 1);
+ dest[len-1] = 0;
+ }
+ }
+ return ret;
+}
+
+/*
+ * strlcat - like strcat/strncat, doesn't overflow destination buffer,
+ * always leaves destination null-terminated (for len > 0).
+ */
+size_t
+strlcat(dest, src, len)
+ char *dest;
+ const char *src;
+ size_t len;
+{
+ size_t dlen = strlen(dest);
+
+ return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0));
+}
+
+
+/*
+ * 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),
+ * %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.
+ */
+int
+slprintf __V((char *buf, int buflen, char *fmt, ...))
+{
+ va_list args;
+ int n;
+
+#if __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;
+}
+
+/*
+ * 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)
+ char *buf;
+ int buflen;
+ 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 = prec = 0;
+ 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 {
+ while (isdigit(c)) {
+ prec = prec * 10 + c - '0';
+ c = *++fmt;
+ }
+ }
+ }
+ str = 0;
+ base = 0;
+ neg = 0;
+ ++fmt;
+ switch (c) {
+ case 'd':
+ i = va_arg(args, int);
+ if (i < 0) {
+ neg = 1;
+ val = -i;
+ } else
+ val = i;
+ 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;
+ 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);
+ 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 && prec < n)
+ 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;
+}
+
+/*
+ * 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 __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;
+}
+
+/*
+ * log_packet - format a packet and log it.
+ */
+
+char line[256]; /* line to be logged accumulated here */
+char *linep;
+
+void
+log_packet(p, len, prefix, level)
+ u_char *p;
+ int len;
+ char *prefix;
+ int level;
+{
+ strlcpy(line, prefix, sizeof(line));
+ linep = line + strlen(line);
+ format_packet(p, len, pr_log, NULL);
+ if (linep != line)
+ syslog(level, "%s", line);
+}
+
+/*
+ * format_packet - make a readable representation of a packet,
+ * calling `printer(arg, format, ...)' to output it.
+ */
+static void
+format_packet(p, len, printer, arg)
+ u_char *p;
+ int len;
+ void (*printer) __P((void *, char *, ...));
+ void *arg;
+{
+ int i, n;
+ u_short proto;
+ struct protent *protp;
+
+ if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
+ p += 2;
+ GETSHORT(proto, p);
+ len -= PPP_HDRLEN;
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (proto == protp->protocol)
+ break;
+ if (protp != NULL) {
+ printer(arg, "[%s", protp->name);
+ n = (*protp->printpkt)(p, len, printer, arg);
+ printer(arg, "]");
+ p += n;
+ len -= n;
+ } else {
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (proto == (protp->protocol & ~0x8000))
+ break;
+ if (protp != 0 && protp->data_name != 0) {
+ printer(arg, "[%s data]", protp->data_name);
+ if (len > 8)
+ printer(arg, "%.8B ...", p);
+ else
+ printer(arg, "%.*B", len, p);
+ len = 0;
+ } else
+ printer(arg, "[proto=0x%x]", proto);
+ }
+ }
+
+ if (len > 32)
+ printer(arg, "%.32B ...", p);
+ else
+ printer(arg, "%.*B", len, p);
+}
+
+static void
+pr_log __V((void *arg, char *fmt, ...))
+{
+ int n;
+ va_list pvar;
+ char buf[256];
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ void *arg;
+ char *fmt;
+ va_start(pvar);
+ arg = va_arg(pvar, void *);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ n = vslprintf(buf, sizeof(buf), fmt, pvar);
+ va_end(pvar);
+
+ if (linep + n + 1 > line + sizeof(line)) {
+ syslog(LOG_DEBUG, "%s", line);
+ linep = line;
+ }
+ strlcpy(linep, buf, line + sizeof(line) - linep);
+ linep += n;
+}
+
+/*
+ * print_string - print a readable representation of a string using
+ * printer.
+ */
+void
+print_string(p, len, printer, arg)
+ char *p;
+ int len;
+ void (*printer) __P((void *, char *, ...));
+ void *arg;
+{
+ int c;
+
+ printer(arg, "\"");
+ for (; len > 0; --len) {
+ c = *p++;
+ if (' ' <= c && c <= '~') {
+ if (c == '\\' || c == '"')
+ printer(arg, "\\");
+ printer(arg, "%c", c);
+ } else {
+ switch (c) {
+ case '\n':
+ printer(arg, "\\n");
+ break;
+ case '\r':
+ printer(arg, "\\r");
+ break;
+ case '\t':
+ printer(arg, "\\t");
+ break;
+ default:
+ printer(arg, "\\%.3o", c);
+ }
+ }
+ }
+ printer(arg, "\"");
+}
+
+/*
+ * logit - does the hard work for fatal et al.
+ */
+static void
+logit(level, fmt, args)
+ int level;
+ char *fmt;
+ va_list args;
+{
+ int n;
+ char buf[256];
+
+ n = vslprintf(buf, sizeof(buf), fmt, args);
+ syslog(level, "%s", buf);
+ if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) {
+ if (buf[n-1] != '\n')
+ buf[n++] = '\n';
+ if (write(log_to_fd, buf, n) != n)
+ log_to_fd = -1;
+ }
+}
+
+/*
+ * fatal - log an error message and die horribly.
+ */
+void
+fatal __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_ERR, fmt, pvar);
+ va_end(pvar);
+
+ die(1); /* as promised */
+}
+
+/*
+ * error - log an error message.
+ */
+void
+error __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_ERR, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * warn - log a warning message.
+ */
+void
+warn __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_WARNING, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * notice - log a notice-level message.
+ */
+void
+notice __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_NOTICE, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * info - log an informational message.
+ */
+void
+info __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_INFO, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * dbglog - log a debug message.
+ */
+void
+dbglog __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_DEBUG, fmt, pvar);
+ va_end(pvar);
+}
+
+/* Procedures for locking the serial device using a lock file. */
+#ifndef LOCK_DIR
+#ifdef _linux_
+#define LOCK_DIR "/var/lock"
+#else
+#ifdef SVR4
+#define LOCK_DIR "/var/spool/locks"
+#else
+#define LOCK_DIR "/var/spool/lock"
+#endif
+#endif
+#endif /* LOCK_DIR */
+
+static char lock_file[MAXPATHLEN];
+
+/*
+ * lock - create a lock file for the named device
+ */
+int
+lock(char *dev)
+{
+#ifdef LOCKLIB
+ int result;
+
+ result = mklock (dev, (void *) 0);
+ if (result == 0) {
+ strlcpy(lock_file, sizeof(lock_file), dev);
+ return 0;
+ }
+
+ if (result > 0)
+ notice("Device %s is locked by pid %d", dev, result);
+ else
+ error("Can't create lock file %s", lock_file);
+ return -1;
+
+#else /* LOCKLIB */
+
+ char lock_buffer[12];
+ int fd, pid, n;
+
+#ifdef SVR4
+ struct stat sbuf;
+
+ if (stat(dev, &sbuf) < 0) {
+ error("Can't get device number for %s: %m", dev);
+ return -1;
+ }
+ if ((sbuf.st_mode & S_IFMT) != S_IFCHR) {
+ error("Can't lock %s: not a character device", dev);
+ return -1;
+ }
+ slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d",
+ LOCK_DIR, major(sbuf.st_dev),
+ major(sbuf.st_rdev), minor(sbuf.st_rdev));
+#else
+ char *p;
+
+ if ((p = strrchr(dev, '/')) != NULL)
+ dev = p + 1;
+ slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev);
+#endif
+
+ while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
+ if (errno != EEXIST) {
+ error("Can't create lock file %s: %m", lock_file);
+ break;
+ }
+
+ /* Read the lock file to find out who has the device locked. */
+ fd = open(lock_file, O_RDONLY, 0);
+ if (fd < 0) {
+ if (errno == ENOENT) /* This is just a timing problem. */
+ continue;
+ error("Can't open existing lock file %s: %m", lock_file);
+ break;
+ }
+#ifndef LOCK_BINARY
+ n = read(fd, lock_buffer, 11);
+#else
+ n = read(fd, &pid, sizeof(pid));
+#endif /* LOCK_BINARY */
+ close(fd);
+ fd = -1;
+ if (n <= 0) {
+ error("Can't read pid from lock file %s", lock_file);
+ break;
+ }
+
+ /* See if the process still exists. */
+#ifndef LOCK_BINARY
+ lock_buffer[n] = 0;
+ pid = atoi(lock_buffer);
+#endif /* LOCK_BINARY */
+ if (pid == 0 || pid == getpid()
+ || (kill(pid, 0) == -1 && errno == ESRCH)) {
+ if (unlink (lock_file) == 0) {
+ notice("Removed stale lock on %s (pid %d)", dev, pid);
+ continue;
+ }
+ warn("Couldn't remove stale lock on %s", dev);
+ } else
+ notice("Device %s is locked by pid %d", dev, pid);
+ break;
+ }
+
+ if (fd < 0) {
+ lock_file[0] = 0;
+ return -1;
+ }
+
+ pid = getpid();
+#ifndef LOCK_BINARY
+ slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
+ write (fd, lock_buffer, 11);
+#else
+ write(fd, &pid, sizeof (pid));
+#endif
+ close(fd);
+ return 0;
+
+#endif
+}
+
+/*
+ * relock - called to update our lockfile when we are about to detach,
+ * thus changing our pid (we fork, the child carries on, and the parent dies).
+ * Note that this is called by the parent, with pid equal to the pid
+ * of the child. This avoids a potential race which would exist if
+ * we had the child rewrite the lockfile (the parent might die first,
+ * and another process could think the lock was stale if it checked
+ * between when the parent died and the child rewrote the lockfile).
+ */
+int
+relock(int pid)
+{
+#ifdef LOCKLIB
+ /* XXX is there a way to do this? */
+ return -1;
+#else /* LOCKLIB */
+
+ int fd;
+ char lock_buffer[12];
+
+ if (lock_file[0] == 0)
+ return -1;
+ fd = open(lock_file, O_WRONLY, 0);
+ if (fd < 0) {
+ error("Couldn't reopen lock file %s: %m", lock_file);
+ lock_file[0] = 0;
+ return -1;
+ }
+
+#ifndef LOCK_BINARY
+ slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
+ write (fd, lock_buffer, 11);
+#else
+ write(fd, &pid, sizeof(pid));
+#endif /* LOCK_BINARY */
+ close(fd);
+ return 0;
+
+#endif /* LOCKLIB */
+}
+
+/*
+ * unlock - remove our lockfile
+ */
+void
+unlock()
+{
+ if (lock_file[0]) {
+#ifdef LOCKLIB
+ (void) rmlock(lock_file, (void *) 0);
+#else
+ unlink(lock_file);
+#endif
+ lock_file[0] = 0;
+ }
+}
+