1 /*
2 * MC account storage backend inspector
3 *
4 * Copyright © 2010 Nokia Corporation
5 * Copyright © 2010 Collabora Ltd.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library 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 GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "config.h"
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <glib.h>
28 #include <glib-object.h>
29
30 #include "account-store-default.h"
31
32 #define DOCSTRING_A \
33 "%s OP BACKEND ACCOUNT [KEY [VALUE]]\n\n" \
34 " OP := <get | set | del | has | list>\n" \
35 " BACKEND := <"
36
37 #define DOCSTRING_B \
38 ">\n" \
39 " ACCOUNT := <MANAGER>/<PROTOCOL>/<ACCOUNT-UID>\n" \
40 " KEY := <manager | protocol | DisplayName | param-<PARAMETER>>\n" \
41 " VALUE := <STRING>\n\n"
42
43 #if ENABLE_LIBACCOUNTS_SSO
44 #include "account-store-libaccounts.h"
45 #endif
46
47 typedef struct {
48 const gchar *name;
49 gchar * (*get) (const gchar *account, const gchar *key);
50 gboolean (*set) (const gchar *account, const gchar *key, const gchar *value);
51 gboolean (*delete) (const gchar *account);
52 gboolean (*exists) (const gchar *account);
53 GStrv (*list) (void);
54 } Backend;
55
56 typedef enum {
57 OP_UNKNOWN,
58 OP_GET,
59 OP_SET,
60 OP_DELETE,
61 OP_EXISTS,
62 OP_LIST
63 } Operation;
64
65 const Backend backends[] = {
66 { "default",
67 default_get,
68 default_set,
69 default_delete,
70 default_exists,
71 default_list },
72
73 #if ENABLE_LIBACCOUNTS_SSO
74 { "libaccounts",
75 libaccounts_get,
76 libaccounts_set,
77 libaccounts_delete,
78 libaccounts_exists,
79 libaccounts_list },
80 #endif
81
82 { NULL }
83 };
84
85 static void usage (const gchar *name, const gchar *fmt,
86 ...) G_GNUC_NORETURN G_GNUC_PRINTF (2, 3);
87
main(int argc,char ** argv)88 int main (int argc, char **argv)
89 {
90 int i;
91 const gchar *op_name = NULL;
92 const gchar *backend = NULL;
93 const gchar *account = NULL;
94 const gchar *setting = NULL;
95 const gchar *value = NULL;
96 const Backend *store = NULL;
97 Operation op = OP_UNKNOWN;
98 gchar *output = NULL;
99 gboolean success = FALSE;
100
101 g_type_init ();
102 g_set_application_name (argv[0]);
103
104 if (argc < 3)
105 usage (argv[0], "Not enough arguments");
106
107 op_name = argv[1];
108 backend = argv[2];
109
110 for (i = 0; backends[i].name != NULL; i++)
111 {
112 if (g_str_equal (backends[i].name, backend))
113 {
114 store = &backends[i];
115 break;
116 }
117 }
118
119 if (store == NULL)
120 usage (argv[0], "No such backend %s", backend);
121
122 if (g_str_equal (op_name, "get"))
123 op = OP_GET;
124 else if (g_str_equal (op_name, "set"))
125 op = OP_SET;
126 else if (g_str_equal (op_name, "del"))
127 op = OP_DELETE;
128 else if (g_str_equal (op_name, "has"))
129 op = OP_EXISTS;
130 else if (g_str_equal (op_name, "list"))
131 op = OP_LIST;
132
133 switch (op)
134 {
135 case OP_SET:
136
137 if (argc >= 6)
138 value = argv[5];
139
140 case OP_GET:
141
142 if (argc < 5)
143 usage (argv[0], "op '%s' requires an account and key", op_name);
144
145 account = argv[3];
146 setting = argv[4];
147
148 if (account == NULL || *account == '\0')
149 usage (argv[0], "op '%s' requires an account", op_name);
150
151 if (setting == NULL || *setting == '\0')
152 usage (argv[0], "op '%s' requires a key", op_name);
153
154 break;
155
156 case OP_DELETE:
157 case OP_EXISTS:
158
159 if (argc < 4)
160 usage (argv[0], "op '%s' requires an account", op_name);
161
162 account = argv[3];
163 break;
164
165 case OP_LIST:
166 if (argc < 3)
167 usage (argv[0], "op '%s' requires an backend", op_name);
168 break;
169
170 case OP_UNKNOWN:
171 usage (argv[0], "Unknown operation: %s", op_name);
172 }
173
174 /* if we got this far, we have all the args we need: */
175 switch (op)
176 {
177 GStrv list;
178
179 case OP_GET:
180 output = store->get (account, setting);
181 success = output != NULL;
182 break;
183
184 case OP_SET:
185 success = store->set (account, setting, value);
186 output = g_strdup_printf ("%s.%s set to '%s' in %s",
187 account, setting, value, store->name);
188 break;
189
190 case OP_DELETE:
191 success = store->delete (account);
192 output = g_strdup_printf ("%s deleted from %s", account, store->name);
193 break;
194
195 case OP_EXISTS:
196 success = store->exists (account);
197 if (success)
198 output = g_strdup_printf ("Exists in %s", store->name);
199 break;
200
201 case OP_LIST:
202 list = store->list ();
203 output = g_strjoinv ("\n", list);
204 g_strfreev (list);
205 break;
206
207 default:
208 output = g_strdup ("Unknown operation");
209 }
210
211 if (output != NULL)
212 printf ("%s\n", output);
213
214 g_free (output);
215
216 return success ? 0 : 1;
217 }
218
219 static void
usage(const gchar * name,const gchar * fmt,...)220 usage (const gchar *name, const gchar *fmt, ...)
221 {
222 guint i;
223 va_list ap;
224
225 fprintf (stderr, DOCSTRING_A, name);
226
227 fprintf (stderr, "%s", backends[0].name);
228
229 for (i = 1; backends[i].name != NULL; i++)
230 fprintf (stderr, " | %s", backends[i].name);
231
232 fprintf (stderr, DOCSTRING_B);
233
234 va_start (ap, fmt);
235 vfprintf (stderr, fmt, ap);
236 va_end (ap);
237
238 exit (1);
239 }
240