]> git.pld-linux.org Git - projects/rc-scripts.git/blame - src/minilogd.c
- removed unneeded termput hpa
[projects/rc-scripts.git] / src / minilogd.c
CommitLineData
35111b89
JR
1/* minilogd.c
2 *
3 * A pale imitation of syslogd. Most notably, doesn't write anything
4 * anywhere except possibly back to syslogd.
5 *
6 * Copyright (c) 1999-2001 Red Hat, Inc. All rights reserved.
7 *
8 * This software may be freely redistributed under the terms of the GNU
9 * public license.
10 *
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.
14 *
15 */
16
17#include <errno.h>
18#include <fcntl.h>
19#include <signal.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <syslog.h>
23#include <unistd.h>
24
25#include <sys/poll.h>
26#include <sys/socket.h>
27#include <sys/stat.h>
28#include <sys/un.h>
29
30static int we_own_log=0;
31static char **buffer=NULL;
32static int buflines=0;
33
34int debug;
35
36int recvsock;
37
38void alarm_handler(int x) {
39 alarm(0);
40 close(recvsock);
41 recvsock = -1;
42}
43
44void freeBuffer() {
45 struct sockaddr_un addr;
46 int sock;
47 int x=0,conn;
48
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 */
53 sleep(2);
54 sock = socket(AF_LOCAL, SOCK_DGRAM,0);
55 conn=connect(sock,(struct sockaddr *) &addr,sizeof(addr));
56 while (x<buflines) {
57 if (!conn) write(sock,buffer[x],strlen(buffer[x])+1);
58 free(buffer[x]);
59 x++;
60 }
61}
62
63void 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.... */
66 if (we_own_log) {
67 perror("wol");
68 unlink(_PATH_LOG);
69 }
70 /* Don't try to free buffer if we were called from a signal handler */
71 if (exitcode<=0) {
72 if (buffer) freeBuffer();
73 exit(exitcode);
74 } else
75 exit(exitcode+128);
76}
77
78void runDaemon(int sock) {
79 struct sockaddr_un addr;
80 int x,len,addrlen,done=0;
81 char *message;
82 struct stat s1,s2;
83 struct pollfd pfds;
84
85 daemon(0,-1);
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);
98 done = 0;
99 /* Get stat info on /dev/log so we can later check to make sure we
100 * still own it... */
101 if (stat(_PATH_LOG,&s1) != 0)
102 memset(&s1, '\0', sizeof(struct stat));
103 while (!done) {
104 pfds.fd = sock;
105 pfds.events = POLLIN|POLLPRI;
106 if ( ( (x=poll(&pfds,1,500))==-1) && errno !=EINTR) {
107 perror("poll");
108 cleanup(-1);
109 }
110 if ( (x>0) && pfds.revents & (POLLIN | POLLPRI)) {
111 message = calloc(8192,sizeof(char));
112 recvsock = accept(sock,(struct sockaddr *) &addr, &addrlen);
113 alarm(2);
114 signal(SIGALRM, alarm_handler);
115 len = read(recvsock,message,8192);
116 alarm(0);
117 close(recvsock);
118 if (len>0) {
119 if (buflines < 200000) {
120 if (buffer)
121 buffer = realloc(buffer,(buflines+1)*sizeof(char *));
122 else
123 buffer = malloc(sizeof(char *));
124 message[strlen(message)]='\n';
125 buffer[buflines]=message;
126 buflines++;
127 }
128 }
129 else {
130 recvsock=-1;
131 }
132 }
133 if ( (x>0) && ( pfds.revents & (POLLHUP | POLLNVAL)) )
134 done = 1;
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) ) {
139 done = 1;
140 we_own_log = 0;
141 }
142 }
143 cleanup(0);
144}
145
146int main(int argc, char **argv) {
147 struct sockaddr_un addr;
148 int sock;
149 int pid;
150
151 /* option processing made simple... */
152 if (argc>1) debug=1;
153 /* just in case */
154 sock = open("/dev/null",O_RDWR);
155 dup2(sock,0);
156 dup2(sock,1);
157 dup2(sock,2);
158 close(sock);
159
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);
164 unlink(_PATH_LOG);
165 /* Bind socket before forking, so we know if the server started */
166 if (!bind(sock,(struct sockaddr *) &addr, sizeof(addr))) {
167 we_own_log = 1;
168 listen(sock,5);
169 if ((pid=fork())==-1) {
170 perror("fork");
171 exit(3);
172 }
173 if (pid) {
174 exit(0);
175 } else {
176 runDaemon(sock);
177 /* shouldn't get back here... */
178 exit(4);
179 }
180 } else {
181 exit(5);
182 }
183}
This page took 0.05284 seconds and 4 git commands to generate.