Commit 2bb68e42 2bb68e42b049f5882385c6e19d29810b5aafb9b7 by Alain Magloire

Pointed by Sam Roberts s/_cplusplus/__cplusplus almost all the headers

had to be fixed.

imap4d server added HEADER.FIELDS.NOT fetch functionality. But still
partial retrieve does not work and I fail to to do proper counting
i.e "\n" must be counted for two bytes "\r\n".

REMINDER: the imap4d/fetch.c is getting heavily bloated, fix later.
1 parent 56461cf8
1 2001-03-03 Alain Magloire
2
3 * imap4d/fetch.c (fetch_operation) : HEADER.FIELDS.NOT implemented.
4 fetch_opertaion() tak e a new argument.
5 * imap4d/util.c (util_upper) : New function string upper.
6
7 * mailbox/heder.c : Added new functionnalities to help the imap4d
8 fetch command.
9 (header_get_field_count) : New function returns the number of header
10 fields in the header.
11 (header_get_field_name): New function returns the field name.
12 (header_get_field_value): New function returns the field value.
13
14 2001-03-03 Alain Magloire
15
16 * include/mailutils/address.h : s/_cplusplus/__cplusplus/g
17 (include/mailutils/auth.h) : Likewised.
18 (include/mailutils/body.h) : Likewised.
19 (include/mailutils/debug.h) : Likewised.
20 (include/mailutils/header.h) : Likewised.
21 (include/mailutils/iterator.h) : Likewised.
22 (include/mailutils/list.h) : Likewised.
23 (include/mailutils/mailer.h) : Likewised.
24 (include/mailutils/message.h) : Likewised.
25 (include/mailutils/mime.h) : Likewised.
26 (include/mailutils/observer.h) : Likewised.
27 (include/mailutils/property.h) : Likewised.
28 (include/mailutils/registrar.h): Likewised.
29 (mailbox/include/address0.h) : Likewised.
30 (mailbox/include/auth0.h) : Likewised.
31 (mailbox/include/body0.h) : Likewised.
32 (mailbox/include/debug0.h) : Likewised.
33 (mailbox/include/header0.h) : Likewised.
34 (mailbox/include/iterator0.h) : Likewised.
35 (mailbox/include/list0.h) : Likewised.
36 (mailbox/include/mailer0.h) : Likewised.
37 (mailbox/include/message0.h) : Likewised.
38 (mailbox/include/mime0.h) : Likewised.
39 (mailbox/include/observer0.h) : Likewised.
40 Pointed by Sam Roberts.
41
1 2001-02-28 Alain Magloire 42 2001-02-28 Alain Magloire
2 43
3 * mailbox/address.c (address_get_personal) : Remove surrounding quotes. 44 * mailbox/address.c (address_get_personal) : Remove surrounding quotes.
......
...@@ -47,7 +47,7 @@ static int fetch_body (struct imap4d_command *, char*); ...@@ -47,7 +47,7 @@ static int fetch_body (struct imap4d_command *, char*);
47 static int fetch_uid (struct imap4d_command *, char*); 47 static int fetch_uid (struct imap4d_command *, char*);
48 48
49 static int fetch_send_address (char *addr); 49 static int fetch_send_address (char *addr);
50 static int fetch_operation (size_t, char *); 50 static int fetch_operation (size_t, char *, int);
51 51
52 struct imap4d_command fetch_command_table [] = 52 struct imap4d_command fetch_command_table [] =
53 { 53 {
...@@ -236,8 +236,7 @@ fetch_envelope (struct imap4d_command *command, char *arg) ...@@ -236,8 +236,7 @@ fetch_envelope (struct imap4d_command *command, char *arg)
236 char from[128]; 236 char from[128];
237 header_t header = NULL; 237 header_t header = NULL;
238 message_t msg = NULL; 238 message_t msg = NULL;
239 /* FIXME: K&R compilers will choke at this, initializing local arrays was 239
240 not permitted. Even AIX xlc use to choke. */
241 mailbox_get_message (mbox, command->states, &msg); 240 mailbox_get_message (mbox, command->states, &msg);
242 message_get_header (msg, &header); 241 message_get_header (msg, &header);
243 util_send ("%s(", command->name); 242 util_send ("%s(", command->name);
...@@ -332,7 +331,7 @@ fetch_flags (struct imap4d_command *command, char *arg) ...@@ -332,7 +331,7 @@ fetch_flags (struct imap4d_command *command, char *arg)
332 } 331 }
333 332
334 /* The internal date of the message. */ 333 /* The internal date of the message. */
335 /* FIXME: Wrong format. */ 334 /* FIXME: Wrong format? */
336 static int 335 static int
337 fetch_internaldate (struct imap4d_command *command, char *arg) 336 fetch_internaldate (struct imap4d_command *command, char *arg)
338 { 337 {
...@@ -357,7 +356,7 @@ fetch_rfc822_header (struct imap4d_command *command, char *arg) ...@@ -357,7 +356,7 @@ fetch_rfc822_header (struct imap4d_command *command, char *arg)
357 char buffer[16]; 356 char buffer[16];
358 util_send ("%s ", command->name); 357 util_send ("%s ", command->name);
359 strcpy (buffer, "[HEADER]"); 358 strcpy (buffer, "[HEADER]");
360 fetch_operation (command->states, buffer); 359 fetch_operation (command->states, buffer, 1);
361 return 0; 360 return 0;
362 } 361 }
363 362
...@@ -374,7 +373,7 @@ fetch_rfc822_text (struct imap4d_command *command, char *arg) ...@@ -374,7 +373,7 @@ fetch_rfc822_text (struct imap4d_command *command, char *arg)
374 attribute_set_read (attr); 373 attribute_set_read (attr);
375 util_send ("%s ", command->name); 374 util_send ("%s ", command->name);
376 strcpy (buffer, "[TEXT]"); 375 strcpy (buffer, "[TEXT]");
377 fetch_operation (command->states, buffer); 376 fetch_operation (command->states, buffer, 1);
378 return 0; 377 return 0;
379 } 378 }
380 379
...@@ -428,7 +427,7 @@ fetch_rfc822 (struct imap4d_command *command, char *arg) ...@@ -428,7 +427,7 @@ fetch_rfc822 (struct imap4d_command *command, char *arg)
428 attribute_set_read (attr); 427 attribute_set_read (attr);
429 util_send ("%s ", command->name); 428 util_send ("%s ", command->name);
430 strcpy (buffer, "[]"); 429 strcpy (buffer, "[]");
431 fetch_operation (command->states, buffer); 430 fetch_operation (command->states, buffer, 1);
432 } 431 }
433 return 0; 432 return 0;
434 } 433 }
...@@ -495,13 +494,15 @@ fetch_body (struct imap4d_command *command, char *arg) ...@@ -495,13 +494,15 @@ fetch_body (struct imap4d_command *command, char *arg)
495 return 0; 494 return 0;
496 } 495 }
497 496
498 util_send ("%s", arg); 497 fetch_operation (command->states, arg, 0);
499 fetch_operation (command->states, arg);
500 return 0; 498 return 0;
501 } 499 }
502 500
501 /* FIXME: "\n" -->"\r\n" is not handle right still it will not be as messy. */
502 /* FIXME: Code bloat move some stuff in routines, to be reuse. */
503 /* FIXME: partial fetch <x.y> still not handle. */
503 static int 504 static int
504 fetch_operation (size_t msgno, char *arg) 505 fetch_operation (size_t msgno, char *arg, int silent)
505 { 506 {
506 off_t offset = 0; 507 off_t offset = 0;
507 size_t limit = -1; /* No limit. */ 508 size_t limit = -1; /* No limit. */
...@@ -513,6 +514,7 @@ fetch_operation (size_t msgno, char *arg) ...@@ -513,6 +514,7 @@ fetch_operation (size_t msgno, char *arg)
513 { 514 {
514 /* FIXME: This shoud be move in imap4d_fetch() and have more 515 /* FIXME: This shoud be move in imap4d_fetch() and have more
515 draconian check. */ 516 draconian check. */
517 *partial = '\0';
516 partial++; 518 partial++;
517 offset = strtoul (partial, &partial, 10); 519 offset = strtoul (partial, &partial, 10);
518 if (*partial == '.') 520 if (*partial == '.')
...@@ -520,7 +522,11 @@ fetch_operation (size_t msgno, char *arg) ...@@ -520,7 +522,11 @@ fetch_operation (size_t msgno, char *arg)
520 partial++; 522 partial++;
521 limit = strtoul (partial, NULL, 10); 523 limit = strtoul (partial, NULL, 10);
522 } 524 }
525 partial = alloca (64);
526 snprintf (partial, 64, "<%lu>", (unsigned long)offset);
523 } 527 }
528 else
529 partial = (char *)"";
524 530
525 mailbox_get_message (mbox, msgno, &msg); 531 mailbox_get_message (mbox, msgno, &msg);
526 532
...@@ -533,7 +539,9 @@ fetch_operation (size_t msgno, char *arg) ...@@ -533,7 +539,9 @@ fetch_operation (size_t msgno, char *arg)
533 message_get_stream (msg, &stream); 539 message_get_stream (msg, &stream);
534 message_size (msg, &size); 540 message_size (msg, &size);
535 message_size (msg, &lines); 541 message_size (msg, &lines);
536 util_send ("{%u}\r\n", size + lines); 542 if (!silent)
543 util_send ("%s", arg);
544 util_send ("%s {%u}\r\n", partial, size + lines);
537 while (stream_readline (stream, buffer, sizeof (buffer), off, &n) == 0 545 while (stream_readline (stream, buffer, sizeof (buffer), off, &n) == 0
538 && n > 0) 546 && n > 0)
539 { 547 {
...@@ -555,7 +563,12 @@ fetch_operation (size_t msgno, char *arg) ...@@ -555,7 +563,12 @@ fetch_operation (size_t msgno, char *arg)
555 message_get_header (msg, &header); 563 message_get_header (msg, &header);
556 header_size (header, &size); 564 header_size (header, &size);
557 header_lines (header, &lines); 565 header_lines (header, &lines);
558 util_send ("{%u}\r\n", size + lines); 566 if (!silent)
567 {
568 util_upper (arg);
569 util_send ("%s", arg);
570 }
571 util_send ("%s {%u}\r\n", partial, size + lines);
559 header_get_stream (header, &stream); 572 header_get_stream (header, &stream);
560 while (stream_readline (stream, buffer, sizeof (buffer), off, &n) == 0 573 while (stream_readline (stream, buffer, sizeof (buffer), off, &n) == 0
561 && n > 0) 574 && n > 0)
...@@ -567,50 +580,178 @@ fetch_operation (size_t msgno, char *arg) ...@@ -567,50 +580,178 @@ fetch_operation (size_t msgno, char *arg)
567 off += n; 580 off += n;
568 } 581 }
569 } 582 }
570 else if (strncasecmp (arg, "[HEADER.FIELDS.NOT", 19) == 0) 583 else if (strncasecmp (arg, "[HEADER.FIELDS.NOT", 18) == 0)
571 { 584 {
572 /* Not implemented. */ 585 char **array = NULL;
586 size_t array_len = 0;
587 char *buffer = NULL;
588 size_t total = 0;
589
590 arg += 18;
591
592 /* Save the field we want to ignore. */
593 {
594 char *field;
595 char *sp = NULL;
596 for (;(field = strtok_r (arg, " ()]\r\n", &sp));
597 arg = NULL, array_len++)
598 {
599 array = realloc (array, (array_len + 1) * sizeof (*array));
600 if (!array)
601 util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
602 array[array_len] = field;
603 }
604 }
605
606 /* Build the buffer. */
607 {
608 size_t i;
609 header_t header = NULL;
610 size_t count = 0;
611 message_get_header (msg, &header);
612 header_get_field_count (header, &count);
613 for (i = 1; i <= count; i++)
614 {
615 char *name;
616 char *value ;
617 size_t ototal;
618 size_t name_len = 0;
619 size_t value_len = 0;
620 size_t ignore = 0;
621
622 /* Get the field name. */
623 header_get_field_name (header, i, NULL, 0, &name_len);
624 if (name_len == 0)
625 continue;
626 name = calloc (name_len + 1, sizeof (*name));
627 if (!name)
628 util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
629 header_get_field_name (header, i, name, name_len + 1, NULL);
630
631 /* Should we ignore the field? */
632 {
633 size_t j;
634 for (j = 0; j < array_len; j++)
635 {
636 if (strcasecmp (array[j], name) == 0)
637 {
638 ignore = 1;
639 break;
640 }
641 }
642 if (ignore)
643 {
644 free (name);
645 continue;
646 }
647 }
648
649 /* Fet the field value. */
650 header_get_field_value (header, i, NULL, 0, &value_len);
651 value = calloc (value_len + 1, sizeof (*value));
652 if (!value)
653 util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
654 header_get_field_value (header, i, value, value_len + 1, NULL);
655
656 /* Save the field. */
657 ototal = name_len + value_len + 4; /* 4 for ": \r\n" */
658 buffer = realloc (buffer, (ototal + total + 1) * sizeof (*buffer));
659 if (!buffer)
660 util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
661 snprintf (buffer + total, ototal + 1, "%s: %s\r\n", name, value);
662 free (value);
663 free (name);
664 total += ototal;
665 }
666 }
667
668 util_send ("[HEADER.FIELDS.NOT");
669 {
670 size_t j;
671 for (j = 0; j < array_len; j++)
672 {
673 util_upper (array[j]);
674 util_send (" \"%s\"", array[j]);
675 }
676 }
677 util_send ("]%s {%u}\r\n", partial, total + 2);
678 util_send ("%s\r\n", (buffer) ? buffer : "");
679 if (buffer)
680 free (buffer);
681 if (array)
682 free (array);
573 } 683 }
574 else if (strncasecmp (arg, "[HEADER.FIELDS", 14) == 0) 684 else if (strncasecmp (arg, "[HEADER.FIELDS", 14) == 0)
575 { 685 {
576 char *field;
577 char *sp = NULL;
578 header_t header = NULL;
579 size_t val_len = 0;
580 size_t total = 0;
581 char *buffer = NULL; 686 char *buffer = NULL;
687 char **array = NULL;
688 size_t array_len = 0;
689 size_t total = 0;
582 690
583 arg += 14; 691 arg += 14;
584 message_get_header (msg, &header);
585
586 for (; field = strtok_r (arg, " ()]\r\n", &sp); arg = NULL, val_len = 0)
587 {
588 size_t ototal;
589 char *value = NULL;
590
591 header_get_value (header, field, NULL, 0, &val_len);
592 if (val_len == 0)
593 continue;
594 value = malloc (val_len + 1);
595 if (!value)
596 util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
597 header_get_value (header, field, value, val_len + 1, NULL);
598
599 ototal = strlen (field) + val_len + 4; /* 4 for ": \r\n" */
600 buffer = realloc (buffer, ototal + total + 1);
601 if (!buffer)
602 util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
603 snprintf (buffer + total, ototal + 1, "%s: %s\r\n", field, value);
604 free (value);
605 total += ototal;
606 }
607 692
608 util_send ("{%u}\r\n", total + 2); 693 /* Save the field. */
694 {
695 char *field;
696 char *sp = NULL;
697 for (;(field = strtok_r (arg, " ()]\r\n", &sp));
698 arg = NULL, array_len++)
699 {
700 array = realloc (array, (array_len + 1) * sizeof (*array));
701 if (!array)
702 util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
703 array[array_len] = field;
704 }
705 }
706
707 {
708 size_t j;
709 header_t header = NULL;
710
711 message_get_header (msg, &header);
712
713 for (j = 0; j < array_len; j++)
714 {
715 size_t ototal;
716 char *value;
717 size_t val_len = 0;
718
719 header_get_value (header, array[j], NULL, 0, &val_len);
720 if (val_len == 0)
721 continue;
722 value = calloc (val_len + 1, sizeof (*value));
723 if (!value)
724 util_quit (1); /* FIXME: send a "* BYE" to the client. */
725 header_get_value (header, array[j], value, val_len + 1, NULL);
726
727 ototal = strlen (array[j]) + val_len + 4; /* 4 for ": \r\n" */
728 buffer = realloc (buffer, (ototal + total + 1) * sizeof (*buffer));
729 if (!buffer)
730 util_quit (1); /* FIXME: send a "* BYE" to the client. */
731 snprintf (buffer + total, ototal + 1, "%s: %s\r\n",
732 array[j], value);
733 free (value);
734 total += ototal;
735 }
736 }
737
738 util_send ("[HEADER.FIELDS");
739 {
740 size_t j;
741 for (j = 0; j < array_len; j++)
742 {
743 util_upper (array[j]);
744 util_send (" \"%s\"", array[j]);
745 }
746 }
747 util_send ("]%s {%u}\r\n", partial, total + 2);
609 if (total) 748 if (total)
610 util_send ("%s", buffer); 749 util_send ("%s", buffer);
611 util_send ("\r\n"); 750 util_send ("\r\n");
612 if (buffer) 751 if (buffer)
613 free (buffer); 752 free (buffer);
753 if (array)
754 free (array);
614 } 755 }
615 else if (strncasecmp (arg, "[TEXT]", 6) == 0) 756 else if (strncasecmp (arg, "[TEXT]", 6) == 0)
616 { 757 {
...@@ -622,7 +763,9 @@ fetch_operation (size_t msgno, char *arg) ...@@ -622,7 +763,9 @@ fetch_operation (size_t msgno, char *arg)
622 message_get_body (msg, &body); 763 message_get_body (msg, &body);
623 body_size (body, &size); 764 body_size (body, &size);
624 body_lines (body, &lines); 765 body_lines (body, &lines);
625 util_send ("{%u}\r\n", size + lines); 766 if (!silent)
767 util_send ("[TEXT]");
768 util_send ("%s {%u}\r\n", partial, size + lines);
626 body_get_stream (body, &stream); 769 body_get_stream (body, &stream);
627 while (stream_readline (stream, buffer, sizeof (buffer), off, &n) == 0 770 while (stream_readline (stream, buffer, sizeof (buffer), off, &n) == 0
628 && n > 0) 771 && n > 0)
......
...@@ -133,6 +133,7 @@ void util_quit __P ((int)); ...@@ -133,6 +133,7 @@ void util_quit __P ((int));
133 char *util_getword __P ((char *s, char **save_ptr)); 133 char *util_getword __P ((char *s, char **save_ptr));
134 int util_token __P ((char *s, size_t, char **save_ptr)); 134 int util_token __P ((char *s, size_t, char **save_ptr));
135 int util_msgset __P ((char *s, int **set, int *n, int isuid)); 135 int util_msgset __P ((char *s, int **set, int *n, int isuid));
136 int util_upper __P ((char *));
136 struct imap4d_command *util_getcommand __P ((char *cmd, 137 struct imap4d_command *util_getcommand __P ((char *cmd,
137 struct imap4d_command [])); 138 struct imap4d_command []));
138 139
......
...@@ -68,17 +68,17 @@ imap4d_select0 (struct imap4d_command *command, char *arg, int flags) ...@@ -68,17 +68,17 @@ imap4d_select0 (struct imap4d_command *command, char *arg, int flags)
68 mailbox_message_unseen (mbox, &unseen); 68 mailbox_message_unseen (mbox, &unseen);
69 util_out (RESP_NONE, "%d EXISTS", count); 69 util_out (RESP_NONE, "%d EXISTS", count);
70 util_out (RESP_NONE, "%d RECENT", recent); 70 util_out (RESP_NONE, "%d RECENT", recent);
71 util_out (RESP_NONE, "FLAGS (%s)", mflags);
72 util_out (RESP_OK, "[UIDNEXT %d] Predicted next uid", uidnext);
73 util_out (RESP_OK, "[UIDVALIDITY (%d)] UID valididy status", 71 util_out (RESP_OK, "[UIDVALIDITY (%d)] UID valididy status",
74 uidvalidity); 72 uidvalidity);
73 util_out (RESP_OK, "[UIDNEXT %d] Predicted next uid", uidnext);
75 if (unseen) 74 if (unseen)
76 util_out (RESP_OK, "[UNSEEN (%d)] %d is first unseen messsage ", 75 util_out (RESP_OK, "[UNSEEN (%d)] %d is first unseen messsage ",
77 unseen, unseen); 76 unseen, unseen);
77 util_out (RESP_NONE, "FLAGS (%s)", mflags);
78 /* FIXME: 78 /* FIXME:
79 - '\*' can be supported if we use the attribute_set userflag() 79 - '\*' can be supported if we use the attribute_set userflag()
80 - Answered is still not set in the mailbox code. */ 80 - Answered is still not set in the mailbox code. */
81 util_out (RESP_OK, "[PERMANENTFLAGS (%s)]", pflags); 81 util_out (RESP_OK, "[PERMANENTFLAGS (%s)] Permanent flags", pflags);
82 return util_send ("%s OK [%s] %s Complete\r\n", command->tag, 82 return util_send ("%s OK [%s] %s Complete\r\n", command->tag,
83 (MU_STREAM_READ == flags) ? 83 (MU_STREAM_READ == flags) ?
84 "READ-ONLY" : "READ-WRITE", command->name); 84 "READ-ONLY" : "READ-WRITE", command->name);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17 17
18 #include "imap4d.h" 18 #include "imap4d.h"
19 #include <ctype.h>
19 20
20 static int add2set (int **set, int *n, unsigned long val, size_t max); 21 static int add2set (int **set, int *n, unsigned long val, size_t max);
21 static const char * sc2string (int rc); 22 static const char * sc2string (int rc);
...@@ -300,6 +301,16 @@ util_do_command (char *prompt) ...@@ -300,6 +301,16 @@ util_do_command (char *prompt)
300 return command->func (command, sp); 301 return command->func (command, sp);
301 } 302 }
302 303
304 int
305 util_upper (char *s)
306 {
307 if (!s)
308 return 0;
309 for (; *s; s++)
310 *s = toupper ((unsigned)*s);
311 return 0;
312 }
313
303 /* FIXME: What is this for? */ 314 /* FIXME: What is this for? */
304 int 315 int
305 util_start (char *tag) 316 util_start (char *tag)
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
28 # endif 28 # endif
29 #endif /*__P */ 29 #endif /*__P */
30 30
31 #ifdef _cplusplus 31 #ifdef __cplusplus
32 extern "C" { 32 extern "C" {
33 #endif 33 #endif
34 34
...@@ -47,7 +47,7 @@ extern int address_get_comments __P ((address_t, size_t, char *, ...@@ -47,7 +47,7 @@ extern int address_get_comments __P ((address_t, size_t, char *,
47 extern int address_to_string __P ((address_t, char *, size_t, size_t *)); 47 extern int address_to_string __P ((address_t, char *, size_t, size_t *));
48 extern int address_get_count __P ((address_t, size_t *)); 48 extern int address_get_count __P ((address_t, size_t *));
49 49
50 #ifdef _cplusplus 50 #ifdef __cplusplus
51 } 51 }
52 #endif 52 #endif
53 53
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
28 #endif 28 #endif
29 #endif /*__P */ 29 #endif /*__P */
30 30
31 #ifdef _cplusplus 31 #ifdef __cplusplus
32 extern "C" { 32 extern "C" {
33 #endif 33 #endif
34 34
...@@ -57,7 +57,7 @@ extern int authority_get_ticket __P ((authority_t, ticket_t *)); ...@@ -57,7 +57,7 @@ extern int authority_get_ticket __P ((authority_t, ticket_t *));
57 extern int authority_authenticate __P ((authority_t)); 57 extern int authority_authenticate __P ((authority_t));
58 extern int authority_set_authenticate __P ((authority_t, int (*_authenticate) __P ((authority_t)), void *)); 58 extern int authority_set_authenticate __P ((authority_t, int (*_authenticate) __P ((authority_t)), void *));
59 59
60 #ifdef _cplusplus 60 #ifdef __cplusplus
61 } 61 }
62 #endif 62 #endif
63 63
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
29 # endif 29 # endif
30 #endif /* __P */ 30 #endif /* __P */
31 31
32 #ifdef _cplusplus 32 #ifdef __cplusplus
33 extern "C" { 33 extern "C" {
34 #endif 34 #endif
35 35
...@@ -55,7 +55,7 @@ extern int body_lines __P ((body_t, size_t *)); ...@@ -55,7 +55,7 @@ extern int body_lines __P ((body_t, size_t *));
55 extern int body_set_lines __P ((body_t, int (*_lines) 55 extern int body_set_lines __P ((body_t, int (*_lines)
56 __P ((body_t, size_t*)), void *owner)); 56 __P ((body_t, size_t*)), void *owner));
57 57
58 #ifdef _cplusplus 58 #ifdef __cplusplus
59 } 59 }
60 #endif 60 #endif
61 61
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
29 #endif 29 #endif
30 #endif /*__P */ 30 #endif /*__P */
31 31
32 #ifdef _cplusplus 32 #ifdef __cplusplus
33 extern "C" { 33 extern "C" {
34 #endif 34 #endif
35 35
...@@ -47,7 +47,7 @@ extern int debug_print __P ((debug_t debug, size_t level, ...@@ -47,7 +47,7 @@ extern int debug_print __P ((debug_t debug, size_t level,
47 const char *format, ...)); 47 const char *format, ...));
48 extern int debug_set_print __P ((debug_t, int (*_print) __P ((debug_t, const char *, va_list)), void *owner)); 48 extern int debug_set_print __P ((debug_t, int (*_print) __P ((debug_t, const char *, va_list)), void *owner));
49 49
50 #ifdef _cplusplus 50 #ifdef __cplusplus
51 } 51 }
52 #endif 52 #endif
53 53
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
29 #endif 29 #endif
30 #endif /*__P */ 30 #endif /*__P */
31 31
32 #ifdef _cplusplus 32 #ifdef __cplusplus
33 extern "C" { 33 extern "C" {
34 #endif 34 #endif
35 35
...@@ -65,7 +65,7 @@ extern "C" { ...@@ -65,7 +65,7 @@ extern "C" {
65 #define MU_HEADER_MIME_VERSION "MIME-Version" 65 #define MU_HEADER_MIME_VERSION "MIME-Version"
66 #define MU_HEADER_X_UIDL "X-UIDL" 66 #define MU_HEADER_X_UIDL "X-UIDL"
67 #define MU_HEADER_X_UID "X-UID" 67 #define MU_HEADER_X_UID "X-UID"
68 #define MU_HEADER_X_IMAPBASE "X-IMAPbase" 68 #define MU_HEADER_X_IMAPBASE "X-IMAPbase"
69 69
70 /* Mime support header attribute */ 70 /* Mime support header attribute */
71 71
...@@ -73,48 +73,54 @@ extern "C" { ...@@ -73,48 +73,54 @@ extern "C" {
73 struct _header; 73 struct _header;
74 typedef struct _header * header_t; 74 typedef struct _header * header_t;
75 75
76 extern int header_create __P ((header_t *, const char *, 76 extern int header_create __P ((header_t *, const char *,
77 size_t, void *)); 77 size_t, void *));
78 extern void header_destroy __P ((header_t *, void *)); 78 extern void header_destroy __P ((header_t *, void *));
79 extern void * header_get_owner __P ((header_t)); 79 extern void * header_get_owner __P ((header_t));
80 80
81 extern int header_is_modified __P ((header_t)); 81 extern int header_is_modified __P ((header_t));
82 extern int header_clear_modified __P ((header_t)); 82 extern int header_clear_modified __P ((header_t));
83 83
84 extern int header_set_value __P ((header_t, const char *, 84 extern int header_set_value __P ((header_t, const char *,
85 const char *, int)); 85 const char *, int));
86 extern int header_set_set_value __P ((header_t, int (*_set_value) 86 extern int header_set_set_value __P ((header_t, int (*_set_value)
87 __P ((header_t, const char *, 87 __P ((header_t, const char *,
88 const char *, int)), void *)); 88 const char *, int)), void *));
89 89
90 extern int header_get_value __P ((header_t, const char *, char *, 90 extern int header_get_value __P ((header_t, const char *, char *,
91 size_t, size_t *)); 91 size_t, size_t *));
92 extern int header_set_get_value __P ((header_t, int (*_get_value) 92 extern int header_set_get_value __P ((header_t, int (*_get_value)
93 __P ((header_t, const char *, char *, 93 __P ((header_t, const char *, char *,
94 size_t, size_t *)), void *)); 94 size_t, size_t *)), void *));
95 extern int header_set_get_fvalue __P ((header_t, int (*_get_value) 95 extern int header_set_get_fvalue __P ((header_t, int (*_get_value)
96 __P ((header_t, const char *, char *, 96 __P ((header_t, const char *, char *,
97 size_t, size_t *)), void *)); 97 size_t, size_t *)), void *));
98 98
99 extern int header_get_stream __P ((header_t, stream_t *)); 99 extern int header_get_field_count __P ((header_t, size_t *));
100 extern int header_set_stream __P ((header_t, stream_t, void *)); 100 extern int header_get_field_value __P ((header_t, size_t, char *,
101 101 size_t, size_t *));
102 extern int header_size __P ((header_t, size_t *)); 102 extern int header_get_field_name __P ((header_t, size_t, char *,
103 extern int header_set_size __P ((header_t, int (*_size) 103 size_t, size_t *));
104 __P ((header_t, size_t *)), void *)); 104
105 105 extern int header_get_stream __P ((header_t, stream_t *));
106 extern int header_lines __P ((header_t, size_t *)); 106 extern int header_set_stream __P ((header_t, stream_t, void *));
107 extern int header_set_lines __P ((header_t, 107
108 int (*_lines) __P ((header_t, 108 extern int header_size __P ((header_t, size_t *));
109 size_t *)), 109 extern int header_set_size __P ((header_t, int (*_size)
110 void *)); 110 __P ((header_t, size_t *)), void *));
111 111
112 extern int header_set_fill __P ((header_t, 112 extern int header_lines __P ((header_t, size_t *));
113 int (*_fill) __P ((header_t, char *, 113 extern int header_set_lines __P ((header_t,
114 size_t, off_t, 114 int (*_lines) __P ((header_t,
115 size_t *)), 115 size_t *)),
116 void *owner)); 116 void *));
117 #ifdef _cplusplus 117
118 extern int header_set_fill __P ((header_t,
119 int (*_fill) __P ((header_t, char *,
120 size_t, off_t,
121 size_t *)),
122 void *owner));
123 #ifdef __cplusplus
118 } 124 }
119 #endif 125 #endif
120 126
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
29 #endif 29 #endif
30 #endif /*__P */ 30 #endif /*__P */
31 31
32 #ifdef _cplusplus 32 #ifdef __cplusplus
33 extern "C" { 33 extern "C" {
34 #endif 34 #endif
35 35
...@@ -43,7 +43,7 @@ extern int iterator_next __P ((iterator_t)); ...@@ -43,7 +43,7 @@ extern int iterator_next __P ((iterator_t));
43 extern int iterator_current __P ((iterator_t, void **pitem)); 43 extern int iterator_current __P ((iterator_t, void **pitem));
44 extern int iterator_is_done __P ((iterator_t)); 44 extern int iterator_is_done __P ((iterator_t));
45 45
46 #ifdef _cplusplus 46 #ifdef __cplusplus
47 } 47 }
48 #endif 48 #endif
49 49
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
28 # endif 28 # endif
29 #endif /*__P */ 29 #endif /*__P */
30 30
31 #ifdef _cplusplus 31 #ifdef __cplusplus
32 extern "C" { 32 extern "C" {
33 #endif 33 #endif
34 34
...@@ -44,7 +44,7 @@ extern int list_count __P ((list_t, size_t *pcount)); ...@@ -44,7 +44,7 @@ extern int list_count __P ((list_t, size_t *pcount));
44 extern int list_remove __P ((list_t, void *item)); 44 extern int list_remove __P ((list_t, void *item));
45 extern int list_get __P ((list_t, size_t _index, void **pitem)); 45 extern int list_get __P ((list_t, size_t _index, void **pitem));
46 46
47 #ifdef _cplusplus 47 #ifdef __cplusplus
48 } 48 }
49 #endif 49 #endif
50 50
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
33 # endif 33 # endif
34 #endif /* __P */ 34 #endif /* __P */
35 35
36 #ifdef _cplusplus 36 #ifdef __cplusplus
37 extern "C" { 37 extern "C" {
38 #endif 38 #endif
39 39
...@@ -60,7 +60,7 @@ extern int mailer_get_observable __P ((mailer_t, observable_t *)); ...@@ -60,7 +60,7 @@ extern int mailer_get_observable __P ((mailer_t, observable_t *));
60 60
61 extern int mailer_get_url __P ((mailer_t, url_t *)); 61 extern int mailer_get_url __P ((mailer_t, url_t *));
62 62
63 #ifdef _cplusplus 63 #ifdef __cplusplus
64 } 64 }
65 #endif 65 #endif
66 66
......
...@@ -40,7 +40,7 @@ typedef struct _message *message_t; ...@@ -40,7 +40,7 @@ typedef struct _message *message_t;
40 # endif 40 # endif
41 #endif /* __P */ 41 #endif /* __P */
42 42
43 #ifdef _cplusplus 43 #ifdef __cplusplus
44 extern "C" { 44 extern "C" {
45 #endif 45 #endif
46 46
...@@ -120,7 +120,7 @@ extern int message_encapsulate __P ((message_t msg, message_t *newmsg, ...@@ -120,7 +120,7 @@ extern int message_encapsulate __P ((message_t msg, message_t *newmsg,
120 extern int message_unencapsulate __P ((message_t msg, message_t *newmsg, 120 extern int message_unencapsulate __P ((message_t msg, message_t *newmsg,
121 void **data)); 121 void **data));
122 122
123 #ifdef _cplusplus 123 #ifdef __cplusplus
124 } 124 }
125 #endif 125 #endif
126 126
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
36 #define MIME_MULTIPART_MIXED 0x1 36 #define MIME_MULTIPART_MIXED 0x1
37 #define MIME_MULTIPART_ALT 0x2 37 #define MIME_MULTIPART_ALT 0x2
38 38
39 #ifdef _cplusplus 39 #ifdef __cplusplus
40 extern "C" { 40 extern "C" {
41 #endif 41 #endif
42 42
...@@ -55,7 +55,7 @@ int mime_add_part __P ((mime_t mime, message_t msg)); ...@@ -55,7 +55,7 @@ int mime_add_part __P ((mime_t mime, message_t msg));
55 55
56 int mime_get_message __P ((mime_t mime, message_t *msg)); 56 int mime_get_message __P ((mime_t mime, message_t *msg));
57 57
58 #ifdef _cplusplus 58 #ifdef __cplusplus
59 } 59 }
60 #endif 60 #endif
61 61
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
28 #endif 28 #endif
29 #endif /*__P */ 29 #endif /*__P */
30 30
31 #ifdef _cplusplus 31 #ifdef __cplusplus
32 extern "C" { 32 extern "C" {
33 #endif 33 #endif
34 34
...@@ -64,7 +64,7 @@ extern int observable_attach __P ((observable_t, size_t type, observer_t obse ...@@ -64,7 +64,7 @@ extern int observable_attach __P ((observable_t, size_t type, observer_t obse
64 extern int observable_detach __P ((observable_t, observer_t observer)); 64 extern int observable_detach __P ((observable_t, observer_t observer));
65 extern int observable_notify __P ((observable_t, int type)); 65 extern int observable_notify __P ((observable_t, int type));
66 66
67 #ifdef _cplusplus 67 #ifdef __cplusplus
68 } 68 }
69 #endif 69 #endif
70 70
......
...@@ -28,25 +28,29 @@ ...@@ -28,25 +28,29 @@
28 # endif 28 # endif
29 #endif /*__P */ 29 #endif /*__P */
30 30
31 #ifdef _cplusplus 31 #ifdef __cplusplus
32 extern "C" { 32 extern "C" {
33 #endif 33 #endif
34 34
35 struct _property; 35 struct _property;
36 typedef struct _property *property_t; 36 typedef struct _property *property_t;
37 enum property_type { TYPE_POINTER, TYPE_LONG };
38 37
39 extern int property_create __P ((property_t *)); 38 extern int property_create __P ((property_t *, void *));
40 extern void property_destroy __P ((property_t *)); 39 extern void property_destroy __P ((property_t *, void *));
40 extern void *property_get_owner __P ((property_t));
41 41
42 extern int property_set_value __P ((property_t, const char *k, const void *v, 42 extern int property_set_value __P ((property_t, const char *, const void *));
43 enum property_type)); 43 extern int property_get_value __P ((property_t, const char *, void **));
44 extern int property_get_value __P ((property_t, const char *k, void **, 44 extern int property_set_set_value __P ((property_t, int (*_set_value)
45 enum property_type *)); 45 __P ((property_t , const char *,
46 const void *)), void *));
47 extern int property_set_get_value __P ((property_t , int (*_get_value)
48 __P ((property_t, const char *,
49 void **)), void *owner));
46 50
47 extern int property_set __P ((property_t, const char *k)); 51 extern int property_set __P ((property_t, const char *));
48 extern int property_unset __P ((property_t, const char *k)); 52 extern int property_unset __P ((property_t, const char *));
49 extern int property_is_set __P ((property_t, const char *k)); 53 extern int property_is_set __P ((property_t, const char *));
50 54
51 extern int property_set_int __P ((property_t, const char *, int)); 55 extern int property_set_int __P ((property_t, const char *, int));
52 extern int property_get_int __P ((property_t, const char *)); 56 extern int property_get_int __P ((property_t, const char *));
...@@ -57,7 +61,7 @@ extern long property_get_long __P ((property_t, const char *)); ...@@ -57,7 +61,7 @@ extern long property_get_long __P ((property_t, const char *));
57 extern int property_set_pointer __P ((property_t, const char *, void *)); 61 extern int property_set_pointer __P ((property_t, const char *, void *));
58 extern void *property_get_pointer __P ((property_t, const char *)); 62 extern void *property_get_pointer __P ((property_t, const char *));
59 63
60 #ifdef _cplusplus 64 #ifdef __cplusplus
61 } 65 }
62 #endif 66 #endif
63 67
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
34 # endif 34 # endif
35 #endif /*__P */ 35 #endif /*__P */
36 36
37 #ifdef _cplusplus 37 #ifdef __cplusplus
38 extern "C" { 38 extern "C" {
39 #endif 39 #endif
40 40
...@@ -119,7 +119,7 @@ extern record_t smtp_record; ...@@ -119,7 +119,7 @@ extern record_t smtp_record;
119 /* Sendmail, "sendmail:" */ 119 /* Sendmail, "sendmail:" */
120 extern record_t sendmail_record; 120 extern record_t sendmail_record;
121 121
122 #ifdef _cplusplus 122 #ifdef __cplusplus
123 } 123 }
124 #endif 124 #endif
125 125
......
...@@ -204,6 +204,8 @@ header_parse (header_t header, const char *blurb, int len) ...@@ -204,6 +204,8 @@ header_parse (header_t header, const char *blurb, int len)
204 { 204 {
205 free (header->blurb); 205 free (header->blurb);
206 free (header->hdr); 206 free (header->hdr);
207 header->blurb = NULL;
208 header->hdr = NULL;
207 return ENOMEM; 209 return ENOMEM;
208 } 210 }
209 hdr[header->hdr_count].fn = fn; 211 hdr[header->hdr_count].fn = fn;
...@@ -307,6 +309,7 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) ...@@ -307,6 +309,7 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
307 { 309 {
308 memcpy (blurb + len, header->blurb, header->blurb_len); 310 memcpy (blurb + len, header->blurb, header->blurb_len);
309 free (header->blurb); 311 free (header->blurb);
312 header->blurb = NULL;
310 } 313 }
311 else 314 else
312 blurb [len] = '\n'; 315 blurb [len] = '\n';
...@@ -486,6 +489,99 @@ header_get_value (header_t header, const char *name, char *buffer, ...@@ -486,6 +489,99 @@ header_get_value (header_t header, const char *name, char *buffer,
486 } 489 }
487 490
488 int 491 int
492 header_get_field_count (header_t header, size_t *pcount)
493 {
494 if (header == NULL)
495 {
496 if (pcount)
497 *pcount = 0;
498 return EINVAL;
499 }
500
501 /* Try to fill out the buffer, if we know how. */
502 if (header->blurb == NULL)
503 {
504 int err = fill_blurb (header);
505 if (err != 0)
506 return err;
507 }
508
509 if (pcount)
510 *pcount = header->hdr_count;
511 return 0;
512 }
513
514 int
515 header_get_field_name (header_t header, size_t num, char *buf,
516 size_t buflen, size_t *nwriten)
517 {
518 size_t len;
519
520 if (header == NULL)
521 return EINVAL;
522
523 /* Try to fill out the buffer, if we know how. */
524 if (header->blurb == NULL)
525 {
526 int err = fill_blurb (header);
527 if (err != 0)
528 return err;
529 }
530
531 if (header->hdr_count == 0 || num > header->hdr_count || num == 0)
532 return ENOENT;
533
534 num--;
535 len = (header->hdr[num].fn_end - header->hdr[num].fn);
536 if (buf && buflen)
537 {
538 /* save one for the null */
539 --buflen;
540 len = (len > buflen) ? len : len;
541 memcpy (buf, header->hdr[num].fn, len);
542 buf[len] = '\0';
543 }
544 if (nwriten)
545 *nwriten = len;
546 return 0;
547 }
548
549 int
550 header_get_field_value (header_t header, size_t num, char *buf,
551 size_t buflen, size_t *nwritten)
552 {
553 size_t len;
554 if (header == NULL)
555 return EINVAL;
556
557 /* Try to fill out the buffer, if we know how. */
558 if (header->blurb == NULL)
559 {
560 int err = fill_blurb (header);
561 if (err != 0)
562 return err;
563 }
564
565 if (header->hdr_count == 0 || num > header->hdr_count || num == 0)
566 return ENOENT;
567
568 num--;
569 len = header->hdr[num].fv_end - header->hdr[num].fv;
570 if (buf && buflen > 0)
571 {
572 /* save one for the null */
573 --buflen;
574 len = (len > buflen) ? buflen : len;
575 memcpy (buf, header->hdr[num].fv, len);
576 buf[len] = '\0';
577 }
578
579 if (nwritten)
580 *nwritten = len;
581 return 0;
582 }
583
584 int
489 header_set_lines (header_t header, int (*_lines) 585 header_set_lines (header_t header, int (*_lines)
490 (header_t, size_t *), void *owner) 586 (header_t, size_t *), void *owner)
491 { 587 {
...@@ -646,7 +742,10 @@ fill_blurb (header_t header) ...@@ -646,7 +742,10 @@ fill_blurb (header_t header)
646 free (header->fhdr[i].fv); 742 free (header->fhdr[i].fv);
647 } 743 }
648 if (header->fhdr) 744 if (header->fhdr)
649 free (header->fhdr); 745 {
746 free (header->fhdr);
747 header->fhdr = NULL;
748 }
650 header->_get_fvalue = NULL; 749 header->_get_fvalue = NULL;
651 750
652 do 751 do
...@@ -788,7 +887,6 @@ header_readline (stream_t is, char *buf, size_t buflen, off_t off, size_t *pn) ...@@ -788,7 +887,6 @@ header_readline (stream_t is, char *buf, size_t buflen, off_t off, size_t *pn)
788 return 0; 887 return 0;
789 } 888 }
790 889
791
792 int 890 int
793 header_get_stream (header_t header, stream_t *pstream) 891 header_get_stream (header_t header, stream_t *pstream)
794 { 892 {
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
32 # endif 32 # endif
33 #endif /*__P */ 33 #endif /*__P */
34 34
35 #ifdef _cplusplus 35 #ifdef __cplusplus
36 extern "C" { 36 extern "C" {
37 #endif 37 #endif
38 38
...@@ -46,7 +46,7 @@ struct _address ...@@ -46,7 +46,7 @@ struct _address
46 struct _address *next; 46 struct _address *next;
47 }; 47 };
48 48
49 #ifdef _cplusplus 49 #ifdef __cplusplus
50 } 50 }
51 #endif 51 #endif
52 52
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
33 #endif 33 #endif
34 #endif /*__P */ 34 #endif /*__P */
35 35
36 #ifdef _cplusplus 36 #ifdef __cplusplus
37 extern "C" { 37 extern "C" {
38 #endif 38 #endif
39 39
...@@ -53,7 +53,7 @@ struct _authority ...@@ -53,7 +53,7 @@ struct _authority
53 }; 53 };
54 54
55 55
56 #ifdef _cplusplus 56 #ifdef __cplusplus
57 } 57 }
58 #endif 58 #endif
59 59
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
36 # endif 36 # endif
37 #endif /* __P */ 37 #endif /* __P */
38 38
39 #ifdef _cplusplus 39 #ifdef __cplusplus
40 extern "C" { 40 extern "C" {
41 #endif 41 #endif
42 42
...@@ -52,7 +52,7 @@ struct _body ...@@ -52,7 +52,7 @@ struct _body
52 int (*_lines) (body_t, size_t*); 52 int (*_lines) (body_t, size_t*);
53 }; 53 };
54 54
55 #ifdef _cplusplus 55 #ifdef __cplusplus
56 } 56 }
57 #endif 57 #endif
58 58
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
32 32
33 #include <mailutils/debug.h> 33 #include <mailutils/debug.h>
34 34
35 #ifdef _cplusplus 35 #ifdef __cplusplus
36 extern "C" { 36 extern "C" {
37 #endif 37 #endif
38 38
...@@ -45,7 +45,7 @@ struct _debug ...@@ -45,7 +45,7 @@ struct _debug
45 int (*_print) __P ((debug_t, const char *, va_list)); 45 int (*_print) __P ((debug_t, const char *, va_list));
46 }; 46 };
47 47
48 #ifdef _cplusplus 48 #ifdef __cplusplus
49 } 49 }
50 #endif 50 #endif
51 51
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
25 #include <mailutils/header.h> 25 #include <mailutils/header.h>
26 #include <sys/types.h> 26 #include <sys/types.h>
27 27
28 #ifdef _cplusplus 28 #ifdef __cplusplus
29 extern "C" { 29 extern "C" {
30 #endif 30 #endif
31 31
...@@ -75,7 +75,7 @@ struct _header ...@@ -75,7 +75,7 @@ struct _header
75 int (*_fill) __P ((header_t, char *, size_t, off_t, size_t *)); 75 int (*_fill) __P ((header_t, char *, size_t, off_t, size_t *));
76 }; 76 };
77 77
78 #ifdef _cplusplus 78 #ifdef __cplusplus
79 } 79 }
80 #endif 80 #endif
81 81
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
32 #endif 32 #endif
33 #endif /*__P */ 33 #endif /*__P */
34 34
35 #ifdef _cplusplus 35 #ifdef __cplusplus
36 extern "C" { 36 extern "C" {
37 #endif 37 #endif
38 38
...@@ -44,7 +44,7 @@ struct _iterator ...@@ -44,7 +44,7 @@ struct _iterator
44 }; 44 };
45 45
46 46
47 #ifdef _cplusplus 47 #ifdef __cplusplus
48 } 48 }
49 #endif 49 #endif
50 50
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
36 #endif 36 #endif
37 #endif /*__P */ 37 #endif /*__P */
38 38
39 #ifdef _cplusplus 39 #ifdef __cplusplus
40 extern "C" { 40 extern "C" {
41 #endif 41 #endif
42 42
...@@ -55,7 +55,7 @@ struct _list ...@@ -55,7 +55,7 @@ struct _list
55 }; 55 };
56 56
57 57
58 #ifdef _cplusplus 58 #ifdef __cplusplus
59 } 59 }
60 #endif 60 #endif
61 61
......
...@@ -75,6 +75,7 @@ struct _mailbox ...@@ -75,6 +75,7 @@ struct _mailbox
75 int (*_expunge) __P ((mailbox_t)); 75 int (*_expunge) __P ((mailbox_t));
76 int (*_uidvalidity) __P ((mailbox_t, unsigned long *num)); 76 int (*_uidvalidity) __P ((mailbox_t, unsigned long *num));
77 int (*_uidnext) __P ((mailbox_t, size_t *num)); 77 int (*_uidnext) __P ((mailbox_t, size_t *num));
78 int (*_get_property) __P ((mailbox_t, property_t *num));
78 79
79 int (*_scan) __P ((mailbox_t, size_t msgno, size_t *count)); 80 int (*_scan) __P ((mailbox_t, size_t msgno, size_t *count));
80 int (*_is_updated) __P ((mailbox_t)); 81 int (*_is_updated) __P ((mailbox_t));
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
25 #include <sys/types.h> 25 #include <sys/types.h>
26 #include <mailutils/mailer.h> 26 #include <mailutils/mailer.h>
27 #include <mailutils/monitor.h> 27 #include <mailutils/monitor.h>
28 #ifdef _cplusplus 28 #ifdef __cplusplus
29 extern "C" { 29 extern "C" {
30 #endif 30 #endif
31 31
...@@ -86,7 +86,7 @@ if (mailer->debug) debug_print (mailer->debug, type, format, arg1, arg2, arg3) ...@@ -86,7 +86,7 @@ if (mailer->debug) debug_print (mailer->debug, type, format, arg1, arg2, arg3)
86 #define MAILER_DEBUG4(mailer, type, format, arg1, arg2, arg3, arg4) \ 86 #define MAILER_DEBUG4(mailer, type, format, arg1, arg2, arg3, arg4) \
87 if (mailer->debug) debug_print (mailer->debug, type, format, arg1, arg2, arg3, arg4) 87 if (mailer->debug) debug_print (mailer->debug, type, format, arg1, arg2, arg3, arg4)
88 88
89 #ifdef _cplusplus 89 #ifdef __cplusplus
90 } 90 }
91 #endif 91 #endif
92 92
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
29 #include <sys/types.h> 29 #include <sys/types.h>
30 #include <stdio.h> 30 #include <stdio.h>
31 31
32 #ifdef _cplusplus 32 #ifdef __cplusplus
33 extern "C" { 33 extern "C" {
34 #endif 34 #endif
35 35
...@@ -74,7 +74,7 @@ struct _message ...@@ -74,7 +74,7 @@ struct _message
74 int (*_size) __P ((message_t, size_t *)); 74 int (*_size) __P ((message_t, size_t *));
75 }; 75 };
76 76
77 #ifdef _cplusplus 77 #ifdef __cplusplus
78 } 78 }
79 #endif 79 #endif
80 80
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
33 #endif 33 #endif
34 #endif /*__P */ 34 #endif /*__P */
35 35
36 #ifdef _cplusplus 36 #ifdef __cplusplus
37 extern "C" { 37 extern "C" {
38 #endif 38 #endif
39 39
...@@ -97,7 +97,7 @@ struct _mime_part ...@@ -97,7 +97,7 @@ struct _mime_part
97 size_t lines; 97 size_t lines;
98 }; 98 };
99 99
100 #ifdef _cplusplus 100 #ifdef __cplusplus
101 } 101 }
102 #endif 102 #endif
103 103
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
32 #endif 32 #endif
33 #endif /*__P */ 33 #endif /*__P */
34 34
35 #ifdef _cplusplus 35 #ifdef __cplusplus
36 extern "C" { 36 extern "C" {
37 #endif 37 #endif
38 38
...@@ -60,7 +60,7 @@ typedef struct _event *event_t; ...@@ -60,7 +60,7 @@ typedef struct _event *event_t;
60 60
61 61
62 62
63 #ifdef _cplusplus 63 #ifdef __cplusplus
64 } 64 }
65 #endif 65 #endif
66 66
......
...@@ -396,6 +396,15 @@ mailbox_get_property (mailbox_t mbox, property_t *pproperty) ...@@ -396,6 +396,15 @@ mailbox_get_property (mailbox_t mbox, property_t *pproperty)
396 { 396 {
397 if (mbox == NULL || pproperty == NULL) 397 if (mbox == NULL || pproperty == NULL)
398 return EINVAL; 398 return EINVAL;
399 if (mbox->property == NULL)
400 {
401 int status;
402 if (mbox->_get_property)
403 return mbox->_get_property (mbox, pproperty);
404 status = property_create (&(mbox->property), mbox);
405 if (status != 0)
406 return status;
407 }
399 *pproperty = mbox->property; 408 *pproperty = mbox->property;
400 return 0; 409 return 0;
401 } 410 }
......
...@@ -153,6 +153,7 @@ struct _mbox_data ...@@ -153,6 +153,7 @@ struct _mbox_data
153 char *sender; 153 char *sender;
154 char *date; 154 char *date;
155 off_t off; 155 off_t off;
156 property_t property;
156 mailbox_t mailbox; /* Back pointer. */ 157 mailbox_t mailbox; /* Back pointer. */
157 }; 158 };
158 159
...@@ -171,6 +172,7 @@ static int mbox_uidnext __P ((mailbox_t, size_t *)); ...@@ -171,6 +172,7 @@ static int mbox_uidnext __P ((mailbox_t, size_t *));
171 static int mbox_scan __P ((mailbox_t, size_t, size_t *)); 172 static int mbox_scan __P ((mailbox_t, size_t, size_t *));
172 static int mbox_is_updated __P ((mailbox_t)); 173 static int mbox_is_updated __P ((mailbox_t));
173 static int mbox_size __P ((mailbox_t, off_t *)); 174 static int mbox_size __P ((mailbox_t, off_t *));
175 static int mbox_get_property __P ((mailbox_t, property_t *));
174 176
175 /* private stuff */ 177 /* private stuff */
176 static int mbox_scan0 __P ((mailbox_t, size_t, size_t *, int)); 178 static int mbox_scan0 __P ((mailbox_t, size_t, size_t *, int));
...@@ -267,6 +269,8 @@ _mailbox_mbox_init (mailbox_t mailbox) ...@@ -267,6 +269,8 @@ _mailbox_mbox_init (mailbox_t mailbox)
267 269
268 mailbox->_size = mbox_size; 270 mailbox->_size = mbox_size;
269 271
272 mailbox->_get_property = mbox_get_property;
273
270 MAILBOX_DEBUG1 (mailbox, MU_DEBUG_TRACE, "mbox_init(%s)\n", mud->name); 274 MAILBOX_DEBUG1 (mailbox, MU_DEBUG_TRACE, "mbox_init(%s)\n", mud->name);
271 return 0; /* okdoke */ 275 return 0; /* okdoke */
272 } 276 }
...@@ -437,7 +441,7 @@ mbox_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) ...@@ -437,7 +441,7 @@ mbox_scan (mailbox_t mailbox, size_t msgno, size_t *pcount)
437 return mbox_scan0 (mailbox, msgno, pcount, 1); 441 return mbox_scan0 (mailbox, msgno, pcount, 1);
438 /* Since the mailbox is already updated fake the scan. */ 442 /* Since the mailbox is already updated fake the scan. */
439 if (msgno > 0) 443 if (msgno > 0)
440 msgno--; /* The fist message is number "1", decremente for the C array. */ 444 msgno--; /* The fist message is number "1", decremente for the C array. */
441 for (i = msgno; i < mud->messages_count; i++) 445 for (i = msgno; i < mud->messages_count; i++)
442 { 446 {
443 if (observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD) != 0) 447 if (observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD) != 0)
...@@ -966,6 +970,41 @@ mbox_unset_attr_flags (attribute_t attr, int flags) ...@@ -966,6 +970,41 @@ mbox_unset_attr_flags (attribute_t attr, int flags)
966 } 970 }
967 971
968 static int 972 static int
973 mbox_property_set_value (property_t property, const char *k, const void *v)
974 {
975 mailbox_t mbox = property_get_owner (property);
976 mbox_data_t mud = mbox->data;
977 return property_set_value (mud->property, k, v);
978 }
979
980 static int
981 mbox_property_get_value (property_t property, const char *k, void **v)
982 {
983 mailbox_t mbox = property_get_owner (property);
984 mbox_data_t mud = mbox->data;
985 return property_get_value (mud->property, k, v);
986 }
987
988 static int
989 mbox_get_property (mailbox_t mbox, property_t *pprop)
990 {
991 mbox_data_t mud = mbox->data;
992 int status = property_create (&(mbox->property), mbox);
993 if (status != 0)
994 return status;
995 status = property_create (&(mud->property), mud);
996 if (status != 0)
997 {
998 property_destroy (&(mbox->property), mbox);
999 return status;
1000 }
1001 property_set_set_value (mbox->property, mbox_property_set_value, mbox);
1002 property_set_get_value (mbox->property, mbox_property_get_value, mbox);
1003 *pprop = mbox->property;
1004 return 0;
1005 }
1006
1007 static int
969 mbox_body_readline (stream_t is, char *buffer, size_t buflen, 1008 mbox_body_readline (stream_t is, char *buffer, size_t buflen,
970 off_t off, size_t *pnread) 1009 off_t off, size_t *pnread)
971 { 1010 {
......
1 /* GNU mailutils - a suite of utilities for electronic mail 1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3 3
4 This program is free software; you can redistribute it and/or modify 4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Library Public License as published by 5 it under the terms of the GNU General Library Public License as published by
...@@ -26,27 +26,29 @@ ...@@ -26,27 +26,29 @@
26 #include <mailutils/list.h> 26 #include <mailutils/list.h>
27 #include <mailutils/iterator.h> 27 #include <mailutils/iterator.h>
28 28
29 #ifdef DMALLOC
30 # include <dmalloc.h>
31 #endif
32
29 struct property_data 33 struct property_data
30 { 34 {
31 size_t hash; 35 size_t hash;
32 enum property_type type; 36 const void *value;
33 union
34 {
35 long l;
36 void *v;
37 } value;
38 }; 37 };
39 38
40 struct _property 39 struct _property
41 { 40 {
41 void *owner;
42 list_t list; 42 list_t list;
43 int (*_set_value) __P ((property_t , const char *, const void *));
44 int (*_get_value) __P ((property_t, const char *, void **));
43 }; 45 };
44 46
45 static int property_find __P ((list_t, const char *, struct property_data **)); 47 static int property_find __P ((list_t, const char *, struct property_data **));
46 static size_t hash __P ((const char *)); 48 static size_t hash __P ((const char *));
47 49
48 int 50 int
49 property_create (property_t *pp) 51 property_create (property_t *pp, void *owner)
50 { 52 {
51 property_t prop; 53 property_t prop;
52 int status; 54 int status;
...@@ -61,33 +63,57 @@ property_create (property_t *pp) ...@@ -61,33 +63,57 @@ property_create (property_t *pp)
61 free (prop); 63 free (prop);
62 return status; 64 return status;
63 } 65 }
66 prop->owner = owner;
64 *pp = prop; 67 *pp = prop;
65 return 0; 68 return 0;
66 } 69 }
67 70
68 void 71 void
69 property_destroy (property_t *pp) 72 property_destroy (property_t *pp, void *owner)
70 { 73 {
71 if (pp && *pp) 74 if (pp && *pp)
72 { 75 {
73 property_t prop = *pp; 76 property_t prop = *pp;
74 list_destroy (&(prop->list)); 77 if (prop->owner == owner)
75 free (prop); 78 {
79 list_destroy (&(prop->list));
80 free (prop);
81 }
76 *pp = NULL; 82 *pp = NULL;
77 } 83 }
78 } 84 }
79 85
86 void *
87 property_get_owner (property_t prop)
88 {
89 return (prop == NULL) ? NULL : prop->owner;
90 }
91
92 int
93 property_set_set_value (property_t prop, int (*_set_value)
94 __P ((property_t , const char *, const void *)),
95 void *owner)
96 {
97 if (prop == NULL)
98 return EINVAL;
99 if (prop->owner != owner)
100 return EACCES;
101 prop->_set_value = _set_value;
102 return 0;
103 }
80 104
81 int 105 int
82 property_set_value (property_t prop, const char *key, const void *value, 106 property_set_value (property_t prop, const char *key, const void *value)
83 enum property_type type)
84 { 107 {
85 struct property_data *pd; 108 struct property_data *pd = NULL;
86 int status; 109 int status;
87 110
88 if (prop == NULL) 111 if (prop == NULL)
89 return EINVAL; 112 return EINVAL;
90 113
114 if (prop->_set_value)
115 return prop->_set_value (prop, key, value);
116
91 status = property_find (prop->list, key, &pd); 117 status = property_find (prop->list, key, &pd);
92 if (status != 0) 118 if (status != 0)
93 return status; 119 return status;
...@@ -98,34 +124,39 @@ property_set_value (property_t prop, const char *key, const void *value, ...@@ -98,34 +124,39 @@ property_set_value (property_t prop, const char *key, const void *value,
98 if (pd == NULL) 124 if (pd == NULL)
99 return ENOMEM; 125 return ENOMEM;
100 pd->hash = hash (key); 126 pd->hash = hash (key);
101 pd->type = type; 127 pd->value = (void *)value;
102 switch (type)
103 {
104 case TYPE_POINTER:
105 pd->value.v = (void *)value;
106 break;
107
108 case TYPE_LONG:
109 pd->value.l = (long)value;
110 break;
111 }
112 list_append (prop->list, (void *)pd); 128 list_append (prop->list, (void *)pd);
113 } 129 }
114 else 130 else
115 pd->value.v = (void *)value; 131 pd->value = (void *)value;
116 return 0; 132 return 0;
117 } 133 }
118 134
119 int 135 int
120 property_get_value (property_t prop, const char *key, void **pvalue, 136 property_set_get_value (property_t prop, int (*_get_value)
121 enum property_type *ptype) 137 __P ((property_t, const char *, void **)),
138 void *owner)
122 { 139 {
123 struct property_data *pd; 140 if (prop == NULL)
141 return EINVAL;
142 if (prop->owner != owner)
143 return EACCES;
144 prop->_get_value = _get_value;
145 return 0;
146 }
147
148 int
149 property_get_value (property_t prop, const char *key, void **pvalue)
150 {
151 struct property_data *pd = NULL;
124 int status; 152 int status;
125 153
126 if (prop == NULL) 154 if (prop == NULL)
127 return EINVAL; 155 return EINVAL;
128 156
157 if (prop->_get_value)
158 return prop->_get_value (prop, key, pvalue);
159
129 status = property_find (prop->list, key, &pd); 160 status = property_find (prop->list, key, &pd);
130 if (status != 0) 161 if (status != 0)
131 return status; 162 return status;
...@@ -133,10 +164,8 @@ property_get_value (property_t prop, const char *key, void **pvalue, ...@@ -133,10 +164,8 @@ property_get_value (property_t prop, const char *key, void **pvalue,
133 if (pd == NULL) 164 if (pd == NULL)
134 return ENOENT; 165 return ENOENT;
135 166
136 if (ptype)
137 *ptype = pd->type;
138 if (pvalue) 167 if (pvalue)
139 *pvalue = pd->value.v; 168 *pvalue = (void *)pd->value;
140 return 0; 169 return 0;
141 } 170 }
142 171
...@@ -161,45 +190,46 @@ property_is_set (property_t prop, const char *k) ...@@ -161,45 +190,46 @@ property_is_set (property_t prop, const char *k)
161 int 190 int
162 property_set_int (property_t prop, const char *k, int i) 191 property_set_int (property_t prop, const char *k, int i)
163 { 192 {
164 return property_set_value (prop, k, (void *)i, TYPE_LONG); 193 return property_set_value (prop, k, (void *)i);
165 } 194 }
166 195
167 int 196 int
168 property_get_int (property_t prop, const char *k) 197 property_get_int (property_t prop, const char *k)
169 { 198 {
170 int value = 0; 199 int value = 0;
171 property_get_value (prop, k, (void **)&value, NULL); 200 property_get_value (prop, k, (void **)&value);
172 return value; 201 return value;
173 } 202 }
174 203
175 int 204 int
176 property_set_long (property_t prop, const char *k, long l) 205 property_set_long (property_t prop, const char *k, long l)
177 { 206 {
178 return property_set_value (prop, k, (const void *)l, TYPE_LONG); 207 return property_set_value (prop, k, (const void *)l);
179 } 208 }
180 209
181 long 210 long
182 property_get_long (property_t prop, const char *k) 211 property_get_long (property_t prop, const char *k)
183 { 212 {
184 long value = 0; 213 long value = 0;
185 property_get_value (prop, k, (void **)&value, NULL); 214 property_get_value (prop, k, (void **)&value);
186 return value; 215 return value;
187 } 216 }
188 217
189 int 218 int
190 property_set_pointer (property_t prop, const char *k, void *p) 219 property_set_pointer (property_t prop, const char *k, void *p)
191 { 220 {
192 return property_set_value (prop, k, p, TYPE_POINTER); 221 return property_set_value (prop, k, p);
193 } 222 }
194 223
195 void * 224 void *
196 property_get_pointer (property_t prop, const char *k) 225 property_get_pointer (property_t prop, const char *k)
197 { 226 {
198 void *value = NULL; 227 void *value = NULL;
199 property_get_value (prop, k, &value, NULL); 228 property_get_value (prop, k, &value);
200 return value; 229 return value;
201 } 230 }
202 231
232 /* Taking from an article in Dr Dobbs. */
203 static size_t 233 static size_t
204 hash (const char *s) 234 hash (const char *s)
205 { 235 {
...@@ -207,12 +237,12 @@ hash (const char *s) ...@@ -207,12 +237,12 @@ hash (const char *s)
207 for (hashval = 0; *s != '\0' ; s++) 237 for (hashval = 0; *s != '\0' ; s++)
208 { 238 {
209 hashval += (unsigned)*s ; 239 hashval += (unsigned)*s ;
210 hashval += (hashval <<10); 240 hashval += (hashval << 10);
211 hashval ^= (hashval >>6) ; 241 hashval ^= (hashval >> 6) ;
212 } 242 }
213 hashval += (hashval <<3); 243 hashval += (hashval << 3);
214 hashval ^= (hashval >>11); 244 hashval ^= (hashval >> 11);
215 hashval += (hashval <<15); 245 hashval += (hashval << 15);
216 return hashval; 246 return hashval;
217 } 247 }
218 248
......