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