diff options
author | Christian Grothoff <grothoff@gnunet.org> | 2021-07-24 22:05:46 +0200 |
---|---|---|
committer | Christian Grothoff <grothoff@gnunet.org> | 2021-07-24 22:06:04 +0200 |
commit | 31eae6bbe16302d2593b806ef3d2ac2ca9c2d8de (patch) | |
tree | eba886ebfd704f83f13ce1b50976e3bdca6b2449 | |
parent | ebd034f8139ee90336fd8e7e2f24f9c9d39c5e25 (diff) | |
download | gnunet-31eae6bbe16302d2593b806ef3d2ac2ca9c2d8de.tar.gz gnunet-31eae6bbe16302d2593b806ef3d2ac2ca9c2d8de.zip |
early draft for libgnunetpq event notification support
-rw-r--r-- | src/include/gnunet_common.h | 11 | ||||
-rw-r--r-- | src/include/gnunet_pq_lib.h | 168 | ||||
-rw-r--r-- | src/include/gnunet_strings_lib.h | 55 | ||||
-rw-r--r-- | src/json/json_helper.c | 28 | ||||
-rw-r--r-- | src/pq/Makefile.am | 2 | ||||
-rw-r--r-- | src/pq/pq.h | 20 | ||||
-rw-r--r-- | src/pq/pq_connect.c | 2 | ||||
-rw-r--r-- | src/pq/pq_event.c | 396 | ||||
-rw-r--r-- | src/util/strings.c | 467 |
9 files changed, 714 insertions, 435 deletions
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h index 1126deaf4..df1ccff26 100644 --- a/src/include/gnunet_common.h +++ b/src/include/gnunet_common.h | |||
@@ -435,11 +435,12 @@ enum GNUNET_ErrorType | |||
435 | * @param date when was the message logged? | 435 | * @param date when was the message logged? |
436 | * @param message what is the message | 436 | * @param message what is the message |
437 | */ | 437 | */ |
438 | typedef void (*GNUNET_Logger) (void *cls, | 438 | typedef void |
439 | enum GNUNET_ErrorType kind, | 439 | (*GNUNET_Logger) (void *cls, |
440 | const char *component, | 440 | enum GNUNET_ErrorType kind, |
441 | const char *date, | 441 | const char *component, |
442 | const char *message); | 442 | const char *date, |
443 | const char *message); | ||
443 | 444 | ||
444 | 445 | ||
445 | /** | 446 | /** |
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h index 2cecb9885..1f2915165 100644 --- a/src/include/gnunet_pq_lib.h +++ b/src/include/gnunet_pq_lib.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2016, 2017, 2020 GNUnet e.V. | 3 | Copyright (C) 2016, 2017, 2020, 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 |
@@ -853,6 +853,170 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db); | |||
853 | 853 | ||
854 | 854 | ||
855 | /** | 855 | /** |
856 | * Function called whenever the socket needed for | ||
857 | * notifications from postgres changes. | ||
858 | * | ||
859 | * @param cls closure | ||
860 | * @param fd socket to listen on, -1 for none | ||
861 | */ | ||
862 | typedef void | ||
863 | (*GNUNET_PQ_SocketCallback)(void *cls, | ||
864 | int fd); | ||
865 | |||
866 | |||
867 | /** | ||
868 | * Obtain the file descriptor to poll on for notifications. | ||
869 | * Useful if the GNUnet scheduler is NOT to be used for | ||
870 | * such notifications. | ||
871 | * | ||
872 | * @param db database handle | ||
873 | * @param sc function to call with the socket | ||
874 | * @param sc_cls closure for @a sc | ||
875 | */ | ||
876 | void | ||
877 | GNUNET_PQ_event_set_socket_callback (struct GNUNET_PQ_Context *db, | ||
878 | GNUNET_PQ_SocketCallback sc, | ||
879 | void *sc_cls); | ||
880 | |||
881 | |||
882 | /** | ||
883 | * Poll for database events now. Used if the event FD | ||
884 | * is ready and the application wants to trigger applicable | ||
885 | * events. | ||
886 | * Useful if the GNUnet scheduler is NOT to be used for | ||
887 | * such notifications. | ||
888 | * | ||
889 | * @param db database handle | ||
890 | */ | ||
891 | void | ||
892 | GNUNET_PQ_event_do_poll (struct GNUNET_PQ_Context *db); | ||
893 | |||
894 | |||
895 | /** | ||
896 | * Run poll event loop using the GNUnet scheduler. | ||
897 | * | ||
898 | * @param db database handle | ||
899 | */ | ||
900 | void | ||
901 | GNUNET_PQ_event_scheduler_start (struct GNUNET_PQ_Context *db); | ||
902 | |||
903 | |||
904 | /** | ||
905 | * Stop running poll event loop using the GNUnet scheduler. | ||
906 | * | ||
907 | * @param db database handle | ||
908 | */ | ||
909 | void | ||
910 | GNUNET_PQ_event_scheduler_stop (struct GNUNET_PQ_Context *db); | ||
911 | |||
912 | |||
913 | /** | ||
914 | * Handle for an active LISTENer to the database. | ||
915 | */ | ||
916 | struct GNUNET_PQ_EventHandler; | ||
917 | |||
918 | /** | ||
919 | * Function called on events received from Postgres. | ||
920 | * | ||
921 | * @param cls closure | ||
922 | * @param extra additional event data provided | ||
923 | * @param extra_size number of bytes in @a extra | ||
924 | */ | ||
925 | typedef void | ||
926 | (*GNUNET_PQ_EventCallback)(void *cls, | ||
927 | const void *extra, | ||
928 | size_t extra_size); | ||
929 | |||
930 | GNUNET_NETWORK_STRUCT_BEGIN | ||
931 | |||
932 | |||
933 | /** | ||
934 | * Header of a structure that describes an | ||
935 | * event channel we may subscribe to or notify on. | ||
936 | */ | ||
937 | struct GNUNET_PQ_EventHeaderP | ||
938 | { | ||
939 | /** | ||
940 | * The length of the struct (in bytes, including the length field itself), | ||
941 | * in big-endian format. | ||
942 | */ | ||
943 | uint16_t size GNUNET_PACKED; | ||
944 | |||
945 | /** | ||
946 | * The type of the message (GNUNET_PQ_EVENT_TYPE_XXXX), in big-endian format. | ||
947 | */ | ||
948 | uint16_t type GNUNET_PACKED; | ||
949 | |||
950 | }; | ||
951 | |||
952 | GNUNET_NETWORK_STRUCT_END | ||
953 | |||
954 | |||
955 | /** | ||
956 | * Handle for an active LISTENer to the database. | ||
957 | */ | ||
958 | struct GNUNET_PQ_EventHandler; | ||
959 | |||
960 | /** | ||
961 | * Register callback to be invoked on events of type @a es. | ||
962 | * | ||
963 | * Unlike many other calls, this function is thread-safe | ||
964 | * and may be called from threads that are different | ||
965 | * from the one that setup @a db. However, the @a cb | ||
966 | * will always be called from the thread that runs | ||
967 | * #GNUNET_PQ_event_do_poll() or the GNUnet scheduler. | ||
968 | * | ||
969 | * @param db database context to use | ||
970 | * @param es specification of the event to listen for | ||
971 | * @param cb function to call when the event happens, possibly | ||
972 | * multiple times (until #GNUNET_PQ_event_listen_cancel() is invoked) | ||
973 | * @param cb_cls closure for @a cb | ||
974 | * @return handle useful to cancel the listener | ||
975 | */ | ||
976 | struct GNUNET_PQ_EventHandler * | ||
977 | GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db, | ||
978 | const struct GNUNET_PQ_EventHeaderP *es, | ||
979 | GNUNET_PQ_EventCallback cb, | ||
980 | void *cb_cls); | ||
981 | |||
982 | |||
983 | /** | ||
984 | * Stop notifications. | ||
985 | * | ||
986 | * Unlike many other calls, this function is thread-safe | ||
987 | * and may be called from threads that are different | ||
988 | * from the one that setup @a db. However, the @a cb | ||
989 | * will always be called from the thread that runs | ||
990 | * #GNUNET_PQ_event_do_poll() or the GNUnet scheduler. | ||
991 | * | ||
992 | * @param eh handle to unregister. | ||
993 | */ | ||
994 | void | ||
995 | GNUNET_PQ_event_listen_cancel (struct GNUNET_PQ_EventHandler *eh); | ||
996 | |||
997 | |||
998 | /** | ||
999 | * Notify all that listen on @a es of an event. | ||
1000 | * | ||
1001 | * Unlike many other calls, this function is thread-safe | ||
1002 | * and may be called from threads that are different | ||
1003 | * from the one that setup @a db. However, the @a cb | ||
1004 | * will always be called from the thread that runs | ||
1005 | * #GNUNET_PQ_event_do_poll() or the GNUnet scheduler. | ||
1006 | * | ||
1007 | * @param db database context to use | ||
1008 | * @param es specification of the event to generate | ||
1009 | * @param extra additional event data provided | ||
1010 | * @param extra_size number of bytes in @a extra | ||
1011 | */ | ||
1012 | void | ||
1013 | GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db, | ||
1014 | const struct GNUNET_PQ_EventHeaderP *es, | ||
1015 | const void *extra, | ||
1016 | size_t extra_size); | ||
1017 | |||
1018 | |||
1019 | /** | ||
856 | * Within the @a db context, run all the SQL files | 1020 | * Within the @a db context, run all the SQL files |
857 | * from the @a load_path from 0000-9999.sql (as long | 1021 | * from the @a load_path from 0000-9999.sql (as long |
858 | * as the files exist contiguously). | 1022 | * as the files exist contiguously). |
@@ -861,7 +1025,7 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db); | |||
861 | * @param load_path where to find the XXXX.sql files | 1025 | * @param load_path where to find the XXXX.sql files |
862 | * @return #GNUNET_OK on success | 1026 | * @return #GNUNET_OK on success |
863 | */ | 1027 | */ |
864 | int | 1028 | enum GNUNET_GenericReturnValue |
865 | GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, | 1029 | GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, |
866 | const char *load_path); | 1030 | const char *load_path); |
867 | 1031 | ||
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h index 955a3afca..977c2ead7 100644 --- a/src/include/gnunet_strings_lib.h +++ b/src/include/gnunet_strings_lib.h | |||
@@ -327,7 +327,7 @@ GNUNET_STRINGS_data_to_string_alloc (const void *buf, | |||
327 | * @param out_size size of the output buffer @a out | 327 | * @param out_size size of the output buffer @a out |
328 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding | 328 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding |
329 | */ | 329 | */ |
330 | int | 330 | enum GNUNET_GenericReturnValue |
331 | GNUNET_STRINGS_string_to_data (const char *enc, | 331 | GNUNET_STRINGS_string_to_data (const char *enc, |
332 | size_t enclen, | 332 | size_t enclen, |
333 | void *out, | 333 | void *out, |
@@ -335,6 +335,24 @@ GNUNET_STRINGS_string_to_data (const char *enc, | |||
335 | 335 | ||
336 | 336 | ||
337 | /** | 337 | /** |
338 | * Convert CrockfordBase32 encoding back to data. | ||
339 | * @a out_size will be determined from @a enc and | ||
340 | * @a out will be allocated to be large enough. | ||
341 | * | ||
342 | * @param enc the encoding | ||
343 | * @param enclen number of characters in @a enc (without 0-terminator, which can be missing) | ||
344 | * @param[out] out location where to allocate and store the decoded data | ||
345 | * @param[out] out_size set to the size of the output buffer @a out | ||
346 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding | ||
347 | */ | ||
348 | enum GNUNET_GenericReturnValue | ||
349 | GNUNET_STRINGS_string_to_data_alloc (const char *enc, | ||
350 | size_t enclen, | ||
351 | void **out, | ||
352 | size_t *out_size); | ||
353 | |||
354 | |||
355 | /** | ||
338 | * Encode into Base64. | 356 | * Encode into Base64. |
339 | * | 357 | * |
340 | * @param data the data to encode | 358 | * @param data the data to encode |
@@ -359,7 +377,10 @@ GNUNET_STRINGS_base64_encode (const void *in, | |||
359 | * @return the size of the output | 377 | * @return the size of the output |
360 | */ | 378 | */ |
361 | size_t | 379 | size_t |
362 | GNUNET_STRINGS_urlencode (const char *data, size_t len, char **out); | 380 | GNUNET_STRINGS_urlencode (const char *data, |
381 | size_t len, | ||
382 | char **out); | ||
383 | |||
363 | 384 | ||
364 | /** | 385 | /** |
365 | * Encode into Base64url. RFC7515 | 386 | * Encode into Base64url. RFC7515 |
@@ -371,7 +392,9 @@ GNUNET_STRINGS_urlencode (const char *data, size_t len, char **out); | |||
371 | * @return the size of the output | 392 | * @return the size of the output |
372 | */ | 393 | */ |
373 | size_t | 394 | size_t |
374 | GNUNET_STRINGS_base64url_encode (const void *in, size_t len, char **output); | 395 | GNUNET_STRINGS_base64url_encode (const void *in, |
396 | size_t len, | ||
397 | char **output); | ||
375 | 398 | ||
376 | 399 | ||
377 | /** | 400 | /** |
@@ -399,7 +422,9 @@ GNUNET_STRINGS_base64_decode (const char *data, | |||
399 | * @return the size of the output | 422 | * @return the size of the output |
400 | */ | 423 | */ |
401 | size_t | 424 | size_t |
402 | GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out); | 425 | GNUNET_STRINGS_base64url_decode (const char *data, |
426 | size_t len, | ||
427 | void **out); | ||
403 | 428 | ||
404 | /** | 429 | /** |
405 | * url/percent encode (RFC3986). | 430 | * url/percent encode (RFC3986). |
@@ -411,7 +436,9 @@ GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out); | |||
411 | * @return the size of the output | 436 | * @return the size of the output |
412 | */ | 437 | */ |
413 | size_t | 438 | size_t |
414 | GNUNET_STRINGS_urldecode (const char *data, size_t len, char **out); | 439 | GNUNET_STRINGS_urldecode (const char *data, |
440 | size_t len, | ||
441 | char **out); | ||
415 | 442 | ||
416 | 443 | ||
417 | /** | 444 | /** |
@@ -442,7 +469,7 @@ GNUNET_STRINGS_pp2s (const struct GNUNET_PeerIdentity *pids, | |||
442 | * an URI, '* scheme_part' and '*path_part' will remain unchanged | 469 | * an URI, '* scheme_part' and '*path_part' will remain unchanged |
443 | * (if they weren't NULL). | 470 | * (if they weren't NULL). |
444 | */ | 471 | */ |
445 | int | 472 | enum GNUNET_GenericReturnValue |
446 | GNUNET_STRINGS_parse_uri (const char *path, | 473 | GNUNET_STRINGS_parse_uri (const char *path, |
447 | char **scheme_part, | 474 | char **scheme_part, |
448 | const char **path_part); | 475 | const char **path_part); |
@@ -462,7 +489,7 @@ GNUNET_STRINGS_parse_uri (const char *path, | |||
462 | * GNUNET_free (). Can be NULL. | 489 | * GNUNET_free (). Can be NULL. |
463 | * @return #GNUNET_YES if 'filename' is absolute, #GNUNET_NO otherwise. | 490 | * @return #GNUNET_YES if 'filename' is absolute, #GNUNET_NO otherwise. |
464 | */ | 491 | */ |
465 | int | 492 | enum GNUNET_GenericReturnValue |
466 | GNUNET_STRINGS_path_is_absolute (const char *filename, | 493 | GNUNET_STRINGS_path_is_absolute (const char *filename, |
467 | int can_be_uri, | 494 | int can_be_uri, |
468 | int *r_is_uri, | 495 | int *r_is_uri, |
@@ -505,7 +532,7 @@ enum GNUNET_STRINGS_FilenameCheck | |||
505 | * @return #GNUNET_YES if all checks pass, #GNUNET_NO if at least one of them | 532 | * @return #GNUNET_YES if all checks pass, #GNUNET_NO if at least one of them |
506 | * fails, #GNUNET_SYSERR when a check can't be performed | 533 | * fails, #GNUNET_SYSERR when a check can't be performed |
507 | */ | 534 | */ |
508 | int | 535 | enum GNUNET_GenericReturnValue |
509 | GNUNET_STRINGS_check_filename (const char *filename, | 536 | GNUNET_STRINGS_check_filename (const char *filename, |
510 | enum GNUNET_STRINGS_FilenameCheck checks); | 537 | enum GNUNET_STRINGS_FilenameCheck checks); |
511 | 538 | ||
@@ -521,7 +548,7 @@ GNUNET_STRINGS_check_filename (const char *filename, | |||
521 | * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in which | 548 | * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in which |
522 | * case the contents of r_buf are undefined. | 549 | * case the contents of r_buf are undefined. |
523 | */ | 550 | */ |
524 | int | 551 | enum GNUNET_GenericReturnValue |
525 | GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr, | 552 | GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr, |
526 | uint16_t addrlen, | 553 | uint16_t addrlen, |
527 | struct sockaddr_in6 *r_buf); | 554 | struct sockaddr_in6 *r_buf); |
@@ -537,7 +564,7 @@ GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr, | |||
537 | * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in which case | 564 | * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in which case |
538 | * the contents of r_buf are undefined. | 565 | * the contents of r_buf are undefined. |
539 | */ | 566 | */ |
540 | int | 567 | enum GNUNET_GenericReturnValue |
541 | GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, | 568 | GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, |
542 | uint16_t addrlen, | 569 | uint16_t addrlen, |
543 | struct sockaddr_in *r_buf); | 570 | struct sockaddr_in *r_buf); |
@@ -569,7 +596,7 @@ GNUNET_STRINGS_parse_socket_addr (const char *addr, | |||
569 | * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in which | 596 | * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in which |
570 | * case the contents of r_buf are undefined. | 597 | * case the contents of r_buf are undefined. |
571 | */ | 598 | */ |
572 | int | 599 | enum GNUNET_GenericReturnValue |
573 | GNUNET_STRINGS_to_address_ip (const char *addr, | 600 | GNUNET_STRINGS_to_address_ip (const char *addr, |
574 | uint16_t addrlen, | 601 | uint16_t addrlen, |
575 | struct sockaddr_storage *r_buf); | 602 | struct sockaddr_storage *r_buf); |
@@ -587,7 +614,7 @@ GNUNET_STRINGS_to_address_ip (const char *addr, | |||
587 | * @param u8argv a location to store new argv in | 614 | * @param u8argv a location to store new argv in |
588 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure | 615 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure |
589 | */ | 616 | */ |
590 | int | 617 | enum GNUNET_GenericReturnValue |
591 | GNUNET_STRINGS_get_utf8_args (int argc, | 618 | GNUNET_STRINGS_get_utf8_args (int argc, |
592 | char *const *argv, | 619 | char *const *argv, |
593 | int *u8argc, | 620 | int *u8argc, |
@@ -610,7 +637,9 @@ GNUNET_STRINGS_get_utf8_args (int argc, | |||
610 | * null byte | 637 | * null byte |
611 | */ | 638 | */ |
612 | size_t | 639 | size_t |
613 | GNUNET_strlcpy (char *dst, const char *src, size_t n); | 640 | GNUNET_strlcpy (char *dst, |
641 | const char *src, | ||
642 | size_t n); | ||
614 | 643 | ||
615 | 644 | ||
616 | /* ***************** IPv4/IPv6 parsing ****************** */ | 645 | /* ***************** IPv4/IPv6 parsing ****************** */ |
diff --git a/src/json/json_helper.c b/src/json/json_helper.c index 03db9ec80..55435ea19 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c | |||
@@ -116,7 +116,6 @@ parse_variable_data (void *cls, | |||
116 | const char *str; | 116 | const char *str; |
117 | size_t size; | 117 | size_t size; |
118 | void *data; | 118 | void *data; |
119 | int res; | ||
120 | 119 | ||
121 | str = json_string_value (root); | 120 | str = json_string_value (root); |
122 | if (NULL == str) | 121 | if (NULL == str) |
@@ -124,30 +123,13 @@ parse_variable_data (void *cls, | |||
124 | GNUNET_break_op (0); | 123 | GNUNET_break_op (0); |
125 | return GNUNET_SYSERR; | 124 | return GNUNET_SYSERR; |
126 | } | 125 | } |
127 | size = (strlen (str) * 5) / 8; | 126 | if (GNUNET_OK != |
128 | if (size >= GNUNET_MAX_MALLOC_CHECKED) | 127 | GNUNET_STRINGS_string_to_data_alloc (str, |
129 | { | 128 | strlen (str), |
130 | GNUNET_break_op (0); | 129 | &data, |
131 | return GNUNET_SYSERR; | 130 | &size)) |
132 | } | ||
133 | data = GNUNET_malloc (size); | ||
134 | res = GNUNET_STRINGS_string_to_data (str, | ||
135 | strlen (str), | ||
136 | data, | ||
137 | size); | ||
138 | if ( (0 < size) && | ||
139 | (GNUNET_OK != res) ) | ||
140 | { | ||
141 | size--; | ||
142 | res = GNUNET_STRINGS_string_to_data (str, | ||
143 | strlen (str), | ||
144 | data, | ||
145 | size); | ||
146 | } | ||
147 | if (GNUNET_OK != res) | ||
148 | { | 131 | { |
149 | GNUNET_break_op (0); | 132 | GNUNET_break_op (0); |
150 | GNUNET_free (data); | ||
151 | return GNUNET_SYSERR; | 133 | return GNUNET_SYSERR; |
152 | } | 134 | } |
153 | *(void **) spec->ptr = data; | 135 | *(void **) spec->ptr = data; |
diff --git a/src/pq/Makefile.am b/src/pq/Makefile.am index fcc30f6ff..0febac4ac 100644 --- a/src/pq/Makefile.am +++ b/src/pq/Makefile.am | |||
@@ -14,6 +14,7 @@ libgnunetpq_la_SOURCES = \ | |||
14 | pq.h \ | 14 | pq.h \ |
15 | pq_connect.c \ | 15 | pq_connect.c \ |
16 | pq_eval.c \ | 16 | pq_eval.c \ |
17 | pq_event.c \ | ||
17 | pq_exec.c \ | 18 | pq_exec.c \ |
18 | pq_prepare.c \ | 19 | pq_prepare.c \ |
19 | pq_query_helper.c \ | 20 | pq_query_helper.c \ |
@@ -23,6 +24,7 @@ libgnunetpq_la_LIBADD = -lpq \ | |||
23 | libgnunetpq_la_LDFLAGS = \ | 24 | libgnunetpq_la_LDFLAGS = \ |
24 | $(POSTGRESQL_LDFLAGS) \ | 25 | $(POSTGRESQL_LDFLAGS) \ |
25 | $(GN_LIB_LDFLAGS) \ | 26 | $(GN_LIB_LDFLAGS) \ |
27 | -lpthread \ | ||
26 | -version-info 1:0:0 | 28 | -version-info 1:0:0 |
27 | 29 | ||
28 | if ENABLE_TEST_RUN | 30 | if ENABLE_TEST_RUN |
diff --git a/src/pq/pq.h b/src/pq/pq.h index 91a890bcb..3c89626a9 100644 --- a/src/pq/pq.h +++ b/src/pq/pq.h | |||
@@ -57,6 +57,26 @@ struct GNUNET_PQ_Context | |||
57 | * Path to load SQL files from. | 57 | * Path to load SQL files from. |
58 | */ | 58 | */ |
59 | char *load_path; | 59 | char *load_path; |
60 | |||
61 | /** | ||
62 | * Function to call on Postgres FDs. | ||
63 | */ | ||
64 | GNUNET_PQ_SocketCallback sc; | ||
65 | |||
66 | /** | ||
67 | * Closure for @e sc. | ||
68 | */ | ||
69 | void *sc_cls; | ||
70 | |||
71 | /** | ||
72 | * Map managing event subscriptions. | ||
73 | */ | ||
74 | struct GNUNET_CONTAINER_MultiShortmap *channel_map; | ||
75 | |||
76 | /** | ||
77 | * Lock to access @e channel_map. | ||
78 | */ | ||
79 | pthread_mutex_t notify_lock; | ||
60 | }; | 80 | }; |
61 | 81 | ||
62 | #endif | 82 | #endif |
diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c index cd52c2728..00664dcd0 100644 --- a/src/pq/pq_connect.c +++ b/src/pq/pq_connect.c | |||
@@ -209,7 +209,7 @@ apply_patch (struct GNUNET_PQ_Context *db, | |||
209 | * @param load_path where to find the XXXX.sql files | 209 | * @param load_path where to find the XXXX.sql files |
210 | * @return #GNUNET_OK on success | 210 | * @return #GNUNET_OK on success |
211 | */ | 211 | */ |
212 | int | 212 | enum GNUNET_GenericReturnValue |
213 | GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, | 213 | GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, |
214 | const char *load_path) | 214 | const char *load_path) |
215 | { | 215 | { |
diff --git a/src/pq/pq_event.c b/src/pq/pq_event.c new file mode 100644 index 000000000..ecb942230 --- /dev/null +++ b/src/pq/pq_event.c | |||
@@ -0,0 +1,396 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2021 GNUnet e.V. | ||
4 | |||
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 | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @file pq/pq_event.c | ||
22 | * @brief event notifications via Postgres | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "pq.h" | ||
27 | #include <pthread.h> | ||
28 | |||
29 | |||
30 | /** | ||
31 | * Handle for an active LISTENer to the database. | ||
32 | */ | ||
33 | struct GNUNET_PQ_EventHandler | ||
34 | { | ||
35 | /** | ||
36 | * Channel name. | ||
37 | */ | ||
38 | struct GNUNET_ShortHashCode sh; | ||
39 | |||
40 | /** | ||
41 | * Function to call on events. | ||
42 | */ | ||
43 | GNUNET_PQ_EventCallback cb; | ||
44 | |||
45 | /** | ||
46 | * Closure for @e cb. | ||
47 | */ | ||
48 | void *cb_cls; | ||
49 | |||
50 | /** | ||
51 | * Database context this event handler is with. | ||
52 | */ | ||
53 | struct GNUNET_PQ_Context *db; | ||
54 | }; | ||
55 | |||
56 | |||
57 | |||
58 | |||
59 | /** | ||
60 | * Convert @a es to a short hash. | ||
61 | * | ||
62 | * @param es spec to hash to an identifier | ||
63 | * @param[out] sh short hash to set | ||
64 | */ | ||
65 | static void | ||
66 | es_to_sh (const struct GNUNET_PQ_EventHeaderP *es, | ||
67 | struct GNUNET_ShortHashCode *sh) | ||
68 | { | ||
69 | struct GNUNET_HashCode h_channel; | ||
70 | |||
71 | GNUNET_CRYPTO_hash (es, | ||
72 | ntohs (es->size), | ||
73 | &h_channel); | ||
74 | GNUNET_static_assert (sizeof (*sh) <= sizeof (h_channel)); | ||
75 | memcpy (sh, | ||
76 | &h_channel, | ||
77 | sizeof (*sh)); | ||
78 | } | ||
79 | |||
80 | |||
81 | /** | ||
82 | * Convert @a sh to a Postgres identifier. | ||
83 | * | ||
84 | * @param sh short hash to convert to an identifier | ||
85 | * @param[out] identifier by default, Postgres supports | ||
86 | * NAMEDATALEN=64 character identifiers | ||
87 | * @return end position of the identifier | ||
88 | */ | ||
89 | static char * | ||
90 | sh_to_channel (struct GNUNET_ShortHashCode *sh, | ||
91 | char identifier[64]) | ||
92 | { | ||
93 | char *end; | ||
94 | |||
95 | end = GNUNET_STRINGS_data_to_string (sh, | ||
96 | sizeof (*sh), | ||
97 | identifier, | ||
98 | 63); | ||
99 | GNUNET_assert (NULL != end); | ||
100 | *end = '\0'; | ||
101 | return end; | ||
102 | } | ||
103 | |||
104 | |||
105 | /** | ||
106 | * Convert @a es to a Postgres identifier. | ||
107 | * | ||
108 | * @param es spec to hash to an identifier | ||
109 | * @param[out] identifier by default, Postgres supports | ||
110 | * NAMEDATALEN=64 character identifiers | ||
111 | * @return end position of the identifier | ||
112 | */ | ||
113 | static char * | ||
114 | es_to_channel (const struct GNUNET_PQ_EventHeaderP *es, | ||
115 | char identifier[64]) | ||
116 | { | ||
117 | struct GNUNET_ShortHashCode sh; | ||
118 | |||
119 | es_to_sh (es, | ||
120 | &sh); | ||
121 | return sh_to_channel (&sh, | ||
122 | identifier); | ||
123 | } | ||
124 | |||
125 | |||
126 | /** | ||
127 | * Closure for #do_notify(). | ||
128 | */ | ||
129 | struct NotifyContext | ||
130 | { | ||
131 | /** | ||
132 | * Extra argument of the notification, or NULL. | ||
133 | */ | ||
134 | void *extra; | ||
135 | |||
136 | /** | ||
137 | * Number of bytes in @e extra. | ||
138 | */ | ||
139 | size_t extra_size; | ||
140 | }; | ||
141 | |||
142 | |||
143 | /** | ||
144 | * Function called on every event handler that | ||
145 | * needs to be triggered. | ||
146 | * | ||
147 | * @param cls a `struct NotifyContext` | ||
148 | * @param sh channel name | ||
149 | * @param value a `struct GNUNET_PQ_EventHandler` | ||
150 | * @return #GNUNET_OK continue to iterate | ||
151 | */ | ||
152 | static int | ||
153 | do_notify (void *cls, | ||
154 | const struct GNUNET_ShortHashCode *sh, | ||
155 | void *value) | ||
156 | { | ||
157 | struct NotifyContext *ctx = cls; | ||
158 | struct GNUNET_PQ_EventHandler *eh = value; | ||
159 | |||
160 | eh->cb (eh->cb_cls, | ||
161 | ctx->extra, | ||
162 | ctx->extra_size); | ||
163 | return GNUNET_OK; | ||
164 | } | ||
165 | |||
166 | |||
167 | void | ||
168 | GNUNET_PQ_event_set_socket_callback (struct GNUNET_PQ_Context *db, | ||
169 | GNUNET_PQ_SocketCallback sc, | ||
170 | void *sc_cls) | ||
171 | { | ||
172 | int fd; | ||
173 | |||
174 | db->sc = sc; | ||
175 | db->sc_cls = sc_cls; | ||
176 | if (NULL == sc) | ||
177 | return; | ||
178 | GNUNET_assert (0 == | ||
179 | pthread_mutex_lock (&db->notify_lock)); | ||
180 | fd = PQsocket (db->conn); | ||
181 | if ( (-1 != fd) && | ||
182 | (0 != GNUNET_CONTAINER_multishortmap_size (db->channel_map)) ) | ||
183 | sc (sc_cls, | ||
184 | fd); | ||
185 | GNUNET_assert (0 == | ||
186 | pthread_mutex_unlock (&db->notify_lock)); | ||
187 | } | ||
188 | |||
189 | |||
190 | void | ||
191 | GNUNET_PQ_event_do_poll (struct GNUNET_PQ_Context *db) | ||
192 | { | ||
193 | PGnotify *n; | ||
194 | |||
195 | GNUNET_assert (0 == | ||
196 | pthread_mutex_lock (&db->notify_lock)); | ||
197 | while (NULL != (n = PQnotifies (db->conn))) | ||
198 | { | ||
199 | struct GNUNET_ShortHashCode sh; | ||
200 | struct NotifyContext ctx = { | ||
201 | .extra = NULL | ||
202 | }; | ||
203 | |||
204 | if (GNUNET_OK != | ||
205 | GNUNET_STRINGS_string_to_data (n->relname, | ||
206 | strlen (n->relname), | ||
207 | &sh, | ||
208 | sizeof (sh))) | ||
209 | { | ||
210 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
211 | "Ignoring notification for unsupported channel identifier `%s'\n", | ||
212 | n->relname); | ||
213 | continue; | ||
214 | } | ||
215 | if ( (NULL != n->extra) && | ||
216 | (GNUNET_OK != | ||
217 | GNUNET_STRINGS_string_to_data_alloc (n->extra, | ||
218 | strlen (n->extra), | ||
219 | &ctx.extra, | ||
220 | &ctx.extra_size))) | ||
221 | { | ||
222 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
223 | "Ignoring notification for unsupported extra data `%s' on channel `%s'\n", | ||
224 | n->extra, | ||
225 | n->relname); | ||
226 | continue; | ||
227 | } | ||
228 | GNUNET_CONTAINER_multishortmap_iterate (db->channel_map, | ||
229 | &do_notify, | ||
230 | &ctx); | ||
231 | GNUNET_free (ctx.extra); | ||
232 | } | ||
233 | GNUNET_assert (0 == | ||
234 | pthread_mutex_unlock (&db->notify_lock)); | ||
235 | } | ||
236 | |||
237 | |||
238 | void | ||
239 | GNUNET_PQ_event_scheduler_start (struct GNUNET_PQ_Context *db) | ||
240 | { | ||
241 | GNUNET_break (0); // FIXME: not implemented | ||
242 | } | ||
243 | |||
244 | |||
245 | void | ||
246 | GNUNET_PQ_event_scheduler_stop (struct GNUNET_PQ_Context *db) | ||
247 | { | ||
248 | GNUNET_break (0); // FIXME: not implemented | ||
249 | } | ||
250 | |||
251 | |||
252 | static void | ||
253 | manage_subscribe (struct GNUNET_PQ_Context *db, | ||
254 | const char *cmd, | ||
255 | struct GNUNET_PQ_EventHandler *eh) | ||
256 | { | ||
257 | char sql[16 + 64]; | ||
258 | char *end; | ||
259 | PGresult *result; | ||
260 | |||
261 | end = stpcpy (sql, | ||
262 | cmd); | ||
263 | end = sh_to_channel (&eh->sh, | ||
264 | end); | ||
265 | result = PQexec (db->conn, | ||
266 | sql); | ||
267 | if (PGRES_COMMAND_OK != PQresultStatus (result)) | ||
268 | { | ||
269 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
270 | "pq", | ||
271 | "Failed to execute `%s': %s/%s/%s/%s/%s", | ||
272 | sql, | ||
273 | PQresultErrorField (result, | ||
274 | PG_DIAG_MESSAGE_PRIMARY), | ||
275 | PQresultErrorField (result, | ||
276 | PG_DIAG_MESSAGE_DETAIL), | ||
277 | PQresultErrorMessage (result), | ||
278 | PQresStatus (PQresultStatus (result)), | ||
279 | PQerrorMessage (db->conn)); | ||
280 | } | ||
281 | PQclear (result); | ||
282 | } | ||
283 | |||
284 | |||
285 | struct GNUNET_PQ_EventHandler * | ||
286 | GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db, | ||
287 | const struct GNUNET_PQ_EventHeaderP *es, | ||
288 | GNUNET_PQ_EventCallback cb, | ||
289 | void *cb_cls) | ||
290 | { | ||
291 | struct GNUNET_PQ_EventHandler *eh; | ||
292 | bool was_zero; | ||
293 | |||
294 | eh = GNUNET_new (struct GNUNET_PQ_EventHandler); | ||
295 | eh->db = db; | ||
296 | es_to_sh (es, | ||
297 | &eh->sh); | ||
298 | eh->cb = cb; | ||
299 | eh->cb_cls = cb_cls; | ||
300 | GNUNET_assert (0 == | ||
301 | pthread_mutex_lock (&db->notify_lock)); | ||
302 | was_zero = (0 == GNUNET_CONTAINER_multishortmap_size (db->channel_map)); | ||
303 | GNUNET_assert (GNUNET_OK == | ||
304 | GNUNET_CONTAINER_multishortmap_put (db->channel_map, | ||
305 | &eh->sh, | ||
306 | eh, | ||
307 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); | ||
308 | if ( (NULL != db->sc) && | ||
309 | was_zero) | ||
310 | { | ||
311 | int fd = PQsocket (db->conn); | ||
312 | |||
313 | if (-1 != fd) | ||
314 | db->sc (db->sc_cls, | ||
315 | fd); | ||
316 | } | ||
317 | manage_subscribe (db, | ||
318 | "LISTEN ", | ||
319 | eh); | ||
320 | GNUNET_assert (0 == | ||
321 | pthread_mutex_unlock (&db->notify_lock)); | ||
322 | return eh; | ||
323 | } | ||
324 | |||
325 | |||
326 | void | ||
327 | GNUNET_PQ_event_listen_cancel (struct GNUNET_PQ_EventHandler *eh) | ||
328 | { | ||
329 | struct GNUNET_PQ_Context *db = eh->db; | ||
330 | |||
331 | GNUNET_assert (0 == | ||
332 | pthread_mutex_lock (&db->notify_lock)); | ||
333 | GNUNET_assert (GNUNET_OK == | ||
334 | GNUNET_CONTAINER_multishortmap_remove (db->channel_map, | ||
335 | &eh->sh, | ||
336 | eh)); | ||
337 | |||
338 | manage_subscribe (db, | ||
339 | "UNLISTEN ", | ||
340 | eh); | ||
341 | if ( (NULL != db->sc) && | ||
342 | (0 == GNUNET_CONTAINER_multishortmap_size (db->channel_map)) ) | ||
343 | { | ||
344 | db->sc (db->sc_cls, | ||
345 | -1); | ||
346 | } | ||
347 | GNUNET_assert (0 == | ||
348 | pthread_mutex_unlock (&db->notify_lock)); | ||
349 | } | ||
350 | |||
351 | |||
352 | void | ||
353 | GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db, | ||
354 | const struct GNUNET_PQ_EventHeaderP *es, | ||
355 | const void *extra, | ||
356 | size_t extra_size) | ||
357 | { | ||
358 | char sql[16 + 64 + extra_size * 8 / 5 + 8]; | ||
359 | char *end; | ||
360 | PGresult *result; | ||
361 | |||
362 | end = stpcpy (sql, | ||
363 | "NOTIFY "); | ||
364 | end = es_to_channel (es, | ||
365 | end); | ||
366 | end = stpcpy (end, | ||
367 | "'"); | ||
368 | end = GNUNET_STRINGS_data_to_string (extra, | ||
369 | extra_size, | ||
370 | end, | ||
371 | sizeof (sql) - (end - sql) - 1); | ||
372 | GNUNET_assert (NULL != end); | ||
373 | *end = '\0'; | ||
374 | end = stpcpy (end, | ||
375 | "'"); | ||
376 | result = PQexec (db->conn, | ||
377 | sql); | ||
378 | if (PGRES_COMMAND_OK != PQresultStatus (result)) | ||
379 | { | ||
380 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
381 | "pq", | ||
382 | "Failed to execute `%s': %s/%s/%s/%s/%s", | ||
383 | sql, | ||
384 | PQresultErrorField (result, | ||
385 | PG_DIAG_MESSAGE_PRIMARY), | ||
386 | PQresultErrorField (result, | ||
387 | PG_DIAG_MESSAGE_DETAIL), | ||
388 | PQresultErrorMessage (result), | ||
389 | PQresStatus (PQresultStatus (result)), | ||
390 | PQerrorMessage (db->conn)); | ||
391 | } | ||
392 | PQclear (result); | ||
393 | } | ||
394 | |||
395 | /* end of pq_event.c */ | ||
396 | |||
diff --git a/src/util/strings.c b/src/util/strings.c index b62d5f547..24335e444 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -41,27 +41,6 @@ | |||
41 | GNUNET_log_from_strerror (kind, "util-strings", syscall) | 41 | GNUNET_log_from_strerror (kind, "util-strings", syscall) |
42 | 42 | ||
43 | 43 | ||
44 | /** | ||
45 | * Fill a buffer of the given size with | ||
46 | * count 0-terminated strings (given as varargs). | ||
47 | * If "buffer" is NULL, only compute the amount of | ||
48 | * space required (sum of "strlen(arg)+1"). | ||
49 | * | ||
50 | * Unlike using "snprintf" with "%s", this function | ||
51 | * will add 0-terminators after each string. The | ||
52 | * #GNUNET_string_buffer_tokenize() function can be | ||
53 | * used to parse the buffer back into individual | ||
54 | * strings. | ||
55 | * | ||
56 | * @param buffer the buffer to fill with strings, can | ||
57 | * be NULL in which case only the necessary | ||
58 | * amount of space will be calculated | ||
59 | * @param size number of bytes available in buffer | ||
60 | * @param count number of strings that follow | ||
61 | * @param ... count 0-terminated strings to copy to buffer | ||
62 | * @return number of bytes written to the buffer | ||
63 | * (or number of bytes that would have been written) | ||
64 | */ | ||
65 | size_t | 44 | size_t |
66 | GNUNET_STRINGS_buffer_fill (char *buffer, | 45 | GNUNET_STRINGS_buffer_fill (char *buffer, |
67 | size_t size, | 46 | size_t size, |
@@ -90,13 +69,6 @@ GNUNET_STRINGS_buffer_fill (char *buffer, | |||
90 | } | 69 | } |
91 | 70 | ||
92 | 71 | ||
93 | /** | ||
94 | * Convert a peer path to a human-readable string. | ||
95 | * | ||
96 | * @param pids array of PIDs to convert to a string | ||
97 | * @param num_pids length of the @a pids array | ||
98 | * @return string representing the array of @a pids | ||
99 | */ | ||
100 | char * | 72 | char * |
101 | GNUNET_STRINGS_pp2s (const struct GNUNET_PeerIdentity *pids, | 73 | GNUNET_STRINGS_pp2s (const struct GNUNET_PeerIdentity *pids, |
102 | unsigned int num_pids) | 74 | unsigned int num_pids) |
@@ -120,19 +92,6 @@ GNUNET_STRINGS_pp2s (const struct GNUNET_PeerIdentity *pids, | |||
120 | } | 92 | } |
121 | 93 | ||
122 | 94 | ||
123 | /** | ||
124 | * Given a buffer of a given size, find "count" | ||
125 | * 0-terminated strings in the buffer and assign | ||
126 | * the count (varargs) of type "const char**" to the | ||
127 | * locations of the respective strings in the | ||
128 | * buffer. | ||
129 | * | ||
130 | * @param buffer the buffer to parse | ||
131 | * @param size size of the buffer | ||
132 | * @param count number of strings to locate | ||
133 | * @return offset of the character after the last 0-termination | ||
134 | * in the buffer, or 0 on error. | ||
135 | */ | ||
136 | unsigned int | 95 | unsigned int |
137 | GNUNET_STRINGS_buffer_tokenize (const char *buffer, | 96 | GNUNET_STRINGS_buffer_tokenize (const char *buffer, |
138 | size_t size, | 97 | size_t size, |
@@ -167,12 +126,6 @@ GNUNET_STRINGS_buffer_tokenize (const char *buffer, | |||
167 | } | 126 | } |
168 | 127 | ||
169 | 128 | ||
170 | /** | ||
171 | * Convert a given filesize into a fancy human-readable format. | ||
172 | * | ||
173 | * @param size number of bytes | ||
174 | * @return fancy representation of the size (possibly rounded) for humans | ||
175 | */ | ||
176 | char * | 129 | char * |
177 | GNUNET_STRINGS_byte_size_fancy (unsigned long long size) | 130 | GNUNET_STRINGS_byte_size_fancy (unsigned long long size) |
178 | { | 131 | { |
@@ -205,20 +158,10 @@ GNUNET_STRINGS_byte_size_fancy (unsigned long long size) | |||
205 | } | 158 | } |
206 | 159 | ||
207 | 160 | ||
208 | /** | ||
209 | * Like strlcpy but portable. The given string @a src is copied until its null | ||
210 | * byte or until @a n - 1 bytes have been read. The destination buffer is | ||
211 | * guaranteed to be null-terminated. | ||
212 | * | ||
213 | * @param dst destination of the copy (must be @a n bytes long) | ||
214 | * @param src source of the copy (at most @a n - 1 bytes will be read) | ||
215 | * @param n the length of the string to copy, including its terminating null | ||
216 | * byte | ||
217 | * @return the length of the string that was copied, excluding the terminating | ||
218 | * null byte | ||
219 | */ | ||
220 | size_t | 161 | size_t |
221 | GNUNET_strlcpy (char *dst, const char *src, size_t n) | 162 | GNUNET_strlcpy (char *dst, |
163 | const char *src, | ||
164 | size_t n) | ||
222 | { | 165 | { |
223 | size_t slen; | 166 | size_t slen; |
224 | 167 | ||
@@ -313,13 +256,6 @@ convert_with_table (const char *input, | |||
313 | } | 256 | } |
314 | 257 | ||
315 | 258 | ||
316 | /** | ||
317 | * Convert a given fancy human-readable size to bytes. | ||
318 | * | ||
319 | * @param fancy_size human readable string (e.g. 1 MB) | ||
320 | * @param size set to the size in bytes | ||
321 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
322 | */ | ||
323 | int | 259 | int |
324 | GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, | 260 | GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, |
325 | unsigned long long *size) | 261 | unsigned long long *size) |
@@ -344,14 +280,6 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, | |||
344 | } | 280 | } |
345 | 281 | ||
346 | 282 | ||
347 | /** | ||
348 | * Convert a given fancy human-readable time to our internal | ||
349 | * representation. | ||
350 | * | ||
351 | * @param fancy_time human readable string (e.g. 1 minute) | ||
352 | * @param rtime set to the relative time | ||
353 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
354 | */ | ||
355 | int | 283 | int |
356 | GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, | 284 | GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, |
357 | struct GNUNET_TIME_Relative *rtime) | 285 | struct GNUNET_TIME_Relative *rtime) |
@@ -394,15 +322,6 @@ GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, | |||
394 | } | 322 | } |
395 | 323 | ||
396 | 324 | ||
397 | /** | ||
398 | * Convert a given fancy human-readable time to our internal | ||
399 | * representation. The human-readable time is expected to be | ||
400 | * in local time, whereas the returned value will be in UTC. | ||
401 | * | ||
402 | * @param fancy_time human readable string (e.g. %Y-%m-%d %H:%M:%S) | ||
403 | * @param atime set to the absolute time | ||
404 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
405 | */ | ||
406 | int | 325 | int |
407 | GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, | 326 | GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, |
408 | struct GNUNET_TIME_Absolute *atime) | 327 | struct GNUNET_TIME_Absolute *atime) |
@@ -435,19 +354,6 @@ GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, | |||
435 | } | 354 | } |
436 | 355 | ||
437 | 356 | ||
438 | /** | ||
439 | * Convert the len characters long character sequence | ||
440 | * given in input that is in the given input charset | ||
441 | * to a string in given output charset. | ||
442 | * | ||
443 | * @param input input string | ||
444 | * @param len number of bytes in @a input | ||
445 | * @param input_charset character set used for @a input | ||
446 | * @param output_charset desired character set for the return value | ||
447 | * @return the converted string (0-terminated), | ||
448 | * if conversion fails, a copy of the original | ||
449 | * string is returned. | ||
450 | */ | ||
451 | char * | 357 | char * |
452 | GNUNET_STRINGS_conv (const char *input, | 358 | GNUNET_STRINGS_conv (const char *input, |
453 | size_t len, | 359 | size_t len, |
@@ -510,18 +416,6 @@ fail: | |||
510 | } | 416 | } |
511 | 417 | ||
512 | 418 | ||
513 | /** | ||
514 | * Convert the len characters long character sequence | ||
515 | * given in input that is in the given charset | ||
516 | * to UTF-8. | ||
517 | * | ||
518 | * @param input the input string (not necessarily 0-terminated) | ||
519 | * @param len the number of bytes in the @a input | ||
520 | * @param charset character set to convert from | ||
521 | * @return the converted string (0-terminated), | ||
522 | * if conversion fails, a copy of the original | ||
523 | * string is returned. | ||
524 | */ | ||
525 | char * | 419 | char * |
526 | GNUNET_STRINGS_to_utf8 (const char *input, | 420 | GNUNET_STRINGS_to_utf8 (const char *input, |
527 | size_t len, | 421 | size_t len, |
@@ -534,17 +428,6 @@ GNUNET_STRINGS_to_utf8 (const char *input, | |||
534 | } | 428 | } |
535 | 429 | ||
536 | 430 | ||
537 | /** | ||
538 | * Convert the len bytes-long UTF-8 string | ||
539 | * given in input to the given charset. | ||
540 | * | ||
541 | * @param input the input string (not necessarily 0-terminated) | ||
542 | * @param len the number of bytes in the @a input | ||
543 | * @param charset character set to convert to | ||
544 | * @return the converted string (0-terminated), | ||
545 | * if conversion fails, a copy of the original | ||
546 | * string is returned. | ||
547 | */ | ||
548 | char * | 431 | char * |
549 | GNUNET_STRINGS_from_utf8 (const char *input, | 432 | GNUNET_STRINGS_from_utf8 (const char *input, |
550 | size_t len, | 433 | size_t len, |
@@ -557,15 +440,9 @@ GNUNET_STRINGS_from_utf8 (const char *input, | |||
557 | } | 440 | } |
558 | 441 | ||
559 | 442 | ||
560 | /** | ||
561 | * Convert the utf-8 input string to lowercase. | ||
562 | * Output needs to be allocated appropriately. | ||
563 | * | ||
564 | * @param input input string | ||
565 | * @param output output buffer | ||
566 | */ | ||
567 | void | 443 | void |
568 | GNUNET_STRINGS_utf8_tolower (const char *input, char *output) | 444 | GNUNET_STRINGS_utf8_tolower (const char *input, |
445 | char *output) | ||
569 | { | 446 | { |
570 | uint8_t *tmp_in; | 447 | uint8_t *tmp_in; |
571 | size_t len; | 448 | size_t len; |
@@ -582,15 +459,9 @@ GNUNET_STRINGS_utf8_tolower (const char *input, char *output) | |||
582 | } | 459 | } |
583 | 460 | ||
584 | 461 | ||
585 | /** | ||
586 | * Convert the utf-8 input string to uppercase. | ||
587 | * Output needs to be allocated appropriately. | ||
588 | * | ||
589 | * @param input input string | ||
590 | * @param output output buffer | ||
591 | */ | ||
592 | void | 462 | void |
593 | GNUNET_STRINGS_utf8_toupper (const char *input, char *output) | 463 | GNUNET_STRINGS_utf8_toupper (const char *input, |
464 | char *output) | ||
594 | { | 465 | { |
595 | uint8_t *tmp_in; | 466 | uint8_t *tmp_in; |
596 | size_t len; | 467 | size_t len; |
@@ -607,13 +478,6 @@ GNUNET_STRINGS_utf8_toupper (const char *input, char *output) | |||
607 | } | 478 | } |
608 | 479 | ||
609 | 480 | ||
610 | /** | ||
611 | * Complete filename (a la shell) from abbrevition. | ||
612 | * @param fil the name of the file, may contain ~/ or | ||
613 | * be relative to the current directory | ||
614 | * @returns the full file name, | ||
615 | * NULL is returned on error | ||
616 | */ | ||
617 | char * | 481 | char * |
618 | GNUNET_STRINGS_filename_expand (const char *fil) | 482 | GNUNET_STRINGS_filename_expand (const char *fil) |
619 | { | 483 | { |
@@ -689,15 +553,6 @@ GNUNET_STRINGS_filename_expand (const char *fil) | |||
689 | } | 553 | } |
690 | 554 | ||
691 | 555 | ||
692 | /** | ||
693 | * Give relative time in human-readable fancy format. | ||
694 | * This is one of the very few calls in the entire API that is | ||
695 | * NOT reentrant! | ||
696 | * | ||
697 | * @param delta time in milli seconds | ||
698 | * @param do_round are we allowed to round a bit? | ||
699 | * @return time as human-readable string | ||
700 | */ | ||
701 | const char * | 556 | const char * |
702 | GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta, | 557 | GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta, |
703 | int do_round) | 558 | int do_round) |
@@ -745,15 +600,6 @@ GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta, | |||
745 | } | 600 | } |
746 | 601 | ||
747 | 602 | ||
748 | /** | ||
749 | * "asctime", except for GNUnet time. Converts a GNUnet internal | ||
750 | * absolute time (which is in UTC) to a string in local time. | ||
751 | * Note that the returned value will be overwritten if this function | ||
752 | * is called again. | ||
753 | * | ||
754 | * @param t the absolute time to convert | ||
755 | * @return timestamp in human-readable form in local time | ||
756 | */ | ||
757 | const char * | 603 | const char * |
758 | GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t) | 604 | GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t) |
759 | { | 605 | { |
@@ -776,17 +622,6 @@ GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t) | |||
776 | } | 622 | } |
777 | 623 | ||
778 | 624 | ||
779 | /** | ||
780 | * "man basename" | ||
781 | * Returns a pointer to a part of filename (allocates nothing)! | ||
782 | * | ||
783 | * @param filename filename to extract basename from | ||
784 | * @return short (base) name of the file (that is, everything following the | ||
785 | * last directory separator in filename. If filename ends with a | ||
786 | * directory separator, the result will be a zero-length string. | ||
787 | * If filename has no directory separators, the result is filename | ||
788 | * itself. | ||
789 | */ | ||
790 | const char * | 625 | const char * |
791 | GNUNET_STRINGS_get_short_name (const char *filename) | 626 | GNUNET_STRINGS_get_short_name (const char *filename) |
792 | { | 627 | { |
@@ -856,18 +691,6 @@ getValue__ (unsigned char a) | |||
856 | } | 691 | } |
857 | 692 | ||
858 | 693 | ||
859 | /** | ||
860 | * Convert binary data to ASCII encoding using Crockford Base32 encoding. | ||
861 | * Returns a pointer to the byte after the last byte in the string, that | ||
862 | * is where the 0-terminator was placed if there was room. | ||
863 | * | ||
864 | * @param data data to encode | ||
865 | * @param size size of data (in bytes) | ||
866 | * @param out buffer to fill | ||
867 | * @param out_size size of the buffer. Must be large enough to hold | ||
868 | * (size * 8 + 4) / 5 bytes | ||
869 | * @return pointer to the next byte in @a out or NULL on error. | ||
870 | */ | ||
871 | char * | 694 | char * |
872 | GNUNET_STRINGS_data_to_string (const void *data, | 695 | GNUNET_STRINGS_data_to_string (const void *data, |
873 | size_t size, | 696 | size_t size, |
@@ -923,16 +746,6 @@ GNUNET_STRINGS_data_to_string (const void *data, | |||
923 | } | 746 | } |
924 | 747 | ||
925 | 748 | ||
926 | /** | ||
927 | * Return the base32crockford encoding of the given buffer. | ||
928 | * | ||
929 | * The returned string will be freshly allocated, and must be free'd | ||
930 | * with GNUNET_free(). | ||
931 | * | ||
932 | * @param buffer with data | ||
933 | * @param size size of the buffer | ||
934 | * @return freshly allocated, null-terminated string | ||
935 | */ | ||
936 | char * | 749 | char * |
937 | GNUNET_STRINGS_data_to_string_alloc (const void *buf, size_t size) | 750 | GNUNET_STRINGS_data_to_string_alloc (const void *buf, size_t size) |
938 | { | 751 | { |
@@ -958,17 +771,7 @@ GNUNET_STRINGS_data_to_string_alloc (const void *buf, size_t size) | |||
958 | } | 771 | } |
959 | 772 | ||
960 | 773 | ||
961 | /** | 774 | enum GNUNET_GenericReturnValue |
962 | * Convert Crockford Base32hex encoding back to data. | ||
963 | * @a out_size must match exactly the size of the data before it was encoded. | ||
964 | * | ||
965 | * @param enc the encoding | ||
966 | * @param enclen number of characters in @a enc (without 0-terminator, which can be missing) | ||
967 | * @param out location where to store the decoded data | ||
968 | * @param out_size size of the output buffer @a out | ||
969 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding | ||
970 | */ | ||
971 | int | ||
972 | GNUNET_STRINGS_string_to_data (const char *enc, | 775 | GNUNET_STRINGS_string_to_data (const char *enc, |
973 | size_t enclen, | 776 | size_t enclen, |
974 | void *out, | 777 | void *out, |
@@ -1034,23 +837,49 @@ GNUNET_STRINGS_string_to_data (const char *enc, | |||
1034 | } | 837 | } |
1035 | 838 | ||
1036 | 839 | ||
1037 | /** | 840 | enum GNUNET_GenericReturnValue |
1038 | * Parse a path that might be an URI. | 841 | GNUNET_STRINGS_string_to_data_alloc (const char *enc, |
1039 | * | 842 | size_t enclen, |
1040 | * @param path path to parse. Must be NULL-terminated. | 843 | void **out, |
1041 | * @param scheme_part a pointer to 'char *' where a pointer to a string that | 844 | size_t *out_size) |
1042 | * represents the URI scheme will be stored. Can be NULL. The string is | 845 | { |
1043 | * allocated by the function, and should be freed by GNUNET_free() when | 846 | size_t size; |
1044 | * it is no longer needed. | 847 | void *data; |
1045 | * @param path_part a pointer to 'const char *' where a pointer to the path | 848 | int res; |
1046 | * part of the URI will be stored. Can be NULL. Points to the same block | 849 | |
1047 | * of memory as 'path', and thus must not be freed. Might point to '\0', | 850 | size = (enclen * 5) / 8; |
1048 | * if path part is zero-length. | 851 | if (size >= GNUNET_MAX_MALLOC_CHECKED) |
1049 | * @return GNUNET_YES if it's an URI, GNUNET_NO otherwise. If 'path' is not | 852 | { |
1050 | * an URI, '* scheme_part' and '*path_part' will remain unchanged | 853 | GNUNET_break_op (0); |
1051 | * (if they weren't NULL). | 854 | return GNUNET_SYSERR; |
1052 | */ | 855 | } |
1053 | int | 856 | data = GNUNET_malloc (size); |
857 | res = GNUNET_STRINGS_string_to_data (enc, | ||
858 | enclen, | ||
859 | data, | ||
860 | size); | ||
861 | if ( (0 < size) && | ||
862 | (GNUNET_OK != res) ) | ||
863 | { | ||
864 | size--; | ||
865 | res = GNUNET_STRINGS_string_to_data (enc, | ||
866 | enclen, | ||
867 | data, | ||
868 | size); | ||
869 | } | ||
870 | if (GNUNET_OK != res) | ||
871 | { | ||
872 | GNUNET_break_op (0); | ||
873 | GNUNET_free (data); | ||
874 | return GNUNET_SYSERR; | ||
875 | } | ||
876 | *out = data; | ||
877 | *out_size = size; | ||
878 | return GNUNET_OK; | ||
879 | } | ||
880 | |||
881 | |||
882 | enum GNUNET_GenericReturnValue | ||
1054 | GNUNET_STRINGS_parse_uri (const char *path, | 883 | GNUNET_STRINGS_parse_uri (const char *path, |
1055 | char **scheme_part, | 884 | char **scheme_part, |
1056 | const char **path_part) | 885 | const char **path_part) |
@@ -1112,21 +941,7 @@ GNUNET_STRINGS_parse_uri (const char *path, | |||
1112 | } | 941 | } |
1113 | 942 | ||
1114 | 943 | ||
1115 | /** | 944 | enum GNUNET_GenericReturnValue |
1116 | * Check whether @a filename is absolute or not, and if it's an URI | ||
1117 | * | ||
1118 | * @param filename filename to check | ||
1119 | * @param can_be_uri #GNUNET_YES to check for being URI, #GNUNET_NO - to | ||
1120 | * assume it's not URI | ||
1121 | * @param r_is_uri a pointer to an int that is set to #GNUNET_YES if @a filename | ||
1122 | * is URI and to #GNUNET_NO otherwise. Can be NULL. If @a can_be_uri is | ||
1123 | * not #GNUNET_YES, `* r_is_uri` is set to #GNUNET_NO. | ||
1124 | * @param r_uri_scheme a pointer to a char * that is set to a pointer to URI scheme. | ||
1125 | * The string is allocated by the function, and should be freed with | ||
1126 | * GNUNET_free(). Can be NULL. | ||
1127 | * @return #GNUNET_YES if @a filename is absolute, #GNUNET_NO otherwise. | ||
1128 | */ | ||
1129 | int | ||
1130 | GNUNET_STRINGS_path_is_absolute (const char *filename, | 945 | GNUNET_STRINGS_path_is_absolute (const char *filename, |
1131 | int can_be_uri, | 946 | int can_be_uri, |
1132 | int *r_is_uri, | 947 | int *r_is_uri, |
@@ -1168,15 +983,7 @@ GNUNET_STRINGS_path_is_absolute (const char *filename, | |||
1168 | } | 983 | } |
1169 | 984 | ||
1170 | 985 | ||
1171 | /** | 986 | enum GNUNET_GenericReturnValue |
1172 | * Perform @a checks on @a filename. | ||
1173 | * | ||
1174 | * @param filename file to check | ||
1175 | * @param checks checks to perform | ||
1176 | * @return #GNUNET_YES if all checks pass, #GNUNET_NO if at least one of them | ||
1177 | * fails, #GNUNET_SYSERR when a check can't be performed | ||
1178 | */ | ||
1179 | int | ||
1180 | GNUNET_STRINGS_check_filename (const char *filename, | 987 | GNUNET_STRINGS_check_filename (const char *filename, |
1181 | enum GNUNET_STRINGS_FilenameCheck checks) | 988 | enum GNUNET_STRINGS_FilenameCheck checks) |
1182 | { | 989 | { |
@@ -1209,19 +1016,7 @@ GNUNET_STRINGS_check_filename (const char *filename, | |||
1209 | } | 1016 | } |
1210 | 1017 | ||
1211 | 1018 | ||
1212 | /** | 1019 | enum GNUNET_GenericReturnValue |
1213 | * Tries to convert @a zt_addr string to an IPv6 address. | ||
1214 | * The string is expected to have the format "[ABCD::01]:80". | ||
1215 | * | ||
1216 | * @param zt_addr 0-terminated string. May be mangled by the function. | ||
1217 | * @param addrlen length of @a zt_addr (not counting 0-terminator). | ||
1218 | * @param r_buf a buffer to fill. Initially gets filled with zeroes, | ||
1219 | * then its sin6_port, sin6_family and sin6_addr are set appropriately. | ||
1220 | * @return #GNUNET_OK if conversion succeeded. | ||
1221 | * #GNUNET_SYSERR otherwise, in which | ||
1222 | * case the contents of @a r_buf are undefined. | ||
1223 | */ | ||
1224 | int | ||
1225 | GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr, | 1020 | GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr, |
1226 | uint16_t addrlen, | 1021 | uint16_t addrlen, |
1227 | struct sockaddr_in6 *r_buf) | 1022 | struct sockaddr_in6 *r_buf) |
@@ -1284,18 +1079,7 @@ GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr, | |||
1284 | } | 1079 | } |
1285 | 1080 | ||
1286 | 1081 | ||
1287 | /** | 1082 | enum GNUNET_GenericReturnValue |
1288 | * Tries to convert 'zt_addr' string to an IPv4 address. | ||
1289 | * The string is expected to have the format "1.2.3.4:80". | ||
1290 | * | ||
1291 | * @param zt_addr 0-terminated string. May be mangled by the function. | ||
1292 | * @param addrlen length of @a zt_addr (not counting 0-terminator). | ||
1293 | * @param r_buf a buffer to fill. | ||
1294 | * @return #GNUNET_OK if conversion succeeded. | ||
1295 | * #GNUNET_SYSERR otherwise, in which case | ||
1296 | * the contents of @a r_buf are undefined. | ||
1297 | */ | ||
1298 | int | ||
1299 | GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, | 1083 | GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, |
1300 | uint16_t addrlen, | 1084 | uint16_t addrlen, |
1301 | struct sockaddr_in *r_buf) | 1085 | struct sockaddr_in *r_buf) |
@@ -1333,18 +1117,7 @@ GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, | |||
1333 | } | 1117 | } |
1334 | 1118 | ||
1335 | 1119 | ||
1336 | /** | 1120 | enum GNUNET_GenericReturnValue |
1337 | * Tries to convert @a addr string to an IP (v4 or v6) address. | ||
1338 | * Will automatically decide whether to treat 'addr' as v4 or v6 address. | ||
1339 | * | ||
1340 | * @param addr a string, may not be 0-terminated. | ||
1341 | * @param addrlen number of bytes in @a addr (if addr is 0-terminated, | ||
1342 | * 0-terminator should not be counted towards addrlen). | ||
1343 | * @param r_buf a buffer to fill. | ||
1344 | * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in which | ||
1345 | * case the contents of @a r_buf are undefined. | ||
1346 | */ | ||
1347 | int | ||
1348 | GNUNET_STRINGS_to_address_ip (const char *addr, | 1121 | GNUNET_STRINGS_to_address_ip (const char *addr, |
1349 | uint16_t addrlen, | 1122 | uint16_t addrlen, |
1350 | struct sockaddr_storage *r_buf) | 1123 | struct sockaddr_storage *r_buf) |
@@ -1359,15 +1132,6 @@ GNUNET_STRINGS_to_address_ip (const char *addr, | |||
1359 | } | 1132 | } |
1360 | 1133 | ||
1361 | 1134 | ||
1362 | /** | ||
1363 | * Parse an address given as a string into a | ||
1364 | * `struct sockaddr`. | ||
1365 | * | ||
1366 | * @param addr the address | ||
1367 | * @param[out] af set to the parsed address family (e.g. AF_INET) | ||
1368 | * @param[out] sa set to the parsed address | ||
1369 | * @return 0 on error, otherwise number of bytes in @a sa | ||
1370 | */ | ||
1371 | size_t | 1135 | size_t |
1372 | GNUNET_STRINGS_parse_socket_addr (const char *addr, | 1136 | GNUNET_STRINGS_parse_socket_addr (const char *addr, |
1373 | uint8_t *af, | 1137 | uint8_t *af, |
@@ -1441,21 +1205,7 @@ _make_continuous_arg_copy (int argc, char *const *argv) | |||
1441 | } | 1205 | } |
1442 | 1206 | ||
1443 | 1207 | ||
1444 | /** | 1208 | enum GNUNET_GenericReturnValue |
1445 | * Returns utf-8 encoded arguments. | ||
1446 | * Does nothing (returns a copy of argc and argv) on any platform | ||
1447 | * other than W32. | ||
1448 | * Returned argv has u8argv[u8argc] == NULL. | ||
1449 | * Returned argv is a single memory block, and can be freed with a single | ||
1450 | * GNUNET_free() call. | ||
1451 | * | ||
1452 | * @param argc argc (as given by main()) | ||
1453 | * @param argv argv (as given by main()) | ||
1454 | * @param u8argc a location to store new argc in (though it's th same as argc) | ||
1455 | * @param u8argv a location to store new argv in | ||
1456 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure | ||
1457 | */ | ||
1458 | int | ||
1459 | GNUNET_STRINGS_get_utf8_args (int argc, | 1209 | GNUNET_STRINGS_get_utf8_args (int argc, |
1460 | char *const *argv, | 1210 | char *const *argv, |
1461 | int *u8argc, | 1211 | int *u8argc, |
@@ -1478,7 +1228,7 @@ GNUNET_STRINGS_get_utf8_args (int argc, | |||
1478 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the | 1228 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the |
1479 | * @a port_policy is malformed | 1229 | * @a port_policy is malformed |
1480 | */ | 1230 | */ |
1481 | static int | 1231 | static enum GNUNET_GenericReturnValue |
1482 | parse_port_policy (const char *port_policy, | 1232 | parse_port_policy (const char *port_policy, |
1483 | struct GNUNET_STRINGS_PortPolicy *pp) | 1233 | struct GNUNET_STRINGS_PortPolicy *pp) |
1484 | { | 1234 | { |
@@ -1523,18 +1273,6 @@ parse_port_policy (const char *port_policy, | |||
1523 | } | 1273 | } |
1524 | 1274 | ||
1525 | 1275 | ||
1526 | /** | ||
1527 | * Parse an IPv4 network policy. The argument specifies a list of | ||
1528 | * subnets. The format is | ||
1529 | * <tt>(network[/netmask][:SPORT[-DPORT]];)*</tt> (no whitespace, must | ||
1530 | * be terminated with a semicolon). The network must be given in | ||
1531 | * dotted-decimal notation. The netmask can be given in CIDR notation | ||
1532 | * (/16) or in dotted-decimal (/255.255.0.0). | ||
1533 | * | ||
1534 | * @param routeListX a string specifying the IPv4 subnets | ||
1535 | * @return the converted list, terminated with all zeros; | ||
1536 | * NULL if the synatx is flawed | ||
1537 | */ | ||
1538 | struct GNUNET_STRINGS_IPv4NetworkPolicy * | 1276 | struct GNUNET_STRINGS_IPv4NetworkPolicy * |
1539 | GNUNET_STRINGS_parse_ipv4_policy (const char *routeListX) | 1277 | GNUNET_STRINGS_parse_ipv4_policy (const char *routeListX) |
1540 | { | 1278 | { |
@@ -1716,17 +1454,6 @@ GNUNET_STRINGS_parse_ipv4_policy (const char *routeListX) | |||
1716 | } | 1454 | } |
1717 | 1455 | ||
1718 | 1456 | ||
1719 | /** | ||
1720 | * Parse an IPv6 network policy. The argument specifies a list of | ||
1721 | * subnets. The format is <tt>(network[/netmask[:SPORT[-DPORT]]];)*</tt> | ||
1722 | * (no whitespace, must be terminated with a semicolon). The network | ||
1723 | * must be given in colon-hex notation. The netmask must be given in | ||
1724 | * CIDR notation (/16) or can be omitted to specify a single host. | ||
1725 | * Note that the netmask is mandatory if ports are specified. | ||
1726 | * | ||
1727 | * @param routeListX a string specifying the policy | ||
1728 | * @return the converted list, 0-terminated, NULL if the synatx is flawed | ||
1729 | */ | ||
1730 | struct GNUNET_STRINGS_IPv6NetworkPolicy * | 1457 | struct GNUNET_STRINGS_IPv6NetworkPolicy * |
1731 | GNUNET_STRINGS_parse_ipv6_policy (const char *routeListX) | 1458 | GNUNET_STRINGS_parse_ipv6_policy (const char *routeListX) |
1732 | { | 1459 | { |
@@ -1863,17 +1590,10 @@ static char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |||
1863 | "0123456789+/"; | 1590 | "0123456789+/"; |
1864 | 1591 | ||
1865 | 1592 | ||
1866 | /** | ||
1867 | * Encode into Base64. | ||
1868 | * | ||
1869 | * @param in the data to encode | ||
1870 | * @param len the length of the input | ||
1871 | * @param output where to write the output (*output should be NULL, | ||
1872 | * is allocated) | ||
1873 | * @return the size of the output | ||
1874 | */ | ||
1875 | size_t | 1593 | size_t |
1876 | GNUNET_STRINGS_base64_encode (const void *in, size_t len, char **output) | 1594 | GNUNET_STRINGS_base64_encode (const void *in, |
1595 | size_t len, | ||
1596 | char **output) | ||
1877 | { | 1597 | { |
1878 | const char *data = in; | 1598 | const char *data = in; |
1879 | size_t ret; | 1599 | size_t ret; |
@@ -1919,17 +1639,10 @@ GNUNET_STRINGS_base64_encode (const void *in, size_t len, char **output) | |||
1919 | } | 1639 | } |
1920 | 1640 | ||
1921 | 1641 | ||
1922 | /** | ||
1923 | * Encode into Base64url. RFC7515 | ||
1924 | * | ||
1925 | * @param in the data to encode | ||
1926 | * @param len the length of the input | ||
1927 | * @param output where to write the output (*output should be NULL, | ||
1928 | * is allocated) | ||
1929 | * @return the size of the output | ||
1930 | */ | ||
1931 | size_t | 1642 | size_t |
1932 | GNUNET_STRINGS_base64url_encode (const void *in, size_t len, char **output) | 1643 | GNUNET_STRINGS_base64url_encode (const void *in, |
1644 | size_t len, | ||
1645 | char **output) | ||
1933 | { | 1646 | { |
1934 | char *enc; | 1647 | char *enc; |
1935 | size_t pos; | 1648 | size_t pos; |
@@ -1965,17 +1678,10 @@ GNUNET_STRINGS_base64url_encode (const void *in, size_t len, char **output) | |||
1965 | : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1) | 1678 | : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1) |
1966 | 1679 | ||
1967 | 1680 | ||
1968 | /** | ||
1969 | * Decode from Base64. | ||
1970 | * | ||
1971 | * @param data the data to encode | ||
1972 | * @param len the length of the input | ||
1973 | * @param output where to write the output (*output should be NULL, | ||
1974 | * is allocated) | ||
1975 | * @return the size of the output | ||
1976 | */ | ||
1977 | size_t | 1681 | size_t |
1978 | GNUNET_STRINGS_base64_decode (const char *data, size_t len, void **out) | 1682 | GNUNET_STRINGS_base64_decode (const char *data, |
1683 | size_t len, | ||
1684 | void **out) | ||
1979 | { | 1685 | { |
1980 | char *output; | 1686 | char *output; |
1981 | size_t ret = 0; | 1687 | size_t ret = 0; |
@@ -2037,17 +1743,10 @@ END: | |||
2037 | } | 1743 | } |
2038 | 1744 | ||
2039 | 1745 | ||
2040 | /** | ||
2041 | * Decode from Base64url. RFC7515 | ||
2042 | * | ||
2043 | * @param data the data to decode | ||
2044 | * @param len the length of the input | ||
2045 | * @param output where to write the output (*output should be NULL, | ||
2046 | * is allocated) | ||
2047 | * @return the size of the output | ||
2048 | */ | ||
2049 | size_t | 1746 | size_t |
2050 | GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out) | 1747 | GNUNET_STRINGS_base64url_decode (const char *data, |
1748 | size_t len, | ||
1749 | void **out) | ||
2051 | { | 1750 | { |
2052 | char *s; | 1751 | char *s; |
2053 | int padding; | 1752 | int padding; |
@@ -2090,17 +1789,10 @@ GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out) | |||
2090 | } | 1789 | } |
2091 | 1790 | ||
2092 | 1791 | ||
2093 | /** | ||
2094 | * url/percent encode (RFC3986). | ||
2095 | * | ||
2096 | * @param data the data to encode | ||
2097 | * @param len the length of the input | ||
2098 | * @param output where to write the output (*output should be NULL, | ||
2099 | * is allocated) | ||
2100 | * @return the size of the output | ||
2101 | */ | ||
2102 | size_t | 1792 | size_t |
2103 | GNUNET_STRINGS_urldecode (const char *data, size_t len, char **out) | 1793 | GNUNET_STRINGS_urldecode (const char *data, |
1794 | size_t len, | ||
1795 | char **out) | ||
2104 | { | 1796 | { |
2105 | const char *rpos = data; | 1797 | const char *rpos = data; |
2106 | *out = GNUNET_malloc (len + 1); /* output should always fit into input */ | 1798 | *out = GNUNET_malloc (len + 1); /* output should always fit into input */ |
@@ -2134,17 +1826,10 @@ GNUNET_STRINGS_urldecode (const char *data, size_t len, char **out) | |||
2134 | } | 1826 | } |
2135 | 1827 | ||
2136 | 1828 | ||
2137 | /** | ||
2138 | * url/percent encode (RFC3986). | ||
2139 | * | ||
2140 | * @param data the data to decode | ||
2141 | * @param len the length of the input | ||
2142 | * @param output where to write the output (*output should be NULL, | ||
2143 | * is allocated) | ||
2144 | * @return the size of the output | ||
2145 | */ | ||
2146 | size_t | 1829 | size_t |
2147 | GNUNET_STRINGS_urlencode (const char *data, size_t len, char **out) | 1830 | GNUNET_STRINGS_urlencode (const char *data, |
1831 | size_t len, | ||
1832 | char **out) | ||
2148 | { | 1833 | { |
2149 | struct GNUNET_Buffer buf = { 0 }; | 1834 | struct GNUNET_Buffer buf = { 0 }; |
2150 | const uint8_t *i8 = (uint8_t *) data; | 1835 | const uint8_t *i8 = (uint8_t *) data; |