* examples/lsf.c: Use mu_folder_enumerate + callback function, for
speed up. * imap4d/imap4d.h (WCARD_NOMATCH,WCARD_MATCH) (WCARD_RECURSE_MATCH): Remove. * imap4d/list.c: Rewrite using mu_folder_enumerate. * imap4d/lsub.c (imap4d_lsub): Fix call to util_wcard_match. * imap4d/util.c (util_wcard_match): Return 0 for match, 1 otherwise. * imap4d/testsuite/imap4d/list.exp: Fix two testcases to match the new (stricter RFC-compliant) behavior. * include/mailutils/folder.h (mu_folder_match_fp): New typedef. (mu_folder_enumerate_fp): New typedef. (mu_folder_enumerate): New function. (mu_folder_set_match, mu_folder_get_match): New functions. * libproto/imap/folder.c, libproto/include/imap0.h, libproto/nntp/folder.c : Use new folder list framework. * libproto/include/folder0.h (struct _mu_folder._list): Change signature. (_match): New member. * libproto/mbox/folder.c (_path_is_scheme): Improve automatic mailbox format detection. (folder_mbox_list): Do not use glob, recursively scan subdirectories instead. * mailbox/folder.c (mu_folder_match): New function. (mu_folder_create_from_record): Set mu_folder_match as the default matcher. (mu_folder_set_match, mu_folder_get_match): New functions. (mu_folder_enumerate): New function. (mu_folder_list): Rewrite using mu_folder_enumerate.
Showing
15 changed files
with
306 additions
and
142 deletions
1 | 2007-12-21 Sergey Poznyakoff <gray@gnu.org.ua> | ||
2 | |||
3 | * examples/lsf.c: Use mu_folder_enumerate + callback function, for | ||
4 | speed up. | ||
5 | * imap4d/imap4d.h (WCARD_NOMATCH,WCARD_MATCH) | ||
6 | (WCARD_RECURSE_MATCH): Remove. | ||
7 | * imap4d/list.c: Rewrite using mu_folder_enumerate. | ||
8 | * imap4d/lsub.c (imap4d_lsub): Fix call to util_wcard_match. | ||
9 | * imap4d/util.c (util_wcard_match): Return 0 for match, 1 | ||
10 | otherwise. | ||
11 | * imap4d/testsuite/imap4d/list.exp: Fix two testcases to match | ||
12 | the new (stricter RFC-compliant) behavior. | ||
13 | * include/mailutils/folder.h (mu_folder_match_fp): New typedef. | ||
14 | (mu_folder_enumerate_fp): New typedef. | ||
15 | (mu_folder_enumerate): New function. | ||
16 | (mu_folder_set_match, mu_folder_get_match): New functions. | ||
17 | |||
18 | * libproto/imap/folder.c, libproto/include/imap0.h, | ||
19 | libproto/nntp/folder.c : Use new folder list framework. | ||
20 | * libproto/include/folder0.h (struct _mu_folder._list): Change | ||
21 | signature. | ||
22 | (_match): New member. | ||
23 | * libproto/mbox/folder.c (_path_is_scheme): Improve automatic | ||
24 | mailbox format detection. | ||
25 | (folder_mbox_list): Do not use glob, recursively scan | ||
26 | subdirectories instead. | ||
27 | * mailbox/folder.c (mu_folder_match): New function. | ||
28 | (mu_folder_create_from_record): Set mu_folder_match as the default | ||
29 | matcher. | ||
30 | (mu_folder_set_match, mu_folder_get_match): New functions. | ||
31 | (mu_folder_enumerate): New function. | ||
32 | (mu_folder_list): Rewrite using mu_folder_enumerate. | ||
33 | |||
1 | 2007-12-19 Sergey Poznyakoff <gray@gnu.org.ua> | 34 | 2007-12-19 Sergey Poznyakoff <gray@gnu.org.ua> |
2 | 35 | ||
3 | * NEWS: Update. | 36 | * NEWS: Update. | ... | ... |
... | @@ -25,10 +25,8 @@ | ... | @@ -25,10 +25,8 @@ |
25 | #include <mailutils/mailutils.h> | 25 | #include <mailutils/mailutils.h> |
26 | 26 | ||
27 | static int | 27 | static int |
28 | ls_printer (void *item, void *data) | 28 | enumfun (mu_folder_t folder, struct mu_list_response *resp, void *data) |
29 | { | 29 | { |
30 | struct mu_list_response *resp = item; | ||
31 | |||
32 | printf ("%c%c %c %4d %s\n", | 30 | printf ("%c%c %c %4d %s\n", |
33 | (resp->type & MU_FOLDER_ATTRIBUTE_DIRECTORY) ? 'd' : '-', | 31 | (resp->type & MU_FOLDER_ATTRIBUTE_DIRECTORY) ? 'd' : '-', |
34 | (resp->type & MU_FOLDER_ATTRIBUTE_FILE) ? 'f' : '-', | 32 | (resp->type & MU_FOLDER_ATTRIBUTE_FILE) ? 'f' : '-', |
... | @@ -60,13 +58,14 @@ ls_folders (char *fname, char *ref, char *pattern, int level) | ... | @@ -60,13 +58,14 @@ ls_folders (char *fname, char *ref, char *pattern, int level) |
60 | return 1; | 58 | return 1; |
61 | } | 59 | } |
62 | 60 | ||
63 | status = mu_folder_list (folder, ref, pattern, level, &flist); | 61 | status = mu_folder_enumerate (folder, ref, pattern, 0, level, &flist, |
62 | enumfun, NULL); | ||
63 | |||
64 | switch (status) | 64 | switch (status) |
65 | { | 65 | { |
66 | case 0: | 66 | case 0: |
67 | mu_list_count (flist, &count); | 67 | mu_list_count (flist, &count); |
68 | printf ("Number of folders: %lu\n", (unsigned long) count); | 68 | printf ("Number of folders: %lu\n", (unsigned long) count); |
69 | mu_list_do (flist, ls_printer, NULL); | ||
70 | mu_list_destroy (&flist); | 69 | mu_list_destroy (&flist); |
71 | break; | 70 | break; |
72 | case MU_ERR_NOENT: | 71 | case MU_ERR_NOENT: |
... | @@ -105,7 +104,5 @@ main (int argc, char *argv[]) | ... | @@ -105,7 +104,5 @@ main (int argc, char *argv[]) |
105 | 104 | ||
106 | mu_register_all_mbox_formats (); | 105 | mu_register_all_mbox_formats (); |
107 | 106 | ||
108 | if (!ref) | ||
109 | ref = folder; | ||
110 | return ls_folders (folder, ref, pattern, level); | 107 | return ls_folders (folder, ref, pattern, level); |
111 | } | 108 | } | ... | ... |
... | @@ -148,11 +148,6 @@ struct imap4d_command | ... | @@ -148,11 +148,6 @@ struct imap4d_command |
148 | #define NS_SHARED 2 | 148 | #define NS_SHARED 2 |
149 | #define NS_MAX 3 | 149 | #define NS_MAX 3 |
150 | 150 | ||
151 | /* Wildcard return codes */ | ||
152 | #define WCARD_NOMATCH 0 | ||
153 | #define WCARD_MATCH 1 | ||
154 | #define WCARD_RECURSE_MATCH 2 | ||
155 | |||
156 | /* IMAP4D capability names */ | 151 | /* IMAP4D capability names */ |
157 | #define IMAP_CAPA_STARTTLS "STARTTLS" | 152 | #define IMAP_CAPA_STARTTLS "STARTTLS" |
158 | #define IMAP_CAPA_LOGINDISABLED "LOGINDISABLED" | 153 | #define IMAP_CAPA_LOGINDISABLED "LOGINDISABLED" | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -60,12 +60,12 @@ imap4d_lsub (struct imap4d_command *command, char *arg) | ... | @@ -60,12 +60,12 @@ imap4d_lsub (struct imap4d_command *command, char *arg) |
60 | char *buf = NULL; | 60 | char *buf = NULL; |
61 | size_t n = 0; | 61 | size_t n = 0; |
62 | 62 | ||
63 | while (getline(&buf, &n, fp) > 0) | 63 | while (getline (&buf, &n, fp) > 0) |
64 | { | 64 | { |
65 | int len = strlen (buf); | 65 | int len = strlen (buf); |
66 | if (buf[len - 1] == '\n') | 66 | if (buf[len - 1] == '\n') |
67 | buf[len - 1] = '\0'; | 67 | buf[len - 1] = '\0'; |
68 | if (util_wcard_match (buf, pattern, delim) != WCARD_NOMATCH) | 68 | if (util_wcard_match (buf, pattern, delim) == 0) |
69 | util_out (RESP_NONE, "LIST () \"%s\" %s", delim, buf); | 69 | util_out (RESP_NONE, "LIST () \"%s\" %s", delim, buf); |
70 | } | 70 | } |
71 | fclose (fp); | 71 | fclose (fp); | ... | ... |
... | @@ -53,8 +53,6 @@ imap4d_test "LIST \"/\" \"*\""\ | ... | @@ -53,8 +53,6 @@ imap4d_test "LIST \"/\" \"*\""\ |
53 | 53 | ||
54 | imap4d_test -sort "LIST \"$MU_DATA_DIR\" \"*\""\ | 54 | imap4d_test -sort "LIST \"$MU_DATA_DIR\" \"*\""\ |
55 | "LIST (\\NoSelect) \"/\" $MU_DATA_DIR/etc"\ | 55 | "LIST (\\NoSelect) \"/\" $MU_DATA_DIR/etc"\ |
56 | "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/etc/mail.rc"\ | ||
57 | "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/etc/passwd"\ | ||
58 | "LIST (\\NoSelect) \"/\" $MU_DATA_DIR/spool"\ | 56 | "LIST (\\NoSelect) \"/\" $MU_DATA_DIR/spool"\ |
59 | "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/spool/bigto.mbox"\ | 57 | "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/spool/bigto.mbox"\ |
60 | "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/spool/relational.mbox" \ | 58 | "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/spool/relational.mbox" \ |
... | @@ -77,13 +75,8 @@ imap4d_test "LIST \"$MU_DATA_DIR/folder\" \"one\""\ | ... | @@ -77,13 +75,8 @@ imap4d_test "LIST \"$MU_DATA_DIR/folder\" \"one\""\ |
77 | "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/folder/one"\ | 75 | "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/folder/one"\ |
78 | "OK LIST Completed" | 76 | "OK LIST Completed" |
79 | 77 | ||
80 | # Well, I doubt if this is quite OK with the RFC, but at least it does | ||
81 | # not contradict it. The first INBOX refers to the reserved word meaning | ||
82 | # "the primary mailbox for this user on this server", the second one is | ||
83 | # the actual filename. | ||
84 | imap4d_test -sort "LIST \"\" INBOX"\ | 78 | imap4d_test -sort "LIST \"\" INBOX"\ |
85 | "LIST (\\NoInferiors) NIL INBOX"\ | 79 | "LIST (\\NoInferiors) NIL INBOX"\ |
86 | "LIST (\\NoInferiors) \"/\" INBOX"\ | ||
87 | "OK LIST Completed" | 80 | "OK LIST Completed" |
88 | 81 | ||
89 | imap4d_stop | 82 | imap4d_stop | ... | ... |
... | @@ -1028,7 +1028,7 @@ util_localname () | ... | @@ -1028,7 +1028,7 @@ util_localname () |
1028 | return localname; | 1028 | return localname; |
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | /* Match STRING against the IMAP4 wildard pattern PATTERN */ | 1031 | /* Match STRING against the IMAP4 wildcard pattern PATTERN. */ |
1032 | 1032 | ||
1033 | int | 1033 | int |
1034 | util_wcard_match (const char *string, const char *pattern, const char *delim) | 1034 | util_wcard_match (const char *string, const char *pattern, const char *delim) |
... | @@ -1041,40 +1041,39 @@ util_wcard_match (const char *string, const char *pattern, const char *delim) | ... | @@ -1041,40 +1041,39 @@ util_wcard_match (const char *string, const char *pattern, const char *delim) |
1041 | switch (c) | 1041 | switch (c) |
1042 | { | 1042 | { |
1043 | case '%': | 1043 | case '%': |
1044 | /* Matches everything except '/' */ | ||
1044 | if (*p == '\0') | 1045 | if (*p == '\0') |
1045 | { | 1046 | { |
1046 | /* Matches everything except '/' */ | 1047 | for (; *n; ++n) |
1047 | for (; *n && *n != delim[0]; n++) | 1048 | if (*n == *delim) |
1048 | ; | 1049 | return 1; |
1049 | return (*n == delim[0]) ? WCARD_RECURSE_MATCH : WCARD_MATCH; | 1050 | return 0; |
1050 | } | 1051 | } |
1051 | else | 1052 | else |
1052 | for (; *n != '\0'; ++n) | 1053 | for (; *n != '\0'; ++n) |
1053 | if (util_wcard_match (n, p, delim) == WCARD_MATCH) | 1054 | if (util_wcard_match (n, p, delim) == 0) |
1054 | return WCARD_MATCH; | 1055 | return 0; |
1055 | break; | 1056 | break; |
1056 | 1057 | ||
1057 | case '*': | 1058 | case '*': |
1058 | if (*p == '\0') | 1059 | if (*p == '\0') |
1059 | return WCARD_RECURSE_MATCH; | 1060 | return 0; |
1061 | else | ||
1060 | for (; *n != '\0'; ++n) | 1062 | for (; *n != '\0'; ++n) |
1061 | { | 1063 | if (util_wcard_match (n, p, delim) == 0) |
1062 | int status = util_wcard_match (n, p, delim); | 1064 | return 0; |
1063 | if (status == WCARD_MATCH || status == WCARD_RECURSE_MATCH) | ||
1064 | return status; | ||
1065 | } | ||
1066 | break; | 1065 | break; |
1067 | 1066 | ||
1068 | default: | 1067 | default: |
1069 | if (c != *n) | 1068 | if (c != *n) |
1070 | return WCARD_NOMATCH; | 1069 | return 1; |
1071 | } | 1070 | } |
1072 | } | 1071 | } |
1073 | 1072 | ||
1074 | if (!c && !*n) | 1073 | if (!c && !*n) |
1075 | return WCARD_MATCH; | 1074 | return 0; |
1076 | 1075 | ||
1077 | return WCARD_NOMATCH; | 1076 | return 1; |
1078 | } | 1077 | } |
1079 | 1078 | ||
1080 | /* Return the uindvalidity of a mailbox. | 1079 | /* Return the uindvalidity of a mailbox. | ... | ... |
... | @@ -33,6 +33,10 @@ struct mu_list_response | ... | @@ -33,6 +33,10 @@ struct mu_list_response |
33 | char *name; | 33 | char *name; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | typedef int (*mu_folder_match_fp) (const char *, void *, int); | ||
37 | typedef int (*mu_folder_enumerate_fp) (mu_folder_t, struct mu_list_response *, | ||
38 | void *data); | ||
39 | |||
36 | /* Constructor/destructor and possible types. */ | 40 | /* Constructor/destructor and possible types. */ |
37 | extern int mu_folder_create (mu_folder_t *, const char *); | 41 | extern int mu_folder_create (mu_folder_t *, const char *); |
38 | extern int mu_folder_create_from_record (mu_folder_t *, const char *, | 42 | extern int mu_folder_create_from_record (mu_folder_t *, const char *, |
... | @@ -47,8 +51,12 @@ extern int mu_folder_delete (mu_folder_t, const char *); | ... | @@ -47,8 +51,12 @@ extern int mu_folder_delete (mu_folder_t, const char *); |
47 | extern int mu_folder_rename (mu_folder_t, const char *, const char *); | 51 | extern int mu_folder_rename (mu_folder_t, const char *, const char *); |
48 | extern int mu_folder_subscribe (mu_folder_t, const char *); | 52 | extern int mu_folder_subscribe (mu_folder_t, const char *); |
49 | extern int mu_folder_unsubscribe (mu_folder_t, const char *); | 53 | extern int mu_folder_unsubscribe (mu_folder_t, const char *); |
50 | extern int mu_folder_list (mu_folder_t, const char *, const char *, | 54 | extern int mu_folder_list (mu_folder_t, const char *, void *, |
51 | size_t, mu_list_t *); | 55 | size_t, mu_list_t *); |
56 | extern int mu_folder_enumerate (mu_folder_t, const char *, | ||
57 | void *, int, | ||
58 | size_t, mu_list_t *, | ||
59 | mu_folder_enumerate_fp, void *); | ||
52 | extern int mu_folder_lsub (mu_folder_t, const char *, const char *, | 60 | extern int mu_folder_lsub (mu_folder_t, const char *, const char *, |
53 | mu_list_t *); | 61 | mu_list_t *); |
54 | 62 | ||
... | @@ -56,6 +64,11 @@ extern int mu_folder_lsub (mu_folder_t, const char *, const char *, | ... | @@ -56,6 +64,11 @@ extern int mu_folder_lsub (mu_folder_t, const char *, const char *, |
56 | extern int mu_folder_get_stream (mu_folder_t, mu_stream_t *); | 64 | extern int mu_folder_get_stream (mu_folder_t, mu_stream_t *); |
57 | extern int mu_folder_set_stream (mu_folder_t, mu_stream_t); | 65 | extern int mu_folder_set_stream (mu_folder_t, mu_stream_t); |
58 | 66 | ||
67 | /* Match function */ | ||
68 | extern int mu_folder_set_match (mu_folder_t folder, mu_folder_match_fp pmatch); | ||
69 | extern int mu_folder_get_match (mu_folder_t folder, | ||
70 | mu_folder_match_fp *pmatch); | ||
71 | |||
59 | /* Notifications. */ | 72 | /* Notifications. */ |
60 | extern int mu_folder_get_observable (mu_folder_t, mu_observable_t *); | 73 | extern int mu_folder_get_observable (mu_folder_t, mu_observable_t *); |
61 | 74 | ... | ... |
... | @@ -111,6 +111,7 @@ typedef struct _mu_tcp_server *mu_tcp_server_t; | ... | @@ -111,6 +111,7 @@ typedef struct _mu_tcp_server *mu_tcp_server_t; |
111 | 111 | ||
112 | #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001 | 112 | #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001 |
113 | #define MU_FOLDER_ATTRIBUTE_FILE 0x002 | 113 | #define MU_FOLDER_ATTRIBUTE_FILE 0x002 |
114 | |||
114 | #define MU_FOLDER_ATTRIBUTE_ALL \ | 115 | #define MU_FOLDER_ATTRIBUTE_ALL \ |
115 | (MU_FOLDER_ATTRIBUTE_DIRECTORY|MU_FOLDER_ATTRIBUTE_FILE) | 116 | (MU_FOLDER_ATTRIBUTE_DIRECTORY|MU_FOLDER_ATTRIBUTE_FILE) |
116 | 117 | ... | ... |
... | @@ -111,9 +111,10 @@ static int folder_imap_open (mu_folder_t, int); | ... | @@ -111,9 +111,10 @@ static int folder_imap_open (mu_folder_t, int); |
111 | static int folder_imap_close (mu_folder_t); | 111 | static int folder_imap_close (mu_folder_t); |
112 | static void folder_imap_destroy (mu_folder_t); | 112 | static void folder_imap_destroy (mu_folder_t); |
113 | static int folder_imap_delete (mu_folder_t, const char *); | 113 | static int folder_imap_delete (mu_folder_t, const char *); |
114 | static int folder_imap_list (mu_folder_t, const char *, const char *, | 114 | static int folder_imap_list (mu_folder_t, const char *, void *, |
115 | size_t, | 115 | size_t, |
116 | mu_list_t); | 116 | mu_list_t, |
117 | mu_folder_enumerate_fp efp, void *edp); | ||
117 | static int folder_imap_lsub (mu_folder_t, const char *, const char *, | 118 | static int folder_imap_lsub (mu_folder_t, const char *, const char *, |
118 | mu_list_t); | 119 | mu_list_t); |
119 | static int folder_imap_rename (mu_folder_t, const char *, | 120 | static int folder_imap_rename (mu_folder_t, const char *, |
... | @@ -975,9 +976,10 @@ glob_to_imap (const char *pat, int recursive) | ... | @@ -975,9 +976,10 @@ glob_to_imap (const char *pat, int recursive) |
975 | } | 976 | } |
976 | 977 | ||
977 | static int | 978 | static int |
978 | folder_imap_list (mu_folder_t folder, const char *ref, const char *name, | 979 | folder_imap_list (mu_folder_t folder, const char *ref, void *name, |
979 | size_t max_level, | 980 | size_t max_level, |
980 | mu_list_t flist) | 981 | mu_list_t flist, |
982 | mu_folder_enumerate_fp efp, void *edp) | ||
981 | { | 983 | { |
982 | f_imap_t f_imap = folder->data; | 984 | f_imap_t f_imap = folder->data; |
983 | int status = 0; | 985 | int status = 0; |
... | @@ -992,6 +994,11 @@ folder_imap_list (mu_folder_t folder, const char *ref, const char *name, | ... | @@ -992,6 +994,11 @@ folder_imap_list (mu_folder_t folder, const char *ref, const char *name, |
992 | if (name == NULL) | 994 | if (name == NULL) |
993 | name = ""; | 995 | name = ""; |
994 | 996 | ||
997 | f_imap->folder = folder; | ||
998 | f_imap->enum_fun = efp; | ||
999 | f_imap->enum_stop = 0; | ||
1000 | f_imap->enum_data = edp; | ||
1001 | |||
995 | switch (f_imap->state) | 1002 | switch (f_imap->state) |
996 | { | 1003 | { |
997 | case IMAP_NO_STATE: | 1004 | case IMAP_NO_STATE: |
... | @@ -1017,6 +1024,11 @@ folder_imap_list (mu_folder_t folder, const char *ref, const char *name, | ... | @@ -1017,6 +1024,11 @@ folder_imap_list (mu_folder_t folder, const char *ref, const char *name, |
1017 | break; | 1024 | break; |
1018 | } | 1025 | } |
1019 | 1026 | ||
1027 | f_imap->folder = NULL; | ||
1028 | f_imap->enum_fun = NULL; | ||
1029 | f_imap->enum_stop = 0; | ||
1030 | f_imap->enum_data = NULL; | ||
1031 | |||
1020 | list_copy (flist, f_imap->flist, strlen (ref), | 1032 | list_copy (flist, f_imap->flist, strlen (ref), |
1021 | imap_mailbox_name_match, name, max_level); | 1033 | imap_mailbox_name_match, name, max_level); |
1022 | 1034 | ||
... | @@ -1041,6 +1053,10 @@ folder_imap_lsub (mu_folder_t folder, const char *ref, const char *name, | ... | @@ -1041,6 +1053,10 @@ folder_imap_lsub (mu_folder_t folder, const char *ref, const char *name, |
1041 | if (name == NULL) | 1053 | if (name == NULL) |
1042 | name = ""; | 1054 | name = ""; |
1043 | 1055 | ||
1056 | f_imap->enum_fun = NULL; | ||
1057 | f_imap->enum_stop = 0; | ||
1058 | f_imap->enum_data = NULL; | ||
1059 | |||
1044 | switch (f_imap->state) | 1060 | switch (f_imap->state) |
1045 | { | 1061 | { |
1046 | case IMAP_NO_STATE: | 1062 | case IMAP_NO_STATE: |
... | @@ -1385,6 +1401,9 @@ imap_list (f_imap_t f_imap) | ... | @@ -1385,6 +1401,9 @@ imap_list (f_imap_t f_imap) |
1385 | int argc; | 1401 | int argc; |
1386 | char **argv; | 1402 | char **argv; |
1387 | 1403 | ||
1404 | if (f_imap->enum_stop) | ||
1405 | return 0; | ||
1406 | |||
1388 | buffer = malloc (len); | 1407 | buffer = malloc (len); |
1389 | if (!buffer) | 1408 | if (!buffer) |
1390 | return ENOMEM; | 1409 | return ENOMEM; |
... | @@ -1400,7 +1419,6 @@ imap_list (f_imap_t f_imap) | ... | @@ -1400,7 +1419,6 @@ imap_list (f_imap_t f_imap) |
1400 | mu_list_create (&f_imap->flist); | 1419 | mu_list_create (&f_imap->flist); |
1401 | mu_list_set_destroy_item (f_imap->flist, mu_list_response_free); | 1420 | mu_list_set_destroy_item (f_imap->flist, mu_list_response_free); |
1402 | } | 1421 | } |
1403 | mu_list_append (f_imap->flist, lr); | ||
1404 | 1422 | ||
1405 | /* Glob untag. */ | 1423 | /* Glob untag. */ |
1406 | tok = strtok_r (buffer, " ", &sp); | 1424 | tok = strtok_r (buffer, " ", &sp); |
... | @@ -1475,6 +1493,12 @@ imap_list (f_imap_t f_imap) | ... | @@ -1475,6 +1493,12 @@ imap_list (f_imap_t f_imap) |
1475 | } | 1493 | } |
1476 | mu_argcv_free (argc, argv); | 1494 | mu_argcv_free (argc, argv); |
1477 | free (buffer); | 1495 | free (buffer); |
1496 | |||
1497 | if (f_imap->enum_fun) | ||
1498 | f_imap->enum_stop = f_imap->enum_fun (f_imap->folder, lr, | ||
1499 | f_imap->enum_data); | ||
1500 | mu_list_append (f_imap->flist, lr); | ||
1501 | |||
1478 | return status; | 1502 | return status; |
1479 | } | 1503 | } |
1480 | 1504 | ... | ... |
... | @@ -33,6 +33,9 @@ | ... | @@ -33,6 +33,9 @@ |
33 | extern "C" { | 33 | extern "C" { |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | #define MU_FOLDER_LIST 0 | ||
37 | #define MU_FOLDER_ENUM 1 | ||
38 | |||
36 | struct _mu_folder | 39 | struct _mu_folder |
37 | { | 40 | { |
38 | /* Data */ | 41 | /* Data */ |
... | @@ -55,11 +58,11 @@ struct _mu_folder | ... | @@ -55,11 +58,11 @@ struct _mu_folder |
55 | 58 | ||
56 | int (*_open) (mu_folder_t, int flag); | 59 | int (*_open) (mu_folder_t, int flag); |
57 | int (*_close) (mu_folder_t); | 60 | int (*_close) (mu_folder_t); |
58 | int (*_list) (mu_folder_t, const char *, const char *, | 61 | int (*_list) (mu_folder_t, const char *, void *, int, size_t, |
59 | size_t, | 62 | mu_list_t, mu_folder_enumerate_fp, void *); |
60 | mu_list_t); | ||
61 | int (*_lsub) (mu_folder_t, const char *, const char *, | 63 | int (*_lsub) (mu_folder_t, const char *, const char *, |
62 | mu_list_t); | 64 | mu_list_t); |
65 | mu_folder_match_fp _match; | ||
63 | int (*_delete) (mu_folder_t, const char *); | 66 | int (*_delete) (mu_folder_t, const char *); |
64 | int (*_rename) (mu_folder_t, const char *, const char *); | 67 | int (*_rename) (mu_folder_t, const char *, const char *); |
65 | int (*_subscribe) (mu_folder_t, const char *); | 68 | int (*_subscribe) (mu_folder_t, const char *); | ... | ... |
... | @@ -161,6 +161,9 @@ struct _f_imap | ... | @@ -161,6 +161,9 @@ struct _f_imap |
161 | 161 | ||
162 | /* Use for LIST and LSUB. */ | 162 | /* Use for LIST and LSUB. */ |
163 | mu_list_t flist; | 163 | mu_list_t flist; |
164 | mu_folder_enumerate_fp enum_fun; | ||
165 | void *enum_data; | ||
166 | int enum_stop; | ||
164 | 167 | ||
165 | int isopen; | 168 | int isopen; |
166 | 169 | ||
... | @@ -170,8 +173,8 @@ struct _f_imap | ... | @@ -170,8 +173,8 @@ struct _f_imap |
170 | char *ptr; | 173 | char *ptr; |
171 | char *nl; | 174 | char *nl; |
172 | mu_off_t offset; /* Dummy, this is used because of the stream buffering. | 175 | mu_off_t offset; /* Dummy, this is used because of the stream buffering. |
173 | The mu_stream_t maintains and offset and the offset we use must | 176 | The mu_stream_t maintains and offset and the offset we |
174 | be in sync. */ | 177 | use must be in sync. */ |
175 | 178 | ||
176 | /* Login */ | 179 | /* Login */ |
177 | char *user; | 180 | char *user; | ... | ... |
... | @@ -41,6 +41,7 @@ | ... | @@ -41,6 +41,7 @@ |
41 | #include <mailutils/stream.h> | 41 | #include <mailutils/stream.h> |
42 | #include <mailutils/mutil.h> | 42 | #include <mailutils/mutil.h> |
43 | #include <mailutils/errno.h> | 43 | #include <mailutils/errno.h> |
44 | #include <mailutils/debug.h> | ||
44 | 45 | ||
45 | /* We export url parsing and the initialisation of | 46 | /* We export url parsing and the initialisation of |
46 | the mailbox, via the register entry/record. */ | 47 | the mailbox, via the register entry/record. */ |
... | @@ -77,11 +78,32 @@ _path_is_scheme (mu_record_t record, const char *url, int flags) | ... | @@ -77,11 +78,32 @@ _path_is_scheme (mu_record_t record, const char *url, int flags) |
77 | struct stat st; | 78 | struct stat st; |
78 | 79 | ||
79 | if (stat (path, &st) < 0) | 80 | if (stat (path, &st) < 0) |
80 | return MU_FOLDER_ATTRIBUTE_ALL; /* mu_mailbox_open will complain */ | 81 | { |
82 | if (errno == ENOENT) | ||
83 | rc |= MU_FOLDER_ATTRIBUTE_FILE; | ||
84 | return rc; | ||
85 | } | ||
81 | 86 | ||
82 | if ((flags & MU_FOLDER_ATTRIBUTE_FILE) | 87 | if (S_ISREG (st.st_mode) || S_ISCHR (st.st_mode)) |
83 | && (S_ISREG (st.st_mode) || S_ISCHR (st.st_mode))) | 88 | { |
89 | if (st.st_size == 0) | ||
90 | { | ||
91 | rc |= MU_FOLDER_ATTRIBUTE_FILE; | ||
92 | } | ||
93 | else if (flags & MU_FOLDER_ATTRIBUTE_FILE) | ||
94 | { | ||
95 | int fd = open (path, O_RDONLY); | ||
96 | if (fd != -1) | ||
97 | { | ||
98 | char buf[5]; | ||
99 | if (read (fd, buf, 5) == 5) | ||
100 | if (memcmp (buf, "From ", 5) == 0) | ||
84 | rc |= MU_FOLDER_ATTRIBUTE_FILE; | 101 | rc |= MU_FOLDER_ATTRIBUTE_FILE; |
102 | close (fd); | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | |||
85 | if ((flags & MU_FOLDER_ATTRIBUTE_DIRECTORY) | 107 | if ((flags & MU_FOLDER_ATTRIBUTE_DIRECTORY) |
86 | && S_ISDIR (st.st_mode)) | 108 | && S_ISDIR (st.st_mode)) |
87 | rc |= MU_FOLDER_ATTRIBUTE_DIRECTORY; | 109 | rc |= MU_FOLDER_ATTRIBUTE_DIRECTORY; |
... | @@ -113,8 +135,9 @@ static int folder_mbox_open (mu_folder_t, int); | ... | @@ -113,8 +135,9 @@ static int folder_mbox_open (mu_folder_t, int); |
113 | static int folder_mbox_close (mu_folder_t); | 135 | static int folder_mbox_close (mu_folder_t); |
114 | static int folder_mbox_delete (mu_folder_t, const char *); | 136 | static int folder_mbox_delete (mu_folder_t, const char *); |
115 | static int folder_mbox_rename (mu_folder_t , const char *, const char *); | 137 | static int folder_mbox_rename (mu_folder_t , const char *, const char *); |
116 | static int folder_mbox_list (mu_folder_t, const char *, const char *, | 138 | static int folder_mbox_list (mu_folder_t, const char *, void *, int, |
117 | size_t, mu_list_t); | 139 | size_t, mu_list_t, mu_folder_enumerate_fp, |
140 | void *); | ||
118 | static int folder_mbox_subscribe (mu_folder_t, const char *); | 141 | static int folder_mbox_subscribe (mu_folder_t, const char *); |
119 | static int folder_mbox_unsubscribe (mu_folder_t, const char *); | 142 | static int folder_mbox_unsubscribe (mu_folder_t, const char *); |
120 | static int folder_mbox_lsub (mu_folder_t, const char *, const char *, | 143 | static int folder_mbox_lsub (mu_folder_t, const char *, const char *, |
... | @@ -228,7 +251,8 @@ folder_mbox_delete (mu_folder_t folder, const char *filename) | ... | @@ -228,7 +251,8 @@ folder_mbox_delete (mu_folder_t folder, const char *filename) |
228 | } | 251 | } |
229 | 252 | ||
230 | static int | 253 | static int |
231 | folder_mbox_rename (mu_folder_t folder, const char *oldpath, const char *newpath) | 254 | folder_mbox_rename (mu_folder_t folder, const char *oldpath, |
255 | const char *newpath) | ||
232 | { | 256 | { |
233 | fmbox_t fmbox = folder->data; | 257 | fmbox_t fmbox = folder->data; |
234 | if (oldpath && newpath) | 258 | if (oldpath && newpath) |
... | @@ -266,8 +290,15 @@ struct inode_list /* Inode/dev number list used to cut off | ... | @@ -266,8 +290,15 @@ struct inode_list /* Inode/dev number list used to cut off |
266 | struct search_data | 290 | struct search_data |
267 | { | 291 | { |
268 | mu_list_t result; | 292 | mu_list_t result; |
269 | const char *pattern; | 293 | mu_folder_enumerate_fp enumfun; |
294 | void *enumdata; | ||
295 | char *dirname; | ||
296 | size_t dirlen; | ||
297 | void *pattern; | ||
298 | int flags; | ||
270 | size_t max_level; | 299 | size_t max_level; |
300 | size_t errcnt; | ||
301 | mu_folder_t folder; | ||
271 | }; | 302 | }; |
272 | 303 | ||
273 | static int | 304 | static int |
... | @@ -279,126 +310,146 @@ inode_list_lookup (struct inode_list *list, struct stat *st) | ... | @@ -279,126 +310,146 @@ inode_list_lookup (struct inode_list *list, struct stat *st) |
279 | return 0; | 310 | return 0; |
280 | } | 311 | } |
281 | 312 | ||
282 | |||
283 | static int | 313 | static int |
284 | list_helper (struct search_data *data, | 314 | list_helper (struct search_data *data, const char *dirname, size_t level, |
285 | const char *dirname, size_t level, struct inode_list *ilist) | 315 | struct inode_list *ilist) |
286 | { | 316 | { |
287 | int status; | 317 | DIR *dirp; |
288 | glob_t gl; | 318 | struct dirent *dp; |
289 | char *pathname; | 319 | int stop = 0; |
290 | 320 | ||
291 | ++level; | ||
292 | if (data->max_level && level > data->max_level) | 321 | if (data->max_level && level > data->max_level) |
293 | return 0; | 322 | return 0; |
294 | 323 | ||
295 | pathname = get_pathname (dirname, data->pattern); | 324 | dirp = opendir (dirname); |
296 | if (!pathname) | 325 | if (dirp == NULL) |
297 | return ENOMEM; | ||
298 | |||
299 | memset(&gl, 0, sizeof(gl)); | ||
300 | status = glob (pathname, 0, NULL, &gl); | ||
301 | free (pathname); | ||
302 | |||
303 | if (status == 0) | ||
304 | { | 326 | { |
305 | size_t i; | 327 | MU_DEBUG2 (data->folder->debug, MU_DEBUG_ERROR, |
306 | struct mu_list_response *resp; | 328 | "list_helper cannot open directory %s: %s", |
329 | dirname, mu_strerror (errno)); | ||
330 | data->errcnt++; | ||
331 | return 1; | ||
332 | } | ||
307 | 333 | ||
308 | for (i = 0; i < gl.gl_pathc; i++) | 334 | while ((dp = readdir (dirp))) |
335 | { | ||
336 | char const *ename = dp->d_name; | ||
337 | char *fname; | ||
338 | |||
339 | if (ename[ename[0] != '.' ? 0 : ename[1] != '.' ? 1 : 2] == 0) | ||
340 | continue; | ||
341 | fname = get_pathname (dirname, ename); | ||
342 | if (data->folder->_match == NULL | ||
343 | || data->folder->_match (fname + data->dirlen + | ||
344 | ((data->dirlen > 1 | ||
345 | && data->dirname[data->dirlen-1] != '/') ? | ||
346 | 1 : 0), | ||
347 | data->pattern, | ||
348 | data->flags) == 0) | ||
309 | { | 349 | { |
310 | struct stat st; | 350 | struct stat st; |
311 | 351 | ||
352 | if (stat (fname, &st) == 0) | ||
353 | { | ||
354 | char *refname = fname; | ||
355 | int type = 0; | ||
356 | struct mu_list_response *resp; | ||
357 | |||
312 | resp = malloc (sizeof (*resp)); | 358 | resp = malloc (sizeof (*resp)); |
313 | if (resp == NULL) | 359 | if (resp == NULL) |
314 | { | 360 | { |
315 | status = ENOMEM; | 361 | MU_DEBUG1 (data->folder->debug, MU_DEBUG_ERROR, |
316 | break; | 362 | "list_helper: %s", mu_strerror (ENOMEM)); |
363 | data->errcnt++; | ||
364 | free (fname); | ||
365 | continue; | ||
317 | } | 366 | } |
318 | else if ((resp->name = strdup (gl.gl_pathv[i])) == NULL) | 367 | |
368 | mu_registrar_lookup (refname, MU_FOLDER_ATTRIBUTE_ALL, NULL, | ||
369 | &type); | ||
370 | |||
371 | resp->name = fname; | ||
372 | resp->level = level; | ||
373 | resp->separator = '/'; | ||
374 | resp->type = type; | ||
375 | |||
376 | if (resp->type == 0) | ||
319 | { | 377 | { |
378 | free (resp->name); | ||
320 | free (resp); | 379 | free (resp); |
321 | status = ENOMEM; | 380 | continue; |
322 | break; | ||
323 | } | 381 | } |
324 | 382 | ||
325 | resp->level = level; | 383 | if (data->enumfun) |
326 | resp->separator = '/'; | 384 | { |
327 | resp->type = 0; | 385 | if (data->enumfun (data->folder, resp, data->enumdata)) |
386 | { | ||
387 | free (resp->name); | ||
388 | free (resp); | ||
389 | stop = 1; | ||
390 | break; | ||
391 | } | ||
392 | } | ||
328 | 393 | ||
394 | if (data->result) | ||
395 | { | ||
396 | fname = NULL; | ||
329 | mu_list_append (data->result, resp); | 397 | mu_list_append (data->result, resp); |
398 | } | ||
399 | else | ||
400 | free (resp); | ||
330 | 401 | ||
331 | if (stat (gl.gl_pathv[i], &st) == 0) | 402 | if ((type & MU_FOLDER_ATTRIBUTE_DIRECTORY) |
332 | { | ||
333 | resp->type = 0; | ||
334 | mu_registrar_lookup (gl.gl_pathv[i], MU_FOLDER_ATTRIBUTE_ALL, | ||
335 | NULL, &resp->type); | ||
336 | if ((resp->type & MU_FOLDER_ATTRIBUTE_DIRECTORY) | ||
337 | && !inode_list_lookup (ilist, &st)) | 403 | && !inode_list_lookup (ilist, &st)) |
338 | { | 404 | { |
339 | struct inode_list idata; | 405 | struct inode_list idata; |
406 | |||
340 | idata.inode = st.st_ino; | 407 | idata.inode = st.st_ino; |
341 | idata.dev = st.st_dev; | 408 | idata.dev = st.st_dev; |
342 | idata.next = ilist; | 409 | idata.next = ilist; |
343 | status = list_helper (data, gl.gl_pathv[i], level, &idata); | 410 | stop = list_helper (data, refname, level + 1, &idata); |
344 | if (status) | ||
345 | break; | ||
346 | } | ||
347 | } | 411 | } |
348 | } | 412 | } |
349 | globfree (&gl); | ||
350 | } | ||
351 | else | 413 | else |
352 | { | 414 | { |
353 | switch (status) | 415 | MU_DEBUG2 (data->folder->debug, MU_DEBUG_ERROR, |
354 | { | 416 | "list_helper cannot stat %s: %s", |
355 | case GLOB_NOSPACE: | 417 | fname, mu_strerror (errno)); |
356 | status = ENOMEM; | ||
357 | break; | ||
358 | |||
359 | case GLOB_ABORTED: | ||
360 | status = MU_ERR_READ; | ||
361 | break; | ||
362 | |||
363 | case GLOB_NOMATCH: | ||
364 | if (mu_list_is_empty (data->result)) | ||
365 | status = MU_ERR_NOENT; | ||
366 | else | ||
367 | status = 0; | ||
368 | break; | ||
369 | |||
370 | case GLOB_NOSYS: | ||
371 | status = ENOSYS; | ||
372 | break; | ||
373 | |||
374 | default: | ||
375 | status = MU_ERR_FAILURE; | ||
376 | break; | ||
377 | } | 418 | } |
378 | } | 419 | } |
379 | return status; | 420 | free (fname); |
421 | } | ||
422 | closedir (dirp); | ||
423 | return stop; | ||
380 | } | 424 | } |
381 | 425 | ||
382 | /* The listing is not recursive and we use glob() some expansion for us. | ||
383 | Unfortunately glob() does not expand the '~'. We also return | ||
384 | the full pathname so it can be use to create other folders. */ | ||
385 | static int | 426 | static int |
386 | folder_mbox_list (mu_folder_t folder, const char *dirname, const char *pattern, | 427 | folder_mbox_list (mu_folder_t folder, const char *ref, |
428 | void *pattern, | ||
429 | int flags, | ||
387 | size_t max_level, | 430 | size_t max_level, |
388 | mu_list_t flist) | 431 | mu_list_t flist, |
432 | mu_folder_enumerate_fp enumfun, void *enumdata) | ||
389 | { | 433 | { |
390 | fmbox_t fmbox = folder->data; | 434 | fmbox_t fmbox = folder->data; |
391 | struct inode_list iroot; | 435 | struct inode_list iroot; |
392 | struct search_data sdata; | 436 | struct search_data sdata; |
393 | 437 | ||
394 | memset (&iroot, 0, sizeof iroot); | 438 | memset (&iroot, 0, sizeof iroot); |
395 | if (dirname == NULL || dirname[0] == '\0') | 439 | sdata.dirname = get_pathname (fmbox->dirname, ref); |
396 | dirname = (const char *)fmbox->dirname; | 440 | sdata.dirlen = strlen (sdata.dirname); |
397 | |||
398 | sdata.result = flist; | 441 | sdata.result = flist; |
442 | sdata.enumfun = enumfun; | ||
443 | sdata.enumdata = enumdata; | ||
399 | sdata.pattern = pattern; | 444 | sdata.pattern = pattern; |
445 | sdata.flags = flags; | ||
400 | sdata.max_level = max_level; | 446 | sdata.max_level = max_level; |
401 | return list_helper (&sdata, dirname, 0, &iroot); | 447 | sdata.folder = folder; |
448 | sdata.errcnt = 0; | ||
449 | list_helper (&sdata, sdata.dirname, 0, &iroot); | ||
450 | free (sdata.dirname); | ||
451 | /* FIXME: error code */ | ||
452 | return 0; | ||
402 | } | 453 | } |
403 | 454 | ||
404 | static int | 455 | static int | ... | ... |
... | @@ -63,9 +63,10 @@ static int nntp_folder_open (mu_folder_t, int); | ... | @@ -63,9 +63,10 @@ static int nntp_folder_open (mu_folder_t, int); |
63 | static int nntp_folder_close (mu_folder_t); | 63 | static int nntp_folder_close (mu_folder_t); |
64 | static void nntp_folder_destroy (mu_folder_t folder); | 64 | static void nntp_folder_destroy (mu_folder_t folder); |
65 | static int nntp_folder_list (mu_folder_t folder, const char *ref, | 65 | static int nntp_folder_list (mu_folder_t folder, const char *ref, |
66 | const char *name, | 66 | void *name, |
67 | size_t max, | 67 | size_t max, |
68 | mu_list_t flist); | 68 | mu_list_t flist, |
69 | mu_folder_enumerate_fp efp, void *edp); | ||
69 | 70 | ||
70 | int | 71 | int |
71 | _nntp_folder_init (mu_folder_t folder) | 72 | _nntp_folder_init (mu_folder_t folder) |
... | @@ -185,8 +186,9 @@ nntp_folder_destroy (mu_folder_t folder) | ... | @@ -185,8 +186,9 @@ nntp_folder_destroy (mu_folder_t folder) |
185 | 186 | ||
186 | 187 | ||
187 | static int | 188 | static int |
188 | nntp_folder_list (mu_folder_t folder, const char *ref, const char *name, | 189 | nntp_folder_list (mu_folder_t folder, const char *ref, void *pat, |
189 | size_t max_level, mu_list_t flist) | 190 | size_t max_level, mu_list_t flist, |
191 | mu_folder_enumerate_fp efp, void *edp) | ||
190 | { | 192 | { |
191 | return ENOTSUP; | 193 | return ENOTSUP; |
192 | } | 194 | } | ... | ... |
... | @@ -24,6 +24,7 @@ | ... | @@ -24,6 +24,7 @@ |
24 | #include <errno.h> | 24 | #include <errno.h> |
25 | #include <stdlib.h> | 25 | #include <stdlib.h> |
26 | #include <string.h> | 26 | #include <string.h> |
27 | #include <fnmatch.h> | ||
27 | 28 | ||
28 | #include <mailutils/auth.h> | 29 | #include <mailutils/auth.h> |
29 | #include <mailutils/debug.h> | 30 | #include <mailutils/debug.h> |
... | @@ -45,13 +46,19 @@ static int is_known_folder (mu_url_t, mu_folder_t *); | ... | @@ -45,13 +46,19 @@ static int is_known_folder (mu_url_t, mu_folder_t *); |
45 | /* Static folder lock. */ | 46 | /* Static folder lock. */ |
46 | static struct mu_monitor folder_lock = MU_MONITOR_INITIALIZER; | 47 | static struct mu_monitor folder_lock = MU_MONITOR_INITIALIZER; |
47 | 48 | ||
49 | int | ||
50 | mu_folder_match (const char *name, void *pattern, int flags) | ||
51 | { | ||
52 | return fnmatch (pattern, name[0] == '/' ? name + 1 : name, flags); | ||
53 | } | ||
54 | |||
48 | /* A folder could be remote (IMAP), or local(a spool directory) like $HOME/Mail | 55 | /* A folder could be remote (IMAP), or local(a spool directory) like $HOME/Mail |
49 | etc .. We maintain a known list of folder to not generate multiple folder | 56 | etc .. We maintain a list of known folders to avoid creating multiple |
50 | of the same URL. Meaning when mu_folder_create () is call we'll check if we | 57 | folders for the same URL. So, when mu_folder_create is called we check if |
51 | already have a folder for that URL and return the same, if not we create a | 58 | we already have a folder for that URL and return it, otherwise we create a |
52 | new one. The downside, the scheme to detect the same URL is very weak, and | 59 | new one. Downsides: the scheme to detect the same URL is very weak, and |
53 | they maybe cases where you want a different folder for the same URL, there | 60 | there could be cases where you'll want a different folder for the same URL, |
54 | is not easy way to do this. */ | 61 | there is not easy way to do this. */ |
55 | int | 62 | int |
56 | mu_folder_create_from_record (mu_folder_t *pfolder, const char *name, | 63 | mu_folder_create_from_record (mu_folder_t *pfolder, const char *name, |
57 | mu_record_t record) | 64 | mu_record_t record) |
... | @@ -112,6 +119,8 @@ mu_folder_create_from_record (mu_folder_t *pfolder, const char *name, | ... | @@ -112,6 +119,8 @@ mu_folder_create_from_record (mu_folder_t *pfolder, const char *name, |
112 | status = f_init (folder); | 119 | status = f_init (folder); |
113 | if (status == 0) | 120 | if (status == 0) |
114 | { | 121 | { |
122 | if (!folder->_match) | ||
123 | folder->_match = mu_folder_match; | ||
115 | *pfolder = folder; | 124 | *pfolder = folder; |
116 | folder->ref++; | 125 | folder->ref++; |
117 | /* Put on the internal list of known folders. */ | 126 | /* Put on the internal list of known folders. */ |
... | @@ -280,6 +289,26 @@ mu_folder_get_observable (mu_folder_t folder, mu_observable_t *pobservable) | ... | @@ -280,6 +289,26 @@ mu_folder_get_observable (mu_folder_t folder, mu_observable_t *pobservable) |
280 | } | 289 | } |
281 | 290 | ||
282 | int | 291 | int |
292 | mu_folder_set_match (mu_folder_t folder, mu_folder_match_fp pmatch) | ||
293 | { | ||
294 | if (folder == NULL) | ||
295 | return EINVAL; | ||
296 | folder->_match = pmatch; | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | int | ||
301 | mu_folder_get_match (mu_folder_t folder, mu_folder_match_fp *pmatch) | ||
302 | { | ||
303 | if (folder == NULL) | ||
304 | return EINVAL; | ||
305 | if (pmatch == NULL) | ||
306 | return MU_ERR_OUT_PTR_NULL; | ||
307 | *pmatch = folder->_match; | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | int | ||
283 | mu_folder_has_debug (mu_folder_t folder) | 312 | mu_folder_has_debug (mu_folder_t folder) |
284 | { | 313 | { |
285 | if (folder == NULL) | 314 | if (folder == NULL) |
... | @@ -325,20 +354,41 @@ mu_list_response_free (void *data) | ... | @@ -325,20 +354,41 @@ mu_list_response_free (void *data) |
325 | } | 354 | } |
326 | 355 | ||
327 | int | 356 | int |
328 | mu_folder_list (mu_folder_t folder, const char *dirname, const char *basename, | 357 | mu_folder_list (mu_folder_t folder, const char *dirname, void *pattern, |
329 | size_t max_level, | 358 | size_t max_level, |
330 | mu_list_t *pflist) | 359 | mu_list_t *pflist) |
331 | { | 360 | { |
361 | return mu_folder_enumerate (folder, dirname, pattern, 0, max_level, | ||
362 | pflist, NULL, NULL); | ||
363 | } | ||
364 | |||
365 | int | ||
366 | mu_folder_enumerate (mu_folder_t folder, const char *name, | ||
367 | void *pattern, int flags, | ||
368 | size_t max_level, | ||
369 | mu_list_t *pflist, | ||
370 | mu_folder_enumerate_fp enumfun, void *enumdata) | ||
371 | { | ||
332 | int status; | 372 | int status; |
333 | if (folder == NULL || folder->_list == NULL) | 373 | if (folder == NULL || folder->_list == NULL) |
334 | return EINVAL; | 374 | return EINVAL; |
335 | else | 375 | else |
336 | { | 376 | { |
337 | status = mu_list_create (pflist); | 377 | mu_list_t list = NULL; |
378 | |||
379 | if (pflist) | ||
380 | { | ||
381 | status = mu_list_create (&list); | ||
338 | if (status) | 382 | if (status) |
339 | return status; | 383 | return status; |
340 | mu_list_set_destroy_item (*pflist, mu_list_response_free); | 384 | *pflist = list; |
341 | status = folder->_list (folder, dirname, basename, max_level, *pflist); | 385 | mu_list_set_destroy_item (list, mu_list_response_free); |
386 | } | ||
387 | else if (!enumfun) | ||
388 | return EINVAL; | ||
389 | |||
390 | status = folder->_list (folder, name, pattern, flags, max_level, | ||
391 | list, enumfun, enumdata); | ||
342 | if (status) | 392 | if (status) |
343 | mu_list_destroy (pflist); | 393 | mu_list_destroy (pflist); |
344 | } | 394 | } | ... | ... |
-
Please register or sign in to post a comment