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