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