xref: /openbsd/usr.sbin/ractl/ractl.c (revision 09467b48)
1 /*	$OpenBSD: ractl.c,v 1.2 2019/11/01 18:15:28 florian Exp $	*/
2 
3 /*
4  * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
5  * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
6  * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <sys/types.h>
22 #include <sys/queue.h>
23 #include <sys/socket.h>
24 #include <sys/un.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 #include <net/if.h>
28 #include <net/if_media.h>
29 #include <net/if_types.h>
30 
31 #include <err.h>
32 #include <errno.h>
33 #include <event.h>
34 #include <imsg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39 
40 #include "rad.h"
41 #include "frontend.h"
42 #include "parser.h"
43 
44 __dead void	 usage(void);
45 
46 struct imsgbuf	*ibuf;
47 
48 __dead void
49 usage(void)
50 {
51 	extern char *__progname;
52 
53 	fprintf(stderr, "usage: %s [-s socket] command [argument ...]\n",
54 	    __progname);
55 	exit(1);
56 }
57 
58 int
59 main(int argc, char *argv[])
60 {
61 	struct sockaddr_un	 sun;
62 	struct parse_result	*res;
63 	struct imsg		 imsg;
64 	int			 ctl_sock;
65 	int			 done = 0;
66 	int			 n, verbose = 0;
67 	int			 ch;
68 	char			*sockname;
69 
70 	sockname = RAD_SOCKET;
71 	while ((ch = getopt(argc, argv, "s:")) != -1) {
72 		switch (ch) {
73 		case 's':
74 			sockname = optarg;
75 			break;
76 		default:
77 			usage();
78 		}
79 	}
80 	argc -= optind;
81 	argv += optind;
82 
83 	/* Parse command line. */
84 	if ((res = parse(argc, argv)) == NULL)
85 		exit(1);
86 
87 	/* Connect to control socket. */
88 	if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
89 		err(1, "socket");
90 
91 	memset(&sun, 0, sizeof(sun));
92 	sun.sun_family = AF_UNIX;
93 	strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path));
94 
95 	if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
96 		err(1, "connect: %s", sockname);
97 
98 	if (pledge("stdio", NULL) == -1)
99 		err(1, "pledge");
100 
101 	if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
102 		err(1, NULL);
103 	imsg_init(ibuf, ctl_sock);
104 	done = 0;
105 
106 	/* Process user request. */
107 	switch (res->action) {
108 	case LOG_VERBOSE:
109 		verbose = 1;
110 		/* FALLTHROUGH */
111 	case LOG_BRIEF:
112 		imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1,
113 		    &verbose, sizeof(verbose));
114 		printf("logging request sent.\n");
115 		done = 1;
116 		break;
117 	case RELOAD:
118 		imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
119 		printf("reload request sent.\n");
120 		done = 1;
121 		break;
122 	default:
123 		usage();
124 	}
125 
126 	while (ibuf->w.queued)
127 		if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
128 			err(1, "write error");
129 
130 	while (!done) {
131 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
132 			errx(1, "imsg_read error");
133 		if (n == 0)
134 			errx(1, "pipe closed");
135 
136 		while (!done) {
137 			if ((n = imsg_get(ibuf, &imsg)) == -1)
138 				errx(1, "imsg_get error");
139 			if (n == 0)
140 				break;
141 
142 			switch (res->action) {
143 			default:
144 				break;
145 			}
146 			imsg_free(&imsg);
147 		}
148 	}
149 	close(ctl_sock);
150 	free(ibuf);
151 
152 	return (0);
153 }
154