Commit 6049fc43 6049fc437f3f74a4186a6930a890af7b07e3559e by Alain Magloire

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.
1 parent 91905487
...@@ -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);
......