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