xref: /openbsd-src/usr.sbin/syslogc/syslogc.c (revision 1bde5b8953ea6d75feca41f99a1baf1ac9a372f1)
1 /* $OpenBSD: syslogc.c,v 1.5 2004/04/13 01:10:05 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 
34 struct ctl_cmd {
35 #define CMD_READ	1	/* Read out log */
36 #define CMD_READ_CLEAR	2	/* Read and clear log */
37 #define CMD_CLEAR	3	/* Clear log */
38 #define CMD_LIST	4	/* List available logs */
39 	int	cmd;
40 	char	logname[MAX_MEMBUF_NAME];
41 };
42 
43 static void
44 usage(void)
45 {
46 	extern char *__progname;
47 
48 	fprintf(stderr, "Usage: %s [-Ccq] [-s ctlsock] logname\n", __progname);
49 	exit(1);
50 }
51 
52 int
53 main(int argc, char **argv)
54 {
55 	const char *ctlsock_path;
56 	char buf[8192];
57 	struct sockaddr_un ctl;
58 	socklen_t ctllen;
59 	int ctlsock, ch;
60 	FILE *ctlf;
61 	extern char *optarg;
62 	extern int optind;
63 	struct ctl_cmd cc;
64 
65 	memset(&cc, '\0', sizeof(cc));
66 
67 	ctlsock_path = DEFAULT_CTLSOCK;
68 	while ((ch = getopt(argc, argv, "Cchqs:")) != -1) {
69 		switch (ch) {
70 		case 'C':
71 			cc.cmd = CMD_CLEAR;
72 			break;
73 		case 'c':
74 			cc.cmd = CMD_READ_CLEAR;
75 			break;
76 		case 'h':
77 			usage();
78 			break;
79 		case 'q':
80 			cc.cmd = CMD_LIST;
81 			break;
82 		case 's':
83 			ctlsock_path = optarg;
84 			break;
85 		default:
86 			fprintf(stderr, "Invalid commandline option.\n");
87 			usage();
88 			break;
89 		}
90 	}
91 
92 	if (cc.cmd == 0)
93 		cc.cmd = CMD_READ;
94 
95 	if ((cc.cmd != CMD_LIST && optind != argc - 1) ||
96 	    (cc.cmd == CMD_LIST && optind != argc))
97 		usage();
98 
99 	if (cc.cmd != CMD_LIST) {
100 		if (strlcpy(cc.logname, argv[optind], sizeof(cc.logname)) >=
101 		    sizeof(cc.logname))
102 			errx(1, "Specified log name is too long");
103 	}
104 
105 	memset(&ctl, '\0', sizeof(ctl));
106 	strlcpy(ctl.sun_path, ctlsock_path, sizeof(ctl.sun_path));
107 	ctl.sun_family = AF_UNIX;
108 
109 	if ((ctlsock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
110 		err(1, "socket");
111 	if (connect(ctlsock, (struct sockaddr*)&ctl, sizeof(ctl)) == -1)
112 		err(1, "connect: %s", ctl.sun_path);
113 	if ((ctlf = fdopen(ctlsock, "r+")) == NULL)
114 		err(1, "fdopen");
115 	/* Send command */
116 	if (fwrite(&cc, sizeof(cc), 1, ctlf) != 1)
117 		err(1, "fwrite");
118 
119 	fflush(ctlf);
120 	setlinebuf(ctlf);
121 
122 	/* Write out reply */
123 	while((fgets(buf, sizeof(buf), ctlf)) != NULL)
124 		fputs(buf, stdout);
125 
126 	fclose(ctlf);
127 	close(ctlsock);
128 
129 	exit(0);
130 }
131