59#include <sys/inotify.h> 
   60#elif defined(HAVE_KQUEUE) 
   82static char __attribute__((unused)) 
elsieid[] = 
"@(#)localtime.c    8.5";
 
   86#ifndef TZ_ABBR_MAX_LEN 
   87#define TZ_ABBR_MAX_LEN 16 
   90#ifndef TZ_ABBR_CHAR_SET 
   91#define TZ_ABBR_CHAR_SET \ 
   92    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" 
 
   95#ifndef TZ_ABBR_ERR_CHAR 
   96#define TZ_ABBR_ERR_CHAR    '_' 
  104#define OPEN_MODE   (O_RDONLY | O_BINARY) 
  107#define OPEN_MODE   O_RDONLY 
  110static const char   gmt[] = 
"GMT";
 
  111static const struct timeval 
WRONG = { 0, 0 };
 
  127#ifndef TZDEFRULESTRING 
  128#define TZDEFRULESTRING ",M4.1.0,M10.5.0" 
  146#define BIGGEST(a, b)   (((a) > (b)) ? (a) : (b)) 
  149#define MY_TZNAME_MAX   TZNAME_MAX 
  152#define MY_TZNAME_MAX   255 
  155#define TZ_STRLEN_MAX   255 
  175#elif defined(HAVE_KQUEUE) 
  177# ifdef HAVE_O_SYMLINK 
 
  189#define SP_STACK_FLAG INT_MIN 
  191#   define SP_STACK_INIT(sp) do { \ 
  192        (sp).wd[0] = SP_STACK_FLAG; \ 
 
  194#   define SP_STACK_CHECK(sp) ((sp)->wd[0] == SP_STACK_FLAG) 
  195#   define SP_HEAP_INIT(sp) do { \ 
 
  199#   define SP_HEAP_FREE(sp) do {} while (0) 
  201#elif defined(HAVE_KQUEUE) 
  202#   define SP_STACK_INIT(sp) do { \ 
  203        (sp).fd = SP_STACK_FLAG; \ 
  205#   define SP_STACK_CHECK(sp) ((sp)->fd == SP_STACK_FLAG) 
  207#   define SP_HEAP_INIT(sp) do { \ 
  211#   define SP_HEAP_FREE(sp) do { \ 
  213        kqueue_daemon_freestate(sp); \ 
  214        if ((sp)->fd > -1) { close((sp)->fd); (sp)->fd = -1; } \ 
  215        if ((sp)->fds > -1) { close((sp)->fds); (sp)->fds = -1; } \ 
  220#   define SP_HEAP_INIT(sp) do { \ 
  224#   define SP_HEAP_FREE(sp) do { \ 
  226        kqueue_daemon_freestate(sp); \ 
  227        if ((sp)->fd > -1) { close((sp)->fd); (sp)->fd = -1; } \ 
  228        if ((sp)->dir != NULL) { closedir((sp)->dir); (sp)->dir = NULL; } \ 
  235#   define SP_STACK_INIT(sp) do {} while (0) 
  236#   define SP_STACK_CHECK(sp) (0) 
  237#   define SP_HEAP_INIT(sp) do {} while (0) 
  238#   define SP_HEAP_FREE(sp) do {} while (0) 
  258#define MONTH_NTH_DAY_OF_WEEK   2    
  268static const char * 
getqzname P((
const char * strp, 
const int delim));
 
  269static const char * 
getnum P((
const char * strp, 
int * nump, 
int min,
 
  271static const char * 
getsecs P((
const char * strp, 
long * secsp));
 
  272static const char * 
getoffset P((
const char * strp, 
long * offsetp));
 
  273static const char * 
getrule P((
const char * strp, 
struct rule * rulep));
 
  283                int * unitsptr, 
const int base));
 
  287                struct ast_tm * (*funcp) 
P((
const struct timeval *,
 
  289                long offset, 
const struct state *sp));
 
  291                struct ast_tm * (*funcp) 
P((
const struct timeval *,
 
  293                long offset, 
int * okayp, 
const struct state *sp));
 
  295                struct ast_tm * (*funcp) (
const struct timeval *,
 
  297                long offset, 
int * okayp, 
int do_norm_secs, 
const struct state *sp));
 
  301                const struct ast_tm * btmp));
 
  303                const struct rule * rulep, 
