aboutsummaryrefslogtreecommitdiff
path: root/minilogd.c
diff options
context:
space:
mode:
Diffstat (limited to 'minilogd.c')
-rw-r--r--minilogd.c202
1 files changed, 0 insertions, 202 deletions
diff --git a/minilogd.c b/minilogd.c
deleted file mode 100644
index c86ab23..0000000
--- a/minilogd.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* minilogd.c
- *
- * A pale imitation of syslogd. Most notably, doesn't write anything
- * anywhere except possibly back to syslogd.
- *
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <stdarg.h>
-#include <syslog.h>
-#ifndef __USE_BSD
-# define __USE_BSD
-#endif
-#include <unistd.h>
-
-#include <sys/poll.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-
-#define MAX_BUF_LINES 10000
-#define BUF_LINE_SIZE 8192
-
-static int we_own_log=0;
-static char **buffer=NULL;
-static int buflines=0;
-
-int debug;
-
-int recvsock;
-
-void alarm_handler(int x) {
- alarm(0);
- close(recvsock);
- recvsock = -1;
-}
-
-void freeBuffer() {
- struct sockaddr_un addr;
- int sock;
- int x=0,conn;
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strncpy(addr.sun_path,_PATH_LOG,sizeof(addr.sun_path)-1);
- /* wait for klogd to hit syslog */
- sleep(2);
- sock = socket(AF_LOCAL, SOCK_STREAM,0);
- conn=connect(sock,(struct sockaddr *) &addr,(socklen_t)sizeof(addr));
- while (x<buflines) {
- if (!conn) {
- /*printf("to syslog: %s\n", buffer[x]);*/
- write(sock,buffer[x],strlen(buffer[x])+1);
- }
- free(buffer[x]);
- x++;
- }
- free(buffer);
-}
-
-void cleanup(int exitcode) {
- /* If we own the log, unlink it before trying to free our buffer.
- * Otherwise, sending the buffer to /dev/log doesn't make much sense.... */
- if (we_own_log) {
- perror("wol");
- unlink(_PATH_LOG);
- }
- /* Don't try to free buffer if we were called from a signal handler */
- if (exitcode<=0) {
- if (buffer)
- freeBuffer();
- exit(exitcode);
- } else
- exit(exitcode+128);
-}
-
-void runDaemon(int sock) {
- struct sockaddr_un addr;
- int x,done=0;
- ssize_t len;
- socklen_t addrlen = (socklen_t)sizeof(struct sockaddr_un);
- char *message = NULL;
- struct stat s1,s2;
- struct pollfd pfds;
-
- daemon(0,-1);
- /* try not to leave stale sockets lying around */
- /* Hopefully, we won't actually get any of these */
- signal(SIGHUP,cleanup);
- signal(SIGINT,cleanup);
- signal(SIGQUIT,cleanup);
- signal(SIGILL,cleanup);
- signal(SIGABRT,cleanup);
- signal(SIGFPE,cleanup);
- signal(SIGSEGV,cleanup);
- signal(SIGPIPE,cleanup);
- signal(SIGBUS,cleanup);
- signal(SIGTERM,cleanup);
- done = 0;
- /* Get stat info on /dev/log so we can later check to make sure we
- * still own it... */
- if (stat(_PATH_LOG,&s1) != 0)
- memset(&s1, 0, sizeof(struct stat));
- while (!done) {
- pfds.fd = sock;
- pfds.events = POLLIN|POLLPRI;
- pfds.revents = 0;
- if ( ( (x=poll(&pfds,1,500))==-1) && errno !=EINTR) {
- perror("poll");
- cleanup(-1);
- }
- if ( (x>0) && (pfds.revents & (POLLIN | POLLPRI))) {
- if (message == NULL) {
- message = calloc(BUF_LINE_SIZE,sizeof(char));
- }
- recvsock = accept(sock,(struct sockaddr *) &addr, &addrlen);
- alarm(2);
- signal(SIGALRM, alarm_handler);
- len = read(recvsock,message,BUF_LINE_SIZE);
- alarm(0);
- close(recvsock);
- if (len>0) {
- /*printf("line recv'd: %s\n", message);*/
- if (buflines < MAX_BUF_LINES) {
- if (buffer)
- buffer = realloc(buffer,(buflines+1)*sizeof(char *));
- else
- buffer = malloc(sizeof(char *));
- message[strlen(message)]='\n';
- buffer[buflines]=message;
- message = NULL;
- buflines++;
- }
- }
- else {
- recvsock=-1;
- }
- }
- if ( (x>0) && ( pfds.revents & (POLLHUP | POLLNVAL)) )
- done = 1;
- /* Check to see if syslogd's yanked our socket out from under us */
- if ( (stat(_PATH_LOG,&s2)!=0) ||
- (s1.st_ino != s2.st_ino ) || (s1.st_ctime != s2.st_ctime) ||
- (s1.st_mtime != s2.st_mtime) ) { /*|| (s1.st_atime != s2.st_atime) ) {*/
- done = 1;
- we_own_log = 0;
- /*printf("someone stole our %s\n", _PATH_LOG);
- printf("st_ino: %d %d\n", s1.st_ino, s2.st_ino);
- printf("st_ctime: %d %d\n", s1.st_ctime, s2.st_ctime);
- printf("st_atime: %d %d\n", s1.st_atime, s2.st_atime);
- printf("st_mtime: %d %d\n", s1.st_mtime, s2.st_mtime);*/
- }
- }
- free(message);
- cleanup(0);
-}
-
-int main(int argc, char **argv) {
- struct sockaddr_un addr;
- int sock;
- int pid;
-
- /* option processing made simple... */
- if (argc>1) debug=1;
- /* just in case */
- sock = open("/dev/null",O_RDWR);
- dup2(sock,0);
- dup2(sock,1);
- dup2(sock,2);
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strncpy(addr.sun_path,_PATH_LOG,sizeof(addr.sun_path)-1);
- sock = socket(AF_LOCAL, SOCK_STREAM,0);
- unlink(_PATH_LOG);
- /* Bind socket before forking, so we know if the server started */
- if (!bind(sock,(struct sockaddr *) &addr, (socklen_t)sizeof(addr))) {
- we_own_log = 1;
- listen(sock,5);
- if ((pid=fork())==-1) {
- perror("fork");
- exit(3);
- }
- if (pid) {
- exit(0);
- } else {
- /*printf("starting daemon...\n");*/
- runDaemon(sock);
- /* shouldn't get back here... */
- exit(4);
- }
- } else {
- exit(5);
- }
-}
-/* vim: set ts=2 noet: */