<p>Philip Prindeville has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18205">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">time: add support for time64 libcs<br><br>libcs are implementing changes to fix the year 2038 issue on 32 bit<br>platforms (see [1]). musl libc already went ahead and implemented it,<br>starting with musl-1.2.0 (see [2]).<br><br>Running asterisk on a 32 bit box with a time64 libc causes some<br>problems. For instance registering to pjsip doesn't work. The<br>registration completes fine, but the AOR disappears immediately, making<br>the registered clients unreachable.<br><br>Currently time_t is always expected to be (long). This commit changes<br>this and instead always uses "lld" when dealing with time_t and casting<br>the values to be formatted to (long long). The aim is to be future proof<br>and portable. This was suggested on the musl mailing list ([3]).<br><br>When it comes to scanning, no assumptions can be made regarding the type<br>of the time_t destination. It is unknown as it is depending on the<br>platform. So we "read into a known-size integer (either int or long<br>long) and then assign the value to a time_t as a second step" (quote<br>from [4]).<br><br>These changes get rid of the new warnings that appeared with musl-1.2.0 and<br>make the pjsip registration work again. Below an example warning:<br><br>In file included from ../include/asterisk.h:23,<br>                 from res_pjsip/location.c:19:<br>res_pjsip/location.c: In function 'expiration_struct2str':<br>../include/asterisk/astmm.h:270:72: warning: format '%ld' expects argument of type 'long int', but argument 6 has type 'time_t' {aka 'long long int'} [-Wformat=]<br>  270 |         __ast_asprintf(__FILE__, __LINE__, __PRETTY_FUNCTION__, (ret), (fmt), __VA_ARGS__)<br>      |                                                                        ^~~~~<br>res_pjsip/location.c:492:17: note: in expansion of macro 'ast_asprintf'<br>  492 |         return (ast_asprintf(buf, "%ld", contact->expiration_time.tv_sec) < 0) ? -1 : 0;<br>      |                 ^~~~~~~~~~~~<br><br>[1] https://sourceware.org/glibc/wiki/Y2038ProofnessDesign<br>[2] https://musl.libc.org/time64.html<br>[3] https://www.openwall.com/lists/musl/2021/10/27/3<br>[4] https://stackoverflow.com/questions/4171478/how-to-read-data-into-a-time-t-variable-using-scanf<br><br>ASTERISK-29674 #close<br><br>Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net><br>Change-Id: Ic8d61b26033f5c486b917e738c9608b0923a844e<br>---<br>M include/asterisk/time.h<br>M res/res_calendar_caldav.c<br>M res/res_calendar_icalendar.c<br>M res/res_http_media_cache.c<br>M res/res_odbc.c<br>M res/res_pjsip/location.c<br>M res/res_pjsip/pjsip_options.c<br>M res/res_pjsip_history.c<br>M res/res_pjsip_pubsub.c<br>M res/res_pjsip_registrar.c<br>M res/res_stir_shaken.c<br>11 files changed, 34 insertions(+), 19 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/05/18205/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/time.h b/include/asterisk/time.h</span><br><span>index e2ab513..58b5016 100644</span><br><span>--- a/include/asterisk/time.h</span><br><span>+++ b/include/asterisk/time.h</span><br><span>@@ -29,6 +29,9 @@</span><br><span> #include <sys/time.h></span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define TIME_T_FMT "lld"</span><br><span style="color: hsl(120, 100%, 40%);">+#define TIME_T_CAST(x) ((long long)(x))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #ifdef HAVE_UNISTD_H</span><br><span> #include <unistd.h></span><br><span> #endif</span><br><span>diff --git a/res/res_calendar_caldav.c b/res/res_calendar_caldav.c</span><br><span>index 9bdde0e..e109641 100644</span><br><span>--- a/res/res_calendar_caldav.c</span><br><span>+++ b/res/res_calendar_caldav.c</span><br><span>@@ -405,7 +405,7 @@</span><br><span>                    ast_string_field_set(event, uid, event->summary);</span><br><span>                 } else {</span><br><span>                     char tmp[100];</span><br><span style="color: hsl(0, 100%, 40%);">-                  snprintf(tmp, sizeof(tmp), "%ld", event->start);</span><br><span style="color: hsl(120, 100%, 40%);">+                 snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(event->start));</span><br><span>                  ast_string_field_set(event, uid, tmp);</span><br><span>               }</span><br><span>    }</span><br><span>diff --git a/res/res_calendar_icalendar.c b/res/res_calendar_icalendar.c</span><br><span>index 999cf0e..756387d 100644</span><br><span>--- a/res/res_calendar_icalendar.c</span><br><span>+++ b/res/res_calendar_icalendar.c</span><br><span>@@ -246,7 +246,7 @@</span><br><span>                         ast_string_field_set(event, uid, event->summary);</span><br><span>                 } else {</span><br><span>                     char tmp[100];</span><br><span style="color: hsl(0, 100%, 40%);">-                  snprintf(tmp, sizeof(tmp), "%ld", event->start);</span><br><span style="color: hsl(120, 100%, 40%);">+                 snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(event->start));</span><br><span>                  ast_string_field_set(event, uid, tmp);</span><br><span>               }</span><br><span>    }</span><br><span>diff --git a/res/res_http_media_cache.c b/res/res_http_media_cache.c</span><br><span>index 2bace1e..ae3efcd 100644</span><br><span>--- a/res/res_http_media_cache.c</span><br><span>+++ b/res/res_http_media_cache.c</span><br><span>@@ -150,7 +150,7 @@</span><br><span>         }</span><br><span> </span><br><span>        /* Use 'now' if we didn't get an expiration time */</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(time_buf, sizeof(time_buf), "%30lu", actual_expires.tv_sec);</span><br><span style="color: hsl(120, 100%, 40%);">+       snprintf(time_buf, sizeof(time_buf), "%30" TIME_T_FMT, TIME_T_CAST(actual_expires.tv_sec));</span><br><span> </span><br><span>    ast_bucket_file_metadata_set(bucket_file, "__actual_expires", time_buf);</span><br><span> }</span><br><span>@@ -299,15 +299,18 @@</span><br><span>              ao2_cleanup);</span><br><span>        struct timeval current_time = ast_tvnow();</span><br><span>   struct timeval expires = { .tv_sec = 0, .tv_usec = 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+       long long llv;</span><br><span> </span><br><span>   if (!metadata) {</span><br><span>             return 1;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (sscanf(metadata->value, "%lu", &expires.tv_sec) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+  if (sscanf(metadata->value, "%" TIME_T_FMT, &llv) != 1) {</span><br><span>           return 1;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ expires.tv_sec = llv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      return ast_tvcmp(current_time, expires) == -1 ? 0 : 1;</span><br><span> }</span><br><span> </span><br><span>diff --git a/res/res_odbc.c b/res/res_odbc.c</span><br><span>index 63fdf37..6353556 100644</span><br><span>--- a/res/res_odbc.c</span><br><span>+++ b/res/res_odbc.c</span><br><span>@@ -1029,7 +1029,7 @@</span><br><span>         /* Dont connect while server is marked as unreachable via negative_connection_cache */</span><br><span>       negative_cache_expiration = obj->parent->last_negative_connect.tv_sec + obj->parent->negative_connection_cache.tv_sec;</span><br><span>   if (time(NULL) < negative_cache_expiration) {</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_log(LOG_WARNING, "Not connecting to %s. Negative connection cache for %ld seconds\n", obj->parent->name, negative_cache_expiration - time(NULL));</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_log(LOG_WARNING, "Not connecting to %s. Negative connection cache for %" TIME_T_FMT " seconds\n", obj->parent->name, TIME_T_CAST(negative_cache_expiration - time(NULL)));</span><br><span>             return ODBC_FAIL;</span><br><span>    }</span><br><span> </span><br><span>diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c</span><br><span>index bae8a2d..f381165 100644</span><br><span>--- a/res/res_pjsip/location.c</span><br><span>+++ b/res/res_pjsip/location.c</span><br><span>@@ -489,7 +489,7 @@</span><br><span> static int expiration_struct2str(const void *obj, const intptr_t *args, char **buf)</span><br><span> {</span><br><span>         const struct ast_sip_contact *contact = obj;</span><br><span style="color: hsl(0, 100%, 40%);">-    return (ast_asprintf(buf, "%ld", contact->expiration_time.tv_sec) < 0) ? -1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      return (ast_asprintf(buf, "%" TIME_T_FMT, TIME_T_CAST(contact->expiration_time.tv_sec)) < 0) ? -1 : 0;</span><br><span> }</span><br><span> </span><br><span> static int permanent_uri_sort_fn(const void *obj_left, const void *obj_right, int flags)</span><br><span>diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c</span><br><span>index e1f048e..5f60a54 100644</span><br><span>--- a/res/res_pjsip/pjsip_options.c</span><br><span>+++ b/res/res_pjsip/pjsip_options.c</span><br><span>@@ -2733,7 +2733,7 @@</span><br><span>         ast_str_append(&buf, 0, "AOR: %s\r\n", wrapper->aor_id);</span><br><span>    ast_str_append(&buf, 0, "URI: %s\r\n", contact->uri);</span><br><span>       ast_str_append(&buf, 0, "UserAgent: %s\r\n", contact->user_agent);</span><br><span style="color: hsl(0, 100%, 40%);">-     ast_str_append(&buf, 0, "RegExpire: %ld\r\n", contact->expiration_time.tv_sec);</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_str_append(&buf, 0, "RegExpire: %" TIME_T_FMT "\r\n", TIME_T_CAST(contact->expiration_time.tv_sec));</span><br><span>  if (!ast_strlen_zero(contact->via_addr)) {</span><br><span>                ast_str_append(&buf, 0, "ViaAddress: %s", contact->via_addr);</span><br><span>               if (contact->via_port) {</span><br><span>diff --git a/res/res_pjsip_history.c b/res/res_pjsip_history.c</span><br><span>index de1063b..9f01328 100644</span><br><span>--- a/res/res_pjsip_history.c</span><br><span>+++ b/res/res_pjsip_history.c</span><br><span>@@ -198,12 +198,15 @@</span><br><span>         /* Used for timeval */</span><br><span>       {</span><br><span>            struct timeval right = { 0, };</span><br><span style="color: hsl(120, 100%, 40%);">+                long long llv;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-              if (sscanf(op_right->field, "%ld", &right.tv_sec) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (sscanf(op_right->field, "%" TIME_T_FMT, &llv) != 1) {</span><br><span>                   ast_log(LOG_WARNING, "Unable to extract field '%s': not a timestamp\n", op_right->field);</span><br><span>                       return -1;</span><br><span>           }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         right.tv_sec = llv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                return ast_tvcmp(*(struct timeval *)op_left, right) == 0;</span><br><span>    }</span><br><span>    case OPT_SOCKADDR_T:</span><br><span>@@ -269,12 +272,15 @@</span><br><span>         /* Used for timeval */</span><br><span>       {</span><br><span>            struct timeval right = { 0, };</span><br><span style="color: hsl(120, 100%, 40%);">+                long long llv;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-              if (sscanf(op_right->field, "%ld", &right.tv_sec) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (sscanf(op_right->field, "%" TIME_T_FMT, &llv) != 1) {</span><br><span>                   ast_log(LOG_WARNING, "Unable to extract field '%s': not a timestamp\n", op_right->field);</span><br><span>                       return -1;</span><br><span>           }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         right.tv_sec = llv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                return ast_tvcmp(*(struct timeval *)op_left, right) == -1;</span><br><span>   }</span><br><span>    default:</span><br><span>@@ -318,12 +324,15 @@</span><br><span>     /* Used for timeval */</span><br><span>       {</span><br><span>            struct timeval right = { 0, };</span><br><span style="color: hsl(120, 100%, 40%);">+                long long llv;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-              if (sscanf(op_right->field, "%ld", &right.tv_sec) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (sscanf(op_right->field, "%" TIME_T_FMT, &llv) != 1) {</span><br><span>                   ast_log(LOG_WARNING, "Unable to extract field '%s': not a timestamp\n", op_right->field);</span><br><span>                       return -1;</span><br><span>           }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         right.tv_sec = llv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                return ast_tvcmp(*(struct timeval *)op_left, right) == 1;</span><br><span>    }</span><br><span>    default:</span><br><span>@@ -668,18 +677,18 @@</span><br><span>             char uri[128];</span><br><span> </span><br><span>           pjsip_uri_print(PJSIP_URI_IN_REQ_URI, entry->msg->line.req.uri, uri, sizeof(uri));</span><br><span style="color: hsl(0, 100%, 40%);">-                snprintf(line, len, "%-5.5d %-10.10ld %-5.5s %-24.24s %.*s %s SIP/2.0",</span><br><span style="color: hsl(120, 100%, 40%);">+             snprintf(line, len, "%-5.5d %-10.10" TIME_T_FMT " %-5.5s %-24.24s %.*s %s SIP/2.0",</span><br><span>                      entry->number,</span><br><span style="color: hsl(0, 100%, 40%);">-                       entry->timestamp.tv_sec,</span><br><span style="color: hsl(120, 100%, 40%);">+                   TIME_T_CAST(entry->timestamp.tv_sec),</span><br><span>                     entry->transmitted ? "* ==>" : "* <==",</span><br><span>                         addr,</span><br><span>                        (int)pj_strlen(&entry->msg->line.req.method.name),</span><br><span>                         pj_strbuf(&entry->msg->line.req.method.name),</span><br><span>                      uri);</span><br><span>        } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                snprintf(line, len, "%-5.5d %-10.10ld %-5.5s %-24.24s SIP/2.0 %u %.*s",</span><br><span style="color: hsl(120, 100%, 40%);">+             snprintf(line, len, "%-5.5d %-10.10" TIME_T_FMT " %-5.5s %-24.24s SIP/2.0 %u %.*s",</span><br><span>                      entry->number,</span><br><span style="color: hsl(0, 100%, 40%);">-                       entry->timestamp.tv_sec,</span><br><span style="color: hsl(120, 100%, 40%);">+                   TIME_T_CAST(entry->timestamp.tv_sec),</span><br><span>                     entry->transmitted ? "* ==>" : "* <==",</span><br><span>                         addr,</span><br><span>                        entry->msg->line.status.code,</span><br><span>@@ -1169,11 +1178,11 @@</span><br><span>                pj_sockaddr_print(&entry->src, addr, sizeof(addr), 3);</span><br><span>        }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ast_cli(a->fd, "<--- History Entry %d %s %s at %-10.10ld --->\n",</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_cli(a->fd, "<--- History Entry %d %s %s at %-10.10" TIME_T_FMT " --->\n",</span><br><span>           entry->number,</span><br><span>            entry->transmitted ? "Sent to" : "Received from",</span><br><span>             addr,</span><br><span style="color: hsl(0, 100%, 40%);">-           entry->timestamp.tv_sec);</span><br><span style="color: hsl(120, 100%, 40%);">+          TIME_T_CAST(entry->timestamp.tv_sec));</span><br><span>    ast_cli(a->fd, "%s\n", buf);</span><br><span> </span><br><span>        ast_free(buf);</span><br><span>diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c</span><br><span>index dae3fef..1d53960 100644</span><br><span>--- a/res/res_pjsip_pubsub.c</span><br><span>+++ b/res/res_pjsip_pubsub.c</span><br><span>@@ -4771,7 +4771,7 @@</span><br><span> static int persistence_expires_struct2str(const void *obj, const intptr_t *args, char **buf)</span><br><span> {</span><br><span>     const struct subscription_persistence *persistence = obj;</span><br><span style="color: hsl(0, 100%, 40%);">-       return (ast_asprintf(buf, "%ld", persistence->expires.tv_sec) < 0) ? -1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  return (ast_asprintf(buf, "%" TIME_T_FMT, TIME_T_CAST(persistence->expires.tv_sec)) < 0) ? -1 : 0;</span><br><span> }</span><br><span> </span><br><span> #define RESOURCE_LIST_INIT_SIZE 4</span><br><span>diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c</span><br><span>index 9c999c1..c12f244 100644</span><br><span>--- a/res/res_pjsip_registrar.c</span><br><span>+++ b/res/res_pjsip_registrar.c</span><br><span>@@ -1370,7 +1370,7 @@</span><br><span>    while (check_interval) {</span><br><span>             sleep(check_interval);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-              sprintf(time, "%ld", ast_tvnow().tv_sec);</span><br><span style="color: hsl(120, 100%, 40%);">+           sprintf(time, "%" TIME_T_FMT, TIME_T_CAST(ast_tvnow().tv_sec));</span><br><span>            var = ast_variable_new("expiration_time <=", time, "");</span><br><span> </span><br><span>           ast_debug(4, "Woke up at %s  Interval: %d\n", time, check_interval);</span><br><span>diff --git a/res/res_stir_shaken.c b/res/res_stir_shaken.c</span><br><span>index 373a1a1..12c38b6 100644</span><br><span>--- a/res/res_stir_shaken.c</span><br><span>+++ b/res/res_stir_shaken.c</span><br><span>@@ -389,7 +389,7 @@</span><br><span>                actual_expires.tv_sec += EXPIRATION_BUFFER;</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   snprintf(time_buf, sizeof(time_buf), "%30lu", actual_expires.tv_sec);</span><br><span style="color: hsl(120, 100%, 40%);">+       snprintf(time_buf, sizeof(time_buf), "%30" TIME_T_FMT, TIME_T_CAST(actual_expires.tv_sec));</span><br><span> </span><br><span>    ast_db_put(hash, "expiration", time_buf);</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18205">change 18205</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/18205"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 19 </div>
<div style="display:none"> Gerrit-Change-Id: Ic8d61b26033f5c486b917e738c9608b0923a844e </div>
<div style="display:none"> Gerrit-Change-Number: 18205 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Philip Prindeville <philipp@redfish-solutions.com> </div>
<div style="display:none"> Gerrit-CC: Sebastian Kemper <sebastian_ml@gmx.net> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>