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