summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-03-23 13:02:38 +0200
committerSergey Poznyakoff <gray@gnu.org>2019-03-23 13:10:18 +0200
commit15b4ea89880ea674717e9fa64e146dd744e8e35c (patch)
treefe9e3285fa904cf5b64f6936541990d1a9143393
parent963add27d0c6b4361d78c30a1b5a362e2c7355e6 (diff)
downloadmailutils-15b4ea89880ea674717e9fa64e146dd744e8e35c.tar.gz
mailutils-15b4ea89880ea674717e9fa64e146dd744e8e35c.tar.bz2
Rewrite folder listing interface.
New function mu_folder_scan provides an improved scanning interface. In particular, it allows the user to abridge the scan to mailboxes of certain type (or types). Existing listing API functions are rewritten as alternative entry points to mu_folder_scan. * include/mailutils/folder.h (mu_folder_scanner): New struct. (mu_folder_scan): New function. * include/mailutils/registrar.h (mu_registrar_list_p): New function. * include/mailutils/sys/folder.h (_mu_folder._list): Change signature. * libmailutils/base/registrar.c (mu_registrar_list_p): New function. * libmailutils/mailbox/folder.c (mu_folder_scan): New function. (mu_folder_enumerate): Rewrite as entry point to mu_folder_scan. * libmailutils/mailbox/fsfolder.c: Use new API, * libmailutils/tests/fsfolder.c: Rewrite scheme matcher. * libmailutils/tests/fsfolder00.at: Fix test output. * libmailutils/tests/fsfolder02.at: Likewise. * libproto/imap/folder.c: Use new API.
-rw-r--r--include/mailutils/folder.h36
-rw-r--r--include/mailutils/registrar.h1
-rw-r--r--include/mailutils/sys/folder.h3
-rw-r--r--libmailutils/base/registrar.c23
-rw-r--r--libmailutils/mailbox/folder.c44
-rw-r--r--libmailutils/mailbox/fsfolder.c118
-rw-r--r--libmailutils/tests/fsfolder.c26
-rw-r--r--libmailutils/tests/fsfolder00.at20
-rw-r--r--libmailutils/tests/fsfolder02.at2
-rw-r--r--libproto/imap/folder.c25
10 files changed, 194 insertions, 104 deletions
diff --git a/include/mailutils/folder.h b/include/mailutils/folder.h
index 12327987d..4ca4b92ee 100644
--- a/include/mailutils/folder.h
+++ b/include/mailutils/folder.h
@@ -51,18 +51,42 @@ extern int mu_folder_delete (mu_folder_t, const char *);
51extern int mu_folder_rename (mu_folder_t, const char *, const char *); 51extern int mu_folder_rename (mu_folder_t, const char *, const char *);
52extern int mu_folder_subscribe (mu_folder_t, const char *); 52extern int mu_folder_subscribe (mu_folder_t, const char *);
53extern int mu_folder_unsubscribe (mu_folder_t, const char *); 53extern int mu_folder_unsubscribe (mu_folder_t, const char *);
54extern int mu_folder_list (mu_folder_t, const char *, void *,
55 size_t, mu_list_t *);
56extern int mu_folder_enumerate (mu_folder_t, const char *,
57 void *, int,
58 size_t, mu_list_t *,
59 mu_folder_enumerate_fp, void *);
60extern int mu_folder_lsub (mu_folder_t, const char *, const char *, 54extern int mu_folder_lsub (mu_folder_t, const char *, const char *,
61 mu_list_t *); 55 mu_list_t *);
62 56
63extern int mu_folder_attach_ticket (mu_folder_t folder); 57extern int mu_folder_attach_ticket (mu_folder_t folder);
64extern int mu_folder_is_local (mu_folder_t folder); 58extern int mu_folder_is_local (mu_folder_t folder);
65 59
60 /* Scan API */
61/* The mu_folder_scanner structure controls the scanning. All of
62 members are optional. Unused ones must be initialized to 0.
63*/
64struct mu_folder_scanner
65{
66 char const *refname; /* Reference name */
67 void *pattern; /* Matching pattern */
68 int match_flags; /* Matching flags */
69 size_t max_level; /* Max. nesting level to descend */
70 mu_folder_enumerate_fp enumfun; /* Enumeration function */
71 void *enumdata; /* Data for enumfun */
72 mu_list_t records; /* List of allowed records */
73 mu_list_t result; /* Result list */
74};
75
76#define MU_FOLDER_SCANNER_INITIALIZER \
77 { NULL, NULL, 0, 0, NULL, NULL, NULL, NULL }
78
79int mu_folder_scan (mu_folder_t folder, struct mu_folder_scanner *scn);
80
81/* The following two functions are implemented as alternative entry
82 points to mu_folder_scan: */
83extern int mu_folder_list (mu_folder_t, const char *, void *,
84 size_t, mu_list_t *);
85extern int mu_folder_enumerate (mu_folder_t, const char *,
86 void *, int,
87 size_t, mu_list_t *,
88 mu_folder_enumerate_fp, void *);
89
66 /* Match function */ 90 /* Match function */
67extern int mu_folder_set_match (mu_folder_t folder, mu_folder_match_fp pmatch); 91extern int mu_folder_set_match (mu_folder_t folder, mu_folder_match_fp pmatch);
68extern int mu_folder_get_match (mu_folder_t folder, 92extern int mu_folder_get_match (mu_folder_t folder,
diff --git a/include/mailutils/registrar.h b/include/mailutils/registrar.h
index 976e82190..a2cd76b0b 100644
--- a/include/mailutils/registrar.h
+++ b/include/mailutils/registrar.h
@@ -93,6 +93,7 @@ int mu_record_get_mailer (mu_record_t, int (*(*)) (mu_mailer_t));
93int mu_record_get_folder (mu_record_t, int (*(*)) (mu_folder_t)); 93int mu_record_get_folder (mu_record_t, int (*(*)) (mu_folder_t));
94 94
95int mu_record_list_p (mu_record_t record, const char *name, int); 95int mu_record_list_p (mu_record_t record, const char *name, int);
96int mu_registrar_list_p (mu_list_t rlist, char const *name, int flags);
96 97
97/* Records provided by the library. */ 98/* Records provided by the library. */
98 99
diff --git a/include/mailutils/sys/folder.h b/include/mailutils/sys/folder.h
index 050a18f97..6dd2d45da 100644
--- a/include/mailutils/sys/folder.h
+++ b/include/mailutils/sys/folder.h
@@ -49,8 +49,7 @@ struct _mu_folder
49 49
50 int (*_open) (mu_folder_t, int flag); 50 int (*_open) (mu_folder_t, int flag);
51 int (*_close) (mu_folder_t); 51 int (*_close) (mu_folder_t);
52 int (*_list) (mu_folder_t, const char *, void *, int, size_t, 52 int (*_list) (mu_folder_t, struct mu_folder_scanner *);
53 mu_list_t, mu_folder_enumerate_fp, void *);
54 int (*_lsub) (mu_folder_t, const char *, const char *, 53 int (*_lsub) (mu_folder_t, const char *, const char *,
55 mu_list_t); 54 mu_list_t);
56 mu_folder_match_fp _match; 55 mu_folder_match_fp _match;
diff --git a/libmailutils/base/registrar.c b/libmailutils/base/registrar.c
index da736a07f..e25e6d810 100644
--- a/libmailutils/base/registrar.c
+++ b/libmailutils/base/registrar.c
@@ -400,6 +400,29 @@ mu_registrar_test_local_url (mu_url_t url, int *pres)
400 return 0; 400 return 0;
401} 401}
402 402
403struct listable_closure
404{
405 char const *name;
406 int flags;
407};
408
409static int
410record_listable (void *item, void *data)
411{
412 mu_record_t record = item;
413 struct listable_closure *cls = data;
414 return !mu_record_list_p (record, cls->name, cls->flags);
415}
416
417int
418mu_registrar_list_p (mu_list_t rlist, char const *name, int flags)
419{
420 struct listable_closure cls = { name, flags };
421 if (!rlist)
422 rlist = registrar_list;
423 return !mu_list_foreach (rlist, record_listable, &cls);
424}
425
403/* Apply flt to each record in the registry and remove those, for which it 426/* Apply flt to each record in the registry and remove those, for which it
404 returns non-zero. */ 427 returns non-zero. */
405int 428int
diff --git a/libmailutils/mailbox/folder.c b/libmailutils/mailbox/folder.c
index 9df89ed05..8a474c8f6 100644
--- a/libmailutils/mailbox/folder.c
+++ b/libmailutils/mailbox/folder.c
@@ -343,6 +343,18 @@ mu_list_response_free (void *data)
343} 343}
344 344
345int 345int
346mu_folder_scan (mu_folder_t folder, struct mu_folder_scanner *scn)
347{
348 if (!folder || !scn)
349 return EINVAL;
350 if (folder->_list == NULL)
351 return ENOSYS;
352 if (scn->result)
353 mu_list_set_destroy_item (scn->result, mu_list_response_free);
354 return folder->_list (folder, scn);
355}
356
357int
346mu_folder_list (mu_folder_t folder, const char *dirname, void *pattern, 358mu_folder_list (mu_folder_t folder, const char *dirname, void *pattern,
347 size_t max_level, 359 size_t max_level,
348 mu_list_t *pflist) 360 mu_list_t *pflist)
@@ -360,29 +372,35 @@ mu_folder_enumerate (mu_folder_t folder, const char *name,
360 mu_folder_enumerate_fp enumfun, void *enumdata) 372 mu_folder_enumerate_fp enumfun, void *enumdata)
361{ 373{
362 int status; 374 int status;
363 if (folder == NULL) 375 if (folder == NULL || (!pflist && !enumfun))
364 return EINVAL; 376 return EINVAL;
365 else if (folder->_list == NULL) 377 else if (folder->_list == NULL)
366 return ENOSYS; 378 return ENOSYS;
367 else 379 else
368 { 380 {
369 mu_list_t list = NULL; 381 struct mu_folder_scanner scn;
370 382
383 scn.refname = name;
384 scn.pattern = pattern;
385 scn.match_flags = flags;
386 scn.max_level = max_level;
387 scn.enumfun = enumfun;
388 scn.enumdata = enumdata;
389 scn.records = NULL;
371 if (pflist) 390 if (pflist)
372 { 391 {
373 status = mu_list_create (&list); 392 status = mu_list_create (&scn.result);
374 if (status) 393 if (status)
375 return status; 394 return status;
376 *pflist = list;
377 mu_list_set_destroy_item (list, mu_list_response_free);
378 } 395 }
379 else if (!enumfun) 396 status = mu_folder_scan (folder, &scn);
380 return EINVAL; 397 if (status == 0)
381 398 {
382 status = folder->_list (folder, name, pattern, flags, max_level, 399 if (pflist)
383 list, enumfun, enumdata); 400 *pflist = scn.result;
384 if (status) 401 }
385 mu_list_destroy (pflist); 402 else
403 mu_list_destroy (&scn.result);
386 } 404 }
387 return status; 405 return status;
388} 406}
diff --git a/libmailutils/mailbox/fsfolder.c b/libmailutils/mailbox/fsfolder.c
index 2b8aa2e99..042ae6707 100644
--- a/libmailutils/mailbox/fsfolder.c
+++ b/libmailutils/mailbox/fsfolder.c
@@ -183,18 +183,12 @@ struct inode_list /* Inode/dev number list used to cut off
183 dev_t dev; 183 dev_t dev;
184}; 184};
185 185
186struct search_data 186