From e8be982dbc5c6c50dfc9f66737867570c8ed4973 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 12 Apr 1999 06:24:53 +0000 Subject: [PATCH] Move some stuff (printing, logging, [un]locking) into utils.c. 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.NeXT | 8 +- pppd/Makefile.aix4 | 6 +- pppd/Makefile.bsd | 4 +- pppd/Makefile.linux | 6 +- pppd/Makefile.osf | 11 +- pppd/Makefile.sol2 | 4 +- pppd/Makefile.sunos4 | 7 +- pppd/Makefile.svr4 | 4 +- pppd/Makefile.ultrix | 9 +- pppd/auth.c | 4 +- pppd/ipcp.c | 43 ++- pppd/main.c | 665 ++------------------------------- pppd/options.c | 8 +- pppd/pppd.h | 6 +- pppd/sys-NeXT.c | 18 +- pppd/sys-aix4.c | 12 +- pppd/sys-bsd.c | 8 +- pppd/sys-linux.c | 84 ++--- pppd/sys-osf.c | 13 +- pppd/sys-sunos4.c | 11 +- pppd/sys-svr4.c | 17 +- pppd/sys-ultrix.c | 13 +- pppd/utils.c | 862 +++++++++++++++++++++++++++++++++++++++++++ 23 files changed, 1050 insertions(+), 773 deletions(-) create mode 100644 pppd/utils.c diff --git a/pppd/Makefile.NeXT b/pppd/Makefile.NeXT index a2cb74b..11ecabd 100644 --- a/pppd/Makefile.NeXT +++ b/pppd/Makefile.NeXT @@ -2,7 +2,7 @@ # 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 = @@ -11,7 +11,7 @@ BINDIR = /usr/local/ppp/bin 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 @@ -27,8 +27,8 @@ OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ # 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. diff --git a/pppd/Makefile.aix4 b/pppd/Makefile.aix4 index a430f87..05e503b 100644 --- a/pppd/Makefile.aix4 +++ b/pppd/Makefile.aix4 @@ -1,6 +1,6 @@ # # 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 @@ -10,11 +10,11 @@ MANDIR = /usr/man #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 diff --git a/pppd/Makefile.bsd b/pppd/Makefile.bsd index b77cbce..ea94db5 100644 --- a/pppd/Makefile.bsd +++ b/pppd/Makefile.bsd @@ -1,4 +1,4 @@ -# $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 @@ -8,7 +8,7 @@ CFLAGS+= -g -I../include -DHAVE_PATHS_H -D_BITYPES 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 diff --git a/pppd/Makefile.linux b/pppd/Makefile.linux index 249be85..4e0fdf7 100644 --- a/pppd/Makefile.linux +++ b/pppd/Makefile.linux @@ -1,6 +1,6 @@ # # 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 @@ -9,12 +9,12 @@ MANDIR = /usr/man 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 diff --git a/pppd/Makefile.osf b/pppd/Makefile.osf index 2af708f..a673157 100644 --- a/pppd/Makefile.osf +++ b/pppd/Makefile.osf @@ -1,20 +1,21 @@ # # 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 = diff --git a/pppd/Makefile.sol2 b/pppd/Makefile.sol2 index 3802760..2cb5580 100644 --- a/pppd/Makefile.sol2 +++ b/pppd/Makefile.sol2 @@ -1,6 +1,6 @@ # # 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 @@ -11,7 +11,7 @@ LIBS = -lsocket -lnsl 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) diff --git a/pppd/Makefile.sunos4 b/pppd/Makefile.sunos4 index 9e46ad4..415fdd9 100644 --- a/pppd/Makefile.sunos4 +++ b/pppd/Makefile.sunos4 @@ -1,18 +1,19 @@ # # 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) diff --git a/pppd/Makefile.svr4 b/pppd/Makefile.svr4 index 628f0cd..842c615 100644 --- a/pppd/Makefile.svr4 +++ b/pppd/Makefile.svr4 @@ -1,6 +1,6 @@ # # 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 @@ -11,7 +11,7 @@ LIBS = -lsocket -lnsl -lc -L/usr/ucblib -lucb 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) diff --git a/pppd/Makefile.ultrix b/pppd/Makefile.ultrix index 9e2b1a6..cfd191c 100644 --- a/pppd/Makefile.ultrix +++ b/pppd/Makefile.ultrix @@ -1,20 +1,21 @@ # # 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 = diff --git a/pppd/auth.c b/pppd/auth.c index 778397d..53b4ef5 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -33,7 +33,7 @@ */ #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 @@ -1016,7 +1016,7 @@ plogin(user, passwd, msg, msglen) (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); } diff --git a/pppd/ipcp.c b/pppd/ipcp.c index 41eabd2..72e9cc3 100644 --- a/pppd/ipcp.c +++ b/pppd/ipcp.c @@ -18,7 +18,7 @@ */ #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 /* @@ -548,16 +548,15 @@ ipcp_addci(f, ucp, lenp) 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; \ } @@ -568,9 +567,9 @@ ipcp_addci(f, ucp, lenp) 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; } @@ -647,12 +646,31 @@ ipcp_ackci(f, p, 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. */ @@ -728,9 +746,6 @@ ipcp_nakci(f, p, len) code \ } -/* - * Peer returns DNS address in a NAK packet - */ #define NAKCIDNS(opt, neg, code) \ if (go->neg && \ ((cilen = p[1]) == CILEN_ADDR) && \ @@ -788,12 +803,10 @@ ipcp_nakci(f, p, len) 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; ); /* @@ -932,7 +945,7 @@ ipcp_rejci(f, p, len) #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; \ diff --git a/pppd/main.c b/pppd/main.c index cad0fa3..8fab864 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -18,7 +18,7 @@ */ #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 @@ -144,11 +144,6 @@ static void bad_signal __P((int)); 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 *)); @@ -344,7 +339,8 @@ main(argc, argv) } 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, @@ -527,16 +523,19 @@ main(argc, argv) 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 @@ -823,12 +822,25 @@ main(argc, argv) 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(); @@ -1546,177 +1558,6 @@ reap_kids(waitfor) } -/* - * 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. */ @@ -1727,282 +1568,6 @@ novm(msg) 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.) @@ -2076,188 +1641,6 @@ script_unsetenv(var) } } -/* - * 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. */ diff --git a/pppd/options.c b/pppd/options.c index 2418d28..f9c9aa5 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -18,7 +18,7 @@ */ #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 @@ -347,7 +347,7 @@ options_from_file(filename, must_exist, check_prot, priv) int priv; { FILE *f; - int i, newline, ret; + int i, newline, ret, err; option_t *opt; int oldpriv; char *oldsource; @@ -358,11 +358,13 @@ options_from_file(filename, must_exist, check_prot, priv) 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; } diff --git a/pppd/pppd.h b/pppd/pppd.h index c997f81..5dece10 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -16,7 +16,7 @@ * 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 $ */ /* @@ -145,6 +145,8 @@ extern int ngroups; /* How many groups valid in groups */ 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. @@ -381,8 +383,8 @@ int cifproxyarp __P((int, u_int32_t)); /* 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 */ diff --git a/pppd/sys-NeXT.c b/pppd/sys-NeXT.c index d498c4b..76928f2 100644 --- a/pppd/sys-NeXT.c +++ b/pppd/sys-NeXT.c @@ -20,7 +20,7 @@ */ #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 @@ -73,8 +73,6 @@ extern int errno; 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; /* +++ */ @@ -1178,7 +1176,7 @@ int have_route_to(u_int32_t addr) return -1; } - +#if 0 /* * daemon - Detach us from the terminal session. */ @@ -1202,7 +1200,7 @@ daemon(nochdir, noclose) } return 0; } - +#endif char * strdup(s) @@ -1246,9 +1244,9 @@ logwtmp(line, name, host) 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); @@ -1256,6 +1254,7 @@ logwtmp(line, name, host) close(fd); } +#if 0 /* * Routines for locking and unlocking the serial device, moved here * from chat.c. @@ -1263,6 +1262,8 @@ logwtmp(line, name, host) #define LOCK_PREFIX "/usr/spool/uucp/LCK/LCK.." +static char *lock_file; + /* * lock - create a lock file for the named device */ @@ -1331,6 +1332,7 @@ unlock() lock_file = NULL; } } +#endif #if defined(i386) && defined(HAS_BROKEN_IOCTL) int diff --git a/pppd/sys-aix4.c b/pppd/sys-aix4.c index e797c54..c83e375 100644 --- a/pppd/sys-aix4.c +++ b/pppd/sys-aix4.c @@ -21,7 +21,7 @@ */ #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 /* @@ -137,7 +137,7 @@ int have_route_to(u_int32_t addr) return -1; } - +#if 0 /* * daemon - Detach us from the terminal session. */ @@ -161,7 +161,7 @@ daemon(nochdir, noclose) } return 0; } - +#endif /* * ppp_available - check if this kernel supports PPP. @@ -1291,9 +1291,9 @@ logwtmp(line, name, host) 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); diff --git a/pppd/sys-bsd.c b/pppd/sys-bsd.c index 60a7927..1a1810d 100644 --- a/pppd/sys-bsd.c +++ b/pppd/sys-bsd.c @@ -21,7 +21,7 @@ */ #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 @@ -83,8 +83,6 @@ static int restore_term; /* 1 => we've munged the terminal */ 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]; @@ -1447,11 +1445,14 @@ get_host_seed() 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; @@ -1521,3 +1522,4 @@ unlock() lock_file = NULL; } } +#endif diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index 43855a9..33e338d 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -122,8 +122,6 @@ static u_int32_t default_route_gateway; /* Gateway for default route added */ 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)) @@ -167,10 +165,6 @@ extern u_char inpacket_buf[]; /* borrowed from main.c */ 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)); @@ -1570,39 +1564,32 @@ static int 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; } @@ -1618,7 +1605,13 @@ int ppp_available(void) 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. */ @@ -1648,18 +1641,11 @@ int ppp_available(void) 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; @@ -1738,10 +1724,10 @@ void logwtmp (const char *line, const char *name, const char *host) 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); @@ -1750,7 +1736,7 @@ void logwtmp (const char *line, const char *name, const char *host) /* 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) @@ -1778,11 +1764,18 @@ void logwtmp (const char *line, const char *name, const char *host) } } +#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 */ @@ -1915,6 +1908,7 @@ void unlock(void) lock_file = NULL; } } +#endif /******************************************************************** * @@ -2348,6 +2342,7 @@ int cipxfaddr (int unit) return result; } +#if 0 /* * daemon - Detach us from controlling terminal session. */ @@ -2371,6 +2366,7 @@ daemon(nochdir, noclose) } return 0; } +#endif /* * Use the hostname as part of the random number seed. diff --git a/pppd/sys-osf.c b/pppd/sys-osf.c index 45e176f..d9bdd30 100644 --- a/pppd/sys-osf.c +++ b/pppd/sys-osf.c @@ -26,7 +26,7 @@ */ #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 @@ -200,7 +200,7 @@ sys_check_options() return 1; } - +#if 0 /* * daemon - Detach us from controlling terminal session. */ @@ -224,6 +224,7 @@ daemon(nochdir, noclose) } return 0; } +#endif /* * ppp_available - check whether the system has any ppp interfaces @@ -1434,9 +1435,9 @@ logwtmp(line, name, host) 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); @@ -1658,6 +1659,7 @@ get_pty(master_fdp, slave_fdp, slave_name, uid) return 1; } +#if 0 /* * Code for locking/unlocking the serial device. * This code is derived from chat.c. @@ -1761,6 +1763,7 @@ unlock() lock_file = NULL; } } +#endif int set_filters(pass, active) diff --git a/pppd/sys-sunos4.c b/pppd/sys-sunos4.c index ea3deeb..60493fe 100644 --- a/pppd/sys-sunos4.c +++ b/pppd/sys-sunos4.c @@ -26,7 +26,7 @@ */ #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 @@ -201,7 +201,7 @@ sys_check_options() return 1; } - +#if 0 /* * daemon - Detach us from controlling terminal session. */ @@ -225,6 +225,7 @@ daemon(nochdir, noclose) } return 0; } +#endif /* * ppp_available - check whether the system has any ppp interfaces @@ -1271,9 +1272,9 @@ logwtmp(line, name, host) 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); diff --git a/pppd/sys-svr4.c b/pppd/sys-svr4.c index a8d80b9..abc7d96 100644 --- a/pppd/sys-svr4.c +++ b/pppd/sys-svr4.c @@ -26,7 +26,7 @@ */ #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 @@ -222,7 +222,7 @@ sys_check_options() return 1; } - +#if 0 /* * daemon - Detach us from controlling terminal session. */ @@ -246,6 +246,7 @@ daemon(nochdir, noclose) } return 0; } +#endif /* * ppp_available - check whether the system has any ppp interfaces @@ -453,6 +454,9 @@ struct speed { #ifdef B57600 { 57600, B57600 }, #endif +#ifdef B76800 + { 76800, B76800 }, +#endif #ifdef B115200 { 115200, B115200 }, #endif @@ -1610,9 +1614,9 @@ logwtmp(line, name, host) 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 { @@ -1656,6 +1660,7 @@ strioctl(fd, cmd, ptr, ilen, olen) return 0; } +#if 0 /* * lock - create a lock file for the named lock device */ @@ -1733,7 +1738,7 @@ unlock() lock_file[0] = 0; } } - +#endif /* * cifroute - delete a route through the addresses given. diff --git a/pppd/sys-ultrix.c b/pppd/sys-ultrix.c index f004ba6..cc6520b 100644 --- a/pppd/sys-ultrix.c +++ b/pppd/sys-ultrix.c @@ -21,7 +21,7 @@ */ #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 /* @@ -150,7 +150,7 @@ sys_check_options() return 1; } - +#if 0 /* * daemon - Detach us from the terminal session. */ @@ -174,6 +174,7 @@ daemon(nochdir, noclose) } return 0; } +#endif /* * ppp_available - check whether the system has any ppp interfaces @@ -1298,9 +1299,9 @@ logwtmp(line, name, host) 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); @@ -1308,6 +1309,7 @@ logwtmp(line, name, host) close(fd); } +#if 0 /* * Routines for locking and unlocking the serial device, moved here * from chat.c. @@ -1384,3 +1386,4 @@ unlock() lock_file = NULL; } } +#endif diff --git a/pppd/utils.c b/pppd/utils.c new file mode 100644 index 0000000..bec5f89 --- /dev/null +++ b/pppd/utils.c @@ -0,0 +1,862 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + } +} + -- 2.39.2