1 /*
2 * Copyright (c) 1997-2012 Motonori Nakamura <motonori@wide.ad.jp>
3 * Copyright (c) 1997-2012 WIDE Project
4 * Copyright (c) 1997-2003 Kyoto University
5 * Copyright (c) 2012 National Institute of Informatics
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by WIDE Project and
20 * its contributors.
21 * 4. Neither the name of the Project, the University nor the names of
22 * its contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38 #ifndef lint
39 static char *_id_ = "$Id: log.c,v 1.14 2012/06/07 07:51:35 motonori Exp $";
40 #endif
41
42 # include "common.h"
43 # include "extern.h"
44
45 #define SYSLOG_FD
46 #ifdef SYSLOG_FD
47 static int syslog_fd = -1;
48 #endif
49
50 void
init_logg()51 init_logg()
52 {
53 #ifdef SYSLOG_FD
54 int fd_before, fd_after;
55 #endif
56
57 if (cnf.log_facility < 0)
58 return;
59
60 #ifdef SYSLOG_FD
61 /* a hack to get the file descriptor for /dev/log */
62 fd_before = open ("/dev/null", O_WRONLY, 0);
63 if (fd_before >= 0)
64 close(fd_before);
65 #endif
66
67 openlog("smtpfeed", LOG_NDELAY|LOG_PID, cnf.log_facility);
68
69 #ifdef SYSLOG_FD
70 fd_after = open ("/dev/null", O_WRONLY, 0);
71 if (fd_after >= 0)
72 close(fd_after);
73 if (fd_before >= 0 && fd_before != fd_after)
74 {
75 syslog_fd = fd_before;
76 if (cnf.debug & DEBUG_TRANS)
77 logg(LOG_DEBUG, "file descriptor for syslog: %d", syslog_fd);
78 }
79 #endif
80 }
81
82 #ifdef SYSLOG_FD
83 #define SLEEPTIME 100000 /* micro second */
84 #define SYSLOG_RETRY 1000
85 #endif
86
87 void
88 # ifdef __STDC__
logg(int level,const char * fmt,...)89 logg(int level, const char *fmt, ...)
90 # else
91 logg(level, fmt, va_alist)
92 int level;
93 char *fmt;
94 va_dcl
95 # endif
96 {
97 char buf[MAXLINE];
98 int len, save_errno;
99 VA_LOCAL_DECL
100
101 if (cnf.log_facility == LOG_NONE)
102 return;
103 buf[0] = '\0';
104 save_errno = errno;
105 if (env.queueid != NULL)
106 strncpy(buf, env.queueid, MAXLINE);
107 else if (env.envid != NULL)
108 strncpy(buf, env.envid, MAXLINE);
109 else
110 strcpy(buf, "NOID");
111 len = strlen(buf);
112 if (len >= MAXLINE-2)
113 len = 0;
114 else {
115 strcat(buf, ": ");
116 len += 2;
117 }
118
119 VA_START(fmt);
120 vsnprintf(buf+len, sizeof(buf)-len, fmt, ap);
121 VA_END;
122
123 if (cnf.log_facility == LOG_STDERR) {
124 fprintf(stderr, "%s\n", buf);
125 } else {
126 #ifdef SYSLOG_FD
127 int retry = SYSLOG_RETRY;
128
129 errno = 0;
130 #endif
131 syslog(level, "%s", buf);
132 #ifdef SYSLOG_FD
133 while (errno == ENOBUFS && syslog_fd >= 0)
134 {
135 /* retry to write out into syslog */
136 struct timeval timeout;
137 static fd_set slmask;
138 int r;
139
140 timeout.tv_sec = 0;
141 timeout.tv_usec = SLEEPTIME;
142 FD_ZERO(&slmask);
143 FD_SET(syslog_fd, &slmask);
144 r = select(syslog_fd + 1, (fd_set *)NULL, &slmask,
145 (fd_set *)NULL, &timeout);
146 if (r > 0)
147 {
148 /* ready to write */
149 errno = 0;
150 syslog(level, "%s", buf);
151 }
152 if (r < 0 || --retry <= 0)
153 break;
154 }
155 #endif
156 }
157 errno = save_errno;
158 }
159