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.
Showing
34 changed files
with
575 additions
and
192 deletions
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 | ... | ... |
-
Please register or sign in to post a comment