header.c mbx_unixscan.c include/private/message0.h
I'm an idiot, with dup() the file table is share by the two file descriptors, So when one do mailbox_get_message() it was influencing the parsing since the offset was changing the world underneath the parsing code ... duh !! solution reopen the mailbox readonly. Thanks dave for pointing this out.
Showing
3 changed files
with
63 additions
and
74 deletions
... | @@ -234,7 +234,7 @@ header_set_value (header_t h, const char *fn, const char *fv, | ... | @@ -234,7 +234,7 @@ header_set_value (header_t h, const char *fn, const char *fv, |
234 | 234 | ||
235 | int | 235 | int |
236 | header_get_value (header_t header, const char *name, char *buffer, | 236 | header_get_value (header_t header, const char *name, char *buffer, |
237 | size_t buflen, size_t *n) | 237 | size_t buflen, size_t *pn) |
238 | { | 238 | { |
239 | size_t i = 0; | 239 | size_t i = 0; |
240 | size_t name_len; | 240 | size_t name_len; |
... | @@ -285,8 +285,8 @@ header_get_value (header_t header, const char *name, char *buffer, | ... | @@ -285,8 +285,8 @@ header_get_value (header_t header, const char *name, char *buffer, |
285 | } | 285 | } |
286 | if (buffer) | 286 | if (buffer) |
287 | *buffer = '\0'; /* null terminated */ | 287 | *buffer = '\0'; /* null terminated */ |
288 | if (n) | 288 | if (pn) |
289 | *n = total; | 289 | *pn = total; |
290 | return 0; | 290 | return 0; |
291 | } | 291 | } |
292 | 292 | ... | ... |
... | @@ -47,7 +47,6 @@ struct _message | ... | @@ -47,7 +47,6 @@ struct _message |
47 | body_t body; | 47 | body_t body; |
48 | attribute_t attribute; | 48 | attribute_t attribute; |
49 | size_t num; | 49 | size_t num; |
50 | size_t size; | ||
51 | 50 | ||
52 | /* who is the owner */ | 51 | /* who is the owner */ |
53 | void *owner; | 52 | void *owner; |
... | @@ -56,15 +55,6 @@ struct _message | ... | @@ -56,15 +55,6 @@ struct _message |
56 | event_t event; | 55 | event_t event; |
57 | size_t event_num; | 56 | size_t event_num; |
58 | 57 | ||
59 | int (*_get_header) __P ((message_t msg, header_t *hdr)); | ||
60 | int (*_set_header) __P ((message_t msg, header_t hdr, void *owner)); | ||
61 | |||
62 | int (*_get_attribute) __P ((message_t msg, attribute_t *attr)); | ||
63 | int (*_set_attribute) __P ((message_t msg, attribute_t attr, void *owner)); | ||
64 | |||
65 | int (*_get_stream) __P ((message_t msg, stream_t *)); | ||
66 | int (*_set_stream) __P ((message_t msg, stream_t, void *owner)); | ||
67 | |||
68 | int (*_from) __P ((message_t msg, char *, size_t, size_t *)); | 58 | int (*_from) __P ((message_t msg, char *, size_t, size_t *)); |
69 | int (*_received) __P ((message_t msg, char *, size_t, size_t *)); | 59 | int (*_received) __P ((message_t msg, char *, size_t, size_t *)); |
70 | 60 | ... | ... |
... | @@ -165,14 +165,15 @@ do \ | ... | @@ -165,14 +165,15 @@ do \ |
165 | i = tmp - s; \ | 165 | i = tmp - s; \ |
166 | } while (0) | 166 | } while (0) |
167 | 167 | ||
168 | #define ATTRIBUTE_SET(s,buf,mum,c0,c1,type) \ | 168 | #define ATTRIBUTE_SET(buf,mum,c0,c1,type) \ |
169 | do \ | 169 | do \ |
170 | { \ | 170 | { \ |
171 | for (s = buf + 7; *s; s++) \ | 171 | char *s; \ |
172 | for (s = (buf) + 7; *s; s++) \ | ||
172 | { \ | 173 | { \ |
173 | if (*s == c0 || *s == c1) \ | 174 | if (*s == c0 || *s == c1) \ |
174 | { \ | 175 | { \ |
175 | mum->old_attr->flag |= type; \ | 176 | (mum)->old_attr->flag |= (type); \ |
176 | break; \ | 177 | break; \ |
177 | } \ | 178 | } \ |
178 | } \ | 179 | } \ |
... | @@ -187,29 +188,30 @@ do \ | ... | @@ -187,29 +188,30 @@ do \ |
187 | (buf[5] == 'S' || buf[5] == 's') && (buf[6] == ':')) | 188 | (buf[5] == 'S' || buf[5] == 's') && (buf[6] == ':')) |
188 | 189 | ||
189 | /* notification */ | 190 | /* notification */ |
190 | #define MAILBOX_NOTIFICATION(mbx, which) \ | 191 | #define MAILBOX_NOTIFICATION(mbox,which,bailing) \ |
191 | do \ | 192 | do \ |
192 | { \ | 193 | { \ |
193 | size_t i; \ | 194 | size_t i; \ |
194 | event_t event; \ | 195 | event_t event; \ |
195 | for (i = 0; i < mbx->event_num; i++) \ | 196 | for (i = 0; i < (mbox)->event_num; i++) \ |
196 | { \ | 197 | { \ |
197 | event = &(mbx->event[i]); \ | 198 | event = &((mbox)->event[i]); \ |
198 | if ((event->_action) && (event->type & which)) \ | 199 | if ((event->_action) && (event->type & (which))) \ |
199 | status |= event->_action (which, event->arg); \ | 200 | bailing |= event->_action (which, event->arg); \ |
200 | } \ | 201 | } \ |
201 | } while (0) | 202 | } while (0) |
202 | 203 | ||
203 | /* notifications ADD_MESG */ | 204 | /* notifications ADD_MESG */ |
204 | #define DISPATCH_ADD_MSG() \ | 205 | #define DISPATCH_ADD_MSG(mbox,mud,file) \ |
205 | do \ | 206 | do \ |
206 | { \ | 207 | { \ |
208 | int bailing = 0; \ | ||
207 | mailbox_unix_iunlock (mbox); \ | 209 | mailbox_unix_iunlock (mbox); \ |
208 | MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_MSG_ADD); \ | 210 | MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_MSG_ADD, bailing); \ |
209 | if (status != 0) \ | 211 | if (bailing != 0) \ |
210 | { \ | 212 | { \ |
211 | if (pcount) \ | 213 | if (pcount) \ |
212 | *pcount = mud->messages_count; \ | 214 | *pcount = (mud)->messages_count; \ |
213 | fclose (file); \ | 215 | fclose (file); \ |
214 | mailbox_unix_unlock (mbox); \ | 216 | mailbox_unix_unlock (mbox); \ |
215 | return EINTR; \ | 217 | return EINTR; \ |
... | @@ -225,33 +227,28 @@ do \ | ... | @@ -225,33 +227,28 @@ do \ |
225 | */ | 227 | */ |
226 | /* | 228 | /* |
227 | * This is more tricky we can not leave the mum | 229 | * This is more tricky we can not leave the mum |
228 | * struct incomplete. If they want to bailout | 230 | * struct incomplete. So we only tell them about |
229 | * they probably did not care about the last message | 231 | * the complete messages. |
230 | * we should free it; | ||
231 | */ | 232 | */ |
232 | #define DISPATCH_PROGRESS() \ | 233 | #define DISPATCH_PROGRESS(mbox,mud,file) \ |
233 | do \ | 234 | do \ |
234 | { \ | 235 | { \ |
235 | { \ | 236 | { \ |
237 | int bailing = 0; \ | ||
236 | mailbox_unix_iunlock (mbox); \ | 238 | mailbox_unix_iunlock (mbox); \ |
237 | MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_PROGRESS); \ | 239 | if (mud->messages_count != 0) \ |
238 | if (status != 0) \ | ||
239 | { \ | ||
240 | if (mum) \ | ||
241 | { \ | ||
242 | attribute_destroy (&(mum->old_attr), mbox); \ | ||
243 | attribute_destroy (&(mum->new_attr), mbox); \ | ||
244 | message_destroy (&(mum->message), mbox); \ | ||
245 | free (mum); \ | ||
246 | mud->umessages[mud->messages_count - 1] = NULL; \ | ||
247 | mud->messages_count--; \ | 240 | mud->messages_count--; \ |
248 | } \ | 241 | MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_PROGRESS,bailing); \ |
242 | if (bailing != 0) \ | ||
243 | { \ | ||
249 | if (pcount) \ | 244 | if (pcount) \ |
250 | *pcount = mud->messages_count; \ | 245 | *pcount = (mud)->messages_count; \ |
251 | fclose (file); \ | 246 | fclose (file); \ |
252 | mailbox_unix_unlock (mbox); \ | 247 | mailbox_unix_unlock (mbox); \ |
253 | return EINTR; \ | 248 | return EINTR; \ |
254 | } \ | 249 | } \ |
250 | if (mud->messages_count != 0) \ | ||
251 | mud->messages_count++; \ | ||
255 | mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); \ | 252 | mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); \ |
256 | } \ | 253 | } \ |
257 | } while (0) | 254 | } while (0) |
... | @@ -272,15 +269,16 @@ do \ | ... | @@ -272,15 +269,16 @@ do \ |
272 | } while (0) | 269 | } while (0) |
273 | 270 | ||
274 | /* allocate slots for the new messages */ | 271 | /* allocate slots for the new messages */ |
275 | #define ALLOCATE_MSGS() \ | 272 | #define ALLOCATE_MSGS(mbox,mud,file) \ |
276 | do \ | 273 | do \ |
277 | { \ | 274 | { \ |
278 | if (mud->messages_count >= mud->umessages_count) \ | 275 | if (mud->umessages_count == 0 || \ |
276 | ((mud)->umessages_count + 1) <= (mud)->messages_count) \ | ||
279 | { \ | 277 | { \ |
280 | mailbox_unix_message_t *m; \ | 278 | mailbox_unix_message_t *m; \ |
281 | size_t i; \ | 279 | size_t i; \ |
282 | size_t num = 2 * (mud->messages_count) + 10; \ | 280 | size_t num = 2 * ((mud)->messages_count) + 10; \ |
283 | m = realloc (mud->umessages, num * sizeof (*m)); \ | 281 | m = realloc ((mud)->umessages, num * sizeof (*m)); \ |
284 | if (m == NULL) \ | 282 | if (m == NULL) \ |
285 | { \ | 283 | { \ |
286 | fclose (file); \ | 284 | fclose (file); \ |
... | @@ -288,29 +286,28 @@ do \ | ... | @@ -288,29 +286,28 @@ do \ |
288 | mailbox_unix_unlock (mbox); \ | 286 | mailbox_unix_unlock (mbox); \ |
289 | return ENOMEM; \ | 287 | return ENOMEM; \ |
290 | } \ | 288 | } \ |
291 | mud->umessages = m; \ | 289 | (mud)->umessages = m; \ |
292 | for (i = mud->umessages_count; i < num; i++) \ | 290 | if ((mud)->umessages_count) \ |
291 | i = (mud)->umessages_count + 1; \ | ||
292 | else \ | ||
293 | i = 0; \ | ||
294 | for (; i < num; i++) \ | ||
293 | { \ | 295 | { \ |
294 | mud->umessages[i] = calloc (1, sizeof (*mum)); \ | 296 | (mud)->umessages[i] = calloc (1, sizeof (*(mum))); \ |
295 | if (mud->umessages[i] == NULL) \ | 297 | if ((mud)->umessages[i] == NULL) \ |
296 | { \ | 298 | { \ |
297 | fclose (file); \ | 299 | fclose (file); \ |
298 | mailbox_unix_iunlock (mbox); \ | 300 | mailbox_unix_iunlock (mbox); \ |
299 | mailbox_unix_unlock (mbox); \ | 301 | mailbox_unix_unlock (mbox); \ |
300 | return ENOMEM; \ | 302 | return ENOMEM; \ |
301 | } \ | 303 | } \ |
302 | ATTRIBUTE_CREATE ((mud->umessages[i])->old_attr, mbox); \ | 304 | ATTRIBUTE_CREATE (((mud)->umessages[i])->old_attr, mbox); \ |
303 | ATTRIBUTE_CREATE ((mud->umessages[i])->new_attr, mbox); \ | 305 | ATTRIBUTE_CREATE (((mud)->umessages[i])->new_attr, mbox); \ |
304 | } \ | 306 | } \ |
305 | mud->umessages_count = num - 1; \ | 307 | (mud)->umessages_count = num - 1; \ |
306 | mum = mud->umessages[mud->messages_count - 1]; \ | ||
307 | } \ | 308 | } \ |
308 | else \ | ||
309 | mum = mud->umessages[mud->messages_count - 1]; \ | ||
310 | mum->file = mud->file; \ | ||
311 | } while (0) | 309 | } while (0) |
312 | 310 | ||
313 | //fprintf (stderr, "%d %d %d\n", mud->umessages_count, mud->messages_count, (int)mum); | ||
314 | static int | 311 | static int |
315 | mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) | 312 | mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) |
316 | { | 313 | { |
... | @@ -342,10 +339,7 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -342,10 +339,7 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) |
342 | * Really something smaller would be counter productive. | 339 | * Really something smaller would be counter productive. |
343 | */ | 340 | */ |
344 | { | 341 | { |
345 | int fd = dup (fileno (mud->file)); | 342 | file = fopen (mbox->name, "r"); |
346 | if (fd == -1) | ||
347 | return errno; | ||
348 | file = fdopen (fd, "r"); | ||
349 | if (file == NULL) | 343 | if (file == NULL) |
350 | return errno; | 344 | return errno; |
351 | #if BUFSIZ <= 1024 | 345 | #if BUFSIZ <= 1024 |
... | @@ -363,6 +357,9 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -363,6 +357,9 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) |
363 | mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); | 357 | mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); |
364 | mailbox_unix_lock (mbox, MU_LOCKER_RDLOCK); | 358 | mailbox_unix_lock (mbox, MU_LOCKER_RDLOCK); |
365 | 359 | ||
360 | /*start at the beginning */ | ||
361 | rewind (file); | ||
362 | |||
366 | /* save the timestamp and size */ | 363 | /* save the timestamp and size */ |
367 | { | 364 | { |
368 | struct stat st; | 365 | struct stat st; |
... | @@ -392,7 +389,6 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -392,7 +389,6 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) |
392 | } | 389 | } |
393 | } | 390 | } |
394 | 391 | ||
395 | rewind (file); | ||
396 | newline = 1; | 392 | newline = 1; |
397 | errno = total = lines = inheader = inbody = 0; | 393 | errno = total = lines = inheader = inbody = 0; |
398 | 394 | ||
... | @@ -422,24 +418,25 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -422,24 +418,25 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) |
422 | { | 418 | { |
423 | mum->body_end = total - over - newline; | 419 | mum->body_end = total - over - newline; |
424 | mum->body_lines = --lines - newline; | 420 | mum->body_lines = --lines - newline; |
425 | DISPATCH_ADD_MSG(); | 421 | DISPATCH_ADD_MSG(mbox, mud, file); |
426 | } | 422 | } |
427 | mud->messages_count++; | ||
428 | /* allocate_msgs will initialize mum */ | 423 | /* allocate_msgs will initialize mum */ |
429 | ALLOCATE_MSGS(); | 424 | ALLOCATE_MSGS(mbox, mud, file); |
425 | mud->messages_count++; | ||
426 | mum = mud->umessages[mud->messages_count - 1]; | ||
427 | mum->file = mud->file; | ||
430 | mum->header_from = total - over; | 428 | mum->header_from = total - over; |
431 | mum->header_from_end = total; | 429 | mum->header_from_end = total; |
432 | lines = 0; | 430 | lines = 0; |
433 | } | 431 | } |
434 | else if ((over > 7) && ISSTATUS(buf)) | 432 | else if ((over > 7) && ISSTATUS(buf)) |
435 | { | 433 | { |
436 | char *s; | ||
437 | mum->header_status = total - over; | 434 | mum->header_status = total - over; |
438 | mum->header_status_end = total; | 435 | mum->header_status_end = total; |
439 | ATTRIBUTE_SET(s, buf, mum, 'r', 'R', MU_ATTRIBUTE_READ); | 436 | ATTRIBUTE_SET(buf, mum, 'r', 'R', MU_ATTRIBUTE_READ); |
440 | ATTRIBUTE_SET(s, buf, mum, 'o', 'O', MU_ATTRIBUTE_SEEN); | 437 | ATTRIBUTE_SET(buf, mum, 'o', 'O', MU_ATTRIBUTE_SEEN); |
441 | ATTRIBUTE_SET(s, buf, mum, 'a', 'A', MU_ATTRIBUTE_ANSWERED); | 438 | ATTRIBUTE_SET(buf, mum, 'a', 'A', MU_ATTRIBUTE_ANSWERED); |
442 | ATTRIBUTE_SET(s, buf, mum, 'd', 'D', MU_ATTRIBUTE_DELETED); | 439 | ATTRIBUTE_SET(buf, mum, 'd', 'D', MU_ATTRIBUTE_DELETED); |
443 | mum->new_attr->flag = mum->old_attr->flag; | 440 | mum->new_attr->flag = mum->old_attr->flag; |
444 | } | 441 | } |
445 | } | 442 | } |
... | @@ -448,7 +445,7 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -448,7 +445,7 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) |
448 | if (inbody) | 445 | if (inbody) |
449 | { | 446 | { |
450 | /* set the body position */ | 447 | /* set the body position */ |
451 | if (!mum->body) | 448 | if (mum && !mum->body) |
452 | { | 449 | { |
453 | mum->body = total - over + nl; | 450 | mum->body = total - over + nl; |
454 | mum->header_lines = lines; | 451 | mum->header_lines = lines; |
... | @@ -457,12 +454,14 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -457,12 +454,14 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) |
457 | } | 454 | } |
458 | 455 | ||
459 | newline = nl; | 456 | newline = nl; |
457 | |||
460 | /* every 50 mesgs update the lock, it should be every minute */ | 458 | /* every 50 mesgs update the lock, it should be every minute */ |
461 | if ((mud->messages_count % 50) == 0) | 459 | if ((mud->messages_count % 50) == 0) |
462 | mailbox_unix_touchlock (mbox); | 460 | mailbox_unix_touchlock (mbox); |
463 | 461 | ||
464 | if (((lines +1) % 10000) == 0) | 462 | /* ping them every 1000 lines */ |
465 | DISPATCH_PROGRESS(); | 463 | if (((lines +1) % 1000) == 0) |
464 | DISPATCH_PROGRESS(mbox, mud, file); | ||
466 | 465 | ||
467 | } /* while */ | 466 | } /* while */ |
468 | 467 | ||
... | @@ -477,7 +476,7 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -477,7 +476,7 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) |
477 | { | 476 | { |
478 | //mailbox_notification (mbox, MU_EVT_MBX_MSG_ADD); | 477 | //mailbox_notification (mbox, MU_EVT_MBX_MSG_ADD); |
479 | mum->body_end = total - newline; | 478 | mum->body_end = total - newline; |
480 | mum->header_lines = lines - newline; | 479 | mum->body_lines = lines - newline; |
481 | } | 480 | } |
482 | fclose (file); | 481 | fclose (file); |
483 | mailbox_unix_iunlock (mbox); | 482 | mailbox_unix_iunlock (mbox); | ... | ... |
-
Please register or sign in to post a comment