c28b7430e2eba3eb985864de41a8bd5c5b0c436b
[browser-switch] / config-ui / browser-switchboard-config.c
1 /*
2  * browser-switchboard-config.c -- command-line configuration utility for
3  * Browser Switchboard
4  *
5  * Copyright (C) 2009-2010 Steven Luo
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20  * USA.
21  */
22
23
24 #include <stdlib.h>
25 #include <stddef.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <getopt.h>
30
31 #include "config.h"
32 #include "save-config.h"
33 #include "browsers.h"
34
35 extern struct swb_config_option swb_config_options[];
36
37 static int get_config_value(char *name) {
38         struct swb_config cfg;
39         struct swb_config_option *optinfo;
40         ptrdiff_t i;
41         int retval = 1;
42
43         swb_config_init(&cfg);
44
45         if (!swb_config_load(&cfg))
46                 return 1;
47
48         for (optinfo = swb_config_options; optinfo->name; ++optinfo) {
49                 if (strcmp(name, optinfo->name))
50                         continue;
51
52                 i = optinfo - swb_config_options;
53                 switch (optinfo->type) {
54                   case SWB_CONFIG_OPT_STRING:
55                         if (*(char **)cfg.entries[i])
56                                 printf("%s\n", *(char **)cfg.entries[i]);
57                         break;
58                   case SWB_CONFIG_OPT_INT:
59                         printf("%d\n", *(int *)cfg.entries[i]);
60                         break;
61                   default:
62                         break;
63                 }
64                 retval = 0;
65                 break;
66         }
67
68         swb_config_free(&cfg);
69
70         return retval;
71 }
72
73 static int get_default_browser(void) {
74         struct swb_config cfg;
75         int i;
76
77         swb_config_init(&cfg);
78
79         if (!swb_config_load(&cfg))
80                 return 1;
81
82         /* Check to see if the configured default browser is installed
83            If not, report the default default browser */
84         for (i = 0; browsers[i].config; ++i) {
85                 if (strcmp(browsers[i].config, cfg.default_browser))
86                         continue;
87
88                 if (browsers[i].binary && access(browsers[i].binary, X_OK))
89                         printf("%s\n", browsers[0].config);
90                 else
91                         printf("%s\n", browsers[i].config);
92
93                 break;
94         }
95
96         if (!browsers[i].config)
97                 /* Unknown browser configured as default, report the default
98                    default browser */
99                 printf("%s\n", browsers[0].config);
100
101         swb_config_free(&cfg);
102
103         return 0;
104 }
105
106 static int set_config_value(char *name, char *value) {
107         struct swb_config orig_cfg, cfg;
108         struct swb_config_option *optinfo;
109         ptrdiff_t i;
110         int retval = 1;
111
112         swb_config_init(&orig_cfg);
113
114         if (!swb_config_load(&orig_cfg))
115                 return 1;
116
117         swb_config_copy(&cfg, &orig_cfg);
118
119         for (optinfo = swb_config_options; optinfo->name; ++optinfo) {
120                 if (strcmp(name, optinfo->name))
121                         continue;
122
123                 i = optinfo - swb_config_options;
124                 switch (optinfo->type) {
125                   case SWB_CONFIG_OPT_STRING:
126                         if (strlen(value) == 0) {
127                                 /* If the new value is empty, clear the config
128                                    setting */
129                                 *(char **)cfg.entries[i] = NULL;
130                                 cfg.flags &= ~optinfo->set_mask;
131                         } else {
132                                 /* Make a copy of the string -- it's not safe
133                                    to free value, which comes from argv */
134                                 if (!(*(char **)cfg.entries[i] =
135                                       strdup(value)))
136                                         exit(1);
137                                 cfg.flags |= optinfo->set_mask;
138                         }
139                         break;
140                   case SWB_CONFIG_OPT_INT:
141                         if (strlen(value) == 0) {
142                                 /* If the new value is empty, clear the config
143                                    setting */
144                                 cfg.flags &= ~optinfo->set_mask;
145                         } else {
146                                 *(int *)cfg.entries[i] = atoi(value);
147                                 cfg.flags |= optinfo->set_mask;
148                         }
149                         break;
150                 }
151                 retval = 0;
152                 break;
153         }
154
155         if (!retval)
156                 if (!swb_config_save(&cfg))
157                         retval = 1;
158
159         /* Reconfigure a running browser-switchboard, if present */
160         swb_reconfig(&orig_cfg, &cfg);
161
162         swb_config_free(&orig_cfg);
163         /* XXX can't free all of cfg, it contains pointers to memory we just
164            freed above
165         swb_config_free(&cfg); */
166         if (optinfo->name && optinfo->type == SWB_CONFIG_OPT_STRING)
167                 free(*(char **)cfg.entries[i]);
168
169         return retval;
170 }
171
172 void usage(void) {
173         printf("Usage:\n");
174         printf("  browser-switchboard-config -b -- Display default browser\n");
175         printf("  browser-switchboard-config -c -- Display command used when default browser is \"other\"\n");
176         printf("  browser-switchboard-config -m -- Display continuous mode setting\n");
177         printf("  browser-switchboard-config -o option -- Display value of option\n");
178         printf("\n");
179         printf("  browser-switchboard-config -s [-b|-c|-m|-o option] value -- Set the selected option to value\n");
180         printf("\n");
181         printf("  browser-switchboard-config -h -- Show this message\n");
182 }
183
184 int main(int argc, char **argv) {
185         int opt, done = 0;
186         int set = 0;
187         char *selected_opt = NULL;
188
189         while (!done && (opt = getopt(argc, argv, "hsbcmo:")) != -1) {
190                 switch (opt) {
191                   case 'h':
192                         usage();
193                         exit(0);
194                         break;
195                   case 's':
196                         set = 1;
197                         break;
198                   case 'b':
199                         selected_opt = "default_browser";
200                         done = 1;
201                         break;
202                   case 'c':
203                         selected_opt = "other_browser_cmd";
204                         done = 1;
205                         break;
206                   case 'm':
207                         selected_opt = "continuous_mode";
208                         done = 1;
209                         break;
210                   case 'o':
211                         selected_opt = optarg;
212                         done = 1;
213                         break;
214                   default:
215                         usage();
216                         exit(1);
217                         break;
218                 }
219         }
220
221         if (!selected_opt) {
222                 printf("Must specify one of -b, -c, -m, -o\n");
223                 usage();
224                 exit(1);
225         }
226
227         if (set) {
228                 if (optind >= argc) {
229                         printf("Value to set config option to not provided\n");
230                         usage();
231                         exit(1);
232                 }
233                 return set_config_value(selected_opt, argv[optind]);
234         } else if (!strcmp(selected_opt, "default_browser"))
235                 /* Default browser value needs special handling */
236                 return get_default_browser();
237         else
238                 return get_config_value(selected_opt);
239 }