1 /* $OpenBSD: syslogc.c,v 1.1 2004/01/04 08:30:21 djm Exp $ */ 2 3 /* 4 * Copyright (c) 2004 Damien Miller 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/socket.h> 21 #include <sys/un.h> 22 23 #include <err.h> 24 #include <errno.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <unistd.h> 29 30 #define DEFAULT_CTLSOCK "/var/run/syslogd.sock" 31 32 #define MAX_MEMBUF_NAME 64 /* Max length of membuf log name */ 33 struct ctl_cmd { 34 #define CMD_READ 1 /* Read out log */ 35 #define CMD_READ_CLEAR 2 /* Read and clear log */ 36 #define CMD_CLEAR 3 /* Clear log */ 37 #define CMD_LIST 4 /* List available logs */ 38 int cmd; 39 char logname[MAX_MEMBUF_NAME]; 40 }; 41 42 static void 43 usage(void) 44 { 45 extern char *__progname; 46 47 fprintf(stderr, "Usage: %s [-Ccq] [-s ctlsock] logname\n", __progname); 48 exit(1); 49 } 50 51 int 52 main(int argc, char **argv) 53 { 54 const char *ctlsock_path; 55 char buf[8192]; 56 struct sockaddr_un ctl; 57 socklen_t ctllen; 58 int ctlsock, ch; 59 FILE *ctlf; 60 extern char *optarg; 61 extern int optind; 62 struct ctl_cmd cc; 63 64 memset(&cc, '\0', sizeof(cc)); 65 66 ctlsock_path = DEFAULT_CTLSOCK; 67 while ((ch = getopt(argc, argv, "Cchqs:")) != -1) { 68 switch (ch) { 69 case 'h': 70 usage(); 71 break; 72 case 'q': 73 cc.cmd = CMD_LIST; 74 break; 75 case 'c': 76 cc.cmd = CMD_READ_CLEAR; 77 break; 78 case 'C': 79 cc.cmd = CMD_CLEAR; 80 break; 81 case 's': 82 ctlsock_path = optarg; 83 break; 84 default: 85 fprintf(stderr, "Invalid commandline option.\n"); 86 usage(); 87 break; 88 } 89 } 90 91 if (cc.cmd == 0) 92 cc.cmd = CMD_READ; 93 94 if ((cc.cmd != CMD_LIST && optind != argc - 1) || 95 (cc.cmd == CMD_LIST && optind != argc)) 96 usage(); 97 98 if (cc.cmd != CMD_LIST) { 99 if (strlcpy(cc.logname, argv[optind], sizeof(cc.logname)) > 100 sizeof(cc.logname)) 101 errx(1, "Specified log name is too long"); 102 } 103 104 strlcpy(ctl.sun_path, ctlsock_path, sizeof(ctl.sun_path)); 105 ctl.sun_path[sizeof(ctl.sun_path) - 1] = '\0'; 106 ctl.sun_family = AF_UNIX; 107 108 if ((ctlsock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) 109 err(1, "ctl socket() error"); 110 if (connect(ctlsock, (struct sockaddr*)&ctl, sizeof(ctl)) == -1) 111 err(1, "ctl connect(\"%s\") error", ctl.sun_path); 112 if ((ctlf = fdopen(ctlsock, "r+")) == NULL) 113 err(1, "fdopen"); 114 /* Send command */ 115 if (fwrite(&cc, sizeof(cc), 1, ctlf) <= 0) 116 err(1, "fwrite"); 117 118 fflush(ctlf); 119 setlinebuf(ctlf); 120 121 /* Write out reply */ 122 while((fgets(buf, sizeof(buf), ctlf)) != NULL) 123 fputs(buf, stdout); 124 125 fclose(ctlf); 126 close(ctlsock); 127 128 exit(0); 129 } 130