mblaze

Unix utilities to deal with Maildir - my mirror
git clone https://pi.duncano.de/git/mblaze.git
Log | Files | Refs | README | COPYING

commit d458439970caffc3bdebc3c139f29e02b285db55
parent 20dae518c4abaac33226b5e8ae85d0de1a1b226e
Author: Christian Neukirchen <chneukirchen@gmail.com>
Date:   Mon,  8 Aug 2016 16:28:25 +0200

import and use timegm from musl

It's ridiculous this function is not in the standards.

Diffstat:
COPYING | 2+-
Makefile | 24++++++++++++------------
blaze822.c | 2+-
blaze822.h | 8+++++++-
mytimegm.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 107 insertions(+), 15 deletions(-)

diff --git a/COPYING b/COPYING @@ -6,7 +6,7 @@ has waived all copyright and related or neighboring rights to this work. http://creativecommons.org/publicdomain/zero/1.0/ -The files mystrverscmp.c and mymemmem.c +The files mystrverscmp.c and mymemmem.c and mytimegm.c are MIT-licensed and were written by Rich Felker. mpick.c is largely based on code by Christian Neukirchen diff --git a/Makefile b/Makefile @@ -10,24 +10,24 @@ SCRIPT = mcolor mcom mless mquote all: $(ALL) -maddr: maddr.o blaze822.o seq.o rfc2047.o mymemmem.o -magrep: magrep.o blaze822.o seq.o rfc2045.o rfc2047.o mymemmem.o +maddr: maddr.o blaze822.o seq.o rfc2047.o mymemmem.o mytimegm.o +magrep: magrep.o blaze822.o seq.o rfc2045.o rfc2047.o mymemmem.o mytimegm.o mdate: mdate.o -mdeliver: mdeliver.o blaze822.o mymemmem.o +mdeliver: mdeliver.o blaze822.o mymemmem.o mytimegm.o mdirs: mdirs.o -mflag: mflag.o blaze822.o seq.o mymemmem.o -mgenmid: mgenmid.o blaze822.o seq.o mymemmem.o -mhdr: mhdr.o blaze822.o seq.o rfc2047.o mymemmem.o +mflag: mflag.o blaze822.o seq.o mymemmem.o mytimegm.o +mgenmid: mgenmid.o blaze822.o seq.o mymemmem.o mytimegm.o +mhdr: mhdr.o blaze822.o seq.o rfc2047.o mymemmem.o mytimegm.o minc: minc.o mlist: mlist.o mmime: mmime.o -mpick: mpick.o blaze822.o seq.o rfc2047.c mymemmem.o -mscan: mscan.o blaze822.o seq.o rfc2047.o mymemmem.o -msed: msed.o blaze822.o seq.o mymemmem.o +mpick: mpick.o blaze822.o seq.o rfc2047.c mymemmem.o mytimegm.o +mscan: mscan.o blaze822.o seq.o rfc2047.o mymemmem.o mytimegm.o +msed: msed.o blaze822.o seq.o mymemmem.o mytimegm.o mseq: mseq.o seq.o -mshow: mshow.o blaze822.o seq.o rfc2045.o rfc2047.c mymemmem.o filter.o -msort: msort.o blaze822.o seq.o mystrverscmp.o mymemmem.o -mthread: mthread.o blaze822.o seq.o mymemmem.o +mshow: mshow.o blaze822.o seq.o rfc2045.o rfc2047.c mymemmem.o filter.o mytimegm.o +msort: msort.o blaze822.o seq.o mystrverscmp.o mymemmem.o mytimegm.o +mthread: mthread.o blaze822.o seq.o mymemmem.o mytimegm.o README: man/mblaze.7 mandoc -Tutf8 $< | col -bx >$@ diff --git a/blaze822.c b/blaze822.c @@ -121,7 +121,7 @@ blaze822_date(char *s) { tm.tm_isdst = -1; - time_t r = mktime(&tm); + time_t r = tm_to_secs(&tm); return r; fail: diff --git a/blaze822.h b/blaze822.h @@ -1,6 +1,8 @@ -#include <stdint.h> #include <sys/types.h> +#include <stdint.h> +#include <time.h> + struct message; // blaze822.c @@ -71,3 +73,7 @@ char *blaze822_home_file(char *basename); // filter.c int filter(char *input, size_t inlen, char *cmd, char **outputo, size_t *outleno); + +// mygmtime.c + +time_t tm_to_secs(const struct tm *tm); diff --git a/mytimegm.c b/mytimegm.c @@ -0,0 +1,86 @@ +#include <time.h> + +// from musl@1cc81f5cb, slightly tweaked + +static long long +__year_to_secs(long long year, int *is_leap) +{ + if (year-2ULL <= 136) { + int y = year; + int leaps = (y-68)>>2; + if (!((y-68)&3)) { + leaps--; + if (is_leap) *is_leap = 1; + } else if (is_leap) *is_leap = 0; + return 31536000*(y-70) + 86400*leaps; + } + + int cycles, centuries, leaps, rem; + + cycles = (year-100) / 400; + rem = (year-100) % 400; + if (rem < 0) { + cycles--; + rem += 400; + } + if (!rem) { + *is_leap = 1; + centuries = 0; + leaps = 0; + } else { + if (rem >= 200) { + if (rem >= 300) centuries = 3, rem -= 300; + else centuries = 2, rem -= 200; + } else { + if (rem >= 100) centuries = 1, rem -= 100; + else centuries = 0; + } + if (!rem) { + *is_leap = 0; + leaps = 0; + } else { + leaps = rem / 4U; + rem %= 4U; + *is_leap = !rem; + } + } + + leaps += 97*cycles + 24*centuries - *is_leap; + + return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400; +} + +static int +__month_to_secs(int month, int is_leap) +{ + static const int secs_through_month[] = { + 0, 31*86400, 59*86400, 90*86400, + 120*86400, 151*86400, 181*86400, 212*86400, + 243*86400, 273*86400, 304*86400, 334*86400 }; + int t = secs_through_month[month]; + if (is_leap && month >= 2) t+=86400; + return t; +} + +time_t tm_to_secs(const struct tm *tm) +{ + int is_leap; + long long year = tm->tm_year; + int month = tm->tm_mon; + if (month >= 12 || month < 0) { + int adj = month / 12; + month %= 12; + if (month < 0) { + adj--; + month += 12; + } + year += adj; + } + long long t = __year_to_secs(year, &is_leap); + t += __month_to_secs(month, is_leap); + t += 86400LL * (tm->tm_mday-1); + t += 3600LL * tm->tm_hour; + t += 60LL * tm->tm_min; + t += tm->tm_sec; + return t; +}