imap4d: revamp namespace translation
Instead of translating names to full mailbox URLs, translate them to the filesystem pathname and record (mu_record_t) that should be used when creating the mailbox. Never use mu_mailbox_create_default. This patch also fixes memory leaks in some functions (the return value from namespace_get_url was never freed). * imap4d/imap4d.h (namespace_get_url): Remove. (namespace_get_name): New proto. * imap4d/namespace.c (namespace_init): Always intialize the pfx->record member. This requires that the default record be initialized. (namespace_get_url): Remove. (namespace_get_name): New function. * imap4d/create.c: Use namespace_get_name and mu_mailbox_create_from_record to create mailboxes. Fix folder creation. * imap4d/append.c: Use namespace_get_name and mu_mailbox_create_from_record to create mailboxes. * imap4d/copy.c: Likewise. * imap4d/delete.c: Likewise. * imap4d/quota.c: Likewise. * imap4d/rename.c: Likewise. * imap4d/status.c: Likewise.
Showing
9 changed files
with
54 additions
and
41 deletions
... | @@ -201,6 +201,7 @@ imap4d_append (struct imap4d_session *session, | ... | @@ -201,6 +201,7 @@ imap4d_append (struct imap4d_session *session, |
201 | { | 201 | { |
202 | int i; | 202 | int i; |
203 | char *mboxname; | 203 | char *mboxname; |
204 | mu_record_t record; | ||
204 | int flags = 0; | 205 | int flags = 0; |
205 | mu_mailbox_t dest_mbox = NULL; | 206 | mu_mailbox_t dest_mbox = NULL; |
206 | int status; | 207 | int status; |
... | @@ -253,11 +254,11 @@ imap4d_append (struct imap4d_session *session, | ... | @@ -253,11 +254,11 @@ imap4d_append (struct imap4d_session *session, |
253 | 254 | ||
254 | msg_text = imap4d_tokbuf_getarg (tok, i); | 255 | msg_text = imap4d_tokbuf_getarg (tok, i); |
255 | 256 | ||
256 | mboxname = namespace_get_url (mboxname, NULL); | 257 | mboxname = namespace_get_name (mboxname, &record, NULL); |
257 | if (!mboxname) | 258 | if (!mboxname) |
258 | return io_completion_response (command, RESP_NO, "Couldn't open mailbox"); | 259 | return io_completion_response (command, RESP_NO, "Couldn't open mailbox"); |
259 | 260 | ||
260 | status = mu_mailbox_create_default (&dest_mbox, mboxname); | 261 | status = mu_mailbox_create_from_record (&dest_mbox, record, mboxname); |
261 | if (status == 0) | 262 | if (status == 0) |
262 | { | 263 | { |
263 | /* It SHOULD NOT automatically create the mailbox. */ | 264 | /* It SHOULD NOT automatically create the mailbox. */ | ... | ... |
... | @@ -212,6 +212,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) | ... | @@ -212,6 +212,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) |
212 | mu_mailbox_t cmbox = NULL; | 212 | mu_mailbox_t cmbox = NULL; |
213 | int arg = IMAP4_ARG_1 + !!isuid; | 213 | int arg = IMAP4_ARG_1 + !!isuid; |
214 | int mode = 0; | 214 | int mode = 0; |
215 | mu_record_t record; | ||
215 | 216 | ||
216 | *err_text = NULL; | 217 | *err_text = NULL; |
217 | if (imap4d_tokbuf_argc (tok) != arg + 2) | 218 | if (imap4d_tokbuf_argc (tok) != arg + 2) |
... | @@ -240,7 +241,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) | ... | @@ -240,7 +241,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) |
240 | return RESP_BAD; | 241 | return RESP_BAD; |
241 | } | 242 | } |
242 | 243 | ||
243 | mailbox_name = namespace_get_url (name, &mode); | 244 | mailbox_name = namespace_get_name (name, &record, &mode); |
244 | 245 | ||
245 | if (!mailbox_name) | 246 | if (!mailbox_name) |
246 | { | 247 | { |
... | @@ -251,7 +252,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) | ... | @@ -251,7 +252,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) |
251 | 252 | ||
252 | /* If the destination mailbox does not exist, a server should return | 253 | /* If the destination mailbox does not exist, a server should return |
253 | an error. */ | 254 | an error. */ |
254 | status = mu_mailbox_create_default (&cmbox, mailbox_name); | 255 | status = mu_mailbox_create_from_record (&cmbox, record, mailbox_name); |
255 | if (status == 0) | 256 | if (status == 0) |
256 | { | 257 | { |
257 | /* It SHOULD NOT automatifcllly create the mailbox. */ | 258 | /* It SHOULD NOT automatifcllly create the mailbox. */ |
... | @@ -267,6 +268,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) | ... | @@ -267,6 +268,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) |
267 | mu_mailbox_destroy (&cmbox); | 268 | mu_mailbox_destroy (&cmbox); |
268 | } | 269 | } |
269 | mu_msgset_free (msgset); | 270 | mu_msgset_free (msgset); |
271 | free (mailbox_name); | ||
270 | 272 | ||
271 | if (status == 0) | 273 | if (status == 0) |
272 | { | 274 | { | ... | ... |
... | @@ -39,9 +39,10 @@ imap4d_create (struct imap4d_session *session, | ... | @@ -39,9 +39,10 @@ imap4d_create (struct imap4d_session *session, |
39 | { | 39 | { |
40 | char *name; | 40 | char *name; |
41 | int isdir = 0; | 41 | int isdir = 0; |
42 | int mode = 0; | ||
43 | int rc = RESP_OK; | 42 | int rc = RESP_OK; |
44 | const char *msg = "Completed"; | 43 | const char *msg = "Completed"; |
44 | mu_record_t record; | ||
45 | int mode; | ||
45 | 46 | ||
46 | if (imap4d_tokbuf_argc (tok) != 3) | 47 | if (imap4d_tokbuf_argc (tok) != 3) |
47 | return io_completion_response (command, RESP_BAD, "Invalid arguments"); | 48 | return io_completion_response (command, RESP_BAD, "Invalid arguments"); |
... | @@ -67,7 +68,7 @@ imap4d_create (struct imap4d_session *session, | ... | @@ -67,7 +68,7 @@ imap4d_create (struct imap4d_session *session, |
67 | isdir = 1; | 68 | isdir = 1; |
68 | 69 | ||
69 | /* Allocates memory. */ | 70 | /* Allocates memory. */ |
70 | name = namespace_get_url (name, &mode); | 71 | name = namespace_get_name (name, &record, &mode); |
71 | 72 | ||
72 | if (!name) | 73 | if (!name) |
73 | return io_completion_response (command, RESP_NO, "Cannot create mailbox"); | 74 | return io_completion_response (command, RESP_NO, "Cannot create mailbox"); |
... | @@ -76,33 +77,42 @@ imap4d_create (struct imap4d_session *session, | ... | @@ -76,33 +77,42 @@ imap4d_create (struct imap4d_session *session, |
76 | if (access (name, F_OK) != 0) | 77 | if (access (name, F_OK) != 0) |
77 | { | 78 | { |
78 | if (make_interdir (name, MU_HIERARCHY_DELIMITER, MKDIR_PERMISSIONS)) | 79 | if (make_interdir (name, MU_HIERARCHY_DELIMITER, MKDIR_PERMISSIONS)) |
80 | rc = RESP_NO; | ||
81 | |||
82 | if (rc == RESP_OK) | ||
83 | { | ||
84 | if (isdir) | ||
85 | { | ||
86 | if (mkdir (name, MKDIR_PERMISSIONS)) | ||
79 | { | 87 | { |
88 | mu_diag_output (MU_DIAG_ERR, | ||
89 | _("Cannot create directory %s: %s"), name, | ||
90 | mu_strerror (errno)); | ||
80 | rc = RESP_NO; | 91 | rc = RESP_NO; |
81 | msg = "Cannot create mailbox"; | ||
82 | } | 92 | } |
83 | 93 | } | |
84 | if (rc == RESP_OK && !isdir) | 94 | else |
85 | { | 95 | { |
86 | mu_mailbox_t mbox; | 96 | mu_mailbox_t mbox; |
87 | 97 | ||
88 | rc = mu_mailbox_create_default (&mbox, name); | 98 | rc = mu_mailbox_create_from_record (&mbox, record, name); |
89 | if (rc) | 99 | if (rc) |
90 | { | 100 | { |
91 | mu_diag_output (MU_DIAG_ERR, | 101 | mu_diag_output (MU_DIAG_ERR, |
92 | _("Cannot create mailbox %s: %s"), name, | 102 | _("Cannot create mailbox (%s) %s: %s"), name, |
103 | record->scheme, | ||
93 | mu_strerror (rc)); | 104 | mu_strerror (rc)); |
94 | rc = RESP_NO; | 105 | rc = RESP_NO; |
95 | msg = "Cannot create mailbox"; | ||
96 | } | 106 | } |
97 | else if ((rc = mu_mailbox_open (mbox, | 107 | else if ((rc = mu_mailbox_open (mbox, |
98 | MU_STREAM_RDWR | MU_STREAM_CREAT | 108 | MU_STREAM_RDWR | MU_STREAM_CREAT |
99 | | mode))) | 109 | | mode))) |
100 | { | 110 | { |
101 | mu_diag_output (MU_DIAG_ERR, | 111 | mu_diag_output (MU_DIAG_ERR, |
102 | _("Cannot open mailbox %s: %s"), | 112 | _("Cannot open mailbox (%s) %s: %s"), |
113 | record->scheme, | ||
103 | name, mu_strerror (rc)); | 114 | name, mu_strerror (rc)); |
104 | rc = RESP_NO; | 115 | rc = RESP_NO; |
105 | msg = "Cannot create mailbox"; | ||
106 | } | 116 | } |
107 | else | 117 | else |
108 | { | 118 | { |
... | @@ -112,11 +122,14 @@ imap4d_create (struct imap4d_session *session, | ... | @@ -112,11 +122,14 @@ imap4d_create (struct imap4d_session *session, |
112 | } | 122 | } |
113 | } | 123 | } |
114 | } | 124 | } |
125 | if (rc != RESP_OK) | ||
126 | msg = "Cannot create mailbox"; | ||
127 | } | ||
115 | else | 128 | else |
116 | { | 129 | { |
117 | rc = RESP_NO; | 130 | rc = RESP_NO; |
118 | msg = "already exists"; | 131 | msg = "already exists"; |
119 | } | 132 | } |
120 | 133 | free (name); | |
121 | return io_completion_response (command, rc, "%s", msg); | 134 | return io_completion_response (command, rc, "%s", msg); |
122 | } | 135 | } | ... | ... |
... | @@ -36,6 +36,7 @@ imap4d_delete (struct imap4d_session *session, | ... | @@ -36,6 +36,7 @@ imap4d_delete (struct imap4d_session *session, |
36 | const char *msg = "Completed"; | 36 | const char *msg = "Completed"; |
37 | char *name; | 37 | char *name; |
38 | mu_mailbox_t tmpbox; | 38 | mu_mailbox_t tmpbox; |
39 | mu_record_t record; | ||
39 | 40 | ||
40 | if (imap4d_tokbuf_argc (tok) != 3) | 41 | if (imap4d_tokbuf_argc (tok) != 3) |
41 | return io_completion_response (command, RESP_BAD, "Invalid arguments"); | 42 | return io_completion_response (command, RESP_BAD, "Invalid arguments"); |
... | @@ -49,11 +50,11 @@ imap4d_delete (struct imap4d_session *session, | ... | @@ -49,11 +50,11 @@ imap4d_delete (struct imap4d_session *session, |
49 | return io_completion_response (command, RESP_NO, "Already exist"); | 50 | return io_completion_response (command, RESP_NO, "Already exist"); |
50 | 51 | ||
51 | /* Allocates memory. */ | 52 | /* Allocates memory. */ |
52 | name = namespace_get_url (name, NULL); | 53 | name = namespace_get_name (name, &record, NULL); |
53 | if (!name) | 54 | if (!name) |
54 | return io_completion_response (command, RESP_NO, "Cannot remove"); | 55 | return io_completion_response (command, RESP_NO, "Cannot remove"); |
55 | 56 | ||
56 | rc = mu_mailbox_create (&tmpbox, name); | 57 | rc = mu_mailbox_create_from_record (&tmpbox, record, name); |
57 | if (rc == 0) | 58 | if (rc == 0) |
58 | { | 59 | { |
59 | imap4d_enter_critical (); | 60 | imap4d_enter_critical (); |
... | @@ -69,6 +70,7 @@ imap4d_delete (struct imap4d_session *session, | ... | @@ -69,6 +70,7 @@ imap4d_delete (struct imap4d_session *session, |
69 | if (rc) | 70 | if (rc) |
70 | mu_diag_funcall (MU_DIAG_ERROR, "remove", name, errno); | 71 | mu_diag_funcall (MU_DIAG_ERROR, "remove", name, errno); |
71 | } | 72 | } |
73 | free (name); | ||
72 | 74 | ||
73 | if (rc) | 75 | if (rc) |
74 | { | 76 | { | ... | ... |
... | @@ -413,7 +413,7 @@ struct namespace *namespace_lookup (char const *name); | ... | @@ -413,7 +413,7 @@ struct namespace *namespace_lookup (char const *name); |
413 | 413 | ||
414 | char *namespace_translate_name (char const *name, int url, | 414 | char *namespace_translate_name (char const *name, int url, |
415 | struct namespace_prefix const **pfx); | 415 | struct namespace_prefix const **pfx); |
416 | char *namespace_get_url (char const *name, int *mode); | 416 | char *namespace_get_name (char const *name, mu_record_t *rec, int *mode); |
417 | 417 | ||
418 | void translate_delim (char *dst, char const *src, int dst_delim, int src_delim); | 418 | void translate_delim (char *dst, char const *src, int dst_delim, int src_delim); |
419 | 419 | ... | ... |
... | @@ -92,7 +92,6 @@ namespace_init (void) | ... | @@ -92,7 +92,6 @@ namespace_init (void) |
92 | if (mu_list_get_iterator (namespace[i].prefixes, &itr)) | 92 | if (mu_list_get_iterator (namespace[i].prefixes, &itr)) |
93 | imap4d_bye (ERR_NO_MEM); | 93 | imap4d_bye (ERR_NO_MEM); |
94 | 94 | ||
95 | |||
96 | for (mu_iterator_first (itr); | 95 | for (mu_iterator_first (itr); |
97 | !mu_iterator_is_done (itr); mu_iterator_next (itr)) | 96 | !mu_iterator_is_done (itr); mu_iterator_next (itr)) |
98 | { | 97 | { |
... | @@ -106,6 +105,9 @@ namespace_init (void) | ... | @@ -106,6 +105,9 @@ namespace_init (void) |
106 | 105 | ||
107 | trim_delim (pfx->dir, '/'); | 106 | trim_delim (pfx->dir, '/'); |
108 | 107 | ||
108 | if (!pfx->scheme) | ||
109 | mu_registrar_get_default_record (&pfx->record); | ||
110 | |||
109 | rc = mu_assoc_install (prefixes, pfx->prefix, pfx); | 111 | rc = mu_assoc_install (prefixes, pfx->prefix, pfx); |
110 | if (rc == MU_ERR_EXISTS) | 112 | if (rc == MU_ERR_EXISTS) |
111 | { | 113 | { |
... | @@ -351,20 +353,12 @@ namespace_translate_name (char const *name, int url, | ... | @@ -351,20 +353,12 @@ namespace_translate_name (char const *name, int url, |
351 | } | 353 | } |
352 | 354 | ||
353 | char * | 355 | char * |
354 | namespace_get_url (char const *name, int *mode) | 356 | namespace_get_name (char const *name, mu_record_t *rec, int *mode) |
355 | { | 357 | { |
356 | struct namespace_prefix const *pfx; | 358 | struct namespace_prefix const *pfx; |
357 | char *path = namespace_translate_name (name, 1, &pfx); | 359 | char *path = namespace_translate_name (name, 0, &pfx); |
358 | 360 | if (rec) | |
359 | if (path && pfx->scheme) | 361 | *rec = pfx->record; |
360 | { | ||
361 | char *p = mu_alloc (strlen (pfx->scheme) + 3 + strlen (path) + 1); | ||
362 | strcpy (p, pfx->scheme); | ||
363 | strcat (p, "://"); | ||
364 | strcat (p, path); | ||
365 | free (path); | ||
366 | path = p; | ||
367 | } | ||
368 | if (mode) | 362 | if (mode) |
369 | *mode = namespace[pfx->ns].mode; | 363 | *mode = namespace[pfx->ns].mode; |
370 | return path; | 364 | return path; | ... | ... |
... | @@ -132,19 +132,17 @@ quota_check (mu_off_t size) | ... | @@ -132,19 +132,17 @@ quota_check (mu_off_t size) |
132 | mu_mailbox_t mbox; | 132 | mu_mailbox_t mbox; |
133 | mu_off_t total; | 133 | mu_off_t total; |
134 | int rc; | 134 | int rc; |
135 | mu_record_t record; | ||
135 | 136 | ||
136 | if (auth_data->quota == 0) | 137 | if (auth_data->quota == 0) |
137 | return RESP_OK; | 138 | return RESP_OK; |
138 | 139 | ||
139 | total = used_size; | 140 | total = used_size; |
140 | 141 | ||
141 | mailbox_name = namespace_get_url ("INBOX", NULL); | 142 | mailbox_name = namespace_get_name ("INBOX", &record, NULL); |
142 | rc = mu_mailbox_create (&mbox, mailbox_name); | 143 | rc = mu_mailbox_create_from_record (&mbox, record, mailbox_name); |
143 | if (rc) | 144 | if (rc) |
144 | { | ||
145 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_create", mailbox_name, rc); | 145 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_create", mailbox_name, rc); |
146 | free (mailbox_name); | ||
147 | } | ||
148 | else | 146 | else |
149 | { | 147 | { |
150 | do | 148 | do | ... | ... |
... | @@ -110,6 +110,7 @@ imap4d_rename (struct imap4d_session *session, | ... | @@ -110,6 +110,7 @@ imap4d_rename (struct imap4d_session *session, |
110 | const char *msg = "Completed"; | 110 | const char *msg = "Completed"; |
111 | struct stat newst; | 111 | struct stat newst; |
112 | int mode = 0; | 112 | int mode = 0; |
113 | mu_record_t newrec; | ||
113 | 114 | ||
114 | if (imap4d_tokbuf_argc (tok) != 4) | 115 | if (imap4d_tokbuf_argc (tok) != 4) |
115 | return io_completion_response (command, RESP_BAD, "Invalid arguments"); | 116 | return io_completion_response (command, RESP_BAD, "Invalid arguments"); |
... | @@ -121,7 +122,7 @@ imap4d_rename (struct imap4d_session *session, | ... | @@ -121,7 +122,7 @@ imap4d_rename (struct imap4d_session *session, |
121 | return io_completion_response (command, RESP_NO, "Name Inbox is reservered"); | 122 | return io_completion_response (command, RESP_NO, "Name Inbox is reservered"); |
122 | 123 | ||
123 | /* Allocates memory. */ | 124 | /* Allocates memory. */ |
124 | newname = namespace_get_url (newname, &mode); | 125 | newname = namespace_get_name (newname, &newrec, &mode); |
125 | if (!newname) | 126 | if (!newname) |
126 | return io_completion_response (command, RESP_NO, "Permission denied"); | 127 | return io_completion_response (command, RESP_NO, "Permission denied"); |
127 | 128 | ||
... | @@ -158,7 +159,7 @@ imap4d_rename (struct imap4d_session *session, | ... | @@ -158,7 +159,7 @@ imap4d_rename (struct imap4d_session *session, |
158 | return io_completion_response (command, RESP_NO, | 159 | return io_completion_response (command, RESP_NO, |
159 | "Cannot be a directory"); | 160 | "Cannot be a directory"); |
160 | } | 161 | } |
161 | if (mu_mailbox_create (&newmbox, newname) != 0 | 162 | if (mu_mailbox_create_from_record (&newmbox, newrec, newname) != 0 |
162 | || mu_mailbox_open (newmbox, | 163 | || mu_mailbox_open (newmbox, |
163 | MU_STREAM_CREAT | MU_STREAM_RDWR | mode) != 0) | 164 | MU_STREAM_CREAT | MU_STREAM_RDWR | mode) != 0) |
164 | { | 165 | { |
... | @@ -199,7 +200,7 @@ imap4d_rename (struct imap4d_session *session, | ... | @@ -199,7 +200,7 @@ imap4d_rename (struct imap4d_session *session, |
199 | return io_completion_response (command, RESP_OK, "Rename successful"); | 200 | return io_completion_response (command, RESP_OK, "Rename successful"); |
200 | } | 201 | } |
201 | 202 | ||
202 | oldname = namespace_get_url (oldname, NULL); | 203 | oldname = namespace_get_name (oldname, NULL, NULL); |
203 | 204 | ||
204 | /* It must exist. */ | 205 | /* It must exist. */ |
205 | /* FIXME: 1. What if odlname or newname is a remote mailbox? | 206 | /* FIXME: 1. What if odlname or newname is a remote mailbox? |
... | @@ -240,6 +241,7 @@ imap4d_rename (struct imap4d_session *session, | ... | @@ -240,6 +241,7 @@ imap4d_rename (struct imap4d_session *session, |
240 | } | 241 | } |
241 | free (oldname); | 242 | free (oldname); |
242 | } | 243 | } |
244 | |||
243 | free (newname); | 245 | free (newname); |
244 | return io_completion_response (command, rc, "%s", msg); | 246 | return io_completion_response (command, rc, "%s", msg); |
245 | } | 247 | } | ... | ... |
... | @@ -75,13 +75,14 @@ imap4d_status (struct imap4d_session *session, | ... | @@ -75,13 +75,14 @@ imap4d_status (struct imap4d_session *session, |
75 | int count = 0; | 75 | int count = 0; |
76 | char *err_msg = NULL; | 76 | char *err_msg = NULL; |
77 | int argc = imap4d_tokbuf_argc (tok); | 77 | int argc = imap4d_tokbuf_argc (tok); |
78 | mu_record_t record; | ||
78 | 79 | ||
79 | if (argc < 4) | 80 | if (argc < 4) |
80 | return io_completion_response (command, RESP_BAD, "Invalid arguments"); | 81 | return io_completion_response (command, RESP_BAD, "Invalid arguments"); |
81 | 82 | ||
82 | name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); | 83 | name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
83 | 84 | ||
84 | mailbox_name = namespace_get_url (name, NULL); | 85 | mailbox_name = namespace_get_name (name, &record, NULL); |
85 | 86 | ||
86 | if (!mailbox_name) | 87 | if (!mailbox_name) |
87 | return io_completion_response (command, RESP_NO, "Error opening mailbox"); | 88 | return io_completion_response (command, RESP_NO, "Error opening mailbox"); |
... | @@ -92,7 +93,7 @@ imap4d_status (struct imap4d_session *session, | ... | @@ -92,7 +93,7 @@ imap4d_status (struct imap4d_session *session, |
92 | mu_mailbox_sync (mbox); | 93 | mu_mailbox_sync (mbox); |
93 | imap4d_leave_critical (); | 94 | imap4d_leave_critical (); |
94 | 95 | ||
95 | status = mu_mailbox_create_default (&smbox, mailbox_name); | 96 | status = mu_mailbox_create_from_record (&smbox, record, mailbox_name); |
96 | if (status == 0) | 97 | if (status == 0) |
97 | { | 98 | { |
98 | status = mu_mailbox_open (smbox, MU_STREAM_READ); | 99 | status = mu_mailbox_open (smbox, MU_STREAM_READ); | ... | ... |
-
Please register or sign in to post a comment