summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-12-28 15:27:43 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-12-28 15:27:43 +0000
commit36868ac9ddc6b4e521913858b04ace62d8edfa5a (patch)
tree1eddc5d77090130ea7d23eb6d679b403496a6ac0
parent7b123e22274933f402814d3c4e4c146a13ccffb6 (diff)
downloadmailutils-36868ac9ddc6b4e521913858b04ace62d8edfa5a.tar.gz
mailutils-36868ac9ddc6b4e521913858b04ace62d8edfa5a.tar.bz2
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.
-rw-r--r--ChangeLog74
-rw-r--r--NEWS33
-rw-r--r--TODO4
-rw-r--r--examples/url-parse.c17
-rw-r--r--include/mailutils/argcv.h8
-rw-r--r--include/mailutils/mutil.h2
-rw-r--r--include/mailutils/registrar.h8
-rw-r--r--include/mailutils/url.h10
-rw-r--r--lib/.cvsignore2
-rw-r--r--libproto/imap/folder.c5
-rw-r--r--libproto/include/amd.h1
-rw-r--r--libproto/include/registrar0.h22
-rw-r--r--libproto/include/url0.h3
-rw-r--r--libproto/maildir/folder.c28
-rw-r--r--libproto/mbox/Makefile.am3
-rw-r--r--libproto/mbox/folder.c22
-rw-r--r--libproto/mbox/url.c301
-rw-r--r--libproto/mh/folder.c26
-rw-r--r--libproto/nntp/folder.c4
-rw-r--r--m4/.cvsignore1
-rw-r--r--mail/mail.h2
-rw-r--r--mail/quit.c6
-rw-r--r--mail/summary.c2
-rw-r--r--mail/util.c15
-rw-r--r--mailbox/amd.c46
-rw-r--r--mailbox/argcv.c178
-rw-r--r--mailbox/file_stream.c2
-rw-r--r--mailbox/folder.c25
-rw-r--r--mailbox/gdebug.c2
-rw-r--r--mailbox/mailbox.c74
-rw-r--r--mailbox/mutil.c17
-rw-r--r--mailbox/registrar.c36
-rw-r--r--mailbox/testsuite/Urls37
-rw-r--r--mailbox/url.c419
-rw-r--r--pop3d/bulletin.c29
-rw-r--r--pop3d/capa.c2
36 files changed, 850 insertions, 616 deletions
diff --git a/ChangeLog b/ChangeLog
index d113738e8..8fc4359bd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,77 @@
+2007-12-28 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ 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.
+
2007-12-21 Sergey Poznyakoff <gray@gnu.org.ua>
* examples/lsf.c: Use mu_folder_enumerate + callback function, for
diff --git a/NEWS b/NEWS
index 1730f164c..634f30bad 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU mailutils NEWS -- history of user-visible changes. 2007-12-19
+GNU mailutils NEWS -- history of user-visible changes. 2007-12-28
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
See the end of file for copying conditions.
@@ -26,6 +26,11 @@ The programs using configuration file facility also understand the
output the detailed description of configuration file statements that
affect the given program.
+** URL parameters.
+
+Additional mailbox URL parameters `type', `user' and `param' can
+appear in any local URLs.
+
** New utility `maidag'
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 **);
extern int mu_url_sget_query (const mu_url_t, const char **);
extern int mu_url_aget_query (const mu_url_t, char **);
+int mu_url_sget_fvpairs (const mu_url_t, size_t *, char ***);
+int mu_url_aget_fvpairs (const mu_url_t, size_t *, char ***);
+
** ACL
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.,
appending to the URL `remote+smtp://127.0.0.1:24' is equivalent to
sending a message using mailer `smtp://127.0.0.1:24'.
+** New argcv functions.
+
+- int mu_argcv_get_np (const char *command, int len,
+ const char *delim, const char *cmnt,
+ int flags,
+ int *pargc, char ***pargv, char **endp);
+
+This function is an alternative entry point to
+mu_argcv_get/mu_argcv_get_n functions. The resulting argv will contain
+non-whitespace delimiters only if flags contains the bit
+MU_ARGCV_RETURN_DELIMS.
+
+- void mu_argcv_remove (int *pargc, char ***pargv,
+ int (*sel) (const char *, void *), void *);
+
+Removes from pargc/pargv all elements for which the sel function
+returns true.
+
+** New registry functions.
+
+- int mu_registrar_lookup_url (mu_url_t url, int flags,
+ mu_record_t *precord, int *pflags);
+
** Fixed parsing of URLs similar to file:///a/b.
It is parsed as an absolute file name `/a/b'.
diff --git a/TODO b/TODO
index 01b987335..c229b7141 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,9 @@
-GNU mailutils TODO list. 2007-12-07
+GNU mailutils TODO list. 2007-12-28
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006,
2007 Free Software Foundation, Inc.
+* Fix folder_imap_list in libproto/imap/folder.c
+
* Documentation
* Review the code and use mu_vartab_* and mu_kwd_* functions where
diff --git a/examples/url-parse.c b/examples/url-parse.c
index 2d10adecc..cc3e037a1 100644
--- a/examples/url-parse.c
+++ b/examples/url-parse.c
@@ -39,6 +39,22 @@
} \
printf ("\t" #field " <%s>\n", buf)
+static void
+print_fvpairs (mu_url_t url)
+{
+ size_t fvc, i;
+ char **fvp;
+ int rc = mu_url_sget_fvpairs (url, &fvc, &fvp);
+ if (rc)
+ {
+ mu_error ("cannot get F/V pairs: %s", mu_strerror (rc));
+ exit (1);
+ }
+ if (fvc == 0)
+ return;
+ for (i = 0; i < fvc; i++)
+ printf ("\tparam[%d] <%s>\n", i, fvp[i]);
+}
int
main ()
@@ -84,6 +100,7 @@ main ()
printf ("\tport %ld\n", port);
GET_AND_PRINT (path, u, buf, rc);
+ print_fvpairs (u);
GET_AND_PRINT (query, u, buf, rc);
mu_url_destroy (&u);
diff --git a/include/mailutils/argcv.h b/include/mailutils/argcv.h
index a880f05c3..bbae929f9 100644
--- a/include/mailutils/argcv.h
+++ b/include/mailutils/argcv.h
@@ -28,12 +28,18 @@
extern "C" {
#endif
+#define MU_ARGCV_RETURN_DELIMS 0x01
+
extern int mu_argcv_get (const char *command, const char *delim,
const char* cmnt,
int *argc, char ***argv);
extern int mu_argcv_get_n (const char *command, int len,
const char *delim, const char *cmnt,
int *argc, char ***argv);
+extern int mu_argcv_get_np (const char *command, int len,
+ const char *delim, const char *cmnt,
+ int flags,
+ int *pargc, char ***pargv, char **endp);
extern int mu_argcv_string (int argc, char **argv, char **string);
extern int mu_argcv_free (int argc, char **argv);
@@ -42,6 +48,8 @@ extern int mu_argcv_quote_char (int c);
extern size_t mu_argcv_quoted_length (const char *str, int *quote);
extern void mu_argcv_unquote_copy (char *dst, const char *src, size_t n);
extern void mu_argcv_quote_copy (char *dst, const char *src);
+extern void mu_argcv_remove (int *pargc, char ***pargv,
+ int (*sel) (const char *, void *), void *);
#ifdef __cplusplus
}
diff --git a/include/mailutils/mutil.h b/include/mailutils/mutil.h
index 6802de8cf..16765aee0 100644
--- a/include/mailutils/mutil.h
+++ b/include/mailutils/mutil.h
@@ -128,7 +128,7 @@ extern int mu_unre_subject (const char *subject, const char **new_subject);
extern char *mu_charset_lookup (char *lang, char *terr);
extern int mu_true_answer_p (const char *p);
-extern int mu_scheme_autodetect_p (const char *scheme, const char **path);
+extern int mu_scheme_autodetect_p (mu_url_t);
struct timeval;
diff --git a/include/mailutils/registrar.h b/include/mailutils/registrar.h
index 03836b85e..ecc904d32 100644
--- a/include/mailutils/registrar.h
+++ b/include/mailutils/registrar.h
@@ -38,7 +38,7 @@ struct _mu_record
void *data; /* back pointer. */
/* Stub functions to override. The default is to return the fields. */
- int (*_is_scheme) (mu_record_t, const char *, int);
+ int (*_is_scheme) (mu_record_t, mu_url_t, int);
int (*_get_url) (mu_record_t, int (*(*_mu_url)) (mu_url_t));
int (*_get_mailbox) (mu_record_t, int (*(*_mu_mailbox)) (mu_mailbox_t));
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));
extern int mu_registrar_lookup (const char *name, int flags,
mu_record_t *precord, int *pflags);
+extern int mu_registrar_lookup_url (mu_url_t url, int flags,
+ mu_record_t *precord, int *pflags);
extern int mu_registrar_record (mu_record_t);
extern int mu_unregistrar_record (mu_record_t);
/* Scheme. */
-extern int mu_record_is_scheme (mu_record_t, const char *, int flags);
+extern int mu_record_is_scheme (mu_record_t, mu_url_t, int flags);
extern int mu_record_set_scheme (mu_record_t, const char *);
extern int mu_record_set_is_scheme (mu_record_t,
- int (*_is_scheme) (mu_record_t, const char *, int));
+ int (*_is_scheme) (mu_record_t, mu_url_t, int));
/* Url. */
extern int mu_record_get_url (mu_record_t, int (*(*)) (mu_url_t));
diff --git a/include/mailutils/url.h b/include/mailutils/url.h
index 69985f175..52a42264a 100644
--- a/include/mailutils/url.h
+++ b/include/mailutils/url.h
@@ -59,9 +59,13 @@ extern int mu_url_get_query (const mu_url_t, char *, size_t, size_t *);
extern int mu_url_get_port (const mu_url_t, long *);
+int mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp);
+int mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp);
+
+extern int mu_url_expand_path (mu_url_t url);
extern const char *mu_url_to_string (const mu_url_t);
-extern int mu_url_is_scheme (mu_url_t, const char* scheme);
+extern int mu_url_is_scheme (mu_url_t, const char *scheme);
extern int mu_url_is_same_scheme (mu_url_t, mu_url_t);
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);
extern int mu_url_is_same_host (mu_url_t, mu_url_t);
extern int mu_url_is_same_port (mu_url_t, mu_url_t);
-extern char* mu_url_decode (const char *s);
+extern char *mu_url_decode (const char *s);
extern int mu_url_is_ticket (mu_url_t ticket, mu_url_t url);
extern int mu_url_init (mu_url_t url, int port, const char *scheme);
-
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/.cvsignore b/lib/.cvsignore
index 494fca35f..b01887cc1 100644
--- a/lib/.cvsignore
+++ b/lib/.cvsignore
@@ -143,6 +143,8 @@ streq.h
strerror.c
string.h
string.in.h
+strings.h
+strings.in.h
stripslash.c
strncasecmp.c
strndup.c
diff --git a/libproto/imap/folder.c b/libproto/imap/folder.c
index 815b4ecfe..d718a4d3d 100644
--- a/libproto/imap/folder.c
+++ b/libproto/imap/folder.c
@@ -112,7 +112,7 @@ static int folder_imap_close (mu_folder_t);
static void folder_imap_destroy (mu_folder_t);
static int folder_imap_delete (mu_folder_t, const char *);
static int folder_imap_list (mu_folder_t, const char *, void *,
- size_t,
+ int, size_t,
mu_list_t,
mu_folder_enumerate_fp efp, void *edp);
static int folder_imap_lsub (mu_folder_t, const char *, const char *,
@@ -975,9 +975,10 @@ glob_to_imap (const char *pat, int recursive)
return ret;
}
+/* FIXME: Flags unused */
static int
folder_imap_list (mu_folder_t folder, const char *ref, void *name,
- size_t max_level,
+ int flags, size_t max_level,
mu_list_t flist,
mu_folder_enumerate_fp efp, void *edp)
{
diff --git a/libproto/include/amd.h b/libproto/include/amd.h
index 505b48df6..3c9c5ab94 100644
--- a/libproto/include/amd.h
+++ b/libproto/include/amd.h
@@ -99,7 +99,6 @@ int _amd_message_insert (struct _amd_data *mhd, struct _amd_message *msg);
int amd_message_stream_open (struct _amd_message *mhm);
void amd_message_stream_close (struct _amd_message *mhm);
void amd_cleanup (void *arg);
-int amd_url_init (mu_url_t url, const char *scheme);
struct _amd_message *_amd_get_message (struct _amd_data *amd, size_t msgno);
int amd_msg_lookup (struct _amd_data *amd, struct _amd_message *msg,
size_t *pret);
diff --git a/libproto/include/registrar0.h b/libproto/include/registrar0.h
index 571c8a5fb..13d114cf8 100644
--- a/libproto/include/registrar0.h
+++ b/libproto/include/registrar0.h
@@ -36,62 +36,60 @@ extern "C" {
Perhaps they can be changed?
*/
#define MU_POP_PORT 110
-#define MU_POP_SCHEME "pop://"
+#define MU_POP_SCHEME "pop"
#define MU_POP_SCHEME_LEN (sizeof (MU_POP_SCHEME) - 1)
extern int _url_pop_init (mu_url_t);
extern int _mailbox_pop_init (mu_mailbox_t);
extern int _folder_pop_init (mu_folder_t);
#define MU_POPS_PORT 995
-#define MU_POPS_SCHEME "pops://"
+#define MU_POPS_SCHEME "pops"
#define MU_POPS_SCHEME_LEN (sizeof (MU_POPS_SCHEME) - 1)
extern int _url_pops_init (mu_url_t);
extern int _mailbox_pops_init (mu_mailbox_t);
#define MU_IMAP_PORT 143
-#define MU_IMAP_SCHEME "imap://"
+#define MU_IMAP_SCHEME "imap"
#define MU_IMAP_SCHEME_LEN (sizeof (MU_IMAP_SCHEME) - 1)
extern int _url_imap_init (mu_url_t);
extern int _mailbox_imap_init (mu_mailbox_t);
extern int _folder_imap_init (mu_folder_t);
#define MU_IMAPS_PORT 993
-#define MU_IMAPS_SCHEME "imaps://"
+#define MU_IMAPS_SCHEME "imaps"
#define MU_IMAPS_SCHEME_LEN (sizeof (MU_IMAPS_SCHEME) - 1)
extern int _url_imaps_init (mu_url_t);
extern int _mailbox_imaps_init (mu_mailbox_t);
-#define MU_MBOX_SCHEME "mbox:"
+#define MU_MBOX_SCHEME "mbox"
#define MU_MBOX_SCHEME_LEN (sizeof (MU_MBOX_SCHEME) - 1)
-extern int _url_mbox_init (mu_url_t);
extern int _mailbox_mbox_init (mu_mailbox_t);
extern int _folder_mbox_init (mu_folder_t);
-#define MU_FILE_SCHEME "file:"
+#define MU_FILE_SCHEME "file"
#define MU_FILE_SCHEME_LEN (sizeof (MU_FILE_SCHEME) - 1)
#define MU_PATH_SCHEME "/"
#define MU_PATH_SCHEME_LEN (sizeof (MU_PATH_SCHEME) - 1)
-extern int _url_path_init (mu_url_t);
extern int _mailbox_path_init (mu_mailbox_t);
extern int _folder_path_init (mu_folder_t);
-#define MU_SMTP_SCHEME "smtp://"
+#define MU_SMTP_SCHEME "smtp"
#define MU_SMTP_SCHEME_LEN (sizeof (MU_SMTP_SCHEME) - 1)
#define MU_SMTP_PORT 25
extern int _url_smtp_init (mu_url_t);
extern int _mailer_smtp_init (mu_mailer_t);
-#define MU_SENDMAIL_SCHEME "sendmail:"
+#define MU_SENDMAIL_SCHEME "sendmail"
#define MU_SENDMAIL_SCHEME_LEN (sizeof (MU_SENDMAIL_SCHEME) - 1)
extern int _url_sendmail_init (mu_url_t);
extern int _mailer_sendmail_init (mu_mailer_t);
-#define MU_MH_SCHEME "mh:"
+#define MU_MH_SCHEME "mh"
#define MU_MH_SCHEME_LEN (sizeof (MU_MH_SCHEME) - 1)
extern int _mailbox_mh_init (mu_mailbox_t mailbox);
-#define MU_MAILDIR_SCHEME "maildir:"
+#define MU_MAILDIR_SCHEME "maildir"
#define MU_MAILDIR_SCHEME_LEN (sizeof (MU_MAILDIR_SCHEME) - 1)
extern int _mailbox_maildir_init (mu_mailbox_t mailbox);
diff --git a/libproto/include/url0.h b/libproto/include/url0.h
index f4cc8af81..a2485e4e0 100644
--- a/libproto/include/url0.h
+++ b/libproto/include/url0.h
@@ -40,9 +40,10 @@ struct _mu_url
char *host;
long port;
char *path;
+ char **fvpairs;
+ int fvcount;
char *query;
-
void *data;
void (*_destroy) (mu_url_t url);
diff --git a/libproto/maildir/folder.c b/libproto/maildir/folder.c
index 3fe14d76e..cc91b32d8 100644
--- a/libproto/maildir/folder.c
+++ b/libproto/maildir/folder.c
@@ -33,6 +33,7 @@
#include <maildir.h>
#include <mailutils/mutil.h>
+#include <mailutils/url.h>
#include <amd.h>
static int
@@ -56,22 +57,21 @@ dir_exists (const char *name, const char *suf)
}
static int
-_maildir_is_scheme (mu_record_t record, const char *url, int flags)
+_maildir_is_scheme (mu_record_t record, mu_url_t url, int flags)
{
- const char *path;
-
- if (!url || !record->scheme)
- return 0;
-
- if (strncmp (record->scheme, url, strlen (record->scheme)) == 0)
+ if (mu_url_is_scheme (url, record->scheme))
return MU_FOLDER_ATTRIBUTE_ALL & flags;
- if (mu_scheme_autodetect_p (url, &path))
+ if (mu_scheme_autodetect_p (url))
{
/* Attemp auto-detection */
+ const char *path;
struct stat st;
int rc = 0;
+ if (mu_url_sget_path (url, &path))
+ return 0;
+
if (stat (path, &st) < 0)
return 0;
@@ -89,21 +89,11 @@ _maildir_is_scheme (mu_record_t record, const char *url, int flags)
return 0;
}
-/*
- MAILDIR url
- maildir:path
-*/
-int
-_maildir_url_init (mu_url_t url)
-{
- return amd_url_init (url, MU_MAILDIR_SCHEME);
-}
-
static struct _mu_record _maildir_record =
{
MU_MAILDIR_PRIO,
MU_MAILDIR_SCHEME,
- _maildir_url_init, /* Url init. */
+ mu_url_expand_path, /* Url init. */
_mailbox_maildir_init, /* Mailbox init. */
NULL, /* Mailer init. */
_maildir_folder_init, /* Folder init. */
diff --git a/libproto/mbox/Makefile.am b/libproto/mbox/Makefile.am
index 48a7fd2ef..8bc7290d2 100644
--- a/libproto/mbox/Makefile.am
+++ b/libproto/mbox/Makefile.am
@@ -26,6 +26,5 @@ libmu_mbox_la_SOURCES = \
folder.c\
mbox.c\
mboxscan.c\
- mbox0.h\
- url.c
+ mbox0.h
diff --git a/libproto/mbox/folder.c b/libproto/mbox/folder.c
index 7e8354949..cf23178f3 100644
--- a/libproto/mbox/folder.c
+++ b/libproto/mbox/folder.c
@@ -50,7 +50,7 @@ static struct _mu_record _mbox_record =
{
MU_MBOX_PRIO,
MU_MBOX_SCHEME,
- _url_mbox_init, /* Mailbox init. */
+ mu_url_expand_path, /* URL init. */
_mailbox_mbox_init, /* Mailbox init. */
NULL, /* Mailer init. */
_folder_mbox_init, /* Folder init. */
@@ -64,19 +64,18 @@ static struct _mu_record _mbox_record =
mu_record_t mu_mbox_record = &_mbox_record;
static int
-_path_is_scheme (mu_record_t record, const char *url, int flags)
+_path_is_scheme (mu_record_t record, mu_url_t url, int flags)
{
int rc = 0;
- const char *path;
if (url && record->scheme)
{
- if (mu_scheme_autodetect_p (url, &path))
- /* implies:
- if (strncmp (record->scheme, url, strlen(record->scheme)) == 0) */
+ if (mu_scheme_autodetect_p (url))
{
struct stat st;
-
+ const char *path;
+
+ mu_url_sget_path (url, &path);
if (stat (path, &st) < 0)
{
if (errno == ENOENT)
@@ -92,6 +91,10 @@ _path_is_scheme (mu_record_t record, const char *url, int flags)
}
else if (flags & MU_FOLDER_ATTRIBUTE_FILE)
{
+#if 0
+ /* This effectively sieves out all non-mailbox files,
+ but it makes mu_folder_enumerate crawl, which is
+ intolerable for imap4d LIST command. */
int fd = open (path, O_RDONLY);
if (fd != -1)
{
@@ -101,6 +104,9 @@ _path_is_scheme (mu_record_t record, const char *url, int flags)
rc |= MU_FOLDER_ATTRIBUTE_FILE;
close (fd);
}
+#else
+ rc |= MU_FOLDER_ATTRIBUTE_FILE;
+#endif
}
}
@@ -116,7 +122,7 @@ static struct _mu_record _path_record =
{
MU_PATH_PRIO,
MU_PATH_SCHEME,
- _url_path_init, /* Mailbox init. */
+ NULL, /* URL init. */
_mailbox_mbox_init, /* Mailbox init. */
NULL, /* Mailer init. */
_folder_mbox_init, /* Folder init. */
diff --git a/libproto/mbox/url.c b/libproto/mbox/url.c
deleted file mode 100644
index 6841e13a2..000000000
--- a/libproto/mbox/url.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/* GNU Mailutils -- a suite of utilities for electronic mail
- Copyright (C) 1999, 2000, 2003, 2007 Free Software Foundation, Inc.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General
- Public License along with this library; if not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
-#include <registrar0.h>
-#include <url0.h>
-#include <mailutils/errno.h>
-#include <mailutils/mutil.h>
-
-static void url_mbox_destroy (mu_url_t purl);
-
-static void
-url_mbox_destroy (mu_url_t url MU_ARG_UNUSED)
-{
-}
-
-/* Default mailbox path generator */
-static char *
-_url_path_default (const char *spooldir, const char *user, int unused)
-{
- char *mbox = malloc (sizeof(spooldir) + strlen(user) + 2);
- if (!mbox)
- errno = ENOMEM;
- else
- sprintf (mbox, "%s/%s", spooldir, user);
- return mbox;
-}
-
-/* Hashed indexing */
-static char *
-_url_path_hashed (const char *spooldir, const char *user, int param)
-{
- int i;
- int ulen = strlen (user);
- char *mbox;
- unsigned hash;
-
- if (param > ulen)
- param = ulen;
- for (i = 0, hash = 0; i < param; i++)
- hash += user[i];
-
- mbox = malloc (ulen + strlen (spooldir) + 5);
- sprintf (mbox, "%s/%02X/%s", spooldir, hash % 256, user);
- return mbox;
-}
-
-static int transtab[] = {
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
- 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
- 'm', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
- 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
- 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f',
- 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
- 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
- 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f',
- 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
- 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
- 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
- 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
- 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
- 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e',
- 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
- 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
- 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g'
-};
-
-/* Forward Indexing */
-static char *
-_url_path_index (const char *spooldir, const char *iuser, int index_depth)
-{
- const unsigned char* user = (const unsigned char*) iuser;
- int i, ulen = strlen (iuser);
- char *mbox, *p;
-
- if (ulen == 0)
- return NULL;
-
- mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 2);
- strcpy (mbox, spooldir);
- p = mbox + strlen (mbox);
- for (i = 0; i < index_depth && i < ulen; i++)
- {
- *p++ = '/';
- *p++ = transtab[ user[i] ];
- }
- for (; i < index_depth; i++)
- {
- *p++ = '/';
- *p++ = transtab[ user[ulen-1] ];
- }
- *p++ = '/';
- strcpy (p, iuser);
- return mbox;
-}
-
-/* Reverse Indexing */
-static char *
-_url_path_rev_index (const char *spooldir, const char *iuser, int index_depth)
-{
- const unsigned char* user = (const unsigned char*) iuser;
- int i, ulen = strlen (iuser);
- char *mbox, *p;
-
- if (ulen == 0)
- return NULL;
-
- mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 1);
- strcpy (mbox, spooldir);
- p = mbox + strlen (mbox);
- for (i = 0; i < index_depth && i < ulen; i++)
- {
- *p++ = '/';
- *p++ = transtab[ user[ulen - i - 1] ];
- }
- for (; i < index_depth; i++)
- {
- *p++ = '/';
- *p++ = transtab[ user[0] ];
- }
- *p++ = '/';
- strcpy (p, iuser);
- return mbox;
-}
-
-/*
- UNIX Mbox
- mbox:path[;type=TYPE][;param=PARAM][;user=USERNAME]
-*/
-int
-_url_mbox_init (mu_url_t url)
-{
- const char *name = mu_url_to_string (url);
- size_t len = strlen (name);
- char *p;
-
- /* reject the obvious */
- if (name == NULL || strncmp (MU_MBOX_SCHEME, name, MU_MBOX_SCHEME_LEN) != 0
- || len < (MU_MBOX_SCHEME_LEN + 1) /* (scheme)+1+(path)*/)
- return EINVAL;
-
- /* do I need to decode url encoding '% hex hex' ? */
-
- /* TYPE */
- url->_destroy = url_mbox_destroy;
-
- /* SCHEME */
- url->scheme = strdup (MU_MBOX_SCHEME);
- if (url->scheme == NULL)
- {
- url_mbox_destroy (url);
- return ENOMEM;
- }
-
- /* PATH */
- name += MU_MBOX_SCHEME_LEN; /* pass the scheme */
- url->path = strdup (name);
- if (url->path == NULL)
- {
- url_mbox_destroy (url);
- return ENOMEM;
- }
- p = strchr (url->path, ';');
- if (p)
- {
- char *(*fun)() = _url_path_default;
- char *user = NULL;
- int param = 0;
-
- *p++ = 0;
- while (p)
- {
- char *q = strchr (p, ';');
- if (q)
- *q++ = 0;
- if (strncasecmp (p, "type=", 5) == 0)
- {
- char *type = p + 5;
-
- if (strcmp (type, "hash") == 0)
- fun = _url_path_hashed;
- else if (strcmp (type, "index") == 0)
- fun = _url_path_index;
- else if (strcmp (type, "rev-index") == 0)
- fun = _url_path_rev_index;
- else
- {
- url_mbox_destroy (url);
- return MU_ERR_NOENT;
- }
- }
- else if (strncasecmp (p, "user=", 5) == 0)
- {
- user = p + 5;
- }
- else if (strncasecmp (p, "param=", 6) == 0)
- {
- param = strtoul (p+6, NULL, 0);
- }
- p = q;
- }
-
- if (user)
- {
- p = fun (url->path, user, param);
- free (url->path);
- url->path = p;
- }
- else
- {
- url_mbox_destroy (url);
- return MU_ERR_NOENT;
- }
- }
-
- return 0;
-}
-
-static void
-url_path_destroy (mu_url_t url MU_ARG_UNUSED)
-{
-}
-
-int
-_url_path_init (mu_url_t url)
-{
- const char *name = mu_url_to_string (url);
- const char *path;
-
- /* reject the obvious */
- if (name == NULL || *name == '\0')
- return EINVAL;
-
- mu_scheme_autodetect_p (name, &path);
- name = strdup (path);
- free (url->name);
- url->name = (char*) name;
-
- /* TYPE */
- url->_destroy = url_path_destroy;
-
- /* SCHEME */
- url->scheme = strdup (MU_PATH_SCHEME);
- if (url->scheme == NULL)
- {
- url_path_destroy (url);
- return ENOMEM;
- }
-
- /* PATH */
- url->path = strdup (name);
- if (url->path == NULL)
- {
- url_path_destroy (url);
- return ENOMEM;
- }
-
- return 0;
-}
diff --git a/libproto/mh/folder.c b/libproto/mh/folder.c
index a54bda2fc..7d7f7b1c7 100644
--- a/libproto/mh/folder.c
+++ b/libproto/mh/folder.c
@@ -88,22 +88,22 @@ mh_dir_p (const char *name)
}
static int
-_mh_is_scheme (mu_record_t record, const char *url, int flags)
+_mh_is_scheme (mu_record_t record, mu_url_t url, int flags)
{
- const char *path;
int rc = 0;
- if (!url || !record->scheme)
- return 0;
-
- if (strncmp (record->scheme, url, strlen (record->scheme)) == 0)
+ if (mu_url_is_scheme (url, record->scheme))
return MU_FOLDER_ATTRIBUTE_ALL & flags;
- if (mu_scheme_autodetect_p (url, &path))
+ if (mu_scheme_autodetect_p (url))
{
/* Attemp auto-detection */
+ const char *path;
struct stat st;
+ if (mu_url_sget_path (url, &path))
+ return 0;
+
if (stat (path, &st) < 0)
return 0; /* mu_mailbox_open will complain*/
@@ -119,21 +119,11 @@ _mh_is_scheme (mu_record_t record, const char *url, int flags)
return 0;
}
-/*
- MH url
- mh:path
-*/
-static int
-_mh_url_init (mu_url_t url)
-{
- return amd_url_init (url, MU_MH_SCHEME);
-}
-
static struct _mu_record _mh_record =
{
MU_MH_PRIO,
MU_MH_SCHEME,
- _mh_url_init, /* Url init. */
+ mu_url_expand_path, /* Url init. */
_mailbox_mh_init, /* Mailbox init. */
NULL, /* Mailer init. */
_mh_folder_init, /* Folder init. */
diff --git a/libproto/nntp/folder.c b/libproto/nntp/folder.c
index e3a70aa80..55d69ed60 100644
--- a/libproto/nntp/folder.c
+++ b/libproto/nntp/folder.c
@@ -63,7 +63,7 @@ static int nntp_folder_open (mu_folder_t, int);
static int nntp_folder_close (mu_folder_t);
static void nntp_folder_destroy (mu_folder_t folder);
static int nntp_folder_list (mu_folder_t folder, const char *ref,
- void *name,
+ void *name, int flags,
size_t max,
mu_list_t flist,
mu_folder_enumerate_fp efp, void *edp);
@@ -186,7 +186,7 @@ nntp_folder_destroy (mu_folder_t folder)
static int
-nntp_folder_list (mu_folder_t folder, const char *ref, void *pat,
+nntp_folder_list (mu_folder_t folder, const char *ref, void *pat, int flags,
size_t max_level, mu_list_t flist,
mu_folder_enumerate_fp efp, void *edp)
{
diff --git a/m4/.cvsignore b/m4/.cvsignore
index 8b0dd4b11..7c968a538 100644
--- a/m4/.cvsignore
+++ b/m4/.cvsignore
@@ -84,6 +84,7 @@ strchrnul.m4
strdup.m4
strerror.m4
string_h.m4
+strings_h.m4
strndup.m4
strnlen.m4
strtok_r.m4
diff --git a/mail/mail.h b/mail/mail.h
index 86c20c472..704904eec 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -373,6 +373,8 @@ void util_rfc2047_decode (char **value);
void util_mark_read (mu_message_t msg);
+const char *util_url_to_string (mu_url_t url);
+
int is_address_field (const char *name);
extern int ml_got_interrupt (void);
diff --git a/mail/quit.c b/mail/quit.c
index 38476db20..94e0d04fe 100644
--- a/mail/quit.c
+++ b/mail/quit.c
@@ -55,7 +55,7 @@ mail_mbox_close ()
ngettext ("Held %d message in %s\n",
"Held %d messages in %s\n",
held_count),
- held_count, mu_url_to_string (url));
+ held_count, util_url_to_string (url));
mu_mailbox_close (mbox);
mu_mailbox_destroy (&mbox);
return 0;
@@ -75,7 +75,7 @@ mail_mbox_commit ()
int is_user_mbox;
mu_mailbox_get_url (mbox, &url);
- is_user_mbox = strcmp (mu_url_to_string (url), getenv ("MBOX")) == 0;
+ is_user_mbox = strcmp (util_url_to_string (url), getenv ("MBOX")) == 0;
{
mu_mailbox_t mb;
@@ -151,7 +151,7 @@ mail_mbox_commit ()
ngettext ("Saved %d message in %s\n",
"Saved %d messages in %s\n",
saved_count),
- saved_count, mu_url_to_string (u));
+ saved_count, util_url_to_string (u));
mu_mailbox_close (dest_mbox);
mu_mailbox_destroy (&dest_mbox);
}
diff --git a/mail/summary.c b/mail/summary.c
index ab0b73dae..e56910498 100644
--- a/mail/summary.c
+++ b/mail/summary.c
@@ -61,7 +61,7 @@ mail_summary (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
{
mu_url_t url = NULL;
mu_mailbox_get_url (mbox, &url);
- printf("\"%s\": ", mu_url_to_string (url));
+ printf("\"%s\": ", util_url_to_string (url));
}
printf (ngettext ("%d message", "%d messages", count), count);
if (mnew > 0)
diff --git a/mail/util.c b/mail/util.c
index 8af140848..108b6b15d 100644
--- a/mail/util.c
+++ b/mail/util.c
@@ -1460,3 +1460,18 @@ util_rfc2047_decode (char **value)
}
}
+const char *
+util_url_to_string (mu_url_t url)
+{
+ const char *scheme;
+ if (mu_url_sget_scheme (url, &scheme) == 0)
+ {
+ if (strcmp (scheme, "file") == 0 || strcmp (scheme, "mbox") == 0)
+ {
+ const char *path;
+ if (mu_url_sget_path (url, &path) == 0)
+ return path;
+ }
+ }
+ return mu_url_to_string (url);
+}
diff --git a/mailbox/amd.c b/mailbox/amd.c
index aa76b2784..cd46a43dd 100644
--- a/mailbox/amd.c
+++ b/mailbox/amd.c
@@ -1531,50 +1531,4 @@ amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, size_t *psiz
return 0;
}
-static void
-amd_url_destroy (mu_url_t url MU_ARG_UNUSED)
-{
-}
-
-int
-amd_url_init (mu_url_t url, const char *scheme)
-{
- const char *name = mu_url_to_string (url);
- const char *path_ptr = name;
- size_t len = strlen (name);
- size_t scheme_len = strlen (scheme);
-
- if (!name)
- return 0;
-
- if (mu_scheme_autodetect_p (name, &path_ptr))
- /* nothing */ ;
- /* reject the obvious */
- else if (strncmp (scheme, name, scheme_len) != 0
- || len < scheme_len + 1)
- return EINVAL;
- else
- path_ptr = name + scheme_len;
-
- /* TYPE */
- url->_destroy = amd_url_destroy;
-
- /* SCHEME */
- url->scheme = strdup (scheme);
- if (url->scheme == NULL)
- {
- amd_url_destroy (url);
- return ENOMEM;
- }
-
- /* PATH */
- url->path = strdup (path_ptr);
- if (url->path == NULL)
- {
- amd_url_destroy (url);
- return ENOMEM;
- }
-
- return 0;
-}
diff --git a/mailbox/argcv.c b/mailbox/argcv.c
index ba6a1b029..576d2c5bc 100644
--- a/mailbox/argcv.c
+++ b/mailbox/argcv.c
@@ -28,6 +28,7 @@
/* Keep mailutils namespace clean */
#define argcv_get mu_argcv_get
#define argcv_get_n mu_argcv_get_n
+#define argcv_get_np mu_argcv_get_np
#define argcv_string mu_argcv_string
#define argcv_free mu_argcv_free
#define argcv_unquote_char mu_argcv_unquote_char
@@ -47,15 +48,45 @@
#define isws(c) ((c)==' '||(c)=='\t'||(c)=='\n')
#define isdelim(c,delim) (strchr(delim,(c))!=NULL)
+struct argcv_info
+{
+ int len;
+ const char *command;
+ const char *delim;
+ const char *comment;
+ int flags;
+
+ int start;
+ int end;
+ int save;
+ int finish_pos;
+};
+
+static void
+init_argcv_info (struct argcv_info *ap, int flags,
+ int len, const char *command, const char *delim,
+ const char *comment)
+{
+ memset (ap, 0, sizeof *ap);
+ ap->len = len;
+ ap->command = command;
+ ap->delim = delim;
+ ap->comment = comment;
+ ap->flags = flags;
+}
+
static int
-argcv_scan (int len, const char *command, const char *delim, const char* cmnt,
- int *start, int *end, int *save)
+argcv_scan (struct argcv_info *ap)
{
int i = 0;
+ int len = ap->len;
+ const char *command = ap->command;
+ const char *delim = ap->delim;
+ const char *comment = ap->comment;
for (;;)
{
- i = *save;
+ i = ap->save;
if (i >= len)
return i + 1;
@@ -63,7 +94,7 @@ argcv_scan (int len, const char *command, const char *delim, const char* cmnt,
/* Skip initial whitespace */
while (i < len && isws (command[i]))
i++;
- *start = i;
+ ap->start = i;
if (!isdelim (command[i], delim))
{
@@ -80,11 +111,11 @@ argcv_scan (int len, const char *command, const char *delim, const char* cmnt,
if (command[i] == '\'' || command[i] == '"')
{
int j;
- for (j = i+1; j < len && command[j] != command[i]; j++)
+ for (j = i + 1; j < len && command[j] != command[i]; j++)
if (command[j] == '\\')
j++;
if (j < len)
- i = j+1;
+ i = j + 1;
else
i++;
}
@@ -95,27 +126,36 @@ argcv_scan (int len, const char *command, const char *delim, const char* cmnt,
}
i--;
}
+ else if (!(ap->flags & MU_ARGCV_RETURN_DELIMS))
+ {
+ while (i < len && isdelim (command[i], delim))
+ i++;
+ ap->save = i;
+ continue;
+ }
+
- *end = i;
- *save = i + 1;
+ ap->end = i;
+ ap->save = ap->finish_pos = i + 1;
/* If we have a token, and it starts with a comment character, skip
to the newline and restart the token search. */
- if (*save <= len)
+ if (ap->save <= len)
{
- if (strchr (cmnt, command[*start]) != NULL)
+ if (strchr (comment, command[ap->start]) != NULL)
{
- i = *save;
+ ap->finish_pos = ap->start;
+ i = ap->save;
while (i < len && command[i] != '\n')
i++;
- *save = i;
+ ap->save = i;
continue;
}
}
break;
}
- return *save;
+ return ap->save;
}
static char quote_transtab[] = "\\\\a\ab\bf\fn\nr\rt\t";
@@ -312,67 +352,85 @@ argcv_quote_copy (char *dst, const char *src)
}
int
-argcv_get_n (const char *command, int len, const char *delim, const char *cmnt,
- int *argc, char ***argv)
+argcv_get_np (const char *command, int len,
+ const char *delim, const char *cmnt,
+ int flags,
+ int *pargc, char ***pargv, char **endp)
{
int i = 0;
- int start, end, save;
-
- *argv = NULL;
-
- /* Count number of arguments */
- *argc = 0;
- save = 0;
-
+ struct argcv_info info;
+ int argc;
+ char **argv;
+
if (!delim)
delim = "";
if (!cmnt)
cmnt = "";
-
- while (argcv_scan (len, command, delim, cmnt, &start, &end, &save) <= len)
- (*argc)++;
- *argv = calloc ((*argc + 1), sizeof (char *));
- if (*argv == NULL)
+ init_argcv_info (&info, flags, len, command, delim, cmnt);
+
+ /* Count number of arguments */
+ argc = 0;
+ while (argcv_scan (&info) <= len)
+ argc++;
+
+ argv = calloc ((argc + 1), sizeof (char *));
+ if (argv == NULL)
return ENOMEM;
i = 0;
- save = 0;
- for (i = 0; i < *argc; i++)
+ info.save = 0;
+ for (i = 0; i < argc; i++)
{
int n;
int unquote;
- argcv_scan (len, command, delim, cmnt, &start, &end, &save);
+ argcv_scan (&info);
- if ((command[start] == '"' || command[end] == '\'')
- && command[end] == command[start])
+ if ((command[info.start] == '"' || command[info.end] == '\'')
+ && command[info.end] == command[info.start])
{
- if (start < end)
+ if (info.start < info.end)
{
- start++;
- end--;
+ info.start++;
+ info.end--;
}
unquote = 0;
}
else
unquote = 1;
- n = end - start + 1;
- (*argv)[i] = calloc (n+1, sizeof (char));
- if ((*argv)[i] == NULL)
- return ENOMEM;
+ n = info.end - info.start + 1;
+ argv[i] = calloc (n + 1, sizeof (char));
+ if (argv[i] == NULL)
+ {
+ argcv_free (i, argv);
+ return ENOMEM;
+ }
if (unquote)
- argcv_unquote_copy ((*argv)[i], &command[start], n);
+ argcv_unquote_copy (argv[i], &command[info.start], n);
else
- memcpy ((*argv)[i], &command[start], n);
- (*argv)[i][n] = 0;
+ memcpy (argv[i], &command[info.start], n);
+ argv[i][n] = 0;
}
- (*argv)[i] = NULL;
+ argv[i] = NULL;
+
+ *pargc = argc;
+ *pargv = argv;
+ if (endp)
+ *endp = (char*) (command + info.finish_pos);
return 0;
}
int
+argcv_get_n (const char *command, int len, const char *delim, const char *cmnt,
+ int *pargc, char ***pargv)
+{
+ return argcv_get_np (command, len, delim, cmnt, MU_ARGCV_RETURN_DELIMS,
+ pargc, pargv, NULL);
+}
+
+int
argcv_get (const char *command, const char *delim, const char *cmnt,
int *argc, char ***argv)
{
@@ -445,3 +503,35 @@ argcv_string (int argc, char **argv, char **pstring)
return 0;
}
+void
+mu_argcv_remove (int *pargc, char ***pargv,
+ int (*sel) (const char *, void *), void *data)
+{
+ int i, j;
+ int argc = *pargc;
+ char **argv = *pargv;
+ int cnt = 0;
+
+ for (i = j = 0; i < argc; i++)
+ {
+ if (sel (argv[i], data))
+ {
+ free (argv[i]);
+ cnt++;
+ }
+ else
+ {
+ if (i != j)
+ argv[j] = argv[i];
+ j++;
+ }
+ }
+ if (i != j)
+ argv[j] = NULL;
+ argc -= cnt;
+
+ *pargc = argc;
+ *pargv = argv;
+}
+
+
diff --git a/mailbox/file_stream.c b/mailbox/file_stream.c
index 82511c60b..47ff5d9dc 100644
--- a/mailbox/file_stream.c
+++ b/mailbox/file_stream.c
@@ -677,7 +677,7 @@ struct _prog_stream
pid_t pid;
int status;
pid_t writer_pid;
- size_t argc;
+ int argc;
char **argv;
mu_stream_t in, out;
diff --git a/mailbox/folder.c b/mailbox/folder.c
index ac87abf9d..44cbcc31f 100644
--- a/mailbox/folder.c
+++ b/mailbox/folder.c
@@ -73,22 +73,37 @@ mu_folder_create_from_record (mu_folder_t *pfolder, const char *name,
== 0)
{
int (*f_init) (mu_folder_t) = NULL;
- int (*u_init) (mu_url_t) = NULL;
mu_record_get_folder (record, &f_init);
- mu_record_get_url (record, &u_init);
- if (f_init && u_init)
+ if (f_init)
{
int status;
mu_url_t url;
mu_folder_t folder;
+ int (*u_init) (mu_url_t) = NULL;
/* Parse the url, it may be a bad one and we should bailout if this
failed. */
- if ((status = mu_url_create (&url, name) != 0)
- || (status = u_init (url)) != 0)
+ if ((status = mu_url_create (&url, name)) != 0)
return status;
+ status = mu_url_parse (url);
+ if (status)
+ {
+ mu_url_destroy (url);
+ return status;
+ }
+ mu_record_get_url (record, &u_init);
+ if (u_init)
+ {
+ status = u_init (url);
+ if (status)
+ {
+ mu_url_destroy (url);
+ return status;
+ }
+ }
+
mu_monitor_wrlock (&folder_lock);
/* Check if we already have the same URL folder. */
diff --git a/mailbox/gdebug.c b/mailbox/gdebug.c
index af60fc2e1..f35377970 100644
--- a/mailbox/gdebug.c
+++ b/mailbox/gdebug.c
@@ -165,7 +165,7 @@ int
mu_global_debug_from_string (const char *string, const char *errpfx)
{
int rc;
- size_t argc;
+ int argc;
char **argv;
int i;
diff --git a/mailbox/mailbox.c b/mailbox/mailbox.c
index f500e6b1c..af690d554 100644
--- a/mailbox/mailbox.c
+++ b/mailbox/mailbox.c
@@ -42,20 +42,28 @@
#include <mailutils/mutil.h>
#include <mailbox0.h>
+#include <url0.h>
static int
-mailbox_folder_create (mu_folder_t *pfolder, const char *name)
+mailbox_folder_create (mu_mailbox_t mbox, const char *name,
+ mu_record_t record)
{
int rc;
- char *p, *fname = strdup (name);
+ char *fname;
- if (!fname)
- return ENOMEM;
+ if ((rc = mu_url_aget_path (mbox->url, &fname)))
+ return rc;
- p = strrchr (fname, '/'); /* FIXME: Is this always appropriate? */
- if (p && !(mu_is_proto (fname) && strncmp (fname, "file:", 5)))
- *p = 0;
- rc = mu_folder_create (pfolder, fname);
+ if (mu_url_is_scheme (mbox->url, "file")
+ || mu_url_is_scheme (mbox->url, "mbox")
+ || mu_url_is_scheme (mbox->url, "mh")
+ || mu_url_is_scheme (mbox->url, "maildir"))
+ {
+ char *p = strrchr (fname, '/'); /* FIXME: Is this always appropriate? */
+ if (p)
+ *p = 0;
+ }
+ rc = mu_folder_create_from_record (&mbox->folder, fname, record);
free (fname);
return rc;
}
@@ -85,22 +93,21 @@ mu_mailbox_get_default_proto ()
}
static int
-_create_mailbox (mu_mailbox_t *pmbox, const char *name)
+_create_mailbox0 (mu_mailbox_t *pmbox, mu_url_t url, const char *name)
{
+ int status;
mu_record_t record = NULL;
- if (mu_registrar_lookup (name, MU_FOLDER_ATTRIBUTE_FILE, &record, NULL) == 0)
+ if (mu_registrar_lookup_url (url, MU_FOLDER_ATTRIBUTE_FILE, &record, NULL)
+ == 0)
{
mu_log_level_t level;
int (*m_init) (mu_mailbox_t) = NULL;
- int (*u_init) (mu_url_t) = NULL;
mu_record_get_mailbox (record, &m_init);
- mu_record_get_url (record, &u_init);
- if (m_init && u_init)
+ if (m_init)
{
- int status;
- mu_url_t url;
+ int (*u_init) (mu_url_t) = NULL;
mu_mailbox_t mbox;
/* Allocate memory for mbox. */
@@ -117,19 +124,31 @@ _create_mailbox (mu_mailbox_t *pmbox, const char *name)
return status;
}
- /* Parse the url, it may be a bad one and we should bailout if this
- failed. */
- if ((status = mu_url_create (&url, name)) != 0
- || (status = u_init (url)) != 0)
+ mu_record_get_url (record, &u_init);
+ if (u_init && (status = u_init (url)) != 0)
{
mu_mailbox_destroy (&mbox);
return status;
}
+
+ /* Make sure scheme contains actual mailbox scheme */
+ if (strcmp (url->scheme, record->scheme))
+ {
+ char *p = strdup (record->scheme);
+ if (!p)
+ {
+ mu_mailbox_destroy (&mbox);
+ return errno;
+ }
+ free (url->scheme);
+ url->scheme = p;
+ }
+
mbox->url = url;
/* Create the folder before initializing the concrete mailbox.
The mailbox needs it's back pointer. */
- status = mailbox_folder_create (&mbox->folder, name);
+ status = mailbox_folder_create (mbox, name, record);
if (status == 0)
status = m_init (mbox); /* Create the concrete mailbox type. */
@@ -160,6 +179,21 @@ _create_mailbox (mu_mailbox_t *pmbox, const char *name)
return MU_ERR_NO_HANDLER;
}
+static int
+_create_mailbox (mu_mailbox_t *pmbox, const char *name)
+{
+ int status;
+ mu_url_t url;
+
+ status = mu_url_create (&url, name);
+ if (status)
+ return status;
+ status = mu_url_parse (url);
+ if (status == 0)
+ status = _create_mailbox0 (pmbox, url, name);
+ return status;
+}
+
/* The Mailbox Factory.
Create an iterator for registrar and see if any url scheme match,
Then we call the mailbox's mu_url_create() to parse the URL. Last
diff --git a/mailbox/mutil.c b/mailbox/mutil.c
index 25c8ac2e3..89fab1896 100644
--- a/mailbox/mutil.c
+++ b/mailbox/mutil.c
@@ -59,6 +59,7 @@
#include <mailutils/stream.h>
#include <mailutils/filter.h>
#include <mailutils/sql.h>
+#include <mailutils/url.h>
#include <registrar0.h>
@@ -1243,21 +1244,15 @@ mu_true_answer_p (const char *p)
return -1;
}
-/* Returns true if SCHEME represents a local mail folder. Stores
- real folder path to PATH */
+/* Returns true if SCHEME represents a local (autodetect) mail folder. */
int
-mu_scheme_autodetect_p (const char *scheme, const char **path)
+mu_scheme_autodetect_p (mu_url_t url)
{
- *path = scheme;
- if (strncmp (MU_FILE_SCHEME, scheme, MU_FILE_SCHEME_LEN) == 0)
+ if (mu_url_is_scheme (url, "file"))
{
- *path += MU_FILE_SCHEME_LEN;
+ mu_url_expand_path (url);
return 1;
}
- if (access (scheme, F_OK) == 0
- /* FIXME: this can return true even if the folder is unreadable */
- || strncmp (MU_PATH_SCHEME, scheme, MU_PATH_SCHEME_LEN) == 0)
- return 1;
return 0;
}
@@ -1329,7 +1324,7 @@ mu_decode_filter (mu_stream_t *pfilter, mu_stream_t input,
mu_stream_t filter;
int status = mu_filter_create (&filter, input, filter_type,
- MU_FILTER_DECODE, MU_STREAM_READ);
+ MU_FILTER_DECODE, MU_STREAM_READ);
if (status)
return status;
diff --git a/mailbox/registrar.c b/mailbox/registrar.c
index 2b3919157..437974aa3 100644
--- a/mailbox/registrar.c
+++ b/mailbox/registrar.c
@@ -34,6 +34,7 @@
#include <mailutils/errno.h>
#include <mailutils/nls.h>
#include <mailutils/error.h>
+#include <mailutils/url.h>
#include <registrar0.h>
@@ -90,8 +91,8 @@ mu_registrar_get_iterator (mu_iterator_t *pitr)
}
int
-mu_registrar_lookup (const char *name, int flags,
- mu_record_t *precord, int *pflags)
+mu_registrar_lookup_url (mu_url_t url, int flags,
+ mu_record_t *precord, int *pflags)
{
mu_iterator_t iterator;
int status = mu_registrar_get_iterator (&iterator);
@@ -104,7 +105,7 @@ mu_registrar_lookup (const char *name, int flags,
int rc;
mu_record_t record;
mu_iterator_current (iterator, (void **)&record);
- if ((rc = mu_record_is_scheme (record, name, flags)))
+ if ((rc = mu_record_is_scheme (record, url, flags)))
{
status = 0;
if (precord)
@@ -118,6 +119,23 @@ mu_registrar_lookup (const char *name, int flags,
return status;
}
+int
+mu_registrar_lookup (const char *name, int flags,
+ mu_record_t *precord, int *pflags)
+{
+ int rc;
+ mu_url_t url;
+
+ rc = mu_url_create (&url, name);
+ if (rc)
+ return rc;
+ rc = mu_url_parse (url);
+ if (rc == 0)
+ rc = mu_registrar_lookup_url (url, flags, precord, pflags);
+ mu_url_destroy (&url);
+ return rc;
+}
+
static int
_compare_prio (const void *item, const void *value)
{
@@ -156,18 +174,16 @@ mu_unregistrar_record (mu_record_t record)
}
int
-mu_record_is_scheme (mu_record_t record, const char *scheme, int flags)
+mu_record_is_scheme (mu_record_t record, mu_url_t url, int flags)
{
if (record == NULL)
return 0;
/* Overload. */
if (record->_is_scheme)
- return record->_is_scheme (record, scheme, flags);
+ return record->_is_scheme (record, url, flags);
- if (scheme
- && record->scheme
- && strncasecmp (record->scheme, scheme, strlen (record->scheme)) == 0)
+ if (mu_url_is_scheme (url, record->scheme))
return MU_FOLDER_ATTRIBUTE_ALL;
return 0;
@@ -183,8 +199,8 @@ mu_record_set_scheme (mu_record_t record, const char *scheme)
}
int
-mu_record_set_is_scheme (mu_record_t record, int (*_is_scheme)
- (mu_record_t, const char *, int))
+mu_record_set_is_scheme (mu_record_t record,
+ int (*_is_scheme) (mu_record_t, mu_url_t, int))
{
if (record == NULL)
return EINVAL;
diff --git a/mailbox/testsuite/Urls b/mailbox/testsuite/Urls
index f7d8cb084..7a10c3072 100644
--- a/mailbox/testsuite/Urls
+++ b/mailbox/testsuite/Urls
@@ -627,4 +627,41 @@ ftp://ftp.example.org:111/mbox/user%40host => SUCCESS
path <mbox/user@host>
query <>
+ftp://ftp.example.org:111/mbox/user%40host;type=pass => SUCCESS
+ scheme <ftp>
+ user <>
+ passwd <>
+ auth <>
+ host <ftp.example.org>
+ port 111
+ path <mbox/user@host>
+ param[0] <type=pass>
+ query <>
+
+mbox:/var/spool/mail;type=index;param=2;user=gray => SUCCESS
+ scheme <mbox>
+ user <>
+ passwd <>
+ auth <>
+ host <>
+ port 0
+ path </var/spool/mail>
+ param[0] <type=index>
+ param[1] <param=2>
+ param[2] <user=gray>
+ query <>
+
+mbox:///var/spool/mail;type=index;param=2;user=gray => SUCCESS
+ scheme <mbox>
+ user <>
+ passwd <>
+ auth <>
+ host <>
+ port 0
+ path </var/spool/mail>
+ param[0] <type=index>
+ param[1] <param=2>
+ param[2] <user=gray>
+ query <>
+
# NOTE: This file must end with an empty line
diff --git a/mailbox/url.c b/mailbox/url.c
index bf4ae0e31..c3ea2c9f9 100644
--- a/mailbox/url.c
+++ b/mailbox/url.c
@@ -30,6 +30,7 @@
#include <mailutils/mutil.h>
#include <mailutils/errno.h>
+#include <mailutils/argcv.h>
#include <url0.h>
/*
@@ -86,6 +87,9 @@ mu_url_destroy (mu_url_t * purl)
if (url->path)
free (url->path);
+ if (url->fvcount)
+ mu_argcv_free (url->fvcount, url->fvpairs);
+
if (url->query)
free (url->query);
@@ -100,11 +104,12 @@ mu_url_parse (mu_url_t url)
{
int err = 0;
char *n = NULL;
- struct _mu_url u = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ struct _mu_url u;
if (!url || !url->name)
return EINVAL;
+ memset (&u, 0, sizeof u);
/* can't have been parsed already */
if (url->scheme || url->user || url->passwd || url->auth ||
url->host || url->path || url->query)
@@ -125,14 +130,17 @@ mu_url_parse (mu_url_t url)
though.
*/
-#define UALLOC(X) \
- if(u.X && u.X[0] && (url->X = mu_url_decode(u.X)) == 0) { \
- err = ENOMEM; \
- goto CLEANUP; \
- } else { \
- /* Set zero-length strings to NULL. */ \
- u.X = NULL; \
- }
+#define UALLOC(X) \
+ if (u.X && u.X[0] && (url->X = mu_url_decode(u.X)) == 0) \
+ { \
+ err = ENOMEM; \
+ goto CLEANUP; \
+ } \
+ else \
+ { \
+ /* Set zero-length strings to NULL. */ \
+ u.X = NULL; \
+ }
UALLOC (scheme);
UALLOC (user);
@@ -142,6 +150,8 @@ mu_url_parse (mu_url_t url)
UALLOC (path);
UALLOC (query);
#undef UALLOC
+ url->fvcount = u.fvcount;
+ url->fvpairs = u.fvpairs;
url->port = u.port;
}
@@ -150,7 +160,7 @@ CLEANUP:
if (err)
{
-#define UFREE(X) if(X) { free(X); X = 0; }
+#define UFREE(X) if (X) { free(X); X = 0; }
UFREE (url->scheme);
UFREE (url->user);
@@ -199,111 +209,126 @@ url_parse0 (mu_url_t u, char *name)
if (name == NULL)
return EINVAL;
- /* Parse out the SCHEME. */
- p = strchr (name, ':');
- if (p == NULL)
- return MU_ERR_PARSE;
-
- *p++ = 0;
-
- u->scheme = name;
+ if (name[0] == '/')
+ {
+ u->scheme = "file";
+ }
+ else
+ {
+ /* Parse out the SCHEME. */
+ p = strchr (name, ':');
+ if (p == NULL)
+ return MU_ERR_PARSE;
- /* RFC 1738, section 2.1, lower the scheme case */
- for (; name < p; name++)
- *name = tolower (*name);
+ *p++ = 0;
- name = p;
+ u->scheme = name;
+ /* RFC 1738, section 2.1, lower the scheme case */
+ for (; name < p; name++)
+ *name = tolower (*name);
+
+ name = p;
+ }
+
/* Check for nothing following the scheme. */
if (!*name)
return 0;
- if (strncmp (name, "//", 2) != 0)
+ if (strncmp (name, "//", 2) == 0)
{
- u->path = name;
- return 0;
- }
-
- name += 2;
+ name += 2;
- if (name[0] == '/')
- {
- u->path = name;
- return 0;
- }
-
- /* Split into LHS and RHS of the '@', and then parse each side. */
- u->host = strchr (name, '@');
- if (u->host == NULL)
- u->host = name;
- else
- {
- /* Parse the LHS into an identification/authentication pair. */
- *u->host++ = 0;
-
- u->user = name;
-
- /* Try to split the user into a:
- <user>:<password>
- or
- <user>;AUTH=<auth>
- */
-
- for (; *name; name++)
+ if (name[0] == '/')
{
- if (*name == ';')
+ u->path = name;
+ p = u->path + strcspn (u->path, ";?");
+ }
+ else
+ {
+ /* Split into LHS and RHS of the '@', and then parse each side. */
+ u->host = strchr (name, '@');
+ if (u->host == NULL)
+ u->host = name;
+ else
{
- /* Make sure it's the auth token. */
- if (strncasecmp (name + 1, "auth=", 5) == 0)
- {
- *name++ = 0;
+ /* Parse the LHS into an identification/authentication pair. */
+ *u->host++ = 0;
- name += 5;
+ u->user = name;
- u->auth = name;
+ /* Try to split the user into a:
+ <user>:<password>
+ or
+ <user>;AUTH=<auth>
+ */
- break;
+ for (; *name; name++)
+ {
+ if (*name == ';')
+ {
+ /* Make sure it's the auth token. */
+ if (strncasecmp (name + 1, "auth=", 5) == 0)
+ {
+ *name++ = 0;
+ name += 5;
+ u->auth = name;
+ break;
+ }
+ }
+ if (*name == ':')
+ {
+ *name++ = 0;
+ u->passwd = name;
+ break;
+ }
}
}
- if (*name == ':')
+
+ /* Parse the host and port from the RHS. */
+ p = strchr (u->host, ':');
+ if (p)
{
- *name++ = 0;
- u->passwd = name;
- break;
+ *p++ = 0;
+ u->port = strtol (p, &p, 10);
+
+ /* Check for garbage after the port: we should be on the start
+ of a path, a query, or at the end of the string. */
+ if (*p && strcspn (p, "/?") != 0)
+ return MU_ERR_PARSE;
}
+ else
+ p = u->host + strcspn (u->host, ";/?");
}
}
-
- /* Parse the host and port from the RHS. */
- p = strchr (u->host, ':');
-
- if (p)
+ else
+ {
+ u->path = name;
+ p = u->path + strcspn (u->path, ";?");
+ }
+
+ /* Either way, if we're not at a nul, we're at a path or query. */
+ if (u->path == NULL && *p == '/')
{
+ /* found a path */
*p++ = 0;
+ u->path = p;
+ p = u->path + strcspn (u->path, ";?");
+ }
- u->port = strtol (p, &p, 10);
-
- /* Check for garbage after the port: we should be on the start
- of a path, a query, or at the end of the string. */
- if (*p && strcspn (p, "/?") != 0)
- return MU_ERR_PARSE;
+ if (*p == ';')
+ {
+ *p++ = 0;
+ mu_argcv_get_np (p, strlen (p), ";", "?", 0,
+ &u->fvcount, &u->fvpairs, &p);
}
- else
- p = u->host + strcspn (u->host, "/?");
- /* Either way, if we're not at a nul, we're at a path or query. */
if (*p == '?')
{
/* found a query */
*p++ = 0;
u->query = p;
}
- if (*p == '/')
- {
- /* found a path */
- *p++ = 0;
- u->path = p;
- }
return 0;
}
@@ -431,6 +456,46 @@ DECL_ACCESSORS (host)
DECL_ACCESSORS (path)
DECL_ACCESSORS (query)
+/* field-value pairs accessors */
+int
+mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp)
+{
+ if (url == NULL)
+ return EINVAL;
+ /* FIXME: no _get_fvpairs method, but the method stuff needs to be rewritten
+ anyway */
+ *fvc = url->fvcount;
+ *fvp = url->fvpairs;
+ return 0;
+}
+
+int
+mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp)
+{
+ size_t fvc, i;
+ char **fvp;
+ char **fvcopy;
+
+ int rc = mu_url_sget_fvpairs (url, &fvc, &fvp);
+ if (rc)
+ return rc;
+
+ fvcopy = calloc (fvc + 1, sizeof (fvcopy[0]));
+ if (!fvcopy)
+ return errno;
+ for (i = 0; i < fvc; i++)
+ {
+ if (!(fvcopy[i] = strdup (fvp[i])))
+ {
+ mu_argcv_free (i, fvcopy);
+ return errno;
+ }
+ }
+ fvcopy[i] = NULL;
+ *pfvc = fvc;
+ *pfvp = fvcopy;
+ return 0;
+}
int
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)
return status;
}
+
+/* Default mailbox path generator */
+static char *
+_url_path_default (const char *spooldir, const char *user, int unused)
+{
+ char *mbox = malloc (sizeof(spooldir) + strlen(user) + 2);
+ if (!mbox)
+ errno = ENOMEM;
+ else
+ sprintf (mbox, "%s/%s", spooldir, user);
+ return mbox;
+}
+
+/* Hashed indexing */
+static char *
+_url_path_hashed (const char *spooldir, const char *user, int param)
+{
+ int i;
+ int ulen = strlen (user);
+ char *mbox;
+ unsigned hash;
+
+ if (param > ulen)
+ param = ulen;
+ for (i = 0, hash = 0; i < param; i++)
+ hash += user[i];
+
+ mbox = malloc (ulen + strlen (spooldir) + 5);
+ sprintf (mbox, "%s/%02X/%s", spooldir, hash % 256, user);
+ return mbox;
+}
+
+static int transtab[] = {
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+ 'm', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f',
+ 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
+ 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
+ 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e',
+ 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g'
+};
+
+/* Forward Indexing */
+static char *
+_url_path_index (const char *spooldir, const char *iuser, int index_depth)
+{
+ const unsigned char* user = (const unsigned char*) iuser;
+ int i, ulen = strlen (iuser);
+ char *mbox, *p;
+
+ if (ulen == 0)
+ return NULL;
+
+ mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 2);
+ strcpy (mbox, spooldir);
+ p = mbox + strlen (mbox);
+ for (i = 0; i < index_depth && i < ulen; i++)
+ {
+ *p++ = '/';
+ *p++ = transtab[ user[i] ];
+ }
+ for (; i < index_depth; i++)
+ {
+ *p++ = '/';
+ *p++ = transtab[ user[ulen-1] ];
+ }
+ *p++ = '/';
+ strcpy (p, iuser);
+ return mbox;
+}
+
+/* Reverse Indexing */
+static char *
+_url_path_rev_index (const char *spooldir, const char *iuser, int index_depth)
+{
+ const unsigned char* user = (const unsigned char*) iuser;
+ int i, ulen = strlen (iuser);
+ char *mbox, *p;
+
+ if (ulen == 0)
+ return NULL;
+
+ mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 1);
+ strcpy (mbox, spooldir);
+ p = mbox + strlen (mbox);
+ for (i = 0; i < index_depth && i < ulen; i++)
+ {
+ *p++ = '/';
+ *p++ = transtab[ user[ulen - i - 1] ];
+ }
+ for (; i < index_depth; i++)
+ {
+ *p++ = '/';
+ *p++ = transtab[ user[0] ];
+ }
+ *p++ = '/';
+ strcpy (p, iuser);
+ return mbox;
+}
+
+static int
+rmselector (const char *p, void *data MU_ARG_UNUSED)
+{
+ return strncmp (p, "type=", 5) == 0
+ || strncmp (p, "user=", 5) == 0
+ || strncmp (p, "param=", 6) == 0;
+}
+
+int
+mu_url_expand_path (mu_url_t url)
+{
+ size_t i;
+ char *user = NULL;
+ int param = 0;
+ char *p;
+ char *(*fun) (const char *, const char *, int) = _url_path_default;
+
+ if (url->fvcount == 0)
+ return 0;
+
+ for (i = 0; i < url->fvcount; i++)
+ {
+ p = url->fvpairs[i];
+ if (strncmp (p, "type=", 5) == 0)
+ {
+ char *type = p + 5;
+
+ if (strcmp (type, "hash") == 0)
+ fun = _url_path_hashed;
+ else if (strcmp (type, "index") == 0)
+ fun = _url_path_index;
+ else if (strcmp (type, "rev-index") == 0)
+ fun = _url_path_rev_index;
+ else
+ return MU_ERR_NOENT;
+ }
+ else if (strncmp (p, "user=", 5) == 0)
+ {
+ user = p + 5;
+ }
+ else if (strncmp (p, "param=", 6) == 0)
+ {
+ param = strtoul (p + 6, NULL, 0);
+ }
+ }
+
+ if (user)
+ {
+ char *p = fun (url->path, user, param);
+ if (p)
+ {
+ free (url->path);
+ url->path = p;
+ }
+ mu_argcv_remove (&url->fvcount, &url->fvpairs, rmselector, NULL);
+ }
+ else
+ return MU_ERR_NOENT;
+
+ return 0;
+}
diff --git a/pop3d/bulletin.c b/pop3d/bulletin.c
index c59ad79d3..ff4253c29 100644
--- a/pop3d/bulletin.c
+++ b/pop3d/bulletin.c
@@ -24,7 +24,7 @@ static char *bulletin_db_name;
void
set_bulletin_db (char *file)
{
- bulletin_db_name = file;
+ bulletin_db_name = strdup (file);
}
static void
@@ -67,7 +67,7 @@ open_bulletin_mailbox (mu_mailbox_t *pmbox)
int
set_bulletin_source (char *source)
{
- bulletin_mbox_name = source;
+ bulletin_mbox_name = strdup (source);
return 0;
}
@@ -145,8 +145,14 @@ read_bulletin_db (size_t *pnum)
if (rc)
{
+ int ec = errno;
+ if (ec == ENOENT)
+ {
+ *pnum = 0;
+ return 0;
+ }
mu_error (_("Cannot fetch bulletin db data: %s"),
- mu_strerror (errno));
+ mu_strerror (ec));
mu_dbm_close (db);
return 1;
}
@@ -236,18 +242,14 @@ write_bulletin_db (size_t num)
}
#endif /* USE_DBM */
-size_t
-get_last_delivered_num ()
+int
+get_last_delivered_num (size_t *pret)
{
- size_t num = 0;
-
#ifdef USE_DBM
- if (bulletin_db_name && read_bulletin_db (&num) == 0)
- return num;
+ if (bulletin_db_name && read_bulletin_db (pret) == 0)
+ return 0;
#endif
-
- read_popbull_file (&num);
- return num;
+ return read_popbull_file (pret);
}
void
@@ -271,9 +273,8 @@ deliver_pending_bulletins ()
return;
rc = open_bulletin_mailbox (&bull);
- if (rc)
+ if (rc || get_last_delivered_num (&lastnum))
return;
- lastnum = get_last_delivered_num ();
rc = mu_mailbox_messages_count (bull, &total);
if (rc)
diff --git a/pop3d/capa.c b/pop3d/capa.c
index 457ebda18..9b96adb61 100644
--- a/pop3d/capa.c
+++ b/pop3d/capa.c
@@ -50,7 +50,7 @@ pop3d_capa (const char *arg)
login_delay_capa ();
/* This can be implemented by setting an header field on the message. */
- if (expire < 0)
+ if (expire == EXPIRE_NEVER)
pop3d_outf ("EXPIRE NEVER\r\n");
else
pop3d_outf ("EXPIRE %s\r\n", mu_umaxtostr (0, expire));

Return to:

Send suggestions and report system problems to the System administrator.