Add support for listing and deleting entries based on an output port.
[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 "timeval.h"
47 #include "util.h"
48 #include "vlog-socket.h"
49
50 void
51 usage(char *prog_name, int exit_code)
52 {
53     printf("Usage: %s [TARGET] [ACTION...]\n"
54            "Targets:\n"
55            "  -a, --all            Apply to all targets (default)\n"
56            "  -t, --target=TARGET  Specify target program, as a pid, a\n"
57            "                       pidfile, or an absolute path to a Unix\n"
58            "                       domain socket\n"
59            "Actions:\n"
60            "  -l, --list         List current settings\n"
61            "  -s, --set=MODULE[:FACILITY[:LEVEL]]\n"
62            "        Set MODULE and FACILITY log level to LEVEL\n"
63            "        MODULE may be any valid module name or 'ANY'\n"
64            "        FACILITY may be 'syslog', 'console', 'file', or 'ANY' (default)\n"
65            "        LEVEL may be 'emer', 'err', 'warn', or 'dbg' (default)\n"
66            "  -r, --reopen       Make the program reopen its log file\n"
67            "  -h, --help         Print this helpful information\n",
68            prog_name);
69     exit(exit_code);
70 }
71
72 static char *
73 transact(struct vlog_client *client, const char *request, bool *ok)
74 {
75     char *reply;
76     int error = vlog_client_transact(client, request, &reply);
77     if (error) {
78         fprintf(stderr, "%s: transaction error: %s\n",
79                 vlog_client_target(client), strerror(error));
80         *ok = false;
81     }
82     return reply ? reply : xstrdup("");
83 }
84
85 static void
86 transact_ack(struct vlog_client *client, const char* request, bool *ok)
87 {
88     char *reply;
89     int error = vlog_client_transact(client, request, &reply);
90     if (error) {
91         fprintf(stderr, "%s: transaction error: %s\n",
92                 vlog_client_target(client), strerror(error));
93         *ok = false;
94     } else if (strcmp(reply, "ack")) {
95         fprintf(stderr, "Received unexpected reply from %s: %s\n",
96                 vlog_client_target(client), reply);
97         *ok = false;
98     }
99     free(reply);
100 }
101
102 static void
103 add_target(struct vlog_client ***clients, size_t *n_clients,
104            const char *path, bool *ok)
105 {
106     struct vlog_client *client;
107     int error = vlog_client_connect(path, &client);
108     if (error) {
109         fprintf(stderr, "Error connecting to \"%s\": %s\n",
110                 path, strerror(error));
111         *ok = false;
112     } else {
113         *clients = xrealloc(*clients, sizeof *clients * (*n_clients + 1));
114         (*clients)[*n_clients] = client;
115         ++*n_clients;
116     }
117 }
118
119 static void
120 add_all_targets(struct vlog_client ***clients, size_t *n_clients, bool *ok)
121 {
122     DIR *directory;
123     struct dirent* de;
124
125     directory = opendir("/tmp");
126     if (!directory) {
127         fprintf(stderr, "/tmp: opendir: %s\n", strerror(errno));
128     }
129
130     while ((de = readdir(directory)) != NULL) {
131         if (!strncmp(de->d_name, "vlogs.", 5)) {
132             char *path = xasprintf("/tmp/%s", de->d_name);
133             add_target(clients, n_clients, path, ok);
134             free(path);
135         }
136     }
137
138     closedir(directory);
139 }
140
141 int main(int argc, char *argv[])
142 {
143     static const struct option long_options[] = {
144         /* Target options must come first. */
145         {"all", no_argument, NULL, 'a'},
146         {"target", required_argument, NULL, 't'},
147         {"help", no_argument, NULL, 'h'},
148
149         /* Action options come afterward. */
150         {"list", no_argument, NULL, 'l'},
151         {"set", required_argument, NULL, 's'},
152         {"reopen", no_argument, NULL, 'r'},
153         {0, 0, 0, 0},
154     };
155     char *short_options;
156
157     /* Determine targets. */
158     bool ok = true;
159     int n_actions = 0;
160     struct vlog_client **clients = NULL;
161     size_t n_clients = 0;
162
163     set_program_name(argv[0]);
164     time_init();
165
166     short_options = long_options_to_short_options(long_options);
167     for (;;) {
168         int option;
169         size_t i;
170
171         option = getopt_long(argc, argv, short_options, long_options, NULL);
172         if (option == -1) {
173             break;
174         }
175         if (!strchr("ath", option) && n_clients == 0) {
176             ofp_fatal(0, "no targets specified (use --help for help)");
177         } else {
178             ++n_actions;
179         }
180         switch (option) {
181         case 'a':
182             add_all_targets(&clients, &n_clients, &ok);
183             break;
184
185         case 't':
186             add_target(&clients, &n_clients, optarg, &ok);
187             break;
188
189         case 'l':
190             for (i = 0; i < n_clients; i++) {
191                 struct vlog_client *client = clients[i];
192                 char *reply;
193
194                 printf("%s:\n", vlog_client_target(client));
195                 reply = transact(client, "list", &ok);
196                 fputs(reply, stdout);
197                 free(reply);
198             }
199             break;
200
201         case 's':
202             for (i = 0; i < n_clients; i++) {
203                 struct vlog_client *client = clients[i];
204                 char *request = xasprintf("set %s", optarg);
205                 transact_ack(client, request, &ok);
206                 free(request);
207             }
208             break;
209
210         case 'r':
211             for (i = 0; i < n_clients; i++) {
212                 struct vlog_client *client = clients[i];
213                 char *request = xasprintf("reopen");
214                 transact_ack(client, request, &ok);
215                 free(request);
216             }
217             break;
218
219         case 'h':
220             usage(argv[0], EXIT_SUCCESS);
221             break;
222
223         case '?':
224             exit(EXIT_FAILURE);
225
226         default:
227             NOT_REACHED();
228         }
229     }
230     if (!n_actions) {
231         fprintf(stderr,
232                 "warning: no actions specified (use --help for help)\n");
233     }
234     exit(ok ? 0 : 1);
235 }