1 From 472086370630e1547cf9b497295b4a53d811e872 Mon Sep 17 00:00:00 2001
2 From: Sebastian Kemper <sebastian_ml@gmx.net>
3 Date: Sun, 17 Oct 2021 20:17:57 +0200
4 Subject: [PATCH] time: add support for time64 libc
6 libcs are implementing changes to fix the year 2038 issue on 32 bit
7 platforms (see [1]). musl libc already went ahead and implemented it,
8 starting with musl-1.2.0 (see [2]).
10 Running asterisk on a 32 bit box with a time64 libc causes some
11 problems. For instance registering to pjsip doesn't work. The
12 registration completes fine, but the AOR disappears immediately, making
13 the registered clients unreachable.
15 This commit adds two new definitions to include/asterisk/time.h:
20 If __USE_TIME_BITS64 is defined (by a time64 libc, see [1]), they're set
21 to the proper conversions for type int64_t, PRId64 and PRIu64
22 respectively. If __USE_TIME_BITS64 is not defined, the status quo
23 remains unchanged ("%ld" and "%lu" are used).
25 The new definitions are used in the different parts of asterisk, where
28 These changes get rid of the new warnings that appeared with musl-1.2.0 and
29 make the pjsip registration work again. Below an example warning:
31 In file included from ../include/asterisk.h:23,
32 from res_pjsip/location.c:19:
33 res_pjsip/location.c: In function 'expiration_struct2str':
34 ../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=]
35 270 | __ast_asprintf(__FILE__, __LINE__, __PRETTY_FUNCTION__, (ret), (fmt), __VA_ARGS__)
37 res_pjsip/location.c:492:17: note: in expansion of macro 'ast_asprintf'
38 492 | return (ast_asprintf(buf, "%ld", contact->expiration_time.tv_sec) < 0) ? -1 : 0;
41 [1] https://sourceware.org/glibc/wiki/Y2038ProofnessDesign
42 [2] https://musl.libc.org/time64.html
46 Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
47 Change-Id: Ic8d61b26033f5c486b917e738c9608b0923a844e
49 include/asterisk/time.h | 16 ++++++++++++++++
50 res/res_calendar_caldav.c | 2 +-
51 res/res_calendar_icalendar.c | 2 +-
52 res/res_http_media_cache.c | 4 ++--
54 res/res_pjsip/location.c | 2 +-
55 res/res_pjsip/pjsip_options.c | 2 +-
56 res/res_pjsip_history.c | 12 ++++++------
57 res/res_pjsip_pubsub.c | 2 +-
58 res/res_pjsip_registrar.c | 2 +-
59 res/res_stir_shaken.c | 2 +-
60 11 files changed, 32 insertions(+), 16 deletions(-)
62 --- a/include/asterisk/time.h
63 +++ b/include/asterisk/time.h
68 +#ifndef TIME_T_INT_FMT
69 +#ifdef __USE_TIME_BITS64
70 +#define TIME_T_INT_FMT PRId64
72 +#define TIME_T_INT_FMT "ld"
76 +#ifndef TIME_T_UINT_FMT
77 +#ifdef __USE_TIME_BITS64
78 +#define TIME_T_UINT_FMT PRIu64
80 +#define TIME_T_UINT_FMT "lu"
87 --- a/res/res_calendar_caldav.c
88 +++ b/res/res_calendar_caldav.c
89 @@ -405,7 +405,7 @@ static void caldav_add_event(icalcompone
90 ast_string_field_set(event, uid, event->summary);
93 - snprintf(tmp, sizeof(tmp), "%ld", event->start);
94 + snprintf(tmp, sizeof(tmp), "%" TIME_T_INT_FMT, event->start);
95 ast_string_field_set(event, uid, tmp);
98 --- a/res/res_calendar_icalendar.c
99 +++ b/res/res_calendar_icalendar.c
100 @@ -246,7 +246,7 @@ static void icalendar_add_event(icalcomp
101 ast_string_field_set(event, uid, event->summary);
104 - snprintf(tmp, sizeof(tmp), "%ld", event->start);
105 + snprintf(tmp, sizeof(tmp), "%" TIME_T_INT_FMT, event->start);
106 ast_string_field_set(event, uid, tmp);
109 --- a/res/res_http_media_cache.c
110 +++ b/res/res_http_media_cache.c
111 @@ -150,7 +150,7 @@ static void bucket_file_set_expiration(s
114 /* Use 'now' if we didn't get an expiration time */
115 - snprintf(time_buf, sizeof(time_buf), "%30lu", actual_expires.tv_sec);
116 + snprintf(time_buf, sizeof(time_buf), "%30" TIME_T_UINT_FMT, actual_expires.tv_sec);
118 ast_bucket_file_metadata_set(bucket_file, "__actual_expires", time_buf);
120 @@ -314,7 +314,7 @@ static int bucket_file_expired(struct as
124 - if (sscanf(metadata->value, "%lu", &expires.tv_sec) != 1) {
125 + if (sscanf(metadata->value, "%" TIME_T_UINT_FMT, &expires.tv_sec) != 1) {
131 @@ -1029,7 +1029,7 @@ static odbc_status odbc_obj_connect(stru
132 /* Dont connect while server is marked as unreachable via negative_connection_cache */
133 negative_cache_expiration = obj->parent->last_negative_connect.tv_sec + obj->parent->negative_connection_cache.tv_sec;
134 if (time(NULL) < negative_cache_expiration) {
135 - ast_log(LOG_WARNING, "Not connecting to %s. Negative connection cache for %ld seconds\n", obj->parent->name, negative_cache_expiration - time(NULL));
136 + ast_log(LOG_WARNING, "Not connecting to %s. Negative connection cache for %" TIME_T_INT_FMT " seconds\n", obj->parent->name, negative_cache_expiration - time(NULL));
140 --- a/res/res_pjsip/location.c
141 +++ b/res/res_pjsip/location.c
142 @@ -489,7 +489,7 @@ static int expiration_str2struct(const s
143 static int expiration_struct2str(const void *obj, const intptr_t *args, char **buf)
145 const struct ast_sip_contact *contact = obj;
146 - return (ast_asprintf(buf, "%ld", contact->expiration_time.tv_sec) < 0) ? -1 : 0;
147 + return (ast_asprintf(buf, "%" TIME_T_INT_FMT, contact->expiration_time.tv_sec) < 0) ? -1 : 0;
150 static int permanent_uri_sort_fn(const void *obj_left, const void *obj_right, int flags)
151 --- a/res/res_pjsip/pjsip_options.c
152 +++ b/res/res_pjsip/pjsip_options.c
153 @@ -2733,7 +2733,7 @@ int ast_sip_format_contact_ami(void *obj
154 ast_str_append(&buf, 0, "AOR: %s\r\n", wrapper->aor_id);
155 ast_str_append(&buf, 0, "URI: %s\r\n", contact->uri);
156 ast_str_append(&buf, 0, "UserAgent: %s\r\n", contact->user_agent);
157 - ast_str_append(&buf, 0, "RegExpire: %ld\r\n", contact->expiration_time.tv_sec);
158 + ast_str_append(&buf, 0, "RegExpire: %" TIME_T_INT_FMT "\r\n", contact->expiration_time.tv_sec);
159 if (!ast_strlen_zero(contact->via_addr)) {
160 ast_str_append(&buf, 0, "ViaAddress: %s", contact->via_addr);
161 if (contact->via_port) {
162 --- a/res/res_pjsip_history.c
163 +++ b/res/res_pjsip_history.c
164 @@ -199,7 +199,7 @@ static int evaluate_equal(struct operato
166 struct timeval right = { 0, };
168 - if (sscanf(op_right->field, "%ld", &right.tv_sec) != 1) {
169 + if (sscanf(op_right->field, "%" TIME_T_INT_FMT, &right.tv_sec) != 1) {
170 ast_log(LOG_WARNING, "Unable to extract field '%s': not a timestamp\n", op_right->field);
173 @@ -270,7 +270,7 @@ static int evaluate_less_than(struct ope
175 struct timeval right = { 0, };
177 - if (sscanf(op_right->field, "%ld", &right.tv_sec) != 1) {
178 + if (sscanf(op_right->field, "%" TIME_T_INT_FMT, &right.tv_sec) != 1) {
179 ast_log(LOG_WARNING, "Unable to extract field '%s': not a timestamp\n", op_right->field);
182 @@ -319,7 +319,7 @@ static int evaluate_greater_than(struct
184 struct timeval right = { 0, };
186 - if (sscanf(op_right->field, "%ld", &right.tv_sec) != 1) {
187 + if (sscanf(op_right->field, "%" TIME_T_INT_FMT, &right.tv_sec) != 1) {
188 ast_log(LOG_WARNING, "Unable to extract field '%s': not a timestamp\n", op_right->field);
191 @@ -668,7 +668,7 @@ static void sprint_list_entry(struct pjs
194 pjsip_uri_print(PJSIP_URI_IN_REQ_URI, entry->msg->line.req.uri, uri, sizeof(uri));
195 - snprintf(line, len, "%-5.5d %-10.10ld %-5.5s %-24.24s %.*s %s SIP/2.0",
196 + snprintf(line, len, "%-5.5d %-10.10" TIME_T_INT_FMT " %-5.5s %-24.24s %.*s %s SIP/2.0",
198 entry->timestamp.tv_sec,
199 entry->transmitted ? "* ==>" : "* <==",
200 @@ -677,7 +677,7 @@ static void sprint_list_entry(struct pjs
201 pj_strbuf(&entry->msg->line.req.method.name),
204 - snprintf(line, len, "%-5.5d %-10.10ld %-5.5s %-24.24s SIP/2.0 %u %.*s",
205 + snprintf(line, len, "%-5.5d %-10.10" TIME_T_INT_FMT " %-5.5s %-24.24s SIP/2.0 %u %.*s",
207 entry->timestamp.tv_sec,
208 entry->transmitted ? "* ==>" : "* <==",
209 @@ -1169,7 +1169,7 @@ static void display_single_entry(struct
210 pj_sockaddr_print(&entry->src, addr, sizeof(addr), 3);
213 - ast_cli(a->fd, "<--- History Entry %d %s %s at %-10.10ld --->\n",
214 + ast_cli(a->fd, "<--- History Entry %d %s %s at %-10.10" TIME_T_INT_FMT " --->\n",
216 entry->transmitted ? "Sent to" : "Received from",
218 --- a/res/res_pjsip_pubsub.c
219 +++ b/res/res_pjsip_pubsub.c
220 @@ -4872,7 +4872,7 @@ static int persistence_expires_str2struc
221 static int persistence_expires_struct2str(const void *obj, const intptr_t *args, char **buf)
223 const struct subscription_persistence *persistence = obj;
224 - return (ast_asprintf(buf, "%ld", persistence->expires.tv_sec) < 0) ? -1 : 0;
225 + return (ast_asprintf(buf, "%" TIME_T_INT_FMT, persistence->expires.tv_sec) < 0) ? -1 : 0;
228 #define RESOURCE_LIST_INIT_SIZE 4
229 --- a/res/res_pjsip_registrar.c
230 +++ b/res/res_pjsip_registrar.c
231 @@ -1370,7 +1370,7 @@ static void *check_expiration_thread(voi
232 while (check_interval) {
233 sleep(check_interval);
235 - sprintf(time, "%ld", ast_tvnow().tv_sec);
236 + sprintf(time, "%" TIME_T_INT_FMT, ast_tvnow().tv_sec);
237 var = ast_variable_new("expiration_time <=", time, "");
239 ast_debug(4, "Woke up at %s Interval: %d\n", time, check_interval);
240 --- a/res/res_stir_shaken.c
241 +++ b/res/res_stir_shaken.c
242 @@ -441,7 +441,7 @@ static void set_public_key_expiration(co
243 actual_expires.tv_sec += EXPIRATION_BUFFER;
246 - snprintf(time_buf, sizeof(time_buf), "%30lu", actual_expires.tv_sec);
247 + snprintf(time_buf, sizeof(time_buf), "%30" TIME_T_UINT_FMT, actual_expires.tv_sec);
249 ast_db_put(hash, "expiration", time_buf);