GNUnet  0.11.x
pq_result_helper.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2014, 2015, 2016 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  */
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 #include "gnunet_pq_lib.h"
28 
29 
37 static void
38 clean_varsize_blob (void *cls,
39  void *rd)
40 {
41  void **dst = rd;
42 
43  (void) cls;
44  if (NULL != *dst)
45  {
46  GNUNET_free (*dst);
47  *dst = NULL;
48  }
49 }
50 
51 
65 static int
67  PGresult *result,
68  int row,
69  const char *fname,
70  size_t *dst_size,
71  void *dst)
72 {
73  size_t len;
74  const char *res;
75  void *idst;
76  int fnum;
77 
78  (void) cls;
79  *dst_size = 0;
80  *((void **) dst) = NULL;
81 
82  fnum = PQfnumber (result,
83  fname);
84  if (fnum < 0)
85  {
86  GNUNET_break (0);
87  return GNUNET_SYSERR;
88  }
89  if (PQgetisnull (result,
90  row,
91  fnum))
92  {
93  /* Let's allow this for varsize */
94  return GNUNET_OK;
95  }
96  /* if a field is null, continue but
97  * remember that we now return a different result */
98  len = PQgetlength (result,
99  row,
100  fnum);
101  res = PQgetvalue (result,
102  row,
103  fnum);
104  GNUNET_assert (NULL != res);
105  *dst_size = len;
106  idst = GNUNET_malloc (len);
107  *((void **) dst) = idst;
108  GNUNET_memcpy (idst,
109  res,
110  len);
111  return GNUNET_OK;
112 }
113 
114 
125  void **dst,
126  size_t *sptr)
127 {
128  struct GNUNET_PQ_ResultSpec res =
130  &clean_varsize_blob, NULL,
131  (void *) (dst), 0, name, sptr };
132 
133  return res;
134 }
135 
136 
150 static int
152  PGresult *result,
153  int row,
154  const char *fname,
155  size_t *dst_size,
156  void *dst)
157 {
158  size_t len;
159  const char *res;
160  int fnum;
161 
162  (void) cls;
163  fnum = PQfnumber (result,
164  fname);
165  if (fnum < 0)
166  {
167  GNUNET_break (0);
168  return GNUNET_SYSERR;
169  }
170  if (PQgetisnull (result,
171  row,
172  fnum))
173  {
174  GNUNET_break (0);
175  return GNUNET_SYSERR;
176  }
177 
178  /* if a field is null, continue but
179  * remember that we now return a different result */
180  len = PQgetlength (result,
181  row,
182  fnum);
183  if (*dst_size != len)
184  {
185  GNUNET_break (0);
186  return GNUNET_SYSERR;
187  }
188  res = PQgetvalue (result,
189  row,
190  fnum);
191  GNUNET_assert (NULL != res);
192  GNUNET_memcpy (dst,
193  res,
194  len);
195  return GNUNET_OK;
196 }
197 
198 
209  void *dst,
210  size_t dst_size)
211 {
212  struct GNUNET_PQ_ResultSpec res =
214  NULL, NULL,
215  (dst), dst_size, name, NULL };
216 
217  return res;
218 }
219 
220 
234 static int
236  PGresult *result,
237  int row,
238  const char *fname,
239  size_t *dst_size,
240  void *dst)
241 {
242  struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
243  size_t len;
244  const char *res;
245  int fnum;
246 
247  (void) cls;
248  *pk = NULL;
249  fnum = PQfnumber (result,
250  fname);
251  if (fnum < 0)
252  {
253  GNUNET_break (0);
254  return GNUNET_SYSERR;
255  }
256  if (PQgetisnull (result,
257  row,
258  fnum))
259  {
260  GNUNET_break (0);
261  return GNUNET_SYSERR;
262  }
263  /* if a field is null, continue but
264  * remember that we now return a different result */
265  len = PQgetlength (result,
266  row,
267  fnum);
268  res = PQgetvalue (result,
269  row,
270  fnum);
272  len);
273  if (NULL == *pk)
274  {
275  GNUNET_break (0);
276  return GNUNET_SYSERR;
277  }
278  return GNUNET_OK;
279 }
280 
281 
289 static void
291  void *rd)
292 {
293  struct GNUNET_CRYPTO_RsaPublicKey **pk = rd;
294 
295  (void) cls;
296  if (NULL != *pk)
297  {
299  *pk = NULL;
300  }
301 }
302 
303 
313  struct GNUNET_CRYPTO_RsaPublicKey **rsa)
314 {
315  struct GNUNET_PQ_ResultSpec res =
318  NULL,
319  (void *) rsa, 0, name, NULL };
320 
321  return res;
322 }
323 
324 
338 static int
340  PGresult *result,
341  int row,
342  const char *fname,
343  size_t *dst_size,
344  void *dst)
345 {
346  struct GNUNET_CRYPTO_RsaSignature **sig = dst;
347  size_t len;
348  const char *res;
349  int fnum;
350 
351  (void) cls;
352  *sig = NULL;
353  fnum = PQfnumber (result,
354  fname);
355  if (fnum < 0)
356  {
357  GNUNET_break (0);
358  return GNUNET_SYSERR;
359  }
360  if (PQgetisnull (result,
361  row,
362  fnum))
363  {
364  GNUNET_break (0);
365  return GNUNET_SYSERR;
366  }
367  /* if a field is null, continue but
368  * remember that we now return a different result */
369  len = PQgetlength (result,
370  row,
371  fnum);
372  res = PQgetvalue (result,
373  row,
374  fnum);
376  len);
377  if (NULL == *sig)
378  {
379  GNUNET_break (0);
380  return GNUNET_SYSERR;
381  }
382  return GNUNET_OK;
383 }
384 
385 
393 static void
395  void *rd)
396 {
397  struct GNUNET_CRYPTO_RsaSignature **sig = rd;
398 
399  (void) cls;
400  if (NULL != *sig)
401  {
403  *sig = NULL;
404  }
405 }
406 
407 
417  struct GNUNET_CRYPTO_RsaSignature **sig)
418 {
419  struct GNUNET_PQ_ResultSpec res =
422  NULL,
423  (void *) sig, 0, (name), NULL };
424 
425  return res;
426 }
427 
428 
442 static int
444  PGresult *result,
445  int row,
446  const char *fname,
447  size_t *dst_size,
448  void *dst)
449 {
450  char **str = dst;
451  size_t len;
452  const char *res;
453  int fnum;
454 
455  (void) cls;
456  *str = NULL;
457  fnum = PQfnumber (result,
458  fname);
459  if (fnum < 0)
460  {
461  GNUNET_break (0);
462  return GNUNET_SYSERR;
463  }
464  if (PQgetisnull (result,
465  row,
466  fnum))
467  {
468  GNUNET_break (0);
469  return GNUNET_SYSERR;
470  }
471  /* if a field is null, continue but
472  * remember that we now return a different result */
473  len = PQgetlength (result,
474  row,
475  fnum);
476  res = PQgetvalue (result,
477  row,
478  fnum);
479  *str = GNUNET_strndup (res,
480  len);
481  if (NULL == *str)
482  {
483  GNUNET_break (0);
484  return GNUNET_SYSERR;
485  }
486  return GNUNET_OK;
487 }
488 
489 
497 static void
499  void *rd)
500 {
501  char **str = rd;
502 
503  (void) cls;
504  if (NULL != *str)
505  {
506  GNUNET_free (*str);
507  *str = NULL;
508  }
509 }
510 
511 
521  char **dst)
522 {
523  struct GNUNET_PQ_ResultSpec res =
524  { &extract_string,
525  &clean_string,
526  NULL,
527  (void *) dst, 0, (name), NULL };
528 
529  return res;
530 }
531 
532 
546 static int
548  PGresult *result,
549  int row,
550  const char *fname,
551  size_t *dst_size,
552  void *dst)
553 {
554  struct GNUNET_TIME_Absolute *udst = dst;
555  const int64_t *res;
556  int fnum;
557 
558  (void) cls;
559  fnum = PQfnumber (result,
560  fname);
561  if (fnum < 0)
562  {
563  GNUNET_break (0);
564  return GNUNET_SYSERR;
565  }
566  if (PQgetisnull (result,
567  row,
568  fnum))
569  {
570  GNUNET_break (0);
571  return GNUNET_SYSERR;
572  }
573  GNUNET_assert (NULL != dst);
574  if (sizeof(struct GNUNET_TIME_Absolute) != *dst_size)
575  {
576  GNUNET_break (0);
577  return GNUNET_SYSERR;
578  }
579  if (sizeof(int64_t) !=
580  PQgetlength (result,
581  row,
582  fnum))
583  {
584  GNUNET_break (0);
585  return GNUNET_SYSERR;
586  }
587  res = (int64_t *) PQgetvalue (result,
588  row,
589  fnum);
590  if (INT64_MAX == GNUNET_ntohll ((uint64_t) *res))
592  else
593  udst->abs_value_us = GNUNET_ntohll ((uint64_t) *res);
594  return GNUNET_OK;
595 }
596 
597 
607  struct GNUNET_TIME_Absolute *at)
608 {
609  struct GNUNET_PQ_ResultSpec res =
610  { &extract_abs_time,
611  NULL,
612  NULL,
613  (void *) at, sizeof(*at), (name), NULL };
614 
615  return res;
616 }
617 
618 
628  struct GNUNET_TIME_AbsoluteNBO *at)
629 {
630  struct GNUNET_PQ_ResultSpec res =
631  GNUNET_PQ_result_spec_auto_from_type (name, &at->abs_value_us__);
632 
633  return res;
634 }
635 
636 
650 static int
652  PGresult *result,
653  int row,
654  const char *fname,
655  size_t *dst_size,
656  void *dst)
657 {
658  uint16_t *udst = dst;
659  const uint16_t *res;
660  int fnum;
661 
662  (void) cls;
663  fnum = PQfnumber (result,
664  fname);
665  if (fnum < 0)
666  {
667  GNUNET_break (0);
668  return GNUNET_SYSERR;
669  }
670  if (PQgetisnull (result,
671  row,
672  fnum))
673  {
674  GNUNET_break (0);
675  return GNUNET_SYSERR;
676  }
677  GNUNET_assert (NULL != dst);
678  if (sizeof(uint16_t) != *dst_size)
679  {
680  GNUNET_break (0);
681  return GNUNET_SYSERR;
682  }
683  if (sizeof(uint16_t) !=
684  PQgetlength (result,
685  row,
686  fnum))
687  {
688  GNUNET_break (0);
689  return GNUNET_SYSERR;
690  }
691  res = (uint16_t *) PQgetvalue (result,
692  row,
693  fnum);
694  *udst = ntohs (*res);
695  return GNUNET_OK;
696 }
697 
698 
708  uint16_t *u16)
709 {
710  struct GNUNET_PQ_ResultSpec res =
711  { &extract_uint16,
712  NULL,
713  NULL,
714  (void *) u16, sizeof(*u16), (name), NULL };
715 
716  return res;
717 }
718 
719 
733 static int
735  PGresult *result,
736  int row,
737  const char *fname,
738  size_t *dst_size,
739  void *dst)
740 {
741  uint32_t *udst = dst;
742  const uint32_t *res;
743  int fnum;
744 
745  (void) cls;
746  fnum = PQfnumber (result,
747  fname);
748  if (fnum < 0)
749  {
750  GNUNET_break (0);
751  return GNUNET_SYSERR;
752  }
753  if (PQgetisnull (result,
754  row,
755  fnum))
756  {
757  GNUNET_break (0);
758  return GNUNET_SYSERR;
759  }
760  GNUNET_assert (NULL != dst);
761  if (sizeof(uint32_t) != *dst_size)
762  {
763  GNUNET_break (0);
764  return GNUNET_SYSERR;
765  }
766  if (sizeof(uint32_t) !=
767  PQgetlength (result,
768  row,
769  fnum))
770  {
771  GNUNET_break (0);
772  return GNUNET_SYSERR;
773  }
774  res = (uint32_t *) PQgetvalue (result,
775  row,
776  fnum);
777  *udst = ntohl (*res);
778  return GNUNET_OK;
779 }
780 
781 
791  uint32_t *u32)
792 {
793  struct GNUNET_PQ_ResultSpec res =
794  { &extract_uint32,
795  NULL,
796  NULL,
797  (void *) u32, sizeof(*u32), (name), NULL };
798 
799  return res;
800 }
801 
802 
816 static int
818  PGresult *result,
819  int row,
820  const char *fname,
821  size_t *dst_size,
822  void *dst)
823 {
824  uint64_t *udst = dst;
825  const uint64_t *res;
826  int fnum;
827 
828  (void) cls;
829  fnum = PQfnumber (result,
830  fname);
831  if (fnum < 0)
832  {
833  GNUNET_break (0);
834  return GNUNET_SYSERR;
835  }
836  if (PQgetisnull (result,
837  row,
838  fnum))
839  {
840  GNUNET_break (0);
841  return GNUNET_SYSERR;
842  }
843  GNUNET_assert (NULL != dst);
844  if (sizeof(uint64_t) != *dst_size)
845  {
846  GNUNET_break (0);
847  return GNUNET_SYSERR;
848  }
849  if (sizeof(uint64_t) !=
850  PQgetlength (result,
851  row,
852  fnum))
853  {
854  GNUNET_break (0);
855  return GNUNET_SYSERR;
856  }
857  res = (uint64_t *) PQgetvalue (result,
858  row,
859  fnum);
860  *udst = GNUNET_ntohll (*res);
861  return GNUNET_OK;
862 }
863 
864 
874  uint64_t *u64)
875 {
876  struct GNUNET_PQ_ResultSpec res =
877  { &extract_uint64,
878  NULL,
879  NULL,
880  (void *) u64, sizeof(*u64), (name), NULL };
881 
882  return res;
883 }
884 
885 
886 /* end of pq_result_helper.c */
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_rsa_public_key(const char *name, struct GNUNET_CRYPTO_RsaPublicKey **rsa)
RSA public key expected.
static struct GNUNET_CRYPTO_EddsaPrivateKey * pk
Private key of this peer.
static void clean_string(void *cls, void *rd)
Function called to clean up memory allocated by a GNUNET_PQ_ResultConverter.
an RSA signature
Definition: crypto_rsa.c:65
void GNUNET_CRYPTO_rsa_signature_free(struct GNUNET_CRYPTO_RsaSignature *sig)
Free memory occupied by signature.
Definition: crypto_rsa.c:1112
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint16(const char *name, uint16_t *u16)
uint16_t expected.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_absolute_time_nbo(const char *name, struct GNUNET_TIME_AbsoluteNBO *at)
Absolute time in network byte order expected.
const char * fname
Field name of the desired result.
Description of a DB result cell.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int extract_uint64(void *cls, PGresult *result, int row, const char *fname, size_t *dst_size, void *dst)
Extract data from a Postgres database result at row row.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static void clean_rsa_signature(void *cls, void *rd)
Function called to clean up memory allocated by a GNUNET_PQ_ResultConverter.
Time for absolute time used by GNUnet, in microseconds and in network byte order. ...
uint64_t abs_value_us
The actual value.
The public information of an RSA key pair.
Definition: crypto_rsa.c:53
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
static int extract_fixed_blob(void *cls, PGresult *result, int row, const char *fname, size_t *dst_size, void *dst)
Extract data from a Postgres database result at row row.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint64(const char *name, uint64_t *u64)
uint64_t expected.
static int extract_varsize_blob(void *cls, PGresult *result, int row, const char *fname, size_t *dst_size, void *dst)
Extract data from a Postgres database result at row row.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_rsa_signature(const char *name, struct GNUNET_CRYPTO_RsaSignature **sig)
RSA signature expected.
void * cls
Closure for conv and cleaner.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint32(const char *name, uint32_t *u32)
uint32_t expected.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_fixed_size(const char *name, void *dst, size_t dst_size)
Fixed-size result expected.
static int extract_string(void *cls, PGresult *result, int row, const char *fname, size_t *dst_size, void *dst)
Extract data from a Postgres database result at row row.
struct GNUNET_CRYPTO_RsaPublicKey * GNUNET_CRYPTO_rsa_public_key_decode(const char *buf, size_t len)
Decode the public key from the data-format back to the "normal", internal format. ...
Definition: crypto_rsa.c:465
static int extract_uint32(void *cls, PGresult *result, int row, const char *fname, size_t *dst_size, void *dst)
Extract data from a Postgres database result at row row.
static int result
Global testing status.
size_t dst_size
Allowed size for the data, 0 for variable-size (in this case, the type of dst is a void ** and we nee...
static int res
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_string(const char *name, char **dst)
0-terminated string expected.
#define GNUNET_PQ_result_spec_auto_from_type(name, dst)
We expect a fixed-size result, with size determined by the type of * dst
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static int extract_abs_time(void *cls, PGresult *result, int row, const char *fname, size_t *dst_size, void *dst)
Extract data from a Postgres database result at row row.
helper functions for Postgres DB interactions
static int extract_rsa_signature(void *cls, PGresult *result, int row, const char *fname, size_t *dst_size, void *dst)
Extract data from a Postgres database result at row row.
static void clean_rsa_public_key(void *cls, void *rd)
Function called to clean up memory allocated by a GNUNET_PQ_ResultConverter.
static void clean_varsize_blob(void *cls, void *rd)
Function called to clean up memory allocated by a GNUNET_PQ_ResultConverter.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
static int extract_rsa_public_key(void *cls, PGresult *result, int row, const char *fname, size_t *dst_size, void *dst)
Extract data from a Postgres database result at row row.
const char * name
struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_signature_decode(const char *buf, size_t len)
Decode the signature from the data-format back to the "normal", internal format.
Definition: crypto_rsa.c:1192
static int extract_uint16(void *cls, PGresult *result, int row, const char *fname, size_t *dst_size, void *dst)
Extract data from a Postgres database result at row row.
void GNUNET_CRYPTO_rsa_public_key_free(struct GNUNET_CRYPTO_RsaPublicKey *key)
Free memory occupied by the public key.
Definition: crypto_rsa.c:307
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_variable_size(const char *name, void **dst, size_t *sptr)
Variable-size result expected.
Time for absolute times used by GNUnet, in microseconds.
void * dst
Destination for the data.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_absolute_time(const char *name, struct GNUNET_TIME_Absolute *at)
Absolute time expected.
#define GNUNET_malloc(size)
Wrapper around malloc.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...