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