Additional mailbox URL parameters `type', `user' and `param' can
appear in any local URLs. * TODO, NEWS: Update. * examples/url-parse.c: Print field/value pairs. * include/mailutils/argcv.h (MU_ARGCV_RETURN_DELIMS): New macro. (mu_argcv_get_np): New function. (mu_argcv_remove): New function. * include/mailutils/mutil.h (mu_scheme_autodetect_p): Change prototype. * include/mailutils/registrar.h (mu_registrar_lookup_url): New function. (struct _mu_record._is_scheme): Change signature. * include/mailutils/url.h (mu_url_sget_fvpairs) (mu_url_aget_fvpairs): New functions. (mu_url_expand_path): New function. * libproto/imap/folder.c (folder_imap_list): Fix signature. * libproto/nntp/folder.c (nntp_folder_list): Fix signature. * libproto/include/amd.h (amd_url_init): Remove. * libproto/include/registrar0.h: Fix scheme defines. * libproto/include/url0.h (struct _mu_url.fvpairs,fvcount): New members. * libproto/maildir/folder.c (_maildir_is_scheme): Change signature. (_maildir_url_init): Remove (_maildir_record): Remove url_init. * libproto/mbox/folder.c (_path_record): Remove url_init. (_mbox_record): Use mu_url_expand_path as url_init. (_path_is_scheme): Change signature. * libproto/mh/folder.c (_mh_is_scheme): Change signature. (_mh_url_init): Remove. (_mh_record): Use mu_url_expand_path as url_init. * libproto/mbox/Makefile.am (libmu_mbox_la_SOURCES): Remove url.c * libproto/mbox/url.c: Remove. * mail/mail.h, mail/util.c (util_url_to_string): New function. * mail/quit.c, mail/summary.c: Use util_url_to_string where appropriate. * mailbox/amd.c (amd_url_destroy, amd_url_init): Remove. * mailbox/argcv.c (mu_argcv_get_np): New function. (argcv_scan): Change signature. All callers updated. (argcv_get_n): Rewrite using argcv_get_np. (mu_argcv_remove): New function. * mailbox/file_stream.c (struct _prog_stream.argc): Fix data type. * mailbox/folder.c (mu_folder_create_from_record): URL initializer is optional. * mailbox/gdebug.c (mu_global_debug_from_string): Fix datatype of argc. * mailbox/mailbox.c (mailbox_folder_create): Rewrite. (_create_mailbox): Split off _create_mailbox0 function. Make URL initializer optional. * mailbox/mutil.c (mu_scheme_autodetect_p): Rewrite. * mailbox/registrar.c (mu_registrar_lookup_url): New function. (mu_registrar_lookup): Rewrite using mu_registrar_lookup_url. (mu_record_is_scheme,mu_record_set_is_scheme): Change signature. * mailbox/url.c (mu_url_destroy): Destroy fvpairs. (url_parse0): Use scheme "file" for URLs beginning with a /. Parse parameters. (mu_url_sget_fvpairs, mu_url_aget_fvpairs): New functions. (mu_url_expand_path): New function. * mailbox/testsuite/Urls: Update. * pop3d/bulletin.c (set_bulletin_db,set_bulletin_source): Allocate string storage. (read_bulletin_db): Return 0 if no record was found. (get_last_delivered_num): Return error code. (deliver_pending_bulletins): Rewrite. * pop3d/capa.c (pop3d_capa): Bugfix.
Showing
36 changed files
with
850 additions
and
616 deletions
1 | 2007-12-28 Sergey Poznyakoff <gray@gnu.org.ua> | ||
2 | |||
3 | Additional mailbox URL parameters `type', `user' and `param' can | ||
4 | appear in any local URLs. | ||
5 | |||
6 | * TODO, NEWS: Update. | ||
7 | |||
8 | * examples/url-parse.c: Print field/value pairs. | ||
9 | * include/mailutils/argcv.h (MU_ARGCV_RETURN_DELIMS): New macro. | ||
10 | (mu_argcv_get_np): New function. | ||
11 | (mu_argcv_remove): New function. | ||
12 | * include/mailutils/mutil.h (mu_scheme_autodetect_p): Change | ||
13 | prototype. | ||
14 | * include/mailutils/registrar.h (mu_registrar_lookup_url): New | ||
15 | function. | ||
16 | (struct _mu_record._is_scheme): Change signature. | ||
17 | * include/mailutils/url.h (mu_url_sget_fvpairs) | ||
18 | (mu_url_aget_fvpairs): New functions. | ||
19 | (mu_url_expand_path): New function. | ||
20 | |||
21 | * libproto/imap/folder.c (folder_imap_list): Fix signature. | ||
22 | * libproto/nntp/folder.c (nntp_folder_list): Fix signature. | ||
23 | * libproto/include/amd.h (amd_url_init): Remove. | ||
24 | * libproto/include/registrar0.h: Fix scheme defines. | ||
25 | * libproto/include/url0.h (struct _mu_url.fvpairs,fvcount): New | ||
26 | members. | ||
27 | * libproto/maildir/folder.c (_maildir_is_scheme): Change | ||
28 | signature. | ||
29 | (_maildir_url_init): Remove | ||
30 | (_maildir_record): Remove url_init. | ||
31 | * libproto/mbox/folder.c (_path_record): Remove url_init. | ||
32 | (_mbox_record): Use mu_url_expand_path as url_init. | ||
33 | (_path_is_scheme): Change signature. | ||
34 | * libproto/mh/folder.c (_mh_is_scheme): Change signature. | ||
35 | (_mh_url_init): Remove. | ||
36 | (_mh_record): Use mu_url_expand_path as url_init. | ||
37 | * libproto/mbox/Makefile.am (libmu_mbox_la_SOURCES): Remove url.c | ||
38 | * libproto/mbox/url.c: Remove. | ||
39 | |||
40 | * mail/mail.h, mail/util.c (util_url_to_string): New function. | ||
41 | * mail/quit.c, mail/summary.c: Use util_url_to_string where | ||
42 | appropriate. | ||
43 | * mailbox/amd.c (amd_url_destroy, amd_url_init): Remove. | ||
44 | * mailbox/argcv.c (mu_argcv_get_np): New function. | ||
45 | (argcv_scan): Change signature. All callers updated. | ||
46 | (argcv_get_n): Rewrite using argcv_get_np. | ||
47 | (mu_argcv_remove): New function. | ||
48 | |||
49 | * mailbox/file_stream.c (struct _prog_stream.argc): Fix data type. | ||
50 | * mailbox/folder.c (mu_folder_create_from_record): URL initializer | ||
51 | is optional. | ||
52 | * mailbox/gdebug.c (mu_global_debug_from_string): Fix datatype of | ||
53 | argc. | ||
54 | * mailbox/mailbox.c (mailbox_folder_create): Rewrite. | ||
55 | (_create_mailbox): Split off _create_mailbox0 function. | ||
56 | Make URL initializer optional. | ||
57 | * mailbox/mutil.c (mu_scheme_autodetect_p): Rewrite. | ||
58 | * mailbox/registrar.c (mu_registrar_lookup_url): New function. | ||
59 | (mu_registrar_lookup): Rewrite using mu_registrar_lookup_url. | ||
60 | (mu_record_is_scheme,mu_record_set_is_scheme): Change signature. | ||
61 | * mailbox/url.c (mu_url_destroy): Destroy fvpairs. | ||
62 | (url_parse0): Use scheme "file" for URLs beginning with a /. | ||
63 | Parse parameters. | ||
64 | (mu_url_sget_fvpairs, mu_url_aget_fvpairs): New functions. | ||
65 | (mu_url_expand_path): New function. | ||
66 | * mailbox/testsuite/Urls: Update. | ||
67 | |||
68 | * pop3d/bulletin.c (set_bulletin_db,set_bulletin_source): Allocate | ||
69 | string storage. | ||
70 | (read_bulletin_db): Return 0 if no record was found. | ||
71 | (get_last_delivered_num): Return error code. | ||
72 | (deliver_pending_bulletins): Rewrite. | ||
73 | * pop3d/capa.c (pop3d_capa): Bugfix. | ||
74 | |||
1 | 2007-12-21 Sergey Poznyakoff <gray@gnu.org.ua> | 75 | 2007-12-21 Sergey Poznyakoff <gray@gnu.org.ua> |
2 | 76 | ||
3 | * examples/lsf.c: Use mu_folder_enumerate + callback function, for | 77 | * examples/lsf.c: Use mu_folder_enumerate + callback function, for | ... | ... |
1 | GNU mailutils NEWS -- history of user-visible changes. 2007-12-19 | 1 | GNU mailutils NEWS -- history of user-visible changes. 2007-12-28 |
2 | Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. |
3 | See the end of file for copying conditions. | 3 | See the end of file for copying conditions. |
4 | 4 | ||
... | @@ -26,6 +26,11 @@ The programs using configuration file facility also understand the | ... | @@ -26,6 +26,11 @@ The programs using configuration file facility also understand the |
26 | output the detailed description of configuration file statements that | 26 | output the detailed description of configuration file statements that |
27 | affect the given program. | 27 | affect the given program. |
28 | 28 | ||
29 | ** URL parameters. | ||
30 | |||
31 | Additional mailbox URL parameters `type', `user' and `param' can | ||
32 | appear in any local URLs. | ||
33 | |||
29 | ** New utility `maidag' | 34 | ** New utility `maidag' |
30 | 35 | ||
31 | Maidag is a MAIl Delivery AGent. It is a general-purpose MDA able to | 36 | Maidag is a MAIl Delivery AGent. It is a general-purpose MDA able to |
... | @@ -185,6 +190,9 @@ extern int mu_url_aget_path (const mu_url_t, char **); | ... | @@ -185,6 +190,9 @@ extern int mu_url_aget_path (const mu_url_t, char **); |
185 | extern int mu_url_sget_query (const mu_url_t, const char **); | 190 | extern int mu_url_sget_query (const mu_url_t, const char **); |
186 | extern int mu_url_aget_query (const mu_url_t, char **); | 191 | extern int mu_url_aget_query (const mu_url_t, char **); |
187 | 192 | ||
193 | int mu_url_sget_fvpairs (const mu_url_t, size_t *, char ***); | ||
194 | int mu_url_aget_fvpairs (const mu_url_t, size_t *, char ***); | ||
195 | |||
188 | ** ACL | 196 | ** ACL |
189 | 197 | ||
190 | A set of functions implements general-purpose access control lists. | 198 | A set of functions implements general-purpose access control lists. |
... | @@ -227,6 +235,29 @@ that can be done over them is mu_mailbox_append_message. E.g., | ... | @@ -227,6 +235,29 @@ that can be done over them is mu_mailbox_append_message. E.g., |
227 | appending to the URL `remote+smtp://127.0.0.1:24' is equivalent to | 235 | appending to the URL `remote+smtp://127.0.0.1:24' is equivalent to |
228 | sending a message using mailer `smtp://127.0.0.1:24'. | 236 | sending a message using mailer `smtp://127.0.0.1:24'. |
229 | 237 | ||
238 | ** New argcv functions. | ||
239 | |||
240 | - int mu_argcv_get_np (const char *command, int len, | ||
241 | const char *delim, const char *cmnt, | ||
242 | int flags, | ||
243 | int *pargc, char ***pargv, char **endp); | ||
244 | |||
245 | This function is an alternative entry point to | ||
246 | mu_argcv_get/mu_argcv_get_n functions. The resulting argv will contain | ||
247 | non-whitespace delimiters only if flags contains the bit | ||
248 | MU_ARGCV_RETURN_DELIMS. | ||
249 | |||
250 | - void mu_argcv_remove (int *pargc, char ***pargv, | ||
251 | int (*sel) (const char *, void *), void *); | ||
252 | |||
253 | Removes from pargc/pargv all elements for which the sel function | ||
254 | returns true. | ||
255 | |||
256 | ** New registry functions. | ||
257 | |||
258 | - int mu_registrar_lookup_url (mu_url_t url, int flags, | ||
259 | mu_record_t *precord, int *pflags); | ||
260 | |||
230 | ** Fixed parsing of URLs similar to file:///a/b. | 261 | ** Fixed parsing of URLs similar to file:///a/b. |
231 | 262 | ||
232 | It is parsed as an absolute file name `/a/b'. | 263 | It is parsed as an absolute file name `/a/b'. | ... | ... |
1 | GNU mailutils TODO list. 2007-12-07 | 1 | GNU mailutils TODO list. 2007-12-28 |
2 | Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, | 2 | Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, |
3 | 2007 Free Software Foundation, Inc. | 3 | 2007 Free Software Foundation, Inc. |
4 | 4 | ||
5 | * Fix folder_imap_list in libproto/imap/folder.c | ||
6 | |||
5 | * Documentation | 7 | * Documentation |
6 | 8 | ||
7 | * Review the code and use mu_vartab_* and mu_kwd_* functions where | 9 | * Review the code and use mu_vartab_* and mu_kwd_* functions where | ... | ... |
... | @@ -39,6 +39,22 @@ | ... | @@ -39,6 +39,22 @@ |
39 | } \ | 39 | } \ |
40 | printf ("\t" #field " <%s>\n", buf) | 40 | printf ("\t" #field " <%s>\n", buf) |
41 | 41 | ||
42 | static void | ||
43 | print_fvpairs (mu_url_t url) | ||
44 | { | ||
45 | size_t fvc, i; | ||
46 | char **fvp; | ||
47 | int rc = mu_url_sget_fvpairs (url, &fvc, &fvp); | ||
48 | if (rc) | ||
49 | { | ||
50 | mu_error ("cannot get F/V pairs: %s", mu_strerror (rc)); | ||
51 | exit (1); | ||
52 | } | ||
53 | if (fvc == 0) | ||
54 | return; | ||
55 | for (i = 0; i < fvc; i++) | ||
56 | printf ("\tparam[%d] <%s>\n", i, fvp[i]); | ||
57 | } | ||
42 | 58 | ||
43 | int | 59 | int |
44 | main () | 60 | main () |
... | @@ -84,6 +100,7 @@ main () | ... | @@ -84,6 +100,7 @@ main () |
84 | printf ("\tport %ld\n", port); | 100 | printf ("\tport %ld\n", port); |
85 | 101 | ||
86 | GET_AND_PRINT (path, u, buf, rc); | 102 | GET_AND_PRINT (path, u, buf, rc); |
103 | print_fvpairs (u); | ||
87 | GET_AND_PRINT (query, u, buf, rc); | 104 | GET_AND_PRINT (query, u, buf, rc); |
88 | 105 | ||
89 | mu_url_destroy (&u); | 106 | mu_url_destroy (&u); | ... | ... |
... | @@ -28,12 +28,18 @@ | ... | @@ -28,12 +28,18 @@ |
28 | extern "C" { | 28 | extern "C" { |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #define MU_ARGCV_RETURN_DELIMS 0x01 | ||
32 | |||
31 | extern int mu_argcv_get (const char *command, const char *delim, | 33 | extern int mu_argcv_get (const char *command, const char *delim, |
32 | const char* cmnt, | 34 | const char* cmnt, |
33 | int *argc, char ***argv); | 35 | int *argc, char ***argv); |
34 | extern int mu_argcv_get_n (const char *command, int len, | 36 | extern int mu_argcv_get_n (const char *command, int len, |
35 | const char *delim, const char *cmnt, | 37 | const char *delim, const char *cmnt, |
36 | int *argc, char ***argv); | 38 | int *argc, char ***argv); |
39 | extern int mu_argcv_get_np (const char *command, int len, | ||
40 | const char *delim, const char *cmnt, | ||
41 | int flags, | ||
42 | int *pargc, char ***pargv, char **endp); | ||
37 | 43 | ||
38 | extern int mu_argcv_string (int argc, char **argv, char **string); | 44 | extern int mu_argcv_string (int argc, char **argv, char **string); |
39 | extern int mu_argcv_free (int argc, char **argv); | 45 | extern int mu_argcv_free (int argc, char **argv); |
... | @@ -42,6 +48,8 @@ extern int mu_argcv_quote_char (int c); | ... | @@ -42,6 +48,8 @@ extern int mu_argcv_quote_char (int c); |
42 | extern size_t mu_argcv_quoted_length (const char *str, int *quote); | 48 | extern size_t mu_argcv_quoted_length (const char *str, int *quote); |
43 | extern void mu_argcv_unquote_copy (char *dst, const char *src, size_t n); | 49 | extern void mu_argcv_unquote_copy (char *dst, const char *src, size_t n); |
44 | extern void mu_argcv_quote_copy (char *dst, const char *src); | 50 | extern void mu_argcv_quote_copy (char *dst, const char *src); |
51 | extern void mu_argcv_remove (int *pargc, char ***pargv, | ||
52 | int (*sel) (const char *, void *), void *); | ||
45 | 53 | ||
46 | #ifdef __cplusplus | 54 | #ifdef __cplusplus |
47 | } | 55 | } | ... | ... |
... | @@ -128,7 +128,7 @@ extern int mu_unre_subject (const char *subject, const char **new_subject); | ... | @@ -128,7 +128,7 @@ extern int mu_unre_subject (const char *subject, const char **new_subject); |
128 | extern char *mu_charset_lookup (char *lang, char *terr); | 128 | extern char *mu_charset_lookup (char *lang, char *terr); |
129 | 129 | ||
130 | extern int mu_true_answer_p (const char *p); | 130 | extern int mu_true_answer_p (const char *p); |
131 | extern int mu_scheme_autodetect_p (const char *scheme, const char **path); | 131 | extern int mu_scheme_autodetect_p (mu_url_t); |
132 | 132 | ||
133 | struct timeval; | 133 | struct timeval; |
134 | 134 | ... | ... |
... | @@ -38,7 +38,7 @@ struct _mu_record | ... | @@ -38,7 +38,7 @@ struct _mu_record |
38 | void *data; /* back pointer. */ | 38 | void *data; /* back pointer. */ |
39 | 39 | ||
40 | /* Stub functions to override. The default is to return the fields. */ | 40 | /* Stub functions to override. The default is to return the fields. */ |
41 | int (*_is_scheme) (mu_record_t, const char *, int); | 41 | int (*_is_scheme) (mu_record_t, mu_url_t, int); |
42 | int (*_get_url) (mu_record_t, int (*(*_mu_url)) (mu_url_t)); | 42 | int (*_get_url) (mu_record_t, int (*(*_mu_url)) (mu_url_t)); |
43 | int (*_get_mailbox) (mu_record_t, int (*(*_mu_mailbox)) (mu_mailbox_t)); | 43 | int (*_get_mailbox) (mu_record_t, int (*(*_mu_mailbox)) (mu_mailbox_t)); |
44 | int (*_get_mailer) (mu_record_t, int (*(*_mu_mailer)) (mu_mailer_t)); | 44 | int (*_get_mailer) (mu_record_t, int (*(*_mu_mailer)) (mu_mailer_t)); |
... | @@ -51,14 +51,16 @@ extern int mu_registrar_get_list (mu_list_t *) __attribute__ ((deprecated)); | ... | @@ -51,14 +51,16 @@ extern int mu_registrar_get_list (mu_list_t *) __attribute__ ((deprecated)); |
51 | 51 | ||
52 | extern int mu_registrar_lookup (const char *name, int flags, | 52 | extern int mu_registrar_lookup (const char *name, int flags, |
53 | mu_record_t *precord, int *pflags); | 53 | mu_record_t *precord, int *pflags); |
54 | extern int mu_registrar_lookup_url (mu_url_t url, int flags, | ||
55 | mu_record_t *precord, int *pflags); | ||
54 | extern int mu_registrar_record (mu_record_t); | 56 | extern int mu_registrar_record (mu_record_t); |
55 | extern int mu_unregistrar_record (mu_record_t); | 57 | extern int mu_unregistrar_record (mu_record_t); |
56 | 58 | ||
57 | /* Scheme. */ | 59 | /* Scheme. */ |
58 | extern int mu_record_is_scheme (mu_record_t, const char *, int flags); | 60 | extern int mu_record_is_scheme (mu_record_t, mu_url_t, int flags); |
59 | extern int mu_record_set_scheme (mu_record_t, const char *); | 61 | extern int mu_record_set_scheme (mu_record_t, const char *); |
60 | extern int mu_record_set_is_scheme (mu_record_t, | 62 | extern int mu_record_set_is_scheme (mu_record_t, |
61 | int (*_is_scheme) (mu_record_t, const char *, int)); | 63 | int (*_is_scheme) (mu_record_t, mu_url_t, int)); |
62 | 64 | ||
63 | /* Url. */ | 65 | /* Url. */ |
64 | extern int mu_record_get_url (mu_record_t, int (*(*)) (mu_url_t)); | 66 | extern int mu_record_get_url (mu_record_t, int (*(*)) (mu_url_t)); | ... | ... |
... | @@ -59,9 +59,13 @@ extern int mu_url_get_query (const mu_url_t, char *, size_t, size_t *); | ... | @@ -59,9 +59,13 @@ extern int mu_url_get_query (const mu_url_t, char *, size_t, size_t *); |
59 | 59 | ||
60 | extern int mu_url_get_port (const mu_url_t, long *); | 60 | extern int mu_url_get_port (const mu_url_t, long *); |
61 | 61 | ||
62 | int mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp); | ||
63 | int mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp); | ||
64 | |||
65 | extern int mu_url_expand_path (mu_url_t url); | ||
62 | extern const char *mu_url_to_string (const mu_url_t); | 66 | extern const char *mu_url_to_string (const mu_url_t); |
63 | 67 | ||
64 | extern int mu_url_is_scheme (mu_url_t, const char* scheme); | 68 | extern int mu_url_is_scheme (mu_url_t, const char *scheme); |
65 | 69 | ||
66 | extern int mu_url_is_same_scheme (mu_url_t, mu_url_t); | 70 | extern int mu_url_is_same_scheme (mu_url_t, mu_url_t); |
67 | extern int mu_url_is_same_user (mu_url_t, mu_url_t); | 71 | extern int mu_url_is_same_user (mu_url_t, mu_url_t); |
... | @@ -69,11 +73,11 @@ extern int mu_url_is_same_path (mu_url_t, mu_url_t); | ... | @@ -69,11 +73,11 @@ extern int mu_url_is_same_path (mu_url_t, mu_url_t); |
69 | extern int mu_url_is_same_host (mu_url_t, mu_url_t); | 73 | extern int mu_url_is_same_host (mu_url_t, mu_url_t); |
70 | extern int mu_url_is_same_port (mu_url_t, mu_url_t); | 74 | extern int mu_url_is_same_port (mu_url_t, mu_url_t); |
71 | 75 | ||
72 | extern char* mu_url_decode (const char *s); | 76 | extern char *mu_url_decode (const char *s); |
73 | 77 | ||
74 | extern int mu_url_is_ticket (mu_url_t ticket, mu_url_t url); | 78 | extern int mu_url_is_ticket (mu_url_t ticket, mu_url_t url); |
75 | extern int mu_url_init (mu_url_t url, int port, const char *scheme); | 79 | extern int mu_url_init (mu_url_t url, int port, const char *scheme); |
76 | 80 | ||
77 | #ifdef __cplusplus | 81 | #ifdef __cplusplus |
78 | } | 82 | } |
79 | #endif | 83 | #endif | ... | ... |
... | @@ -112,7 +112,7 @@ static int folder_imap_close (mu_folder_t); | ... | @@ -112,7 +112,7 @@ 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 *, void *, | 114 | static int folder_imap_list (mu_folder_t, const char *, void *, |
115 | size_t, | 115 | int, size_t, |
116 | mu_list_t, | 116 | mu_list_t, |
117 | mu_folder_enumerate_fp efp, void *edp); | 117 | mu_folder_enumerate_fp efp, void *edp); |
118 | 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 *, |
... | @@ -975,9 +975,10 @@ glob_to_imap (const char *pat, int recursive) | ... | @@ -975,9 +975,10 @@ glob_to_imap (const char *pat, int recursive) |
975 | return ret; | 975 | return ret; |
976 | } | 976 | } |
977 | 977 | ||
978 | /* FIXME: Flags unused */ | ||
978 | static int | 979 | static int |
979 | folder_imap_list (mu_folder_t folder, const char *ref, void *name, | 980 | folder_imap_list (mu_folder_t folder, const char *ref, void *name, |
980 | size_t max_level, | 981 | int flags, size_t max_level, |
981 | mu_list_t flist, | 982 | mu_list_t flist, |
982 | mu_folder_enumerate_fp efp, void *edp) | 983 | mu_folder_enumerate_fp efp, void *edp) |
983 | { | 984 | { | ... | ... |
... | @@ -99,7 +99,6 @@ int _amd_message_insert (struct _amd_data *mhd, struct _amd_message *msg); | ... | @@ -99,7 +99,6 @@ int _amd_message_insert (struct _amd_data *mhd, struct _amd_message *msg); |
99 | int amd_message_stream_open (struct _amd_message *mhm); | 99 | int amd_message_stream_open (struct _amd_message *mhm); |
100 | void amd_message_stream_close (struct _amd_message *mhm); | 100 | void amd_message_stream_close (struct _amd_message *mhm); |
101 | void amd_cleanup (void *arg); | 101 | void amd_cleanup (void *arg); |
102 | int amd_url_init (mu_url_t url, const char *scheme); | ||
103 | struct _amd_message *_amd_get_message (struct _amd_data *amd, size_t msgno); | 102 | struct _amd_message *_amd_get_message (struct _amd_data *amd, size_t msgno); |
104 | int amd_msg_lookup (struct _amd_data *amd, struct _amd_message *msg, | 103 | int amd_msg_lookup (struct _amd_data *amd, struct _amd_message *msg, |
105 | size_t *pret); | 104 | size_t *pret); | ... | ... |
... | @@ -36,62 +36,60 @@ extern "C" { | ... | @@ -36,62 +36,60 @@ extern "C" { |
36 | Perhaps they can be changed? | 36 | Perhaps they can be changed? |
37 | */ | 37 | */ |
38 | #define MU_POP_PORT 110 | 38 | #define MU_POP_PORT 110 |
39 | #define MU_POP_SCHEME "pop://" | 39 | #define MU_POP_SCHEME "pop" |
40 | #define MU_POP_SCHEME_LEN (sizeof (MU_POP_SCHEME) - 1) | 40 | #define MU_POP_SCHEME_LEN (sizeof (MU_POP_SCHEME) - 1) |
41 | extern int _url_pop_init (mu_url_t); | 41 | extern int _url_pop_init (mu_url_t); |
42 | extern int _mailbox_pop_init (mu_mailbox_t); | 42 | extern int _mailbox_pop_init (mu_mailbox_t); |
43 | extern int _folder_pop_init (mu_folder_t); | 43 | extern int _folder_pop_init (mu_folder_t); |
44 | 44 | ||
45 | #define MU_POPS_PORT 995 | 45 | #define MU_POPS_PORT 995 |
46 | #define MU_POPS_SCHEME "pops://" | 46 | #define MU_POPS_SCHEME "pops" |
47 | #define MU_POPS_SCHEME_LEN (sizeof (MU_POPS_SCHEME) - 1) | 47 | #define MU_POPS_SCHEME_LEN (sizeof (MU_POPS_SCHEME) - 1) |
48 | extern int _url_pops_init (mu_url_t); | 48 | extern int _url_pops_init (mu_url_t); |
49 | extern int _mailbox_pops_init (mu_mailbox_t); | 49 | extern int _mailbox_pops_init (mu_mailbox_t); |
50 | 50 | ||
51 | #define MU_IMAP_PORT 143 | 51 | #define MU_IMAP_PORT 143 |
52 | #define MU_IMAP_SCHEME "imap://" | 52 | #define MU_IMAP_SCHEME "imap" |
53 | #define MU_IMAP_SCHEME_LEN (sizeof (MU_IMAP_SCHEME) - 1) | 53 | #define MU_IMAP_SCHEME_LEN (sizeof (MU_IMAP_SCHEME) - 1) |
54 | extern int _url_imap_init (mu_url_t); | 54 | extern int _url_imap_init (mu_url_t); |
55 | extern int _mailbox_imap_init (mu_mailbox_t); | 55 | extern int _mailbox_imap_init (mu_mailbox_t); |
56 | extern int _folder_imap_init (mu_folder_t); | 56 | extern int _folder_imap_init (mu_folder_t); |
57 | 57 | ||
58 | #define MU_IMAPS_PORT 993 | 58 | #define MU_IMAPS_PORT 993 |
59 | #define MU_IMAPS_SCHEME "imaps://" | 59 | #define MU_IMAPS_SCHEME "imaps" |
60 | #define MU_IMAPS_SCHEME_LEN (sizeof (MU_IMAPS_SCHEME) - 1) | 60 | #define MU_IMAPS_SCHEME_LEN (sizeof (MU_IMAPS_SCHEME) - 1) |
61 | extern int _url_imaps_init (mu_url_t); | 61 | extern int _url_imaps_init (mu_url_t); |
62 | extern int _mailbox_imaps_init (mu_mailbox_t); | 62 | extern int _mailbox_imaps_init (mu_mailbox_t); |
63 | 63 | ||
64 | #define MU_MBOX_SCHEME "mbox:" | 64 | #define MU_MBOX_SCHEME "mbox" |
65 | #define MU_MBOX_SCHEME_LEN (sizeof (MU_MBOX_SCHEME) - 1) | 65 | #define MU_MBOX_SCHEME_LEN (sizeof (MU_MBOX_SCHEME) - 1) |
66 | extern int _url_mbox_init (mu_url_t); | ||
67 | extern int _mailbox_mbox_init (mu_mailbox_t); | 66 | extern int _mailbox_mbox_init (mu_mailbox_t); |
68 | extern int _folder_mbox_init (mu_folder_t); | 67 | extern int _folder_mbox_init (mu_folder_t); |
69 | 68 | ||
70 | #define MU_FILE_SCHEME "file:" | 69 | #define MU_FILE_SCHEME "file" |
71 | #define MU_FILE_SCHEME_LEN (sizeof (MU_FILE_SCHEME) - 1) | 70 | #define MU_FILE_SCHEME_LEN (sizeof (MU_FILE_SCHEME) - 1) |
72 | 71 | ||
73 | #define MU_PATH_SCHEME "/" | 72 | #define MU_PATH_SCHEME "/" |
74 | #define MU_PATH_SCHEME_LEN (sizeof (MU_PATH_SCHEME) - 1) | 73 | #define MU_PATH_SCHEME_LEN (sizeof (MU_PATH_SCHEME) - 1) |
75 | extern int _url_path_init (mu_url_t); | ||
76 | extern int _mailbox_path_init (mu_mailbox_t); | 74 | extern int _mailbox_path_init (mu_mailbox_t); |
77 | extern int _folder_path_init (mu_folder_t); | 75 | extern int _folder_path_init (mu_folder_t); |
78 | 76 | ||
79 | #define MU_SMTP_SCHEME "smtp://" | 77 | #define MU_SMTP_SCHEME "smtp" |
80 | #define MU_SMTP_SCHEME_LEN (sizeof (MU_SMTP_SCHEME) - 1) | 78 | #define MU_SMTP_SCHEME_LEN (sizeof (MU_SMTP_SCHEME) - 1) |
81 | #define MU_SMTP_PORT 25 | 79 | #define MU_SMTP_PORT 25 |
82 | extern int _url_smtp_init (mu_url_t); | 80 | extern int _url_smtp_init (mu_url_t); |
83 | extern int _mailer_smtp_init (mu_mailer_t); | 81 | extern int _mailer_smtp_init (mu_mailer_t); |
84 | 82 | ||
85 | #define MU_SENDMAIL_SCHEME "sendmail:" | 83 | #define MU_SENDMAIL_SCHEME "sendmail" |
86 | #define MU_SENDMAIL_SCHEME_LEN (sizeof (MU_SENDMAIL_SCHEME) - 1) | 84 | #define MU_SENDMAIL_SCHEME_LEN (sizeof (MU_SENDMAIL_SCHEME) - 1) |
87 | extern int _url_sendmail_init (mu_url_t); | 85 | extern int _url_sendmail_init (mu_url_t); |
88 | extern int _mailer_sendmail_init (mu_mailer_t); | 86 | extern int _mailer_sendmail_init (mu_mailer_t); |
89 | 87 | ||
90 | #define MU_MH_SCHEME "mh:" | 88 | #define MU_MH_SCHEME "mh" |
91 | #define MU_MH_SCHEME_LEN (sizeof (MU_MH_SCHEME) - 1) | 89 | #define MU_MH_SCHEME_LEN (sizeof (MU_MH_SCHEME) - 1) |
92 | extern int _mailbox_mh_init (mu_mailbox_t mailbox); | 90 | extern int _mailbox_mh_init (mu_mailbox_t mailbox); |
93 | 91 | ||
94 | #define MU_MAILDIR_SCHEME "maildir:" | 92 | #define MU_MAILDIR_SCHEME "maildir" |
95 | #define MU_MAILDIR_SCHEME_LEN (sizeof (MU_MAILDIR_SCHEME) - 1) | 93 | #define MU_MAILDIR_SCHEME_LEN (sizeof (MU_MAILDIR_SCHEME) - 1) |
96 | extern int _mailbox_maildir_init (mu_mailbox_t mailbox); | 94 | extern int _mailbox_maildir_init (mu_mailbox_t mailbox); |
97 | 95 | ... | ... |
... | @@ -40,9 +40,10 @@ struct _mu_url | ... | @@ -40,9 +40,10 @@ struct _mu_url |
40 | char *host; | 40 | char *host; |
41 | long port; | 41 | long port; |
42 | char *path; | 42 | char *path; |
43 | char **fvpairs; | ||
44 | int fvcount; | ||
43 | char *query; | 45 | char *query; |
44 | 46 | ||
45 | |||
46 | void *data; | 47 | void *data; |
47 | 48 | ||
48 | void (*_destroy) (mu_url_t url); | 49 | void (*_destroy) (mu_url_t url); | ... | ... |
... | @@ -33,6 +33,7 @@ | ... | @@ -33,6 +33,7 @@ |
33 | 33 | ||
34 | #include <maildir.h> | 34 | #include <maildir.h> |
35 | #include <mailutils/mutil.h> | 35 | #include <mailutils/mutil.h> |
36 | #include <mailutils/url.h> | ||
36 | #include <amd.h> | 37 | #include <amd.h> |
37 | 38 | ||
38 | static int | 39 | static int |
... | @@ -56,22 +57,21 @@ dir_exists (const char *name, const char *suf) | ... | @@ -56,22 +57,21 @@ dir_exists (const char *name, const char *suf) |
56 | } | 57 | } |
57 | 58 | ||
58 | static int | 59 | static int |
59 | _maildir_is_scheme (mu_record_t record, const char *url, int flags) | 60 | _maildir_is_scheme (mu_record_t record, mu_url_t url, int flags) |
60 | { | 61 | { |
61 | const char *path; | 62 | if (mu_url_is_scheme (url, record->scheme)) |
62 | |||
63 | if (!url || !record->scheme) | ||
64 | return 0; | ||
65 | |||
66 | if (strncmp (record->scheme, url, strlen (record->scheme)) == 0) | ||
67 | return MU_FOLDER_ATTRIBUTE_ALL & flags; | 63 | return MU_FOLDER_ATTRIBUTE_ALL & flags; |
68 | 64 | ||
69 | if (mu_scheme_autodetect_p (url, &path)) | 65 | if (mu_scheme_autodetect_p (url)) |
70 | { | 66 | { |
71 | /* Attemp auto-detection */ | 67 | /* Attemp auto-detection */ |
68 | const char *path; | ||
72 | struct stat st; | 69 | struct stat st; |
73 | int rc = 0; | 70 | int rc = 0; |
74 | 71 | ||
72 | if (mu_url_sget_path (url, &path)) | ||
73 | return 0; | ||
74 | |||
75 | if (stat (path, &st) < 0) | 75 | if (stat (path, &st) < 0) |
76 | return 0; | 76 | return 0; |
77 | 77 | ||
... | @@ -89,21 +89,11 @@ _maildir_is_scheme (mu_record_t record, const char *url, int flags) | ... | @@ -89,21 +89,11 @@ _maildir_is_scheme (mu_record_t record, const char *url, int flags) |
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | 91 | ||
92 | /* | ||
93 | MAILDIR url | ||
94 | maildir:path | ||
95 | */ | ||
96 | int | ||
97 | _maildir_url_init (mu_url_t url) | ||
98 | { | ||
99 | return amd_url_init (url, MU_MAILDIR_SCHEME); | ||
100 | } | ||
101 | |||
102 | static struct _mu_record _maildir_record = | 92 | static struct _mu_record _maildir_record = |
103 | { | 93 | { |
104 | MU_MAILDIR_PRIO, | 94 | MU_MAILDIR_PRIO, |
105 | MU_MAILDIR_SCHEME, | 95 | MU_MAILDIR_SCHEME, |
106 | _maildir_url_init, /* Url init. */ | 96 | mu_url_expand_path, /* Url init. */ |
107 | _mailbox_maildir_init, /* Mailbox init. */ | 97 | _mailbox_maildir_init, /* Mailbox init. */ |
108 | NULL, /* Mailer init. */ | 98 | NULL, /* Mailer init. */ |
109 | _maildir_folder_init, /* Folder init. */ | 99 | _maildir_folder_init, /* Folder init. */ | ... | ... |
... | @@ -50,7 +50,7 @@ static struct _mu_record _mbox_record = | ... | @@ -50,7 +50,7 @@ static struct _mu_record _mbox_record = |
50 | { | 50 | { |
51 | MU_MBOX_PRIO, | 51 | MU_MBOX_PRIO, |
52 | MU_MBOX_SCHEME, | 52 | MU_MBOX_SCHEME, |
53 | _url_mbox_init, /* Mailbox init. */ | 53 | mu_url_expand_path, /* URL init. */ |
54 | _mailbox_mbox_init, /* Mailbox init. */ | 54 | _mailbox_mbox_init, /* Mailbox init. */ |
55 | NULL, /* Mailer init. */ | 55 | NULL, /* Mailer init. */ |
56 | _folder_mbox_init, /* Folder init. */ | 56 | _folder_mbox_init, /* Folder init. */ |
... | @@ -64,19 +64,18 @@ static struct _mu_record _mbox_record = | ... | @@ -64,19 +64,18 @@ static struct _mu_record _mbox_record = |
64 | mu_record_t mu_mbox_record = &_mbox_record; | 64 | mu_record_t mu_mbox_record = &_mbox_record; |
65 | 65 | ||
66 | static int | 66 | static int |
67 | _path_is_scheme (mu_record_t record, const char *url, int flags) | 67 | _path_is_scheme (mu_record_t record, mu_url_t url, int flags) |
68 | { | 68 | { |
69 | int rc = 0; | 69 | int rc = 0; |
70 | const char *path; | ||
71 | 70 | ||
72 | if (url && record->scheme) | 71 | if (url && record->scheme) |
73 | { | 72 | { |
74 | if (mu_scheme_autodetect_p (url, &path)) | 73 | if (mu_scheme_autodetect_p (url)) |
75 | /* implies: | ||
76 | if (strncmp (record->scheme, url, strlen(record->scheme)) == 0) */ | ||
77 | { | 74 | { |
78 | struct stat st; | 75 | struct stat st; |
79 | 76 | const char *path; | |
77 | |||
78 | mu_url_sget_path (url, &path); | ||
80 | if (stat (path, &st) < 0) | 79 | if (stat (path, &st) < 0) |
81 | { | 80 | { |
82 | if (errno == ENOENT) | 81 | if (errno == ENOENT) |
... | @@ -92,6 +91,10 @@ _path_is_scheme (mu_record_t record, const char *url, int flags) | ... | @@ -92,6 +91,10 @@ _path_is_scheme (mu_record_t record, const char *url, int flags) |
92 | } | 91 | } |
93 | else if (flags & MU_FOLDER_ATTRIBUTE_FILE) | 92 | else if (flags & MU_FOLDER_ATTRIBUTE_FILE) |
94 | { | 93 | { |
94 | #if 0 | ||
95 | /* This effectively sieves out all non-mailbox files, | ||
96 | but it makes mu_folder_enumerate crawl, which is | ||
97 | intolerable for imap4d LIST command. */ | ||
95 | int fd = open (path, O_RDONLY); | 98 | int fd = open (path, O_RDONLY); |
96 | if (fd != -1) | 99 | if (fd != -1) |
97 | { | 100 | { |
... | @@ -101,6 +104,9 @@ _path_is_scheme (mu_record_t record, const char *url, int flags) | ... | @@ -101,6 +104,9 @@ _path_is_scheme (mu_record_t record, const char *url, int flags) |
101 | rc |= MU_FOLDER_ATTRIBUTE_FILE; | 104 | rc |= MU_FOLDER_ATTRIBUTE_FILE; |
102 | close (fd); | 105 | close (fd); |
103 | } | 106 | } |
107 | #else | ||
108 | rc |= MU_FOLDER_ATTRIBUTE_FILE; | ||
109 | #endif | ||
104 | } | 110 | } |
105 | } | 111 | } |
106 | 112 | ||
... | @@ -116,7 +122,7 @@ static struct _mu_record _path_record = | ... | @@ -116,7 +122,7 @@ static struct _mu_record _path_record = |
116 | { | 122 | { |
117 | MU_PATH_PRIO, | 123 | MU_PATH_PRIO, |
118 | MU_PATH_SCHEME, | 124 | MU_PATH_SCHEME, |
119 | _url_path_init, /* Mailbox init. */ | 125 | NULL, /* URL init. */ |
120 | _mailbox_mbox_init, /* Mailbox init. */ | 126 | _mailbox_mbox_init, /* Mailbox init. */ |
121 | NULL, /* Mailer init. */ | 127 | NULL, /* Mailer init. */ |
122 | _folder_mbox_init, /* Folder init. */ | 128 | _folder_mbox_init, /* Folder init. */ | ... | ... |
libproto/mbox/url.c
deleted
100644 → 0
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2003, 2007 Free Software Foundation, Inc. | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 3 of the License, or (at your option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General | ||
15 | Public License along with this library; if not, write to the | ||
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
17 | Boston, MA 02110-1301 USA */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include <config.h> | ||
21 | #endif | ||
22 | |||
23 | #include <errno.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <stdio.h> | ||
26 | #include <string.h> | ||
27 | |||
28 | #ifdef HAVE_STRINGS_H | ||
29 | # include <strings.h> | ||
30 | #endif | ||
31 | |||
32 | #include <registrar0.h> | ||
33 | #include <url0.h> | ||
34 | #include <mailutils/errno.h> | ||
35 | #include <mailutils/mutil.h> | ||
36 | |||
37 | static void url_mbox_destroy (mu_url_t purl); | ||
38 | |||
39 | static void | ||
40 | url_mbox_destroy (mu_url_t url MU_ARG_UNUSED) | ||
41 | { | ||
42 | } | ||
43 | |||
44 | /* Default mailbox path generator */ | ||
45 | static char * | ||
46 | _url_path_default (const char *spooldir, const char *user, int unused) | ||
47 | { | ||
48 | char *mbox = malloc (sizeof(spooldir) + strlen(user) + 2); | ||
49 | if (!mbox) | ||
50 | errno = ENOMEM; | ||
51 | else | ||
52 | sprintf (mbox, "%s/%s", spooldir, user); | ||
53 | return mbox; | ||
54 | } | ||
55 | |||
56 | /* Hashed indexing */ | ||
57 | static char * | ||
58 | _url_path_hashed (const char *spooldir, const char *user, int param) | ||
59 | { | ||
60 | int i; | ||
61 | int ulen = strlen (user); | ||
62 | char *mbox; | ||
63 | unsigned hash; | ||
64 | |||
65 | if (param > ulen) | ||
66 | param = ulen; | ||
67 | for (i = 0, hash = 0; i < param; i++) | ||
68 | hash += user[i]; | ||
69 | |||
70 | mbox = malloc (ulen + strlen (spooldir) + 5); | ||
71 | sprintf (mbox, "%s/%02X/%s", spooldir, hash % 256, user); | ||
72 | return mbox; | ||
73 | } | ||
74 | |||
75 | static int transtab[] = { | ||
76 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', | ||
77 | 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', | ||
78 | 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', | ||
79 | 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', | ||
80 | 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', | ||
81 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', | ||
82 | 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', | ||
83 | 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', | ||
84 | 'm', 'a', 'b', 'c', 'd', 'e', 'f', 'g', | ||
85 | 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', | ||
86 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', | ||
87 | 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f', | ||
88 | 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g', | ||
89 | 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', | ||
90 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', | ||
91 | 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f', | ||
92 | 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', | ||
93 | 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', | ||
94 | 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', | ||
95 | 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', | ||
96 | 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', | ||
97 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', | ||
98 | 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', | ||
99 | 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', | ||
100 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', | ||
101 | 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', | ||
102 | 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', | ||
103 | 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g', | ||
104 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', | ||
105 | 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', | ||
106 | 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', | ||
107 | 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g' | ||
108 | }; | ||
109 | |||
110 | /* Forward Indexing */ | ||
111 | static char * | ||
112 | _url_path_index (const char *spooldir, const char *iuser, int index_depth) | ||
113 | { | ||
114 | const unsigned char* user = (const unsigned char*) iuser; | ||
115 | int i, ulen = strlen (iuser); | ||
116 | char *mbox, *p; | ||
117 | |||
118 | if (ulen == 0) | ||
119 | return NULL; | ||
120 | |||
121 | mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 2); | ||
122 | strcpy (mbox, spooldir); | ||
123 | p = mbox + strlen (mbox); | ||
124 | for (i = 0; i < index_depth && i < ulen; i++) | ||
125 | { | ||
126 | *p++ = '/'; | ||
127 | *p++ = transtab[ user[i] ]; | ||
128 | } | ||
129 | for (; i < index_depth; i++) | ||
130 | { | ||
131 | *p++ = '/'; | ||
132 | *p++ = transtab[ user[ulen-1] ]; | ||
133 | } | ||
134 | *p++ = '/'; | ||
135 | strcpy (p, iuser); | ||
136 | return mbox; | ||
137 | } | ||
138 | |||
139 | /* Reverse Indexing */ | ||
140 | static char * | ||
141 | _url_path_rev_index (const char *spooldir, const char *iuser, int index_depth) | ||
142 | { | ||
143 | const unsigned char* user = (const unsigned char*) iuser; | ||
144 | int i, ulen = strlen (iuser); | ||
145 | char *mbox, *p; | ||
146 | |||
147 | if (ulen == 0) | ||
148 | return NULL; | ||
149 | |||
150 | mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 1); | ||
151 | strcpy (mbox, spooldir); | ||
152 | p = mbox + strlen (mbox); | ||
153 | for (i = 0; i < index_depth && i < ulen; i++) | ||
154 | { | ||
155 | *p++ = '/'; | ||
156 | *p++ = transtab[ user[ulen - i - 1] ]; | ||
157 | } | ||
158 | for (; i < index_depth; i++) | ||
159 | { | ||
160 | *p++ = '/'; | ||
161 | *p++ = transtab[ user[0] ]; | ||
162 | } | ||
163 | *p++ = '/'; | ||
164 | strcpy (p, iuser); | ||
165 | return mbox; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | UNIX Mbox | ||
170 | mbox:path[;type=TYPE][;param=PARAM][;user=USERNAME] | ||
171 | */ | ||
172 | int | ||
173 | _url_mbox_init (mu_url_t url) | ||
174 | { | ||
175 | const char *name = mu_url_to_string (url); | ||
176 | size_t len = strlen (name); | ||
177 | char *p; | ||
178 | |||
179 | /* reject the obvious */ | ||
180 | if (name == NULL || strncmp (MU_MBOX_SCHEME, name, MU_MBOX_SCHEME_LEN) != 0 | ||
181 | || len < (MU_MBOX_SCHEME_LEN + 1) /* (scheme)+1+(path)*/) | ||
182 | return EINVAL; | ||
183 | |||
184 | /* do I need to decode url encoding '% hex hex' ? */ | ||
185 | |||
186 | /* TYPE */ | ||
187 | url->_destroy = url_mbox_destroy; | ||
188 | |||
189 | /* SCHEME */ | ||
190 | url->scheme = strdup (MU_MBOX_SCHEME); | ||
191 | if (url->scheme == NULL) | ||
192 | { | ||
193 | url_mbox_destroy (url); | ||
194 | return ENOMEM; | ||
195 | } | ||
196 | |||
197 | /* PATH */ | ||
198 | name += MU_MBOX_SCHEME_LEN; /* pass the scheme */ | ||
199 | url->path = strdup (name); | ||
200 | if (url->path == NULL) | ||
201 | { | ||
202 | url_mbox_destroy (url); | ||
203 | return ENOMEM; | ||
204 | } | ||
205 | p = strchr (url->path, ';'); | ||
206 | if (p) | ||
207 | { | ||
208 | char *(*fun)() = _url_path_default; | ||
209 | char *user = NULL; | ||
210 | int param = 0; | ||
211 | |||
212 | *p++ = 0; | ||
213 | while (p) | ||
214 | { | ||
215 | char *q = strchr (p, ';'); | ||
216 | if (q) | ||
217 | *q++ = 0; | ||
218 | if (strncasecmp (p, "type=", 5) == 0) | ||
219 | { | ||
220 | char *type = p + 5; | ||
221 | |||
222 | if (strcmp (type, "hash") == 0) | ||
223 | fun = _url_path_hashed; | ||
224 | else if (strcmp (type, "index") == 0) | ||
225 | fun = _url_path_index; | ||
226 | else if (strcmp (type, "rev-index") == 0) | ||
227 | fun = _url_path_rev_index; | ||
228 | else | ||
229 | { | ||
230 | url_mbox_destroy (url); | ||
231 | return MU_ERR_NOENT; | ||
232 | } | ||
233 | } | ||
234 | else if (strncasecmp (p, "user=", 5) == 0) | ||
235 | { | ||
236 | user = p + 5; | ||
237 | } | ||
238 | else if (strncasecmp (p, "param=", 6) == 0) | ||
239 | { | ||
240 | param = strtoul (p+6, NULL, 0); | ||
241 | } | ||
242 | p = q; | ||
243 | } | ||
244 | |||
245 | if (user) | ||
246 | { | ||
247 | p = fun (url->path, user, param); | ||
248 | free (url->path); | ||
249 | url->path = p; | ||
250 | } | ||
251 | else | ||
252 | { | ||
253 | url_mbox_destroy (url); | ||
254 | return MU_ERR_NOENT; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static void | ||
262 | url_path_destroy (mu_url_t url MU_ARG_UNUSED) | ||
263 | { | ||
264 | } | ||
265 | |||
266 | int | ||
267 | _url_path_init (mu_url_t url) | ||
268 | { | ||
269 | const char *name = mu_url_to_string (url); | ||
270 | const char *path; | ||
271 | |||
272 | /* reject the obvious */ | ||
273 | if (name == NULL || *name == '\0') | ||
274 | return EINVAL; | ||
275 | |||
276 | mu_scheme_autodetect_p (name, &path); | ||
277 | name = strdup (path); | ||
278 | free (url->name); | ||
279 | url->name = (char*) name; | ||
280 | |||
281 | /* TYPE */ | ||
282 | url->_destroy = url_path_destroy; | ||
283 | |||
284 | /* SCHEME */ | ||
285 | url->scheme = strdup (MU_PATH_SCHEME); | ||
286 | if (url->scheme == NULL) | ||
287 | { | ||
288 | url_path_destroy (url); | ||
289 | return ENOMEM; | ||
290 | } | ||
291 | |||
292 | /* PATH */ | ||
293 | url->path = strdup (name); | ||
294 | if (url->path == NULL) | ||
295 | { | ||
296 | url_path_destroy (url); | ||
297 | return ENOMEM; | ||
298 | } | ||
299 | |||
300 | return 0; | ||
301 | } |
... | @@ -88,22 +88,22 @@ mh_dir_p (const char *name) | ... | @@ -88,22 +88,22 @@ mh_dir_p (const char *name) |
88 | } | 88 | } |
89 | 89 | ||
90 | static int | 90 | static int |
91 | _mh_is_scheme (mu_record_t record, const char *url, int flags) | 91 | _mh_is_scheme (mu_record_t record, mu_url_t url, int flags) |
92 | { | 92 | { |
93 | const char *path; | ||
94 | int rc = 0; | 93 | int rc = 0; |
95 | 94 | ||
96 | if (!url || !record->scheme) | 95 | if (mu_url_is_scheme (url, record->scheme)) |
97 | return 0; | ||
98 | |||
99 | if (strncmp (record->scheme, url, strlen (record->scheme)) == 0) | ||
100 | return MU_FOLDER_ATTRIBUTE_ALL & flags; | 96 | return MU_FOLDER_ATTRIBUTE_ALL & flags; |
101 | 97 | ||
102 | if (mu_scheme_autodetect_p (url, &path)) | 98 | if (mu_scheme_autodetect_p (url)) |
103 | { | 99 | { |
104 | /* Attemp auto-detection */ | 100 | /* Attemp auto-detection */ |
101 | const char *path; | ||
105 | struct stat st; | 102 | struct stat st; |
106 | 103 | ||
104 | if (mu_url_sget_path (url, &path)) | ||
105 | return 0; | ||
106 | |||
107 | if (stat (path, &st) < 0) | 107 | if (stat (path, &st) < 0) |
108 | return 0; /* mu_mailbox_open will complain*/ | 108 | return 0; /* mu_mailbox_open will complain*/ |
109 | 109 | ||
... | @@ -119,21 +119,11 @@ _mh_is_scheme (mu_record_t record, const char *url, int flags) | ... | @@ -119,21 +119,11 @@ _mh_is_scheme (mu_record_t record, const char *url, int flags) |
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | 121 | ||
122 | /* | ||
123 | MH url | ||
124 | mh:path | ||
125 | */ | ||
126 | static int | ||
127 | _mh_url_init (mu_url_t url) | ||
128 | { | ||
129 | return amd_url_init (url, MU_MH_SCHEME); | ||
130 | } | ||
131 | |||
132 | static struct _mu_record _mh_record = | 122 | static struct _mu_record _mh_record = |
133 | { | 123 | { |
134 | MU_MH_PRIO, | 124 | MU_MH_PRIO, |
135 | MU_MH_SCHEME, | 125 | MU_MH_SCHEME, |
136 | _mh_url_init, /* Url init. */ | 126 | mu_url_expand_path, /* Url init. */ |
137 | _mailbox_mh_init, /* Mailbox init. */ | 127 | _mailbox_mh_init, /* Mailbox init. */ |
138 | NULL, /* Mailer init. */ | 128 | NULL, /* Mailer init. */ |
139 | _mh_folder_init, /* Folder init. */ | 129 | _mh_folder_init, /* Folder init. */ | ... | ... |
... | @@ -63,7 +63,7 @@ static int nntp_folder_open (mu_folder_t, int); | ... | @@ -63,7 +63,7 @@ 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 | void *name, | 66 | void *name, int flags, |
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 | mu_folder_enumerate_fp efp, void *edp); |
... | @@ -186,7 +186,7 @@ nntp_folder_destroy (mu_folder_t folder) | ... | @@ -186,7 +186,7 @@ nntp_folder_destroy (mu_folder_t folder) |
186 | 186 | ||
187 | 187 | ||
188 | static int | 188 | static int |
189 | nntp_folder_list (mu_folder_t folder, const char *ref, void *pat, | 189 | nntp_folder_list (mu_folder_t folder, const char *ref, void *pat, int flags, |
190 | 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) | 191 | mu_folder_enumerate_fp efp, void *edp) |
192 | { | 192 | { | ... | ... |
... | @@ -373,6 +373,8 @@ void util_rfc2047_decode (char **value); | ... | @@ -373,6 +373,8 @@ void util_rfc2047_decode (char **value); |
373 | 373 | ||
374 | void util_mark_read (mu_message_t msg); | 374 | void util_mark_read (mu_message_t msg); |
375 | 375 | ||
376 | const char *util_url_to_string (mu_url_t url); | ||
377 | |||
376 | int is_address_field (const char *name); | 378 | int is_address_field (const char *name); |
377 | 379 | ||
378 | extern int ml_got_interrupt (void); | 380 | extern int ml_got_interrupt (void); | ... | ... |
... | @@ -55,7 +55,7 @@ mail_mbox_close () | ... | @@ -55,7 +55,7 @@ mail_mbox_close () |
55 | ngettext ("Held %d message in %s\n", | 55 | ngettext ("Held %d message in %s\n", |
56 | "Held %d messages in %s\n", | 56 | "Held %d messages in %s\n", |
57 | held_count), | 57 | held_count), |
58 | held_count, mu_url_to_string (url)); | 58 | held_count, util_url_to_string (url)); |
59 | mu_mailbox_close (mbox); | 59 | mu_mailbox_close (mbox); |
60 | mu_mailbox_destroy (&mbox); | 60 | mu_mailbox_destroy (&mbox); |
61 | return 0; | 61 | return 0; |
... | @@ -75,7 +75,7 @@ mail_mbox_commit () | ... | @@ -75,7 +75,7 @@ mail_mbox_commit () |
75 | int is_user_mbox; | 75 | int is_user_mbox; |
76 | 76 | ||
77 | mu_mailbox_get_url (mbox, &url); | 77 | mu_mailbox_get_url (mbox, &url); |
78 | is_user_mbox = strcmp (mu_url_to_string (url), getenv ("MBOX")) == 0; | 78 | is_user_mbox = strcmp (util_url_to_string (url), getenv ("MBOX")) == 0; |
79 | 79 | ||
80 | { | 80 | { |
81 | mu_mailbox_t mb; | 81 | mu_mailbox_t mb; |
... | @@ -151,7 +151,7 @@ mail_mbox_commit () | ... | @@ -151,7 +151,7 @@ mail_mbox_commit () |
151 | ngettext ("Saved %d message in %s\n", | 151 | ngettext ("Saved %d message in %s\n", |
152 | "Saved %d messages in %s\n", | 152 | "Saved %d messages in %s\n", |
153 | saved_count), | 153 | saved_count), |
154 | saved_count, mu_url_to_string (u)); | 154 | saved_count, util_url_to_string (u)); |
155 | mu_mailbox_close (dest_mbox); | 155 | mu_mailbox_close (dest_mbox); |
156 | mu_mailbox_destroy (&dest_mbox); | 156 | mu_mailbox_destroy (&dest_mbox); |
157 | } | 157 | } | ... | ... |
... | @@ -61,7 +61,7 @@ mail_summary (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) | ... | @@ -61,7 +61,7 @@ mail_summary (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) |
61 | { | 61 | { |
62 | mu_url_t url = NULL; | 62 | mu_url_t url = NULL; |
63 | mu_mailbox_get_url (mbox, &url); | 63 | mu_mailbox_get_url (mbox, &url); |
64 | printf("\"%s\": ", mu_url_to_string (url)); | 64 | printf("\"%s\": ", util_url_to_string (url)); |
65 | } | 65 | } |
66 | printf (ngettext ("%d message", "%d messages", count), count); | 66 | printf (ngettext ("%d message", "%d messages", count), count); |
67 | if (mnew > 0) | 67 | if (mnew > 0) | ... | ... |
... | @@ -1460,3 +1460,18 @@ util_rfc2047_decode (char **value) | ... | @@ -1460,3 +1460,18 @@ util_rfc2047_decode (char **value) |
1460 | } | 1460 | } |
1461 | } | 1461 | } |
1462 | 1462 | ||
1463 | const char * | ||
1464 | util_url_to_string (mu_url_t url) | ||
1465 | { | ||
1466 | const char *scheme; | ||
1467 | if (mu_url_sget_scheme (url, &scheme) == 0) | ||
1468 | { | ||
1469 | if (strcmp (scheme, "file") == 0 || strcmp (scheme, "mbox") == 0) | ||
1470 | { | ||
1471 | const char *path; | ||
1472 | if (mu_url_sget_path (url, &path) == 0) | ||
1473 | return path; | ||
1474 | } | ||
1475 | } | ||
1476 | return mu_url_to_string (url); | ||
1477 | } | ... | ... |
... | @@ -1531,50 +1531,4 @@ amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, size_t *psiz | ... | @@ -1531,50 +1531,4 @@ amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, size_t *psiz |
1531 | return 0; | 1531 | return 0; |
1532 | } | 1532 | } |
1533 | 1533 | ||
1534 | static void | ||
1535 | amd_url_destroy (mu_url_t url MU_ARG_UNUSED) | ||
1536 | { | ||
1537 | } | ||
1538 | |||
1539 | int | ||
1540 | amd_url_init (mu_url_t url, const char *scheme) | ||
1541 | { | ||
1542 | const char *name = mu_url_to_string (url); | ||
1543 | const char *path_ptr = name; | ||
1544 | size_t len = strlen (name); | ||
1545 | size_t scheme_len = strlen (scheme); | ||
1546 | |||
1547 | if (!name) | ||
1548 | return 0; | ||
1549 | |||
1550 | if (mu_scheme_autodetect_p (name, &path_ptr)) | ||
1551 | /* nothing */ ; | ||
1552 | /* reject the obvious */ | ||
1553 | else if (strncmp (scheme, name, scheme_len) != 0 | ||
1554 | || len < scheme_len + 1) | ||
1555 | return EINVAL; | ||
1556 | else | ||
1557 | path_ptr = name + scheme_len; | ||
1558 | |||
1559 | /* TYPE */ | ||
1560 | url->_destroy = amd_url_destroy; | ||
1561 | |||
1562 | /* SCHEME */ | ||
1563 | url->scheme = strdup (scheme); | ||
1564 | if (url->scheme == NULL) | ||
1565 | { | ||
1566 | amd_url_destroy (url); | ||
1567 | return ENOMEM; | ||
1568 | } | ||
1569 | |||
1570 | /* PATH */ | ||
1571 | url->path = strdup (path_ptr); | ||
1572 | if (url->path == NULL) | ||
1573 | { | ||
1574 | amd_url_destroy (url); | ||
1575 | return ENOMEM; | ||
1576 | } | ||
1577 | |||
1578 | return 0; | ||
1579 | } | ||
1580 | 1534 | ... | ... |
... | @@ -28,6 +28,7 @@ | ... | @@ -28,6 +28,7 @@ |
28 | /* Keep mailutils namespace clean */ | 28 | /* Keep mailutils namespace clean */ |
29 | #define argcv_get mu_argcv_get | 29 | #define argcv_get mu_argcv_get |
30 | #define argcv_get_n mu_argcv_get_n | 30 | #define argcv_get_n mu_argcv_get_n |
31 | #define argcv_get_np mu_argcv_get_np | ||
31 | #define argcv_string mu_argcv_string | 32 | #define argcv_string mu_argcv_string |
32 | #define argcv_free mu_argcv_free | 33 | #define argcv_free mu_argcv_free |
33 | #define argcv_unquote_char mu_argcv_unquote_char | 34 | #define argcv_unquote_char mu_argcv_unquote_char |
... | @@ -47,15 +48,45 @@ | ... | @@ -47,15 +48,45 @@ |
47 | #define isws(c) ((c)==' '||(c)=='\t'||(c)=='\n') | 48 | #define isws(c) ((c)==' '||(c)=='\t'||(c)=='\n') |
48 | #define isdelim(c,delim) (strchr(delim,(c))!=NULL) | 49 | #define isdelim(c,delim) (strchr(delim,(c))!=NULL) |
49 | 50 | ||
51 | struct argcv_info | ||
52 | { | ||
53 | int len; | ||
54 | const char *command; | ||
55 | const char *delim; | ||
56 | const char *comment; | ||
57 | int flags; | ||
58 | |||
59 | int start; | ||
60 | int end; | ||
61 | int save; | ||
62 | int finish_pos; | ||
63 | }; | ||
64 | |||
65 | static void | ||
66 | init_argcv_info (struct argcv_info *ap, int flags, | ||
67 | int len, const char *command, const char *delim, | ||
68 | const char *comment) | ||
69 | { | ||
70 | memset (ap, 0, sizeof *ap); | ||
71 | ap->len = len; | ||
72 | ap->command = command; | ||
73 | ap->delim = delim; | ||
74 | ap->comment = comment; | ||
75 | ap->flags = flags; | ||
76 | } | ||
77 | |||
50 | static int | 78 | static int |
51 | argcv_scan (int len, const char *command, const char *delim, const char* cmnt, | 79 | argcv_scan (struct argcv_info *ap) |
52 | int *start, int *end, int *save) | ||
53 | { | 80 | { |
54 | int i = 0; | 81 | int i = 0; |
82 | int len = ap->len; | ||
83 | const char *command = ap->command; | ||
84 | const char *delim = ap->delim; | ||
85 | const char *comment = ap->comment; | ||
55 | 86 | ||
56 | for (;;) | 87 | for (;;) |
57 | { | 88 | { |
58 | i = *save; | 89 | i = ap->save; |
59 | 90 | ||
60 | if (i >= len) | 91 | if (i >= len) |
61 | return i + 1; | 92 | return i + 1; |
... | @@ -63,7 +94,7 @@ argcv_scan (int len, const char *command, const char *delim, const char* cmnt, | ... | @@ -63,7 +94,7 @@ argcv_scan (int len, const char *command, const char *delim, const char* cmnt, |
63 | /* Skip initial whitespace */ | 94 | /* Skip initial whitespace */ |
64 | while (i < len && isws (command[i])) | 95 | while (i < len && isws (command[i])) |
65 | i++; | 96 | i++; |
66 | *start = i; | 97 | ap->start = i; |
67 | 98 | ||
68 | if (!isdelim (command[i], delim)) | 99 | if (!isdelim (command[i], delim)) |
69 | { | 100 | { |
... | @@ -80,11 +111,11 @@ argcv_scan (int len, const char *command, const char *delim, const char* cmnt, | ... | @@ -80,11 +111,11 @@ argcv_scan (int len, const char *command, const char *delim, const char* cmnt, |
80 | if (command[i] == '\'' || command[i] == '"') | 111 | if (command[i] == '\'' || command[i] == '"') |
81 | { | 112 | { |
82 | int j; | 113 | int j; |
83 | for (j = i+1; j < len && command[j] != command[i]; j++) | 114 | for (j = i + 1; j < len && command[j] != command[i]; j++) |
84 | if (command[j] == '\\') | 115 | if (command[j] == '\\') |
85 | j++; | 116 | j++; |
86 | if (j < len) | 117 | if (j < len) |
87 | i = j+1; | 118 | i = j + 1; |
88 | else | 119 | else |
89 | i++; | 120 | i++; |
90 | } | 121 | } |
... | @@ -95,27 +126,36 @@ argcv_scan (int len, const char *command, const char *delim, const char* cmnt, | ... | @@ -95,27 +126,36 @@ argcv_scan (int len, const char *command, const char *delim, const char* cmnt, |
95 | } | 126 | } |
96 | i--; | 127 | i--; |
97 | } | 128 | } |
129 | else if (!(ap->flags & MU_ARGCV_RETURN_DELIMS)) | ||
130 | { | ||
131 | while (i < len && isdelim (command[i], delim)) | ||
132 | i++; | ||
133 | ap->save = i; | ||
134 | continue; | ||
135 | } | ||
136 | |||
98 | 137 | ||
99 | *end = i; | 138 | ap->end = i; |
100 | *save = i + 1; | 139 | ap->save = ap->finish_pos = i + 1; |
101 | 140 | ||
102 | /* If we have a token, and it starts with a comment character, skip | 141 | /* If we have a token, and it starts with a comment character, skip |
103 | to the newline and restart the token search. */ | 142 | to the newline and restart the token search. */ |
104 | if (*save <= len) | 143 | if (ap->save <= len) |
105 | { | 144 | { |
106 | if (strchr (cmnt, command[*start]) != NULL) | 145 | if (strchr (comment, command[ap->start]) != NULL) |
107 | { | 146 | { |
108 | i = *save; | 147 | ap->finish_pos = ap->start; |
148 | i = ap->save; | ||
109 | while (i < len && command[i] != '\n') | 149 | while (i < len && command[i] != '\n') |
110 | i++; | 150 | i++; |
111 | 151 | ||
112 | *save = i; | 152 | ap->save = i; |
113 | continue; | 153 | continue; |
114 | } | 154 | } |
115 | } | 155 | } |
116 | break; | 156 | break; |
117 | } | 157 | } |
118 | return *save; | 158 | return ap->save; |
119 | } | 159 | } |
120 | 160 | ||
121 | static char quote_transtab[] = "\\\\a\ab\bf\fn\nr\rt\t"; | 161 | static char quote_transtab[] = "\\\\a\ab\bf\fn\nr\rt\t"; |
... | @@ -312,67 +352,85 @@ argcv_quote_copy (char *dst, const char *src) | ... | @@ -312,67 +352,85 @@ argcv_quote_copy (char *dst, const char *src) |
312 | } | 352 | } |
313 | 353 | ||
314 | int | 354 | int |
315 | argcv_get_n (const char *command, int len, const char *delim, const char *cmnt, | 355 | argcv_get_np (const char *command, int len, |
316 | int *argc, char ***argv) | 356 | const char *delim, const char *cmnt, |
357 | int flags, | ||
358 | int *pargc, char ***pargv, char **endp) | ||
317 | { | 359 | { |
318 | int i = 0; | 360 | int i = 0; |
319 | int start, end, save; | 361 | struct argcv_info info; |
320 | 362 | int argc; | |
321 | *argv = NULL; | 363 | char **argv; |
322 | 364 | ||
323 | /* Count number of arguments */ | ||
324 | *argc = 0; | ||
325 | save = 0; | ||
326 | |||
327 | if (!delim) | 365 | if (!delim) |
328 | delim = ""; | 366 | delim = ""; |
329 | if (!cmnt) | 367 | if (!cmnt) |
330 | cmnt = ""; | 368 | cmnt = ""; |
331 | |||
332 | while (argcv_scan (len, command, delim, cmnt, &start, &end, &save) <= len) | ||
333 | (*argc)++; | ||
334 | 369 | ||
335 | *argv = calloc ((*argc + 1), sizeof (char *)); | 370 | init_argcv_info (&info, flags, len, command, delim, cmnt); |
336 | if (*argv == NULL) | 371 | |
372 | /* Count number of arguments */ | ||
373 | argc = 0; | ||
374 | while (argcv_scan (&info) <= len) | ||
375 | argc++; | ||
376 | |||
377 | argv = calloc ((argc + 1), sizeof (char *)); | ||
378 | if (argv == NULL) | ||
337 | return ENOMEM; | 379 | return ENOMEM; |
338 | 380 | ||
339 | i = 0; | 381 | i = 0; |
340 | save = 0; | 382 | info.save = 0; |
341 | for (i = 0; i < *argc; i++) | 383 | for (i = 0; i < argc; i++) |
342 | { | 384 | { |
343 | int n; | 385 | int n; |
344 | int unquote; | 386 | int unquote; |
345 | 387 | ||
346 | argcv_scan (len, command, delim, cmnt, &start, &end, &save); | 388 | argcv_scan (&info); |
347 | 389 | ||
348 | if ((command[start] == '"' || command[end] == '\'') | 390 | if ((command[info.start] == '"' || command[info.end] == '\'') |
349 | && command[end] == command[start]) | 391 | && command[info.end] == command[info.start]) |
350 | { | 392 | { |
351 | if (start < end) | 393 | if (info.start < info.end) |
352 | { | 394 | { |
353 | start++; | 395 | info.start++; |
354 | end--; | 396 | info.end--; |
355 | } | 397 | } |
356 | unquote = 0; | 398 | unquote = 0; |
357 | } | 399 | } |
358 | else | 400 | else |
359 | unquote = 1; | 401 | unquote = 1; |
360 | 402 | ||
361 | n = end - start + 1; | 403 | n = info.end - info.start + 1; |
362 | (*argv)[i] = calloc (n+1, sizeof (char)); | 404 | argv[i] = calloc (n + 1, sizeof (char)); |
363 | if ((*argv)[i] == NULL) | 405 | if (argv[i] == NULL) |
364 | return ENOMEM; | 406 | { |
407 | argcv_free (i, argv); | ||
408 | return ENOMEM; | ||
409 | } | ||
365 | if (unquote) | 410 | if (unquote) |
366 | argcv_unquote_copy ((*argv)[i], &command[start], n); | 411 | argcv_unquote_copy (argv[i], &command[info.start], n); |
367 | else | 412 | else |
368 | memcpy ((*argv)[i], &command[start], n); | 413 | memcpy (argv[i], &command[info.start], n); |
369 | (*argv)[i][n] = 0; | 414 | argv[i][n] = 0; |
370 | } | 415 | } |
371 | (*argv)[i] = NULL; | 416 | argv[i] = NULL; |
417 | |||
418 | *pargc = argc; | ||
419 | *pargv = argv; | ||
420 | if (endp) | ||
421 | *endp = (char*) (command + info.finish_pos); | ||
372 | return 0; | 422 | return 0; |
373 | } | 423 | } |
374 | 424 | ||
375 | int | 425 | int |
426 | argcv_get_n (const char *command, int len, const char *delim, const char *cmnt, | ||
427 | int *pargc, char ***pargv) | ||
428 | { | ||
429 | return argcv_get_np (command, len, delim, cmnt, MU_ARGCV_RETURN_DELIMS, | ||
430 | pargc, pargv, NULL); | ||
431 | } | ||
432 | |||
433 | int | ||
376 | argcv_get (const char *command, const char *delim, const char *cmnt, | 434 | argcv_get (const char *command, const char *delim, const char *cmnt, |
377 | int *argc, char ***argv) | 435 | int *argc, char ***argv) |
378 | { | 436 | { |
... | @@ -445,3 +503,35 @@ argcv_string (int argc, char **argv, char **pstring) | ... | @@ -445,3 +503,35 @@ argcv_string (int argc, char **argv, char **pstring) |
445 | return 0; | 503 | return 0; |
446 | } | 504 | } |
447 | 505 | ||
506 | void | ||
507 | mu_argcv_remove (int *pargc, char ***pargv, | ||
508 | int (*sel) (const char *, void *), void *data) | ||
509 | { | ||
510 | int i, j; | ||
511 | int argc = *pargc; | ||
512 | char **argv = *pargv; | ||
513 | int cnt = 0; | ||
514 | |||
515 | for (i = j = 0; i < argc; i++) | ||
516 | { | ||
517 | if (sel (argv[i], data)) | ||
518 | { | ||
519 | free (argv[i]); | ||
520 | cnt++; | ||
521 | } | ||
522 | else | ||
523 | { | ||
524 | if (i != j) | ||
525 | argv[j] = argv[i]; | ||
526 | j++; | ||
527 | } | ||
528 | } | ||
529 | if (i != j) | ||
530 | argv[j] = NULL; | ||
531 | argc -= cnt; | ||
532 | |||
533 | *pargc = argc; | ||
534 | *pargv = argv; | ||
535 | } | ||
536 | |||
537 | ... | ... |
... | @@ -677,7 +677,7 @@ struct _prog_stream | ... | @@ -677,7 +677,7 @@ struct _prog_stream |
677 | pid_t pid; | 677 | pid_t pid; |
678 | int status; | 678 | int status; |
679 | pid_t writer_pid; | 679 | pid_t writer_pid; |
680 | size_t argc; | 680 | int argc; |
681 | char **argv; | 681 | char **argv; |
682 | mu_stream_t in, out; | 682 | mu_stream_t in, out; |
683 | 683 | ... | ... |
... | @@ -73,22 +73,37 @@ mu_folder_create_from_record (mu_folder_t *pfolder, const char *name, | ... | @@ -73,22 +73,37 @@ mu_folder_create_from_record (mu_folder_t *pfolder, const char *name, |
73 | == 0) | 73 | == 0) |
74 | { | 74 | { |
75 | int (*f_init) (mu_folder_t) = NULL; | 75 | int (*f_init) (mu_folder_t) = NULL; |
76 | int (*u_init) (mu_url_t) = NULL; | ||
77 | 76 | ||
78 | mu_record_get_folder (record, &f_init); | 77 | mu_record_get_folder (record, &f_init); |
79 | mu_record_get_url (record, &u_init); | 78 | if (f_init) |
80 | if (f_init && u_init) | ||
81 | { | 79 | { |
82 | int status; | 80 | int status; |
83 | mu_url_t url; | 81 | mu_url_t url; |
84 | mu_folder_t folder; | 82 | mu_folder_t folder; |
83 | int (*u_init) (mu_url_t) = NULL; | ||
85 | 84 | ||
86 | /* Parse the url, it may be a bad one and we should bailout if this | 85 | /* Parse the url, it may be a bad one and we should bailout if this |
87 | failed. */ | 86 | failed. */ |
88 | if ((status = mu_url_create (&url, name) != 0) | 87 | if ((status = mu_url_create (&url, name)) != 0) |
89 | || (status = u_init (url)) != 0) | ||
90 | return status; | 88 | return status; |
91 | 89 | ||
90 | status = mu_url_parse (url); | ||
91 | if (status) | ||
92 | { | ||
93 | mu_url_destroy (url); | ||
94 | return status; | ||
95 | } | ||
96 | mu_record_get_url (record, &u_init); | ||
97 | if (u_init) | ||
98 | { | ||
99 | status = u_init (url); | ||
100 | if (status) | ||
101 | { | ||
102 | mu_url_destroy (url); | ||
103 | return status; | ||
104 | } | ||
105 | } | ||
106 | |||
92 | mu_monitor_wrlock (&folder_lock); | 107 | mu_monitor_wrlock (&folder_lock); |
93 | 108 | ||
94 | /* Check if we already have the same URL folder. */ | 109 | /* Check if we already have the same URL folder. */ | ... | ... |
... | @@ -165,7 +165,7 @@ int | ... | @@ -165,7 +165,7 @@ int |
165 | mu_global_debug_from_string (const char *string, const char *errpfx) | 165 | mu_global_debug_from_string (const char *string, const char *errpfx) |
166 | { | 166 | { |
167 | int rc; | 167 | int rc; |
168 | size_t argc; | 168 | int argc; |
169 | char **argv; | 169 | char **argv; |
170 | int i; | 170 | int i; |
171 | 171 | ... | ... |
... | @@ -42,20 +42,28 @@ | ... | @@ -42,20 +42,28 @@ |
42 | #include <mailutils/mutil.h> | 42 | #include <mailutils/mutil.h> |
43 | 43 | ||
44 | #include <mailbox0.h> | 44 | #include <mailbox0.h> |
45 | #include <url0.h> | ||
45 | 46 | ||
46 | static int | 47 | static int |
47 | mailbox_folder_create (mu_folder_t *pfolder, const char *name) | 48 | mailbox_folder_create (mu_mailbox_t mbox, const char *name, |
49 | mu_record_t record) | ||
48 | { | 50 | { |
49 | int rc; | 51 | int rc; |
50 | char *p, *fname = strdup (name); | 52 | char *fname; |
51 | 53 | ||
52 | if (!fname) | 54 | if ((rc = mu_url_aget_path (mbox->url, &fname))) |
53 | return ENOMEM; | 55 | return rc; |
54 | 56 | ||
55 | p = strrchr (fname, '/'); /* FIXME: Is this always appropriate? */ | 57 | if (mu_url_is_scheme (mbox->url, "file") |
56 | if (p && !(mu_is_proto (fname) && strncmp (fname, "file:", 5))) | 58 | || mu_url_is_scheme (mbox->url, "mbox") |
57 | *p = 0; | 59 | || mu_url_is_scheme (mbox->url, "mh") |
58 | rc = mu_folder_create (pfolder, fname); | 60 | || mu_url_is_scheme (mbox->url, "maildir")) |
61 | { | ||
62 | char *p = strrchr (fname, '/'); /* FIXME: Is this always appropriate? */ | ||
63 | if (p) | ||
64 | *p = 0; | ||
65 | } | ||
66 | rc = mu_folder_create_from_record (&mbox->folder, fname, record); | ||
59 | free (fname); | 67 | free (fname); |
60 | return rc; | 68 | return rc; |
61 | } | 69 | } |
... | @@ -85,22 +93,21 @@ mu_mailbox_get_default_proto () | ... | @@ -85,22 +93,21 @@ mu_mailbox_get_default_proto () |
85 | } | 93 | } |
86 | 94 | ||
87 | static int | 95 | static int |
88 | _create_mailbox (mu_mailbox_t *pmbox, const char *name) | 96 | _create_mailbox0 (mu_mailbox_t *pmbox, mu_url_t url, const char *name) |
89 | { | 97 | { |
98 | int status; | ||
90 | mu_record_t record = NULL; | 99 | mu_record_t record = NULL; |
91 | 100 | ||
92 | if (mu_registrar_lookup (name, MU_FOLDER_ATTRIBUTE_FILE, &record, NULL) == 0) | 101 | if (mu_registrar_lookup_url (url, MU_FOLDER_ATTRIBUTE_FILE, &record, NULL) |
102 | == 0) | ||
93 | { | 103 | { |
94 | mu_log_level_t level; | 104 | mu_log_level_t level; |
95 | int (*m_init) (mu_mailbox_t) = NULL; | 105 | int (*m_init) (mu_mailbox_t) = NULL; |
96 | int (*u_init) (mu_url_t) = NULL; | ||
97 | 106 | ||
98 | mu_record_get_mailbox (record, &m_init); | 107 | mu_record_get_mailbox (record, &m_init); |
99 | mu_record_get_url (record, &u_init); | 108 | if (m_init) |
100 | if (m_init && u_init) | ||
101 | { | 109 | { |
102 | int status; | 110 | int (*u_init) (mu_url_t) = NULL; |
103 | mu_url_t url; | ||
104 | mu_mailbox_t mbox; | 111 | mu_mailbox_t mbox; |
105 | 112 | ||
106 | /* Allocate memory for mbox. */ | 113 | /* Allocate memory for mbox. */ |
... | @@ -117,19 +124,31 @@ _create_mailbox (mu_mailbox_t *pmbox, const char *name) | ... | @@ -117,19 +124,31 @@ _create_mailbox (mu_mailbox_t *pmbox, const char *name) |
117 | return status; | 124 | return status; |
118 | } | 125 | } |
119 | 126 | ||
120 | /* Parse the url, it may be a bad one and we should bailout if this | 127 | mu_record_get_url (record, &u_init); |
121 | failed. */ | 128 | if (u_init && (status = u_init (url)) != 0) |
122 | if ((status = mu_url_create (&url, name)) != 0 | ||
123 | || (status = u_init (url)) != 0) | ||
124 | { | 129 | { |
125 | mu_mailbox_destroy (&mbox); | 130 | mu_mailbox_destroy (&mbox); |
126 | return status; | 131 | return status; |
127 | } | 132 | } |
133 | |||
134 | /* Make sure scheme contains actual mailbox scheme */ | ||
135 | if (strcmp (url->scheme, record->scheme)) | ||
136 | { | ||
137 | char *p = strdup (record->scheme); | ||
138 | if (!p) | ||
139 | { | ||
140 | mu_mailbox_destroy (&mbox); | ||
141 | return errno; | ||
142 | } | ||
143 | free (url->scheme); | ||
144 | url->scheme = p; | ||
145 | } | ||
146 | |||
128 | mbox->url = url; | 147 | mbox->url = url; |
129 | 148 | ||
130 | /* Create the folder before initializing the concrete mailbox. | 149 | /* Create the folder before initializing the concrete mailbox. |
131 | The mailbox needs it's back pointer. */ | 150 | The mailbox needs it's back pointer. */ |
132 | status = mailbox_folder_create (&mbox->folder, name); | 151 | status = mailbox_folder_create (mbox, name, record); |
133 | 152 | ||
134 | if (status == 0) | 153 | if (status == 0) |
135 | status = m_init (mbox); /* Create the concrete mailbox type. */ | 154 | status = m_init (mbox); /* Create the concrete mailbox type. */ |
... | @@ -160,6 +179,21 @@ _create_mailbox (mu_mailbox_t *pmbox, const char *name) | ... | @@ -160,6 +179,21 @@ _create_mailbox (mu_mailbox_t *pmbox, const char *name) |
160 | return MU_ERR_NO_HANDLER; | 179 | return MU_ERR_NO_HANDLER; |
161 | } | 180 | } |
162 | 181 | ||
182 | static int | ||
183 | _create_mailbox (mu_mailbox_t *pmbox, const char *name) | ||
184 | { | ||
185 | int status; | ||
186 | mu_url_t url; | ||
187 | |||
188 | status = mu_url_create (&url, name); | ||
189 | if (status) | ||
190 | return status; | ||
191 | status = mu_url_parse (url); | ||
192 | if (status == 0) | ||
193 | status = _create_mailbox0 (pmbox, url, name); | ||
194 | return status; | ||
195 | } | ||
196 | |||
163 | /* The Mailbox Factory. | 197 | /* The Mailbox Factory. |
164 | Create an iterator for registrar and see if any url scheme match, | 198 | Create an iterator for registrar and see if any url scheme match, |
165 | Then we call the mailbox's mu_url_create() to parse the URL. Last | 199 | Then we call the mailbox's mu_url_create() to parse the URL. Last | ... | ... |
... | @@ -59,6 +59,7 @@ | ... | @@ -59,6 +59,7 @@ |
59 | #include <mailutils/stream.h> | 59 | #include <mailutils/stream.h> |
60 | #include <mailutils/filter.h> | 60 | #include <mailutils/filter.h> |
61 | #include <mailutils/sql.h> | 61 | #include <mailutils/sql.h> |
62 | #include <mailutils/url.h> | ||
62 | 63 | ||
63 | #include <registrar0.h> | 64 | #include <registrar0.h> |
64 | 65 | ||
... | @@ -1243,21 +1244,15 @@ mu_true_answer_p (const char *p) | ... | @@ -1243,21 +1244,15 @@ mu_true_answer_p (const char *p) |
1243 | return -1; | 1244 | return -1; |
1244 | } | 1245 | } |
1245 | 1246 | ||
1246 | /* Returns true if SCHEME represents a local mail folder. Stores | 1247 | /* Returns true if SCHEME represents a local (autodetect) mail folder. */ |
1247 | real folder path to PATH */ | ||
1248 | int | 1248 | int |
1249 | mu_scheme_autodetect_p (const char *scheme, const char **path) | 1249 | mu_scheme_autodetect_p (mu_url_t url) |
1250 | { | 1250 | { |
1251 | *path = scheme; | 1251 | if (mu_url_is_scheme (url, "file")) |
1252 | if (strncmp (MU_FILE_SCHEME, scheme, MU_FILE_SCHEME_LEN) == 0) | ||
1253 | { | 1252 | { |
1254 | *path += MU_FILE_SCHEME_LEN; | 1253 | mu_url_expand_path (url); |
1255 | return 1; | 1254 | return 1; |
1256 | } | 1255 | } |
1257 | if (access (scheme, F_OK) == 0 | ||
1258 | /* FIXME: this can return true even if the folder is unreadable */ | ||
1259 | || strncmp (MU_PATH_SCHEME, scheme, MU_PATH_SCHEME_LEN) == 0) | ||
1260 | return 1; | ||
1261 | return 0; | 1256 | return 0; |
1262 | } | 1257 | } |
1263 | 1258 | ||
... | @@ -1329,7 +1324,7 @@ mu_decode_filter (mu_stream_t *pfilter, mu_stream_t input, | ... | @@ -1329,7 +1324,7 @@ mu_decode_filter (mu_stream_t *pfilter, mu_stream_t input, |
1329 | mu_stream_t filter; | 1324 | mu_stream_t filter; |
1330 | 1325 | ||
1331 | int status = mu_filter_create (&filter, input, filter_type, | 1326 | int status = mu_filter_create (&filter, input, filter_type, |
1332 | MU_FILTER_DECODE, MU_STREAM_READ); | 1327 | MU_FILTER_DECODE, MU_STREAM_READ); |
1333 | if (status) | 1328 | if (status) |
1334 | return status; | 1329 | return status; |
1335 | 1330 | ... | ... |
... | @@ -34,6 +34,7 @@ | ... | @@ -34,6 +34,7 @@ |
34 | #include <mailutils/errno.h> | 34 | #include <mailutils/errno.h> |
35 | #include <mailutils/nls.h> | 35 | #include <mailutils/nls.h> |
36 | #include <mailutils/error.h> | 36 | #include <mailutils/error.h> |
37 | #include <mailutils/url.h> | ||
37 | 38 | ||
38 | #include <registrar0.h> | 39 | #include <registrar0.h> |
39 | 40 | ||
... | @@ -90,8 +91,8 @@ mu_registrar_get_iterator (mu_iterator_t *pitr) | ... | @@ -90,8 +91,8 @@ mu_registrar_get_iterator (mu_iterator_t *pitr) |
90 | } | 91 | } |
91 | 92 | ||
92 | int | 93 | int |
93 | mu_registrar_lookup (const char *name, int flags, | 94 | mu_registrar_lookup_url (mu_url_t url, int flags, |
94 | mu_record_t *precord, int *pflags) | 95 | mu_record_t *precord, int *pflags) |
95 | { | 96 | { |
96 | mu_iterator_t iterator; | 97 | mu_iterator_t iterator; |
97 | int status = mu_registrar_get_iterator (&iterator); | 98 | int status = mu_registrar_get_iterator (&iterator); |
... | @@ -104,7 +105,7 @@ mu_registrar_lookup (const char *name, int flags, | ... | @@ -104,7 +105,7 @@ mu_registrar_lookup (const char *name, int flags, |
104 | int rc; | 105 | int rc; |
105 | mu_record_t record; | 106 | mu_record_t record; |
106 | mu_iterator_current (iterator, (void **)&record); | 107 | mu_iterator_current (iterator, (void **)&record); |
107 | if ((rc = mu_record_is_scheme (record, name, flags))) | 108 | if ((rc = mu_record_is_scheme (record, url, flags))) |
108 | { | 109 | { |
109 | status = 0; | 110 | status = 0; |
110 | if (precord) | 111 | if (precord) |
... | @@ -118,6 +119,23 @@ mu_registrar_lookup (const char *name, int flags, | ... | @@ -118,6 +119,23 @@ mu_registrar_lookup (const char *name, int flags, |
118 | return status; | 119 | return status; |
119 | } | 120 | } |
120 | 121 | ||
122 | int | ||
123 | mu_registrar_lookup (const char *name, int flags, | ||
124 | mu_record_t *precord, int *pflags) | ||
125 | { | ||
126 | int rc; | ||
127 | mu_url_t url; | ||
128 | |||
129 | rc = mu_url_create (&url, name); | ||
130 | if (rc) | ||
131 | return rc; | ||
132 | rc = mu_url_parse (url); | ||
133 | if (rc == 0) | ||
134 | rc = mu_registrar_lookup_url (url, flags, precord, pflags); | ||
135 | mu_url_destroy (&url); | ||
136 | return rc; | ||
137 | } | ||
138 | |||
121 | static int | 139 | static int |
122 | _compare_prio (const void *item, const void *value) | 140 | _compare_prio (const void *item, const void *value) |
123 | { | 141 | { |
... | @@ -156,18 +174,16 @@ mu_unregistrar_record (mu_record_t record) | ... | @@ -156,18 +174,16 @@ mu_unregistrar_record (mu_record_t record) |
156 | } | 174 | } |
157 | 175 | ||
158 | int | 176 | int |
159 | mu_record_is_scheme (mu_record_t record, const char *scheme, int flags) | 177 | mu_record_is_scheme (mu_record_t record, mu_url_t url, int flags) |
160 | { | 178 | { |
161 | if (record == NULL) | 179 | if (record == NULL) |
162 | return 0; | 180 | return 0; |
163 | 181 | ||
164 | /* Overload. */ | 182 | /* Overload. */ |
165 | if (record->_is_scheme) | 183 | if (record->_is_scheme) |
166 | return record->_is_scheme (record, scheme, flags); | 184 | return record->_is_scheme (record, url, flags); |
167 | 185 | ||
168 | if (scheme | 186 | if (mu_url_is_scheme (url, record->scheme)) |
169 | && record->scheme | ||
170 | && strncasecmp (record->scheme, scheme, strlen (record->scheme)) == 0) | ||
171 | return MU_FOLDER_ATTRIBUTE_ALL; | 187 | return MU_FOLDER_ATTRIBUTE_ALL; |
172 | 188 | ||
173 | return 0; | 189 | return 0; |
... | @@ -183,8 +199,8 @@ mu_record_set_scheme (mu_record_t record, const char *scheme) | ... | @@ -183,8 +199,8 @@ mu_record_set_scheme (mu_record_t record, const char *scheme) |
183 | } | 199 | } |
184 | 200 | ||
185 | int | 201 | int |
186 | mu_record_set_is_scheme (mu_record_t record, int (*_is_scheme) | 202 | mu_record_set_is_scheme (mu_record_t record, |
187 | (mu_record_t, const char *, int)) | 203 | int (*_is_scheme) (mu_record_t, mu_url_t, int)) |
188 | { | 204 | { |
189 | if (record == NULL) | 205 | if (record == NULL) |
190 | return EINVAL; | 206 | return EINVAL; | ... | ... |
... | @@ -627,4 +627,41 @@ ftp://ftp.example.org:111/mbox/user%40host => SUCCESS | ... | @@ -627,4 +627,41 @@ ftp://ftp.example.org:111/mbox/user%40host => SUCCESS |
627 | path <mbox/user@host> | 627 | path <mbox/user@host> |
628 | query <> | 628 | query <> |
629 | 629 | ||
630 | ftp://ftp.example.org:111/mbox/user%40host;type=pass => SUCCESS | ||
631 | scheme <ftp> | ||
632 | user <> | ||
633 | passwd <> | ||
634 | auth <> | ||
635 | host <ftp.example.org> | ||
636 | port 111 | ||
637 | path <mbox/user@host> | ||
638 | param[0] <type=pass> | ||
639 | query <> | ||
640 | |||
641 | mbox:/var/spool/mail;type=index;param=2;user=gray => SUCCESS | ||
642 | scheme <mbox> | ||
643 | user <> | ||
644 | passwd <> | ||
645 | auth <> | ||
646 | host <> | ||
647 | port 0 | ||
648 | path </var/spool/mail> | ||
649 | param[0] <type=index> | ||
650 | param[1] <param=2> | ||
651 | param[2] <user=gray> | ||
652 | query <> | ||
653 | |||
654 | mbox:///var/spool/mail;type=index;param=2;user=gray => SUCCESS | ||
655 | scheme <mbox> | ||
656 | user <> | ||
657 | passwd <> | ||
658 | auth <> | ||
659 | host <> | ||
660 | port 0 | ||
661 | path </var/spool/mail> | ||
662 | param[0] <type=index> | ||
663 | param[1] <param=2> | ||
664 | param[2] <user=gray> | ||
665 | query <> | ||
666 | |||
630 | # NOTE: This file must end with an empty line | 667 | # NOTE: This file must end with an empty line | ... | ... |
... | @@ -30,6 +30,7 @@ | ... | @@ -30,6 +30,7 @@ |
30 | 30 | ||
31 | #include <mailutils/mutil.h> | 31 | #include <mailutils/mutil.h> |
32 | #include <mailutils/errno.h> | 32 | #include <mailutils/errno.h> |
33 | #include <mailutils/argcv.h> | ||
33 | #include <url0.h> | 34 | #include <url0.h> |
34 | 35 | ||
35 | /* | 36 | /* |
... | @@ -86,6 +87,9 @@ mu_url_destroy (mu_url_t * purl) | ... | @@ -86,6 +87,9 @@ mu_url_destroy (mu_url_t * purl) |
86 | if (url->path) | 87 | if (url->path) |
87 | free (url->path); | 88 | free (url->path); |
88 | 89 | ||
90 | if (url->fvcount) | ||
91 | mu_argcv_free (url->fvcount, url->fvpairs); | ||
92 | |||
89 | if (url->query) | 93 | if (url->query) |
90 | free (url->query); | 94 | free (url->query); |
91 | 95 | ||
... | @@ -100,11 +104,12 @@ mu_url_parse (mu_url_t url) | ... | @@ -100,11 +104,12 @@ mu_url_parse (mu_url_t url) |
100 | { | 104 | { |
101 | int err = 0; | 105 | int err = 0; |
102 | char *n = NULL; | 106 | char *n = NULL; |
103 | struct _mu_url u = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | 107 | struct _mu_url u; |
104 | 108 | ||
105 | if (!url || !url->name) | 109 | if (!url || !url->name) |
106 | return EINVAL; | 110 | return EINVAL; |
107 | 111 | ||
112 | memset (&u, 0, sizeof u); | ||
108 | /* can't have been parsed already */ | 113 | /* can't have been parsed already */ |
109 | if (url->scheme || url->user || url->passwd || url->auth || | 114 | if (url->scheme || url->user || url->passwd || url->auth || |
110 | url->host || url->path || url->query) | 115 | url->host || url->path || url->query) |
... | @@ -125,14 +130,17 @@ mu_url_parse (mu_url_t url) | ... | @@ -125,14 +130,17 @@ mu_url_parse (mu_url_t url) |
125 | though. | 130 | though. |
126 | */ | 131 | */ |
127 | 132 | ||
128 | #define UALLOC(X) \ | 133 | #define UALLOC(X) \ |
129 | if(u.X && u.X[0] && (url->X = mu_url_decode(u.X)) == 0) { \ | 134 | if (u.X && u.X[0] && (url->X = mu_url_decode(u.X)) == 0) \ |
130 | err = ENOMEM; \ | 135 | { \ |
131 | goto CLEANUP; \ | 136 | err = ENOMEM; \ |
132 | } else { \ | 137 | goto CLEANUP; \ |
133 | /* Set zero-length strings to NULL. */ \ | 138 | } \ |
134 | u.X = NULL; \ | 139 | else \ |
135 | } | 140 | { \ |
141 | /* Set zero-length strings to NULL. */ \ | ||
142 | u.X = NULL; \ | ||
143 | } | ||
136 | 144 | ||
137 | UALLOC (scheme); | 145 | UALLOC (scheme); |
138 | UALLOC (user); | 146 | UALLOC (user); |
... | @@ -142,6 +150,8 @@ mu_url_parse (mu_url_t url) | ... | @@ -142,6 +150,8 @@ mu_url_parse (mu_url_t url) |
142 | UALLOC (path); | 150 | UALLOC (path); |
143 | UALLOC (query); | 151 | UALLOC (query); |
144 | #undef UALLOC | 152 | #undef UALLOC |
153 | url->fvcount = u.fvcount; | ||
154 | url->fvpairs = u.fvpairs; | ||
145 | url->port = u.port; | 155 | url->port = u.port; |
146 | } | 156 | } |
147 | 157 | ||
... | @@ -150,7 +160,7 @@ CLEANUP: | ... | @@ -150,7 +160,7 @@ CLEANUP: |
150 | 160 | ||
151 | if (err) | 161 | if (err) |
152 | { | 162 | { |
153 | #define UFREE(X) if(X) { free(X); X = 0; } | 163 | #define UFREE(X) if (X) { free(X); X = 0; } |
154 | 164 | ||
155 | UFREE (url->scheme); | 165 | UFREE (url->scheme); |
156 | UFREE (url->user); | 166 | UFREE (url->user); |
... | @@ -199,111 +209,126 @@ url_parse0 (mu_url_t u, char *name) | ... | @@ -199,111 +209,126 @@ url_parse0 (mu_url_t u, char *name) |
199 | if (name == NULL) | 209 | if (name == NULL) |
200 | return EINVAL; | 210 | return EINVAL; |
201 | 211 | ||
202 | /* Parse out the SCHEME. */ | 212 | if (name[0] == '/') |
203 | p = strchr (name, ':'); | 213 | { |
204 | if (p == NULL) | 214 | u->scheme = "file"; |
205 | return MU_ERR_PARSE; | 215 | } |
206 | 216 | else | |
207 | *p++ = 0; | 217 | { |
208 | 218 | /* Parse out the SCHEME. */ | |
209 | u->scheme = name; | 219 | p = strchr (name, ':'); |
220 | if (p == NULL) | ||
221 | return MU_ERR_PARSE; | ||
210 | 222 | ||
211 | /* RFC 1738, section 2.1, lower the scheme case */ | 223 | *p++ = 0; |
212 | for (; name < p; name++) | ||
213 | *name = tolower (*name); | ||
214 | 224 | ||
215 | name = p; | 225 | u->scheme = name; |
216 | 226 | ||
227 | /* RFC 1738, section 2.1, lower the scheme case */ | ||
228 | for (; name < p; name++) | ||
229 | *name = tolower (*name); | ||
230 | |||
231 | name = p; | ||
232 | } | ||
233 | |||
217 | /* Check for nothing following the scheme. */ | 234 | /* Check for nothing following the scheme. */ |
218 | if (!*name) | 235 | if (!*name) |
219 | return 0; | 236 | return 0; |
220 | 237 | ||
221 | if (strncmp (name, "//", 2) != 0) | 238 | if (strncmp (name, "//", 2) == 0) |
222 | { | 239 | { |
223 | u->path = name; | 240 | name += 2; |
224 | return 0; | ||
225 | } | ||
226 | |||
227 | name += 2; | ||
228 | 241 | ||
229 | if (name[0] == '/') | 242 | if (name[0] == '/') |
230 | { | ||
231 | u->path = name; | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | /* Split into LHS and RHS of the '@', and then parse each side. */ | ||
236 | u->host = strchr (name, '@'); | ||
237 | if (u->host == NULL) | ||
238 | u->host = name; | ||
239 | else | ||
240 | { | ||
241 | /* Parse the LHS into an identification/authentication pair. */ | ||
242 | *u->host++ = 0; | ||
243 | |||
244 | u->user = name; | ||
245 | |||
246 | /* Try to split the user into a: | ||
247 | <user>:<password> | ||
248 | or | ||
249 | <user>;AUTH=<auth> | ||
250 | */ | ||
251 | |||
252 | for (; *name; name++) | ||
253 | { | 243 | { |
254 | if (*name == ';') | 244 | u->path = name; |
245 | p = u->path + strcspn (u->path, ";?"); | ||
246 | } | ||
247 | else | ||
248 | { | ||
249 | /* Split into LHS and RHS of the '@', and then parse each side. */ | ||
250 | u->host = strchr (name, '@'); | ||
251 | if (u->host == NULL) | ||
252 | u->host = name; | ||
253 | else | ||
255 | { | 254 | { |
256 | /* Make sure it's the auth token. */ | 255 | /* Parse the LHS into an identification/authentication pair. */ |
257 | if (strncasecmp (name + 1, "auth=", 5) == 0) | 256 | *u->host++ = 0; |
258 | { | ||
259 | *name++ = 0; | ||
260 | 257 | ||
261 | name += 5; | 258 | u->user = name; |
262 | 259 | ||
263 | u->auth = name; | 260 | /* Try to split the user into a: |
261 | <user>:<password> | ||
262 | or | ||
263 | <user>;AUTH=<auth> | ||
264 | */ | ||
264 | 265 | ||
265 | break; | 266 | for (; *name; name++) |
267 | { | ||
268 | if (*name == ';') | ||
269 | { | ||
270 | /* Make sure it's the auth token. */ | ||
271 | if (strncasecmp (name + 1, "auth=", 5) == 0) | ||
272 | { | ||
273 | *name++ = 0; | ||
274 | name += 5; | ||
275 | u->auth = name; | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | if (*name == ':') | ||
280 | { | ||
281 | *name++ = 0; | ||
282 | u->passwd = name; | ||
283 | break; | ||
284 | } | ||
266 | } | 285 | } |
267 | } | 286 | } |
268 | if (*name == ':') | 287 | |
288 | /* Parse the host and port from the RHS. */ | ||
289 | p = strchr (u->host, ':'); | ||
290 | if (p) | ||
269 | { | 291 | { |
270 | *name++ = 0; | 292 | *p++ = 0; |
271 | u->passwd = name; | 293 | u->port = strtol (p, &p, 10); |
272 | break; | 294 | |
295 | /* Check for garbage after the port: we should be on the start | ||
296 | of a path, a query, or at the end of the string. */ | ||
297 | if (*p && strcspn (p, "/?") != 0) | ||
298 | return MU_ERR_PARSE; | ||
273 | } | 299 | } |
300 | else | ||
301 | p = u->host + strcspn (u->host, ";/?"); | ||
274 | } | 302 | } |
275 | } | 303 | } |
276 | 304 | else | |
277 | /* Parse the host and port from the RHS. */ | 305 | { |
278 | p = strchr (u->host, ':'); | 306 | u->path = name; |
279 | 307 | p = u->path + strcspn (u->path, ";?"); | |
280 | if (p) | 308 | } |
309 | |||
310 | /* Either way, if we're not at a nul, we're at a path or query. */ | ||
311 | if (u->path == NULL && *p == '/') | ||
281 | { | 312 | { |
313 | /* found a path */ | ||
282 | *p++ = 0; | 314 | *p++ = 0; |
315 | u->path = p; | ||
316 | p = u->path + strcspn (u->path, ";?"); | ||
317 | } | ||
283 | 318 | ||
284 | u->port = strtol (p, &p, 10); | 319 | if (*p == ';') |
285 | 320 | { | |
286 | /* Check for garbage after the port: we should be on the start | 321 | *p++ = 0; |
287 | of a path, a query, or at the end of the string. */ | 322 | mu_argcv_get_np (p, strlen (p), ";", "?", 0, |
288 | if (*p && strcspn (p, "/?") != 0) | 323 | &u->fvcount, &u->fvpairs, &p); |
289 | return MU_ERR_PARSE; | ||
290 | } | 324 | } |
291 | else | ||
292 | p = u->host + strcspn (u->host, "/?"); | ||
293 | 325 | ||
294 | /* Either way, if we're not at a nul, we're at a path or query. */ | ||
295 | if (*p == '?') | 326 | if (*p == '?') |
296 | { | 327 | { |
297 | /* found a query */ | 328 | /* found a query */ |
298 | *p++ = 0; | 329 | *p++ = 0; |
299 | u->query = p; | 330 | u->query = p; |
300 | } | 331 | } |
301 | if (*p == '/') | ||
302 | { | ||
303 | /* found a path */ | ||
304 | *p++ = 0; | ||
305 | u->path = p; | ||
306 | } | ||
307 | 332 | ||
308 | return 0; | 333 | return 0; |
309 | } | 334 | } |
... | @@ -431,6 +456,46 @@ DECL_ACCESSORS (host) | ... | @@ -431,6 +456,46 @@ DECL_ACCESSORS (host) |
431 | DECL_ACCESSORS (path) | 456 | DECL_ACCESSORS (path) |
432 | DECL_ACCESSORS (query) | 457 | DECL_ACCESSORS (query) |
433 | 458 | ||
459 | /* field-value pairs accessors */ | ||
460 | int | ||
461 | mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp) | ||
462 | { | ||
463 | if (url == NULL) | ||
464 | return EINVAL; | ||
465 | /* FIXME: no _get_fvpairs method, but the method stuff needs to be rewritten | ||
466 | anyway */ | ||
467 | *fvc = url->fvcount; | ||
468 | *fvp = url->fvpairs; | ||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | int | ||
473 | mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp) | ||
474 | { | ||
475 | size_t fvc, i; | ||
476 | char **fvp; | ||
477 | char **fvcopy; | ||
478 | |||
479 | int rc = mu_url_sget_fvpairs (url, &fvc, &fvp); | ||
480 | if (rc) | ||
481 | return rc; | ||
482 | |||
483 | fvcopy = calloc (fvc + 1, sizeof (fvcopy[0])); | ||
484 | if (!fvcopy) | ||
485 | return errno; | ||
486 | for (i = 0; i < fvc; i++) | ||
487 | { | ||
488 | if (!(fvcopy[i] = strdup (fvp[i]))) | ||
489 | { | ||
490 | mu_argcv_free (i, fvcopy); | ||
491 | return errno; | ||
492 | } | ||
493 | } | ||
494 | fvcopy[i] = NULL; | ||
495 | *pfvc = fvc; | ||
496 | *pfvp = fvcopy; | ||
497 | return 0; | ||
498 | } | ||
434 | 499 | ||
435 | int | 500 | int |
436 | mu_url_get_port (const mu_url_t url, long *pport) | 501 | mu_url_get_port (const mu_url_t url, long *pport) |
... | @@ -572,3 +637,189 @@ mu_url_init (mu_url_t url, int port, const char *scheme) | ... | @@ -572,3 +637,189 @@ mu_url_init (mu_url_t url, int port, const char *scheme) |
572 | 637 | ||
573 | return status; | 638 | return status; |
574 | } | 639 | } |
640 | |||
641 | /* Default mailbox path generator */ | ||
642 | static char * | ||
643 | _url_path_default (const char *spooldir, const char *user, int unused) | ||
644 | { | ||
645 | char *mbox = malloc (sizeof(spooldir) + strlen(user) + 2); | ||
646 | if (!mbox) | ||
647 | errno = ENOMEM; | ||
648 | else | ||
649 | sprintf (mbox, "%s/%s", spooldir, user); | ||
650 | return mbox; | ||
651 | } | ||
652 | |||
653 | /* Hashed indexing */ | ||
654 | static char * | ||
655 | _url_path_hashed (const char *spooldir, const char *user, int param) | ||
656 | { | ||
657 | int i; | ||
658 | int ulen = strlen (user); | ||
659 | char *mbox; | ||
660 | unsigned hash; | ||
661 | |||
662 | if (param > ulen) | ||
663 | param = ulen; | ||
664 | for (i = 0, hash = 0; i < param; i++) | ||
665 | hash += user[i]; | ||
666 | |||
667 | mbox = malloc (ulen + strlen (spooldir) + 5); | ||
668 | sprintf (mbox, "%s/%02X/%s", spooldir, hash % 256, user); | ||
669 | return mbox; | ||
670 | } | ||
671 | |||
672 | static int transtab[] = { | ||
673 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', | ||
674 | 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', | ||
675 | 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', | ||
676 | 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', | ||
677 | 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', | ||
678 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', | ||
679 | 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', | ||
680 | 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', | ||
681 | 'm', 'a', 'b', 'c', 'd', 'e', 'f', 'g', | ||
682 | 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', | ||
683 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', | ||
684 | 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f', | ||
685 | 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g', | ||
686 | 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', | ||
687 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', | ||
688 | 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f', | ||
689 | 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', | ||
690 | 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', | ||
691 | 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', | ||
692 | 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', | ||
693 | 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', | ||
694 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', | ||
695 | 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', | ||
696 | 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', | ||
697 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', | ||
698 | 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', | ||
699 | 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', | ||
700 | 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g', | ||
701 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', | ||
702 | 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', | ||
703 | 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', | ||
704 | 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g' | ||
705 | }; | ||
706 | |||
707 | /* Forward Indexing */ | ||
708 | static char * | ||
709 | _url_path_index (const char *spooldir, const char *iuser, int index_depth) | ||
710 | { | ||
711 | const unsigned char* user = (const unsigned char*) iuser; | ||
712 | int i, ulen = strlen (iuser); | ||
713 | char *mbox, *p; | ||
714 | |||
715 | if (ulen == 0) | ||
716 | return NULL; | ||
717 | |||
718 | mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 2); | ||
719 | strcpy (mbox, spooldir); | ||
720 | p = mbox + strlen (mbox); | ||
721 | for (i = 0; i < index_depth && i < ulen; i++) | ||
722 | { | ||
723 | *p++ = '/'; | ||
724 | *p++ = transtab[ user[i] ]; | ||
725 | } | ||
726 | for (; i < index_depth; i++) | ||
727 | { | ||
728 | *p++ = '/'; | ||
729 | *p++ = transtab[ user[ulen-1] ]; | ||
730 | } | ||
731 | *p++ = '/'; | ||
732 | strcpy (p, iuser); | ||
733 | return mbox; | ||
734 | } | ||
735 | |||
736 | /* Reverse Indexing */ | ||
737 | static char * | ||
738 | _url_path_rev_index (const char *spooldir, const char *iuser, int index_depth) | ||
739 | { | ||
740 | const unsigned char* user = (const unsigned char*) iuser; | ||
741 | int i, ulen = strlen (iuser); | ||
742 | char *mbox, *p; | ||
743 | |||
744 | if (ulen == 0) | ||
745 | return NULL; | ||
746 | |||
747 | mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 1); | ||
748 | strcpy (mbox, spooldir); | ||
749 | p = mbox + strlen (mbox); | ||
750 | for (i = 0; i < index_depth && i < ulen; i++) | ||
751 | { | ||
752 | *p++ = '/'; | ||
753 | *p++ = transtab[ user[ulen - i - 1] ]; | ||
754 | } | ||
755 | for (; i < index_depth; i++) | ||
756 | { | ||
757 | *p++ = '/'; | ||
758 | *p++ = transtab[ user[0] ]; | ||
759 | } | ||
760 | *p++ = '/'; | ||
761 | strcpy (p, iuser); | ||
762 | return mbox; | ||
763 | } | ||
764 | |||
765 | static int | ||
766 | rmselector (const char *p, void *data MU_ARG_UNUSED) | ||
767 | { | ||
768 | return strncmp (p, "type=", 5) == 0 | ||
769 | || strncmp (p, "user=", 5) == 0 | ||
770 | || strncmp (p, "param=", 6) == 0; | ||
771 | } | ||
772 | |||
773 | int | ||
774 | mu_url_expand_path (mu_url_t url) | ||
775 | { | ||
776 | size_t i; | ||
777 | char *user = NULL; | ||
778 | int param = 0; | ||
779 | char *p; | ||
780 | char *(*fun) (const char *, const char *, int) = _url_path_default; | ||
781 | |||
782 | if (url->fvcount == 0) | ||
783 | return 0; | ||
784 | |||
785 | for (i = 0; i < url->fvcount; i++) | ||
786 | { | ||
787 | p = url->fvpairs[i]; | ||
788 | if (strncmp (p, "type=", 5) == 0) | ||
789 | { | ||
790 | char *type = p + 5; | ||
791 | |||
792 | if (strcmp (type, "hash") == 0) | ||
793 | fun = _url_path_hashed; | ||
794 | else if (strcmp (type, "index") == 0) | ||
795 | fun = _url_path_index; | ||
796 | else if (strcmp (type, "rev-index") == 0) | ||
797 | fun = _url_path_rev_index; | ||
798 | else | ||
799 | return MU_ERR_NOENT; | ||
800 | } | ||
801 | else if (strncmp (p, "user=", 5) == 0) | ||
802 | { | ||
803 | user = p + 5; | ||
804 | } | ||
805 | else if (strncmp (p, "param=", 6) == 0) | ||
806 | { | ||
807 | param = strtoul (p + 6, NULL, 0); | ||
808 | } | ||
809 | } | ||
810 | |||
811 | if (user) | ||
812 | { | ||
813 | char *p = fun (url->path, user, param); | ||
814 | if (p) | ||
815 | { | ||
816 | free (url->path); | ||
817 | url->path = p; | ||
818 | } | ||
819 | mu_argcv_remove (&url->fvcount, &url->fvpairs, rmselector, NULL); | ||
820 | } | ||
821 | else | ||
822 | return MU_ERR_NOENT; | ||
823 | |||
824 | return 0; | ||
825 | } | ... | ... |
... | @@ -24,7 +24,7 @@ static char *bulletin_db_name; | ... | @@ -24,7 +24,7 @@ static char *bulletin_db_name; |
24 | void | 24 | void |
25 | set_bulletin_db (char *file) | 25 | set_bulletin_db (char *file) |
26 | { | 26 | { |
27 | bulletin_db_name = file; | 27 | bulletin_db_name = strdup (file); |
28 | } | 28 | } |
29 | 29 | ||
30 | static void | 30 | static void |
... | @@ -67,7 +67,7 @@ open_bulletin_mailbox (mu_mailbox_t *pmbox) | ... | @@ -67,7 +67,7 @@ open_bulletin_mailbox (mu_mailbox_t *pmbox) |
67 | int | 67 | int |
68 | set_bulletin_source (char *source) | 68 | set_bulletin_source (char *source) |
69 | { | 69 | { |
70 | bulletin_mbox_name = source; | 70 | bulletin_mbox_name = strdup (source); |
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
... | @@ -145,8 +145,14 @@ read_bulletin_db (size_t *pnum) | ... | @@ -145,8 +145,14 @@ read_bulletin_db (size_t *pnum) |
145 | 145 | ||
146 | if (rc) | 146 | if (rc) |
147 | { | 147 | { |
148 | int ec = errno; | ||
149 | if (ec == ENOENT) | ||
150 | { | ||
151 | *pnum = 0; | ||
152 | return 0; | ||
153 | } | ||
148 | mu_error (_("Cannot fetch bulletin db data: %s"), | 154 | mu_error (_("Cannot fetch bulletin db data: %s"), |
149 | mu_strerror (errno)); | 155 | mu_strerror (ec)); |
150 | mu_dbm_close (db); | 156 | mu_dbm_close (db); |
151 | return 1; | 157 | return 1; |
152 | } | 158 | } |
... | @@ -236,18 +242,14 @@ write_bulletin_db (size_t num) | ... | @@ -236,18 +242,14 @@ write_bulletin_db (size_t num) |
236 | } | 242 | } |
237 | #endif /* USE_DBM */ | 243 | #endif /* USE_DBM */ |
238 | 244 | ||
239 | size_t | 245 | int |
240 | get_last_delivered_num () | 246 | get_last_delivered_num (size_t *pret) |
241 | { | 247 | { |
242 | size_t num = 0; | ||
243 | |||
244 | #ifdef USE_DBM | 248 | #ifdef USE_DBM |
245 | if (bulletin_db_name && read_bulletin_db (&num) == 0) | 249 | if (bulletin_db_name && read_bulletin_db (pret) == 0) |
246 | return num; | 250 | return 0; |
247 | #endif | 251 | #endif |
248 | 252 | return read_popbull_file (pret); | |
249 | read_popbull_file (&num); | ||
250 | return num; | ||
251 | } | 253 | } |
252 | 254 | ||
253 | void | 255 | void |
... | @@ -271,9 +273,8 @@ deliver_pending_bulletins () | ... | @@ -271,9 +273,8 @@ deliver_pending_bulletins () |
271 | return; | 273 | return; |
272 | 274 | ||
273 | rc = open_bulletin_mailbox (&bull); | 275 | rc = open_bulletin_mailbox (&bull); |
274 | if (rc) | 276 | if (rc || get_last_delivered_num (&lastnum)) |
275 | return; | 277 | return; |
276 | lastnum = get_last_delivered_num (); | ||
277 | 278 | ||
278 | rc = mu_mailbox_messages_count (bull, &total); | 279 | rc = mu_mailbox_messages_count (bull, &total); |
279 | if (rc) | 280 | if (rc) | ... | ... |
... | @@ -50,7 +50,7 @@ pop3d_capa (const char *arg) | ... | @@ -50,7 +50,7 @@ pop3d_capa (const char *arg) |
50 | 50 | ||
51 | login_delay_capa (); | 51 | login_delay_capa (); |
52 | /* This can be implemented by setting an header field on the message. */ | 52 | /* This can be implemented by setting an header field on the message. */ |
53 | if (expire < 0) | 53 | if (expire == EXPIRE_NEVER) |
54 | pop3d_outf ("EXPIRE NEVER\r\n"); | 54 | pop3d_outf ("EXPIRE NEVER\r\n"); |
55 | else | 55 | else |
56 | pop3d_outf ("EXPIRE %s\r\n", mu_umaxtostr (0, expire)); | 56 | pop3d_outf ("EXPIRE %s\r\n", mu_umaxtostr (0, expire)); | ... | ... |
-
Please register or sign in to post a comment