aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-12-14 15:59:07 +0100
committerChristian Grothoff <christian@grothoff.org>2021-12-14 15:59:12 +0100
commit99779b455ce3bf9c53dd411575766bf298a3a5f3 (patch)
tree12cd49f097fdd1947580b08ec10ca961f8c250b9
parent8c702327dae9e504e0f6e1678884d9327321f44a (diff)
downloadgnunet-99779b455ce3bf9c53dd411575766bf298a3a5f3.tar.gz
gnunet-99779b455ce3bf9c53dd411575766bf298a3a5f3.zip
introducing GNUNET_TIME_Timestamp
-rw-r--r--src/curl/curl.c196
-rw-r--r--src/include/gnunet_getopt_lib.h18
-rw-r--r--src/include/gnunet_json_lib.h38
-rw-r--r--src/include/gnunet_pq_lib.h53
-rw-r--r--src/include/gnunet_sq_lib.h10
-rw-r--r--src/include/gnunet_strings_lib.h19
-rw-r--r--src/include/gnunet_time_lib.h220
-rw-r--r--src/json/json_generator.c86
-rw-r--r--src/json/json_helper.c124
-rw-r--r--src/json/json_pack.c16
-rw-r--r--src/json/test_json.c70
-rw-r--r--src/pq/pq_query_helper.c107
-rw-r--r--src/pq/pq_result_helper.c142
-rw-r--r--src/util/Makefile.am2
-rw-r--r--src/util/getopt_helpers.c249
-rw-r--r--src/util/strings.c22
-rw-r--r--src/util/time.c218
17 files changed, 979 insertions, 611 deletions
diff --git a/src/curl/curl.c b/src/curl/curl.c
index 684610101..e45612e94 100644
--- a/src/curl/curl.c
+++ b/src/curl/curl.c
@@ -201,14 +201,6 @@ struct GNUNET_CURL_Context
201}; 201};
202 202
203 203
204/**
205 * Force use of the provided username and password
206 * for client authentication for all operations performed
207 * with @a ctx.
208 *
209 * @param ctx context to set authentication data for
210 * @param userpass string with "$USERNAME:$PASSWORD"
211 */
212void 204void
213GNUNET_CURL_set_userpass (struct GNUNET_CURL_Context *ctx, 205GNUNET_CURL_set_userpass (struct GNUNET_CURL_Context *ctx,
214 const char *userpass) 206 const char *userpass)
@@ -219,21 +211,6 @@ GNUNET_CURL_set_userpass (struct GNUNET_CURL_Context *ctx,
219} 211}
220 212
221 213
222/**
223 * Force use of the provided TLS client certificate
224 * for client authentication for all operations performed
225 * with @a ctx.
226 *
227 * Note that if the provided information is incorrect,
228 * the earliest operation that could fail is
229 * #GNUNET_CURL_job_add() or #GNUNET_CURL_job_add2()!
230 *
231 * @param ctx context to set authentication data for
232 * @param certtype type of the certificate
233 * @param certfile file with the certificate
234 * @param keyfile file with the private key
235 * @param keypass passphrase to decrypt @a keyfile (or NULL)
236 */
237void 214void
238GNUNET_CURL_set_tlscert (struct GNUNET_CURL_Context *ctx, 215GNUNET_CURL_set_tlscert (struct GNUNET_CURL_Context *ctx,
239 const char *certtype, 216 const char *certtype,
@@ -256,14 +233,6 @@ GNUNET_CURL_set_tlscert (struct GNUNET_CURL_Context *ctx,
256} 233}
257 234
258 235
259/**
260 * Initialise this library. This function should be called before using any of
261 * the following functions.
262 *
263 * @param cb function to call when rescheduling is required
264 * @param cb_cls closure for @a cb
265 * @return library context
266 */
267struct GNUNET_CURL_Context * 236struct GNUNET_CURL_Context *
268GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, 237GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb,
269 void *cb_cls) 238 void *cb_cls)
@@ -299,12 +268,6 @@ GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb,
299} 268}
300 269
301 270
302/**
303 * Enable sending the async scope ID as a header.
304 *
305 * @param ctx the context to enable this for
306 * @param header_name name of the header to send.
307 */
308void 271void
309GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx, 272GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx,
310 const char *header_name) 273 const char *header_name)
@@ -313,15 +276,6 @@ GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx,
313} 276}
314 277
315 278
316/**
317 * Return #GNUNET_YES if given a valid scope ID and
318 * #GNUNET_NO otherwise. See #setup_job_headers,
319 * logic related to
320 * #GNUNET_CURL_enable_async_scope_header() for the
321 * code that generates such a @a scope_id.
322 *
323 * @returns #GNUNET_YES iff given a valid scope ID
324 */
325int 279int
326GNUNET_CURL_is_valid_scope_id (const char *scope_id) 280GNUNET_CURL_is_valid_scope_id (const char *scope_id)
327{ 281{
@@ -447,7 +401,9 @@ setup_job (CURL *eh,
447 struct GNUNET_CURL_Job *job; 401 struct GNUNET_CURL_Job *job;
448 402
449 if (CURLE_OK != 403 if (CURLE_OK !=
450 curl_easy_setopt (eh, CURLOPT_HTTPHEADER, all_headers)) 404 curl_easy_setopt (eh,
405 CURLOPT_HTTPHEADER,
406 all_headers))
451 { 407 {
452 GNUNET_break (0); 408 GNUNET_break (0);
453 curl_slist_free_all (all_headers); 409 curl_slist_free_all (all_headers);
@@ -491,12 +447,6 @@ setup_job (CURL *eh,
491} 447}
492 448
493 449
494/**
495 * Add @a extra_headers to the HTTP headers for @a job.
496 *
497 * @param[in,out] job the job to modify
498 * @param extra_headers headers to append
499 */
500void 450void
501GNUNET_CURL_extend_headers (struct GNUNET_CURL_Job *job, 451GNUNET_CURL_extend_headers (struct GNUNET_CURL_Job *job,
502 const struct curl_slist *extra_headers) 452 const struct curl_slist *extra_headers)
@@ -515,21 +465,6 @@ GNUNET_CURL_extend_headers (struct GNUNET_CURL_Job *job,
515} 465}
516 466
517 467
518/**
519 * Schedule a CURL request to be executed and call the given @a jcc
520 * upon its completion. Note that the context will make use of the
521 * CURLOPT_PRIVATE facility of the CURL @a eh. Used to download
522 * resources that are NOT in JSON. The raw body will be returned.
523 *
524 * @param ctx context to execute the job in
525 * @param eh curl easy handle for the request, will
526 * be executed AND cleaned up
527 * @param job_headers extra headers to add for this request
528 * @param max_reply_size largest acceptable response body
529 * @param jcc callback to invoke upon completion
530 * @param jcc_cls closure for @a jcc
531 * @return NULL on error (in this case, @eh is still released!)
532 */
533struct GNUNET_CURL_Job * 468struct GNUNET_CURL_Job *
534GNUNET_CURL_job_add_raw (struct GNUNET_CURL_Context *ctx, 469GNUNET_CURL_job_add_raw (struct GNUNET_CURL_Context *ctx,
535 CURL *eh, 470 CURL *eh,
@@ -554,25 +489,6 @@ GNUNET_CURL_job_add_raw (struct GNUNET_CURL_Context *ctx,
554} 489}
555 490
556 491
557/**
558 * Schedule a CURL request to be executed and call the given @a jcc
559 * upon its completion. Note that the context will make use of the
560 * CURLOPT_PRIVATE facility of the CURL @a eh.
561 *
562 * This function modifies the CURL handle to add the
563 * "Content-Type: application/json" header if @a add_json is set.
564 *
565 * @param ctx context to execute the job in
566 * @param eh curl easy handle for the request, will be executed AND
567 * cleaned up. NOTE: the handle should _never_ have gotten
568 * any headers list, as that would then be overridden by
569 * @a jcc. Therefore, always pass custom headers as the
570 * @a job_headers parameter.
571 * @param job_headers extra headers to add for this request
572 * @param jcc callback to invoke upon completion
573 * @param jcc_cls closure for @a jcc
574 * @return NULL on error (in this case, @eh is still released!)
575 */
576struct GNUNET_CURL_Job * 492struct GNUNET_CURL_Job *
577GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx, 493GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx,
578 CURL *eh, 494 CURL *eh,
@@ -624,21 +540,6 @@ GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx,
624} 540}
625 541
626 542
627/**
628 * Schedule a CURL request to be executed and call the given @a jcc
629 * upon its completion. Note that the context will make use of the
630 * CURLOPT_PRIVATE facility of the CURL @a eh.
631 *
632 * This function modifies the CURL handle to add the
633 * "Content-Type: application/json" header.
634 *
635 * @param ctx context to execute the job in
636 * @param eh curl easy handle for the request, will
637 * be executed AND cleaned up
638 * @param jcc callback to invoke upon completion
639 * @param jcc_cls closure for @a jcc
640 * @return NULL on error (in this case, @eh is still released!)
641 */
642struct GNUNET_CURL_Job * 543struct GNUNET_CURL_Job *
643GNUNET_CURL_job_add_with_ct_json (struct GNUNET_CURL_Context *ctx, 544GNUNET_CURL_job_add_with_ct_json (struct GNUNET_CURL_Context *ctx,
644 CURL *eh, 545 CURL *eh,
@@ -661,18 +562,6 @@ GNUNET_CURL_job_add_with_ct_json (struct GNUNET_CURL_Context *ctx,
661} 562}
662 563
663 564
664/**
665 * Schedule a CURL request to be executed and call the given @a jcc
666 * upon its completion. Note that the context will make use of the
667 * CURLOPT_PRIVATE facility of the CURL @a eh.
668 *
669 * @param ctx context to execute the job in
670 * @param eh curl easy handle for the request, will
671 * be executed AND cleaned up
672 * @param jcc callback to invoke upon completion
673 * @param jcc_cls closure for @a jcc
674 * @return NULL on error (in this case, @eh is still released!)
675 */
676struct GNUNET_CURL_Job * 565struct GNUNET_CURL_Job *
677GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx, 566GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx,
678 CURL *eh, 567 CURL *eh,
@@ -687,12 +576,6 @@ GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx,
687} 576}
688 577
689 578
690/**
691 * Cancel a job. Must only be called before the job completion
692 * callback is called for the respective job.
693 *
694 * @param job job to cancel
695 */
696void 579void
697GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job) 580GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job)
698{ 581{
@@ -746,24 +629,6 @@ is_json (const char *ct)
746} 629}
747 630
748 631
749/**
750 * Obtain information about the final result about the
751 * HTTP download. If the download was successful, parses
752 * the JSON in the @a db and returns it. Also returns
753 * the HTTP @a response_code. If the download failed,
754 * the return value is NULL. The response code is set
755 * in any case, on download errors to zero.
756 *
757 * Calling this function also cleans up @a db.
758 *
759 * @param db download buffer
760 * @param eh CURL handle (to get the response code)
761 * @param[out] response_code set to the HTTP response code
762 * (or zero if we aborted the download, for example
763 * because the response was too big, or if
764 * the JSON we received was malformed).
765 * @return NULL if downloading a JSON reply failed.
766 */
767void * 632void *
768GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db, 633GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
769 CURL *eh, 634 CURL *eh,
@@ -838,13 +703,6 @@ GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
838} 703}
839 704
840 705
841/**
842 * Add custom request header.
843 *
844 * @param ctx cURL context.
845 * @param header header string; will be given to the context AS IS.
846 * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise.
847 */
848enum GNUNET_GenericReturnValue 706enum GNUNET_GenericReturnValue
849GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, 707GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx,
850 const char *header) 708 const char *header)
@@ -858,14 +716,6 @@ GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx,
858} 716}
859 717
860 718
861/**
862 * Run the main event loop for the HTTP interaction.
863 *
864 * @param ctx the library context
865 * @param rp parses the raw response returned from
866 * the Web server.
867 * @param rc cleans/frees the response
868 */
869void 719void
870GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx, 720GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx,
871 GNUNET_CURL_RawParser rp, 721 GNUNET_CURL_RawParser rp,
@@ -920,11 +770,6 @@ GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx,
920} 770}
921 771
922 772
923/**
924 * Run the main event loop for the HTTP interaction.
925 *
926 * @param ctx the library context
927 */
928void 773void
929GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx) 774GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx)
930{ 775{
@@ -934,34 +779,6 @@ GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx)
934} 779}
935 780
936 781
937/**
938 * Obtain the information for a select() call to wait until
939 * #GNUNET_CURL_perform() is ready again. Note that calling
940 * any other GNUNET_CURL-API may also imply that the library
941 * is again ready for #GNUNET_CURL_perform().
942 *
943 * Basically, a client should use this API to prepare for select(),
944 * then block on select(), then call #GNUNET_CURL_perform() and then
945 * start again until the work with the context is done.
946 *
947 * This function will NOT zero out the sets and assumes that @a max_fd
948 * and @a timeout are already set to minimal applicable values. It is
949 * safe to give this API FD-sets and @a max_fd and @a timeout that are
950 * already initialized to some other descriptors that need to go into
951 * the select() call.
952 *
953 * @param ctx context to get the event loop information for
954 * @param read_fd_set will be set for any pending read operations
955 * @param write_fd_set will be set for any pending write operations
956 * @param except_fd_set is here because curl_multi_fdset() has this argument
957 * @param max_fd set to the highest FD included in any set;
958 * if the existing sets have no FDs in it, the initial
959 * value should be "-1". (Note that `max_fd + 1` will need
960 * to be passed to select().)
961 * @param timeout set to the timeout in milliseconds (!); -1 means
962 * no timeout (NULL, blocking forever is OK), 0 means to
963 * proceed immediately with #GNUNET_CURL_perform().
964 */
965void 782void
966GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx, 783GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx,
967 fd_set *read_fd_set, 784 fd_set *read_fd_set,
@@ -995,13 +812,6 @@ GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx,
995} 812}
996 813
997 814
998/**
999 * Cleanup library initialisation resources. This function should be called
1000 * after using this library to cleanup the resources occupied during library's
1001 * initialisation.
1002 *
1003 * @param ctx the library context
1004 */
1005void 815void
1006GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx) 816GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx)
1007{ 817{
diff --git a/src/include/gnunet_getopt_lib.h b/src/include/gnunet_getopt_lib.h
index 731be4159..259d648dd 100644
--- a/src/include/gnunet_getopt_lib.h
+++ b/src/include/gnunet_getopt_lib.h
@@ -378,6 +378,24 @@ GNUNET_GETOPT_option_absolute_time (char shortName,
378 378
379 379
380/** 380/**
381 * Allow user to specify a `struct GNUNET_TIME_Timestamp`
382 * (using human-readable "fancy" time).
383 *
384 * @param shortName short name of the option
385 * @param name long name of the option
386 * @param argumentHelp help text for the option argument
387 * @param description long help text for the option
388 * @param[out] val set to the time specified at the command line
389 */
390struct GNUNET_GETOPT_CommandLineOption
391GNUNET_GETOPT_option_timestamp (char shortName,
392 const char *name,
393 const char *argumentHelp,
394 const char *description,
395 struct GNUNET_TIME_Timestamp *val);
396
397
398/**
381 * Increment @a val each time the option flag is given by one. 399 * Increment @a val each time the option flag is given by one.
382 * 400 *
383 * @param shortName short name of the option 401 * @param shortName short name of the option
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h
index 5ef4592e5..7d101196c 100644
--- a/src/include/gnunet_json_lib.h
+++ b/src/include/gnunet_json_lib.h
@@ -304,25 +304,25 @@ GNUNET_JSON_spec_boolean (const char *name,
304/* ************ GNUnet-specific parser specifications ******************* */ 304/* ************ GNUnet-specific parser specifications ******************* */
305 305
306/** 306/**
307 * Absolute time. 307 * Timestamp.
308 * 308 *
309 * @param name name of the JSON field 309 * @param name name of the JSON field
310 * @param[out] at where to store the absolute time found under @a name 310 * @param[out] at where to store the absolute time found under @a name
311 */ 311 */
312struct GNUNET_JSON_Specification 312struct GNUNET_JSON_Specification
313GNUNET_JSON_spec_absolute_time (const char *name, 313GNUNET_JSON_spec_timestamp (const char *name,
314 struct GNUNET_TIME_Absolute *at); 314 struct GNUNET_TIME_Timestamp *t);
315 315
316 316
317/** 317/**
318 * Absolute time in network byte order. 318 * Timestamp in network byte order.
319 * 319 *
320 * @param name name of the JSON field 320 * @param name name of the JSON field
321 * @param[out] at where to store the absolute time found under @a name 321 * @param[out] tn where to store the absolute time found under @a name
322 */ 322 */
323struct GNUNET_JSON_Specification 323struct GNUNET_JSON_Specification
324GNUNET_JSON_spec_absolute_time_nbo (const char *name, 324GNUNET_JSON_spec_timestamp_nbo (const char *name,
325 struct GNUNET_TIME_AbsoluteNBO *at); 325 struct GNUNET_TIME_TimestampNBO *tn);
326 326
327 327
328/** 328/**
@@ -385,23 +385,23 @@ GNUNET_JSON_from_data (const void *data, size_t size);
385 385
386 386
387/** 387/**
388 * Convert absolute timestamp to a json string. 388 * Convert timestamp to a json string.
389 * 389 *
390 * @param stamp the time stamp 390 * @param stamp the time stamp
391 * @return a json string with the timestamp in @a stamp 391 * @return a json string with the timestamp in @a stamp
392 */ 392 */
393json_t * 393json_t *
394GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp); 394GNUNET_JSON_from_timestamp (struct GNUNET_TIME_Timestamp stamp);
395 395
396 396
397/** 397/**
398 * Convert absolute timestamp to a json string. 398 * Convert timestamp to a json string.
399 * 399 *
400 * @param stamp the time stamp 400 * @param stamp the time stamp
401 * @return a json string with the timestamp in @a stamp 401 * @return a json string with the timestamp in @a stamp
402 */ 402 */
403json_t * 403json_t *
404GNUNET_JSON_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO stamp); 404GNUNET_JSON_from_timestamp_nbo (struct GNUNET_TIME_TimestampNBO stamp);
405 405
406 406
407/** 407/**
@@ -747,30 +747,30 @@ GNUNET_JSON_pack_data_varsize (const char *name,
747 747
748/** 748/**
749 * Generate packer instruction for a JSON field of type 749 * Generate packer instruction for a JSON field of type
750 * absolute time. 750 * timestamp.
751 * 751 *
752 * @param name name of the field to add to the object 752 * @param name name of the field to add to the object
753 * @param at absolute time to pack, a value of 0 is only 753 * @param at timestamp pack, a value of 0 is only
754 * allowed with #GNUNET_JSON_pack_allow_null()! 754 * allowed with #GNUNET_JSON_pack_allow_null()!
755 * @return json pack specification 755 * @return json pack specification
756 */ 756 */
757struct GNUNET_JSON_PackSpec 757struct GNUNET_JSON_PackSpec
758GNUNET_JSON_pack_time_abs (const char *name, 758GNUNET_JSON_pack_timestamp (const char *name,
759 struct GNUNET_TIME_Absolute at); 759 struct GNUNET_TIME_Timestamp at);
760 760
761 761
762/** 762/**
763 * Generate packer instruction for a JSON field of type 763 * Generate packer instruction for a JSON field of type
764 * absolute time in network byte order. 764 * timestamp in network byte order.
765 * 765 *
766 * @param name name of the field to add to the object 766 * @param name name of the field to add to the object
767 * @param at absolute time to pack, a value of 0 is only 767 * @param at timestamp to pack, a value of 0 is only
768 * allowed with #GNUNET_JSON_pack_allow_null()! 768 * allowed with #GNUNET_JSON_pack_allow_null()!
769 * @return json pack specification 769 * @return json pack specification
770 */ 770 */
771struct GNUNET_JSON_PackSpec 771struct GNUNET_JSON_PackSpec
772GNUNET_JSON_pack_time_abs_nbo (const char *name, 772GNUNET_JSON_pack_timestamp_nbo (const char *name,
773 struct GNUNET_TIME_AbsoluteNBO at); 773 struct GNUNET_TIME_TimestampNBO at);
774 774
775 775
776/** 776/**
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h
index 05d373f88..f7bf59212 100644
--- a/src/include/gnunet_pq_lib.h
+++ b/src/include/gnunet_pq_lib.h
@@ -96,7 +96,11 @@ struct GNUNET_PQ_QueryParam
96 */ 96 */
97#define GNUNET_PQ_query_param_end \ 97#define GNUNET_PQ_query_param_end \
98 { \ 98 { \
99 NULL, NULL, NULL, 0, 0 \ 99 .conv = NULL, \
100 .conv_cls = NULL, \
101 .data = NULL, \
102 .size = 0, \
103 .num_params = 0 \
100 } 104 }
101 105
102 106
@@ -200,6 +204,17 @@ GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x);
200 204
201 205
202/** 206/**
207 * Generate query parameter for a timestamp.
208 * The database must store a 64-bit integer.
209 *
210 * @param x pointer to the query parameter to pass
211 * @return query parameter to use
212 */
213struct GNUNET_PQ_QueryParam
214GNUNET_PQ_query_param_timestamp (const struct GNUNET_TIME_Timestamp *x);
215
216
217/**
203 * Generate query parameter for an absolute time value. 218 * Generate query parameter for an absolute time value.
204 * The database must store a 64-bit integer. 219 * The database must store a 64-bit integer.
205 * 220 *
@@ -212,6 +227,18 @@ GNUNET_PQ_query_param_absolute_time_nbo (
212 227
213 228
214/** 229/**
230 * Generate query parameter for a timestamp in NBO.
231 * The database must store a 64-bit integer.
232 *
233 * @param x pointer to the query parameter to pass
234 * @return query parameter to use
235 */
236struct GNUNET_PQ_QueryParam
237GNUNET_PQ_query_param_timestamp_nbo (
238 const struct GNUNET_TIME_TimestampNBO *t);
239
240
241/**
215 * Generate query parameter for an uint16_t in host byte order. 242 * Generate query parameter for an uint16_t in host byte order.
216 * 243 *
217 * @param x pointer to the query parameter to pass 244 * @param x pointer to the query parameter to pass
@@ -472,6 +499,18 @@ GNUNET_PQ_result_spec_absolute_time (const char *name,
472 499
473 500
474/** 501/**
502 * Timestamp expected.
503 *
504 * @param name name of the field in the table
505 * @param[out] t where to store the result
506 * @return array entry for the result specification to use
507 */
508struct GNUNET_PQ_ResultSpec
509GNUNET_PQ_result_spec_timestamp (const char *name,
510 struct GNUNET_TIME_Timestamp *t);
511
512
513/**
475 * Relative time expected. 514 * Relative time expected.
476 * 515 *
477 * @param name name of the field in the table 516 * @param name name of the field in the table
@@ -496,6 +535,18 @@ GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
496 535
497 536
498/** 537/**
538 * Timestamp expected.
539 *
540 * @param name name of the field in the table
541 * @param[out] tn where to store the result
542 * @return array entry for the result specification to use
543 */
544struct GNUNET_PQ_ResultSpec
545GNUNET_PQ_result_spec_timestamp_nbo (const char *name,
546 struct GNUNET_TIME_TimestampNBO *tn);
547
548
549/**
499 * uint16_t expected. 550 * uint16_t expected.
500 * 551 *
501 * @param name name of the field in the table 552 * @param name name of the field in the table
diff --git a/src/include/gnunet_sq_lib.h b/src/include/gnunet_sq_lib.h
index 21ce5b393..e89ded07e 100644
--- a/src/include/gnunet_sq_lib.h
+++ b/src/include/gnunet_sq_lib.h
@@ -40,7 +40,7 @@
40 * so immediately suitable for passing to `sqlite3_bind`-functions. 40 * so immediately suitable for passing to `sqlite3_bind`-functions.
41 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success 41 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
42 */ 42 */
43typedef int 43typedef enum GNUNET_GenericReturnValue
44(*GNUNET_SQ_QueryConverter)(void *cls, 44(*GNUNET_SQ_QueryConverter)(void *cls,
45 const void *data, 45 const void *data,
46 size_t data_len, 46 size_t data_len,
@@ -156,8 +156,8 @@ GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x);
156 * @param x pointer to the query parameter to pass 156 * @param x pointer to the query parameter to pass
157 */ 157 */
158struct GNUNET_SQ_QueryParam 158struct GNUNET_SQ_QueryParam
159GNUNET_SQ_query_param_absolute_time_nbo (const struct 159GNUNET_SQ_query_param_absolute_time_nbo (
160 GNUNET_TIME_AbsoluteNBO *x); 160 const struct GNUNET_TIME_AbsoluteNBO *x);
161 161
162 162
163/** 163/**
@@ -222,7 +222,7 @@ GNUNET_SQ_reset (sqlite3 *dbh,
222 * #GNUNET_YES if all results could be extracted 222 * #GNUNET_YES if all results could be extracted
223 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) 223 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
224 */ 224 */
225typedef int 225typedef enum GNUNET_GenericReturnValue
226(*GNUNET_SQ_ResultConverter)(void *cls, 226(*GNUNET_SQ_ResultConverter)(void *cls,
227 sqlite3_stmt *result, 227 sqlite3_stmt *result,
228 unsigned int column, 228 unsigned int column,
@@ -436,7 +436,7 @@ GNUNET_SQ_result_spec_uint64 (uint64_t *u64);
436 * #GNUNET_OK if all results could be extracted 436 * #GNUNET_OK if all results could be extracted
437 * #GNUNET_SYSERR if a result was invalid (non-existing field) 437 * #GNUNET_SYSERR if a result was invalid (non-existing field)
438 */ 438 */
439int 439enum GNUNET_GenericReturnValue
440GNUNET_SQ_extract_result (sqlite3_stmt *result, 440GNUNET_SQ_extract_result (sqlite3_stmt *result,
441 struct GNUNET_SQ_ResultSpec *rs); 441 struct GNUNET_SQ_ResultSpec *rs);
442 442
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h
index 977c2ead7..2e0c720ee 100644
--- a/src/include/gnunet_strings_lib.h
+++ b/src/include/gnunet_strings_lib.h
@@ -76,7 +76,7 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
76 * @param rtime set to the relative time 76 * @param rtime set to the relative time
77 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 77 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
78 */ 78 */
79int 79enum GNUNET_GenericReturnValue
80GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, 80GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time,
81 struct GNUNET_TIME_Relative *rtime); 81 struct GNUNET_TIME_Relative *rtime);
82 82
@@ -91,12 +91,27 @@ GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time,
91 * @param atime set to the absolute time 91 * @param atime set to the absolute time
92 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 92 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
93 */ 93 */
94int 94enum GNUNET_GenericReturnValue
95GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, 95GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time,
96 struct GNUNET_TIME_Absolute *atime); 96 struct GNUNET_TIME_Absolute *atime);
97 97
98 98
99/** 99/**
100 * @ingroup time
101 * Convert a given fancy human-readable time to our internal
102 * representation. The human-readable time is expected to be
103 * in local time, whereas the returned value will be in UTC.
104 *
105 * @param fancy_time human readable string (e.g. %Y-%m-%d %H:%M:%S)
106 * @param atime set to the absolute time
107 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
108 */
109enum GNUNET_GenericReturnValue
110GNUNET_STRINGS_fancy_time_to_timestamp (const char *fancy_time,
111 struct GNUNET_TIME_Timestamp *atime);
112
113
114/**
100 * Convert a given filesize into a fancy human-readable format. 115 * Convert a given filesize into a fancy human-readable format.
101 * 116 *
102 * @param size number of bytes 117 * @param size number of bytes
diff --git a/src/include/gnunet_time_lib.h b/src/include/gnunet_time_lib.h
index 26b442066..5e826ace0 100644
--- a/src/include/gnunet_time_lib.h
+++ b/src/include/gnunet_time_lib.h
@@ -54,6 +54,17 @@ struct GNUNET_TIME_Absolute
54}; 54};
55 55
56/** 56/**
57 * Rounded time for timestamps used by GNUnet, in seconds.
58 */
59struct GNUNET_TIME_Timestamp
60{
61 /**
62 * The actual value. Must be round number in seconds.
63 */
64 struct GNUNET_TIME_Absolute abs_time;
65};
66
67/**
57 * Time for relative time used by GNUnet, in microseconds. 68 * Time for relative time used by GNUnet, in microseconds.
58 * Always positive, so we can only refer to future time. 69 * Always positive, so we can only refer to future time.
59 */ 70 */
@@ -89,17 +100,34 @@ struct GNUNET_TIME_AbsoluteNBO
89 */ 100 */
90 uint64_t abs_value_us__ GNUNET_PACKED; 101 uint64_t abs_value_us__ GNUNET_PACKED;
91}; 102};
103
104/**
105 * Time for timestamps used by GNUnet, in seconds and in network byte order.
106 */
107struct GNUNET_TIME_TimestampNBO
108{
109 /**
110 * The actual value. Must be round number in seconds.
111 */
112 struct GNUNET_TIME_AbsoluteNBO abs_time_nbo;
113};
114
92GNUNET_NETWORK_STRUCT_END 115GNUNET_NETWORK_STRUCT_END
93 116
94/** 117/**
95 * Relative time zero. 118 * Relative time zero.
96 */ 119 */
97#define GNUNET_TIME_UNIT_ZERO GNUNET_TIME_relative_get_zero_ () 120#define GNUNET_TIME_UNIT_ZERO ((struct GNUNET_TIME_Relative){0})
98 121
99/** 122/**
100 * Absolute time zero. 123 * Absolute time zero.
101 */ 124 */
102#define GNUNET_TIME_UNIT_ZERO_ABS GNUNET_TIME_absolute_get_zero_ () 125#define GNUNET_TIME_UNIT_ZERO_ABS ((struct GNUNET_TIME_Absolute){0})
126
127/**
128 * Timestamp of zero.
129 */
130#define GNUNET_TIME_UNIT_ZERO_TS ((struct GNUNET_TIME_Timestamp){{0}})
103 131
104/** 132/**
105 * One microsecond, our basic time unit. 133 * One microsecond, our basic time unit.
@@ -154,13 +182,22 @@ GNUNET_NETWORK_STRUCT_END
154 * Constant used to specify "forever". This constant 182 * Constant used to specify "forever". This constant
155 * will be treated specially in all time operations. 183 * will be treated specially in all time operations.
156 */ 184 */
157#define GNUNET_TIME_UNIT_FOREVER_REL GNUNET_TIME_relative_get_forever_ () 185#define GNUNET_TIME_UNIT_FOREVER_REL \
186 ((struct GNUNET_TIME_Relative){UINT64_MAX})
158 187
159/** 188/**
160 * Constant used to specify "forever". This constant 189 * Constant used to specify "forever". This constant
161 * will be treated specially in all time operations. 190 * will be treated specially in all time operations.
162 */ 191 */
163#define GNUNET_TIME_UNIT_FOREVER_ABS GNUNET_TIME_absolute_get_forever_ () 192#define GNUNET_TIME_UNIT_FOREVER_ABS \
193 ((struct GNUNET_TIME_Absolute){UINT64_MAX})
194
195/**
196 * Constant used to specify "forever". This constant
197 * will be treated specially in all time operations.
198 */
199#define GNUNET_TIME_UNIT_FOREVER_TS \
200 ((struct GNUNET_TIME_Timestamp){{UINT64_MAX}})
164 201
165 202
166/** 203/**
@@ -183,6 +220,47 @@ GNUNET_NETWORK_STRUCT_END
183 220
184 221
185/** 222/**
223 * Convert @a ts to human-readable timestamp.
224 * Note that the returned value will be overwritten if this function
225 * is called again.
226 *
227 * @param ts the timestamp to convert
228 * @return statically allocated string, will change on the next call
229 */
230const char *
231GNUNET_TIME_timestamp2s (struct GNUNET_TIME_Timestamp ts);
232
233
234/**
235 * @ingroup time
236 * Like `asctime`, except for GNUnet time. Converts a GNUnet internal
237 * absolute time (which is in UTC) to a string in local time.
238 * Note that the returned value will be overwritten if this function
239 * is called again.
240 *
241 * @param t the absolute time to convert
242 * @return timestamp in human-readable form in local time
243 */
244const char *
245GNUNET_TIME_absolute2s (struct GNUNET_TIME_Absolute ts);
246
247
248/**
249 * @ingroup time
250 * Give relative time in human-readable fancy format.
251 * This is one of the very few calls in the entire API that is
252 * NOT reentrant!
253 *
254 * @param delta time in milli seconds
255 * @param do_round are we allowed to round a bit?
256 * @return string in human-readable form
257 */
258const char *
259GNUNET_TIME_relative2s (struct GNUNET_TIME_Relative delta,
260 bool do_round);
261
262
263/**
186 * Randomized exponential back-off, starting at 1 ms 264 * Randomized exponential back-off, starting at 1 ms
187 * and going up by a factor of 2+r, where 0 <= r <= 0.5, up 265 * and going up by a factor of 2+r, where 0 <= r <= 0.5, up
188 * to a maximum of the given threshold. 266 * to a maximum of the given threshold.
@@ -192,8 +270,8 @@ GNUNET_NETWORK_STRUCT_END
192 * @return the next backoff time 270 * @return the next backoff time
193 */ 271 */
194struct GNUNET_TIME_Relative 272struct GNUNET_TIME_Relative
195GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt, struct 273GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt,
196 GNUNET_TIME_Relative threshold); 274 struct GNUNET_TIME_Relative threshold);
197 275
198 276
199/** 277/**
@@ -290,27 +368,69 @@ GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel);
290 368
291 369
292/** 370/**
293 * Round a time value so that it is suitable for transmission 371 * Convert relative time to a timestamp in the
294 * via JSON encodings. 372 * future.
373 *
374 * @param rel relative time to convert
375 * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
376 */
377struct GNUNET_TIME_Timestamp
378GNUNET_TIME_relative_to_timestamp (struct GNUNET_TIME_Relative rel);
379
380
381/**
382 * Round an absolute time to a timestamp.
295 * 383 *
296 * @param at time to round 384 * @param at time to round
297 * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if 385 * @return the result
298 * it was just now rounded
299 */ 386 */
300int 387struct GNUNET_TIME_Timestamp
301GNUNET_TIME_round_abs (struct GNUNET_TIME_Absolute *at); 388GNUNET_TIME_absolute_to_timestamp (struct GNUNET_TIME_Absolute at);
302 389
303 390
304/** 391/**
305 * Round a time value so that it is suitable for transmission 392 * Get timestamp representing the current time.
306 * via JSON encodings.
307 * 393 *
308 * @param rt time to round 394 * @return current time, rounded down to seconds
309 * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
310 * it was just now rounded
311 */ 395 */
312int 396struct GNUNET_TIME_Timestamp
313GNUNET_TIME_round_rel (struct GNUNET_TIME_Relative *rt); 397GNUNET_TIME_timestamp_get (void);
398
399
400/**
401 * Compare two absolute times.
402 *
403 * @param t1 first time
404 * @param op compare operator
405 * @param t2 second time
406 * @return true if @a t1 @a op @a t2
407 */
408#define GNUNET_TIME_absolute_cmp(t1,op,t2) \
409 (((void) (1 op 2), (t1).abs_value_us op (t2).abs_value_us))
410
411
412/**
413 * Compare two timestamps
414 *
415 * @param t1 first timestamp
416 * @param op compare operator
417 * @param t2 second timestamp
418 * @return true if @a t1 @a op @a t2
419 */
420#define GNUNET_TIME_timestamp_cmp(t1,op,t2) \
421 GNUNET_TIME_absolute_cmp ((t1).abs_time,op,(t2).abs_time)
422
423
424/**
425 * Compare two relative times.
426 *
427 * @param t1 first time
428 * @param op compare operator
429 * @param t2 second time
430 * @return true if @a t1 @a op @a t2
431 */
432#define GNUNET_TIME_relative_cmp(t1,op,t2) \
433 ((void) (1 op 2), (t1).rel_value_us op (t2).rel_value_us)
314 434
315 435
316/** 436/**
@@ -362,6 +482,30 @@ GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
362 482
363 483
364/** 484/**
485 * Return the maximum of two timestamps.
486 *
487 * @param t1 first timestamp
488 * @param t2 other timestamp
489 * @return timestamp that is smaller
490 */
491struct GNUNET_TIME_Timestamp
492GNUNET_TIME_timestamp_max (struct GNUNET_TIME_Timestamp t1,
493 struct GNUNET_TIME_Timestamp t2);
494
495
496/**
497 * Return the minimum of two timestamps.
498 *
499 * @param t1 first timestamp
500 * @param t2 other timestamp
501 * @return timestamp that is smaller
502 */
503struct GNUNET_TIME_Timestamp
504GNUNET_TIME_timestamp_min (struct GNUNET_TIME_Timestamp t1,
505 struct GNUNET_TIME_Timestamp t2);
506
507
508/**
365 * Given a timestamp in the future, how much time 509 * Given a timestamp in the future, how much time
366 * remains until then? 510 * remains until then?
367 * 511 *
@@ -530,6 +674,16 @@ GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a);
530 674
531 675
532/** 676/**
677 * Convert timestamp to network byte order.
678 *
679 * @param t time to convert
680 * @return converted time value
681 */
682struct GNUNET_TIME_TimestampNBO
683GNUNET_TIME_timestamp_hton (struct GNUNET_TIME_Timestamp t);
684
685
686/**
533 * Convert milliseconds after the UNIX epoch to absolute time. 687 * Convert milliseconds after the UNIX epoch to absolute time.
534 * 688 *
535 * @param ms_after_epoch millisecond timestamp to convert 689 * @param ms_after_epoch millisecond timestamp to convert
@@ -558,6 +712,15 @@ GNUNET_TIME_absolute_is_past (struct GNUNET_TIME_Absolute abs);
558 712
559 713
560/** 714/**
715 * Test if @a abs is truly zero.
716 *
717 * @return true if it is.
718 */
719bool
720GNUNET_TIME_absolute_is_zero (struct GNUNET_TIME_Absolute abs);
721
722
723/**
561 * Test if @a abs is truly in the future (excluding now). 724 * Test if @a abs is truly in the future (excluding now).
562 * 725 *
563 * @return true if it is. 726 * @return true if it is.
@@ -595,6 +758,15 @@ GNUNET_TIME_absolute_from_s (uint64_t s_after_epoch);
595 758
596 759
597/** 760/**
761 * Convert seconds after the UNIX epoch to timestamp.
762 *
763 * @param s_after_epoch seconds after epoch to convert
764 * @return converted time value
765 */struct GNUNET_TIME_Timestamp
766GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch);
767
768
769/**
598 * Convert absolute time from network byte order. 770 * Convert absolute time from network byte order.
599 * 771 *
600 * @param a time to convert 772 * @param a time to convert
@@ -605,6 +777,16 @@ GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a);
605 777
606 778
607/** 779/**
780 * Convert timestamp from network byte order.
781 *
782 * @param tn time to convert
783 * @return converted time value
784 */
785struct GNUNET_TIME_Timestamp
786GNUNET_TIME_timestamp_ntoh (struct GNUNET_TIME_TimestampNBO tn);
787
788
789/**
608 * Set the timestamp offset for this instance. 790 * Set the timestamp offset for this instance.
609 * 791 *
610 * @param offset the offset to skew the locale time by 792 * @param offset the offset to skew the locale time by
diff --git a/src/json/json_generator.c b/src/json/json_generator.c
index 0c513ca9d..eb275712c 100644
--- a/src/json/json_generator.c
+++ b/src/json/json_generator.c
@@ -27,14 +27,6 @@
27#include "gnunet_json_lib.h" 27#include "gnunet_json_lib.h"
28 28
29 29
30/**
31 * Convert binary data to a JSON string
32 * with the base32crockford encoding.
33 *
34 * @param data binary data
35 * @param size size of @a data in bytes
36 * @return json string that encodes @a data
37 */
38json_t * 30json_t *
39GNUNET_JSON_from_data (const void *data, 31GNUNET_JSON_from_data (const void *data,
40 size_t size) 32 size_t size)
@@ -57,31 +49,22 @@ GNUNET_JSON_from_data (const void *data,
57} 49}
58 50
59 51
60/**
61 * Convert absolute timestamp to a json string.
62 *
63 * @param stamp the time stamp
64 * @return a json string with the timestamp in @a stamp
65 */
66json_t * 52json_t *
67GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp) 53GNUNET_JSON_from_timestamp (struct GNUNET_TIME_Timestamp stamp)
68{ 54{
69 json_t *j; 55 json_t *j;
70 56
71 GNUNET_assert (GNUNET_OK ==
72 GNUNET_TIME_round_abs (&stamp));
73
74 j = json_object (); 57 j = json_object ();
75 if (NULL == j) 58 if (NULL == j)
76 { 59 {
77 GNUNET_break (0); 60 GNUNET_break (0);
78 return NULL; 61 return NULL;
79 } 62 }
80 if (stamp.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) 63 if (GNUNET_TIME_absolute_is_never (stamp.abs_time))
81 { 64 {
82 if (0 != 65 if (0 !=
83 json_object_set_new (j, 66 json_object_set_new (j,
84 "t_ms", 67 "t_s",
85 json_string ("never"))) 68 json_string ("never")))
86 { 69 {
87 GNUNET_break (0); 70 GNUNET_break (0);
@@ -90,11 +73,17 @@ GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp)
90 } 73 }
91 return j; 74 return j;
92 } 75 }
76 GNUNET_assert (
77 0 ==
78 (stamp.abs_time.abs_value_us
79 % GNUNET_TIME_UNIT_SECONDS.rel_value_us));
93 if (0 != 80 if (0 !=
94 json_object_set_new (j, 81 json_object_set_new (
95 "t_ms", 82 j,
96 json_integer ((json_int_t) (stamp.abs_value_us 83 "t_s",
97 / 1000LL)))) 84 json_integer (
85 (json_int_t) (stamp.abs_time.abs_value_us
86 / GNUNET_TIME_UNIT_SECONDS.rel_value_us))))
98 { 87 {
99 GNUNET_break (0); 88 GNUNET_break (0);
100 json_decref (j); 89 json_decref (j);
@@ -104,44 +93,29 @@ GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp)
104} 93}
105 94
106 95
107/**
108 * Convert absolute timestamp to a json string.
109 *
110 * @param stamp the time stamp
111 * @return a json string with the timestamp in @a stamp
112 */
113json_t * 96json_t *
114GNUNET_JSON_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO stamp) 97GNUNET_JSON_from_timestamp_nbo (struct GNUNET_TIME_TimestampNBO stamp)
115{ 98{
116 return GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (stamp)); 99 return GNUNET_JSON_from_timestamp (GNUNET_TIME_timestamp_ntoh (stamp));
117} 100}
118 101
119 102
120/**
121 * Convert relative timestamp to a json string.
122 *
123 * @param stamp the time stamp
124 * @return a json string with the timestamp in @a stamp
125 */
126json_t * 103json_t *
127GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp) 104GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp)
128{ 105{
129 json_t *j; 106 json_t *j;
130 107
131 GNUNET_assert (GNUNET_OK ==
132 GNUNET_TIME_round_rel (&stamp));
133
134 j = json_object (); 108 j = json_object ();
135 if (NULL == j) 109 if (NULL == j)
136 { 110 {
137 GNUNET_break (0); 111 GNUNET_break (0);
138 return NULL; 112 return NULL;
139 } 113 }
140 if (stamp.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) 114 if (GNUNET_TIME_relative_is_forever (stamp))
141 { 115 {
142 if (0 != 116 if (0 !=
143 json_object_set_new (j, 117 json_object_set_new (j,
144 "d_ms", 118 "d_us",
145 json_string ("forever"))) 119 json_string ("forever")))
146 { 120 {
147 GNUNET_break (0); 121 GNUNET_break (0);
@@ -150,11 +124,17 @@ GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp)
150 } 124 }
151 return j; 125 return j;
152 } 126 }
127 if (stamp.rel_value_us >= (1LLU << 53))
128 {
129 /* value is larger than allowed */
130 GNUNET_break (0);
131 return NULL;
132 }
153 if (0 != 133 if (0 !=
154 json_object_set_new (j, 134 json_object_set_new (
155 "d_ms", 135 j,
156 json_integer ((json_int_t) (stamp.rel_value_us 136 "d_us",
157 / 1000LL)))) 137 json_integer ((json_int_t) stamp.rel_value_us)))
158 { 138 {
159 GNUNET_break (0); 139 GNUNET_break (0);
160 json_decref (j); 140 json_decref (j);
@@ -164,12 +144,6 @@ GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp)
164} 144}
165 145
166 146
167/**
168 * Convert RSA public key to JSON.
169 *
170 * @param pk public key to convert
171 * @return corresponding JSON encoding
172 */
173json_t * 147json_t *
174GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk) 148GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk)
175{ 149{
@@ -186,12 +160,6 @@ GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk)
186} 160}
187 161
188 162
189/**
190 * Convert RSA signature to JSON.
191 *
192 * @param sig signature to convert
193 * @return corresponding JSON encoding
194 */
195json_t * 163json_t *
196GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig) 164GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig)
197{ 165{
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index 3a11f205c..73f5fc00c 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -49,7 +49,7 @@ GNUNET_JSON_spec_end ()
49 * @param[out] spec where to write the data 49 * @param[out] spec where to write the data
50 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error 50 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
51 */ 51 */
52static int 52static enum GNUNET_GenericReturnValue
53parse_fixed_data (void *cls, 53parse_fixed_data (void *cls,
54 json_t *root, 54 json_t *root,
55 struct GNUNET_JSON_Specification *spec) 55 struct GNUNET_JSON_Specification *spec)
@@ -579,20 +579,20 @@ GNUNET_JSON_spec_int64 (const char *name,
579/* ************ GNUnet-specific parser specifications ******************* */ 579/* ************ GNUnet-specific parser specifications ******************* */
580 580
581/** 581/**
582 * Parse given JSON object to absolute time. 582 * Parse given JSON object to a timestamp.
583 * 583 *
584 * @param cls closure, NULL 584 * @param cls closure, NULL
585 * @param root the json object representing data 585 * @param root the json object representing data
586 * @param[out] spec where to write the data 586 * @param[out] spec where to write the data
587 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error 587 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
588 */ 588 */
589static int 589static enum GNUNET_GenericReturnValue
590parse_abs_time (void *cls, 590parse_timestamp (void *cls,
591 json_t *root, 591 json_t *root,
592 struct GNUNET_JSON_Specification *spec) 592 struct GNUNET_JSON_Specification *spec)
593{ 593{
594 struct GNUNET_TIME_Absolute *abs = spec->ptr; 594 struct GNUNET_TIME_Timestamp *ts = spec->ptr;
595 json_t *json_t_ms; 595 json_t *json_t_s;
596 unsigned long long int tval; 596 unsigned long long int tval;
597 597
598 if (! json_is_object (root)) 598 if (! json_is_object (root))
@@ -600,14 +600,16 @@ parse_abs_time (void *cls,
600 GNUNET_break_op (0); 600 GNUNET_break_op (0);
601 return GNUNET_SYSERR; 601 return GNUNET_SYSERR;
602 } 602 }
603 json_t_ms = json_object_get (root, "t_ms"); 603 json_t_s = json_object_get (root,
604 if (json_is_integer (json_t_ms)) 604 "t_s");
605 if (json_is_integer (json_t_s))
605 { 606 {
606 tval = json_integer_value (json_t_ms); 607 tval = json_integer_value (json_t_s);
607 /* Time is in milliseconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ 608 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
608 abs->abs_value_us = tval * GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us; 609 ts->abs_time.abs_value_us
609 if ((abs->abs_value_us) 610 = tval * GNUNET_TIME_UNIT_SECONDS.rel_value_us;
610 / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us 611 if (ts->abs_time.abs_value_us
612 / GNUNET_TIME_UNIT_SECONDS.rel_value_us
611 != tval) 613 != tval)
612 { 614 {
613 /* Integer overflow */ 615 /* Integer overflow */
@@ -616,14 +618,15 @@ parse_abs_time (void *cls,
616 } 618 }
617 return GNUNET_OK; 619 return GNUNET_OK;
618 } 620 }
619 if (json_is_string (json_t_ms)) 621 if (json_is_string (json_t_s))
620 { 622 {
621 const char *val; 623 const char *val;
622 624
623 val = json_string_value (json_t_ms); 625 val = json_string_value (json_t_s);
624 if ((0 == strcasecmp (val, "never"))) 626 if ((0 == strcasecmp (val,
627 "never")))
625 { 628 {
626 *abs = GNUNET_TIME_UNIT_FOREVER_ABS; 629 ts->abs_time = GNUNET_TIME_UNIT_FOREVER_ABS;
627 return GNUNET_OK; 630 return GNUNET_OK;
628 } 631 }
629 GNUNET_break_op (0); 632 GNUNET_break_op (0);
@@ -635,17 +638,14 @@ parse_abs_time (void *cls,
635 638
636 639
637struct GNUNET_JSON_Specification 640struct GNUNET_JSON_Specification
638GNUNET_JSON_spec_absolute_time (const char *name, 641GNUNET_JSON_spec_timestamp (const char *name,
639 struct GNUNET_TIME_Absolute *at) 642 struct GNUNET_TIME_Timestamp *t)
640{ 643{
641 struct GNUNET_JSON_Specification ret = { 644 struct GNUNET_JSON_Specification ret = {
642 .parser = &parse_abs_time, 645 .parser = &parse_timestamp,
643 .cleaner = NULL,
644 .cls = NULL,
645 .field = name, 646 .field = name,
646 .ptr = at, 647 .ptr = t,
647 .ptr_size = sizeof(struct GNUNET_TIME_Absolute), 648 .ptr_size = sizeof(struct GNUNET_TIME_Timestamp)
648 .size_ptr = NULL
649 }; 649 };
650 650
651 return ret; 651 return ret;
@@ -660,40 +660,37 @@ GNUNET_JSON_spec_absolute_time (const char *name,
660 * @param[out] spec where to write the data 660 * @param[out] spec where to write the data
661 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error 661 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
662 */ 662 */
663static int 663static enum GNUNET_GenericReturnValue
664parse_abs_time_nbo (void *cls, 664parse_timestamp_nbo (void *cls,
665 json_t *root, 665 json_t *root,
666 struct GNUNET_JSON_Specification *spec) 666 struct GNUNET_JSON_Specification *spec)
667{ 667{
668 struct GNUNET_TIME_AbsoluteNBO *abs = spec->ptr; 668 struct GNUNET_TIME_TimestampNBO *ts = spec->ptr;
669 struct GNUNET_TIME_Absolute a; 669 struct GNUNET_TIME_Timestamp a;
670 struct GNUNET_JSON_Specification ispec; 670 struct GNUNET_JSON_Specification ispec;
671 671
672 ispec = *spec; 672 ispec = *spec;
673 ispec.parser = &parse_abs_time; 673 ispec.parser = &parse_timestamp;
674 ispec.ptr = &a; 674 ispec.ptr = &a;
675 if (GNUNET_OK != 675 if (GNUNET_OK !=
676 parse_abs_time (NULL, 676 parse_timestamp (NULL,
677 root, 677 root,
678 &ispec)) 678 &ispec))
679 return GNUNET_SYSERR; 679 return GNUNET_SYSERR;
680 *abs = GNUNET_TIME_absolute_hton (a); 680 *ts = GNUNET_TIME_timestamp_hton (a);
681 return GNUNET_OK; 681 return GNUNET_OK;
682} 682}
683 683
684 684
685struct GNUNET_JSON_Specification 685struct GNUNET_JSON_Specification
686GNUNET_JSON_spec_absolute_time_nbo (const char *name, 686GNUNET_JSON_spec_timestamp_nbo (const char *name,
687 struct GNUNET_TIME_AbsoluteNBO *at) 687 struct GNUNET_TIME_TimestampNBO *at)
688{ 688{
689 struct GNUNET_JSON_Specification ret = { 689 struct GNUNET_JSON_Specification ret = {
690 .parser = &parse_abs_time_nbo, 690 .parser = &parse_timestamp_nbo,
691 .cleaner = NULL,
692 .cls = NULL,
693 .field = name, 691 .field = name,
694 .ptr = at, 692 .ptr = at,
695 .ptr_size = sizeof(struct GNUNET_TIME_AbsoluteNBO), 693 .ptr_size = sizeof(struct GNUNET_TIME_TimestampNBO)
696 .size_ptr = NULL
697 }; 694 };
698 695
699 return ret; 696 return ret;
@@ -708,13 +705,13 @@ GNUNET_JSON_spec_absolute_time_nbo (const char *name,
708 * @param[out] spec where to write the data 705 * @param[out] spec where to write the data
709 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error 706 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
710 */ 707 */
711static int 708static enum GNUNET_GenericReturnValue
712parse_rel_time (void *cls, 709parse_rel_time (void *cls,
713 json_t *root, 710 json_t *root,
714 struct GNUNET_JSON_Specification *spec) 711 struct GNUNET_JSON_Specification *spec)
715{ 712{
716 struct GNUNET_TIME_Relative *rel = spec->ptr; 713 struct GNUNET_TIME_Relative *rel = spec->ptr;
717 json_t *json_d_ms; 714 json_t *json_d_us;
718 unsigned long long int tval; 715 unsigned long long int tval;
719 716
720 if (! json_is_object (root)) 717 if (! json_is_object (root))
@@ -722,25 +719,27 @@ parse_rel_time (void *cls,
722 GNUNET_break_op (0); 719 GNUNET_break_op (0);
723 return GNUNET_SYSERR; 720 return GNUNET_SYSERR;
724 } 721 }
725 json_d_ms = json_object_get (root, "d_ms"); 722 json_d_us = json_object_get (root,
726 if (json_is_integer (json_d_ms)) 723 "d_us");
724 if (json_is_integer (json_d_us))
727 { 725 {
728 tval = json_integer_value (json_d_ms); 726 tval = json_integer_value (json_d_us);
729 /* Time is in milliseconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ 727 if (tval >= (1LLU << 53))
730 rel->rel_value_us = tval * 1000LL;
731 if ((rel->rel_value_us) / 1000LL != tval)
732 { 728 {
733 /* Integer overflow */ 729 /* value is larger than allowed */
734 GNUNET_break_op (0); 730 GNUNET_break_op (0);
735 return GNUNET_SYSERR; 731 return GNUNET_SYSERR;
736 } 732 }
733 rel->rel_value_us = tval;
737 return GNUNET_OK; 734 return GNUNET_OK;
738 } 735 }
739 if (json_is_string (json_d_ms)) 736 if (json_is_string (json_d_us))
740 { 737 {
741 const char *val; 738 const char *val;
742 val = json_string_value (json_d_ms); 739
743 if ((0 == strcasecmp (val, "forever"))) 740 val = json_string_value (json_d_us);
741 if ((0 == strcasecmp (val,
742 "forever")))
744 { 743 {
745 *rel = GNUNET_TIME_UNIT_FOREVER_REL; 744 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
746 return GNUNET_OK; 745 return GNUNET_OK;
@@ -759,12 +758,9 @@ GNUNET_JSON_spec_relative_time (const char *name,
759{ 758{
760 struct GNUNET_JSON_Specification ret = { 759 struct GNUNET_JSON_Specification ret = {
761 .parser = &parse_rel_time, 760 .parser = &parse_rel_time,
762 .cleaner = NULL,
763 .cls = NULL,
764 .field = name, 761 .field = name,
765 .ptr = rt, 762 .ptr = rt,
766 .ptr_size = sizeof(struct GNUNET_TIME_Relative), 763 .ptr_size = sizeof(struct GNUNET_TIME_Relative)
767 .size_ptr = NULL
768 }; 764 };
769 765
770 return ret; 766 return ret;
@@ -779,7 +775,7 @@ GNUNET_JSON_spec_relative_time (const char *name,
779 * @param[out] spec where to write the data 775 * @param[out] spec where to write the data
780 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error 776 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
781 */ 777 */
782static int 778static enum GNUNET_GenericReturnValue
783parse_rsa_public_key (void *cls, 779parse_rsa_public_key (void *cls,
784 json_t *root, 780 json_t *root,
785 struct GNUNET_JSON_Specification *spec) 781 struct GNUNET_JSON_Specification *spec)
@@ -864,7 +860,7 @@ GNUNET_JSON_spec_rsa_public_key (const char *name,
864 * @param[out] spec where to write the data 860 * @param[out] spec where to write the data
865 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error 861 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
866 */ 862 */
867static int 863static enum GNUNET_GenericReturnValue
868parse_rsa_signature (void *cls, 864parse_rsa_signature (void *cls,
869 json_t *root, 865 json_t *root,
870 struct GNUNET_JSON_Specification *spec) 866 struct GNUNET_JSON_Specification *spec)
@@ -952,7 +948,7 @@ GNUNET_JSON_spec_rsa_signature (const char *name,
952 * @param[out] spec where to write the data 948 * @param[out] spec where to write the data
953 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error 949 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
954 */ 950 */
955static int 951static enum GNUNET_GenericReturnValue
956parse_boolean (void *cls, 952parse_boolean (void *cls,
957 json_t *root, 953 json_t *root,
958 struct GNUNET_JSON_Specification *spec) 954 struct GNUNET_JSON_Specification *spec)
diff --git a/src/json/json_pack.c b/src/json/json_pack.c
index 92f8b4535..296f56104 100644
--- a/src/json/json_pack.c
+++ b/src/json/json_pack.c
@@ -245,16 +245,16 @@ GNUNET_JSON_pack_data_varsize (const char *name,
245 245
246 246
247struct GNUNET_JSON_PackSpec 247struct GNUNET_JSON_PackSpec
248GNUNET_JSON_pack_time_abs (const char *name, 248GNUNET_JSON_pack_timestamp (const char *name,
249 struct GNUNET_TIME_Absolute at) 249 struct GNUNET_TIME_Timestamp t)
250{ 250{
251 struct GNUNET_JSON_PackSpec ps = { 251 struct GNUNET_JSON_PackSpec ps = {
252 .field_name = name 252 .field_name = name
253 }; 253 };
254 254
255 if (0 != at.abs_value_us) 255 if (! GNUNET_TIME_absolute_is_zero (t.abs_time))
256 { 256 {
257 ps.object = GNUNET_JSON_from_time_abs (at); 257 ps.object = GNUNET_JSON_from_timestamp (t);
258 GNUNET_assert (NULL != ps.object); 258 GNUNET_assert (NULL != ps.object);
259 } 259 }
260 else 260 else
@@ -266,11 +266,11 @@ GNUNET_JSON_pack_time_abs (const char *name,
266 266
267 267
268struct GNUNET_JSON_PackSpec 268struct GNUNET_JSON_PackSpec
269GNUNET_JSON_pack_time_abs_nbo (const char *name, 269GNUNET_JSON_pack_timestamp_nbo (const char *name,
270 struct GNUNET_TIME_AbsoluteNBO at) 270 struct GNUNET_TIME_TimestampNBO at)
271{ 271{
272 return GNUNET_JSON_pack_time_abs (name, 272 return GNUNET_JSON_pack_timestamp (name,
273 GNUNET_TIME_absolute_ntoh (at)); 273 GNUNET_TIME_timestamp_ntoh (at));
274} 274}
275 275
276 276
diff --git a/src/json/test_json.c b/src/json/test_json.c
index 4485a37a4..7e9025b5b 100644
--- a/src/json/test_json.c
+++ b/src/json/test_json.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 (C) 2015, 2016 GNUnet e.V. 3 (C) 2015, 2016, 2021 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -34,33 +34,45 @@
34 * @return 0 on success 34 * @return 0 on success
35 */ 35 */
36static int 36static int
37test_abs_time () 37test_timestamp (void)
38{ 38{
39 json_t *j; 39 json_t *j;
40 struct GNUNET_TIME_Absolute a1; 40 struct GNUNET_TIME_Absolute a1;
41 struct GNUNET_TIME_Absolute a2; 41 struct GNUNET_TIME_Timestamp t1;
42 struct GNUNET_JSON_Specification s1[] = { GNUNET_JSON_spec_absolute_time ( 42 struct GNUNET_TIME_Timestamp t2;
43 NULL, 43 struct GNUNET_JSON_Specification s1[] = {
44 &a2), 44 GNUNET_JSON_spec_timestamp (NULL,
45 GNUNET_JSON_spec_end () }; 45 &t2),
46 struct GNUNET_JSON_Specification s2[] = { GNUNET_JSON_spec_absolute_time ( 46 GNUNET_JSON_spec_end ()
47 NULL, 47 };
48 &a2), 48 struct GNUNET_JSON_Specification s2[] = {
49 GNUNET_JSON_spec_end () }; 49 GNUNET_JSON_spec_timestamp (NULL,
50 &t2),
51 GNUNET_JSON_spec_end ()
52 };
50 53
51 a1 = GNUNET_TIME_absolute_get (); 54 a1 = GNUNET_TIME_absolute_get ();
52 GNUNET_TIME_round_abs (&a1); 55 GNUNET_TIME_absolute_to_timestamp (a1,
53 j = GNUNET_JSON_from_time_abs (a1); 56 &t1);
57 j = GNUNET_JSON_from_timestamp (t1);
54 GNUNET_assert (NULL != j); 58 GNUNET_assert (NULL != j);
55 GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (j, s1, NULL, NULL)); 59 GNUNET_assert (GNUNET_OK ==
56 GNUNET_assert (a1.abs_value_us == a2.abs_value_us); 60 GNUNET_JSON_parse (j,
61 s1,
62 NULL,
63 NULL));
64 GNUNET_assert (GNUNET_TIME_timestamp_cmp (t1, ==, t2));
57 json_decref (j); 65 json_decref (j);
58 66
59 a1 = GNUNET_TIME_UNIT_FOREVER_ABS; 67 a1 = GNUNET_TIME_UNIT_FOREVER_ABS;
60 j = GNUNET_JSON_from_time_abs (a1); 68 j = GNUNET_JSON_from_timestamp (t1);
61 GNUNET_assert (NULL != j); 69 GNUNET_assert (NULL != j);
62 GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (j, s2, NULL, NULL)); 70 GNUNET_assert (GNUNET_OK ==
63 GNUNET_assert (a1.abs_value_us == a2.abs_value_us); 71 GNUNET_JSON_parse (j,
72 s2,
73 NULL,
74 NULL));
75 GNUNET_assert (GNUNET_TIME_timestamp_cmp (t1, ==, t2));
64 json_decref (j); 76 json_decref (j);
65 return 0; 77 return 0;
66} 78}
@@ -72,19 +84,21 @@ test_abs_time ()
72 * @return 0 on success 84 * @return 0 on success
73 */ 85 */
74static int 86static int
75test_rel_time () 87test_rel_time (void)
76{ 88{
77 json_t *j; 89 json_t *j;
78 struct GNUNET_TIME_Relative r1; 90 struct GNUNET_TIME_Relative r1;
79 struct GNUNET_TIME_Relative r2; 91 struct GNUNET_TIME_Relative r2;
80 struct GNUNET_JSON_Specification s1[] = { GNUNET_JSON_spec_relative_time ( 92 struct GNUNET_JSON_Specification s1[] = {
81 NULL, 93 GNUNET_JSON_spec_relative_time (NULL,
82 &r2), 94 &r2),
83 GNUNET_JSON_spec_end () }; 95 GNUNET_JSON_spec_end ()
84 struct GNUNET_JSON_Specification s2[] = { GNUNET_JSON_spec_relative_time ( 96 };
85 NULL, 97 struct GNUNET_JSON_Specification s2[] = {
86 &r2), 98 GNUNET_JSON_spec_relative_time (NULL,
87 GNUNET_JSON_spec_end () }; 99 &r2),
100 GNUNET_JSON_spec_end ()
101 };
88 102
89 r1 = GNUNET_TIME_UNIT_SECONDS; 103 r1 = GNUNET_TIME_UNIT_SECONDS;
90 j = GNUNET_JSON_from_time_rel (r1); 104 j = GNUNET_JSON_from_time_rel (r1);
@@ -211,7 +225,7 @@ int
211main (int argc, const char *const argv[]) 225main (int argc, const char *const argv[])
212{ 226{
213 GNUNET_log_setup ("test-json", "WARNING", NULL); 227 GNUNET_log_setup ("test-json", "WARNING", NULL);
214 if (0 != test_abs_time ()) 228 if (0 != test_timestamp ())
215 return 1; 229 return 1;
216 if (0 != test_rel_time ()) 230 if (0 != test_rel_time ())
217 return 1; 231 return 1;
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
index 78c324512..f5b4f38a2 100644
--- a/src/pq/pq_query_helper.c
+++ b/src/pq/pq_query_helper.c
@@ -70,7 +70,8 @@ struct GNUNET_PQ_QueryParam
70GNUNET_PQ_query_param_null (void) 70GNUNET_PQ_query_param_null (void)
71{ 71{
72 struct GNUNET_PQ_QueryParam res = { 72 struct GNUNET_PQ_QueryParam res = {
73 &qconv_null, NULL, NULL, 0, 1 73 .conv = &qconv_null,
74 .num_params = 1
74 }; 75 };
75 76
76 return res; 77 return res;
@@ -192,7 +193,10 @@ struct GNUNET_PQ_QueryParam
192GNUNET_PQ_query_param_uint16 (const uint16_t *x) 193GNUNET_PQ_query_param_uint16 (const uint16_t *x)
193{ 194{
194 struct GNUNET_PQ_QueryParam res = { 195 struct GNUNET_PQ_QueryParam res = {
195 &qconv_uint16, NULL, x, sizeof(*x), 1 196 .conv = &qconv_uint16,
197 .data = x,
198 .size = sizeof(*x),
199 .num_params = 1
196 }; 200 };
197 201
198 return res; 202 return res;
@@ -246,7 +250,10 @@ struct GNUNET_PQ_QueryParam
246GNUNET_PQ_query_param_uint32 (const uint32_t *x) 250GNUNET_PQ_query_param_uint32 (const uint32_t *x)
247{ 251{
248 struct GNUNET_PQ_QueryParam res = { 252 struct GNUNET_PQ_QueryParam res = {
249 &qconv_uint32, NULL, x, sizeof(*x), 1 253 .conv = &qconv_uint32,
254 .data = x,
255 .size = sizeof(*x),
256 .num_params = 1
250 }; 257 };
251 258
252 return res; 259 return res;
@@ -300,7 +307,10 @@ struct GNUNET_PQ_QueryParam
300GNUNET_PQ_query_param_uint64 (const uint64_t *x) 307GNUNET_PQ_query_param_uint64 (const uint64_t *x)
301{ 308{
302 struct GNUNET_PQ_QueryParam res = { 309 struct GNUNET_PQ_QueryParam res = {
303 &qconv_uint64, NULL, x, sizeof(*x), 1 310 .conv = &qconv_uint64,
311 .data = x,
312 .size = sizeof(*x),
313 .num_params = 1
304 }; 314 };
305 315
306 return res; 316 return res;
@@ -350,11 +360,13 @@ qconv_rsa_public_key (void *cls,
350 360
351 361
352struct GNUNET_PQ_QueryParam 362struct GNUNET_PQ_QueryParam
353GNUNET_PQ_query_param_rsa_public_key (const struct 363GNUNET_PQ_query_param_rsa_public_key (
354 GNUNET_CRYPTO_RsaPublicKey *x) 364 const struct GNUNET_CRYPTO_RsaPublicKey *x)
355{ 365{
356 struct GNUNET_PQ_QueryParam res = { 366 struct GNUNET_PQ_QueryParam res = {
357 &qconv_rsa_public_key, NULL, (x), 0, 1 367 .conv = &qconv_rsa_public_key,
368 .data = x,
369 .num_params = 1
358 }; 370 };
359 371
360 return res; 372 return res;
@@ -407,7 +419,9 @@ struct GNUNET_PQ_QueryParam
407GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) 419GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x)
408{ 420{
409 struct GNUNET_PQ_QueryParam res = { 421 struct GNUNET_PQ_QueryParam res = {
410 &qconv_rsa_signature, NULL, (x), 0, 1 422 .conv = &qconv_rsa_signature,
423 .data = x,
424 .num_params = 1
411 }; 425 };
412 426
413 return res; 427 return res;
@@ -463,7 +477,10 @@ struct GNUNET_PQ_QueryParam
463GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x) 477GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x)
464{ 478{
465 struct GNUNET_PQ_QueryParam res = { 479 struct GNUNET_PQ_QueryParam res = {
466 &qconv_rel_time, NULL, x, sizeof(*x), 1 480 .conv = &qconv_rel_time,
481 .data = x,
482 .size = sizeof(*x),
483 .num_params = 1
467 }; 484 };
468 485
469 return res; 486 return res;
@@ -519,7 +536,10 @@ struct GNUNET_PQ_QueryParam
519GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) 536GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x)
520{ 537{
521 struct GNUNET_PQ_QueryParam res = { 538 struct GNUNET_PQ_QueryParam res = {
522 &qconv_abs_time, NULL, x, sizeof(*x), 1 539 .conv = &qconv_abs_time,
540 .data = x,
541 .size = sizeof(*x),
542 .num_params = 1
523 }; 543 };
524 544
525 return res; 545 return res;
@@ -534,4 +554,71 @@ GNUNET_PQ_query_param_absolute_time_nbo (
534} 554}
535 555
536 556
557/**
558 * Function called to convert input argument into SQL parameters.
559 *
560 * @param cls closure
561 * @param data pointer to input argument
562 * @param data_len number of bytes in @a data (if applicable)
563 * @param[out] param_values SQL data to set
564 * @param[out] param_lengths SQL length data to set
565 * @param[out] param_formats SQL format data to set
566 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
567 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
568 * @param scratch_length number of entries left in @a scratch
569 * @return -1 on error, number of offsets used in @a scratch otherwise
570 */
571static int
572qconv_timestamp (void *cls,
573 const void *data,
574 size_t data_len,
575 void *param_values[],
576 int param_lengths[],
577 int param_formats[],
578 unsigned int param_length,
579 void *scratch[],
580 unsigned int scratch_length)
581{
582 const struct GNUNET_TIME_Timestamp *u = data;
583 struct GNUNET_TIME_Absolute abs;
584 uint64_t *u_nbo;
585
586 GNUNET_break (NULL == cls);
587 if (1 != param_length)
588 return -1;
589 abs = u->abs_time;
590 if (abs.abs_value_us > INT64_MAX)
591 abs.abs_value_us = INT64_MAX;
592 u_nbo = GNUNET_new (uint64_t);
593 scratch[0] = u_nbo;
594 *u_nbo = GNUNET_htonll (abs.abs_value_us);
595 param_values[0] = (void *) u_nbo;
596 param_lengths[0] = sizeof(uint64_t);
597 param_formats[0] = 1;
598 return 1;
599}
600
601
602struct GNUNET_PQ_QueryParam
603GNUNET_PQ_query_param_timestamp (const struct GNUNET_TIME_Timestamp *x)
604{
605 struct GNUNET_PQ_QueryParam res = {
606 .conv = &qconv_timestamp,
607 .data = x,
608 .size = sizeof(*x),
609 .num_params = 1
610 };
611
612 return res;
613}
614
615
616struct GNUNET_PQ_QueryParam
617GNUNET_PQ_query_param_timestamp_nbo (
618 const struct GNUNET_TIME_TimestampNBO *x)
619{
620 return GNUNET_PQ_query_param_absolute_time_nbo (&x->abs_time_nbo);
621}
622
623
537/* end of pq_query_helper.c */ 624/* end of pq_query_helper.c */
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c
index 4057772ec..be7c85ce9 100644
--- a/src/pq/pq_result_helper.c
+++ b/src/pq/pq_result_helper.c
@@ -757,6 +757,148 @@ GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
757 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) 757 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
758 */ 758 */
759static enum GNUNET_GenericReturnValue 759static enum GNUNET_GenericReturnValue
760extract_timestamp (void *cls,
761 PGresult *result,
762 int row,
763 const char *fname,
764 size_t *dst_size,
765 void *dst)
766{
767 struct GNUNET_TIME_Timestamp *udst = dst;
768 struct GNUNET_TIME_Absolute abs;
769 const int64_t *res;
770 int fnum;
771
772 (void) cls;
773 fnum = PQfnumber (result,
774 fname);
775 if (fnum < 0)
776 {
777 GNUNET_break (0);
778 return GNUNET_SYSERR;
779 }
780 if (PQgetisnull (result,
781 row,
782 fnum))
783 return GNUNET_NO;
784 GNUNET_assert (NULL != dst);
785 if (sizeof(struct GNUNET_TIME_Absolute) != *dst_size)
786 {
787 GNUNET_break (0);
788 return GNUNET_SYSERR;
789 }
790 if (sizeof(int64_t) !=
791 PQgetlength (result,
792 row,
793 fnum))
794 {
795 GNUNET_break (0);
796 return GNUNET_SYSERR;
797 }
798 res = (int64_t *) PQgetvalue (result,
799 row,
800 fnum);
801 if (INT64_MAX == GNUNET_ntohll ((uint64_t) *res))
802 {
803 abs = GNUNET_TIME_UNIT_FOREVER_ABS;
804 }
805 else
806 {
807 abs.abs_value_us = GNUNET_ntohll ((uint64_t) *res);
808 if (0 != abs.abs_value_us % GNUNET_TIME_UNIT_SECONDS.rel_value_us)
809 {
810 /* timestamps must be multiple of seconds! */
811 GNUNET_break (0);
812 return GNUNET_SYSERR;
813 }
814 }
815 udst->abs_time = abs;
816 return GNUNET_OK;
817}
818
819
820struct GNUNET_PQ_ResultSpec
821GNUNET_PQ_result_spec_timestamp (const char *name,
822 struct GNUNET_TIME_Timestamp *at)
823{
824 struct GNUNET_PQ_ResultSpec res = {
825 .conv = &extract_timestamp,
826 .dst = (void *) at,
827 .dst_size = sizeof(*at),
828 .fname = name
829 };
830
831 return res;
832}
833
834
835/**
836 * Extract data from a Postgres database @a result at row @a row.
837 *
838 * @param cls closure
839 * @param result where to extract data from
840 * @param int row to extract data from
841 * @param fname name (or prefix) of the fields to extract from
842 * @param[in,out] dst_size where to store size of result, may be NULL
843 * @param[out] dst where to store the result
844 * @return
845 * #GNUNET_YES if all results could be extracted
846 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
847 */
848static enum GNUNET_GenericReturnValue
849extract_timestamp_nbo (void *cls,
850 PGresult *result,
851 int row,
852 const char *fname,
853 size_t *dst_size,
854 void *dst)
855{
856 struct GNUNET_TIME_TimestampNBO *udst = dst;
857 struct GNUNET_TIME_Timestamp t;
858 enum GNUNET_GenericReturnValue r;
859
860 r = extract_timestamp (&t,
861 result,
862 row,
863 fname,
864 dst_size,
865 dst);
866 if (GNUNET_OK != r)
867 return r;
868 *udst = GNUNET_TIME_timestamp_hton (t);
869 return r;
870}
871
872
873struct GNUNET_PQ_ResultSpec
874GNUNET_PQ_result_spec_timestamp_nbo (const char *name,
875 struct GNUNET_TIME_TimestampNBO *at)
876{
877 struct GNUNET_PQ_ResultSpec res = {
878 .conv = &extract_timestamp_nbo,
879 .dst = (void *) at,
880 .dst_size = sizeof(*at),
881 .fname = name
882 };
883
884 return res;
885}
886
887
888/**
889 * Extract data from a Postgres database @a result at row @a row.
890 *
891 * @param cls closure
892 * @param result where to extract data from
893 * @param int row to extract data from
894 * @param fname name (or prefix) of the fields to extract from
895 * @param[in,out] dst_size where to store size of result, may be NULL
896 * @param[out] dst where to store the result
897 * @return
898 * #GNUNET_YES if all results could be extracted
899 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
900 */
901static enum GNUNET_GenericReturnValue
760extract_uint16 (void *cls, 902extract_uint16 (void *cls,
761 PGresult *result, 903 PGresult *result,
762 int row, 904 int row,
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 9fda40f51..406d42b1e 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -144,7 +144,7 @@ libgnunetutil_la_LIBADD = \
144 144
145libgnunetutil_la_LDFLAGS = \ 145libgnunetutil_la_LDFLAGS = \
146 $(GN_LIB_LDFLAGS) \ 146 $(GN_LIB_LDFLAGS) \
147 -version-info 14:0:0 147 -version-info 15:0:0
148 148
149GNUNET_ECC = gnunet-ecc 149GNUNET_ECC = gnunet-ecc
150GNUNET_SCRYPT = gnunet-scrypt 150GNUNET_SCRYPT = gnunet-scrypt
diff --git a/src/util/getopt_helpers.c b/src/util/getopt_helpers.c
index 592875531..917aa440b 100644
--- a/src/util/getopt_helpers.c
+++ b/src/util/getopt_helpers.c
@@ -38,7 +38,7 @@
38 * @param value not used (NULL) 38 * @param value not used (NULL)
39 * @return #GNUNET_NO (do not continue, not an error) 39 * @return #GNUNET_NO (do not continue, not an error)
40 */ 40 */
41static int 41static enum GNUNET_GenericReturnValue
42print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 42print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
43 void *scls, 43 void *scls,
44 const char *option, 44 const char *option,
@@ -53,12 +53,6 @@ print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
53} 53}
54 54
55 55
56/**
57 * Define the option to print the version of
58 * the application (-v option)
59 *
60 * @param version string with the version number
61 */
62struct GNUNET_GETOPT_CommandLineOption 56struct GNUNET_GETOPT_CommandLineOption
63GNUNET_GETOPT_option_version (const char *version) 57GNUNET_GETOPT_option_version (const char *version)
64{ 58{
@@ -90,7 +84,7 @@ GNUNET_GETOPT_option_version (const char *version)
90 * @param value not used (NULL) 84 * @param value not used (NULL)
91 * @return #GNUNET_NO (do not continue, not an error) 85 * @return #GNUNET_NO (do not continue, not an error)
92 */ 86 */
93static int 87static enum GNUNET_GenericReturnValue
94format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 88format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
95 void *scls, 89 void *scls,
96 const char *option, 90 const char *option,
@@ -192,12 +186,6 @@ OUTER:
192} 186}
193 187
194 188
195/**
196 * Defining the option to print the command line
197 * help text (-h option).
198 *
199 * @param about string with brief description of the application
200 */
201struct GNUNET_GETOPT_CommandLineOption 189struct GNUNET_GETOPT_CommandLineOption
202GNUNET_GETOPT_option_help (const char *about) 190GNUNET_GETOPT_option_help (const char *about)
203{ 191{
@@ -229,7 +217,7 @@ GNUNET_GETOPT_option_help (const char *about)
229 * @param value not used (NULL) 217 * @param value not used (NULL)
230 * @return #GNUNET_OK 218 * @return #GNUNET_OK
231 */ 219 */
232static int 220static enum GNUNET_GenericReturnValue
233increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 221increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
234 void *scls, 222 void *scls,
235 const char *option, 223 const char *option,
@@ -245,15 +233,6 @@ increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
245} 233}
246 234
247 235
248/**
249 * Increment @a val each time the option flag is given by one.
250 *
251 * @param shortName short name of the option
252 * @param name long name of the option
253 * @param argumentHelp help text for the option argument
254 * @param description long help text for the option
255 * @param[out] val increment by 1 each time the option is present
256 */
257struct GNUNET_GETOPT_CommandLineOption 236struct GNUNET_GETOPT_CommandLineOption
258GNUNET_GETOPT_option_increment_uint (char shortName, 237GNUNET_GETOPT_option_increment_uint (char shortName,
259 const char *name, 238 const char *name,
@@ -272,12 +251,6 @@ GNUNET_GETOPT_option_increment_uint (char shortName,
272} 251}
273 252
274 253
275/**
276 * Define the '-V' verbosity option. Using the option more
277 * than once increments @a level each time.
278 *
279 * @param[out] level set to the verbosity level
280 */
281struct GNUNET_GETOPT_CommandLineOption 254struct GNUNET_GETOPT_CommandLineOption
282GNUNET_GETOPT_option_verbose (unsigned int *level) 255GNUNET_GETOPT_option_verbose (unsigned int *level)
283{ 256{
@@ -308,7 +281,7 @@ GNUNET_GETOPT_option_verbose (unsigned int *level)
308 * @param value not used (NULL) 281 * @param value not used (NULL)
309 * @return #GNUNET_OK 282 * @return #GNUNET_OK
310 */ 283 */
311static int 284static enum GNUNET_GenericReturnValue
312set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 285set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
313 void *scls, 286 void *scls,
314 const char *option, 287 const char *option,
@@ -324,16 +297,6 @@ set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
324} 297}
325 298
326 299
327/**
328 * Allow user to specify a flag (which internally means setting
329 * an integer to 1/#GNUNET_YES/#GNUNET_OK.
330 *
331 * @param shortName short name of the option
332 * @param name long name of the option
333 * @param argumentHelp help text for the option argument
334 * @param description long help text for the option
335 * @param[out] val set to 1 if the option is present
336 */
337struct GNUNET_GETOPT_CommandLineOption 300struct GNUNET_GETOPT_CommandLineOption
338GNUNET_GETOPT_option_flag (char shortName, 301GNUNET_GETOPT_option_flag (char shortName,
339 const char *name, 302 const char *name,
@@ -366,7 +329,7 @@ GNUNET_GETOPT_option_flag (char shortName,
366 * @param value actual value of the option (a string) 329 * @param value actual value of the option (a string)
367 * @return #GNUNET_OK 330 * @return #GNUNET_OK
368 */ 331 */
369static int 332static enum GNUNET_GenericReturnValue
370set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 333set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
371 void *scls, 334 void *scls,
372 const char *option, 335 const char *option,
@@ -383,15 +346,6 @@ set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
383} 346}
384 347
385 348
386/**
387 * Allow user to specify a string.
388 *
389 * @param shortName short name of the option
390 * @param name long name of the option
391 * @param argumentHelp help text for the option argument
392 * @param description long help text for the option
393 * @param[out] str set to the string
394 */
395struct GNUNET_GETOPT_CommandLineOption 349struct GNUNET_GETOPT_CommandLineOption
396GNUNET_GETOPT_option_string (char shortName, 350GNUNET_GETOPT_option_string (char shortName,
397 const char *name, 351 const char *name,
@@ -413,12 +367,6 @@ GNUNET_GETOPT_option_string (char shortName,
413} 367}
414 368
415 369
416/**
417 * Define the '-L' log level option. Note that we do not check
418 * that the log level is valid here.
419 *
420 * @param[out] level set to the log level
421 */
422struct GNUNET_GETOPT_CommandLineOption 370struct GNUNET_GETOPT_CommandLineOption
423GNUNET_GETOPT_option_loglevel (char **level) 371GNUNET_GETOPT_option_loglevel (char **level)
424{ 372{
@@ -447,7 +395,7 @@ GNUNET_GETOPT_option_loglevel (char **level)
447 * @param value actual value of the option (a string) 395 * @param value actual value of the option (a string)
448 * @return #GNUNET_OK 396 * @return #GNUNET_OK
449 */ 397 */
450static int 398static enum GNUNET_GenericReturnValue
451set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 399set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
452 void *scls, 400 void *scls,
453 const char *option, 401 const char *option,
@@ -464,15 +412,6 @@ set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
464} 412}
465 413
466 414
467/**
468 * Allow user to specify a filename (automatically path expanded).
469 *
470 * @param shortName short name of the option
471 * @param name long name of the option
472 * @param argumentHelp help text for the option argument
473 * @param description long help text for the option
474 * @param[out] str set to the string
475 */
476struct GNUNET_GETOPT_CommandLineOption 415struct GNUNET_GETOPT_CommandLineOption
477GNUNET_GETOPT_option_filename (char shortName, 416GNUNET_GETOPT_option_filename (char shortName,
478 const char *name, 417 const char *name,
@@ -494,11 +433,6 @@ GNUNET_GETOPT_option_filename (char shortName,
494} 433}
495 434
496 435
497/**
498 * Allow user to specify log file name (-l option)
499 *
500 * @param[out] logfn set to the name of the logfile
501 */
502struct GNUNET_GETOPT_CommandLineOption 436struct GNUNET_GETOPT_CommandLineOption
503GNUNET_GETOPT_option_logfile (char **logfn) 437GNUNET_GETOPT_option_logfile (char **logfn)
504{ 438{
@@ -517,11 +451,6 @@ GNUNET_GETOPT_option_logfile (char **logfn)
517} 451}
518 452
519 453
520/**
521 * Allow user to specify configuration file name (-c option)
522 *
523 * @param[out] fn set to the name of the configuration file
524 */
525struct GNUNET_GETOPT_CommandLineOption 454struct GNUNET_GETOPT_CommandLineOption
526GNUNET_GETOPT_option_cfgfile (char **fn) 455GNUNET_GETOPT_option_cfgfile (char **fn)
527{ 456{
@@ -552,7 +481,7 @@ GNUNET_GETOPT_option_cfgfile (char **fn)
552 * @param value actual value of the option as a string. 481 * @param value actual value of the option as a string.
553 * @return #GNUNET_OK if parsing the value worked 482 * @return #GNUNET_OK if parsing the value worked
554 */ 483 */
555static int 484static enum GNUNET_GenericReturnValue
556set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 485set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
557 void *scls, 486 void *scls,
558 const char *option, 487 const char *option,
@@ -573,15 +502,6 @@ set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
573} 502}
574 503
575 504
576/**
577 * Allow user to specify an `unsigned long long`
578 *
579 * @param shortName short name of the option
580 * @param name long name of the option
581 * @param argumentHelp help text for the option argument
582 * @param description long help text for the option
583 * @param[out] val set to the value specified at the command line
584 */
585struct GNUNET_GETOPT_CommandLineOption 505struct GNUNET_GETOPT_CommandLineOption
586GNUNET_GETOPT_option_ulong (char shortName, 506GNUNET_GETOPT_option_ulong (char shortName,
587 const char *name, 507 const char *name,
@@ -616,7 +536,7 @@ GNUNET_GETOPT_option_ulong (char shortName,
616 * @param value actual value of the option as a string. 536 * @param value actual value of the option as a string.
617 * @return #GNUNET_OK if parsing the value worked 537 * @return #GNUNET_OK if parsing the value worked
618 */ 538 */
619static int 539static enum GNUNET_GenericReturnValue
620set_timetravel_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 540set_timetravel_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
621 void *scls, 541 void *scls,
622 const char *option, 542 const char *option,
@@ -664,15 +584,6 @@ set_timetravel_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
664} 584}
665 585
666 586
667/**
668 * Allow user to specify a `long long` with an offset to add to the current
669 * system time to construct the time seen by the application. Used for
670 * debugging / testing.
671 *
672 * @param shortName short name of the option
673 * @param name long name of the option
674 * @param[out] val set to the time specified at the command line
675 */
676struct GNUNET_GETOPT_CommandLineOption 587struct GNUNET_GETOPT_CommandLineOption
677GNUNET_GETOPT_option_timetravel (char shortName, 588GNUNET_GETOPT_option_timetravel (char shortName,
678 const char *name) 589 const char *name)
@@ -684,8 +595,7 @@ GNUNET_GETOPT_option_timetravel (char shortName,
684 .description = _ ( 595 .description = _ (
685 "modify system time by given offset (for debugging/testing only)"), 596 "modify system time by given offset (for debugging/testing only)"),
686 .require_argument = 1, 597 .require_argument = 1,
687 .processor = 598 .processor = &set_timetravel_time
688 &set_timetravel_time
689 }; 599 };
690 600
691 return clo; 601 return clo;
@@ -705,7 +615,7 @@ GNUNET_GETOPT_option_timetravel (char shortName,
705 * @param value actual value of the option as a string. 615 * @param value actual value of the option as a string.
706 * @return #GNUNET_OK if parsing the value worked 616 * @return #GNUNET_OK if parsing the value worked
707 */ 617 */
708static int 618static enum GNUNET_GenericReturnValue
709set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 619set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
710 void *scls, 620 void *scls,
711 const char *option, 621 const char *option,
@@ -725,16 +635,6 @@ set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
725} 635}
726 636
727 637
728/**
729 * Allow user to specify a `struct GNUNET_TIME_Relative`
730 * (using human-readable "fancy" time).
731 *
732 * @param shortName short name of the option
733 * @param name long name of the option
734 * @param argumentHelp help text for the option argument
735 * @param description long help text for the option
736 * @param[out] val set to the time specified at the command line
737 */
738struct GNUNET_GETOPT_CommandLineOption 638struct GNUNET_GETOPT_CommandLineOption
739GNUNET_GETOPT_option_relative_time (char shortName, 639GNUNET_GETOPT_option_relative_time (char shortName,
740 const char *name, 640 const char *name,
@@ -748,8 +648,7 @@ GNUNET_GETOPT_option_relative_time (char shortName,
748 .argumentHelp = argumentHelp, 648 .argumentHelp = argumentHelp,
749 .description = description, 649 .description = description,
750 .require_argument = 1, 650 .require_argument = 1,
751 .processor = 651 .processor = &set_relative_time,
752 &set_relative_time,
753 .scls = (void *) val 652 .scls = (void *) val
754 }; 653 };
755 654
@@ -770,7 +669,7 @@ GNUNET_GETOPT_option_relative_time (char shortName,
770 * @param value actual value of the option as a string. 669 * @param value actual value of the option as a string.
771 * @return #GNUNET_OK if parsing the value worked 670 * @return #GNUNET_OK if parsing the value worked
772 */ 671 */
773static int 672static enum GNUNET_GenericReturnValue
774set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 673set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
775 void *scls, 674 void *scls,
776 const char *option, 675 const char *option,
@@ -790,16 +689,6 @@ set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
790} 689}
791 690
792 691
793/**
794 * Allow user to specify a `struct GNUNET_TIME_Absolute`
795 * (using human-readable "fancy" time).
796 *
797 * @param shortName short name of the option
798 * @param name long name of the option
799 * @param argumentHelp help text for the option argument
800 * @param description long help text for the option
801 * @param[out] val set to the time specified at the command line
802 */
803struct GNUNET_GETOPT_CommandLineOption 692struct GNUNET_GETOPT_CommandLineOption
804GNUNET_GETOPT_option_absolute_time (char shortName, 693GNUNET_GETOPT_option_absolute_time (char shortName,
805 const char *name, 694 const char *name,
@@ -813,8 +702,71 @@ GNUNET_GETOPT_option_absolute_time (char shortName,
813 .argumentHelp = argumentHelp, 702 .argumentHelp = argumentHelp,
814 .description = description, 703 .description = description,
815 .require_argument = 1, 704 .require_argument = 1,
816 .processor = 705 .processor = &set_absolute_time,
817 &set_absolute_time, 706 .scls = (void *) val
707 };
708
709 return clo;
710}
711
712
713/**
714 * Set an option of type 'struct GNUNET_TIME_Timestamp' from the command line.
715 * A pointer to this function should be passed as part of the
716 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
717 * of this type. It should be followed by a pointer to a value of
718 * type 'struct GNUNET_TIME_Absolute'.
719 *
720 * @param ctx command line processing context
721 * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
722 * @param option name of the option
723 * @param value actual value of the option as a string.
724 * @return #GNUNET_OK if parsing the value worked
725 */
726static enum GNUNET_GenericReturnValue
727set_timestamp (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
728 void *scls,
729 const char *option,
730 const char *value)
731{
732 struct GNUNET_TIME_Timestamp *t = scls;
733 struct GNUNET_TIME_Absolute abs;
734
735 (void) ctx;
736 if (GNUNET_OK !=
737 GNUNET_STRINGS_fancy_time_to_absolute (value,
738 &abs))
739 {
740 fprintf (stderr,
741 _ ("You must pass a timestamp to the `%s' option.\n"),
742 option);
743 return GNUNET_SYSERR;
744 }
745 if (0 != abs.abs_value_us % GNUNET_TIME_UNIT_SECONDS.rel_value_us)
746 {
747 fprintf (stderr,
748 _ ("The maximum precision allowed for timestamps is seconds.\n"));
749 return GNUNET_SYSERR;
750 }
751 t->abs_time = abs;
752 return GNUNET_OK;
753}
754
755
756struct GNUNET_GETOPT_CommandLineOption
757GNUNET_GETOPT_option_timestamp (char shortName,
758 const char *name,
759 const char *argumentHelp,
760 const char *description,
761 struct GNUNET_TIME_Timestamp *val)
762{
763 struct GNUNET_GETOPT_CommandLineOption clo = {
764 .shortName = shortName,
765 .name = name,
766 .argumentHelp = argumentHelp,
767 .description = description,
768 .require_argument = 1,
769 .processor = &set_timestamp,
818 .scls = (void *) val 770 .scls = (void *) val
819 }; 771 };
820 772
@@ -835,7 +787,7 @@ GNUNET_GETOPT_option_absolute_time (char shortName,
835 * @param value actual value of the option as a string. 787 * @param value actual value of the option as a string.
836 * @return #GNUNET_OK if parsing the value worked 788 * @return #GNUNET_OK if parsing the value worked
837 */ 789 */
838static int 790static enum GNUNET_GenericReturnValue
839set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 791set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
840 void *scls, 792 void *scls,
841 const char *option, 793 const char *option,
@@ -864,15 +816,6 @@ set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
864} 816}
865 817
866 818
867/**
868 * Allow user to specify an unsigned integer.
869 *
870 * @param shortName short name of the option
871 * @param name long name of the option
872 * @param argumentHelp help text for the option argument
873 * @param description long help text for the option
874 * @param[out] val set to the value specified at the command line
875 */
876struct GNUNET_GETOPT_CommandLineOption 819struct GNUNET_GETOPT_CommandLineOption
877GNUNET_GETOPT_option_uint (char shortName, 820GNUNET_GETOPT_option_uint (char shortName,
878 const char *name, 821 const char *name,
@@ -907,7 +850,7 @@ GNUNET_GETOPT_option_uint (char shortName,
907 * @param value actual value of the option as a string. 850 * @param value actual value of the option as a string.
908 * @return #GNUNET_OK if parsing the value worked 851 * @return #GNUNET_OK if parsing the value worked
909 */ 852 */
910static int 853static enum GNUNET_GenericReturnValue
911set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 854set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
912 void *scls, 855 void *scls,
913 const char *option, 856 const char *option,
@@ -938,15 +881,6 @@ set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
938} 881}
939 882
940 883
941/**
942 * Allow user to specify an uint16_t.
943 *
944 * @param shortName short name of the option
945 * @param name long name of the option
946 * @param argumentHelp help text for the option argument
947 * @param description long help text for the option
948 * @param[out] val set to the value specified at the command line
949 */
950struct GNUNET_GETOPT_CommandLineOption 884struct GNUNET_GETOPT_CommandLineOption
951GNUNET_GETOPT_option_uint16 (char shortName, 885GNUNET_GETOPT_option_uint16 (char shortName,
952 const char *name, 886 const char *name,
@@ -998,7 +932,7 @@ struct Base32Context
998 * @param value actual value of the option as a string. 932 * @param value actual value of the option as a string.
999 * @return #GNUNET_OK if parsing the value worked 933 * @return #GNUNET_OK if parsing the value worked
1000 */ 934 */
1001static int 935static enum GNUNET_GenericReturnValue
1002set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 936set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
1003 void *scls, 937 void *scls,
1004 const char *option, 938 const char *option,
@@ -1036,17 +970,6 @@ free_bc (void *cls)
1036} 970}
1037 971
1038 972
1039/**
1040 * Allow user to specify a binary value using Crockford
1041 * Base32 encoding.
1042 *
1043 * @param shortName short name of the option
1044 * @param name long name of the option
1045 * @param argumentHelp help text for the option argument
1046 * @param description long help text for the option
1047 * @param[out] val binary value decoded from Crockford Base32-encoded argument
1048 * @param val_size size of @a val in bytes
1049 */
1050struct GNUNET_GETOPT_CommandLineOption 973struct GNUNET_GETOPT_CommandLineOption
1051GNUNET_GETOPT_option_base32_fixed_size (char shortName, 974GNUNET_GETOPT_option_base32_fixed_size (char shortName,
1052 const char *name, 975 const char *name,
@@ -1073,12 +996,6 @@ GNUNET_GETOPT_option_base32_fixed_size (char shortName,
1073} 996}
1074 997
1075 998
1076/**
1077 * Make the given option mandatory.
1078 *
1079 * @param opt option to modify
1080 * @return @a opt with the mandatory flag set.
1081 */
1082struct GNUNET_GETOPT_CommandLineOption 999struct GNUNET_GETOPT_CommandLineOption
1083GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt) 1000GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
1084{ 1001{
@@ -1087,12 +1004,6 @@ GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
1087} 1004}
1088 1005
1089 1006
1090/**
1091 * Make the given option mutually exclusive with other options.
1092 *
1093 * @param opt option to modify
1094 * @return @a opt with the exclusive flag set.
1095 */
1096struct GNUNET_GETOPT_CommandLineOption 1007struct GNUNET_GETOPT_CommandLineOption
1097GNUNET_GETOPT_option_exclusive (struct GNUNET_GETOPT_CommandLineOption opt) 1008GNUNET_GETOPT_option_exclusive (struct GNUNET_GETOPT_CommandLineOption opt)
1098{ 1009{
diff --git a/src/util/strings.c b/src/util/strings.c
index 673915888..db672da87 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -201,7 +201,7 @@ struct ConversionTable
201 * @param output where to store the result 201 * @param output where to store the result
202 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 202 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
203 */ 203 */
204static int 204static enum GNUNET_GenericReturnValue
205convert_with_table (const char *input, 205convert_with_table (const char *input,
206 const struct ConversionTable *table, 206 const struct ConversionTable *table,
207 unsigned long long *output) 207 unsigned long long *output)
@@ -256,7 +256,7 @@ convert_with_table (const char *input,
256} 256}
257 257
258 258
259int 259enum GNUNET_GenericReturnValue
260GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, 260GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
261 unsigned long long *size) 261 unsigned long long *size)
262{ 262{
@@ -280,7 +280,7 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
280} 280}
281 281
282 282
283int 283enum GNUNET_GenericReturnValue
284GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, 284GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time,
285 struct GNUNET_TIME_Relative *rtime) 285 struct GNUNET_TIME_Relative *rtime)
286{ 286{
@@ -322,7 +322,7 @@ GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time,
322} 322}
323 323
324 324
325int 325enum GNUNET_GenericReturnValue
326GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, 326GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time,
327 struct GNUNET_TIME_Absolute *atime) 327 struct GNUNET_TIME_Absolute *atime)
328{ 328{
@@ -354,6 +354,15 @@ GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time,
354} 354}
355 355
356 356
357enum GNUNET_GenericReturnValue
358GNUNET_STRINGS_fancy_time_to_timestamp (const char *fancy_time,
359 struct GNUNET_TIME_Timestamp *atime)
360{
361 return GNUNET_STRINGS_fancy_time_to_absolute (fancy_time,
362 &atime->abs_time);
363}
364
365
357char * 366char *
358GNUNET_STRINGS_conv (const char *input, 367GNUNET_STRINGS_conv (const char *input,
359 size_t len, 368 size_t len,
@@ -607,7 +616,7 @@ GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t)
607 time_t tt; 616 time_t tt;
608 struct tm *tp; 617 struct tm *tp;
609 618
610 if (t.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) 619 if (GNUNET_TIME_absolute_is_never (t))
611 return "end of time"; 620 return "end of time";
612 tt = t.abs_value_us / 1000LL / 1000LL; 621 tt = t.abs_value_us / 1000LL / 1000LL;
613 tp = localtime (&tt); 622 tp = localtime (&tt);
@@ -616,7 +625,8 @@ GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t)
616 * As for msvcrt, use the wide variant, which always returns utf16 625 * As for msvcrt, use the wide variant, which always returns utf16
617 * (otherwise we'd have to detect current codepage or use W32API character 626 * (otherwise we'd have to detect current codepage or use W32API character
618 * set conversion routines to convert to UTF8). 627 * set conversion routines to convert to UTF8).
619 */strftime (buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", tp); 628 */
629 strftime (buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", tp);
620 630
621 return buf; 631 return buf;
622} 632}
diff --git a/src/util/time.c b/src/util/time.c
index 144e1b401..83b39b4e8 100644
--- a/src/util/time.c
+++ b/src/util/time.c
@@ -58,27 +58,35 @@ GNUNET_TIME_get_offset ()
58} 58}
59 59
60 60
61int 61struct GNUNET_TIME_Timestamp
62GNUNET_TIME_round_abs (struct GNUNET_TIME_Absolute *at) 62GNUNET_TIME_absolute_to_timestamp (struct GNUNET_TIME_Absolute at)
63{ 63{
64 if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) 64 struct GNUNET_TIME_Timestamp ts;
65 return GNUNET_OK; 65
66 if (0 == at->abs_value_us % 1000000) 66 if (GNUNET_TIME_absolute_is_never (at))
67 return GNUNET_OK; 67 return GNUNET_TIME_UNIT_FOREVER_TS;
68 at->abs_value_us -= at->abs_value_us % 1000000; 68 ts.abs_time.abs_value_us = at.abs_value_us - at.abs_value_us % 1000000;
69 return GNUNET_NO; 69 return ts;
70}
71
72
73struct GNUNET_TIME_TimestampNBO
74GNUNET_TIME_timestamp_hton (struct GNUNET_TIME_Timestamp t)
75{
76 struct GNUNET_TIME_TimestampNBO tn;
77
78 tn.abs_time_nbo = GNUNET_TIME_absolute_hton (t.abs_time);
79 return tn;
70} 80}
71 81
72 82
73int 83struct GNUNET_TIME_Timestamp
74GNUNET_TIME_round_rel (struct GNUNET_TIME_Relative *rt) 84GNUNET_TIME_timestamp_ntoh (struct GNUNET_TIME_TimestampNBO tn)
75{ 85{
76 if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) 86 struct GNUNET_TIME_Timestamp t;
77 return GNUNET_OK; 87
78 if (0 == rt->rel_value_us % 1000000) 88 t.abs_time = GNUNET_TIME_absolute_ntoh (tn.abs_time_nbo);
79 return GNUNET_OK; 89 return t;
80 rt->rel_value_us -= rt->rel_value_us % 1000000;
81 return GNUNET_NO;
82} 90}
83 91
84 92
@@ -96,6 +104,14 @@ GNUNET_TIME_absolute_get ()
96} 104}
97 105
98 106
107struct GNUNET_TIME_Timestamp
108GNUNET_TIME_timestamp_get ()
109{
110 return GNUNET_TIME_absolute_to_timestamp (
111 GNUNET_TIME_absolute_get ());
112}
113
114
99struct GNUNET_TIME_Relative 115struct GNUNET_TIME_Relative
100GNUNET_TIME_relative_get_zero_ () 116GNUNET_TIME_relative_get_zero_ ()
101{ 117{
@@ -177,12 +193,114 @@ GNUNET_TIME_absolute_get_forever_ ()
177} 193}
178 194
179 195
196const char *
197GNUNET_TIME_timestamp2s (struct GNUNET_TIME_Timestamp ts)
198{
199 static GNUNET_THREAD_LOCAL char buf[255];
200 time_t tt;
201 struct tm *tp;
202
203 if (GNUNET_TIME_absolute_is_never (ts.abs_time))
204 return "end of time";
205 tt = ts.abs_time.abs_value_us / 1000LL / 1000LL;
206 tp = localtime (&tt);
207 /* This is hacky, but i don't know a way to detect libc character encoding.
208 * Just expect utf8 from glibc these days.
209 * As for msvcrt, use the wide variant, which always returns utf16
210 * (otherwise we'd have to detect current codepage or use W32API character
211 * set conversion routines to convert to UTF8).
212 */
213 strftime (buf,
214 sizeof(buf),
215 "%a %b %d %H:%M:%S %Y",
216 tp);
217 return buf;
218}
219
220
221const char *
222GNUNET_TIME_absolute2s (struct GNUNET_TIME_Absolute t)
223{
224 static GNUNET_THREAD_LOCAL char buf[255];
225 time_t tt;
226 struct tm *tp;
227
228 if (GNUNET_TIME_absolute_is_never (t))
229 return "end of time";
230 tt = t.abs_value_us / 1000LL / 1000LL;
231 tp = localtime (&tt);
232 /* This is hacky, but i don't know a way to detect libc character encoding.
233 * Just expect utf8 from glibc these days.
234 * As for msvcrt, use the wide variant, which always returns utf16
235 * (otherwise we'd have to detect current codepage or use W32API character
236 * set conversion routines to convert to UTF8).
237 */
238 strftime (buf,
239 sizeof(buf),
240 "%a %b %d %H:%M:%S %Y",
241 tp);
242 return buf;
243}
244
245
246const char *
247GNUNET_TIME_relative2s (struct GNUNET_TIME_Relative delta,
248 bool do_round)
249{
250 static GNUNET_THREAD_LOCAL char buf[128];
251 const char *unit = /* time unit */ "µs";
252 uint64_t dval = delta.rel_value_us;
253
254 if (GNUNET_TIME_relative_is_forever (delta))
255 return "forever";
256 if (0 == delta.rel_value_us)
257 return "0 ms";
258 if ( ((GNUNET_YES == do_round) &&
259 (dval > 5 * 1000)) ||
260 (0 == (dval % 1000)))
261 {
262 dval = dval / 1000;
263 unit = /* time unit */ "ms";
264 if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000)))
265 {
266 dval = dval / 1000;
267 unit = /* time unit */ "s";
268 if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60)))
269 {
270 dval = dval / 60;
271 unit = /* time unit */ "m";
272 if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60)))
273 {
274 dval = dval / 60;
275 unit = /* time unit */ "h";
276 if (((GNUNET_YES == do_round) && (dval > 5 * 24)) ||
277 (0 == (dval % 24)))
278 {
279 dval = dval / 24;
280 if (1 == dval)
281 unit = /* time unit */ "day";
282 else
283 unit = /* time unit */ "days";
284 }
285 }
286 }
287 }
288 }
289 GNUNET_snprintf (buf,
290 sizeof(buf),
291 "%llu %s",
292 (unsigned long long) dval,
293 unit);
294 return buf;
295}
296
297
180struct GNUNET_TIME_Absolute 298struct GNUNET_TIME_Absolute
181GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel) 299GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
182{ 300{
183 struct GNUNET_TIME_Absolute ret; 301 struct GNUNET_TIME_Absolute ret;
184 302
185 if (rel.rel_value_us == UINT64_MAX) 303 if (GNUNET_TIME_relative_is_forever (rel))
186 return GNUNET_TIME_UNIT_FOREVER_ABS; 304 return GNUNET_TIME_UNIT_FOREVER_ABS;
187 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); 305 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
188 306
@@ -196,6 +314,14 @@ GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
196} 314}
197 315
198 316
317struct GNUNET_TIME_Timestamp
318GNUNET_TIME_relative_to_timestamp (struct GNUNET_TIME_Relative rel)
319{
320 return GNUNET_TIME_absolute_to_timestamp (
321 GNUNET_TIME_relative_to_absolute (rel));
322}
323
324
199struct GNUNET_TIME_Relative 325struct GNUNET_TIME_Relative
200GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1, 326GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1,
201 struct GNUNET_TIME_Relative t2) 327 struct GNUNET_TIME_Relative t2)
@@ -228,12 +354,28 @@ GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
228} 354}
229 355
230 356
357struct GNUNET_TIME_Timestamp
358GNUNET_TIME_timestamp_max (struct GNUNET_TIME_Timestamp t1,
359 struct GNUNET_TIME_Timestamp t2)
360{
361 return (t1.abs_time.abs_value_us > t2.abs_time.abs_value_us) ? t1 : t2;
362}
363
364
365struct GNUNET_TIME_Timestamp
366GNUNET_TIME_timestamp_min (struct GNUNET_TIME_Timestamp t1,
367 struct GNUNET_TIME_Timestamp t2)
368{
369 return (t1.abs_time.abs_value_us < t2.abs_time.abs_value_us) ? t1 : t2;
370}
371
372
231struct GNUNET_TIME_Relative 373struct GNUNET_TIME_Relative
232GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future) 374GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
233{ 375{
234 struct GNUNET_TIME_Relative ret; 376 struct GNUNET_TIME_Relative ret;
235 377
236 if (future.abs_value_us == UINT64_MAX) 378 if (GNUNET_TIME_absolute_is_never (future))
237 return GNUNET_TIME_UNIT_FOREVER_REL; 379 return GNUNET_TIME_UNIT_FOREVER_REL;
238 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); 380 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
239 381
@@ -250,7 +392,7 @@ GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
250{ 392{
251 struct GNUNET_TIME_Relative ret; 393 struct GNUNET_TIME_Relative ret;
252 394
253 if (end.abs_value_us == UINT64_MAX) 395 if (GNUNET_TIME_absolute_is_never (end))
254 return GNUNET_TIME_UNIT_FOREVER_REL; 396 return GNUNET_TIME_UNIT_FOREVER_REL;
255 if (end.abs_value_us < start.abs_value_us) 397 if (end.abs_value_us < start.abs_value_us)
256 return GNUNET_TIME_UNIT_ZERO; 398 return GNUNET_TIME_UNIT_ZERO;
@@ -279,8 +421,8 @@ GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
279{ 421{
280 struct GNUNET_TIME_Absolute ret; 422 struct GNUNET_TIME_Absolute ret;
281 423
282 if ((start.abs_value_us == UINT64_MAX) || 424 if (GNUNET_TIME_absolute_is_never (start) ||
283 (duration.rel_value_us == UINT64_MAX)) 425 GNUNET_TIME_relative_is_forever (duration))
284 return GNUNET_TIME_UNIT_FOREVER_ABS; 426 return GNUNET_TIME_UNIT_FOREVER_ABS;
285 if (start.abs_value_us + duration.rel_value_us < start.abs_value_us) 427 if (start.abs_value_us + duration.rel_value_us < start.abs_value_us)
286 { 428 {
@@ -300,7 +442,7 @@ GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start,
300 442
301 if (start.abs_value_us <= duration.rel_value_us) 443 if (start.abs_value_us <= duration.rel_value_us)
302 return GNUNET_TIME_UNIT_ZERO_ABS; 444 return GNUNET_TIME_UNIT_ZERO_ABS;
303 if (start.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) 445 if (GNUNET_TIME_absolute_is_never (start))
304 return GNUNET_TIME_UNIT_FOREVER_ABS; 446 return GNUNET_TIME_UNIT_FOREVER_ABS;
305 ret.abs_value_us = start.abs_value_us - duration.rel_value_us; 447 ret.abs_value_us = start.abs_value_us - duration.rel_value_us;
306 return ret; 448 return ret;
@@ -315,7 +457,7 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
315 457
316 if (0 == factor) 458 if (0 == factor)
317 return GNUNET_TIME_UNIT_ZERO; 459 return GNUNET_TIME_UNIT_ZERO;
318 if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) 460 if (GNUNET_TIME_relative_is_forever (rel))
319 return GNUNET_TIME_UNIT_FOREVER_REL; 461 return GNUNET_TIME_UNIT_FOREVER_REL;
320 ret.rel_value_us = rel.rel_value_us * factor; 462 ret.rel_value_us = rel.rel_value_us * factor;
321 if (ret.rel_value_us / factor != rel.rel_value_us) 463 if (ret.rel_value_us / factor != rel.rel_value_us)
@@ -328,7 +470,8 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
328 470
329 471
330struct GNUNET_TIME_Relative 472struct GNUNET_TIME_Relative
331relative_multiply_double (struct GNUNET_TIME_Relative rel, double factor) 473relative_multiply_double (struct GNUNET_TIME_Relative rel,
474 double factor)
332{ 475{
333 struct GNUNET_TIME_Relative out; 476 struct GNUNET_TIME_Relative out;
334 double m; 477 double m;
@@ -337,7 +480,7 @@ relative_multiply_double (struct GNUNET_TIME_Relative rel, double factor)
337 480
338 if (0 == factor) 481 if (0 == factor)
339 return GNUNET_TIME_UNIT_ZERO; 482 return GNUNET_TIME_UNIT_ZERO;
340 if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) 483 if (GNUNET_TIME_relative_is_forever (rel))
341 return GNUNET_TIME_UNIT_FOREVER_REL; 484 return GNUNET_TIME_UNIT_FOREVER_REL;
342 485
343 m = ((double) rel.rel_value_us) * factor; 486 m = ((double) rel.rel_value_us) * factor;
@@ -361,7 +504,7 @@ GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel,
361 504
362 if (0 == factor) 505 if (0 == factor)
363 return GNUNET_TIME_UNIT_ZERO; 506 return GNUNET_TIME_UNIT_ZERO;
364 if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) 507 if (GNUNET_TIME_relative_is_forever (rel))
365 return GNUNET_TIME_UNIT_FOREVER_REL; 508 return GNUNET_TIME_UNIT_FOREVER_REL;
366 ret.rel_value_us = rel.rel_value_us * factor; 509 ret.rel_value_us = rel.rel_value_us * factor;
367 if (ret.rel_value_us / factor != rel.rel_value_us) 510 if (ret.rel_value_us / factor != rel.rel_value_us)
@@ -379,7 +522,7 @@ GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
379 struct GNUNET_TIME_Relative ret; 522 struct GNUNET_TIME_Relative ret;
380 523
381 if ((0 == factor) || 524 if ((0 == factor) ||
382 (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)) 525 (GNUNET_TIME_relative_is_forever (rel)))
383 return GNUNET_TIME_UNIT_FOREVER_REL; 526 return GNUNET_TIME_UNIT_FOREVER_REL;
384 ret.rel_value_us = rel.rel_value_us / factor; 527 ret.rel_value_us = rel.rel_value_us / factor;
385 return ret; 528 return ret;
@@ -538,6 +681,20 @@ GNUNET_TIME_absolute_from_s (uint64_t s_after_epoch)
538} 681}
539 682
540 683
684struct GNUNET_TIME_Timestamp
685GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch)
686{
687 struct GNUNET_TIME_Timestamp ret;
688
689 ret.abs_time.abs_value_us
690 = GNUNET_TIME_UNIT_SECONDS.rel_value_us * s_after_epoch;
691 if (ret.abs_time.abs_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us
692 != s_after_epoch)
693 ret = GNUNET_TIME_UNIT_FOREVER_TS;
694 return ret;
695}
696
697
541struct GNUNET_TIME_Absolute 698struct GNUNET_TIME_Absolute
542GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a) 699GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
543{ 700{
@@ -645,6 +802,13 @@ GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt,
645} 802}
646 803
647 804
805bool
806GNUNET_TIME_absolute_is_zero (struct GNUNET_TIME_Absolute abs)
807{
808 return 0 == abs.abs_value_us;
809}
810
811
648struct GNUNET_TIME_Relative 812struct GNUNET_TIME_Relative
649GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r) 813GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r)
650{ 814{