Commit 193c1ef7 193c1ef73dcbc058ee4481e2eed90288ffa5db24 by Alain Magloire

attribute.c attribute.h attribute0.h header.c header.h

 	header0.h mailbox.c mailbox.h mailbox0.h mbx_mbox.c mbx_unix.c
 	message.c registrar.c registrar.h registrar0.h rfc822.c url.c

more cleanups.
1 parent e3fa2e8c
...@@ -62,7 +62,6 @@ attribute_set_answered (attribute_t attr) ...@@ -62,7 +62,6 @@ attribute_set_answered (attribute_t attr)
62 if (attr == NULL) 62 if (attr == NULL)
63 return EINVAL; 63 return EINVAL;
64 attr->flag|= MU_ATTRIBUTE_ANSWERED; 64 attr->flag|= MU_ATTRIBUTE_ANSWERED;
65 attr->flag |= MU_ATTRIBUTE_SEEN;
66 return 0; 65 return 0;
67 } 66 }
68 67
...@@ -72,7 +71,6 @@ attribute_set_flagged (attribute_t attr) ...@@ -72,7 +71,6 @@ attribute_set_flagged (attribute_t attr)
72 if (attr == NULL) 71 if (attr == NULL)
73 return EINVAL; 72 return EINVAL;
74 attr->flag |= MU_ATTRIBUTE_FLAGGED; 73 attr->flag |= MU_ATTRIBUTE_FLAGGED;
75 attr->flag |= MU_ATTRIBUTE_SEEN;
76 return 0; 74 return 0;
77 } 75 }
78 76
...@@ -82,7 +80,6 @@ attribute_set_read (attribute_t attr) ...@@ -82,7 +80,6 @@ attribute_set_read (attribute_t attr)
82 if (attr == NULL) 80 if (attr == NULL)
83 return EINVAL; 81 return EINVAL;
84 attr->flag |= MU_ATTRIBUTE_READ; 82 attr->flag |= MU_ATTRIBUTE_READ;
85 attr->flag |= MU_ATTRIBUTE_SEEN;
86 return 0; 83 return 0;
87 } 84 }
88 85
...@@ -175,9 +172,6 @@ attribute_unset_seen (attribute_t attr) ...@@ -175,9 +172,6 @@ attribute_unset_seen (attribute_t attr)
175 if (attr == NULL) 172 if (attr == NULL)
176 return 0; 173 return 0;
177 attr->flag ^= MU_ATTRIBUTE_SEEN; 174 attr->flag ^= MU_ATTRIBUTE_SEEN;
178 attr->flag ^= MU_ATTRIBUTE_ANSWERED;
179 attr->flag ^= MU_ATTRIBUTE_FLAGGED;
180 attr->flag ^= MU_ATTRIBUTE_READ;
181 return 0; 175 return 0;
182 } 176 }
183 177
...@@ -235,3 +229,38 @@ attribute_unset_recent (attribute_t attr) ...@@ -235,3 +229,38 @@ attribute_unset_recent (attribute_t attr)
235 return 0; 229 return 0;
236 } 230 }
237 231
232 int
233 attribute_is_equal (attribute_t attr, attribute_t attr2)
234 {
235 if (attr == NULL || attr2 == NULL)
236 return 0;
237 return attr->flag == attr2->flag;
238 }
239
240 int
241 attribute_copy (attribute_t dest, attribute_t src)
242 {
243 if (dest == NULL || src == NULL)
244 return EINVAL;
245 memcpy (dest, src, sizeof (*dest));
246 return 0;
247 }
248
249 int
250 attribute_set_owner (attribute_t attr, message_t *msg)
251 {
252 if (attr == NULL)
253 return EINVAL;
254 attr->message = msg;
255 return 0;
256 }
257
258 int
259 attribute_get_owner (attribute_t attr, message_t *msg)
260 {
261 if (attr == NULL)
262 return EINVAL;
263 if (msg)
264 *msg = attr->message;
265 return 0;
266 }
......
...@@ -60,6 +60,8 @@ extern int attribute_unset_draft __P ((attribute_t)); ...@@ -60,6 +60,8 @@ extern int attribute_unset_draft __P ((attribute_t));
60 extern int attribute_unset_recent __P ((attribute_t)); 60 extern int attribute_unset_recent __P ((attribute_t));
61 extern int attribute_unset_read __P ((attribute_t)); 61 extern int attribute_unset_read __P ((attribute_t));
62 62
63 extern int attribute_is_equal __P ((attribute_t att1, attribute_t att2));
64
63 #ifdef __cplusplus 65 #ifdef __cplusplus
64 } 66 }
65 #endif 67 #endif
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
18 #ifndef _ATTRIBUTE0_H 18 #ifndef _ATTRIBUTE0_H
19 #define _ATTRIBUTE0_H 19 #define _ATTRIBUTE0_H
20 20
21 #include <message.h>
21 #include <attribute.h> 22 #include <attribute.h>
22 23
23 #include <sys/types.h> 24 #include <sys/types.h>
...@@ -48,6 +49,11 @@ struct _attribute ...@@ -48,6 +49,11 @@ struct _attribute
48 void *message; 49 void *message;
49 }; 50 };
50 51
52 /* not user visible ?? */
53 extern int attribute_copy __P ((attribute_t dst, attribute_t src));
54 extern int attribute_set_owner __P ((attribute_t attr, message_t *msg));
55 extern int attribute_get_owner __P ((attribute_t attr, message_t *msg));
56
51 #ifdef __cplusplus 57 #ifdef __cplusplus
52 } 58 }
53 #endif 59 #endif
......
...@@ -45,7 +45,7 @@ int ...@@ -45,7 +45,7 @@ int
45 header_set_value (header_t h, const char *fn, const char *fb, size_t n, 45 header_set_value (header_t h, const char *fn, const char *fb, size_t n,
46 int replace) 46 int replace)
47 { 47 {
48 if (h == NULL) 48 if (h == NULL || h->_set_value == NULL)
49 return EINVAL; 49 return EINVAL;
50 return h->_set_value (h, fn, fb, n, replace); 50 return h->_set_value (h, fn, fb, n, replace);
51 } 51 }
...@@ -54,15 +54,41 @@ int ...@@ -54,15 +54,41 @@ int
54 header_get_value (header_t h, const char *fn, char *fb, 54 header_get_value (header_t h, const char *fn, char *fb,
55 size_t len, size_t *n) 55 size_t len, size_t *n)
56 { 56 {
57 if (h == NULL) 57 if (h == NULL || h->_get_value == NULL )
58 return EINVAL; 58 return EINVAL;
59 return h->_get_value (h, fn, fb, len, n); 59 return h->_get_value (h, fn, fb, len, n);
60 } 60 }
61 61
62 int
63 header_entry_name (header_t h, size_t num, char *buf, size_t len, size_t *n)
64 {
65 if (h == NULL || h->_entry_name == NULL)
66 return EINVAL;
67
68 return h->_entry_name (h, num, buf, len, n);
69 }
70
71 int
72 header_entry_value (header_t h, size_t num, char *buf, size_t len, size_t *n)
73 {
74 if (h == NULL || h->_entry_value == NULL)
75 return EINVAL;
76
77 return h->_entry_value (h, num, buf, len, n);
78 }
79
80 int
81 header_entry_count (header_t h, size_t *num)
82 {
83 if (h == NULL || h->_entry_count)
84 return EINVAL;
85 return h->_entry_count (h, num);
86 }
87
62 ssize_t 88 ssize_t
63 header_get_data (header_t h, char *data, size_t len, off_t off, int *err) 89 header_get_data (header_t h, char *data, size_t len, off_t off, int *err)
64 { 90 {
65 if (h == NULL) 91 if (h == NULL || h->_get_data)
66 return EINVAL; 92 return EINVAL;
67 return h->_get_data (h, data, len, off, err); 93 return h->_get_data (h, data, len, off, err);
68 } 94 }
......
...@@ -74,9 +74,12 @@ extern void header_destroy __P ((header_t *)); ...@@ -74,9 +74,12 @@ extern void header_destroy __P ((header_t *));
74 extern int header_set_value __P ((header_t, const char *fn, 74 extern int header_set_value __P ((header_t, const char *fn,
75 const char *fv, size_t n, int replace)); 75 const char *fv, size_t n, int replace));
76 extern int header_get_value __P ((header_t, const char *fn, char *fv, 76 extern int header_get_value __P ((header_t, const char *fn, char *fv,
77 size_t len, size_t *n)); 77 size_t len, size_t *nwritten));
78 extern ssize_t header_get_data __P ((header_t h, char *data, 78 extern int header_entry_count __P ((header_t, size_t *num));
79 size_t len, off_t off, int *err)); 79 extern int header_entry_name __P ((header_t, size_t num, char *buf,
80 size_t buflen, size_t *total));
81 extern int header_entry_value __P ((header_t, size_t num, char *buf,
82 size_t buflen, size_t *total));
80 #ifdef _cpluscplus 83 #ifdef _cpluscplus
81 } 84 }
82 #endif 85 #endif
......
...@@ -44,6 +44,7 @@ typedef struct _hdr *hdr_t; ...@@ -44,6 +44,7 @@ typedef struct _hdr *hdr_t;
44 44
45 struct _header 45 struct _header
46 { 46 {
47 size_t num;
47 /* Data */ 48 /* Data */
48 void *data; 49 void *data;
49 /* owner ? */ 50 /* owner ? */
...@@ -56,13 +57,23 @@ struct _header ...@@ -56,13 +57,23 @@ struct _header
56 size_t n, int replace)); 57 size_t n, int replace));
57 int (*_get_value) __P ((header_t, const char *fn, char *fv, 58 int (*_get_value) __P ((header_t, const char *fn, char *fv,
58 size_t len, size_t *n)); 59 size_t len, size_t *n));
59 ssize_t (*_get_data) __P ((header_t h, char *data, 60 int (*_entry_count) __P ((header_t, size_t *));
60 size_t len, off_t off, int *err)); 61 int (*_entry_name) __P ((header_t, size_t num, char *buf,
62 size_t buflen, size_t *nwritten));
63 int (*_entry_value) __P ((header_t, size_t num, char *buf,
64 size_t buflen, size_t *nwritten));
65 ssize_t (*_get_data) __P ((header_t h, char *data, size_t len,
66 off_t off, int *err));
61 int (*_parse) __P ((header_t, const char *blurb, size_t len)); 67 int (*_parse) __P ((header_t, const char *blurb, size_t len));
62 } ; 68 };
63 69
70 extern ssize_t header_get_data __P ((header_t h, char *data,
71 size_t len, off_t off, int *err));
72
73 /* rfc822 */
64 extern int rfc822_init __P ((header_t *ph, const char *blurb, size_t len)); 74 extern int rfc822_init __P ((header_t *ph, const char *blurb, size_t len));
65 extern void rfc822_destroy __P ((header_t *ph)); 75 extern void rfc822_destroy __P ((header_t *ph));
76
66 #ifdef _cpluscplus 77 #ifdef _cpluscplus
67 } 78 }
68 #endif 79 #endif
......
...@@ -61,11 +61,7 @@ mailbox_init (mailbox_t *pmbox, const char *name, int id) ...@@ -61,11 +61,7 @@ mailbox_init (mailbox_t *pmbox, const char *name, int id)
61 61
62 /* if things went ok set mreg for mailbox_destroy and the URL */ 62 /* if things went ok set mreg for mailbox_destroy and the URL */
63 if (status == 0) 63 if (status == 0)
64 {
65 (*pmbox)->url = url; 64 (*pmbox)->url = url;
66 (*pmbox)->_init = mreg->_init;
67 (*pmbox)->_destroy = mreg->_destroy;
68 }
69 return status; 65 return status;
70 } 66 }
71 67
...@@ -245,10 +241,26 @@ mailbox_set_auth (mailbox_t mbox, auth_t auth) ...@@ -245,10 +241,26 @@ mailbox_set_auth (mailbox_t mbox, auth_t auth)
245 } 241 }
246 242
247 int 243 int
248 mailbox_get_auth (mailbox_t mbox, auth_t *auth) 244 mailbox_get_auth (mailbox_t mbox, auth_t *pauth)
249 { 245 {
250 if (mbox == NULL || auth == NULL) 246 if (mbox == NULL || pauth == NULL)
251 return EINVAL; 247 return EINVAL;
252 *auth = mbox->auth; 248 *pauth = mbox->auth;
253 return 0; 249 return 0;
254 } 250 }
251
252 int
253 mailbox_get_attribute (mailbox_t mbox, size_t msgno, attribute_t *pattr)
254 {
255 if (mbox == NULL || mbox->_get_attribute == NULL)
256 return ENOSYS;
257 return mbox->_get_attribute (mbox, msgno, pattr);
258 }
259
260 int
261 mailbox_set_attribute (mailbox_t mbox, size_t msgno, attribute_t attr)
262 {
263 if (mbox == NULL || mbox->_set_attribute == NULL)
264 return ENOSYS;
265 return mbox->_set_attribute (mbox, msgno, attr);
266 }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
22 22
23 #include <url.h> 23 #include <url.h>
24 #include <message.h> 24 #include <message.h>
25 #include <attribute.h>
25 #include <auth.h> 26 #include <auth.h>
26 #include <locker.h> 27 #include <locker.h>
27 28
......
...@@ -85,6 +85,10 @@ struct _mailbox ...@@ -85,6 +85,10 @@ struct _mailbox
85 size_t len, off_t off, int *err)); 85 size_t len, off_t off, int *err));
86 ssize_t (*_get_body) __P ((mailbox_t, size_t msgno, char *b, 86 ssize_t (*_get_body) __P ((mailbox_t, size_t msgno, char *b,
87 size_t len, off_t off, int *err)); 87 size_t len, off_t off, int *err));
88 int (*_get_attribute) __P ((mailbox_t mbox, size_t msgno,
89 attribute_t *attr));
90 int (*_set_attribute) __P ((mailbox_t mbox, size_t msgno,
91 attribute_t attr));
88 }; 92 };
89 93
90 /* private */ 94 /* private */
...@@ -103,6 +107,10 @@ extern int mailbox_get_auth __P ((mailbox_t mbox, auth_t *auth)); ...@@ -103,6 +107,10 @@ extern int mailbox_get_auth __P ((mailbox_t mbox, auth_t *auth));
103 extern int mailbox_set_auth __P ((mailbox_t mbox, auth_t auth)); 107 extern int mailbox_set_auth __P ((mailbox_t mbox, auth_t auth));
104 extern int mailbox_get_locker __P ((mailbox_t mbox, locker_t *locker)); 108 extern int mailbox_get_locker __P ((mailbox_t mbox, locker_t *locker));
105 extern int mailbox_set_locker __P ((mailbox_t mbox, locker_t locker)); 109 extern int mailbox_set_locker __P ((mailbox_t mbox, locker_t locker));
110 extern int mailbox_get_attribute __P ((mailbox_t mbox, size_t msgno,
111 attribute_t *attr));
112 extern int mailbox_set_attribute __P ((mailbox_t mbox, size_t msgno,
113 attribute_t attr));
106 extern int mailbox_progress __P ((mailbox_t mbox, 114 extern int mailbox_progress __P ((mailbox_t mbox,
107 int (*progress) (int, void *arg), 115 int (*progress) (int, void *arg),
108 void *arg)); 116 void *arg));
......
...@@ -32,32 +32,41 @@ struct mailbox_registrar _mailbox_mbox_registrar = ...@@ -32,32 +32,41 @@ struct mailbox_registrar _mailbox_mbox_registrar =
32 }; 32 };
33 33
34 /* 34 /*
35 if there is no specific URL for file mailbox, 35 Caveat there is no specific URL for file mailbox or simple path name,
36 file://<path_name> 36 <path_name>
37 file:<path_name>
37 38
38 It would be preferrable to use : 39 It would be preferrable to use :
39 maildir://<path> 40 maildir:<path>
40 unix://<path> 41 unix:<path>
41 mmdf://<path> 42 mmdf:<path>
42 This would eliminate heuristic discovery that would turn 43 This would eliminate heuristic discovery that would turn
43 out to be wrong. Caveat, there is no std URL for those 44 out to be wrong.
44 mailbox.
45 */ 45 */
46 46
47 static int 47 static int
48 mailbox_mbox_init (mailbox_t *mbox, const char *name) 48 mailbox_mbox_init (mailbox_t *mbox, const char *name)
49 { 49 {
50 struct stat st; 50 struct stat st;
51 char *scheme = strstr (name, "://"); 51 size_t len;
52 52
53 if (scheme) 53 if (name == NULL || mbox == NULL)
54 return EINVAL;
55
56 len = strlen (name);
57 if (len >= 5 &&
58 (name[0] == 'f' || name[0] == 'F') &&
59 (name[1] == 'i' || name[1] == 'I') &&
60 (name[2] == 'l' || name[2] == 'L') &&
61 (name[3] == 'e' || name[3] == 'E') &&
62 name[4] == ':')
54 { 63 {
55 scheme += 3; 64 name += 5;
56 name = scheme;
57 } 65 }
58 /* 66 /*
59 If they want to creat ?? should they know the type ??? 67 * If they want to creat ?? should they know the type ???
60 What is the best course of action ?? 68 * What is the best course of action ??
69 * For the default is unix if the file does not exist.
61 */ 70 */
62 if (stat (name, &st) < 0) 71 if (stat (name, &st) < 0)
63 return _mailbox_unix_registrar._init (mbox, name); 72 return _mailbox_unix_registrar._init (mbox, name);
...@@ -99,7 +108,7 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name) ...@@ -99,7 +108,7 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name)
99 { 108 {
100 if (strncmp (head, "From ", 5) == 0) 109 if (strncmp (head, "From ", 5) == 0)
101 { 110 {
102 /* This is Unix Mbox */ 111 /* This is a Unix Mbox */
103 close (fd); 112 close (fd);
104 return _mailbox_unix_registrar._init (mbox, name); 113 return _mailbox_unix_registrar._init (mbox, name);
105 } 114 }
......
...@@ -183,12 +183,37 @@ message_size (message_t msg, size_t *size) ...@@ -183,12 +183,37 @@ message_size (message_t msg, size_t *size)
183 size_t hs, bs; 183 size_t hs, bs;
184 int status; 184 int status;
185 status = mailbox_get_size (msg->mailbox, msg->num, &hs, &bs); 185 status = mailbox_get_size (msg->mailbox, msg->num, &hs, &bs);
186 if (status == 0) 186 if (status != 0)
187 { 187 return status;
188 if (size)
189 *size = hs + bs; 188 *size = hs + bs;
189 return 0;
190 } 190 }
191 return ENOSYS;
192 }
193
194 int
195 message_get_attribute (message_t msg, attribute_t *pattribute)
196 {
197 if (msg == NULL || pattribute == NULL)
198 return EINVAL;
199 if (msg->attribute)
200 *pattribute = msg->attribute;
201 if (msg->mailbox)
202 {
203 int status;
204 status = mailbox_get_attribute (msg->mailbox, msg->num, pattribute);
205 if (status != 0)
191 return status; 206 return status;
207 msg->attribute = *pattribute;
208 (*pattribute)->message = msg;
209 return 0;
192 } 210 }
193 return ENOSYS; 211 return ENOSYS;
194 } 212 }
213
214 int
215 message_set_attribute (message_t msg, attribute_t attribute)
216 {
217 (void)msg; (void)attribute;
218 return ENOSYS;
219 }
......
...@@ -33,11 +33,12 @@ ...@@ -33,11 +33,12 @@
33 33
34 static struct _registrar registrar [] = { 34 static struct _registrar registrar [] = {
35 { NULL, NULL, 0, &registrar[1] }, /* sentinel, head list */ 35 { NULL, NULL, 0, &registrar[1] }, /* sentinel, head list */
36 { &_url_mbox_registrar, &_mailbox_mbox_registrar, 0, &registrar[2] }, 36 { &_url_file_registrar, &_mailbox_mbox_registrar, 0, &registrar[2] },
37 { &_url_unix_registrar, &_mailbox_unix_registrar, 0, &registrar[3] }, 37 { &_url_mbox_registrar, &_mailbox_mbox_registrar, 0, &registrar[3] },
38 { &_url_maildir_registrar, &_mailbox_maildir_registrar, 0, &registrar[4] }, 38 { &_url_unix_registrar, &_mailbox_unix_registrar, 0, &registrar[4] },
39 { &_url_mmdf_registrar, &_mailbox_mmdf_registrar, 0, &registrar[5] }, 39 { &_url_maildir_registrar, &_mailbox_maildir_registrar, 0, &registrar[5] },
40 { &_url_pop_registrar, &_mailbox_pop_registrar, 0, &registrar[6] }, 40 { &_url_mmdf_registrar, &_mailbox_mmdf_registrar, 0, &registrar[6] },
41 { &_url_pop_registrar, &_mailbox_pop_registrar, 0, &registrar[7] },
41 { &_url_imap_registrar, &_mailbox_imap_registrar, 0, &registrar[0] }, 42 { &_url_imap_registrar, &_mailbox_imap_registrar, 0, &registrar[0] },
42 }; 43 };
43 44
...@@ -175,6 +176,43 @@ registrar_get (int id, ...@@ -175,6 +176,43 @@ registrar_get (int id,
175 } 176 }
176 177
177 int 178 int
179 registrar_entry_count (size_t *num)
180 {
181 struct _registrar *current;
182 size_t count;
183 for (count = 0, current = registrar->next; current != registrar;
184 current = current->next, count++)
185 ;
186 if (num)
187 *num = count;
188 return 0;
189 }
190
191 int
192 registrar_entry (size_t num, struct url_registrar **ureg,
193 struct mailbox_registrar **mreg, int *id)
194 {
195 struct _registrar *current;
196 size_t count, status;
197 for (status = ENOENT, count = 0, current = registrar->next;
198 current != registrar; current = current->next, count++)
199 {
200 if (num == count)
201 {
202 if (ureg)
203 *ureg = current->ureg;
204 if (mreg)
205 *mreg = current->mreg;
206 if (id)
207 *id = (int)current;
208 status = 0;
209 break;
210 }
211 }
212 return status;
213 }
214
215 int
178 registrar_list (struct url_registrar **ureg, struct mailbox_registrar **mreg, 216 registrar_list (struct url_registrar **ureg, struct mailbox_registrar **mreg,
179 int *id, registrar_t *reg) 217 int *id, registrar_t *reg)
180 { 218 {
......
...@@ -59,6 +59,10 @@ extern int registrar_add __P ((struct url_registrar *ureg, ...@@ -59,6 +59,10 @@ extern int registrar_add __P ((struct url_registrar *ureg,
59 extern int registrar_remove __P ((int id)); 59 extern int registrar_remove __P ((int id));
60 extern int registrar_get __P ((int id, struct url_registrar **ureg, 60 extern int registrar_get __P ((int id, struct url_registrar **ureg,
61 struct mailbox_registrar **mreg)); 61 struct mailbox_registrar **mreg));
62 extern int registrar_num __P ((size_t *num));
63 extern int registrar_get_entry __P ((size_t num, struct url_registrar **ureg,
64 struct mailbox_registrar **mreg,
65 int *id));
62 extern int registrar_list __P ((struct url_registrar **ureg, 66 extern int registrar_list __P ((struct url_registrar **ureg,
63 struct mailbox_registrar **mreg, 67 struct mailbox_registrar **mreg,
64 int *id, registrar_t *reg)); 68 int *id, registrar_t *reg));
......
...@@ -46,10 +46,21 @@ struct _registrar ...@@ -46,10 +46,21 @@ struct _registrar
46 struct _registrar *next; 46 struct _registrar *next;
47 }; 47 };
48 48
49
50 /* This is function is obsolete use the registrar_entry_*() ones */
51 extern int registrar_list __P ((struct url_registrar **ureg,
52 struct mailbox_registrar **mreg,
53 int *id, registrar_t *reg));
54 extern int registrar_entry_count __P ((size_t *num));
55 extern int registrar_entry __P ((size_t num, struct url_registrar **ureg,
56 struct mailbox_registrar **mreg,
57 int *id));
49 /* IMAP */ 58 /* IMAP */
50 extern struct mailbox_registrar _mailbox_imap_registrar; 59 extern struct mailbox_registrar _mailbox_imap_registrar;
51 extern struct url_registrar _url_imap_registrar; 60 extern struct url_registrar _url_imap_registrar;
52 61
62 /* FILE */
63 extern struct url_registrar _url_file_registrar;
53 /* MBOX */ 64 /* MBOX */
54 extern struct mailbox_registrar _mailbox_mbox_registrar; 65 extern struct mailbox_registrar _mailbox_mbox_registrar;
55 extern struct url_registrar _url_mbox_registrar; 66 extern struct url_registrar _url_mbox_registrar;
......
...@@ -28,10 +28,15 @@ ...@@ -28,10 +28,15 @@
28 static int rfc822_parse (header_t h, const char *blurb, size_t len); 28 static int rfc822_parse (header_t h, const char *blurb, size_t len);
29 static int rfc822_set_value (header_t h, const char *fn, const char *fb, 29 static int rfc822_set_value (header_t h, const char *fn, const char *fb,
30 size_t n, int replace); 30 size_t n, int replace);
31 ssize_t rfc822_get_data (header_t h, char *buf, size_t buflen, 31 static int rfc822_get_value (header_t h, const char *fn, char *fb,
32 size_t len, size_t *n);
33 static int rfc822_entry_count (header_t, size_t *num);
34 static int rfc822_entry_name (header_t h, size_t num, char *buf,
35 size_t buflen, size_t *total);
36 static int rfc822_entry_value (header_t h, size_t num, char *buf,
37 size_t buflen, size_t *total);
38 static ssize_t rfc822_get_data (header_t h, char *buf, size_t buflen,
32 off_t off, int *err); 39 off_t off, int *err);
33 static int rfc822_get_value (header_t h, const char *fn,
34 char *fb, size_t len, size_t *n);
35 40
36 struct _rfc822 41 struct _rfc822
37 { 42 {
...@@ -57,6 +62,9 @@ rfc822_init (header_t *ph, const char *blurb, size_t len) ...@@ -57,6 +62,9 @@ rfc822_init (header_t *ph, const char *blurb, size_t len)
57 h->_parse = rfc822_parse; 62 h->_parse = rfc822_parse;
58 h->_get_value = rfc822_get_value; 63 h->_get_value = rfc822_get_value;
59 h->_set_value = rfc822_set_value; 64 h->_set_value = rfc822_set_value;
65 h->_entry_count = rfc822_entry_count;
66 h->_entry_name = rfc822_entry_name;
67 h->_entry_value = rfc822_entry_value;
60 h->_get_data = rfc822_get_data; 68 h->_get_data = rfc822_get_data;
61 69
62 status = h->_parse (h, blurb, len); 70 status = h->_parse (h, blurb, len);
...@@ -90,6 +98,14 @@ rfc822_destroy (header_t *ph) ...@@ -90,6 +98,14 @@ rfc822_destroy (header_t *ph)
90 } 98 }
91 } 99 }
92 100
101 /*
102 * Parsing is done in a rather simple fashion.
103 * meaning we just consider an entry to be
104 * a field-name an a field-value. So they
105 * maybe duplicate of field-name like "Received"
106 * they are just put in the array, see _get_value()
107 * on how to handle the case.
108 */
93 static int 109 static int
94 rfc822_parse (header_t h, const char *blurb, size_t len) 110 rfc822_parse (header_t h, const char *blurb, size_t len)
95 { 111 {
...@@ -118,8 +134,8 @@ rfc822_parse (header_t h, const char *blurb, size_t len) ...@@ -118,8 +134,8 @@ rfc822_parse (header_t h, const char *blurb, size_t len)
118 for (header_start = rfc->blurb;; header_start = ++header_end) 134 for (header_start = rfc->blurb;; header_start = ++header_end)
119 { 135 {
120 /* get a header, a header is : 136 /* get a header, a header is :
121 field-name ':' field-body1 137 * field-name ':' ' ' field-value '\r' '\n'
122 [ ' ' '\t' field-body2 ] '\r' '\n' 138 * [ (' ' | '\t') field-value '\r' '\n' ]
123 */ 139 */
124 for (header_start2 = header_start;;header_start2 = ++header_end) 140 for (header_start2 = header_start;;header_start2 = ++header_end)
125 { 141 {
...@@ -195,36 +211,124 @@ rfc822_set_value (header_t h, const char *fn, const char *fv, ...@@ -195,36 +211,124 @@ rfc822_set_value (header_t h, const char *fn, const char *fv,
195 } 211 }
196 212
197 static int 213 static int
198 rfc822_get_value (header_t h, const char *fn, char *fv, size_t len, size_t *n) 214 rfc822_get_value (header_t h, const char *name, char *buffer,
215 size_t buflen, size_t *n)
199 { 216 {
200 size_t i = 0; 217 size_t i = 0;
201 size_t j = 0; 218 size_t name_len;
202 size_t name_len, fn_len, fv_len; 219 size_t total = 0, fn_len = 0, fv_len = 0;
220 int threshold;
203 rfc822_t rfc; 221 rfc822_t rfc;
204 222
205 if (h == NULL || fn == NULL || (rfc = (rfc822_t)h->data) == NULL) 223 if (h == NULL || name == NULL ||
224 (rfc = (rfc822_t)h->data) == NULL)
206 return EINVAL; 225 return EINVAL;
207 226
208 for (name_len = strlen (fn), i = 0; i < rfc->hdr_count; i++) 227 /* we set the threshold to be 1 less for the null */
228 threshold = --buflen;
229
230 /*
231 * Caution: We may have more then one value for a field
232 * name, for example a "Received" field-name is added by
233 * each passing MTA. The way that the parsing (_parse())
234 * is done it's not take to account. So we just stuff in
235 * the buffer all the field-values to a corresponding field-name.
236 * FIXME: Should we kosher the output ? meaning replace
237 * occurences of " \t\r\n" for spaces ? for now we don't.
238 */
239 for (name_len = strlen (name), i = 0; i < rfc->hdr_count; i++)
209 { 240 {
210 fn_len = rfc->hdr[i].fn_end - rfc->hdr[i].fn; 241 fn_len = rfc->hdr[i].fn_end - rfc->hdr[i].fn;
211 if (fn_len == name_len && memcmp (rfc->hdr[i].fn, fn, fn_len) == 0) 242 if (fn_len == name_len && memcmp (rfc->hdr[i].fn, name, fn_len) == 0)
212 { 243 {
213 fv_len = rfc->hdr[i].fv_end - rfc->hdr[i].fv; 244 fv_len = (rfc->hdr[i].fv_end - rfc->hdr[i].fv);
214 j = (len < fv_len) ? len : fv_len; 245 total += fv_len;
215 if (fv) 246 /* can everything fit in the buffer */
216 memcpy (fv, rfc->hdr[i].fv, j); 247 if (buffer && threshold > 0)
217 break; 248 {
249 threshold -= fv_len;
250 if (threshold > 0)
251 {
252 memcpy (buffer, rfc->hdr[i].fv, fv_len);
253 buffer += fv_len;
254 }
255 else if (threshold < 0)
256 {
257 threshold += fv_len;
258 memcpy (buffer, rfc->hdr[i].fv, threshold);
259 buffer += threshold;
260 threshold = 0;
261 }
262 }
218 } 263 }
219 } 264 }
220 if (fv) 265 if (buffer)
221 fv[j] = '\0'; /* null terminated */ 266 *buffer = '\0'; /* null terminated */
222 if (n) 267 if (n)
223 *n = fv_len; 268 *n = total;
269 return 0;
270 }
271
272 static int
273 rfc822_entry_count (header_t h, size_t *num)
274 {
275 rfc822_t rfc;
276 if (h == NULL || (rfc = (rfc822_t)h->data) == NULL)
277 return EINVAL;
278 if (num)
279 *num = rfc->hdr_count;
280 return 0;
281 }
282
283 static int
284 rfc822_entry_name (header_t h, size_t num, char *buf,
285 size_t buflen, size_t *nwritten)
286 {
287 rfc822_t rfc;
288 size_t len;
289 if (h == NULL || (rfc = (rfc822_t)h->data) == NULL)
290 return EINVAL;
291 if (rfc->hdr_count == 0 || num > rfc->hdr_count)
292 return ENOENT;
293 len = rfc->hdr[num].fn_end - rfc->hdr[num].fn;
294 /* save one for the null */
295 --buflen;
296 if (buf && buflen > 0)
297 {
298 buflen = (len > buflen) ? buflen : len;
299 memcpy (buf, rfc->hdr[num].fn, buflen);
300 buf[buflen] = '\0';
301 }
302 if (nwritten)
303 *nwritten = len;
304 return 0;
305 }
306
307 static int
308 rfc822_entry_value (header_t h, size_t num, char *buf,
309 size_t buflen, size_t *nwritten)
310 {
311 rfc822_t rfc;
312 size_t len;
313 if (h == NULL || (rfc = (rfc822_t)h->data) == NULL)
314 return EINVAL;
315 if (rfc->hdr_count == 0 || num > rfc->hdr_count)
316 return ENOENT;
317 len = rfc->hdr[num].fv_end - rfc->hdr[num].fv;
318 /* save one for the null */
319 --buflen;
320 if (buf && buflen > 0)
321 {
322 buflen = (len > buflen) ? buflen : len;
323 memcpy (buf, rfc->hdr[num].fv, buflen);
324 buf[buflen] = '\0';
325 }
326 if (nwritten)
327 *nwritten = len;
224 return 0; 328 return 0;
225 } 329 }
226 330
227 ssize_t 331 static ssize_t
228 rfc822_get_data (header_t h, char *buf, size_t buflen, off_t off, int *err) 332 rfc822_get_data (header_t h, char *buf, size_t buflen, off_t off, int *err)
229 { 333 {
230 rfc822_t rfc; 334 rfc822_t rfc;
......
...@@ -47,6 +47,7 @@ url_init (url_t * purl, const char *name) ...@@ -47,6 +47,7 @@ url_init (url_t * purl, const char *name)
47 registrar_t reg = NULL; 47 registrar_t reg = NULL;
48 size_t name_len; 48 size_t name_len;
49 int id; 49 int id;
50 size_t i, entry_count = 0;
50 51
51 /* Sanity checks */ 52 /* Sanity checks */
52 if (name == NULL || *name == '\0') 53 if (name == NULL || *name == '\0')
...@@ -55,6 +56,22 @@ url_init (url_t * purl, const char *name) ...@@ -55,6 +56,22 @@ url_init (url_t * purl, const char *name)
55 name_len = strlen (name); 56 name_len = strlen (name);
56 57
57 /* Search for a known scheme */ 58 /* Search for a known scheme */
59 registrar_entry_count (&entry_count);
60 for (i = 0; i < entry_count; i++)
61 {
62 if (registrar_entry (i, &ureg, &mreg, &id) == 0)
63 {
64 size_t scheme_len;
65 if (ureg && ureg->scheme &&
66 name_len > (scheme_len = strlen (ureg->scheme)) &&
67 memcmp (name, ureg->scheme, scheme_len) == 0)
68 {
69 status = 0;
70 break;
71 }
72 }
73 }
74 /*
58 while (registrar_list (&ureg, &mreg, &id, &reg) == 0) 75 while (registrar_list (&ureg, &mreg, &id, &reg) == 0)
59 { 76 {
60 size_t scheme_len; 77 size_t scheme_len;
...@@ -66,6 +83,7 @@ url_init (url_t * purl, const char *name) ...@@ -66,6 +83,7 @@ url_init (url_t * purl, const char *name)
66 break; 83 break;
67 } 84 }
68 } 85 }
86 */
69 87
70 /* Found one initialize it */ 88 /* Found one initialize it */
71 if (status == 0) 89 if (status == 0)
......