Rewrite IMAP namespace support.
* imap4d/imap4d.c (imap4d_cfg_param): other-namespace and shared-namespace take proper lists as arguments. (imap4d_session_setup0): Call namespace_init_session. (main): Call namespace_init. * imap4d/imap4d.h (set_namespace): Remove. (namespace_init): Change proto. (namespace_init_session): New prototype. (namespace): New declaration. * imap4d/namespace.c: Rewrite using lists. * mailbox/cfg_parser.y (parse_param): Cast string to lists if the parameter has list type.
Showing
5 changed files
with
133 additions
and
83 deletions
1 | 2008-08-21 Sergey Poznyakoff <gray@gnu.org.ua> | ||
2 | |||
3 | Rewrite IMAP namespace support. | ||
4 | * imap4d/imap4d.c (imap4d_cfg_param): other-namespace and | ||
5 | shared-namespace take proper lists as arguments. | ||
6 | (imap4d_session_setup0): Call namespace_init_session. | ||
7 | (main): Call namespace_init. | ||
8 | * imap4d/imap4d.h (set_namespace): Remove. | ||
9 | (namespace_init): Change proto. | ||
10 | (namespace_init_session): New prototype. | ||
11 | (namespace): New declaration. | ||
12 | * imap4d/namespace.c: Rewrite using lists. | ||
13 | * mailbox/cfg_parser.y (parse_param): Cast string to lists if | ||
14 | the parameter has list type. | ||
15 | |||
1 | 2008-08-20 Sergey Poznyakoff <gray@gnu.org.ua> | 16 | 2008-08-20 Sergey Poznyakoff <gray@gnu.org.ua> |
2 | 17 | ||
3 | Implement ID extension. | 18 | Implement ID extension. | ... | ... |
... | @@ -173,27 +173,6 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -173,27 +173,6 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) |
173 | } | 173 | } |
174 | 174 | ||
175 | static int | 175 | static int |
176 | cb2_namespace (mu_debug_t debug, const char *arg, void *data) | ||
177 | { | ||
178 | int what = (int) data; | ||
179 | set_namespace (what, arg); | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int | ||
184 | cb_other (mu_debug_t debug, void *data, mu_config_value_t *val) | ||
185 | { | ||
186 | return mu_cfg_string_value_cb (debug, val, cb2_namespace, (void*)NS_OTHER); | ||
187 | } | ||
188 | |||
189 | static int | ||
190 | cb_shared (mu_debug_t debug, void *data, mu_config_value_t *val) | ||
191 | { | ||
192 | return mu_cfg_string_value_cb (debug, val, cb2_namespace, (void*)NS_SHARED); | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static int | ||
197 | cb_mode (mu_debug_t debug, void *data, mu_config_value_t *val) | 176 | cb_mode (mu_debug_t debug, void *data, mu_config_value_t *val) |
198 | { | 177 | { |
199 | char *p; | 178 | char *p; |
... | @@ -304,12 +283,12 @@ cb_preauth (mu_debug_t debug, void *data, mu_config_value_t *val) | ... | @@ -304,12 +283,12 @@ cb_preauth (mu_debug_t debug, void *data, mu_config_value_t *val) |
304 | } | 283 | } |
305 | 284 | ||
306 | static struct mu_cfg_param imap4d_cfg_param[] = { | 285 | static struct mu_cfg_param imap4d_cfg_param[] = { |
307 | { "other-namespace", mu_cfg_callback, NULL, 0, cb_other, | 286 | { "other-namespace", MU_CFG_LIST_OF(mu_cfg_string), &namespace[NS_OTHER], |
308 | N_("Set other users' namespace. Argument is a colon-separated list " | 287 | 0, NULL, |
309 | "of directories comprising the namespace.") }, | 288 | N_("Set other users' namespace.") }, |
310 | { "shared-namespace", mu_cfg_callback, NULL, 0, cb_shared, | 289 | { "shared-namespace", MU_CFG_LIST_OF(mu_cfg_string), &namespace[NS_SHARED], |
311 | N_("Set shared namespace. Argument is a colon-separated list " | 290 | 0, NULL, |
312 | "of directories comprising the namespace.") }, | 291 | N_("Set shared namespace.") }, |
313 | { "login-disabled", mu_cfg_bool, &login_disabled, 0, NULL, | 292 | { "login-disabled", mu_cfg_bool, &login_disabled, 0, NULL, |
314 | N_("Disable LOGIN command.") }, | 293 | N_("Disable LOGIN command.") }, |
315 | { "create-home-dir", mu_cfg_bool, &create_home_dir, 0, NULL, | 294 | { "create-home-dir", mu_cfg_bool, &create_home_dir, 0, NULL, |
... | @@ -351,7 +330,7 @@ imap4d_session_setup0 () | ... | @@ -351,7 +330,7 @@ imap4d_session_setup0 () |
351 | setuid (auth_data->uid); | 330 | setuid (auth_data->uid); |
352 | 331 | ||
353 | util_chdir (homedir); | 332 | util_chdir (homedir); |
354 | namespace_init (homedir); | 333 | namespace_init_session (homedir); |
355 | mu_diag_output (MU_DIAG_INFO, | 334 | mu_diag_output (MU_DIAG_INFO, |
356 | _("User `%s' logged in (source: %s)"), auth_data->name, | 335 | _("User `%s' logged in (source: %s)"), auth_data->name, |
357 | auth_data->source); | 336 | auth_data->source); |
... | @@ -526,6 +505,8 @@ main (int argc, char **argv) | ... | @@ -526,6 +505,8 @@ main (int argc, char **argv) |
526 | if (tls_required) | 505 | if (tls_required) |
527 | imap4d_capability_add (IMAP_CAPA_XTLSREQUIRED); | 506 | imap4d_capability_add (IMAP_CAPA_XTLSREQUIRED); |
528 | #endif | 507 | #endif |
508 | |||
509 | namespace_init (); | ||
529 | 510 | ||
530 | auth_gssapi_init (); | 511 | auth_gssapi_init (); |
531 | auth_gsasl_init (); | 512 | auth_gsasl_init (); | ... | ... |
... | @@ -277,8 +277,10 @@ extern int imap4d_bye (int); | ... | @@ -277,8 +277,10 @@ extern int imap4d_bye (int); |
277 | extern int imap4d_bye0 (int reason, struct imap4d_command *command); | 277 | extern int imap4d_bye0 (int reason, struct imap4d_command *command); |
278 | 278 | ||
279 | /* Namespace functions */ | 279 | /* Namespace functions */ |
280 | extern int set_namespace (int i, const char *str); | 280 | extern mu_list_t namespace[NS_MAX]; |
281 | extern int namespace_init (char *path); | 281 | |
282 | extern int namespace_init_session (char *path); | ||
283 | extern void namespace_init (void); | ||
282 | extern char * namespace_getfullpath (char *name, const char *delim); | 284 | extern char * namespace_getfullpath (char *name, const char *delim); |
283 | extern char * namespace_checkfullpath (char *name, const char *pattern, | 285 | extern char * namespace_checkfullpath (char *name, const char *pattern, |
284 | const char *delim); | 286 | const char *delim); | ... | ... |
... | @@ -18,38 +18,9 @@ | ... | @@ -18,38 +18,9 @@ |
18 | 18 | ||
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* FIXME: Rewrite using mu_list_t */ | ||
22 | |||
23 | /*FIXME: should be global? */ | ||
24 | typedef int (*nsfp_t) (void *closure, int ns, char *path, int delim); | 21 | typedef int (*nsfp_t) (void *closure, int ns, char *path, int delim); |
25 | 22 | ||
26 | struct namespace_t | 23 | mu_list_t namespace[NS_MAX]; |
27 | { | ||
28 | int subdir_c; | ||
29 | char **subdir_v; | ||
30 | }; | ||
31 | |||
32 | struct namespace_t namespace[NS_MAX]; | ||
33 | |||
34 | /* Note: str is not supposed to be NULL */ | ||
35 | int | ||
36 | set_namespace (int i, const char *str) | ||
37 | { | ||
38 | struct namespace_t *ns = namespace + i; | ||
39 | int argc; | ||
40 | char **argv; | ||
41 | |||
42 | mu_argcv_get (str, ":", NULL, &argc, &argv); | ||
43 | |||
44 | ns->subdir_v = mu_realloc (ns->subdir_v, | ||
45 | (ns->subdir_c + argc) * sizeof (ns->subdir_v[0])); | ||
46 | for (i = 0; i < argc; i++) | ||
47 | ns->subdir_v[ns->subdir_c++] = mu_normalize_path (argv[i], "/"); | ||
48 | /* Free only argv, not its members */ | ||
49 | free (argv); | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | 24 | ||
54 | static char * | 25 | static char * |
55 | printable_pathname (char *str) | 26 | printable_pathname (char *str) |
... | @@ -63,36 +34,59 @@ printable_pathname (char *str) | ... | @@ -63,36 +34,59 @@ printable_pathname (char *str) |
63 | return str; | 34 | return str; |
64 | } | 35 | } |
65 | 36 | ||
66 | static void | 37 | static int |
67 | print_namespace (int n) | 38 | print_namespace_fun (void *item, void *data) |
68 | { | 39 | { |
69 | int i; | 40 | int *pcount = data; |
70 | 41 | char *dir = printable_pathname (item); | |
71 | if (namespace[n].subdir_c == 0) | 42 | char *suf = (dir[0] && dir[strlen (dir) - 1] != '/') ? "/" : ""; |
72 | { | 43 | if ((*pcount)++) |
73 | util_send ("NIL"); | 44 | util_send (" "); |
74 | return; | 45 | util_send ("(\"%s%s\" \"/\")", dir, suf); |
75 | } | 46 | return 0; |
47 | } | ||
76 | 48 | ||
77 | util_send ("("); | 49 | static void |
78 | for (i = 0; i < namespace[n].subdir_c; i++) | 50 | print_namespace (int nsid) |
51 | { | ||
52 | mu_list_t list = namespace[nsid]; | ||
53 | if (!list) | ||
54 | util_send ("NIL"); | ||
55 | else | ||
79 | { | 56 | { |
80 | char *dir = printable_pathname (namespace[n].subdir_v[i]); | 57 | int count; |
81 | char *suf = (dir[0] && dir[strlen (dir) - 1] != '/') ? "/" : ""; | 58 | count = 0; |
82 | util_send ("(\"%s%s\" \"/\")", dir, suf); | 59 | util_send ("("); |
60 | mu_list_do (list, print_namespace_fun, &count); | ||
61 | util_send (")"); | ||
83 | } | 62 | } |
84 | util_send (")"); | ||
85 | } | 63 | } |
86 | 64 | ||
65 | struct ns_closure | ||
66 | { | ||
67 | int id; | ||
68 | nsfp_t fun; | ||
69 | void *closure; | ||
70 | }; | ||
71 | |||
72 | static int | ||
73 | _enum_fun (void *item, void *data) | ||
74 | { | ||
75 | struct ns_closure *nsp = data; | ||
76 | return nsp->fun (nsp->closure, nsp->id, (char*) item, '/'); | ||
77 | } | ||
78 | |||
87 | static int | 79 | static int |
88 | namespace_enumerate (int ns, nsfp_t f, void *closure) | 80 | namespace_enumerate (int id, nsfp_t f, void *closure) |
89 | { | 81 | { |
90 | int i, rc; | 82 | int i, rc; |
83 | struct ns_closure nsc; | ||
91 | 84 | ||
92 | for (i = 0; i < namespace[ns].subdir_c; i++) | 85 | nsc.id = id; |
93 | if ((rc = (*f) (closure, ns, namespace[ns].subdir_v[i], '/'))) | 86 | nsc.fun = f; |
94 | return rc; | 87 | nsc.closure = closure; |
95 | return 0; | 88 | return namespace[id] == 0 ? 0 : |
89 | mu_list_do (namespace[id], _enum_fun, &nsc); | ||
96 | } | 90 | } |
97 | 91 | ||
98 | static int | 92 | static int |
... | @@ -137,7 +131,7 @@ imap4d_namespace (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -137,7 +131,7 @@ imap4d_namespace (struct imap4d_command *command, imap4d_tokbuf_t tok) |
137 | return util_finish (command, RESP_OK, "Completed"); | 131 | return util_finish (command, RESP_OK, "Completed"); |
138 | } | 132 | } |
139 | 133 | ||
140 | 134 | ||
141 | struct namespace_info | 135 | struct namespace_info |
142 | { | 136 | { |
143 | char *name; | 137 | char *name; |
... | @@ -240,8 +234,45 @@ namespace_getfullpath (char *name, const char *delim) | ... | @@ -240,8 +234,45 @@ namespace_getfullpath (char *name, const char *delim) |
240 | } | 234 | } |
241 | 235 | ||
242 | int | 236 | int |
243 | namespace_init (char *path) | 237 | namespace_init_session (char *path) |
244 | { | 238 | { |
245 | set_namespace (NS_PRIVATE, path); | 239 | mu_list_create (&namespace[NS_PRIVATE]); |
240 | mu_list_append (namespace[NS_PRIVATE], | ||
241 | mu_strdup (mu_normalize_path (path, "/"))); | ||
246 | return 0; | 242 | return 0; |
247 | } | 243 | } |
244 | |||
245 | static int | ||
246 | normalize_fun (void *item, void *data) | ||
247 | { | ||
248 | char *name = item; | ||
249 | mu_list_t list = data; | ||
250 | return mu_list_append (list, | ||
251 | mu_strdup (mu_normalize_path (name, "/"))); | ||
252 | } | ||
253 | |||
254 | static void | ||
255 | free_item (void *item) | ||
256 | { | ||
257 | free (item); | ||
258 | } | ||
259 | |||
260 | void | ||
261 | namespace_init () | ||
262 | { | ||
263 | int i; | ||
264 | |||
265 | for (i = 0; i < NS_MAX; i++) | ||
266 | { | ||
267 | if (namespace[i]) | ||
268 | { | ||
269 | mu_list_t list; | ||
270 | mu_list_create (&list); | ||
271 | mu_list_set_destroy_item (list, free_item); | ||
272 | mu_list_do (namespace[i], normalize_fun, list); | ||
273 | mu_list_set_destroy_item (namespace[i], free_item); | ||
274 | mu_list_destroy (&namespace[i]); | ||
275 | namespace[i] = list; | ||
276 | } | ||
277 | } | ||
278 | } | ... | ... |
... | @@ -1088,6 +1088,27 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) | ... | @@ -1088,6 +1088,27 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) |
1088 | { | 1088 | { |
1089 | clos.sdata = sdata; | 1089 | clos.sdata = sdata; |
1090 | clos.locus = &node->locus; | 1090 | clos.locus = &node->locus; |
1091 | switch (node->label->type) | ||
1092 | { | ||
1093 | case MU_CFG_LIST: | ||
1094 | break; | ||
1095 | |||
1096 | case MU_CFG_STRING: | ||
1097 | { | ||
1098 | mu_list_t list; | ||
1099 | mu_list_create (&list); | ||
1100 | mu_list_append (list, config_value_dup (node->label)); | ||
1101 | node->label->type = MU_CFG_LIST; | ||
1102 | node->label->v.list = list; | ||
1103 | } | ||
1104 | break; | ||
1105 | |||
1106 | case MU_CFG_ARRAY: | ||
1107 | _mu_cfg_perror (sdata->tree->debug, &node->locus, | ||
1108 | _("expected list, but found array")); | ||
1109 | return 1; | ||
1110 | } | ||
1111 | |||
1091 | mu_list_create (&clos.list); | 1112 | mu_list_create (&clos.list); |
1092 | mu_list_do (node->label->v.list, _set_fun, &clos); | 1113 | mu_list_do (node->label->v.list, _set_fun, &clos); |
1093 | *(mu_list_t*)tgt = clos.list; | 1114 | *(mu_list_t*)tgt = clos.list; | ... | ... |
-
Please register or sign in to post a comment