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