3 * A pale imitation of syslogd. Most notably, doesn't write anything
4 * anywhere except possibly back to syslogd.
6 * Copyright (c) 1999-2001 Red Hat, Inc. All rights reserved.
8 * This software may be freely redistributed under the terms of the GNU
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <sys/socket.h>
30 static int we_own_log=0;
31 static char **buffer=NULL;
32 static int buflines=0;
38 void alarm_handler(int x) {
45 struct sockaddr_un addr;
49 bzero(&addr,sizeof(addr));
50 addr.sun_family = AF_LOCAL;
51 strncpy(addr.sun_path,_PATH_LOG,sizeof(addr.sun_path)-1);
52 /* wait for klogd to hit syslog */
54 sock = socket(AF_LOCAL, SOCK_DGRAM,0);
55 conn=connect(sock,(struct sockaddr *) &addr,sizeof(addr));
57 if (!conn) write(sock,buffer[x],strlen(buffer[x])+1);
63 void cleanup(int exitcode) {
64 /* If we own the log, unlink it before trying to free our buffer.
65 * Otherwise, sending the buffer to /dev/log doesn't make much sense.... */
70 /* Don't try to free buffer if we were called from a signal handler */
72 if (buffer) freeBuffer();
78 void runDaemon(int sock) {
79 struct sockaddr_un addr;
81 int addrlen = sizeof(struct sockaddr_un);
87 /* try not to leave stale sockets lying around */
88 /* Hopefully, we won't actually get any of these */
89 signal(SIGHUP,cleanup);
90 signal(SIGINT,cleanup);
91 signal(SIGQUIT,cleanup);
92 signal(SIGILL,cleanup);
93 signal(SIGABRT,cleanup);
94 signal(SIGFPE,cleanup);
95 signal(SIGSEGV,cleanup);
96 signal(SIGPIPE,cleanup);
97 signal(SIGBUS,cleanup);
98 signal(SIGTERM,cleanup);
100 /* Get stat info on /dev/log so we can later check to make sure we
102 if (stat(_PATH_LOG,&s1) != 0)
103 memset(&s1, '\0', sizeof(struct stat));
106 pfds.events = POLLIN|POLLPRI;
107 if ( ( (x=poll(&pfds,1,500))==-1) && errno !=EINTR) {
111 if ( (x>0) && pfds.revents & (POLLIN | POLLPRI)) {
112 message = calloc(8192,sizeof(char));
113 addrlen = sizeof(struct sockaddr_un);
114 recvsock = accept(sock,(struct sockaddr *) &addr, &addrlen);
118 signal(SIGALRM, alarm_handler);
119 len = recv(recvsock,message,8192,0);
123 if (buflines < 200000) {
125 buffer = realloc(buffer,(buflines+1)*sizeof(char *));
127 buffer = malloc(sizeof(char *));
128 message[strlen(message)]='\n';
129 buffer[buflines]=message;
137 if ( (x>0) && ( pfds.revents & (POLLHUP | POLLNVAL)) )
139 /* Check to see if syslogd's yanked our socket out from under us */
140 if ( (stat(_PATH_LOG,&s2)!=0) ||
141 (s1.st_ino != s2.st_ino ) || (s1.st_ctime != s2.st_ctime) ||
142 (s1.st_mtime != s2.st_mtime) ) {
150 int main(int argc, char **argv) {
151 struct sockaddr_un addr;
155 /* option processing made simple... */
158 sock = open("/dev/null",O_RDWR);
164 bzero(&addr, sizeof(addr));
165 addr.sun_family = AF_LOCAL;
166 strncpy(addr.sun_path,_PATH_LOG,sizeof(addr.sun_path)-1);
167 sock = socket(AF_LOCAL, SOCK_STREAM,0);
169 /* Bind socket before forking, so we know if the server started */
170 if (!bind(sock,(struct sockaddr *) &addr, sizeof(addr))) {
173 if ((pid=fork())==-1) {
181 /* shouldn't get back here... */