X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Futils.c;h=e75bb9c8eecd21279a999c18f8c0bc4f132ef1e3;hp=fd213c2044725993565f8352d9e6e05959d70292;hb=HEAD;hpb=214aeb163eb309c53793609871abbac1b793aa52 diff --git a/pppd/utils.c b/pppd/utils.c index fd213c2..bf9923c 100644 --- a/pppd/utils.c +++ b/pppd/utils.c @@ -17,7 +17,7 @@ * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras - * ". + * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY @@ -58,16 +58,17 @@ #include #endif -#include "pppd.h" +#include "pppd-private.h" #include "fsm.h" #include "lcp.h" +#include "pathnames.h" #if defined(SUNOS4) extern char *strerror(); #endif -static void logit(int, char *, va_list); +static void logit(int, const char *, va_list); static void log_write(int, char *); static void vslp_printer(void *, char *, ...); static void format_packet(u_char *, int, printer_func, void *); @@ -119,7 +120,7 @@ strlcat(char *dest, const char *src, size_t len) * Returns the number of chars put into buf. */ int -slprintf(char *buf, int buflen, char *fmt, ...) +slprintf(char *buf, int buflen, const char *fmt, ...) { va_list args; int n; @@ -136,14 +137,15 @@ slprintf(char *buf, int buflen, char *fmt, ...) #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) int -vslprintf(char *buf, int buflen, char *fmt, va_list args) +vslprintf(char *buf, int buflen, const char *fmt, va_list args) { int c, i, n; int width, prec, fillch; int base, len, neg, quoted; long lval = 0; unsigned long val = 0; - char *str, *f, *buf0; + char *str, *buf0; + const char *f; unsigned char *p; char num[32]; time_t t; @@ -599,7 +601,7 @@ print_string(char *p, int len, printer_func printer, void *arg) * logit - does the hard work for fatal et al. */ static void -logit(int level, char *fmt, va_list args) +logit(int level, const char *fmt, va_list args) { char buf[1024]; @@ -634,7 +636,7 @@ log_write(int level, char *buf) * fatal - log an error message and die horribly. */ void -fatal(char *fmt, ...) +fatal(const char *fmt, ...) { va_list pvar; @@ -654,7 +656,7 @@ fatal(char *fmt, ...) * error - log an error message. */ void -error(char *fmt, ...) +error(const char *fmt, ...) { va_list pvar; @@ -669,7 +671,7 @@ error(char *fmt, ...) * warn - log a warning message. */ void -warn(char *fmt, ...) +warn(const char *fmt, ...) { va_list pvar; @@ -683,7 +685,7 @@ warn(char *fmt, ...) * notice - log a notice-level message. */ void -notice(char *fmt, ...) +notice(const char *fmt, ...) { va_list pvar; @@ -697,7 +699,7 @@ notice(char *fmt, ...) * info - log an informational message. */ void -info(char *fmt, ...) +info(const char *fmt, ...) { va_list pvar; @@ -711,7 +713,7 @@ info(char *fmt, ...) * dbglog - log a debug message. */ void -dbglog(char *fmt, ...) +dbglog(const char *fmt, ...) { va_list pvar; @@ -767,7 +769,7 @@ complete_read(int fd, void *buf, size_t count) for (done = 0; done < count; ) { nb = read(fd, ptr, count - done); if (nb < 0) { - if (errno == EINTR && !got_sigterm) + if (errno == EINTR && !ppp_signaled(SIGTERM)) continue; return -1; } @@ -780,19 +782,89 @@ complete_read(int fd, void *buf, size_t count) } #endif -/* Procedures for locking the serial device using a lock file. */ -#ifndef LOCK_DIR -#ifdef __linux__ -#define LOCK_DIR "/var/lock" -#else -#ifdef SVR4 -#define LOCK_DIR "/var/spool/locks" -#else -#define LOCK_DIR "/var/spool/lock" -#endif -#endif -#endif /* LOCK_DIR */ +/* + * mkdir_check - helper for mkdir_recursive, creates a directory + * but do not error on EEXIST if and only if entry is a directory + * The caller must check for errno == ENOENT if appropriate. + */ +static int +mkdir_check(const char *path) +{ + struct stat statbuf; + + if (mkdir(path, 0755) >= 0) + return 0; + + if (errno == EEXIST) { + if (stat(path, &statbuf) < 0) + /* got raced? */ + return -1; + + if ((statbuf.st_mode & S_IFMT) == S_IFDIR) + return 0; + + /* already exists but not a dir, treat as failure */ + errno = EEXIST; + return -1; + } + + return -1; +} + +/* + * mkdir_parent - helper for mkdir_recursive, modifies the string in place + * Assumes mkdir(path) already failed, so it first creates the parent then + * full path again. + */ +static int +mkdir_parent(char *path) +{ + char *slash; + int rc; + slash = strrchr(path, '/'); + if (!slash) + return -1; + + *slash = 0; + if (mkdir_check(path) < 0) { + if (errno != ENOENT) { + *slash = '/'; + return -1; + } + if (mkdir_parent(path) < 0) { + *slash = '/'; + return -1; + } + } + *slash = '/'; + + return mkdir_check(path); +} + +/* + * mkdir_recursive - recursively create directory if it didn't exist + */ +int +mkdir_recursive(const char *path) +{ + char *copy; + int rc; + + // optimistically try on full path first to avoid allocation + if (mkdir_check(path) == 0) + return 0; + + copy = strdup(path); + if (!copy) + return -1; + + rc = mkdir_parent(copy); + free(copy); + return rc; +} + +/* Procedures for locking the serial device using a lock file. */ static char lock_file[MAXPATHLEN]; /* @@ -819,7 +891,7 @@ lock(char *dev) #else /* LOCKLIB */ char lock_buffer[12]; - int fd, pid, n; + int fd, pid, n, siz; #ifdef SVR4 struct stat sbuf; @@ -833,7 +905,7 @@ lock(char *dev) return -1; } slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d", - LOCK_DIR, major(sbuf.st_dev), + PPP_PATH_LOCKDIR, major(sbuf.st_dev), major(sbuf.st_rdev), minor(sbuf.st_rdev)); #else char *p; @@ -851,7 +923,7 @@ lock(char *dev) if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; - slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev); + slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", PPP_PATH_LOCKDIR, dev); #endif while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { @@ -906,11 +978,16 @@ lock(char *dev) pid = getpid(); #ifndef LOCK_BINARY + siz = 11; slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); - write (fd, lock_buffer, 11); + n = write (fd, lock_buffer, siz); #else - write(fd, &pid, sizeof (pid)); + siz = sizeof (pid); + n = write(fd, &pid, siz); #endif + if (n != siz) { + error("Could not write pid to lock file when locking"); + } close(fd); return 0; @@ -934,7 +1011,7 @@ relock(int pid) return -1; #else /* LOCKLIB */ - int fd; + int fd, n, siz; char lock_buffer[12]; if (lock_file[0] == 0) @@ -947,11 +1024,16 @@ relock(int pid) } #ifndef LOCK_BINARY + siz = 11; slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); - write (fd, lock_buffer, 11); + n = write (fd, lock_buffer, siz); #else - write(fd, &pid, sizeof(pid)); + siz = sizeof(pid); + n = write(fd, &pid, siz); #endif /* LOCK_BINARY */ + if (n != siz) { + error("Could not write pid to lock file when locking"); + } close(fd); return 0;