Implement mu_scan_datetime.
* include/mailutils/stream.h (mu_fixed_memory_stream_create): New proto. * libmailutils/stream/memory_stream.c (mu_fixed_memory_stream_create): New function. * include/mailutils/util.h (mu_parse_imap_date_time) (mu_parse_ctime_date_time): Remove. (mu_scan_datetime): New proto. (mu_strftime): Remove const from the last arg. (MU_DATETIME_FROM,MU_DATETIME_IMAP) (MU_DATETIME_IMAP_SEARCH,MU_DATETIME_INTERNALDATE): New defines. * libmailutils/base/strftime.c: New file. * libmailutils/base/Makefile.am (libbase_la_SOURCES): Add strftime.c. * libmailutils/base/date.c (mu_scan_datetime): New function. * libmailutils/base/mutil.c (mu_strftime): Remove. * libmailutils/tests/scantime.at: New file. * libmailutils/tests/scantime.c: New file. * libmailutils/tests/Makefile.am (noinst_PROGRAMS): Add scantime. (TESTSUITE_AT): Add scantime.at. * libmailutils/tests/strftime.c (main): Call mu_set_program_name. * libmailutils/tests/testsuite.at: Include scantime.at * libmu_sieve/actions.c (mime_create_reason): Use mu_c_streamftime. * imap4d/fetch.c (_frt_internaldate): Use mu_scan_datetime. * imap4d/util.c (util_parse_internal_date): Likewise. * libmu_scm/mu_message.c (mu-message-get-envelope-date): Likewise. * libproto/imap/fetch.c (_date_mapper): Likewise. * mail/from.c (hdr_date): Use mu_scan_datetime.
Showing
19 changed files
with
607 additions
and
142 deletions
... | @@ -960,16 +960,12 @@ _frt_internaldate (struct fetch_function_closure *ffc, | ... | @@ -960,16 +960,12 @@ _frt_internaldate (struct fetch_function_closure *ffc, |
960 | mu_envelope_t env = NULL; | 960 | mu_envelope_t env = NULL; |
961 | struct tm tm, *tmp = NULL; | 961 | struct tm tm, *tmp = NULL; |
962 | mu_timezone tz; | 962 | mu_timezone tz; |
963 | char datebuf[sizeof ("13-Jul-2002 00:00:00")]; | ||
964 | int tzoff; | ||
965 | int tzh = 0, tzm = 0; | ||
966 | 963 | ||
967 | mu_message_get_envelope (frt->msg, &env); | 964 | mu_message_get_envelope (frt->msg, &env); |
968 | if (mu_envelope_sget_date (env, &date) == 0 | 965 | if (mu_envelope_sget_date (env, &date) == 0 |
969 | && mu_parse_ctime_date_time (&date, &tm, &tz) == 0) | 966 | && mu_scan_datetime (date, MU_DATETIME_FROM, &tm, &tz, NULL) == 0) |
970 | { | 967 | { |
971 | tmp = &tm; | 968 | tmp = &tm; |
972 | tzoff = tz.utc_offset; | ||
973 | } | 969 | } |
974 | else | 970 | else |
975 | { | 971 | { |
... | @@ -977,18 +973,13 @@ _frt_internaldate (struct fetch_function_closure *ffc, | ... | @@ -977,18 +973,13 @@ _frt_internaldate (struct fetch_function_closure *ffc, |
977 | struct timeval stv; | 973 | struct timeval stv; |
978 | struct timezone stz; | 974 | struct timezone stz; |
979 | 975 | ||
980 | gettimeofday(&stv, &stz); | 976 | gettimeofday (&stv, &stz); |
981 | t = stv.tv_sec; | 977 | t = stv.tv_sec; |
982 | tzoff = - stz.tz_minuteswest; | 978 | tz.utc_offset = - stz.tz_minuteswest; |
983 | tmp = localtime (&t); | 979 | tmp = localtime (&t); |
984 | } | 980 | } |
985 | tzh = tzoff / 3600; | ||
986 | if (tzoff < 0) | ||
987 | tzoff = - tzoff; | ||
988 | tzm = tzoff % 3600; | ||
989 | mu_strftime (datebuf, sizeof (datebuf), "%d-%b-%Y %H:%M:%S", tmp); | ||
990 | io_sendf ("%s", ffc->name); | 981 | io_sendf ("%s", ffc->name); |
991 | io_sendf (" \"%s %+03d%02d\"", datebuf, tzh, tzm); | 982 | mu_c_streamftime (iostream, " \"%d-%b-%Y %H:%M:%S %z\"", tmp, &tz); |
992 | return 0; | 983 | return 0; |
993 | } | 984 | } |
994 | 985 | ... | ... |
... | @@ -373,9 +373,8 @@ util_parse_internal_date (char *date, time_t *timep, | ... | @@ -373,9 +373,8 @@ util_parse_internal_date (char *date, time_t *timep, |
373 | struct tm tm; | 373 | struct tm tm; |
374 | mu_timezone tz; | 374 | mu_timezone tz; |
375 | time_t time; | 375 | time_t time; |
376 | char **datep = &date; | ||
377 | 376 | ||
378 | if (mu_parse_imap_date_time ((const char **) datep, &tm, &tz)) | 377 | if (mu_scan_datetime (date, MU_DATETIME_IMAP_SEARCH, &tm, &tz, NULL)) |
379 | return 1; | 378 | return 1; |
380 | 379 | ||
381 | adjust_tm (&tm, &tz, flag); | 380 | adjust_tm (&tm, &tz, flag); |
... | @@ -412,7 +411,7 @@ util_parse_ctime_date (const char *date, time_t *timep, | ... | @@ -412,7 +411,7 @@ util_parse_ctime_date (const char *date, time_t *timep, |
412 | struct tm tm; | 411 | struct tm tm; |
413 | mu_timezone tz; | 412 | mu_timezone tz; |
414 | 413 | ||
415 | if (mu_parse_ctime_date_time (&date, &tm, &tz) == 0) | 414 | if (mu_scan_datetime (date, MU_DATETIME_FROM, &tm, &tz, NULL) == 0) |
416 | { | 415 | { |
417 | adjust_tm (&tm, &tz, flag); | 416 | adjust_tm (&tm, &tz, flag); |
418 | *timep = mu_tm2time (&tm, &tz); | 417 | *timep = mu_tm2time (&tm, &tz); | ... | ... |
... | @@ -305,6 +305,8 @@ int mu_stdio_stream_create (mu_stream_t *pstream, int fd, int flags); | ... | @@ -305,6 +305,8 @@ int mu_stdio_stream_create (mu_stream_t *pstream, int fd, int flags); |
305 | int mu_memory_stream_create (mu_stream_t *pstream, int flags); | 305 | int mu_memory_stream_create (mu_stream_t *pstream, int flags); |
306 | int mu_static_memory_stream_create (mu_stream_t *pstream, const void *mem, | 306 | int mu_static_memory_stream_create (mu_stream_t *pstream, const void *mem, |
307 | size_t size); | 307 | size_t size); |
308 | int mu_fixed_memory_stream_create (mu_stream_t *pstream, void *mem, | ||
309 | size_t size, int flags); | ||
308 | 310 | ||
309 | int mu_mapfile_stream_create (mu_stream_t *pstream, const char *filename, | 311 | int mu_mapfile_stream_create (mu_stream_t *pstream, const char *filename, |
310 | int flags); | 312 | int flags); | ... | ... |
... | @@ -61,18 +61,22 @@ struct mu_timezone | ... | @@ -61,18 +61,22 @@ struct mu_timezone |
61 | typedef struct mu_timezone mu_timezone; | 61 | typedef struct mu_timezone mu_timezone; |
62 | 62 | ||
63 | int mu_parse_date (const char *p, time_t *rettime, const time_t *now); | 63 | int mu_parse_date (const char *p, time_t *rettime, const time_t *now); |
64 | int mu_parse_imap_date_time (const char **p, struct tm *tm, | ||
65 | mu_timezone *tz); | ||
66 | int mu_parse_ctime_date_time (const char **p, struct tm *tm, | ||
67 | mu_timezone *tz); | ||
68 | 64 | ||
69 | time_t mu_utc_offset (void); | 65 | time_t mu_utc_offset (void); |
70 | time_t mu_tm2time (struct tm *timeptr, mu_timezone *tz); | 66 | time_t mu_tm2time (struct tm *timeptr, mu_timezone *tz); |
71 | size_t mu_strftime (char *s, size_t max, const char *format, | 67 | size_t mu_strftime (char *s, size_t max, const char *format, struct tm *tm); |
72 | const struct tm *tm); | ||
73 | 68 | ||
74 | int mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *tm, | 69 | int mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *tm, |
75 | struct mu_timezone *tz); | 70 | struct mu_timezone *tz); |
71 | int mu_scan_datetime (const char *input, const char *fmt, struct tm *tm, | ||
72 | struct mu_timezone *tz, char **endp); | ||
73 | |||
74 | /* Common datetime formats: */ | ||
75 | #define MU_DATETIME_FROM "%a %b %e %H:%M:%S %Y" | ||
76 | #define MU_DATETIME_IMAP "%d-%b-%Y %H:%M:%S %z" | ||
77 | #define MU_DATETIME_IMAP_SEARCH "%d-%b-%Y%? %H:%M:%S %z" | ||
78 | #define MU_DATETIME_INTERNALDATE "%a, %e %b %Y %H:%M:%S %z" | ||
79 | |||
76 | 80 | ||
77 | /* ----------------------- */ | 81 | /* ----------------------- */ |
78 | /* File & path names. */ | 82 | /* File & path names. */ | ... | ... |
... | @@ -26,6 +26,7 @@ | ... | @@ -26,6 +26,7 @@ |
26 | #include <mailutils/stream.h> | 26 | #include <mailutils/stream.h> |
27 | #include <mailutils/errno.h> | 27 | #include <mailutils/errno.h> |
28 | #include <mailutils/cstr.h> | 28 | #include <mailutils/cstr.h> |
29 | #include <mailutils/cctype.h> | ||
29 | 30 | ||
30 | #define SECS_PER_DAY 86400 | 31 | #define SECS_PER_DAY 86400 |
31 | #define ADJUSTMENT -719162L | 32 | #define ADJUSTMENT -719162L |
... | @@ -528,140 +529,349 @@ mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *input_tm, | ... | @@ -528,140 +529,349 @@ mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *input_tm, |
528 | return rc; | 529 | return rc; |
529 | } | 530 | } |
530 | 531 | ||
531 | int | 532 | static int |
532 | mu_parse_imap_date_time (const char **p, struct tm *tm, mu_timezone *tz) | 533 | _mu_short_weekday_string (const char *str) |
533 | { | 534 | { |
534 | int year, mon, day, hour, min, sec; | ||
535 | char zone[6] = "+0000"; /* ( "+" / "-" ) hhmm */ | ||
536 | char month[5] = ""; | ||
537 | int hh = 0; | ||
538 | int mm = 0; | ||
539 | int sign = 1; | ||
540 | int scanned = 0, scanned3; | ||
541 | int i; | 535 | int i; |
542 | int tzoffset; | ||
543 | 536 | ||
544 | day = mon = year = hour = min = sec = 0; | 537 | for (i = 0; i < 7; i++) |
545 | |||
546 | memset (tm, 0, sizeof (*tm)); | ||
547 | |||
548 | switch (sscanf (*p, | ||
549 | "%2d-%3s-%4d%n %2d:%2d:%2d %5s%n", | ||
550 | &day, month, &year, &scanned3, &hour, &min, &sec, zone, | ||
551 | &scanned)) | ||
552 | { | 538 | { |
553 | case 3: | 539 | if (mu_c_strncasecmp (str, short_wday[i], 3) == 0) |
554 | scanned = scanned3; | 540 | return i; |
555 | break; | ||
556 | case 7: | ||
557 | break; | ||
558 | default: | ||
559 | return -1; | ||
560 | } | 541 | } |
542 | return -1; | ||
543 | } | ||
561 | 544 | ||
562 | tm->tm_sec = sec; | 545 | static int |
563 | tm->tm_min = min; | 546 | _mu_full_weekday_string (const char *str, char **endp) |
564 | tm->tm_hour = hour; | 547 | { |
565 | tm->tm_mday = day; | 548 | int i; |
566 | 549 | ||
567 | for (i = 0; i < 12; i++) | 550 | for (i = 0; i < 7; i++) |
568 | { | 551 | { |
569 | if (mu_c_strncasecmp (month, short_month[i], 3) == 0) | 552 | if (mu_c_strcasecmp (str, full_wday[i]) == 0) |
570 | { | 553 | { |
571 | mon = i; | 554 | if (endp) |
572 | break; | 555 | *endp = (char*) (str + strlen (full_wday[i])); |
556 | return i; | ||
573 | } | 557 | } |
574 | } | 558 | } |
575 | tm->tm_mon = mon; | 559 | return -1; |
576 | tm->tm_year = (year > 1900) ? year - 1900 : year; | 560 | } |
577 | tm->tm_yday = 0; /* unknown. */ | ||
578 | tm->tm_wday = 0; /* unknown. */ | ||
579 | #if HAVE_STRUCT_TM_TM_ISDST | ||
580 | tm->tm_isdst = -1; /* unknown. */ | ||
581 | #endif | ||
582 | 561 | ||
583 | hh = (zone[1] - '0') * 10 + (zone[2] - '0'); | ||
584 | mm = (zone[3] - '0') * 10 + (zone[4] - '0'); | ||
585 | sign = (zone[0] == '-') ? -1 : +1; | ||
586 | tzoffset = sign * (hh * 60 * 60 + mm * 60); | ||
587 | 562 | ||
588 | #if HAVE_STRUCT_TM_TM_GMTOFF | 563 | static int |
589 | tm->tm_gmtoff = tzoffset; | 564 | _mu_short_month_string (const char *str) |
590 | #endif | 565 | { |
566 | int i; | ||
591 | 567 | ||
592 | if (tz) | 568 | for (i = 0; i < 12; i++) |
593 | { | 569 | { |
594 | tz->utc_offset = tzoffset; | 570 | if (mu_c_strncasecmp (str, short_month[i], 3) == 0) |
595 | tz->tz_name = NULL; | 571 | return i; |
596 | } | 572 | } |
573 | return -1; | ||
574 | } | ||
597 | 575 | ||
598 | *p += scanned; | 576 | static int |
577 | _mu_full_month_string (const char *str, char **endp) | ||
578 | { | ||
579 | int i; | ||
599 | 580 | ||
600 | return 0; | 581 | for (i = 0; i < 12; i++) |
582 | { | ||
583 | if (mu_c_strcasecmp (str, full_month[i]) == 0) | ||
584 | { | ||
585 | if (endp) | ||
586 | *endp = (char*) (str + strlen (full_month[i])); | ||
587 | return i; | ||
588 | } | ||
589 | } | ||
590 | return -1; | ||
601 | } | 591 | } |
602 | 592 | ||
603 | /* "ctime" format is: Thu Jul 01 15:58:27 1999, with no trailing \n. */ | ||
604 | int | 593 | int |
605 | mu_parse_ctime_date_time (const char **p, struct tm *tm, mu_timezone *tz) | 594 | get_num (const char *str, char **endp, int ndig, int minval, int maxval, |
595 | int *pn) | ||
606 | { | 596 | { |
607 | int wday = 0; | 597 | int x = 0; |
608 | int year = 0; | ||
609 | int mon = 0; | ||
610 | int day = 0; | ||
611 | int hour = 0; | ||
612 | int min = 0; | ||
613 | int sec = 0; | ||
614 | int n = 0; | ||
615 | int i; | 598 | int i; |
616 | char weekday[5] = ""; | ||
617 | char month[5] = ""; | ||
618 | 599 | ||
619 | if (sscanf (*p, "%3s %3s %2d %2d:%2d:%2d %d%n\n", | 600 | errno = 0; |
620 | weekday, month, &day, &hour, &min, &sec, &year, &n) != 7) | 601 | for (i = 0; i < ndig && *str && mu_isdigit (*str); str++, i++) |
602 | x = x * 10 + *str - '0'; | ||
603 | |||
604 | *endp = (char*) str; | ||
605 | if (i == 0) | ||
621 | return -1; | 606 | return -1; |
607 | else if (pn) | ||
608 | *pn = i; | ||
609 | else if (i != ndig) | ||
610 | return -1; | ||
611 | if (x < minval || x > maxval) | ||
612 | return -1; | ||
613 | return x; | ||
614 | } | ||
622 | 615 | ||
623 | *p += n; | 616 | #define DT_YEAR 0x01 |
617 | #define DT_MONTH 0x02 | ||
618 | #define DT_MDAY 0x04 | ||
619 | #define DT_WDAY 0x08 | ||
620 | #define DT_HOUR 0x10 | ||
621 | #define DT_MIN 0x20 | ||
622 | #define DT_SEC 0x40 | ||
624 | 623 | ||
625 | for (i = 0; i < 7; i++) | 624 | int |
625 | mu_scan_datetime (const char *input, const char *fmt, | ||
626 | struct tm *tm, struct mu_timezone *tz, char **endp) | ||
627 | { | ||
628 | int rc = 0; | ||
629 | char *p; | ||
630 | int n; | ||
631 | int eof_ok = 0; | ||
632 | int datetime_parts = 0; | ||
633 | |||
634 | memset (tm, 0, sizeof *tm); | ||
635 | #ifdef HAVE_STRUCT_TM_TM_ISDST | ||
636 | tm->tm_isdst = -1; /* unknown. */ | ||
637 | #endif | ||
638 | /* provide default timezone, in case it is not supplied in input */ | ||
639 | if (tz) | ||
640 | { | ||
641 | memset (tz, 0, sizeof *tz); | ||
642 | tz->utc_offset = mu_utc_offset (); | ||
643 | } | ||
644 | |||
645 | /* Skip leading whitespace */ | ||
646 | input = mu_str_skip_class (input, MU_CTYPE_BLANK); | ||
647 | for (; *fmt && rc == 0; fmt++) | ||
626 | { | 648 | { |
627 | if (mu_c_strncasecmp (weekday, short_wday[i], 3) == 0) | 649 | if (mu_isspace (*fmt)) |
628 | { | 650 | { |
629 | wday = i; | 651 | fmt = mu_str_skip_class (fmt, MU_CTYPE_BLANK); |
652 | input = mu_str_skip_class (input, MU_CTYPE_BLANK); | ||
653 | if (!*fmt) | ||
630 | break; | 654 | break; |
631 | } | 655 | } |
656 | eof_ok = 0; | ||
657 | |||
658 | if (*fmt == '%') | ||
659 | { | ||
660 | switch (*++fmt) | ||
661 | { | ||
662 | case 'a': | ||
663 | /* The abbreviated weekday name. */ | ||
664 | n = _mu_short_weekday_string (input); | ||
665 | if (n == -1) | ||
666 | rc = MU_ERR_PARSE; | ||
667 | else | ||
668 | { | ||
669 | tm->tm_wday = n; | ||
670 | datetime_parts |= DT_WDAY; | ||
671 | input += 3; | ||
632 | } | 672 | } |
673 | break; | ||
633 | 674 | ||
634 | for (i = 0; i < 12; i++) | 675 | case 'A': |
676 | /* The full weekday name. */ | ||
677 | n = _mu_full_weekday_string (input, &p); | ||
678 | if (n == -1) | ||
679 | rc = MU_ERR_PARSE; | ||
680 | else | ||
635 | { | 681 | { |
636 | if (mu_c_strncasecmp (month, short_month[i], 3) == 0) | 682 | tm->tm_wday = n; |
683 | datetime_parts |= DT_WDAY; | ||
684 | input = p; | ||
685 | } | ||
686 | break; | ||
687 | |||
688 | case 'b': | ||
689 | /* The abbreviated month name. */ | ||
690 | n = _mu_short_month_string (input); | ||
691 | if (n == -1) | ||
692 | rc = MU_ERR_PARSE; | ||
693 | else | ||
637 | { | 694 | { |
638 | mon = i; | 695 | tm->tm_mon = n; |
696 | datetime_parts |= DT_MONTH; | ||
697 | input += 3; | ||
698 | } | ||
639 | break; | 699 | break; |
700 | |||
701 | case 'B': | ||
702 | /* The full month name. */ | ||
703 | n = _mu_full_month_string (input, &p); | ||
704 | if (n == -1) | ||
705 | rc = MU_ERR_PARSE; | ||
706 | else | ||
707 | { | ||
708 | tm->tm_mon = n; | ||
709 | datetime_parts |= DT_MONTH; | ||
710 | input = p; | ||
640 | } | 711 | } |
712 | break; | ||
713 | |||
714 | case 'd': | ||
715 | /* The day of the month as a decimal number (range 01 to 31). */ | ||
716 | n = get_num (input, &p, 2, 1, 31, NULL); | ||
717 | if (n == -1) | ||
718 | rc = MU_ERR_PARSE; | ||
719 | else | ||
720 | { | ||
721 | tm->tm_mday = n; | ||
722 | datetime_parts |= DT_MDAY; | ||
723 | input = p; | ||
641 | } | 724 | } |
725 | break; | ||
642 | 726 | ||
643 | if (tm) | 727 | case 'e': |
728 | /* Like %d, the day of the month as a decimal number, but a | ||
729 | leading zero is replaced by a space. */ | ||
644 | { | 730 | { |
645 | memset (tm, 0, sizeof (struct tm)); | 731 | int ndig; |
646 | 732 | ||
647 | tm->tm_sec = sec; | 733 | n = get_num (input, &p, 2, 1, 31, &ndig); |
648 | tm->tm_min = min; | 734 | if (n == -1) |
649 | tm->tm_hour = hour; | 735 | rc = MU_ERR_PARSE; |
650 | tm->tm_mday = day; | 736 | else |
651 | tm->tm_wday = wday; | 737 | { |
652 | tm->tm_mon = mon; | 738 | tm->tm_mday = n; |
653 | tm->tm_year = (year > 1900) ? year - 1900 : year; | 739 | datetime_parts |= DT_MDAY; |
654 | #ifdef HAVE_STRUCT_TM_TM_ISDST | 740 | input = p; |
655 | tm->tm_isdst = -1; /* unknown. */ | ||
656 | #endif | ||
657 | } | 741 | } |
742 | } | ||
743 | break; | ||
658 | 744 | ||
659 | /* ctime has no timezone information, set tz to local TZ if they ask. */ | 745 | case 'H': |
660 | if (tz) | 746 | /* The hour as a decimal number using a 24-hour clock (range |
747 | 00 to 23). */ | ||
748 | n = get_num (input, &p, 2, 0, 23, NULL); | ||
749 | if (n == -1) | ||
750 | rc = MU_ERR_PARSE; | ||
751 | else | ||
661 | { | 752 | { |
662 | tz->utc_offset = mu_utc_offset (); | 753 | tm->tm_hour = n; |
663 | tz->tz_name = NULL; | 754 | datetime_parts |= DT_HOUR; |
755 | input = p; | ||
756 | } | ||
757 | break; | ||
758 | |||
759 | case 'm': | ||
760 | /* The month as a decimal number (range 01 to 12). */ | ||
761 | n = get_num (input, &p, 2, 1, 12, NULL); | ||
762 | if (n == -1) | ||
763 | rc = MU_ERR_PARSE; | ||
764 | else | ||
765 | { | ||
766 | tm->tm_mon = n - 1; | ||
767 | datetime_parts |= DT_MONTH; | ||
768 | input = p; | ||
664 | } | 769 | } |
770 | break; | ||
665 | 771 | ||
666 | return 0; | 772 | case 'M': |
773 | /* The minute as a decimal number (range 00 to 59). */ | ||
774 | n = get_num (input, &p, 2, 0, 59, NULL); | ||
775 | if (n == -1) | ||
776 | rc = MU_ERR_PARSE; | ||
777 | else | ||
778 | { | ||
779 | tm->tm_min = n; | ||
780 | datetime_parts |= DT_MIN; | ||
781 | input = p; | ||
782 | } | ||
783 | break; | ||
784 | |||
785 | case 'S': | ||
786 | /* The second as a decimal number (range 00 to 60) */ | ||
787 | n = get_num (input, &p, 2, 0, 60, NULL); | ||
788 | if (n == -1) | ||
789 | rc = MU_ERR_PARSE; | ||
790 | else | ||
791 | { | ||
792 | tm->tm_sec = n; | ||
793 | datetime_parts |= DT_SEC; | ||
794 | input = p; | ||
795 | } | ||
796 | break; | ||
797 | |||
798 | case 'Y': | ||
799 | /* The year as a decimal number including the century. */ | ||
800 | errno = 0; | ||
801 | n = strtoul (input, &p, 10); | ||
802 | if (errno || p == input) | ||
803 | rc = MU_ERR_PARSE; | ||
804 | else | ||
805 | { | ||
806 | tm->tm_year = n - 1900; | ||
807 | datetime_parts |= DT_YEAR; | ||
808 | input = p; | ||
809 | } | ||
810 | break; | ||
811 | |||
812 | case 'z': | ||
813 | /* The time-zone as hour offset from GMT */ | ||
814 | { | ||
815 | int sign = 1; | ||
816 | int hr; | ||
817 | |||
818 | if (*input == '+') | ||
819 | input++; | ||
820 | else if (*input == '-') | ||
821 | { | ||
822 | input++; | ||
823 | sign = -1; | ||
824 | } | ||
825 | n = get_num (input, &p, 2, 0, 11, NULL); | ||
826 | if (n == -1) | ||
827 | rc = MU_ERR_PARSE; | ||
828 | else | ||
829 | { | ||
830 | input = p; | ||
831 | hr = n; | ||
832 | n = get_num (input, &p, 2, 0, 59, NULL); | ||
833 | if (n == -1) | ||
834 | rc = MU_ERR_PARSE; | ||
835 | else | ||
836 | { | ||
837 | input = p; | ||
838 | if (tz) | ||
839 | tz->utc_offset = sign * (hr * 60 + n) * 60; | ||
840 | } | ||
841 | } | ||
842 | } | ||
843 | break; | ||
844 | |||
845 | case '%': | ||
846 | if (*input == '%') | ||
847 | input++; | ||
848 | else | ||
849 | rc = MU_ERR_PARSE; | ||
850 | break; | ||
851 | |||
852 | case '?': | ||
853 | eof_ok = 1; | ||
854 | break; | ||
855 | } | ||
856 | if (eof_ok && rc == 0 && *input == 0) | ||
857 | break; | ||
858 | } | ||
859 | else if (*input != *fmt) | ||
860 | rc = MU_ERR_PARSE; | ||
861 | else | ||
862 | input++; | ||
863 | } | ||
864 | |||
865 | if (!eof_ok && rc == 0 && *input == 0 && *fmt) | ||
866 | rc = MU_ERR_PARSE; | ||
867 | |||
868 | if (!(datetime_parts & DT_WDAY) && | ||
869 | (datetime_parts & (DT_YEAR|DT_MONTH|DT_MDAY)) == | ||
870 | (DT_YEAR|DT_MONTH|DT_MDAY)) | ||
871 | tm->tm_wday = dayofweek (tm->tm_year + 1900, tm->tm_mon, tm->tm_mday); | ||
872 | |||
873 | if (endp) | ||
874 | *endp = (char*) input; | ||
875 | |||
876 | return rc; | ||
667 | } | 877 | } | ... | ... |
... | @@ -56,18 +56,6 @@ mu_mh_delim (const char *str) | ... | @@ -56,18 +56,6 @@ mu_mh_delim (const char *str) |
56 | return str[0] == '\n'; | 56 | return str[0] == '\n'; |
57 | } | 57 | } |
58 | 58 | ||
59 | /* A locale-independent version of strftime */ | ||
60 | size_t | ||
61 | mu_strftime (char *s, size_t max, const char *format, const struct tm *tm) | ||
62 | { | ||
63 | size_t size; | ||
64 | mu_set_locale ("C"); | ||
65 | size = strftime (s, max, format, tm); | ||
66 | mu_restore_locale (); | ||
67 | return size; | ||
68 | } | ||
69 | |||
70 | |||
71 | static void | 59 | static void |
72 | assoc_str_free (void *data) | 60 | assoc_str_free (void *data) |
73 | { | 61 | { | ... | ... |
libmailutils/base/strftime.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2011 Free Software Foundation, Inc. | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 3 of the License, or (at your option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General | ||
15 | Public License along with this library. If not, see | ||
16 | <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | #include <mailutils/util.h> | ||
22 | #include <mailutils/stream.h> | ||
23 | #include <mailutils/errno.h> | ||
24 | #include <mailutils/cstr.h> | ||
25 | |||
26 | /* A locale-independent version of strftime */ | ||
27 | size_t | ||
28 | mu_strftime (char *buf, size_t size, const char *format, struct tm *tm) | ||
29 | { | ||
30 | int rc; | ||
31 | mu_stream_t str; | ||
32 | mu_stream_stat_buffer stat; | ||
33 | |||
34 | if (mu_fixed_memory_stream_create (&str, buf, size, MU_STREAM_WRITE)) | ||
35 | return 0; | ||
36 | mu_stream_set_stat (str, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT), stat); | ||
37 | rc = mu_c_streamftime (str, format, tm, NULL); | ||
38 | if (rc == 0) | ||
39 | rc = mu_stream_write (str, "", 1, NULL); | ||
40 | mu_stream_unref (str); | ||
41 | return rc ? 0 : stat[MU_STREAM_STAT_OUT] - 1; | ||
42 | } | ||
43 | |||
44 |
... | @@ -88,6 +88,27 @@ _memory_write (mu_stream_t stream, const char *iptr, size_t isize, | ... | @@ -88,6 +88,27 @@ _memory_write (mu_stream_t stream, const char *iptr, size_t isize, |
88 | } | 88 | } |
89 | 89 | ||
90 | static int | 90 | static int |
91 | _fixed_size_memory_write (mu_stream_t stream, const char *iptr, size_t isize, | ||
92 | size_t *nbytes) | ||
93 | { | ||
94 | struct _mu_memory_stream *mfs = (struct _mu_memory_stream *) stream; | ||
95 | |||
96 | if (mfs->capacity < mfs->offset + isize) | ||
97 | isize = mfs->capacity - mfs->offset; | ||
98 | |||
99 | memcpy (mfs->ptr + mfs->offset, iptr, isize); | ||
100 | |||
101 | mfs->offset += isize; | ||
102 | |||
103 | if (mfs->offset > mfs->size) | ||
104 | mfs->size = mfs->offset; | ||
105 | |||
106 | if (nbytes) | ||
107 | *nbytes = isize; | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static int | ||
91 | _memory_truncate (mu_stream_t stream, mu_off_t len) | 112 | _memory_truncate (mu_stream_t stream, mu_off_t len) |
92 | { | 113 | { |
93 | struct _mu_memory_stream *mfs = (struct _mu_memory_stream *) stream; | 114 | struct _mu_memory_stream *mfs = (struct _mu_memory_stream *) stream; |
... | @@ -271,3 +292,39 @@ mu_static_memory_stream_create (mu_stream_t *pstream, const void *mem, | ... | @@ -271,3 +292,39 @@ mu_static_memory_stream_create (mu_stream_t *pstream, const void *mem, |
271 | return 0; | 292 | return 0; |
272 | } | 293 | } |
273 | 294 | ||
295 | int | ||
296 | mu_fixed_memory_stream_create (mu_stream_t *pstream, void *mem, | ||
297 | size_t size, int flags) | ||
298 | { | ||
299 | mu_stream_t stream; | ||
300 | struct _mu_memory_stream *str; | ||
301 | |||
302 | flags &= (MU_STREAM_READ|MU_STREAM_WRITE); | ||
303 | if (!flags) | ||
304 | return EINVAL; | ||
305 | |||
306 | str = (struct _mu_memory_stream *) | ||
307 | _mu_stream_create (sizeof (*str), flags | MU_STREAM_SEEK); | ||
308 | |||
309 | if (!str) | ||
310 | return ENOMEM; | ||
311 | |||
312 | str->ptr = (void*) mem; | ||
313 | str->size = size; | ||
314 | str->offset = 0; | ||
315 | str->capacity = size; | ||
316 | |||
317 | str->stream.flags |= _MU_STR_OPEN; | ||
318 | if (flags & MU_STREAM_READ) | ||
319 | str->stream.read = _memory_read; | ||
320 | if (flags & MU_STREAM_WRITE) | ||
321 | str->stream.write = _fixed_size_memory_write; | ||
322 | str->stream.size = _memory_size; | ||
323 | str->stream.ctl = _memory_ioctl; | ||
324 | str->stream.seek = _memory_seek; | ||
325 | |||
326 | stream = (mu_stream_t) str; | ||
327 | *pstream = stream; | ||
328 | |||
329 | return 0; | ||
330 | } | ... | ... |
... | @@ -51,6 +51,7 @@ noinst_PROGRAMS = \ | ... | @@ -51,6 +51,7 @@ noinst_PROGRAMS = \ |
51 | listop\ | 51 | listop\ |
52 | mailcap\ | 52 | mailcap\ |
53 | prop\ | 53 | prop\ |
54 | scantime\ | ||
54 | strftime\ | 55 | strftime\ |
55 | tempfile\ | 56 | tempfile\ |
56 | url-comp\ | 57 | url-comp\ |
... | @@ -82,6 +83,7 @@ TESTSUITE_AT = \ | ... | @@ -82,6 +83,7 @@ TESTSUITE_AT = \ |
82 | list.at\ | 83 | list.at\ |
83 | mailcap.at\ | 84 | mailcap.at\ |
84 | prop.at\ | 85 | prop.at\ |
86 | scantime.at\ | ||
85 | strftime.at\ | 87 | strftime.at\ |
86 | testsuite.at\ | 88 | testsuite.at\ |
87 | url.at\ | 89 | url.at\ | ... | ... |
libmailutils/tests/scantime.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2011 Free Software Foundation, Inc. | ||
3 | # | ||
4 | # GNU Mailutils is free software; you can redistribute it and/or | ||
5 | # modify it under the terms of the GNU General Public License as | ||
6 | # published by the Free Software Foundation; either version 3, or (at | ||
7 | # your option) any later version. | ||
8 | # | ||
9 | # GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | # General Public License for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License | ||
15 | # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | AT_BANNER(mu_scan_datetime) | ||
18 | |||
19 | dnl --------------------------------------------------------------------- | ||
20 | dnl SCANTIME([NAME], [KW], [FMT], [INPUT], [STDOUT = `'], [STDERR = `']) | ||
21 | dnl | ||
22 | m4_pushdef([SCANTIME],[ | ||
23 | m4_pushdef([MU_TEST_GROUP],[scantime]) | ||
24 | m4_pushdef([MU_TEST_KEYWORDS],[scantime mu_scan_datetime]) | ||
25 | m4_pushdef([MU_TEST_COMMAND],[TZ=0 scantime -format='$3']) | ||
26 | MU_GENERIC_TEST([$1],[$2],[$4],[],[$5],[$6]) | ||
27 | m4_popdef([MU_TEST_COMMAND]) | ||
28 | m4_popdef([MU_TEST_KEYWORDS]) | ||
29 | m4_popdef([MU_TEST_GROUP]) | ||
30 | ]) | ||
31 | dnl --------------------------------------------------------------------- | ||
32 | |||
33 | SCANTIME([RFC-822 time],[rfc822], | ||
34 | [%a %b %e %H:%M:%S %Y], | ||
35 | [Tue May 3 13:25:26 2011 | ||
36 | Fri Nov 11 11:55:01 2011], | ||
37 | [sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,tz=0 | ||
38 | sec=1,min=55,hour=11,mday=11,mon=10,year=111,wday=5,tz=0 | ||
39 | ]) | ||
40 | |||
41 | SCANTIME([IMAP time format],[imap], | ||
42 | [%d-%b-%Y %H:%M:%S %z], | ||
43 | [03-May-2011 13:25:26 +0100 | ||
44 | 11-Nov-2011 11:55:01 +0100], | ||
45 | [sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,tz=3600 | ||
46 | sec=1,min=55,hour=11,mday=11,mon=10,year=111,wday=5,tz=3600 | ||
47 | ]) | ||
48 | |||
49 | SCANTIME([IMAP search time format],[imap-search], | ||
50 | [%d-%b-%Y%? %H:%M:%S %z], | ||
51 | [03-May-2011 13:25:26 +0100 | ||
52 | 03-May-2011], | ||
53 | [sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,tz=3600 | ||
54 | sec=0,min=0,hour=0,mday=3,mon=4,year=111,wday=2,tz=0 | ||
55 | ]) | ||
56 | |||
57 | SCANTIME([IMAP INTERNALDATE],[imap-internaldate], | ||
58 | [%a, %d %b %Y %H:%M:%S %z], | ||
59 | [Tue, 03 May 2011 13:25:26 +0200], | ||
60 | [sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,tz=7200 | ||
61 | ]) | ||
62 | |||
63 | m4_popdef([SCANTIME]) | ||
64 | dnl --------------------------------------------------------------------- |
libmailutils/tests/scantime.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2007, 2009, 2010, 2011 Free Software | ||
3 | Foundation, Inc. | ||
4 | |||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 3, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | GNU Mailutils is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | #include <stdlib.h> | ||
22 | #include <stdio.h> | ||
23 | #include <string.h> | ||
24 | #include <mailutils/error.h> | ||
25 | #include <mailutils/errno.h> | ||
26 | #include <mailutils/util.h> | ||
27 | #include <mailutils/stream.h> | ||
28 | #include <mailutils/cctype.h> | ||
29 | #include <mailutils/cstr.h> | ||
30 | #include <mailutils/stdstream.h> | ||
31 | |||
32 | void | ||
33 | usage () | ||
34 | { | ||
35 | mu_stream_printf (mu_strout, "usage: %s [-format=FMT] [-tz=TZ]\n", | ||
36 | mu_program_name); | ||
37 | exit (0); | ||
38 | } | ||
39 | |||
40 | int | ||
41 | main (int argc, char **argv) | ||
42 | { | ||
43 | int rc, i; | ||
44 | char *format = "%d-%b-%Y%? %H:%M:%S %z"; | ||
45 | char *buf = NULL; | ||
46 | size_t size = 0; | ||
47 | size_t n; | ||
48 | |||
49 | mu_set_program_name (argv[0]); | ||
50 | |||
51 | mu_stdstream_setup (MU_STDSTREAM_RESET_NONE); | ||
52 | |||
53 | for (i = 1; i < argc; i++) | ||
54 | { | ||
55 | char *opt = argv[i]; | ||
56 | |||
57 | if (strncmp (opt, "-format=", 8) == 0) | ||
58 | format = opt + 8; | ||
59 | else if (strcmp (opt, "-h") == 0) | ||
60 | usage (); | ||
61 | else | ||
62 | { | ||
63 | mu_error ("%s: unrecognized argument", opt); | ||
64 | exit (1); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | while ((rc = mu_stream_getline (mu_strin, &buf, &size, &n)) == 0 && n > 0) | ||
69 | { | ||
70 | char *endp; | ||
71 | struct tm tm; | ||
72 | struct mu_timezone tz; | ||
73 | |||
74 | mu_rtrim_class (buf, MU_CTYPE_ENDLN); | ||
75 | |||
76 | rc = mu_scan_datetime (buf, format, &tm, &tz, &endp); | ||
77 | if (rc) | ||
78 | { | ||
79 | if (*endp) | ||
80 | mu_error ("parse failed near %s", endp); | ||
81 | else | ||
82 | mu_error ("parse failed at end of input"); | ||
83 | continue; | ||
84 | } | ||
85 | if (*endp) | ||
86 | mu_printf ("# stopped at %s\n", endp); | ||
87 | /* FIXME: add tm_yday? */ | ||
88 | mu_printf ("sec=%d,min=%d,hour=%d,mday=%d,mon=%d,year=%d,wday=%d,tz=%d\n", | ||
89 | tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mday, tm.tm_mon, | ||
90 | tm.tm_year, tm.tm_wday, tz.utc_offset); | ||
91 | |||
92 | //mu_c_streamftime (mu_strout, "%c %z%n", &tm, &tz); | ||
93 | } | ||
94 | |||
95 | if (rc) | ||
96 | { | ||
97 | mu_error ("%s", mu_strerror (rc)); | ||
98 | return 1; | ||
99 | } | ||
100 | return 0; | ||
101 | } |
... | @@ -32,7 +32,7 @@ m4_popdef([MU_TEST_GROUP]) | ... | @@ -32,7 +32,7 @@ m4_popdef([MU_TEST_GROUP]) |
32 | ]) | 32 | ]) |
33 | 33 | ||
34 | dnl ------------------------------------------------------------ | 34 | dnl ------------------------------------------------------------ |
35 | # Test data | 35 | # Some test data |
36 | 36 | ||
37 | # January 1970 | 37 | # January 1970 |
38 | # Su Mo Tu We Th Fr Sa | 38 | # Su Mo Tu We Th Fr Sa | ... | ... |
... | @@ -48,6 +48,8 @@ main (int argc, char **argv) | ... | @@ -48,6 +48,8 @@ main (int argc, char **argv) |
48 | struct mu_timezone tz, *tzp = NULL; | 48 | struct mu_timezone tz, *tzp = NULL; |
49 | 49 | ||
50 | mu_set_program_name (argv[0]); | 50 | mu_set_program_name (argv[0]); |
51 | |||
52 | mu_set_program_name (argv[0]); | ||
51 | mu_stdstream_setup (MU_STDSTREAM_RESET_NONE); | 53 | mu_stdstream_setup (MU_STDSTREAM_RESET_NONE); |
52 | 54 | ||
53 | memset (&tz, 0, sizeof tz); | 55 | memset (&tz, 0, sizeof tz); | ... | ... |
... | @@ -24,7 +24,7 @@ m4_define([MU_TEST_KEYWORDS]) | ... | @@ -24,7 +24,7 @@ m4_define([MU_TEST_KEYWORDS]) |
24 | dnl ------------------------------------------------------------ | 24 | dnl ------------------------------------------------------------ |
25 | m4_define([MU_TEST_COMMAND]) | 25 | m4_define([MU_TEST_COMMAND]) |
26 | 26 | ||
27 | m4_define([mu_trimstr],[m4_if([$2],-1,[$1],[m4_substr($1,0,$2)...])]) | 27 | m4_define([mu_trimstr],[m4_if([$2],-1,[$1],[m4_substr([$1],0,$2)...])]) |
28 | m4_define([mu_firstline],[mu_trimstr([$1],m4_index([$1],[ | 28 | m4_define([mu_firstline],[mu_trimstr([$1],m4_index([$1],[ |
29 | ]))]) | 29 | ]))]) |
30 | 30 | ||
... | @@ -43,7 +43,7 @@ dnl RUN-IF-FAIL $7 | ... | @@ -43,7 +43,7 @@ dnl RUN-IF-FAIL $7 |
43 | dnl RUN-IF-PASS $8 | 43 | dnl RUN-IF-PASS $8 |
44 | dnl | 44 | dnl |
45 | m4_define([MU_GENERIC_TEST],[ | 45 | m4_define([MU_GENERIC_TEST],[ |
46 | AT_SETUP([m4_if(MU_TEST_GROUP,[],,MU_TEST_GROUP: )m4_if([$1],[],mu_firstline([$3]),[$1])]) | 46 | AT_SETUP([m4_if(MU_TEST_GROUP,[],,MU_TEST_GROUP: )m4_if([$1],[],[mu_firstline([$3])],[$1])]) |
47 | AT_KEYWORDS([MU_TEST_KEYWORDS $2]) | 47 | AT_KEYWORDS([MU_TEST_KEYWORDS $2]) |
48 | AT_CHECK([ | 48 | AT_CHECK([ |
49 | AT_DATA([input],[$3 | 49 | AT_DATA([input],[$3 |
... | @@ -83,6 +83,7 @@ m4_include([debugspec.at]) | ... | @@ -83,6 +83,7 @@ m4_include([debugspec.at]) |
83 | AT_BANNER([IMAP IO]) | 83 | AT_BANNER([IMAP IO]) |
84 | m4_include([imapio.at]) | 84 | m4_include([imapio.at]) |
85 | 85 | ||
86 | m4_include([scantime.at]) | ||
86 | m4_include([strftime.at]) | 87 | m4_include([strftime.at]) |
87 | 88 | ||
88 | m4_include([fsaf.at]) | 89 | m4_include([fsaf.at]) |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -104,7 +104,7 @@ mu_scm_message_print (SCM message_smob, SCM port, scm_print_state * pstate) | ... | @@ -104,7 +104,7 @@ mu_scm_message_print (SCM message_smob, SCM port, scm_print_state * pstate) |
104 | scm_puts ("UNKNOWN", port); | 104 | scm_puts ("UNKNOWN", port); |
105 | 105 | ||
106 | if (mu_envelope_sget_date (env, &p) == 0 | 106 | if (mu_envelope_sget_date (env, &p) == 0 |
107 | && mu_parse_ctime_date_time (&p, &tm, &tz) == 0) | 107 | && mu_scan_datetime (p, MU_DATETIME_FROM, &tm, &tz, NULL) == 0) |
108 | { | 108 | { |
109 | strftime (datebuf, sizeof (datebuf), "%a %b %e %H:%M", &tm); | 109 | strftime (datebuf, sizeof (datebuf), "%a %b %e %H:%M", &tm); |
110 | buffer = datebuf; | 110 | buffer = datebuf; |
... | @@ -416,7 +416,7 @@ SCM_DEFINE_PUBLIC (scm_mu_message_get_envelope_date, "mu-message-get-envelope-da | ... | @@ -416,7 +416,7 @@ SCM_DEFINE_PUBLIC (scm_mu_message_get_envelope_date, "mu-message-get-envelope-da |
416 | if (status) | 416 | if (status) |
417 | mu_scm_error (FUNC_NAME, status, "cannot get envelope date", | 417 | mu_scm_error (FUNC_NAME, status, "cannot get envelope date", |
418 | scm_list_1 (mesg)); | 418 | scm_list_1 (mesg)); |
419 | status = mu_parse_ctime_date_time (&sdate, &tm, &tz); | 419 | status = mu_scan_datetime (sdate, MU_DATETIME_FROM, &tm, &tz, NULL); |
420 | if (status) | 420 | if (status) |
421 | mu_scm_error (FUNC_NAME, status, "invalid envelope date", | 421 | mu_scm_error (FUNC_NAME, status, "invalid envelope date", |
422 | scm_list_1 (scm_from_locale_string (sdate))); | 422 | scm_list_1 (scm_from_locale_string (sdate))); | ... | ... |
... | @@ -145,7 +145,6 @@ mime_create_reason (mu_mime_t mime, mu_message_t msg, const char *text) | ... | @@ -145,7 +145,6 @@ mime_create_reason (mu_mime_t mime, mu_message_t msg, const char *text) |
145 | char *sender; | 145 | char *sender; |
146 | mu_body_t body; | 146 | mu_body_t body; |
147 | mu_header_t hdr; | 147 | mu_header_t hdr; |
148 | char datestr[80]; | ||
149 | static char *content_header = | 148 | static char *content_header = |
150 | "Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n" | 149 | "Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n" |
151 | "Content-Transfer-Encoding: 8bit\n"; | 150 | "Content-Transfer-Encoding: 8bit\n"; |
... | @@ -156,13 +155,14 @@ mime_create_reason (mu_mime_t mime, mu_message_t msg, const char *text) | ... | @@ -156,13 +155,14 @@ mime_create_reason (mu_mime_t mime, mu_message_t msg, const char *text) |
156 | 155 | ||
157 | time (&t); | 156 | time (&t); |
158 | tm = localtime (&t); | 157 | tm = localtime (&t); |
159 | mu_strftime (datestr, sizeof datestr, "%a, %b %d %H:%M:%S %Y %Z", tm); | ||
160 | 158 | ||
161 | mu_sieve_get_message_sender (msg, &sender); | 159 | mu_sieve_get_message_sender (msg, &sender); |
162 | 160 | ||
163 | mu_stream_printf (stream, | 161 | mu_c_streamftime (stream, |
164 | "The original message was received at %s from %s.\n", | 162 | "The original message was received at " |
165 | datestr, sender); | 163 | "%a, %b %d %H:%M:%S %Y %Z", tm, NULL); |
164 | |||
165 | mu_stream_printf (stream, " from %s.\n", sender); | ||
166 | free (sender); | 166 | free (sender); |
167 | mu_stream_printf (stream, | 167 | mu_stream_printf (stream, |
168 | "Message was refused by recipient's mail filtering program.\n"); | 168 | "Message was refused by recipient's mail filtering program.\n"); |
... | @@ -201,7 +201,7 @@ mime_create_ds (mu_mime_t mime, mu_message_t orig) | ... | @@ -201,7 +201,7 @@ mime_create_ds (mu_mime_t mime, mu_message_t orig) |
201 | 201 | ||
202 | mu_message_get_envelope (orig, &env); | 202 | mu_message_get_envelope (orig, &env); |
203 | if (mu_envelope_sget_date (env, &p) == 0 | 203 | if (mu_envelope_sget_date (env, &p) == 0 |
204 | && mu_parse_ctime_date_time (&p, &tm, &tz) == 0) | 204 | && mu_scan_datetime (p, MU_DATETIME_FROM, &tm, &tz, NULL) == 0) |
205 | t = mu_tm2time (&tm, &tz); | 205 | t = mu_tm2time (&tm, &tz); |
206 | else | 206 | else |
207 | /* Use local time instead */ | 207 | /* Use local time instead */ | ... | ... |
... | @@ -339,14 +339,13 @@ _date_mapper (union mu_imap_fetch_response *resp, | ... | @@ -339,14 +339,13 @@ _date_mapper (union mu_imap_fetch_response *resp, |
339 | struct imap_list_element *elt, | 339 | struct imap_list_element *elt, |
340 | struct parse_response_env *parse_env) | 340 | struct parse_response_env *parse_env) |
341 | { | 341 | { |
342 | const char *p; | ||
343 | struct tm tm; | 342 | struct tm tm; |
344 | struct mu_timezone tz; | 343 | struct mu_timezone tz; |
345 | 344 | ||
346 | if (elt->type != imap_eltype_string) | 345 | if (elt->type != imap_eltype_string) |
347 | return MU_ERR_FAILURE; | 346 | return MU_ERR_FAILURE; |
348 | p = elt->v.string; | 347 | if (mu_scan_datetime (elt->v.string, MU_DATETIME_INTERNALDATE, &tm, &tz, |
349 | if (mu_parse_imap_date_time (&p, &tm, &tz)) | 348 | NULL)) |
350 | return MU_ERR_FAILURE; | 349 | return MU_ERR_FAILURE; |
351 | resp->internaldate.tm = tm; | 350 | resp->internaldate.tm = tm; |
352 | resp->internaldate.tz = tz; | 351 | resp->internaldate.tz = tz; |
... | @@ -472,10 +471,10 @@ _fill_response (void *item, void *data) | ... | @@ -472,10 +471,10 @@ _fill_response (void *item, void *data) |
472 | rc = MU_ERR_FAILURE; | 471 | rc = MU_ERR_FAILURE; |
473 | else | 472 | else |
474 | { | 473 | { |
475 | char const *p = elt->v.string; | 474 | if (mu_scan_datetime (elt->v.string, |
476 | if (mu_parse_imap_date_time (&p, | 475 | MU_DATETIME_IMAP, |
477 | &env->envelope->date, | 476 | &env->envelope->date, |
478 | &env->envelope->tz)) | 477 | &env->envelope->tz, NULL)) |
479 | rc = MU_ERR_FAILURE; | 478 | rc = MU_ERR_FAILURE; |
480 | else | 479 | else |
481 | rc = 0; | 480 | rc = 0; | ... | ... |
... | @@ -213,7 +213,7 @@ hdr_date (struct header_call_args *args, void *data) | ... | @@ -213,7 +213,7 @@ hdr_date (struct header_call_args *args, void *data) |
213 | 213 | ||
214 | mu_message_get_envelope (args->msg, &env); | 214 | mu_message_get_envelope (args->msg, &env); |
215 | if (mu_envelope_sget_date (env, &p) == 0 | 215 | if (mu_envelope_sget_date (env, &p) == 0 |
216 | && mu_parse_ctime_date_time (&p, &tm, &tz) == 0) | 216 | && mu_scan_datetime (p, MU_DATETIME_FROM, &tm, &tz, NULL) == 0) |
217 | strftime (date, sizeof(date), "%a %b %e %H:%M", &tm); | 217 | strftime (date, sizeof(date), "%a %b %e %H:%M", &tm); |
218 | } | 218 | } |
219 | return header_buf_string (args, date); | 219 | return header_buf_string (args, date); | ... | ... |
-
Please register or sign in to post a comment