long offset));
 
  313#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) 
  318#define TZ_STRLEN_MAX 255 
  337        if (sp->
name[0] == 
'/') {
 
 
  356    struct inotify_event *iev;
 
  357    size_t real_sizeof_iev = 
sizeof(*iev) + 
FILENAME_MAX + 1;
 
  378        if ((res = read(
inotify_fd, iev, real_sizeof_iev)) < 
sizeof(*iev) && res > 0) {
 
  380            ast_log(
LOG_ERROR, 
"Inotify read less than a full event (%zd < %zu)?!!\n", res, 
sizeof(*iev));
 
  382        } 
else if (res < 0) {
 
  396            if (cur->
wd[0] == iev->wd || cur->
wd[1] == iev->wd) {
 
 
  428            fprintf(stderr, 
"Unable to start notification thread\n");
 
  437        if (readlink(path, fullpath, 
sizeof(fullpath) - 1) != -1) {
 
  439            sp->
wd[1] = inotify_add_watch(
inotify_fd, fullpath, IN_ATTRIB | IN_DELETE_SELF | IN_MODIFY | IN_MOVE_SELF | IN_CLOSE_WRITE );
 
  444        sp->
wd[0] = inotify_add_watch(
inotify_fd, path, IN_ATTRIB | IN_DELETE_SELF | IN_MODIFY | IN_MOVE_SELF | IN_CLOSE_WRITE
 
 
  451#elif defined(HAVE_KQUEUE) 
  452static int queue_fd = -1;
 
  467#   define EVVN_NOTES_BITS \ 
  468    (NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_REVOKE|NOTE_ATTRIB \ 
  469    |NOTE_RENAME|NOTE_LINK|NOTE_TRUNCATE) 
  471#   define EVVN_NOTES_BITS \ 
  472    (NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_REVOKE|NOTE_ATTRIB \ 
  473    |NOTE_RENAME|NOTE_LINK) 
  476static void *kqueue_daemon(
void *data)
 
  482    if (queue_fd < 0 && (queue_fd = kqueue()) < 0) {
 
  485        fprintf(stderr, 
"Unable to initialize kqueue(): %s\n", strerror(
errno));
 
  500        if (kevent(queue_fd, 
NULL, 0, &kev, 1, 
NULL) < 0) {
 
  507        sp = (
struct state *) kev.udata;
 
  533static void kqueue_daemon_freestate(
struct state *sp)
 
  536    struct timespec no_wait = { 0, 1 };
 
  552        EV_SET(&kev, sp->fd, EVFILT_VNODE, EV_DELETE, 0, 0, 
NULL);
 
  553        kevent(queue_fd, &kev, 1, 
NULL, 0, &no_wait);
 
  559        EV_SET(&kev, sp->fds, EVFILT_VNODE, EV_DELETE, 0, 0, 
NULL);
 
  560        kevent(queue_fd, &kev, 1, 
NULL, 0, &no_wait);
 
  565        EV_SET(&kev, dirfd(sp->dir), EVFILT_VNODE, EV_DELETE, 0, 0, 
NULL);
 
  566        kevent(queue_fd, &kev, 1, 
NULL, 0, &no_wait);
 
  574    struct timespec no_wait = { 0, 1 };
 
  596        if (psx_sp != 
NULL ||
 
  603            sizeof(psx_sp->
name));
 
  625    if (readlink(path, watchdir, 
sizeof(watchdir) - 1) != -1 && (sp->fds = open(path, O_RDONLY | O_SYMLINK
 
  626# ifdef HAVE_O_EVTONLY
 
  630        EV_SET(&kev, sp->fds, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT, EVVN_NOTES_BITS, 0, sp);
 
  632        if (kevent(queue_fd, &kev, 1, 
NULL, 0, &no_wait) < 0 && 
errno != 0) {
 
  637            fprintf(stderr, 
"Unable to watch '%s': %s\n", path, strerror(
errno));
 
  643    if (readlink(path, watchdir, 
sizeof(watchdir) - 1) != -1) {
 
  649        if ((slash = strrchr(watchdir, 
'/'))) {
 
  652        if (!(sp->dir = opendir(watchdir))) {
 
  653            fprintf(stderr, 
"Unable to watch directory with symlink '%s': %s\n", path, strerror(
errno));
 
  666        EV_SET(&kev, dirfd(sp->dir), EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
 
  667                EVVN_NOTES_BITS, 0, sp);
 
  669        if (kevent(queue_fd, &kev, 1, 
NULL, 0, &no_wait) < 0 && 
errno != 0) {
 
  670            fprintf(stderr, 
"Unable to watch '%s': %s\n", watchdir, strerror(
errno));
 
  679    if ((sp->fd = open(path, O_RDONLY
 
  680# ifdef HAVE_O_EVTONLY
 
  684        fprintf(stderr, 
"Unable to watch '%s' for changes: %s\n", path, strerror(
errno));
 
  688    EV_SET(&kev, sp->fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT, EVVN_NOTES_BITS, 0, sp);
 
  690    if (kevent(queue_fd, &kev, 1, 
NULL, 0, &no_wait) < 0 && 
errno != 0) {
 
  695        fprintf(stderr, 
"Unable to watch '%s': %s\n", path, strerror(
errno));
 
  702static void *notify_daemon(
void *data)
 
  706    struct timespec sixty_seconds = { 60, 0 };
 
  717        nanosleep(&sixty_seconds, 
NULL);
 
  724            if (
name[0] != 
'/') {
 
  725                (void) strcpy(fullname, 
TZDIR "/");
 
  726                (void) strcat(fullname, 
name);
 
  731            if (st.st_mtime > cur->mtime[0] || lst.st_mtime > cur->mtime[1]) {
 
  734                    ast_test_status_update(
test, 
"Removing cached TZ entry '%s' because underlying file changed. (%ld != %ld) or (%ld != %ld)\n", 
name, st.st_mtime, cur->mtime[0], lst.st_mtime, cur->mtime[1]);
 
  769    sp->mtime[0] = st.st_mtime;
 
  771    sp->mtime[1] = st.st_mtime;
 
  798    struct timespec wait_time = { .tv_sec = wait_now.tv_sec + 2, .tv_nsec = wait_now.tv_usec * 1000 };
 
 
  827    result = (codep[0] & 0x80) ? ~0L : 0;
 
  828    for (i = 0; i < 4; ++i)
 
 
  839    for (i = 0; i < 8; ++i)
 
 
  846    const long long at1 = t1, at0 = t0;
 
 
  882        doaccess = 
name[0] == 
'/';
 
  886            if ((strlen(p) + strlen(
name) + 1) >= 
sizeof fullname)
 
  888            (void) strcpy(fullname, p);
 
  889            (void) strcat(fullname, 
"/");
 
  890            (void) strcat(fullname, 
name);
 
  898        if (doaccess && access(
name, 
R_OK) != 0)
 
  911    nread = read(fid, u.buf, 
sizeof u.buf);
 
  913    if (close(fid) < 0 || nread < 
sizeof u.tzhead)
 
  915    for (stored = 4; stored <= 8; stored *= 2) {
 
  919        ttisstdcnt = (int) 
detzcode(u.tzhead.tzh_ttisstdcnt);
 
  920        ttisgmtcnt = (int) 
detzcode(u.tzhead.tzh_ttisgmtcnt);
 
  925        p = u.tzhead.tzh_charcnt + 
sizeof u.tzhead.tzh_charcnt;
 
  930            (ttisstdcnt != sp->
typecnt && ttisstdcnt != 0) ||
 
  931            (ttisgmtcnt != sp->
typecnt && ttisgmtcnt != 0))
 
  933        if (nread - (p - u.buf) <
 
  942        for (i = 0; i < sp->
timecnt; ++i) {
 
  943            sp->
ats[i] = (stored == 4) ?
 
  947        for (i = 0; i < sp->
timecnt; ++i) {
 
  948            sp->
types[i] = (
unsigned char) *p++;
 
  952        for (i = 0; i < sp->
typecnt; ++i) {
 
  955            ttisp = &sp->
ttis[i];
 
  958            ttisp->
tt_isdst = (
unsigned char) *p++;
 
  966        for (i = 0; i < sp->
charcnt; ++i)
 
  969        for (i = 0; i < sp->
leapcnt; ++i) {
 
  972            lsisp = &sp->
lsis[i];
 
  979        for (i = 0; i < sp->
typecnt; ++i) {
 
  982            ttisp = &sp->
ttis[i];
 
  992        for (i = 0; i < sp->
typecnt; ++i) {
 
  995            ttisp = &sp->
ttis[i];
 
 1010        for (i = 0; i < sp->
timecnt - 2; ++i)
 
 1011            if (sp->
ats[i] > sp->
ats[i + 1]) {
 
 1024                    for (j = 0; j + i < sp->
timecnt; ++j) {
 
 1025                        sp->
ats[j] = sp->
ats[j + i];
 
 1035        if (u.tzhead.tzh_version[0] == 
'\0')
 
 1038        for (i = 0; i < nread; ++i)
 
 1042        if (nread < 
sizeof(u.tzhead)) {
 
 1048        if (stored >= (
int) 
sizeof(time_t) && 
TYPE_INTEGRAL(time_t))
 
 1051    if (doextend && nread > 2 &&
 
 1052        u.buf[0] == 
'\n' && u.buf[nread - 1] == 
'\n' &&
 
 1063            u.buf[nread - 1] = 
'\0';
 
 1067                    for (i = 0; i < 2; ++i)
 
 1070                    for (i = 0; i < ts.
charcnt; ++i)
 
 
 1104    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
 
 1105    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
 
 
 1122    while ((
c = *strp) != 
'\0' && !
is_digit(
c) && 
c != 
',' && 
c != 
'-' &&
 
 
 1137static const char * 
getqzname(
const char *strp, 
const int delim)
 
 1141    while ((
c = *strp) != 
'\0' && 
c != delim)
 
 
 1153static const char *
getnum(
const char *strp, 
int *nump, 
const int min, 
const int max)
 
 1162        num = num * 10 + (
c - 
'0');
 
 
 1181static const char *
getsecs(
const char *strp, 
long * 
const secsp)
 
 
 1220static const char *
getoffset(
const char *strp, 
long *offsetp)
 
 1227    } 
else if (*strp == 
'+')
 
 1229    strp = 
getsecs(strp, offsetp);
 
 1233        *offsetp = -*offsetp;
 
 
 1253    } 
else if (*strp == 
'M') {
 
 
 1295static time_t 
transtime(
const time_t janfirst, 
const int year, 
const struct rule *rulep, 
const long offset)
 
 1300    int     d, m1, yy0, yy1, yy2, dow;
 
 1315        if (leapyear && rulep->
r_day >= 60)
 
 1333        for (i = 0; i < rulep->
r_mon - 1; ++i)
 
 1340        m1 = (rulep->
r_mon + 9) % 12 + 1;
 
 1341        yy0 = (rulep->
r_mon <= 2) ? (year - 1) : year;
 
 1344        dow = ((26 * m1 - 2) / 10 +
 
 1345            1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
 
 1357        for (i = 1; i < rulep->
r_week; ++i) {
 
 
 1387    const char *            stdname;
 
 1388    const char *            dstname;
 
 1394    unsigned char * typep;
 
 1401        stdlen = strlen(
name);  
 
 1403        if (stdlen >= 
sizeof sp->
chars)
 
 1404            stdlen = (
sizeof sp->
chars) - 1;
 
 1413            stdlen = 
name - stdname;
 
 1417            stdlen = 
name - stdname;
 
 1426    if (load_result != 0)
 
 1428    if (*
name != 
'\0') {
 
 1434            dstlen = 
name - dstname;
 
 1439            dstlen = 
name - dstname; 
 
 1446        if (*
name == 
'\0' && load_result != 0)
 
 1448        if (*
name == 
',' || *
name == 
';') {
 
 1484                starttime = 
transtime(janfirst, year, &start,
 
 1488                if (starttime > endtime) {
 
 1500                newfirst = janfirst;
 
 1503                if (newfirst <= janfirst)
 
 1505                janfirst = newfirst;
 
 1508            long    theirstdoffset;
 
 1519            for (i = 0; i < sp->
timecnt; ++i) {
 
 1527            theiroffset = theirstdoffset;
 
 1532            for (i = 0; i < sp->
timecnt; ++i) {
 
 1539                    sp->
ats[i] += stdoffset - theirstdoffset;
 
 1543                    theirstdoffset = theiroffset;
 
 1572    (void) strncpy(cp, stdname, stdlen);
 
 1576        (void) strncpy(cp, dstname, dstlen);
 
 1577        *(cp + dstlen) = 
'\0';
 
 
 1607        zone = getenv(
"TZ");
 
 1612        zone = 
"/etc/localtime";
 
 1618        if (!strcmp(sp->
name, zone)) {
 
 
 1650    const struct ttinfo *   ttisp;
 
 1654    memcpy(&t, timep, 
sizeof(t));
 
 1657        return gmtsub(timep, offset, tmp);
 
 1658    if ((sp->
goback && t.tv_sec < sp->
ats[0]) ||
 
 1660            struct timeval  newt = t;
 
 1665            if (t.tv_sec < sp->
ats[0])
 
 1666                seconds = sp->
ats[0] - t.tv_sec;
 
 1667            else    seconds = t.tv_sec - sp->
ats[sp->
timecnt - 1];
 
 1672            if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
 
 1677            if (t.tv_sec < sp->
ats[0])
 
 1678                newt.tv_sec += seconds;
 
 1679            else    newt.tv_sec -= seconds;
 
 1680            if (newt.tv_sec < sp->
ats[0] ||
 
 1688                if (t.tv_sec < sp->
ats[0])
 
 1698    if (sp->
timecnt == 0 || t.tv_sec < sp->
ats[0]) {
 
 1711            int mid = (lo + hi) >> 1;
 
 1713            if (t.tv_sec < sp->
ats[mid])
 
 1718        i = (int) sp->
types[lo - 1];
 
 1720    ttisp = &sp->
ttis[i];
 
 1735    tmp->
tm_usec = timep->tv_usec;
 
 
 1742    memset(tmp, 0, 
sizeof(*tmp));
 
 
 1754void ast_get_dst_info(
const time_t * 
const timep, 
int *dst_enabled, time_t *dst_start, time_t *dst_end, 
int *gmt_off, 
const char * 
const zone)
 
 1757    int transition1 = -1;
 
 1758    int transition2 = -1;
 
 1760    int  bounds_exceeded = 0;
 
 1762    const struct state *sp;
 
 1764    if (
NULL == dst_enabled)
 
 1768    if (
NULL == dst_start || 
NULL == dst_end || 
NULL == gmt_off)
 
 1789            seconds = sp->
ats[0] - t;
 
 1795        if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
 
 1808        bounds_exceeded = 1;
 
 1826    for (i = 1; i < sp->
timecnt; ++i) {
 
 1827        if (t < sp->
ats[i]) {
 
 1828            transition1 = sp->
types[i - 1];
 
 1829            transition2 = sp->
types[i];
 
 1835    if (i >= sp->
timecnt || 0 > transition1 || 0 > transition2 ||
 
 1847        if (!bounds_exceeded) {
 
 1851                *dst_start = sp->
ats[i];
 
 1852                *dst_end = sp->
ats[i -1];
 
 1854                *dst_start = sp->
ats[i -1];
 
 1855                *dst_end = sp->
ats[i];
 
 
 1873        if (!strcmp(sp->
name, 
"UTC"))
 
 1897        tmp->TM_ZONE = sp->
chars;
 
 
 1909    return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
 
 
 1915    const struct lsinfo *   lp;
 
 1932        if (timep->tv_sec >= lp->
ls_trans) {
 
 1933            if (timep->tv_sec == lp->
ls_trans) {
 
 1934                hit = ((i == 0 && lp->
ls_corr > 0) ||
 
 1961        if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
 
 1964            idelta = (tdays < 0) ? -1 : 1;
 
 1983    rem += offset - corr;
 
 2028        idays -= ip[tmp->
tm_mon];
 
 2029    tmp->
tm_mday = (int) (idays + 1);
 
 2032    tmp->TM_GMTOFF = offset;
 
 2034    tmp->
tm_usec = timep->tv_usec;
 
 
 2057    return (*
number < number0) != (delta < 0);
 
 
 2066    return (*
number < number0) != (delta < 0);
 
 
 2073    tensdelta = (*unitsptr >= 0) ?
 
 2074        (*unitsptr / base) :
 
 2075        (-1 - (-1 - *unitsptr) / base);
 
 2076    *unitsptr -= tensdelta * base;
 
 
 2084    tensdelta = (*unitsptr >= 0) ?
 
 2085        (*unitsptr / base) :
 
 2086        (-1 - (-1 - *unitsptr) / base);
 
 2087    *unitsptr -= tensdelta * base;
 
 
 2105static struct timeval 
time2sub(struct 
ast_tm *tmp, 
struct ast_tm * (* 
const funcp) (
const struct timeval *, 
long, 
struct ast_tm *, 
const struct state *), 
const long offset, 
int *okayp, 
const int do_norm_secs, 
const struct state *sp)
 
 2114    struct timeval          newt = { 0, 0 };
 
 2115    struct timeval          t = { 0, 0 };
 
 2116    struct ast_tm           yourtm, mytm;
 
 2141        li = y + (1 < yourtm.
tm_mon);
 
 2145        li = y + (1 < yourtm.
tm_mon);
 
 2179        saved_seconds = yourtm.
tm_sec;
 
 2182        saved_seconds = yourtm.
tm_sec;
 
 2192        if (
sizeof(time_t) > 
sizeof(
float))
 
 2193            hi = (time_t) DBL_MAX;
 
 2194        else    hi = (time_t) FLT_MAX;
 
 2198        for (i = 0; i < (int) 
TYPE_BIT(time_t) - 1; ++i)
 
 2203        t.tv_sec = lo / 2 + hi / 2;
 
 2206        else if (t.tv_sec > hi)
 
 2208        if ((*funcp)(&t, offset, &mytm, sp) == 
NULL) {
 
 2214            dir = (t.tv_sec > 0) ? 1 : -1;
 
 2215        } 
else  dir = 
tmcomp(&mytm, &yourtm);
 
 2217            if (t.tv_sec == lo) {
 
 2222            } 
else if (t.tv_sec == hi) {
 
 2246        for (i = sp->
typecnt - 1; i >= 0; --i) {
 
 2249            for (j = sp->
typecnt - 1; j >= 0; --j) {
 
 2254                if ((*funcp)(&newt, offset, &mytm, sp) == 
NULL)
 
 2256                if (
tmcomp(&mytm, &yourtm) != 0)
 
 2258                if (mytm.tm_isdst != yourtm.
tm_isdst)
 
 2270    newt.tv_sec = t.tv_sec + saved_seconds;
 
 2271    if ((newt.tv_sec < t.tv_sec) != (saved_seconds < 0))
 
 2273    t.tv_sec = newt.tv_sec;
 
 2274    if ((*funcp)(&t, offset, tmp, sp))
 
 
 2279static struct timeval 
time2(struct 
ast_tm *tmp, 
struct ast_tm * (* 
const funcp) (
const struct timeval *, 
long, 
struct ast_tm*, 
const struct state *sp), 
const long offset, 
int *okayp, 
const struct state *sp)
 
 2289    return *okayp ? t : 
time2sub(tmp, funcp, offset, okayp, 
TRUE, sp);
 
 
 2292static struct timeval 
time1(struct 
ast_tm *tmp, 
struct ast_tm * (* 
const funcp) (
const struct timeval *, 
long, 
struct ast_tm *, 
const struct state *), 
const long offset, 
const struct state *sp)
 
 2296    int         sameind, otherind;
 
 2303    if (tmp->tm_isdst > 1)
 
 2305    t = 
time2(tmp, funcp, offset, &okay, sp);
 
 2312    if (tmp->tm_isdst < 0)
 
 2316    if (okay || tmp->tm_isdst < 0)
 
 2327    for (i = 0; i < sp->
typecnt; ++i)
 
 2330    for (i = sp->
timecnt - 1; i >= 0; --i)
 
 2331        if (!seen[sp->
types[i]]) {
 
 2333            types[nseen++] = sp->
types[i];
 
 2335    for (sameind = 0; sameind < nseen; ++sameind) {
 
 2336        samei = types[sameind];
 
 2339        for (otherind = 0; otherind < nseen; ++otherind) {
 
 2340            otheri = types[otherind];
 
 2345            tmp->tm_isdst = !tmp->tm_isdst;
 
 2346            t = 
time2(tmp, funcp, offset, &okay, sp);
 
 2351            tmp->tm_isdst = !tmp->tm_isdst;
 
 
 2359    const struct state *sp;
 
 
 2365#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) 
 2381        if (strcmp(
name, cur->
name) == 0) {
 
 
 2391    if (prevlocale == LC_GLOBAL_LOCALE) {
 
 2402            for (x = 0; x < 10000; x++) {
 
 2404                snprintf(
name, 
sizeof(
name), 
"%04d", x);
 
 2407                        cur->
locale = prevlocale;
 
 
 2423    locale_t prevlocale = LC_GLOBAL_LOCALE;
 
 2431        prevlocale = uselocale(cur->
locale);
 
 2439            prevlocale = uselocale(cur->
locale);
 
 
 2454    size_t fmtlen = strlen(tmp) + 1;
 
 2455    char *format = 
ast_calloc(1, fmtlen), *fptr = format, *newfmt;
 
 2456    int decimals = -1, i, res;
 
 2458    const char *prevlocale;
 
 2464    for (; *tmp; tmp++) {
 
 2473                if (tmp[2] != 
'q') {
 
 2476                decimals = tmp[1] - 
'0';
 
 2480                if (decimals == -1) {
 
 2490                fptr = fptr - format + newfmt;
 
 2495                for (i = 6, fraction = tm->
tm_usec; i > decimals; i--) {
 
 2498                fptr += sprintf(fptr, 
"%0*ld", decimals, fraction);
 
 2508defcase:    *fptr++ = *tmp;
 
 2516    res = (int)strftime(
buf, 
len, format, (
struct tm *)tm);
 
 
 2531    struct tm tm2 = { 0, };
 
 2533    const char *prevlocale;
 
 2536    res = strptime(s, format, &tm2);
 
 2542    memcpy(tm, &tm2, 
sizeof(tm2));
 
 
Prototypes for public functions only of internal interest,.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_realloc(p, len)
A wrapper for realloc()
#define ast_calloc(num, len)
A wrapper for calloc()
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
A set of macros to manage forward-linked lists.
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_LOCK(head)
Locks a list.
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
#define AST_LIST_TRYLOCK(head)
Locks a list, without blocking if the list is locked.
static const char * getqzname(const char *strp, const int delim)
Given a pointer into an extended time zone string, scan until the ending delimiter of the zone name i...
static int leaps_thru_end_of(const int y)
Return the number of leap years through the end of the given year where, to make the math easy,...
static void common_startup(void)
static const char * getsecs(const char *strp, long *const secsp)
Given a pointer into a time zone string, extract a number of seconds, in hh[:mm[:ss]] form,...
static int tzload(const char *name, struct state *const sp, const int doextend)
static const struct timeval WRONG
static int differ_by_repeat(const time_t t1, const time_t t0)
static const struct state * ast_tzset(const char *zone)
static struct state * sstate_alloc(void)
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *tmp, const char *zone)
Timezone-independent version of localtime_r(3).
static ast_cond_t initialization
static void * inotify_daemon(void *data)
static struct locale_entry * find_by_name(const char *name)
const char * ast_setlocale(const char *locale)
Set the thread-local representation of the current locale.
static const char * getnum(const char *strp, int *nump, const int min, const int max)
Given a pointer into a time zone string, extract a number from that string. Check that the number is ...
#define SP_STACK_CHECK(sp)
static void sstate_free(struct state *p)
static int long_increment_overflow(long *number, int delta)
int ast_strftime_locale(char *buf, size_t len, const char *tmp, const struct ast_tm *tm, const char *locale)
static void add_notify(struct state *sp, const char *path)
void ast_localtime_wakeup_monitor(struct ast_test *info)
static int increment_overflow(int *number, int delta)
Simplified normalize logic courtesy Paul Eggert.
struct timeval ast_mktime(struct ast_tm *tmp, const char *zone)
Timezone-independent version of mktime(3).
static struct ast_tm * timesub(const struct timeval *timep, const long offset, const struct state *sp, struct ast_tm *tmp)
static int long_normalize_overflow(long *tensptr, int *unitsptr, const int base)
static const char * store_by_locale(locale_t prevlocale)
int ast_strftime(char *buf, size_t len, const char *tmp, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
void clean_time_zones(void)
static int tzparse(const char *name, struct state *sp, const int lastditch)
static ast_mutex_t initialization_lock
static struct locale_entry * find_by_locale(locale_t locale)
static int normalize_overflow(int *tensptr, int *unitsptr, const int base)
static const char * getrule(const char *strp, struct rule *rulep)
Given a pointer into a time zone string, extract a rule in the form date[/time]. See POSIX section 8 ...
static int gmtload(struct state *sp)
char * ast_strptime_locale(const char *s, const char *format, struct ast_tm *tm, const char *locale)
void ast_get_dst_info(const time_t *const timep, int *dst_enabled, time_t *dst_start, time_t *dst_end, int *gmt_off, const char *const zone)
static long detzcode(const char *const codep)
static pthread_t inotify_thread
static time_t transtime(const time_t janfirst, const int year, const struct rule *rulep, const long offset)
Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the year, a rule,...
static struct timeval time2(struct ast_tm *tmp, struct ast_tm *(*const funcp)(const struct timeval *, long, struct ast_tm *, const struct state *sp), const long offset, int *okayp, const struct state *sp)
static const char * getzname(const char *strp)
Given a pointer into a time zone string, scan until a character that is not a valid character in a zo...
static struct ast_tm * localsub(const struct timeval *timep, const long offset, struct ast_tm *tmp, const struct state *sp)
#define MONTH_NTH_DAY_OF_WEEK
static struct ast_tm * gmtsub(const struct timeval *timep, const long offset, struct ast_tm *tmp)
static const char * getoffset(const char *strp, long *offsetp)
Given a pointer into a time zone string, extract an offset, in [+-]hh[:mm[:ss]] form,...
static int tmcomp(const struct ast_tm *atmp, const struct ast_tm *btmp)
#define SP_STACK_INIT(sp)
static const int year_lengths[2]
static const int mon_lengths[2][MONSPERYEAR]
static struct timeval time2sub(struct ast_tm *tmp, struct ast_tm *(*const funcp)(const struct timeval *, long, struct ast_tm *, const struct state *), const long offset, int *okayp, const int do_norm_secs, const struct state *sp)
static struct timeval time1(struct ast_tm *tmp, struct ast_tm *(*const funcp)(const struct timeval *, long, struct ast_tm *, const struct state *), const long offset, const struct state *sp)
char * ast_strptime(const char *s, const char *format, struct ast_tm *tm)
Special version of strptime(3) which places the answer in the common structure ast_tm....
static time_t detzcode64(const char *const codep)
Custom localtime functions for multiple timezones.
Asterisk locking-related definitions:
#define ast_cond_wait(cond, mutex)
#define AST_PTHREADT_NULL
#define ast_cond_init(cond, attr)
#define ast_cond_timedwait(cond, mutex, time)
#define ast_mutex_init(pmutex)
#define ast_mutex_unlock(a)
#define ast_cond_broadcast(cond)
pthread_cond_t ast_cond_t
#define ast_mutex_lock(a)
#define ast_cond_signal(cond)
#define TYPE_INTEGRAL(type)
you may need to compile with DHAVE_STDINT_H typedef long int_fast64_t
#define SECSPERREPEAT_BITS
#define TYPE_SIGNED(type)
String manipulation functions.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Structure for mutex and tracking information.
struct locale_entry::@434 list
char name[TZ_STRLEN_MAX+1]
struct lsinfo lsis[TZ_MAX_LEAPS]
struct ttinfo ttis[TZ_MAX_TYPES]
unsigned char types[TZ_MAX_TIMES]
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, sizeof gmt),(2 *(MY_TZNAME_MAX+1)))]
#define ast_test_status_update(a, b, c...)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define ast_pthread_create_background(a, b, c, d)