xref: /nrf52832-nimble/rt-thread/components/net/lwip-2.0.2/src/netif/ppp/utils.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * utils.c - various utility functions used in pppd.
3*10465441SEvalZero  *
4*10465441SEvalZero  * Copyright (c) 1999-2002 Paul Mackerras. All rights reserved.
5*10465441SEvalZero  *
6*10465441SEvalZero  * Redistribution and use in source and binary forms, with or without
7*10465441SEvalZero  * modification, are permitted provided that the following conditions
8*10465441SEvalZero  * are met:
9*10465441SEvalZero  *
10*10465441SEvalZero  * 1. Redistributions of source code must retain the above copyright
11*10465441SEvalZero  *    notice, this list of conditions and the following disclaimer.
12*10465441SEvalZero  *
13*10465441SEvalZero  * 2. The name(s) of the authors of this software must not be used to
14*10465441SEvalZero  *    endorse or promote products derived from this software without
15*10465441SEvalZero  *    prior written permission.
16*10465441SEvalZero  *
17*10465441SEvalZero  * 3. Redistributions of any form whatsoever must retain the following
18*10465441SEvalZero  *    acknowledgment:
19*10465441SEvalZero  *    "This product includes software developed by Paul Mackerras
20*10465441SEvalZero  *     <[email protected]>".
21*10465441SEvalZero  *
22*10465441SEvalZero  * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
23*10465441SEvalZero  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
24*10465441SEvalZero  * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25*10465441SEvalZero  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26*10465441SEvalZero  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27*10465441SEvalZero  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
28*10465441SEvalZero  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29*10465441SEvalZero  */
30*10465441SEvalZero 
31*10465441SEvalZero #include "netif/ppp/ppp_opts.h"
32*10465441SEvalZero #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
33*10465441SEvalZero 
34*10465441SEvalZero #if 0 /* UNUSED */
35*10465441SEvalZero #include <stdio.h>
36*10465441SEvalZero #include <ctype.h>
37*10465441SEvalZero #include <stdlib.h>
38*10465441SEvalZero #include <string.h>
39*10465441SEvalZero #include <unistd.h>
40*10465441SEvalZero #include <signal.h>
41*10465441SEvalZero #include <errno.h>
42*10465441SEvalZero #include <fcntl.h>
43*10465441SEvalZero #include <syslog.h>
44*10465441SEvalZero #include <netdb.h>
45*10465441SEvalZero #include <time.h>
46*10465441SEvalZero #include <utmp.h>
47*10465441SEvalZero #include <pwd.h>
48*10465441SEvalZero #include <sys/param.h>
49*10465441SEvalZero #include <sys/types.h>
50*10465441SEvalZero #include <sys/wait.h>
51*10465441SEvalZero #include <sys/time.h>
52*10465441SEvalZero #include <sys/resource.h>
53*10465441SEvalZero #include <sys/stat.h>
54*10465441SEvalZero #include <sys/socket.h>
55*10465441SEvalZero #include <netinet/in.h>
56*10465441SEvalZero #ifdef SVR4
57*10465441SEvalZero #include <sys/mkdev.h>
58*10465441SEvalZero #endif
59*10465441SEvalZero #endif /* UNUSED */
60*10465441SEvalZero 
61*10465441SEvalZero #include <ctype.h>  /* isdigit() */
62*10465441SEvalZero 
63*10465441SEvalZero #include "netif/ppp/ppp_impl.h"
64*10465441SEvalZero 
65*10465441SEvalZero #include "netif/ppp/fsm.h"
66*10465441SEvalZero #include "netif/ppp/lcp.h"
67*10465441SEvalZero 
68*10465441SEvalZero #if defined(SUNOS4)
69*10465441SEvalZero extern char *strerror();
70*10465441SEvalZero #endif
71*10465441SEvalZero 
72*10465441SEvalZero static void ppp_logit(int level, const char *fmt, va_list args);
73*10465441SEvalZero static void ppp_log_write(int level, char *buf);
74*10465441SEvalZero #if PRINTPKT_SUPPORT
75*10465441SEvalZero static void ppp_vslp_printer(void *arg, const char *fmt, ...);
76*10465441SEvalZero static void ppp_format_packet(const u_char *p, int len,
77*10465441SEvalZero 		void (*printer) (void *, const char *, ...), void *arg);
78*10465441SEvalZero 
79*10465441SEvalZero struct buffer_info {
80*10465441SEvalZero     char *ptr;
81*10465441SEvalZero     int len;
82*10465441SEvalZero };
83*10465441SEvalZero #endif /* PRINTPKT_SUPPORT */
84*10465441SEvalZero 
85*10465441SEvalZero /*
86*10465441SEvalZero  * ppp_strlcpy - like strcpy/strncpy, doesn't overflow destination buffer,
87*10465441SEvalZero  * always leaves destination null-terminated (for len > 0).
88*10465441SEvalZero  */
ppp_strlcpy(char * dest,const char * src,size_t len)89*10465441SEvalZero size_t ppp_strlcpy(char *dest, const char *src, size_t len) {
90*10465441SEvalZero     size_t ret = strlen(src);
91*10465441SEvalZero 
92*10465441SEvalZero     if (len != 0) {
93*10465441SEvalZero 	if (ret < len)
94*10465441SEvalZero 	    strcpy(dest, src);
95*10465441SEvalZero 	else {
96*10465441SEvalZero 	    strncpy(dest, src, len - 1);
97*10465441SEvalZero 	    dest[len-1] = 0;
98*10465441SEvalZero 	}
99*10465441SEvalZero     }
100*10465441SEvalZero     return ret;
101*10465441SEvalZero }
102*10465441SEvalZero 
103*10465441SEvalZero /*
104*10465441SEvalZero  * ppp_strlcat - like strcat/strncat, doesn't overflow destination buffer,
105*10465441SEvalZero  * always leaves destination null-terminated (for len > 0).
106*10465441SEvalZero  */
ppp_strlcat(char * dest,const char * src,size_t len)107*10465441SEvalZero size_t ppp_strlcat(char *dest, const char *src, size_t len) {
108*10465441SEvalZero     size_t dlen = strlen(dest);
109*10465441SEvalZero 
110*10465441SEvalZero     return dlen + ppp_strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0));
111*10465441SEvalZero }
112*10465441SEvalZero 
113*10465441SEvalZero 
114*10465441SEvalZero /*
115*10465441SEvalZero  * ppp_slprintf - format a message into a buffer.  Like sprintf except we
116*10465441SEvalZero  * also specify the length of the output buffer, and we handle
117*10465441SEvalZero  * %m (error message), %v (visible string),
118*10465441SEvalZero  * %q (quoted string), %t (current time) and %I (IP address) formats.
119*10465441SEvalZero  * Doesn't do floating-point formats.
120*10465441SEvalZero  * Returns the number of chars put into buf.
121*10465441SEvalZero  */
ppp_slprintf(char * buf,int buflen,const char * fmt,...)122*10465441SEvalZero int ppp_slprintf(char *buf, int buflen, const char *fmt, ...) {
123*10465441SEvalZero     va_list args;
124*10465441SEvalZero     int n;
125*10465441SEvalZero 
126*10465441SEvalZero     va_start(args, fmt);
127*10465441SEvalZero     n = ppp_vslprintf(buf, buflen, fmt, args);
128*10465441SEvalZero     va_end(args);
129*10465441SEvalZero     return n;
130*10465441SEvalZero }
131*10465441SEvalZero 
132*10465441SEvalZero /*
133*10465441SEvalZero  * ppp_vslprintf - like ppp_slprintf, takes a va_list instead of a list of args.
134*10465441SEvalZero  */
135*10465441SEvalZero #define OUTCHAR(c)	(buflen > 0? (--buflen, *buf++ = (c)): 0)
136*10465441SEvalZero 
ppp_vslprintf(char * buf,int buflen,const char * fmt,va_list args)137*10465441SEvalZero int ppp_vslprintf(char *buf, int buflen, const char *fmt, va_list args) {
138*10465441SEvalZero     int c, i, n;
139*10465441SEvalZero     int width, prec, fillch;
140*10465441SEvalZero     int base, len, neg, quoted;
141*10465441SEvalZero     unsigned long val = 0;
142*10465441SEvalZero     const char *f;
143*10465441SEvalZero     char *str, *buf0;
144*10465441SEvalZero     const unsigned char *p;
145*10465441SEvalZero     char num[32];
146*10465441SEvalZero #if 0 /* need port */
147*10465441SEvalZero     time_t t;
148*10465441SEvalZero #endif /* need port */
149*10465441SEvalZero     u32_t ip;
150*10465441SEvalZero     static char hexchars[] = "0123456789abcdef";
151*10465441SEvalZero #if PRINTPKT_SUPPORT
152*10465441SEvalZero     struct buffer_info bufinfo;
153*10465441SEvalZero #endif /* PRINTPKT_SUPPORT */
154*10465441SEvalZero 
155*10465441SEvalZero     buf0 = buf;
156*10465441SEvalZero     --buflen;
157*10465441SEvalZero     while (buflen > 0) {
158*10465441SEvalZero 	for (f = fmt; *f != '%' && *f != 0; ++f)
159*10465441SEvalZero 	    ;
160*10465441SEvalZero 	if (f > fmt) {
161*10465441SEvalZero 	    len = f - fmt;
162*10465441SEvalZero 	    if (len > buflen)
163*10465441SEvalZero 		len = buflen;
164*10465441SEvalZero 	    memcpy(buf, fmt, len);
165*10465441SEvalZero 	    buf += len;
166*10465441SEvalZero 	    buflen -= len;
167*10465441SEvalZero 	    fmt = f;
168*10465441SEvalZero 	}
169*10465441SEvalZero 	if (*fmt == 0)
170*10465441SEvalZero 	    break;
171*10465441SEvalZero 	c = *++fmt;
172*10465441SEvalZero 	width = 0;
173*10465441SEvalZero 	prec = -1;
174*10465441SEvalZero 	fillch = ' ';
175*10465441SEvalZero 	if (c == '0') {
176*10465441SEvalZero 	    fillch = '0';
177*10465441SEvalZero 	    c = *++fmt;
178*10465441SEvalZero 	}
179*10465441SEvalZero 	if (c == '*') {
180*10465441SEvalZero 	    width = va_arg(args, int);
181*10465441SEvalZero 	    c = *++fmt;
182*10465441SEvalZero 	} else {
183*10465441SEvalZero 	    while (isdigit(c)) {
184*10465441SEvalZero 		width = width * 10 + c - '0';
185*10465441SEvalZero 		c = *++fmt;
186*10465441SEvalZero 	    }
187*10465441SEvalZero 	}
188*10465441SEvalZero 	if (c == '.') {
189*10465441SEvalZero 	    c = *++fmt;
190*10465441SEvalZero 	    if (c == '*') {
191*10465441SEvalZero 		prec = va_arg(args, int);
192*10465441SEvalZero 		c = *++fmt;
193*10465441SEvalZero 	    } else {
194*10465441SEvalZero 		prec = 0;
195*10465441SEvalZero 		while (isdigit(c)) {
196*10465441SEvalZero 		    prec = prec * 10 + c - '0';
197*10465441SEvalZero 		    c = *++fmt;
198*10465441SEvalZero 		}
199*10465441SEvalZero 	    }
200*10465441SEvalZero 	}
201*10465441SEvalZero 	str = 0;
202*10465441SEvalZero 	base = 0;
203*10465441SEvalZero 	neg = 0;
204*10465441SEvalZero 	++fmt;
205*10465441SEvalZero 	switch (c) {
206*10465441SEvalZero 	case 'l':
207*10465441SEvalZero 	    c = *fmt++;
208*10465441SEvalZero 	    switch (c) {
209*10465441SEvalZero 	    case 'd':
210*10465441SEvalZero 		val = va_arg(args, long);
211*10465441SEvalZero 		if ((long)val < 0) {
212*10465441SEvalZero 		    neg = 1;
213*10465441SEvalZero 		    val = (unsigned long)-(long)val;
214*10465441SEvalZero 		}
215*10465441SEvalZero 		base = 10;
216*10465441SEvalZero 		break;
217*10465441SEvalZero 	    case 'u':
218*10465441SEvalZero 		val = va_arg(args, unsigned long);
219*10465441SEvalZero 		base = 10;
220*10465441SEvalZero 		break;
221*10465441SEvalZero 	    default:
222*10465441SEvalZero 		OUTCHAR('%');
223*10465441SEvalZero 		OUTCHAR('l');
224*10465441SEvalZero 		--fmt;		/* so %lz outputs %lz etc. */
225*10465441SEvalZero 		continue;
226*10465441SEvalZero 	    }
227*10465441SEvalZero 	    break;
228*10465441SEvalZero 	case 'd':
229*10465441SEvalZero 	    i = va_arg(args, int);
230*10465441SEvalZero 	    if (i < 0) {
231*10465441SEvalZero 		neg = 1;
232*10465441SEvalZero 		val = -i;
233*10465441SEvalZero 	    } else
234*10465441SEvalZero 		val = i;
235*10465441SEvalZero 	    base = 10;
236*10465441SEvalZero 	    break;
237*10465441SEvalZero 	case 'u':
238*10465441SEvalZero 	    val = va_arg(args, unsigned int);
239*10465441SEvalZero 	    base = 10;
240*10465441SEvalZero 	    break;
241*10465441SEvalZero 	case 'o':
242*10465441SEvalZero 	    val = va_arg(args, unsigned int);
243*10465441SEvalZero 	    base = 8;
244*10465441SEvalZero 	    break;
245*10465441SEvalZero 	case 'x':
246*10465441SEvalZero 	case 'X':
247*10465441SEvalZero 	    val = va_arg(args, unsigned int);
248*10465441SEvalZero 	    base = 16;
249*10465441SEvalZero 	    break;
250*10465441SEvalZero #if 0 /* unused (and wrong on LLP64 systems) */
251*10465441SEvalZero 	case 'p':
252*10465441SEvalZero 	    val = (unsigned long) va_arg(args, void *);
253*10465441SEvalZero 	    base = 16;
254*10465441SEvalZero 	    neg = 2;
255*10465441SEvalZero 	    break;
256*10465441SEvalZero #endif /* unused (and wrong on LLP64 systems) */
257*10465441SEvalZero 	case 's':
258*10465441SEvalZero 	    str = va_arg(args, char *);
259*10465441SEvalZero 	    break;
260*10465441SEvalZero 	case 'c':
261*10465441SEvalZero 	    num[0] = va_arg(args, int);
262*10465441SEvalZero 	    num[1] = 0;
263*10465441SEvalZero 	    str = num;
264*10465441SEvalZero 	    break;
265*10465441SEvalZero #if 0 /* do we always have strerror() in embedded ? */
266*10465441SEvalZero 	case 'm':
267*10465441SEvalZero 	    str = strerror(errno);
268*10465441SEvalZero 	    break;
269*10465441SEvalZero #endif /* do we always have strerror() in embedded ? */
270*10465441SEvalZero 	case 'I':
271*10465441SEvalZero 	    ip = va_arg(args, u32_t);
272*10465441SEvalZero 	    ip = lwip_ntohl(ip);
273*10465441SEvalZero 	    ppp_slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff,
274*10465441SEvalZero 		     (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
275*10465441SEvalZero 	    str = num;
276*10465441SEvalZero 	    break;
277*10465441SEvalZero #if 0 /* need port */
278*10465441SEvalZero 	case 't':
279*10465441SEvalZero 	    time(&t);
280*10465441SEvalZero 	    str = ctime(&t);
281*10465441SEvalZero 	    str += 4;		/* chop off the day name */
282*10465441SEvalZero 	    str[15] = 0;	/* chop off year and newline */
283*10465441SEvalZero 	    break;
284*10465441SEvalZero #endif /* need port */
285*10465441SEvalZero 	case 'v':		/* "visible" string */
286*10465441SEvalZero 	case 'q':		/* quoted string */
287*10465441SEvalZero 	    quoted = c == 'q';
288*10465441SEvalZero 	    p = va_arg(args, unsigned char *);
289*10465441SEvalZero 	    if (p == NULL)
290*10465441SEvalZero 		p = (const unsigned char *)"<NULL>";
291*10465441SEvalZero 	    if (fillch == '0' && prec >= 0) {
292*10465441SEvalZero 		n = prec;
293*10465441SEvalZero 	    } else {
294*10465441SEvalZero 		n = strlen((const char *)p);
295*10465441SEvalZero 		if (prec >= 0 && n > prec)
296*10465441SEvalZero 		    n = prec;
297*10465441SEvalZero 	    }
298*10465441SEvalZero 	    while (n > 0 && buflen > 0) {
299*10465441SEvalZero 		c = *p++;
300*10465441SEvalZero 		--n;
301*10465441SEvalZero 		if (!quoted && c >= 0x80) {
302*10465441SEvalZero 		    OUTCHAR('M');
303*10465441SEvalZero 		    OUTCHAR('-');
304*10465441SEvalZero 		    c -= 0x80;
305*10465441SEvalZero 		}
306*10465441SEvalZero 		if (quoted && (c == '"' || c == '\\'))
307*10465441SEvalZero 		    OUTCHAR('\\');
308*10465441SEvalZero 		if (c < 0x20 || (0x7f <= c && c < 0xa0)) {
309*10465441SEvalZero 		    if (quoted) {
310*10465441SEvalZero 			OUTCHAR('\\');
311*10465441SEvalZero 			switch (c) {
312*10465441SEvalZero 			case '\t':	OUTCHAR('t');	break;
313*10465441SEvalZero 			case '\n':	OUTCHAR('n');	break;
314*10465441SEvalZero 			case '\b':	OUTCHAR('b');	break;
315*10465441SEvalZero 			case '\f':	OUTCHAR('f');	break;
316*10465441SEvalZero 			default:
317*10465441SEvalZero 			    OUTCHAR('x');
318*10465441SEvalZero 			    OUTCHAR(hexchars[c >> 4]);
319*10465441SEvalZero 			    OUTCHAR(hexchars[c & 0xf]);
320*10465441SEvalZero 			}
321*10465441SEvalZero 		    } else {
322*10465441SEvalZero 			if (c == '\t')
323*10465441SEvalZero 			    OUTCHAR(c);
324*10465441SEvalZero 			else {
325*10465441SEvalZero 			    OUTCHAR('^');
326*10465441SEvalZero 			    OUTCHAR(c ^ 0x40);
327*10465441SEvalZero 			}
328*10465441SEvalZero 		    }
329*10465441SEvalZero 		} else
330*10465441SEvalZero 		    OUTCHAR(c);
331*10465441SEvalZero 	    }
332*10465441SEvalZero 	    continue;
333*10465441SEvalZero #if PRINTPKT_SUPPORT
334*10465441SEvalZero 	case 'P':		/* print PPP packet */
335*10465441SEvalZero 	    bufinfo.ptr = buf;
336*10465441SEvalZero 	    bufinfo.len = buflen + 1;
337*10465441SEvalZero 	    p = va_arg(args, unsigned char *);
338*10465441SEvalZero 	    n = va_arg(args, int);
339*10465441SEvalZero 	    ppp_format_packet(p, n, ppp_vslp_printer, &bufinfo);
340*10465441SEvalZero 	    buf = bufinfo.ptr;
341*10465441SEvalZero 	    buflen = bufinfo.len - 1;
342*10465441SEvalZero 	    continue;
343*10465441SEvalZero #endif /* PRINTPKT_SUPPORT */
344*10465441SEvalZero 	case 'B':
345*10465441SEvalZero 	    p = va_arg(args, unsigned char *);
346*10465441SEvalZero 	    for (n = prec; n > 0; --n) {
347*10465441SEvalZero 		c = *p++;
348*10465441SEvalZero 		if (fillch == ' ')
349*10465441SEvalZero 		    OUTCHAR(' ');
350*10465441SEvalZero 		OUTCHAR(hexchars[(c >> 4) & 0xf]);
351*10465441SEvalZero 		OUTCHAR(hexchars[c & 0xf]);
352*10465441SEvalZero 	    }
353*10465441SEvalZero 	    continue;
354*10465441SEvalZero 	default:
355*10465441SEvalZero 	    *buf++ = '%';
356*10465441SEvalZero 	    if (c != '%')
357*10465441SEvalZero 		--fmt;		/* so %z outputs %z etc. */
358*10465441SEvalZero 	    --buflen;
359*10465441SEvalZero 	    continue;
360*10465441SEvalZero 	}
361*10465441SEvalZero 	if (base != 0) {
362*10465441SEvalZero 	    str = num + sizeof(num);
363*10465441SEvalZero 	    *--str = 0;
364*10465441SEvalZero 	    while (str > num + neg) {
365*10465441SEvalZero 		*--str = hexchars[val % base];
366*10465441SEvalZero 		val = val / base;
367*10465441SEvalZero 		if (--prec <= 0 && val == 0)
368*10465441SEvalZero 		    break;
369*10465441SEvalZero 	    }
370*10465441SEvalZero 	    switch (neg) {
371*10465441SEvalZero 	    case 1:
372*10465441SEvalZero 		*--str = '-';
373*10465441SEvalZero 		break;
374*10465441SEvalZero 	    case 2:
375*10465441SEvalZero 		*--str = 'x';
376*10465441SEvalZero 		*--str = '0';
377*10465441SEvalZero 		break;
378*10465441SEvalZero 	    default:
379*10465441SEvalZero 		break;
380*10465441SEvalZero 	    }
381*10465441SEvalZero 	    len = num + sizeof(num) - 1 - str;
382*10465441SEvalZero 	} else {
383*10465441SEvalZero 	    len = strlen(str);
384*10465441SEvalZero 	    if (prec >= 0 && len > prec)
385*10465441SEvalZero 		len = prec;
386*10465441SEvalZero 	}
387*10465441SEvalZero 	if (width > 0) {
388*10465441SEvalZero 	    if (width > buflen)
389*10465441SEvalZero 		width = buflen;
390*10465441SEvalZero 	    if ((n = width - len) > 0) {
391*10465441SEvalZero 		buflen -= n;
392*10465441SEvalZero 		for (; n > 0; --n)
393*10465441SEvalZero 		    *buf++ = fillch;
394*10465441SEvalZero 	    }
395*10465441SEvalZero 	}
396*10465441SEvalZero 	if (len > buflen)
397*10465441SEvalZero 	    len = buflen;
398*10465441SEvalZero 	memcpy(buf, str, len);
399*10465441SEvalZero 	buf += len;
400*10465441SEvalZero 	buflen -= len;
401*10465441SEvalZero     }
402*10465441SEvalZero     *buf = 0;
403*10465441SEvalZero     return buf - buf0;
404*10465441SEvalZero }
405*10465441SEvalZero 
406*10465441SEvalZero #if PRINTPKT_SUPPORT
407*10465441SEvalZero /*
408*10465441SEvalZero  * vslp_printer - used in processing a %P format
409*10465441SEvalZero  */
ppp_vslp_printer(void * arg,const char * fmt,...)410*10465441SEvalZero static void ppp_vslp_printer(void *arg, const char *fmt, ...) {
411*10465441SEvalZero     int n;
412*10465441SEvalZero     va_list pvar;
413*10465441SEvalZero     struct buffer_info *bi;
414*10465441SEvalZero 
415*10465441SEvalZero     va_start(pvar, fmt);
416*10465441SEvalZero     bi = (struct buffer_info *) arg;
417*10465441SEvalZero     n = ppp_vslprintf(bi->ptr, bi->len, fmt, pvar);
418*10465441SEvalZero     va_end(pvar);
419*10465441SEvalZero 
420*10465441SEvalZero     bi->ptr += n;
421*10465441SEvalZero     bi->len -= n;
422*10465441SEvalZero }
423*10465441SEvalZero #endif /* PRINTPKT_SUPPORT */
424*10465441SEvalZero 
425*10465441SEvalZero #if 0 /* UNUSED */
426*10465441SEvalZero /*
427*10465441SEvalZero  * log_packet - format a packet and log it.
428*10465441SEvalZero  */
429*10465441SEvalZero 
430*10465441SEvalZero void
431*10465441SEvalZero log_packet(p, len, prefix, level)
432*10465441SEvalZero     u_char *p;
433*10465441SEvalZero     int len;
434*10465441SEvalZero     char *prefix;
435*10465441SEvalZero     int level;
436*10465441SEvalZero {
437*10465441SEvalZero 	init_pr_log(prefix, level);
438*10465441SEvalZero 	ppp_format_packet(p, len, pr_log, &level);
439*10465441SEvalZero 	end_pr_log();
440*10465441SEvalZero }
441*10465441SEvalZero #endif /* UNUSED */
442*10465441SEvalZero 
443*10465441SEvalZero #if PRINTPKT_SUPPORT
444*10465441SEvalZero /*
445*10465441SEvalZero  * ppp_format_packet - make a readable representation of a packet,
446*10465441SEvalZero  * calling `printer(arg, format, ...)' to output it.
447*10465441SEvalZero  */
ppp_format_packet(const u_char * p,int len,void (* printer)(void *,const char *,...),void * arg)448*10465441SEvalZero static void ppp_format_packet(const u_char *p, int len,
449*10465441SEvalZero 		void (*printer) (void *, const char *, ...), void *arg) {
450*10465441SEvalZero     int i, n;
451*10465441SEvalZero     u_short proto;
452*10465441SEvalZero     const struct protent *protp;
453*10465441SEvalZero 
454*10465441SEvalZero     if (len >= 2) {
455*10465441SEvalZero 	GETSHORT(proto, p);
456*10465441SEvalZero 	len -= 2;
457*10465441SEvalZero 	for (i = 0; (protp = protocols[i]) != NULL; ++i)
458*10465441SEvalZero 	    if (proto == protp->protocol)
459*10465441SEvalZero 		break;
460*10465441SEvalZero 	if (protp != NULL) {
461*10465441SEvalZero 	    printer(arg, "[%s", protp->name);
462*10465441SEvalZero 	    n = (*protp->printpkt)(p, len, printer, arg);
463*10465441SEvalZero 	    printer(arg, "]");
464*10465441SEvalZero 	    p += n;
465*10465441SEvalZero 	    len -= n;
466*10465441SEvalZero 	} else {
467*10465441SEvalZero 	    for (i = 0; (protp = protocols[i]) != NULL; ++i)
468*10465441SEvalZero 		if (proto == (protp->protocol & ~0x8000))
469*10465441SEvalZero 		    break;
470*10465441SEvalZero 	    if (protp != 0 && protp->data_name != 0) {
471*10465441SEvalZero 		printer(arg, "[%s data]", protp->data_name);
472*10465441SEvalZero 		if (len > 8)
473*10465441SEvalZero 		    printer(arg, "%.8B ...", p);
474*10465441SEvalZero 		else
475*10465441SEvalZero 		    printer(arg, "%.*B", len, p);
476*10465441SEvalZero 		len = 0;
477*10465441SEvalZero 	    } else
478*10465441SEvalZero 		printer(arg, "[proto=0x%x]", proto);
479*10465441SEvalZero 	}
480*10465441SEvalZero     }
481*10465441SEvalZero 
482*10465441SEvalZero     if (len > 32)
483*10465441SEvalZero 	printer(arg, "%.32B ...", p);
484*10465441SEvalZero     else
485*10465441SEvalZero 	printer(arg, "%.*B", len, p);
486*10465441SEvalZero }
487*10465441SEvalZero #endif /* PRINTPKT_SUPPORT */
488*10465441SEvalZero 
489*10465441SEvalZero #if 0 /* UNUSED */
490*10465441SEvalZero /*
491*10465441SEvalZero  * init_pr_log, end_pr_log - initialize and finish use of pr_log.
492*10465441SEvalZero  */
493*10465441SEvalZero 
494*10465441SEvalZero static char line[256];		/* line to be logged accumulated here */
495*10465441SEvalZero static char *linep;		/* current pointer within line */
496*10465441SEvalZero static int llevel;		/* level for logging */
497*10465441SEvalZero 
498*10465441SEvalZero void
499*10465441SEvalZero init_pr_log(prefix, level)
500*10465441SEvalZero      const char *prefix;
501*10465441SEvalZero      int level;
502*10465441SEvalZero {
503*10465441SEvalZero 	linep = line;
504*10465441SEvalZero 	if (prefix != NULL) {
505*10465441SEvalZero 		ppp_strlcpy(line, prefix, sizeof(line));
506*10465441SEvalZero 		linep = line + strlen(line);
507*10465441SEvalZero 	}
508*10465441SEvalZero 	llevel = level;
509*10465441SEvalZero }
510*10465441SEvalZero 
511*10465441SEvalZero void
512*10465441SEvalZero end_pr_log()
513*10465441SEvalZero {
514*10465441SEvalZero 	if (linep != line) {
515*10465441SEvalZero 		*linep = 0;
516*10465441SEvalZero 		ppp_log_write(llevel, line);
517*10465441SEvalZero 	}
518*10465441SEvalZero }
519*10465441SEvalZero 
520*10465441SEvalZero /*
521*10465441SEvalZero  * pr_log - printer routine for outputting to log
522*10465441SEvalZero  */
523*10465441SEvalZero void
524*10465441SEvalZero pr_log (void *arg, const char *fmt, ...)
525*10465441SEvalZero {
526*10465441SEvalZero 	int l, n;
527*10465441SEvalZero 	va_list pvar;
528*10465441SEvalZero 	char *p, *eol;
529*10465441SEvalZero 	char buf[256];
530*10465441SEvalZero 
531*10465441SEvalZero 	va_start(pvar, fmt);
532*10465441SEvalZero 	n = ppp_vslprintf(buf, sizeof(buf), fmt, pvar);
533*10465441SEvalZero 	va_end(pvar);
534*10465441SEvalZero 
535*10465441SEvalZero 	p = buf;
536*10465441SEvalZero 	eol = strchr(buf, '\n');
537*10465441SEvalZero 	if (linep != line) {
538*10465441SEvalZero 		l = (eol == NULL)? n: eol - buf;
539*10465441SEvalZero 		if (linep + l < line + sizeof(line)) {
540*10465441SEvalZero 			if (l > 0) {
541*10465441SEvalZero 				memcpy(linep, buf, l);
542*10465441SEvalZero 				linep += l;
543*10465441SEvalZero 			}
544*10465441SEvalZero 			if (eol == NULL)
545*10465441SEvalZero 				return;
546*10465441SEvalZero 			p = eol + 1;
547*10465441SEvalZero 			eol = strchr(p, '\n');
548*10465441SEvalZero 		}
549*10465441SEvalZero 		*linep = 0;
550*10465441SEvalZero 		ppp_log_write(llevel, line);
551*10465441SEvalZero 		linep = line;
552*10465441SEvalZero 	}
553*10465441SEvalZero 
554*10465441SEvalZero 	while (eol != NULL) {
555*10465441SEvalZero 		*eol = 0;
556*10465441SEvalZero 		ppp_log_write(llevel, p);
557*10465441SEvalZero 		p = eol + 1;
558*10465441SEvalZero 		eol = strchr(p, '\n');
559*10465441SEvalZero 	}
560*10465441SEvalZero 
561*10465441SEvalZero 	/* assumes sizeof(buf) <= sizeof(line) */
562*10465441SEvalZero 	l = buf + n - p;
563*10465441SEvalZero 	if (l > 0) {
564*10465441SEvalZero 		memcpy(line, p, n);
565*10465441SEvalZero 		linep = line + l;
566*10465441SEvalZero 	}
567*10465441SEvalZero }
568*10465441SEvalZero #endif /* UNUSED */
569*10465441SEvalZero 
570*10465441SEvalZero /*
571*10465441SEvalZero  * ppp_print_string - print a readable representation of a string using
572*10465441SEvalZero  * printer.
573*10465441SEvalZero  */
ppp_print_string(const u_char * p,int len,void (* printer)(void *,const char *,...),void * arg)574*10465441SEvalZero void ppp_print_string(const u_char *p, int len, void (*printer) (void *, const char *, ...), void *arg) {
575*10465441SEvalZero     int c;
576*10465441SEvalZero 
577*10465441SEvalZero     printer(arg, "\"");
578*10465441SEvalZero     for (; len > 0; --len) {
579*10465441SEvalZero 	c = *p++;
580*10465441SEvalZero 	if (' ' <= c && c <= '~') {
581*10465441SEvalZero 	    if (c == '\\' || c == '"')
582*10465441SEvalZero 		printer(arg, "\\");
583*10465441SEvalZero 	    printer(arg, "%c", c);
584*10465441SEvalZero 	} else {
585*10465441SEvalZero 	    switch (c) {
586*10465441SEvalZero 	    case '\n':
587*10465441SEvalZero 		printer(arg, "\\n");
588*10465441SEvalZero 		break;
589*10465441SEvalZero 	    case '\r':
590*10465441SEvalZero 		printer(arg, "\\r");
591*10465441SEvalZero 		break;
592*10465441SEvalZero 	    case '\t':
593*10465441SEvalZero 		printer(arg, "\\t");
594*10465441SEvalZero 		break;
595*10465441SEvalZero 	    default:
596*10465441SEvalZero 		printer(arg, "\\%.3o", (u8_t)c);
597*10465441SEvalZero 		/* no break */
598*10465441SEvalZero 	    }
599*10465441SEvalZero 	}
600*10465441SEvalZero     }
601*10465441SEvalZero     printer(arg, "\"");
602*10465441SEvalZero }
603*10465441SEvalZero 
604*10465441SEvalZero /*
605*10465441SEvalZero  * ppp_logit - does the hard work for fatal et al.
606*10465441SEvalZero  */
ppp_logit(int level,const char * fmt,va_list args)607*10465441SEvalZero static void ppp_logit(int level, const char *fmt, va_list args) {
608*10465441SEvalZero     char buf[1024];
609*10465441SEvalZero 
610*10465441SEvalZero     ppp_vslprintf(buf, sizeof(buf), fmt, args);
611*10465441SEvalZero     ppp_log_write(level, buf);
612*10465441SEvalZero }
613*10465441SEvalZero 
ppp_log_write(int level,char * buf)614*10465441SEvalZero static void ppp_log_write(int level, char *buf) {
615*10465441SEvalZero     LWIP_UNUSED_ARG(level); /* necessary if PPPDEBUG is defined to an empty function */
616*10465441SEvalZero     LWIP_UNUSED_ARG(buf);
617*10465441SEvalZero     PPPDEBUG(level, ("%s\n", buf) );
618*10465441SEvalZero #if 0
619*10465441SEvalZero     if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) {
620*10465441SEvalZero 	int n = strlen(buf);
621*10465441SEvalZero 
622*10465441SEvalZero 	if (n > 0 && buf[n-1] == '\n')
623*10465441SEvalZero 	    --n;
624*10465441SEvalZero 	if (write(log_to_fd, buf, n) != n
625*10465441SEvalZero 	    || write(log_to_fd, "\n", 1) != 1)
626*10465441SEvalZero 	    log_to_fd = -1;
627*10465441SEvalZero     }
628*10465441SEvalZero #endif
629*10465441SEvalZero }
630*10465441SEvalZero 
631*10465441SEvalZero /*
632*10465441SEvalZero  * ppp_fatal - log an error message and die horribly.
633*10465441SEvalZero  */
ppp_fatal(const char * fmt,...)634*10465441SEvalZero void ppp_fatal(const char *fmt, ...) {
635*10465441SEvalZero     va_list pvar;
636*10465441SEvalZero 
637*10465441SEvalZero     va_start(pvar, fmt);
638*10465441SEvalZero     ppp_logit(LOG_ERR, fmt, pvar);
639*10465441SEvalZero     va_end(pvar);
640*10465441SEvalZero 
641*10465441SEvalZero     LWIP_ASSERT("ppp_fatal", 0);   /* as promised */
642*10465441SEvalZero }
643*10465441SEvalZero 
644*10465441SEvalZero /*
645*10465441SEvalZero  * ppp_error - log an error message.
646*10465441SEvalZero  */
ppp_error(const char * fmt,...)647*10465441SEvalZero void ppp_error(const char *fmt, ...) {
648*10465441SEvalZero     va_list pvar;
649*10465441SEvalZero 
650*10465441SEvalZero     va_start(pvar, fmt);
651*10465441SEvalZero     ppp_logit(LOG_ERR, fmt, pvar);
652*10465441SEvalZero     va_end(pvar);
653*10465441SEvalZero #if 0 /* UNUSED */
654*10465441SEvalZero     ++error_count;
655*10465441SEvalZero #endif /* UNUSED */
656*10465441SEvalZero }
657*10465441SEvalZero 
658*10465441SEvalZero /*
659*10465441SEvalZero  * ppp_warn - log a warning message.
660*10465441SEvalZero  */
ppp_warn(const char * fmt,...)661*10465441SEvalZero void ppp_warn(const char *fmt, ...) {
662*10465441SEvalZero     va_list pvar;
663*10465441SEvalZero 
664*10465441SEvalZero     va_start(pvar, fmt);
665*10465441SEvalZero     ppp_logit(LOG_WARNING, fmt, pvar);
666*10465441SEvalZero     va_end(pvar);
667*10465441SEvalZero }
668*10465441SEvalZero 
669*10465441SEvalZero /*
670*10465441SEvalZero  * ppp_notice - log a notice-level message.
671*10465441SEvalZero  */
ppp_notice(const char * fmt,...)672*10465441SEvalZero void ppp_notice(const char *fmt, ...) {
673*10465441SEvalZero     va_list pvar;
674*10465441SEvalZero 
675*10465441SEvalZero     va_start(pvar, fmt);
676*10465441SEvalZero     ppp_logit(LOG_NOTICE, fmt, pvar);
677*10465441SEvalZero     va_end(pvar);
678*10465441SEvalZero }
679*10465441SEvalZero 
680*10465441SEvalZero /*
681*10465441SEvalZero  * ppp_info - log an informational message.
682*10465441SEvalZero  */
ppp_info(const char * fmt,...)683*10465441SEvalZero void ppp_info(const char *fmt, ...) {
684*10465441SEvalZero     va_list pvar;
685*10465441SEvalZero 
686*10465441SEvalZero     va_start(pvar, fmt);
687*10465441SEvalZero     ppp_logit(LOG_INFO, fmt, pvar);
688*10465441SEvalZero     va_end(pvar);
689*10465441SEvalZero }
690*10465441SEvalZero 
691*10465441SEvalZero /*
692*10465441SEvalZero  * ppp_dbglog - log a debug message.
693*10465441SEvalZero  */
ppp_dbglog(const char * fmt,...)694*10465441SEvalZero void ppp_dbglog(const char *fmt, ...) {
695*10465441SEvalZero     va_list pvar;
696*10465441SEvalZero 
697*10465441SEvalZero     va_start(pvar, fmt);
698*10465441SEvalZero     ppp_logit(LOG_DEBUG, fmt, pvar);
699*10465441SEvalZero     va_end(pvar);
700*10465441SEvalZero }
701*10465441SEvalZero 
702*10465441SEvalZero #if PRINTPKT_SUPPORT
703*10465441SEvalZero /*
704*10465441SEvalZero  * ppp_dump_packet - print out a packet in readable form if it is interesting.
705*10465441SEvalZero  * Assumes len >= PPP_HDRLEN.
706*10465441SEvalZero  */
ppp_dump_packet(ppp_pcb * pcb,const char * tag,unsigned char * p,int len)707*10465441SEvalZero void ppp_dump_packet(ppp_pcb *pcb, const char *tag, unsigned char *p, int len) {
708*10465441SEvalZero     int proto;
709*10465441SEvalZero 
710*10465441SEvalZero     /*
711*10465441SEvalZero      * don't print data packets, i.e. IPv4, IPv6, VJ, and compressed packets.
712*10465441SEvalZero      */
713*10465441SEvalZero     proto = (p[0] << 8) + p[1];
714*10465441SEvalZero     if (proto < 0xC000 && (proto & ~0x8000) == proto)
715*10465441SEvalZero 	return;
716*10465441SEvalZero 
717*10465441SEvalZero     /*
718*10465441SEvalZero      * don't print valid LCP echo request/reply packets if the link is up.
719*10465441SEvalZero      */
720*10465441SEvalZero     if (proto == PPP_LCP && pcb->phase == PPP_PHASE_RUNNING && len >= 2 + HEADERLEN) {
721*10465441SEvalZero 	unsigned char *lcp = p + 2;
722*10465441SEvalZero 	int l = (lcp[2] << 8) + lcp[3];
723*10465441SEvalZero 
724*10465441SEvalZero 	if ((lcp[0] == ECHOREQ || lcp[0] == ECHOREP)
725*10465441SEvalZero 	    && l >= HEADERLEN && l <= len - 2)
726*10465441SEvalZero 	    return;
727*10465441SEvalZero     }
728*10465441SEvalZero 
729*10465441SEvalZero     ppp_dbglog("%s %P", tag, p, len);
730*10465441SEvalZero }
731*10465441SEvalZero #endif /* PRINTPKT_SUPPORT */
732*10465441SEvalZero 
733*10465441SEvalZero #if 0 /* Unused */
734*10465441SEvalZero 
735*10465441SEvalZero /*
736*10465441SEvalZero  * complete_read - read a full `count' bytes from fd,
737*10465441SEvalZero  * unless end-of-file or an error other than EINTR is encountered.
738*10465441SEvalZero  */
739*10465441SEvalZero ssize_t
740*10465441SEvalZero complete_read(int fd, void *buf, size_t count)
741*10465441SEvalZero {
742*10465441SEvalZero 	size_t done;
743*10465441SEvalZero 	ssize_t nb;
744*10465441SEvalZero 	char *ptr = buf;
745*10465441SEvalZero 
746*10465441SEvalZero 	for (done = 0; done < count; ) {
747*10465441SEvalZero 		nb = read(fd, ptr, count - done);
748*10465441SEvalZero 		if (nb < 0) {
749*10465441SEvalZero 			if (errno == EINTR)
750*10465441SEvalZero 				continue;
751*10465441SEvalZero 			return -1;
752*10465441SEvalZero 		}
753*10465441SEvalZero 		if (nb == 0)
754*10465441SEvalZero 			break;
755*10465441SEvalZero 		done += nb;
756*10465441SEvalZero 		ptr += nb;
757*10465441SEvalZero 	}
758*10465441SEvalZero 	return done;
759*10465441SEvalZero }
760*10465441SEvalZero 
761*10465441SEvalZero /* Procedures for locking the serial device using a lock file. */
762*10465441SEvalZero #ifndef LOCK_DIR
763*10465441SEvalZero #ifdef __linux__
764*10465441SEvalZero #define LOCK_DIR	"/var/lock"
765*10465441SEvalZero #else
766*10465441SEvalZero #ifdef SVR4
767*10465441SEvalZero #define LOCK_DIR	"/var/spool/locks"
768*10465441SEvalZero #else
769*10465441SEvalZero #define LOCK_DIR	"/var/spool/lock"
770*10465441SEvalZero #endif
771*10465441SEvalZero #endif
772*10465441SEvalZero #endif /* LOCK_DIR */
773*10465441SEvalZero 
774*10465441SEvalZero static char lock_file[MAXPATHLEN];
775*10465441SEvalZero 
776*10465441SEvalZero /*
777*10465441SEvalZero  * lock - create a lock file for the named device
778*10465441SEvalZero  */
779*10465441SEvalZero int
780*10465441SEvalZero lock(dev)
781*10465441SEvalZero     char *dev;
782*10465441SEvalZero {
783*10465441SEvalZero #ifdef LOCKLIB
784*10465441SEvalZero     int result;
785*10465441SEvalZero 
786*10465441SEvalZero     result = mklock (dev, (void *) 0);
787*10465441SEvalZero     if (result == 0) {
788*10465441SEvalZero 	ppp_strlcpy(lock_file, dev, sizeof(lock_file));
789*10465441SEvalZero 	return 0;
790*10465441SEvalZero     }
791*10465441SEvalZero 
792*10465441SEvalZero     if (result > 0)
793*10465441SEvalZero         ppp_notice("Device %s is locked by pid %d", dev, result);
794*10465441SEvalZero     else
795*10465441SEvalZero 	ppp_error("Can't create lock file %s", lock_file);
796*10465441SEvalZero     return -1;
797*10465441SEvalZero 
798*10465441SEvalZero #else /* LOCKLIB */
799*10465441SEvalZero 
800*10465441SEvalZero     char lock_buffer[12];
801*10465441SEvalZero     int fd, pid, n;
802*10465441SEvalZero 
803*10465441SEvalZero #ifdef SVR4
804*10465441SEvalZero     struct stat sbuf;
805*10465441SEvalZero 
806*10465441SEvalZero     if (stat(dev, &sbuf) < 0) {
807*10465441SEvalZero 	ppp_error("Can't get device number for %s: %m", dev);
808*10465441SEvalZero 	return -1;
809*10465441SEvalZero     }
810*10465441SEvalZero     if ((sbuf.st_mode & S_IFMT) != S_IFCHR) {
811*10465441SEvalZero 	ppp_error("Can't lock %s: not a character device", dev);
812*10465441SEvalZero 	return -1;
813*10465441SEvalZero     }
814*10465441SEvalZero     ppp_slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d",
815*10465441SEvalZero 	     LOCK_DIR, major(sbuf.st_dev),
816*10465441SEvalZero 	     major(sbuf.st_rdev), minor(sbuf.st_rdev));
817*10465441SEvalZero #else
818*10465441SEvalZero     char *p;
819*10465441SEvalZero     char lockdev[MAXPATHLEN];
820*10465441SEvalZero 
821*10465441SEvalZero     if ((p = strstr(dev, "dev/")) != NULL) {
822*10465441SEvalZero 	dev = p + 4;
823*10465441SEvalZero 	strncpy(lockdev, dev, MAXPATHLEN-1);
824*10465441SEvalZero 	lockdev[MAXPATHLEN-1] = 0;
825*10465441SEvalZero 	while ((p = strrchr(lockdev, '/')) != NULL) {
826*10465441SEvalZero 	    *p = '_';
827*10465441SEvalZero 	}
828*10465441SEvalZero 	dev = lockdev;
829*10465441SEvalZero     } else
830*10465441SEvalZero 	if ((p = strrchr(dev, '/')) != NULL)
831*10465441SEvalZero 	    dev = p + 1;
832*10465441SEvalZero 
833*10465441SEvalZero     ppp_slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev);
834*10465441SEvalZero #endif
835*10465441SEvalZero 
836*10465441SEvalZero     while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
837*10465441SEvalZero 	if (errno != EEXIST) {
838*10465441SEvalZero 	    ppp_error("Can't create lock file %s: %m", lock_file);
839*10465441SEvalZero 	    break;
840*10465441SEvalZero 	}
841*10465441SEvalZero 
842*10465441SEvalZero 	/* Read the lock file to find out who has the device locked. */
843*10465441SEvalZero 	fd = open(lock_file, O_RDONLY, 0);
844*10465441SEvalZero 	if (fd < 0) {
845*10465441SEvalZero 	    if (errno == ENOENT) /* This is just a timing problem. */
846*10465441SEvalZero 		continue;
847*10465441SEvalZero 	    ppp_error("Can't open existing lock file %s: %m", lock_file);
848*10465441SEvalZero 	    break;
849*10465441SEvalZero 	}
850*10465441SEvalZero #ifndef LOCK_BINARY
851*10465441SEvalZero 	n = read(fd, lock_buffer, 11);
852*10465441SEvalZero #else
853*10465441SEvalZero 	n = read(fd, &pid, sizeof(pid));
854*10465441SEvalZero #endif /* LOCK_BINARY */
855*10465441SEvalZero 	close(fd);
856*10465441SEvalZero 	fd = -1;
857*10465441SEvalZero 	if (n <= 0) {
858*10465441SEvalZero 	    ppp_error("Can't read pid from lock file %s", lock_file);
859*10465441SEvalZero 	    break;
860*10465441SEvalZero 	}
861*10465441SEvalZero 
862*10465441SEvalZero 	/* See if the process still exists. */
863*10465441SEvalZero #ifndef LOCK_BINARY
864*10465441SEvalZero 	lock_buffer[n] = 0;
865*10465441SEvalZero 	pid = atoi(lock_buffer);
866*10465441SEvalZero #endif /* LOCK_BINARY */
867*10465441SEvalZero 	if (pid == getpid())
868*10465441SEvalZero 	    return 1;		/* somebody else locked it for us */
869*10465441SEvalZero 	if (pid == 0
870*10465441SEvalZero 	    || (kill(pid, 0) == -1 && errno == ESRCH)) {
871*10465441SEvalZero 	    if (unlink (lock_file) == 0) {
872*10465441SEvalZero 		ppp_notice("Removed stale lock on %s (pid %d)", dev, pid);
873*10465441SEvalZero 		continue;
874*10465441SEvalZero 	    }
875*10465441SEvalZero 	    ppp_warn("Couldn't remove stale lock on %s", dev);
876*10465441SEvalZero 	} else
877*10465441SEvalZero 	    ppp_notice("Device %s is locked by pid %d", dev, pid);
878*10465441SEvalZero 	break;
879*10465441SEvalZero     }
880*10465441SEvalZero 
881*10465441SEvalZero     if (fd < 0) {
882*10465441SEvalZero 	lock_file[0] = 0;
883*10465441SEvalZero 	return -1;
884*10465441SEvalZero     }
885*10465441SEvalZero 
886*10465441SEvalZero     pid = getpid();
887*10465441SEvalZero #ifndef LOCK_BINARY
888*10465441SEvalZero     ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
889*10465441SEvalZero     write (fd, lock_buffer, 11);
890*10465441SEvalZero #else
891*10465441SEvalZero     write(fd, &pid, sizeof (pid));
892*10465441SEvalZero #endif
893*10465441SEvalZero     close(fd);
894*10465441SEvalZero     return 0;
895*10465441SEvalZero 
896*10465441SEvalZero #endif
897*10465441SEvalZero }
898*10465441SEvalZero 
899*10465441SEvalZero /*
900*10465441SEvalZero  * relock - called to update our lockfile when we are about to detach,
901*10465441SEvalZero  * thus changing our pid (we fork, the child carries on, and the parent dies).
902*10465441SEvalZero  * Note that this is called by the parent, with pid equal to the pid
903*10465441SEvalZero  * of the child.  This avoids a potential race which would exist if
904*10465441SEvalZero  * we had the child rewrite the lockfile (the parent might die first,
905*10465441SEvalZero  * and another process could think the lock was stale if it checked
906*10465441SEvalZero  * between when the parent died and the child rewrote the lockfile).
907*10465441SEvalZero  */
908*10465441SEvalZero int
909*10465441SEvalZero relock(pid)
910*10465441SEvalZero     int pid;
911*10465441SEvalZero {
912*10465441SEvalZero #ifdef LOCKLIB
913*10465441SEvalZero     /* XXX is there a way to do this? */
914*10465441SEvalZero     return -1;
915*10465441SEvalZero #else /* LOCKLIB */
916*10465441SEvalZero 
917*10465441SEvalZero     int fd;
918*10465441SEvalZero     char lock_buffer[12];
919*10465441SEvalZero 
920*10465441SEvalZero     if (lock_file[0] == 0)
921*10465441SEvalZero 	return -1;
922*10465441SEvalZero     fd = open(lock_file, O_WRONLY, 0);
923*10465441SEvalZero     if (fd < 0) {
924*10465441SEvalZero 	ppp_error("Couldn't reopen lock file %s: %m", lock_file);
925*10465441SEvalZero 	lock_file[0] = 0;
926*10465441SEvalZero 	return -1;
927*10465441SEvalZero     }
928*10465441SEvalZero 
929*10465441SEvalZero #ifndef LOCK_BINARY
930*10465441SEvalZero     ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
931*10465441SEvalZero     write (fd, lock_buffer, 11);
932*10465441SEvalZero #else
933*10465441SEvalZero     write(fd, &pid, sizeof(pid));
934*10465441SEvalZero #endif /* LOCK_BINARY */
935*10465441SEvalZero     close(fd);
936*10465441SEvalZero     return 0;
937*10465441SEvalZero 
938*10465441SEvalZero #endif /* LOCKLIB */
939*10465441SEvalZero }
940*10465441SEvalZero 
941*10465441SEvalZero /*
942*10465441SEvalZero  * unlock - remove our lockfile
943*10465441SEvalZero  */
944*10465441SEvalZero void
945*10465441SEvalZero unlock()
946*10465441SEvalZero {
947*10465441SEvalZero     if (lock_file[0]) {
948*10465441SEvalZero #ifdef LOCKLIB
949*10465441SEvalZero 	(void) rmlock(lock_file, (void *) 0);
950*10465441SEvalZero #else
951*10465441SEvalZero 	unlink(lock_file);
952*10465441SEvalZero #endif
953*10465441SEvalZero 	lock_file[0] = 0;
954*10465441SEvalZero     }
955*10465441SEvalZero }
956*10465441SEvalZero 
957*10465441SEvalZero #endif /* Unused */
958*10465441SEvalZero 
959*10465441SEvalZero #endif /* PPP_SUPPORT */
960