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;
80 int x,len,addrlen,done=0;
86 /* try not to leave stale sockets lying around */
87 /* Hopefully, we won't actually get any of these */
88 signal(SIGHUP,cleanup);
89 signal(SIGINT,cleanup);
90 signal(SIGQUIT,cleanup);
91 signal(SIGILL,cleanup);
92 signal(SIGABRT,cleanup);
93 signal(SIGFPE,cleanup);
94 signal(SIGSEGV,cleanup);
95 signal(SIGPIPE,cleanup);
96 signal(SIGBUS,cleanup);
97 signal(SIGTERM,cleanup);
99 /* Get stat info on /dev/log so we can later check to make sure we
101 if (stat(_PATH_LOG,&s1) != 0)
102 memset(&s1, '\0', sizeof(struct stat));
105 pfds.events = POLLIN|POLLPRI;
106 if ( ( (x=poll(&pfds,1,500))==-1) && errno !=EINTR) {
110 if ( (x>0) && pfds.revents & (POLLIN | POLLPRI)) {
111 message = calloc(8192,sizeof(char));
112 recvsock = accept(sock,(struct sockaddr *) &addr, &addrlen);
114 signal(SIGALRM, alarm_handler);
115 len = read(recvsock,message,8192);
119 if (buflines < 200000) {
121 buffer = realloc(buffer,(buflines+1)*sizeof(char *));
123 buffer = malloc(sizeof(char *));
124 message[strlen(message)]='\n';
125 buffer[buflines]=message;
133 if ( (x>0) && ( pfds.revents & (POLLHUP | POLLNVAL)) )
135 /* Check to see if syslogd's yanked our socket out from under us */
136 if ( (stat(_PATH_LOG,&s2)!=0) ||
137 (s1.st_ino != s2.st_ino ) || (s1.st_ctime != s2.st_ctime) ||
138 (s1.st_mtime != s2.st_mtime) || (s1.st_atime != s2.st_atime) ) {
146 int main(int argc, char **argv) {
147 struct sockaddr_un addr;
151 /* option processing made simple... */
154 sock = open("/dev/null",O_RDWR);
160 bzero(&addr, sizeof(addr));
161 addr.sun_family = AF_LOCAL;
162 strncpy(addr.sun_path,_PATH_LOG,sizeof(addr.sun_path)-1);
163 sock = socket(AF_LOCAL, SOCK_STREAM,0);
165 /* Bind socket before forking, so we know if the server started */
166 if (!bind(sock,(struct sockaddr *) &addr, sizeof(addr))) {
169 if ((pid=fork())==-1) {
177 /* shouldn't get back here... */