1/* util.c ....... error message utilities. 2 * C. Scott Ananian <cananian@alumni.princeton.edu> 3 * 4 * $Id: util.c,v 1.11 2005/08/22 00:49:48 quozl Exp $ 5 */ 6 7#include <stdio.h> 8#include <stdarg.h> 9#include <syslog.h> 10#include <unistd.h> 11#include <stdlib.h> 12#include "util.h" 13 14#ifndef PROGRAM_NAME 15#define PROGRAM_NAME "pptp" 16#endif 17 18/* implementation of log_string, defined as extern in util.h */ 19char *log_string = "anon"; 20 21static void open_log(void) __attribute__ ((constructor)); 22static void close_log(void) __attribute__ ((destructor)); 23 24#define MAKE_STRING(label) \ 25va_list ap; \ 26char buf[256], string[256]; \ 27va_start(ap, format); \ 28vsnprintf(buf, sizeof(buf), format, ap); \ 29snprintf(string, sizeof(string), "%s", buf); \ 30va_end(ap) 31 32/*** open log *****************************************************************/ 33static void open_log(void) { 34 openlog(PROGRAM_NAME, LOG_PID, LOG_DAEMON); 35} 36 37/*** close log ****************************************************************/ 38static void close_log(void) 39{ 40 closelog(); 41} 42 43/*** print a message to syslog ************************************************/ 44void _log(const char *func, const char *file, int line, const char *format, ...) 45{ 46 if (log_level > 0) 47 { 48 MAKE_STRING("log"); 49 syslog(LOG_NOTICE, "%s", string); 50 } 51} 52 53/*** print a warning to syslog ************************************************/ 54void _warn(const char *func, const char *file, int line, const char *format, ...) 55{ 56 MAKE_STRING("warn"); 57 fprintf(stderr, "%s\n", string); 58 syslog(LOG_WARNING, "%s", string); 59} 60 61/*** print a fatal warning to syslog and exit *********************************/ 62void _fatal(const char *func, const char *file, int line, const char *format, ...) 63{ 64 MAKE_STRING("fatal"); 65 fprintf(stderr, "%s\n", string); 66 syslog(LOG_CRIT, "%s", string); 67 exit(1); 68} 69 70/*** connect a file to a file descriptor **************************************/ 71int file2fd(const char *path, const char *mode, int fd) 72{ 73 int ok = 0; 74 FILE *file = NULL; 75 file = fopen(path, mode); 76 if (file != NULL && dup2(fileno(file), fd) != -1) 77 ok = 1; 78 if (file) fclose(file); 79 return ok; 80} 81 82/* signal to pipe delivery implementation */ 83#include <unistd.h> 84#include <fcntl.h> 85#include <signal.h> 86#include <string.h> 87 88/* pipe private to process */ 89static int sigpipe[2]; 90 91/* create a signal pipe, returns 0 for success, -1 with errno for failure */ 92int sigpipe_create() 93{ 94 int rc; 95 96 rc = pipe(sigpipe); 97 if (rc < 0) return rc; 98 99 fcntl(sigpipe[0], F_SETFD, FD_CLOEXEC); 100 fcntl(sigpipe[1], F_SETFD, FD_CLOEXEC); 101 102#ifdef O_NONBLOCK 103#define FLAG_TO_SET O_NONBLOCK 104#else 105#ifdef SYSV 106#define FLAG_TO_SET O_NDELAY 107#else /* BSD */ 108#define FLAG_TO_SET FNDELAY 109#endif 110#endif 111 112 rc = fcntl(sigpipe[1], F_GETFL); 113 if (rc != -1) 114 rc = fcntl(sigpipe[1], F_SETFL, rc | FLAG_TO_SET); 115 if (rc < 0) return rc; 116 return 0; 117#undef FLAG_TO_SET 118} 119 120/* generic handler for signals, writes signal number to pipe */ 121void sigpipe_handler(int signum) 122{ 123 write(sigpipe[1], &signum, sizeof(signum)); 124 signal(signum, sigpipe_handler); 125} 126 127/* assign a signal number to the pipe */ 128void sigpipe_assign(int signum) 129{ 130 struct sigaction sa; 131 132 memset(&sa, 0, sizeof(sa)); 133 sa.sa_handler = sigpipe_handler; 134 sigaction(signum, &sa, NULL); 135} 136 137/* return the signal pipe read file descriptor for select(2) */ 138int sigpipe_fd() 139{ 140 return sigpipe[0]; 141} 142 143/* read and return the pending signal from the pipe */ 144int sigpipe_read() 145{ 146 int signum; 147 read(sigpipe[0], &signum, sizeof(signum)); 148 return signum; 149} 150 151void sigpipe_close() 152{ 153 close(sigpipe[0]); 154 close(sigpipe[1]); 155} 156 157