Don't unnecessarily link against -lresolv and -ldl.
[sliver-openvswitch.git] / utilities / vlogconf.c
1 /* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
2  * Junior University
3  * 
4  * We are making the OpenFlow specification and associated documentation
5  * (Software) available for public use and benefit with the expectation
6  * that others will use, modify and enhance the Software and contribute
7  * those enhancements back to the community. However, since we would
8  * like to make the Software available for broadest use, with as few
9  * restrictions as possible permission is hereby granted, free of
10  * charge, to any person obtaining a copy of this Software to deal in
11  * the Software under the copyrights without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sublicense, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  * 
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  * 
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE.
28  * 
29  * The name and trademarks of copyright holder(s) may NOT be used in
30  * advertising or publicity pertaining to the Software or any
31  * derivatives without specific, written prior permission.
32  */
33 #include <config.h>
34 #include "vlog.h"
35
36 #include <dirent.h>
37 #include <errno.h>
38 #include <getopt.h>
39 #include <stdarg.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdlib.h>
43
44 #include "command-line.h"
45 #include "compiler.h"
46 #include "util.h"
47 #include "vlog-socket.h"
48
49 void
50 usage(char *prog_name, int exit_code)
51 {
52     printf("Usage: %s [TARGET] [ACTION...]\n"
53            "Targets:\n"
54            "  -a, --all            Apply to all targets (default)\n"
55            "  -t, --target=TARGET  Specify target program, as a pid or an\n"
56            "                       absolute path to a Unix domain socket\n"
57            "Actions:\n"
58            "  -l, --list         List current settings\n"
59            "  -s, --set=MODULE[:FACILITY[:LEVEL]]\n"
60            "        Set MODULE and FACILITY log level to LEVEL\n"
61            "        MODULE may be any valid module name or 'ANY'\n"
62            "        FACILITY may be 'syslog' or 'console' or 'ANY' (default)\n"
63            "        LEVEL may be 'emer', 'err', 'warn', or 'dbg (default)'\n"
64            "  -h, --help         Print this helpful information\n",
65            prog_name);
66     exit(exit_code);
67 }
68
69 static char *
70 transact(struct vlog_client *client, const char *request, bool *ok)
71 {
72     char *reply;
73     int error = vlog_client_transact(client, request, &reply);
74     if (error) {
75         fprintf(stderr, "%s: transaction error: %s\n",
76                 vlog_client_target(client), strerror(error));
77         *ok = false;
78     }
79     return reply ? reply : xstrdup("");
80 }
81
82 static void
83 transact_ack(struct vlog_client *client, const char* request, bool *ok)
84 {
85     char *reply;
86     int error = vlog_client_transact(client, request, &reply);
87     if (error) {
88         fprintf(stderr, "%s: transaction error: %s\n",
89                 vlog_client_target(client), strerror(error));
90         *ok = false;
91     } else if (strcmp(reply, "ack")) {
92         fprintf(stderr, "Received unexpected reply from %s: %s\n",
93                 vlog_client_target(client), reply);
94         *ok = false;
95     }
96     free(reply);
97 }
98
99 static void
100 add_target(struct vlog_client ***clients, size_t *n_clients,
101            const char *path, bool *ok)
102 {
103     struct vlog_client *client;
104     int error = vlog_client_connect(path, &client);
105     if (error) {
106         fprintf(stderr, "Error connecting to \"%s\": %s\n",
107                 path, strerror(error));
108         *ok = false;
109     } else {
110         *clients = xrealloc(*clients, sizeof *clients * (*n_clients + 1));
111         (*clients)[*n_clients] = client;
112         ++*n_clients;
113     }
114 }
115
116 static void
117 add_all_targets(struct vlog_client ***clients, size_t *n_clients, bool *ok)
118 {
119     DIR *directory;
120     struct dirent* de;
121
122     directory = opendir("/tmp");
123     if (!directory) {
124         fprintf(stderr, "/tmp: opendir: %s\n", strerror(errno));
125     }
126
127     while ((de = readdir(directory)) != NULL) {
128         if (!strncmp(de->d_name, "vlogs.", 5)) {
129             char *path = xasprintf("/tmp/%s", de->d_name);
130             add_target(clients, n_clients, path, ok);
131             free(path);
132         }
133     }
134
135     closedir(directory);
136 }
137
138 int main(int argc, char *argv[])
139 {
140     static const struct option long_options[] = {
141         /* Target options must come first. */
142         {"all", no_argument, NULL, 'a'},
143         {"target", required_argument, NULL, 't'},
144         {"help", no_argument, NULL, 'h'},
145
146         /* Action options come afterward. */
147         {"list", no_argument, NULL, 'l'},
148         {"set", required_argument, NULL, 's'},
149         {0, 0, 0, 0},
150     };
151     char *short_options;
152
153     /* Determine targets. */
154     bool ok = true;
155     int n_actions = 0;
156     struct vlog_client **clients = NULL;
157     size_t n_clients = 0;
158
159     set_program_name(argv[0]);
160
161     short_options = long_options_to_short_options(long_options);
162     for (;;) {
163         int option;
164         size_t i;
165
166         option = getopt_long(argc, argv, short_options, long_options, NULL);
167         if (option == -1) {
168             break;
169         }
170         if (!strchr("ath", option) && n_clients == 0) {
171             fatal(0, "no targets specified (use --help for help)");
172         } else {
173             ++n_actions;
174         }
175         switch (option) {
176         case 'a':
177             add_all_targets(&clients, &n_clients, &ok);
178             break;
179
180         case 't':
181             add_target(&clients, &n_clients, optarg, &ok);
182             break;
183
184         case 'l':
185             for (i = 0; i < n_clients; i++) {
186                 struct vlog_client *client = clients[i];
187                 char *reply;
188
189                 printf("%s:\n", vlog_client_target(client));
190                 reply = transact(client, "list", &ok);
191                 fputs(reply, stdout);
192                 free(reply);
193             }
194             break;
195
196         case 's':
197             for (i = 0; i < n_clients; i++) {
198                 struct vlog_client *client = clients[i];
199                 char *request = xasprintf("set %s", optarg);
200                 transact_ack(client, request, &ok);
201                 free(request);
202             }
203             break;
204
205         case 'h':
206             usage(argv[0], EXIT_SUCCESS);
207             break;
208
209         default:
210             NOT_REACHED();
211         }
212     }
213     if (!n_actions) {
214         fprintf(stderr,
215                 "warning: no actions specified (use --help for help)\n");
216     }
217     exit(ok ? 0 : 1);
218 }