Commit 24d3722e 24d3722ecab73da942988dc586ebfc28748fb873 by Alain Magloire

Cleanup again and all of this done with one hand !!!

We're moving closer to cleaning the repository and using
autoconf and all.  But my keyboard quota is almost expired.
1 parent 75a14dc5
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
23 #include <errno.h> 23 #include <errno.h>
24 24
25 int 25 int
26 attribute_create (attribute_t *pattr) 26 attribute_create (attribute_t *pattr, void *owner)
27 { 27 {
28 attribute_t attr; 28 attribute_t attr;
29 if (pattr == NULL) 29 if (pattr == NULL)
...@@ -31,16 +31,19 @@ attribute_create (attribute_t *pattr) ...@@ -31,16 +31,19 @@ attribute_create (attribute_t *pattr)
31 attr = calloc (1, sizeof(*attr)); 31 attr = calloc (1, sizeof(*attr));
32 if (attr == NULL) 32 if (attr == NULL)
33 return ENOMEM; 33 return ENOMEM;
34 attr->owner = owner;
34 *pattr = attr; 35 *pattr = attr;
35 return 0; 36 return 0;
36 } 37 }
37 38
38 void 39 void
39 attribute_destroy (attribute_t *pattr) 40 attribute_destroy (attribute_t *pattr, void *owner)
40 { 41 {
41 if (pattr && *pattr) 42 if (pattr && *pattr)
42 { 43 {
43 free (*pattr); 44 attribute_t attr = *pattr;
45 if (attr->owner != owner)
46 free (*pattr);
44 /* loose the link */ 47 /* loose the link */
45 *pattr = NULL; 48 *pattr = NULL;
46 } 49 }
...@@ -48,68 +51,144 @@ attribute_destroy (attribute_t *pattr) ...@@ -48,68 +51,144 @@ attribute_destroy (attribute_t *pattr)
48 } 51 }
49 52
50 int 53 int
54 attribute_get_flags (attribute_t attr, int *pflags)
55 {
56 if (attr->_get_flags)
57 return attr->_get_flags (attr, pflags);
58 if (pflags)
59 *pflags = attr->flags;
60 return 0;
61 }
62
63 int
64 attribute_set_flags (attribute_t attr, int flags)
65 {
66 if (attr->_set_flags)
67 return attr->_set_flags (attr, flags);
68 attr->flags |= flags;
69 return 0;
70 }
71
72 int
73 attribute_set_get_flags (attribute_t attr, int (*_get_flags)
74 (attribute_t, int *), void *owner)
75 {
76 if (attr == NULL)
77 return EINVAL;
78 if (attr->owner != owner)
79 return EACCES;
80 attr->_get_flags = _get_flags;
81 return 0;
82 }
83
84 int
85 attribute_set_set_flags (attribute_t attr, int (*_set_flags)
86 (attribute_t, int), void *owner)
87 {
88 if (attr == NULL)
89 return EINVAL;
90 if (attr->owner != owner)
91 return EACCES;
92 attr->_set_flags = _set_flags;
93 return 0;
94 }
95
96 int
97 attribute_set_unset_flags (attribute_t attr, int (*_unset_flags)
98 (attribute_t, int), void *owner)
99 {
100 if (attr == NULL)
101 return EINVAL;
102 if (attr->owner != owner)
103 return EACCES;
104 attr->_unset_flags = _unset_flags;
105 return 0;
106 }
107
108 int
51 attribute_set_seen (attribute_t attr) 109 attribute_set_seen (attribute_t attr)
52 { 110 {
111 int status = 0;
53 if (attr == NULL) 112 if (attr == NULL)
54 return EINVAL; 113 return EINVAL;
55 attr->flag |= MU_ATTRIBUTE_SEEN; 114 if (attr->_get_flags)
115 status = attr->_get_flags (attr, &(attr->flags));
116 attr->flags |= MU_ATTRIBUTE_SEEN;
56 return 0; 117 return 0;
57 } 118 }
58 119
59 int 120 int
60 attribute_set_answered (attribute_t attr) 121 attribute_set_answered (attribute_t attr)
61 { 122 {
123 int status = 0;
62 if (attr == NULL) 124 if (attr == NULL)
63 return EINVAL; 125 return EINVAL;
64 attr->flag |= MU_ATTRIBUTE_ANSWERED; 126 if (attr->_get_flags)
127 status = attr->_get_flags (attr, &(attr->flags));
128 attr->flags |= MU_ATTRIBUTE_ANSWERED;
65 return 0; 129 return 0;
66 } 130 }
67 131
68 int 132 int
69 attribute_set_flagged (attribute_t attr) 133 attribute_set_flagged (attribute_t attr)
70 { 134 {
135 int status = 0;
71 if (attr == NULL) 136 if (attr == NULL)
72 return EINVAL; 137 return EINVAL;
73 attr->flag |= MU_ATTRIBUTE_FLAGGED; 138 if (attr->_get_flags)
139 status = attr->_get_flags (attr, &(attr->flags));
140 attr->flags |= MU_ATTRIBUTE_FLAGGED;
74 return 0; 141 return 0;
75 } 142 }
76 143
77 int 144 int
78 attribute_set_read (attribute_t attr) 145 attribute_set_read (attribute_t attr)
79 { 146 {
147 int status = 0;
80 if (attr == NULL) 148 if (attr == NULL)
81 return EINVAL; 149 return EINVAL;
82 attr->flag |= MU_ATTRIBUTE_READ; 150 if (attr->_get_flags)
151 status = attr->_get_flags (attr, &(attr->flags));
152 attr->flags |= MU_ATTRIBUTE_READ;
83 return 0; 153 return 0;
84 } 154 }
85 155
86 int 156 int
87 attribute_set_deleted (attribute_t attr) 157 attribute_set_deleted (attribute_t attr)
88 { 158 {
159 int status = 0;
89 if (attr == NULL) 160 if (attr == NULL)
90 return EINVAL; 161 return EINVAL;
91 attr->flag |= MU_ATTRIBUTE_DELETED; 162 if (attr->_get_flags)
163 status = attr->_get_flags (attr, &(attr->flags));
164 attr->flags |= MU_ATTRIBUTE_DELETED;
92 return 0; 165 return 0;
93 } 166 }
94 167
95 int 168 int
96 attribute_set_draft (attribute_t attr) 169 attribute_set_draft (attribute_t attr)
97 { 170 {
171 int status = 0;
98 if (attr == NULL) 172 if (attr == NULL)
99 return EINVAL; 173 return EINVAL;
100 attr->flag |= MU_ATTRIBUTE_DRAFT; 174 if (attr->_get_flags)
175 status = attr->_get_flags (attr, &(attr->flags));
176 attr->flags |= MU_ATTRIBUTE_DRAFT;
101 return 0; 177 return 0;
102 } 178 }
103 179
104 int 180 int
105 attribute_set_recent (attribute_t attr) 181 attribute_set_recent (attribute_t attr)
106 { 182 {
183 int status = 0;
107 if (attr == NULL) 184 if (attr == NULL)
108 return EINVAL; 185 return EINVAL;
186 if (attr->_get_flags)
187 status = attr->_get_flags (attr, &(attr->flags));
109 if (attr == NULL) 188 if (attr == NULL)
110 { 189 {
111 attr->flag &= ~MU_ATTRIBUTE_READ; 190 attr->flags &= ~MU_ATTRIBUTE_READ;
112 attr->flag &= ~MU_ATTRIBUTE_SEEN; 191 attr->flags &= ~MU_ATTRIBUTE_SEEN;
113 return 0; 192 return 0;
114 } 193 }
115 return EACCES; 194 return EACCES;
...@@ -118,131 +197,176 @@ attribute_set_recent (attribute_t attr) ...@@ -118,131 +197,176 @@ attribute_set_recent (attribute_t attr)
118 int 197 int
119 attribute_is_seen (attribute_t attr) 198 attribute_is_seen (attribute_t attr)
120 { 199 {
200 int status = 0;
121 if (attr == NULL) 201 if (attr == NULL)
122 return 0; 202 return 0;
123 return attr->flag & MU_ATTRIBUTE_SEEN; 203 if (attr->_get_flags)
204 status = attr->_get_flags (attr, &(attr->flags));
205 return attr->flags & MU_ATTRIBUTE_SEEN;
124 } 206 }
125 207
126 int 208 int
127 attribute_is_answered (attribute_t attr) 209 attribute_is_answered (attribute_t attr)
128 { 210 {
211 int status = 0;
129 if (attr == NULL) 212 if (attr == NULL)
130 return 0; 213 return 0;
131 return attr->flag & MU_ATTRIBUTE_ANSWERED; 214 if (attr->_get_flags)
215 status = attr->_get_flags (attr, &(attr->flags));
216 return attr->flags & MU_ATTRIBUTE_ANSWERED;
132 } 217 }
133 218
134 int 219 int
135 attribute_is_flagged (attribute_t attr) 220 attribute_is_flagged (attribute_t attr)
136 { 221 {
222 int status = 0;
137 if (attr == NULL) 223 if (attr == NULL)
138 return 0; 224 return 0;
139 return attr->flag & MU_ATTRIBUTE_FLAGGED; 225 if (attr->_get_flags)
226 status = attr->_get_flags (attr, &(attr->flags));
227 return attr->flags & MU_ATTRIBUTE_FLAGGED;
140 } 228 }
141 229
142 int 230 int
143 attribute_is_read (attribute_t attr) 231 attribute_is_read (attribute_t attr)
144 { 232 {
233 int status = 0;
145 if (attr == NULL) 234 if (attr == NULL)
146 return 0; 235 return 0;
147 return attr->flag & MU_ATTRIBUTE_READ; 236 if (attr->_get_flags)
237 status = attr->_get_flags (attr, &(attr->flags));
238 return attr->flags & MU_ATTRIBUTE_READ;
148 } 239 }
149 240
150 int 241 int
151 attribute_is_deleted (attribute_t attr) 242 attribute_is_deleted (attribute_t attr)
152 { 243 {
244 int status = 0;
153 if (attr == NULL) 245 if (attr == NULL)
154 return 0; 246 return 0;
155 return attr->flag & MU_ATTRIBUTE_DELETED; 247 if (attr->_get_flags)
248 status = attr->_get_flags (attr, &(attr->flags));
249 return attr->flags & MU_ATTRIBUTE_DELETED;
156 } 250 }
157 251
158 int 252 int
159 attribute_is_draft (attribute_t attr) 253 attribute_is_draft (attribute_t attr)
160 { 254 {
255 int status = 0;
161 if (attr == NULL) 256 if (attr == NULL)
162 return 0; 257 return 0;
163 return attr->flag & MU_ATTRIBUTE_DRAFT; 258 if (attr->_get_flags)
259 status = attr->_get_flags (attr, &(attr->flags));
260 return attr->flags & MU_ATTRIBUTE_DRAFT;
164 } 261 }
165 262
166 int 263 int
167 attribute_is_recent (attribute_t attr) 264 attribute_is_recent (attribute_t attr)
168 { 265 {
266 int status = 0;
169 if (attr == NULL) 267 if (attr == NULL)
170 return 0; 268 return 0;
269 if (attr->_get_flags)
270 status = attr->_get_flags (attr, &(attr->flags));
171 /* something is recent when it is not read and not seen. */ 271 /* something is recent when it is not read and not seen. */
172 return (attr->flag == 0 272 return (attr->flags == 0
173 || ! ((attr->flag & MU_ATTRIBUTE_SEEN) 273 || ! ((attr->flags & MU_ATTRIBUTE_SEEN)
174 && (attr->flag & MU_ATTRIBUTE_READ))); 274 && (attr->flags & MU_ATTRIBUTE_READ)));
175 } 275 }
176 276
177 int 277 int
178 attribute_unset_seen (attribute_t attr) 278 attribute_unset_seen (attribute_t attr)
179 { 279 {
280 int status = 0;
180 if (attr == NULL) 281 if (attr == NULL)
181 return 0; 282 return 0;
182 attr->flag &= ~MU_ATTRIBUTE_SEEN; 283 if (attr->_unset_flags)
183 return 0; 284 status = attr->_unset_flags (attr, MU_ATTRIBUTE_SEEN);
285 attr->flags &= ~MU_ATTRIBUTE_SEEN;
286 return status;
184 } 287 }
185 288
186 int 289 int
187 attribute_unset_answered (attribute_t attr) 290 attribute_unset_answered (attribute_t attr)
188 { 291 {
292 int status = 0;
189 if (attr == NULL) 293 if (attr == NULL)
190 return 0; 294 return 0;
191 attr->flag &= ~MU_ATTRIBUTE_ANSWERED; 295 if (attr->_unset_flags)
192 return 0; 296 status = attr->_unset_flags (attr, MU_ATTRIBUTE_ANSWERED);
297 attr->flags &= ~MU_ATTRIBUTE_ANSWERED;
298 return status;
193 } 299 }
194 300
195 int 301 int
196 attribute_unset_flagged (attribute_t attr) 302 attribute_unset_flagged (attribute_t attr)
197 { 303 {
304 int status = 0;
198 if (attr == NULL) 305 if (attr == NULL)
199 return 0; 306 return 0;
200 attr->flag &= ~MU_ATTRIBUTE_FLAGGED; 307 if (attr->_unset_flags)
201 return 0; 308 status = attr->_unset_flags (attr, MU_ATTRIBUTE_FLAGGED);
309 attr->flags &= ~MU_ATTRIBUTE_FLAGGED;
310 return status;
202 } 311 }
203 312
204 int 313 int
205 attribute_unset_read (attribute_t attr) 314 attribute_unset_read (attribute_t attr)
206 { 315 {
316 int status = 0;
207 if (attr == NULL) 317 if (attr == NULL)
208 return 0; 318 return 0;
209 attr->flag &= ~MU_ATTRIBUTE_READ; 319 if (attr->_unset_flags)
210 return 0; 320 status = attr->_unset_flags (attr, MU_ATTRIBUTE_READ);
321 attr->flags &= ~MU_ATTRIBUTE_READ;
322 return status;
211 } 323 }
212 324
213 int 325 int
214 attribute_unset_deleted (attribute_t attr) 326 attribute_unset_deleted (attribute_t attr)
215 { 327 {
328 int status = 0;
216 if (attr == NULL) 329 if (attr == NULL)
217 return 0; 330 return 0;
218 attr->flag &= ~MU_ATTRIBUTE_DELETED; 331 if (attr->_unset_flags)
219 return 0; 332 status = attr->_unset_flags (attr, MU_ATTRIBUTE_DELETED);
333 attr->flags &= ~MU_ATTRIBUTE_DELETED;
334 return status;
220 } 335 }
221 336
222 int 337 int
223 attribute_unset_draft (attribute_t attr) 338 attribute_unset_draft (attribute_t attr)
224 { 339 {
340 int status = 0;
225 if (attr == NULL) 341 if (attr == NULL)
226 return 0; 342 return 0;
227 attr->flag &= ~MU_ATTRIBUTE_DRAFT; 343 if (attr->_unset_flags)
228 return 0; 344 status = attr->_unset_flags (attr, MU_ATTRIBUTE_DRAFT);
345 attr->flags &= ~MU_ATTRIBUTE_DRAFT;
346 return status;
229 } 347 }
230 348
231 int 349 int
232 attribute_unset_recent (attribute_t attr) 350 attribute_unset_recent (attribute_t attr)
233 { 351 {
352 int status = 0;
234 if (attr == NULL) 353 if (attr == NULL)
235 return 0; 354 return 0;
236 attr->flag |= MU_ATTRIBUTE_SEEN; 355 if (attr->_unset_flags)
237 return 0; 356 status = attr->_unset_flags (attr, MU_ATTRIBUTE_SEEN);
357 attr->flags |= MU_ATTRIBUTE_SEEN;
358 return status;
238 } 359 }
239 360
240 int 361 int
241 attribute_is_equal (attribute_t attr, attribute_t attr2) 362 attribute_is_equal (attribute_t attr, attribute_t attr2)
242 { 363 {
364 int status = 0;
243 if (attr == NULL || attr2 == NULL) 365 if (attr == NULL || attr2 == NULL)
244 return 0; 366 return 0;
245 return attr->flag == attr2->flag; 367 if (attr->_get_flags)
368 status = attr->_get_flags (attr, &(attr->flags));
369 return attr->flags == attr2->flags;
246 } 370 }
247 371
248 int 372 int
...@@ -255,14 +379,12 @@ attribute_copy (attribute_t dest, attribute_t src) ...@@ -255,14 +379,12 @@ attribute_copy (attribute_t dest, attribute_t src)
255 } 379 }
256 380
257 int 381 int
258 string_to_attribute (const char *buffer, attribute_t *pattr) 382 string_to_flags (const char *buffer, int *pflags)
259 { 383 {
260 const char *sep; 384 const char *sep;
261 int status;
262 385
263 status = attribute_create (pattr); 386 if (pflags == NULL)
264 if (status != 0) 387 return EINVAL;
265 return status;
266 388
267 /* Set the attribute */ 389 /* Set the attribute */
268 if (strncasecmp (buffer, "Status:", 7) == 0) 390 if (strncasecmp (buffer, "Status:", 7) == 0)
...@@ -271,22 +393,22 @@ string_to_attribute (const char *buffer, attribute_t *pattr) ...@@ -271,22 +393,22 @@ string_to_attribute (const char *buffer, attribute_t *pattr)
271 sep++; 393 sep++;
272 } 394 }
273 else 395 else
274 sep = buffer; 396 return EINVAL;
275 397
276 while (*sep == ' ') sep++; /* glob spaces */ 398 while (*sep == ' ') sep++; /* glob spaces */
277 if (strchr (sep, 'R') != NULL || strchr (sep, 'r') != NULL) 399 if (strchr (sep, 'R') != NULL || strchr (sep, 'r') != NULL)
278 attribute_set_read (*pattr); 400 *pflags |= MU_ATTRIBUTE_READ;
279 if (strchr (sep, 'O') != NULL || strchr (sep, 'o') != NULL) 401 if (strchr (sep, 'O') != NULL || strchr (sep, 'o') != NULL)
280 attribute_set_seen (*pattr); 402 *pflags |= MU_ATTRIBUTE_SEEN;
281 if (strchr (sep, 'A') != NULL || strchr (sep, 'a') != NULL) 403 if (strchr (sep, 'A') != NULL || strchr (sep, 'a') != NULL)
282 attribute_set_answered (*pattr); 404 *pflags |= MU_ATTRIBUTE_ANSWERED;
283 if (strchr (sep, 'F') != NULL || strchr (sep, 'f') != NULL) 405 if (strchr (sep, 'F') != NULL || strchr (sep, 'f') != NULL)
284 attribute_set_flagged (*pattr); 406 *pflags |= MU_ATTRIBUTE_FLAGGED;
285 return 0; 407 return 0;
286 } 408 }
287 409
288 int 410 int
289 attribute_to_string (attribute_t attr, char *buffer, size_t len, size_t *pn) 411 flags_to_string (int flags, char *buffer, size_t len, size_t *pn)
290 { 412 {
291 char status[32]; 413 char status[32];
292 char a[8]; 414 char a[8];
...@@ -294,14 +416,16 @@ attribute_to_string (attribute_t attr, char *buffer, size_t len, size_t *pn) ...@@ -294,14 +416,16 @@ attribute_to_string (attribute_t attr, char *buffer, size_t len, size_t *pn)
294 416
295 *status = *a = '\0'; 417 *status = *a = '\0';
296 418
297 if (attribute_is_seen (attr)) 419 if (flags & MU_ATTRIBUTE_SEEN)
298 strcat (a, "R"); 420 strcat (a, "R");
299 if (attribute_is_answered (attr)) 421 if (flags & MU_ATTRIBUTE_ANSWERED)
300 strcat (a, "A"); 422 strcat (a, "A");
301 if (attribute_is_flagged (attr)) 423 if (flags & MU_ATTRIBUTE_FLAGGED)
302 strcat (a, "F"); 424 strcat (a, "F");
303 if (attribute_is_read (attr)) 425 if (flags & MU_ATTRIBUTE_READ)
304 strcat (a, "O"); 426 strcat (a, "O");
427 if (flags & MU_ATTRIBUTE_DELETED)
428 strcat (a, "d");
305 429
306 if (*a != '\0') 430 if (*a != '\0')
307 { 431 {
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
20 # include "config.h" 20 # include "config.h"
21 #endif 21 #endif
22 22
23 #include <header.h> 23 #include <header0.h>
24 #include <io0.h> 24 #include <io0.h>
25 #include <string.h> 25 #include <string.h>
26 #include <stdlib.h> 26 #include <stdlib.h>
...@@ -33,30 +33,6 @@ static int header_read (stream_t is, char *buf, size_t buflen, ...@@ -33,30 +33,6 @@ static int header_read (stream_t is, char *buf, size_t buflen,
33 static int header_write (stream_t os, const char *buf, size_t buflen, 33 static int header_write (stream_t os, const char *buf, size_t buflen,
34 off_t off, size_t *pnwrite); 34 off_t off, size_t *pnwrite);
35 35
36 struct _hdr
37 {
38 char *fn;
39 char *fn_end;
40 char *fv;
41 char *fv_end;
42 };
43
44 struct _header
45 {
46 /* Owner. */
47 void *owner;
48 /* Data. */
49 char *blurb;
50 size_t blurb_len;
51 size_t hdr_count;
52 struct _hdr *hdr;
53
54 /* Streams. */
55 stream_t stream;
56 int (*_get_value) __P ((header_t, const char *, char *, size_t , size_t *));
57
58 };
59
60 int 36 int
61 header_create (header_t *ph, const char *blurb, size_t len, void *owner) 37 header_create (header_t *ph, const char *blurb, size_t len, void *owner)
62 { 38 {
...@@ -66,6 +42,7 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner) ...@@ -66,6 +42,7 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner)
66 return ENOMEM; 42 return ENOMEM;
67 h->owner = owner; 43 h->owner = owner;
68 44
45 /* Ignore the return value. */
69 header_parse (h, blurb, len); 46 header_parse (h, blurb, len);
70 47
71 *ph = h; 48 *ph = h;
...@@ -83,8 +60,10 @@ header_destroy (header_t *ph, void *owner) ...@@ -83,8 +60,10 @@ header_destroy (header_t *ph, void *owner)
83 if (h->owner == owner) 60 if (h->owner == owner)
84 { 61 {
85 stream_destroy (&(h->stream), h); 62 stream_destroy (&(h->stream), h);
86 free (h->hdr); 63 if (h->hdr)
87 free (h->blurb); 64 free (h->hdr);
65 if (h->blurb)
66 free (h->blurb);
88 free (h); 67 free (h);
89 } 68 }
90 *ph = NULL; 69 *ph = NULL;
...@@ -207,8 +186,7 @@ header_parse (header_t header, const char *blurb, int len) ...@@ -207,8 +186,7 @@ header_parse (header_t header, const char *blurb, int len)
207 } 186 }
208 187
209 /* FIXME: grossly inneficient, to many copies and reallocating. 188 /* FIXME: grossly inneficient, to many copies and reallocating.
210 * This all header business need a good rewrite. 189 This all header business need a good rewrite. */
211 */
212 int 190 int
213 header_set_value (header_t header, const char *fn, const char *fv, int replace) 191 header_set_value (header_t header, const char *fn, const char *fv, int replace)
214 { 192 {
...@@ -218,11 +196,14 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) ...@@ -218,11 +196,14 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
218 if (header == NULL || fn == NULL || fv == NULL) 196 if (header == NULL || fn == NULL || fv == NULL)
219 return EINVAL; 197 return EINVAL;
220 198
221 /* Easy approach: if replace, overwrite the field-{namve,value} 199 /* Try to fill out the buffer, if we know how. */
222 and readjust the pointers by calling header_parse () 200 if (header->_set_value != NULL)
223 this is wastefull, we're just fragmenting the memory 201 return header->_set_value (header, fn, fv, replace);
224 it can be done better. But that may imply a rewite of the headers 202
225 So for another day. */ 203 /* Easy approach: if replace, overwrite the field-{name,value} and readjust
204 the pointers by calling header_parse () this is wastefull, we're just
205 fragmenting the memory it can be done better. But that may imply a
206 rewite of the headers So for another day. */
226 if (replace) 207 if (replace)
227 { 208 {
228 size_t name_len; 209 size_t name_len;
...@@ -251,8 +232,8 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) ...@@ -251,8 +232,8 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
251 } 232 }
252 } 233 }
253 234
254 /* Replacing was taking care of above now just add to 235 /* Replacing was taking care of above now just add to the end the new
255 the end the new header. Really not cute. */ 236 header. Really not cute. */
256 len = strlen (fn) + strlen (fv) + 1 + 1 + 1 + 1; 237 len = strlen (fn) + strlen (fv) + 1 + 1 + 1 + 1;
257 blurb = calloc (header->blurb_len + len, 1); 238 blurb = calloc (header->blurb_len + len, 1);
258 if (blurb == NULL) 239 if (blurb == NULL)
...@@ -266,20 +247,6 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) ...@@ -266,20 +247,6 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
266 } 247 }
267 248
268 int 249 int
269 header_set_get_value (header_t header, int (*_get_value)
270 (header_t, const char *, char *, size_t, size_t *),
271 void *owner)
272 {
273 if (header == NULL)
274 return EINVAL;
275 if (header->owner != owner)
276 return EACCES;
277
278 header->_get_value = _get_value;
279 return 0;
280 }
281
282 int
283 header_get_value (header_t header, const char *name, char *buffer, 250 header_get_value (header_t header, const char *name, char *buffer,
284 size_t buflen, size_t *pn) 251 size_t buflen, size_t *pn)
285 { 252 {
...@@ -287,20 +254,61 @@ header_get_value (header_t header, const char *name, char *buffer, ...@@ -287,20 +254,61 @@ header_get_value (header_t header, const char *name, char *buffer,
287 size_t name_len; 254 size_t name_len;
288 size_t total = 0, fn_len = 0, fv_len = 0; 255 size_t total = 0, fn_len = 0, fv_len = 0;
289 int threshold; 256 int threshold;
257 int err = 0;
290 258
291 if (header == NULL || name == NULL) 259 if (header == NULL || name == NULL)
292 return EINVAL; 260 return EINVAL;
293 261
262 if (header->_get_value != NULL)
263 return header->_get_value (header, name, buffer, buflen, pn);
264
265 /* Try to fill out the buffer, if we know how. */
266 if (header->blurb == NULL)
267 {
268 stream_t is;
269 err = header_get_stream (header, &is);
270 if (err != 0)
271 return err;
272 else
273 {
274 char buf[1024];
275 char *tbuf;
276 size_t nread = 0;
277 do
278 {
279 err = stream_read (is, buf, sizeof (buf), header->temp_blurb_len,
280 &nread);
281 if (err != 0
282 || (tbuf = realloc (header->temp_blurb,
283 header->temp_blurb_len + nread)) == NULL)
284 {
285 free (header->temp_blurb);
286 header->temp_blurb = NULL;
287 header->temp_blurb_len = 0;
288 return err;
289 }
290 else
291 header->temp_blurb = tbuf;
292 memcpy (header->temp_blurb + header->temp_blurb_len, buf, nread);
293 header->temp_blurb_len += nread;
294 } while (nread != 0);
295 /* parse it. */
296 header_parse (header, header->temp_blurb, header->temp_blurb_len);
297 free (header->temp_blurb);
298 header->temp_blurb = NULL;
299 header->temp_blurb_len = 0;
300 }
301 }
302
294 /* We set the threshold to be 1 less for the null. */ 303 /* We set the threshold to be 1 less for the null. */
295 threshold = --buflen; 304 threshold = --buflen;
296 305
297 /* Caution: We may have more then one value for a field 306 /* Caution: We may have more then one value for a field name, for example
298 name, for example a "Received" field-name is added by 307 a "Received" field-name is added by each passing MTA. The way that the
299 each passing MTA. The way that the parsing (_parse()) 308 parsing (_parse()) is done it's not take to account. So we just stuff
300 is done it's not take to account. So we just stuff in 309 in the buffer all the field-values to a corresponding field-name.
301 the buffer all the field-values to a corresponding field-name. 310 FIXME: Should we kosher the output ? meaning replace occurences of
302 FIXME: Should we kosher the output ? meaning replace 311 " \t\r\n" for spaces ? for now we don't. */
303 occurences of " \t\r\n" for spaces ? for now we don't. */
304 for (name_len = strlen (name), i = 0; i < header->hdr_count; i++) 312 for (name_len = strlen (name), i = 0; i < header->hdr_count; i++)
305 { 313 {
306 fn_len = header->hdr[i].fn_end - header->hdr[i].fn; 314 fn_len = header->hdr[i].fn_end - header->hdr[i].fn;
...@@ -332,48 +340,35 @@ header_get_value (header_t header, const char *name, char *buffer, ...@@ -332,48 +340,35 @@ header_get_value (header_t header, const char *name, char *buffer,
332 *buffer = '\0'; /* Null terminated. */ 340 *buffer = '\0'; /* Null terminated. */
333 if (pn) 341 if (pn)
334 *pn = total; 342 *pn = total;
343
344 /* Check if they provided a hook. */
335 if (total == 0) 345 if (total == 0)
336 { 346 {
337 int err = ENOENT; 347 err = ENOENT;
338 /* Check if they provided a hook. */
339 if (header->_get_value != NULL) 348 if (header->_get_value != NULL)
340 err = header->_get_value (header, name, buffer, buflen, pn); 349 err = header->_get_value (header, name, buffer, buflen, pn);
341 /* Cache it locally. */ 350 /* Success. Cache it locally. */
342 if (err == 0) 351 if (err == 0)
343 header_set_value (header, name, buffer, 0); 352 header_set_value (header, name, buffer, 0);
344 return err;
345 } 353 }
346 return 0; 354 return err;
347 }
348
349 int
350 header_entry_count (header_t header, size_t *pnum)
351 {
352 if (header == NULL)
353 {
354 if (pnum)
355 *pnum = 0;
356 return EINVAL;
357 }
358 if (pnum)
359 *pnum = header->hdr_count;
360 return 0;
361 } 355 }
362 356
363 int 357 int
364 header_lines (header_t header, size_t *plines) 358 header_lines (header_t header, size_t *plines)
365 { 359 {
366 int n; 360 int n;
367 size_t t = 0; 361 size_t lines = 0;
368 if (header == NULL) 362 if (header == NULL)
369 return EINVAL; 363 return EINVAL;
364
370 for (n = header->blurb_len - 1; n >= 0; n--) 365 for (n = header->blurb_len - 1; n >= 0; n--)
371 { 366 {
372 if (header->blurb[n] == '\n') 367 if (header->blurb[n] == '\n')
373 t++; 368 lines++;
374 } 369 }
375 if (plines) 370 if (plines)
376 *plines = t; 371 *plines = lines;
377 return 0; 372 return 0;
378 } 373 }
379 374
...@@ -382,57 +377,50 @@ header_size (header_t header, size_t *pnum) ...@@ -382,57 +377,50 @@ header_size (header_t header, size_t *pnum)
382 { 377 {
383 if (header == NULL) 378 if (header == NULL)
384 return EINVAL; 379 return EINVAL;
380
385 if (pnum) 381 if (pnum)
386 *pnum = header->blurb_len; 382 *pnum = header->blurb_len;
387 return 0; 383 return 0;
388 } 384 }
389 385
390 int 386 int
391 header_entry_name (header_t header, size_t num, char *buf, 387 header_set_get_value (header_t header, int (*_get_value)
392 size_t buflen, size_t *nwritten) 388 (header_t, const char *, char *, size_t, size_t *),
389 void *owner)
393 { 390 {
394 size_t len;
395 if (header == NULL) 391 if (header == NULL)
396 return EINVAL; 392 return EINVAL;
397 if (header->hdr_count == 0 || num > header->hdr_count) 393 if (header->owner != owner)
398 return ENOENT; 394 return EACCES;
399 len = header->hdr[num].fn_end - header->hdr[num].fn; 395 header->_get_value = _get_value;
400 /* save one for the null */
401 --buflen;
402 if (buf && buflen > 0)
403 {
404 buflen = (len > buflen) ? buflen : len;
405 memcpy (buf, header->hdr[num].fn, buflen);
406 buf[buflen] = '\0';
407 }
408 if (nwritten)
409 *nwritten = len;
410 return 0; 396 return 0;
411 } 397 }
412 398
413 int 399 int
414 header_entry_value (header_t header, size_t num, char *buf, 400 header_set_set_value (header_t header, int (*_set_value)
415 size_t buflen, size_t *nwritten) 401 (header_t , const char *, const char *, int),
402 void *owner)
416 { 403 {
417 size_t len;
418 if (header == NULL) 404 if (header == NULL)
419 return EINVAL; 405 return EINVAL;
420 if (header->hdr_count == 0 || num > header->hdr_count) 406 if (header->owner != owner)
421 return ENOENT; 407 return EACCES;
422 len = header->hdr[num].fv_end - header->hdr[num].fv; 408 header->_set_value = _set_value;
423 /* Save one for the null. */
424 --buflen;
425 if (buf && buflen > 0)
426 {
427 buflen = (len > buflen) ? buflen : len;
428 memcpy (buf, header->hdr[num].fv, buflen);
429 buf[buflen] = '\0';
430 }
431 if (nwritten)
432 *nwritten = len;
433 return 0; 409 return 0;
434 } 410 }
435 411
412 int
413 header_set_stream (header_t header, stream_t stream, void *owner)
414 {
415 if (header == NULL)
416 return EINVAL;
417 if (header->owner != owner)
418 return EACCES;
419 header->stream = stream;
420 return 0;
421 }
422
423
436 static int 424 static int
437 header_write (stream_t os, const char *buf, size_t buflen, 425 header_write (stream_t os, const char *buf, size_t buflen,
438 off_t off, size_t *pnwrite) 426 off_t off, size_t *pnwrite)
......
...@@ -34,17 +34,13 @@ extern "C" { ...@@ -34,17 +34,13 @@ extern "C" {
34 34
35 struct _attribute 35 struct _attribute
36 { 36 {
37 size_t flag; 37 void *owner;
38 size_t flags;
39 int (*_get_flags) __P ((attribute_t, int *));
40 int (*_set_flags) __P ((attribute_t, int));
41 int (*_unset_flags) __P ((attribute_t, int));
38 }; 42 };
39 43
40 #define MU_ATTRIBUTE_ANSWERED 0x01
41 #define MU_ATTRIBUTE_FLAGGED 0x02
42 #define MU_ATTRIBUTE_DELETED 0x04
43 #define MU_ATTRIBUTE_DRAFT 0x08
44 #define MU_ATTRIBUTE_SEEN 0x10
45 #define MU_ATTRIBUTE_READ 0x20
46 #define MU_ATTRIBUTE_RECENT 0x00
47
48 #ifdef __cplusplus 44 #ifdef __cplusplus
49 } 45 }
50 #endif 46 #endif
......
...@@ -35,8 +35,16 @@ extern "C" { ...@@ -35,8 +35,16 @@ extern "C" {
35 struct _attribute; 35 struct _attribute;
36 typedef struct _attribute * attribute_t; 36 typedef struct _attribute * attribute_t;
37 37
38 extern int attribute_create __P ((attribute_t *)); 38 #define MU_ATTRIBUTE_ANSWERED 0x01
39 extern void attribute_destroy __P ((attribute_t *)); 39 #define MU_ATTRIBUTE_FLAGGED 0x02
40 #define MU_ATTRIBUTE_DELETED 0x04
41 #define MU_ATTRIBUTE_DRAFT 0x08
42 #define MU_ATTRIBUTE_SEEN 0x10
43 #define MU_ATTRIBUTE_READ 0x20
44 #define MU_ATTRIBUTE_RECENT 0x00
45
46 extern int attribute_create __P ((attribute_t *, void *));
47 extern void attribute_destroy __P ((attribute_t *, void *));
40 48
41 extern int attribute_is_seen __P ((attribute_t)); 49 extern int attribute_is_seen __P ((attribute_t));
42 extern int attribute_is_answered __P ((attribute_t)); 50 extern int attribute_is_answered __P ((attribute_t));
...@@ -62,14 +70,22 @@ extern int attribute_unset_draft __P ((attribute_t)); ...@@ -62,14 +70,22 @@ extern int attribute_unset_draft __P ((attribute_t));
62 extern int attribute_unset_recent __P ((attribute_t)); 70 extern int attribute_unset_recent __P ((attribute_t));
63 extern int attribute_unset_read __P ((attribute_t)); 71 extern int attribute_unset_read __P ((attribute_t));
64 72
73 extern int attribute_get_flags __P ((attribute_t, int *));
74 extern int attribute_set_flags __P ((attribute_t, int));
75
76 extern int attribute_set_set_flags __P ((attribute_t, int (*_set_flags)
77 __P ((attribute_t, int)), void *));
78 extern int attribute_set_unset_flags __P ((attribute_t, int (*_unset_flags)
79 __P ((attribute_t, int)), void *));
80 extern int attribute_set_get_flags __P ((attribute_t, int (*_get_flags)
81 __P ((attribute_t, int *)), void *));
65 extern int attribute_is_equal __P ((attribute_t att1, attribute_t att2)); 82 extern int attribute_is_equal __P ((attribute_t att1, attribute_t att2));
66 83
67 extern int attribute_copy __P ((attribute_t dst, 84 extern int attribute_copy __P ((attribute_t dst,
68 attribute_t src)); 85 attribute_t src));
69 86
70 extern int string_to_attribute __P ((const char *buf, 87 extern int string_to_flags __P ((const char *buf, int *pattr));
71 attribute_t *pattr)); 88 extern int flags_to_string __P ((int flags, char *buf,
72 extern int attribute_to_string __P ((attribute_t attr, char *buf,
73 size_t len, size_t *)); 89 size_t len, size_t *));
74 90
75 #ifdef __cplusplus 91 #ifdef __cplusplus
......
...@@ -67,27 +67,27 @@ extern "C" { ...@@ -67,27 +67,27 @@ extern "C" {
67 struct _header; 67 struct _header;
68 typedef struct _header * header_t; 68 typedef struct _header * header_t;
69 69
70 extern int header_create __P ((header_t *, const char *blurb, 70 extern int header_create __P ((header_t *, const char *,
71 size_t ln, void *owner)); 71 size_t, void *));
72 extern void header_destroy __P ((header_t *, void *owner)); 72 extern void header_destroy __P ((header_t *, void *));
73 extern int header_set_value __P ((header_t, const char *,
74 const char *, int));
75 extern int header_get_value __P ((header_t, const char *, char *,
76 size_t, size_t *));
77 extern int header_get_stream __P ((header_t, stream_t *));
78 extern int header_size __P ((header_t, size_t *));
79 extern int header_lines __P ((header_t, size_t *));
73 80
74 extern int header_set_value __P ((header_t, const char *fn, 81 extern int header_set_stream __P ((header_t, stream_t, void *));
75 const char *fv, int replace));
76 82
83 extern int header_set_set_value __P ((header_t, int (*_set_value)
84 __P ((header_t, const char *,
85 const char *, int)),
86 void *));
77 extern int header_set_get_value __P ((header_t, int (*_get_value) 87 extern int header_set_get_value __P ((header_t, int (*_get_value)
78 __P ((header_t, const char *fn, char *buf, 88 __P ((header_t, const char *,
79 size_t buflen, size_t *nwritten)), 89 char *, size_t, size_t *)),
80 void *owner)); 90 void *));
81 extern int header_get_value __P ((header_t, const char *fn, char *buf,
82 size_t buflen, size_t *nwritten));
83 extern int header_entry_count __P ((header_t, size_t *num));
84 extern int header_entry_name __P ((header_t, size_t num, char *buf,
85 size_t buflen, size_t *total));
86 extern int header_entry_value __P ((header_t, size_t num, char *buf,
87 size_t buflen, size_t *total));
88 extern int header_get_stream __P ((header_t, stream_t *stream));
89 extern int header_size __P ((header_t, size_t *size));
90 extern int header_lines __P ((header_t, size_t *lines));
91 91
92 #ifdef _cplusplus 92 #ifdef _cplusplus
93 } 93 }
......
...@@ -173,7 +173,7 @@ do \ ...@@ -173,7 +173,7 @@ do \
173 { \ 173 { \
174 if (*s == c0 || *s == c1) \ 174 if (*s == c0 || *s == c1) \
175 { \ 175 { \
176 (mum)->old_attr->flag |= (type); \ 176 (mum)->old_flags |= (type); \
177 break; \ 177 break; \
178 } \ 178 } \
179 } \ 179 } \
...@@ -206,16 +206,16 @@ do \ ...@@ -206,16 +206,16 @@ do \
206 do \ 206 do \
207 { \ 207 { \
208 int bailing = 0; \ 208 int bailing = 0; \
209 mailbox_unix_iunlock (mbox); \ 209 unix_iunlock (mbox); \
210 MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_MSG_ADD, bailing); \ 210 MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_MSG_ADD, bailing); \
211 if (bailing != 0) \ 211 if (bailing != 0) \
212 { \ 212 { \
213 if (pcount) \ 213 if (pcount) \
214 *pcount = (mud)->messages_count; \ 214 *pcount = (mud)->messages_count; \
215 mailbox_unix_unlock (mbox); \ 215 unix_unlock (mbox); \
216 return EINTR; \ 216 return EINTR; \
217 } \ 217 } \
218 mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); \ 218 unix_ilock (mbox, MU_LOCKER_WRLOCK); \
219 } while (0); 219 } while (0);
220 220
221 /* notification MBX_PROGRESS 221 /* notification MBX_PROGRESS
...@@ -234,33 +234,38 @@ do \ ...@@ -234,33 +234,38 @@ do \
234 { \ 234 { \
235 { \ 235 { \
236 int bailing = 0; \ 236 int bailing = 0; \
237 mailbox_unix_iunlock (mbox); \ 237 unix_iunlock (mbox); \
238 mud->messages_count--; \ 238 mud->messages_count--; \
239 MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_PROGRESS,bailing); \ 239 MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_PROGRESS,bailing); \
240 if (bailing != 0) \ 240 if (bailing != 0) \
241 { \ 241 { \
242 if (pcount) \ 242 if (pcount) \
243 *pcount = (mud)->messages_count; \ 243 *pcount = (mud)->messages_count; \
244 mailbox_unix_unlock (mbox); \ 244 unix_unlock (mbox); \
245 return EINTR; \ 245 return EINTR; \
246 } \ 246 } \
247 mud->messages_count++; \ 247 mud->messages_count++; \
248 mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); \ 248 unix_ilock (mbox, MU_LOCKER_WRLOCK); \
249 } \ 249 } \
250 } while (0) 250 } while (0)
251 251
252 #if 0
252 /* skip a function call, ?? do we gain that much */ 253 /* skip a function call, ?? do we gain that much */
253 #define ATTRIBUTE_CREATE(attr,mbox) \ 254 #define ATTRIBUTE_CREATE(attr, m, mbox) \
254 do \ 255 do \
255 { \ 256 { \
256 attr = calloc (1, sizeof(*(attr))); \ 257 attr = calloc (1, sizeof(*(attr))); \
258 attr->owner = m; \
257 if ((attr) == NULL) \ 259 if ((attr) == NULL) \
258 { \ 260 { \
259 mailbox_unix_iunlock (mbox); \ 261 unix_iunlock (mbox); \
260 mailbox_unix_unlock (mbox); \ 262 unix_unlock (mbox); \
261 return ENOMEM; \ 263 return ENOMEM; \
262 } \ 264 } \
263 } while (0) 265 } while (0)
266 #else
267 # define ATTRIBUTE_CREATE
268 #endif
264 269
265 /* allocate slots for the new messages */ 270 /* allocate slots for the new messages */
266 /* size_t num = 2 * ((mud)->messages_count) + 10; */ 271 /* size_t num = 2 * ((mud)->messages_count) + 10; */
...@@ -269,38 +274,37 @@ do \ ...@@ -269,38 +274,37 @@ do \
269 { \ 274 { \
270 if ((mud)->messages_count >= (mud)->umessages_count) \ 275 if ((mud)->messages_count >= (mud)->umessages_count) \
271 { \ 276 { \
272 mailbox_unix_message_t *m; \ 277 unix_message_t *m; \
273 size_t num = ((mud)->umessages_count) + 1; \ 278 size_t num = ((mud)->umessages_count) + 1; \
274 m = realloc ((mud)->umessages, num * sizeof (*m)); \ 279 m = realloc ((mud)->umessages, num * sizeof (*m)); \
275 if (m == NULL) \ 280 if (m == NULL) \
276 { \ 281 { \
277 mailbox_unix_iunlock (mbox); \ 282 unix_iunlock (mbox); \
278 mailbox_unix_unlock (mbox); \ 283 unix_unlock (mbox); \
279 return ENOMEM; \ 284 return ENOMEM; \
280 } \ 285 } \
281 (mud)->umessages = m; \ 286 (mud)->umessages = m; \
282 (mud)->umessages[num - 1] = calloc (1, sizeof (*(mum))); \ 287 (mud)->umessages[num - 1] = calloc (1, sizeof (*(mum))); \
283 if ((mud)->umessages[num - 1] == NULL) \ 288 if ((mud)->umessages[num - 1] == NULL) \
284 { \ 289 { \
285 mailbox_unix_iunlock (mbox); \ 290 unix_iunlock (mbox); \
286 mailbox_unix_unlock (mbox); \ 291 unix_unlock (mbox); \
287 return ENOMEM; \ 292 return ENOMEM; \
288 } \ 293 } \
289 ATTRIBUTE_CREATE (((mud)->umessages[num - 1])->old_attr, mbox); \
290 (mud)->umessages_count = num; \ 294 (mud)->umessages_count = num; \
291 } \ 295 } \
292 } while (0) 296 } while (0)
293 297
294 static int 298 static int
295 mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) 299 unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
296 { 300 {
297 #define MSGLINELEN 1024 301 #define MSGLINELEN 1024
298 char buf[MSGLINELEN]; 302 char buf[MSGLINELEN];
299 int inheader; 303 int inheader;
300 int inbody; 304 int inbody;
301 off_t total = 0; 305 off_t total = 0;
302 mailbox_unix_data_t mud; 306 unix_data_t mud;
303 mailbox_unix_message_t mum = NULL; 307 unix_message_t mum = NULL;
304 int status = 0; 308 int status = 0;
305 size_t lines; 309 size_t lines;
306 int newline; 310 int newline;
...@@ -311,7 +315,7 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) ...@@ -311,7 +315,7 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
311 315
312 /* sanity */ 316 /* sanity */
313 if (mbox == NULL || 317 if (mbox == NULL ||
314 (mud = (mailbox_unix_data_t)mbox->data) == NULL) 318 (mud = (unix_data_t)mbox->data) == NULL)
315 return EINVAL; 319 return EINVAL;
316 320
317 /* save the timestamp and size */ 321 /* save the timestamp and size */
...@@ -320,8 +324,8 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) ...@@ -320,8 +324,8 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
320 return status; 324 return status;
321 325
322 /* grab the locks */ 326 /* grab the locks */
323 mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); 327 unix_ilock (mbox, MU_LOCKER_WRLOCK);
324 mailbox_unix_lock (mbox, MU_LOCKER_RDLOCK); 328 unix_lock (mbox, MU_LOCKER_RDLOCK);
325 329
326 /* seek to the starting point */ 330 /* seek to the starting point */
327 if (mud->umessages && msgno > 0 && mud->messages_count > 0 331 if (mud->umessages && msgno > 0 && mud->messages_count > 0
...@@ -403,7 +407,7 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) ...@@ -403,7 +407,7 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
403 407
404 /* every 50 mesgs update the lock, it should be every minute */ 408 /* every 50 mesgs update the lock, it should be every minute */
405 if ((mud->messages_count % 50) == 0) 409 if ((mud->messages_count % 50) == 0)
406 mailbox_unix_touchlock (mbox); 410 unix_touchlock (mbox);
407 411
408 /* ping them every 1000 lines */ 412 /* ping them every 1000 lines */
409 if (do_notif) 413 if (do_notif)
...@@ -419,8 +423,8 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) ...@@ -419,8 +423,8 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
419 if (do_notif) 423 if (do_notif)
420 DISPATCH_ADD_MSG(mbox, mud); 424 DISPATCH_ADD_MSG(mbox, mud);
421 } 425 }
422 mailbox_unix_iunlock (mbox); 426 unix_iunlock (mbox);
423 mailbox_unix_unlock (mbox); 427 unix_unlock (mbox);
424 if (pcount) 428 if (pcount)
425 *pcount = mud->messages_count; 429 *pcount = mud->messages_count;
426 return status; 430 return status;
......
...@@ -68,7 +68,7 @@ message_destroy (message_t *pmsg, void *owner) ...@@ -68,7 +68,7 @@ message_destroy (message_t *pmsg, void *owner)
68 /* header */ 68 /* header */
69 header_destroy (&(msg->header), owner); 69 header_destroy (&(msg->header), owner);
70 /* attribute */ 70 /* attribute */
71 attribute_destroy (&(msg->attribute)); 71 attribute_destroy (&(msg->attribute), owner);
72 /* stream */ 72 /* stream */
73 stream_destroy (&(msg->stream), owner); 73 stream_destroy (&(msg->stream), owner);
74 74
...@@ -325,7 +325,7 @@ message_get_attribute (message_t msg, attribute_t *pattribute) ...@@ -325,7 +325,7 @@ message_get_attribute (message_t msg, attribute_t *pattribute)
325 if (msg->attribute == NULL) 325 if (msg->attribute == NULL)
326 { 326 {
327 attribute_t attribute; 327 attribute_t attribute;
328 int status = attribute_create (&attribute); 328 int status = attribute_create (&attribute, msg);
329 if (status != 0) 329 if (status != 0)
330 return status; 330 return status;
331 msg->attribute = attribute; 331 msg->attribute = attribute;
...@@ -341,7 +341,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner) ...@@ -341,7 +341,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner)
341 return EINVAL; 341 return EINVAL;
342 if (msg->owner != owner) 342 if (msg->owner != owner)
343 return EACCES; 343 return EACCES;
344 attribute_destroy (&(msg->attribute)); 344 attribute_destroy (&(msg->attribute), owner);
345 msg->attribute = attribute; 345 msg->attribute = attribute;
346 return 0; 346 return 0;
347 } 347 }
...@@ -532,7 +532,11 @@ message_read (stream_t is, char *buf, size_t buflen, ...@@ -532,7 +532,11 @@ message_read (stream_t is, char *buf, size_t buflen,
532 header_size (msg->header, &hsize); 532 header_size (msg->header, &hsize);
533 body_size (msg->body, &bsize); 533 body_size (msg->body, &bsize);
534 534
535 if ((size_t)off <= hsize) 535 /* On some remote sever (POP) the size of the header and body is not known
536 until you start reading them. So by checking hsize == bsize == 0, we
537 This kludge of a way of detecting the anomalie and start by the
538 header. */
539 if ((size_t)off <= hsize || (hsize == 0 && bsize == 0))
536 { 540 {
537 header_get_stream (msg->header, &his); 541 header_get_stream (msg->header, &his);
538 stream_read (his, buf, buflen, off, &hread); 542 stream_read (his, buf, buflen, off, &hread);
......
...@@ -25,13 +25,12 @@ ...@@ -25,13 +25,12 @@
25 #include <string.h> 25 #include <string.h>
26 #include <errno.h> 26 #include <errno.h>
27 27
28 /* 28 /* Builtin mailbox types. A circular list is use for the builtin.
29 Builtin mailbox types.
30 A circular list is use for the builtin.
31 Proper locking is not done when accessing the list. 29 Proper locking is not done when accessing the list.
32 FIXME: not thread-safe. */ 30 FIXME: not thread-safe. */
33 31
34 static struct _registrar registrar [] = { 32 static struct _registrar registrar [] =
33 {
35 { NULL, NULL, 0, &registrar[1] }, /* sentinel, head list */ 34 { NULL, NULL, 0, &registrar[1] }, /* sentinel, head list */
36 { &_url_file_registrar, &_mailbox_mbox_registrar, 0, &registrar[2] }, 35 { &_url_file_registrar, &_mailbox_mbox_registrar, 0, &registrar[2] },
37 { &_url_mbox_registrar, &_mailbox_mbox_registrar, 0, &registrar[3] }, 36 { &_url_mbox_registrar, &_mailbox_mbox_registrar, 0, &registrar[3] },
......