GNUnet  0.10.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  return res;
133 }
134 
135 
149 static int
151  PGresult *result,
152  int row,
153  const char *fname,
154  size_t *dst_size,
155  void *dst)
156 {
157  size_t len;
158  const char *res;
159  int fnum;
160 
161  (void) cls;
162  fnum = PQfnumber (result,
163  fname);
164  if (fnum < 0)
165  {
166  GNUNET_break (0);
167  return GNUNET_SYSERR;
168  }
169  if (PQgetisnull (result,
170  row,
171  fnum))
172  {
173  GNUNET_break (0);
174  return GNUNET_SYSERR;
175  }
176 
177  /* if a field is null, continue but
178  * remember that we now return a different result */
179  len = PQgetlength (result,
180  row,
181  fnum);
182  if (*dst_size != len)
183  {
184  GNUNET_break (0);
185  return GNUNET_SYSERR;
186  }
187  res = PQgetvalue (result,
188  row,
189  fnum);
190  GNUNET_assert (NULL != res);
191  GNUNET_memcpy (dst,
192  res,
193  len);
194  return GNUNET_OK;
195 }
196 
197 
208  void *dst,
209  size_t dst_size)
210 {
211  struct GNUNET_PQ_ResultSpec res =
213  NULL, NULL,
214  (dst), dst_size, name, NULL };
215  return res;
216 }
217 
218 
232 static int
234  PGresult *result,
235  int row,
236  const char *fname,
237  size_t *dst_size,
238  void *dst)
239 {
240  struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
241  size_t len;
242  const char *res;
243  int fnum;
244 
245  (void) cls;
246  *pk = NULL;
247  fnum = PQfnumber (result,
248  fname);
249  if (fnum < 0)
250  {
251  GNUNET_break (0);
252  return GNUNET_SYSERR;
253  }
254  if (PQgetisnull (result,
255  row,
256  fnum))
257  {
258  GNUNET_break (0);
259  return GNUNET_SYSERR;
260  }
261  /* if a field is null, continue but
262  * remember that we now return a different result */
263  len = PQgetlength (result,
264  row,
265  fnum);
266  res = PQgetvalue (result,
267  row,
268  fnum);
270  len);
271  if (NULL == *pk)
272  {
273  GNUNET_break (0);
274  return GNUNET_SYSERR;
275  }
276  return GNUNET_OK;
277 }
278 
279 
287 static void
289  void *rd)
290 {
291  struct GNUNET_CRYPTO_RsaPublicKey **pk = rd;
292 
293  (void) cls;
294  if (NULL != *pk)
295  {
297  *pk = NULL;
298  }
299 }
300 
301 
311  struct GNUNET_CRYPTO_RsaPublicKey **rsa)
312 {
313  struct GNUNET_PQ_ResultSpec res =
316  NULL,
317  (void *) rsa, 0, name, NULL };
318  return res;
319 }
320 
321 
335 static int
337  PGresult *result,
338  int row,
339  const char *fname,
340  size_t *dst_size,
341  void *dst)
342 {
343  struct GNUNET_CRYPTO_RsaSignature **sig = dst;
344  size_t len;
345  const char *res;
346  int fnum;
347 
348  (void) cls;
349  *sig = NULL;
350  fnum = PQfnumber (result,
351  fname);
352  if (fnum < 0)
353  {
354  GNUNET_break (0);
355  return GNUNET_SYSERR;
356  }
357  if (PQgetisnull (result,
358  row,
359  fnum))
360  {
361  GNUNET_break (0);
362  return GNUNET_SYSERR;
363  }
364  /* if a field is null, continue but
365  * remember that we now return a different result */
366  len = PQgetlength (result,
367  row,
368  fnum);
369  res = PQgetvalue (result,
370  row,
371  fnum);
373  len);
374  if (NULL == *sig)
375  {
376  GNUNET_break (0);
377  return GNUNET_SYSERR;
378  }
379  return GNUNET_OK;
380 }
381 
382 
390 static void
392  void *rd)
393 {
394  struct GNUNET_CRYPTO_RsaSignature **sig = rd;
395 
396  (void) cls;
397  if (NULL != *sig)
398  {
400  *sig = NULL;
401  }
402 }
403 
404 
414  struct GNUNET_CRYPTO_RsaSignature **sig)
415 {
416  struct GNUNET_PQ_ResultSpec res =
419  NULL,
420  (void *) sig, 0, (name), NULL };
421  return res;
422 }
423 
424 
438 static int
440  PGresult *result,
441  int row,
442  const char *fname,
443  size_t *dst_size,
444  void *dst)
445 {
446  char **str = dst;
447  size_t len;
448  const char *res;
449  int fnum;
450 
451  (void) cls;
452  *str = NULL;
453  fnum = PQfnumber (result,
454  fname);
455  if (fnum < 0)
456  {
457  GNUNET_break (0);
458  return GNUNET_SYSERR;
459  }
460  if (PQgetisnull (result,
461  row,
462  fnum))
463  {
464  GNUNET_break (0);
465  return GNUNET_SYSERR;
466  }
467  /* if a field is null, continue but
468  * remember that we now return a different result */
469  len = PQgetlength (result,
470  row,
471  fnum);
472  res = PQgetvalue (result,
473  row,
474  fnum);
475  *str = GNUNET_strndup (res,
476  len);
477  if (NULL == *str)
478  {
479  GNUNET_break (0);
480  return GNUNET_SYSERR;
481  }
482  return GNUNET_OK;
483 }
484 
485 
493 static void
495  void *rd)
496 {
497  char **str = rd;
498 
499  (void) cls;
500  if (NULL != *str)
501  {
502  GNUNET_free (*str);
503  *str = NULL;
504  }
505 }
506 
507 
517  char **dst)
518 {
519  struct GNUNET_PQ_ResultSpec res =
520  { &extract_string,
521  &clean_string,
522  NULL,
523  (void *) dst, 0, (name), NULL };
524  return res;
525 }
526 
527 
541 static int
543  PGresult *result,
544  int row,
545  const char *fname,
546  size_t *dst_size,
547  void *dst)
548 {
549  struct GNUNET_TIME_Absolute *udst = dst;
550  const int64_t *res;
551  int fnum;
552 
553  (void) cls;
554  fnum = PQfnumber (result,
555  fname);
556  if (fnum < 0)
557  {
558  GNUNET_break (0);
559  return GNUNET_SYSERR;
560  }
561  if (PQgetisnull (result,
562  row,
563  fnum))
564  {
565  GNUNET_break (0);
566  return GNUNET_SYSERR;
567  }
568  GNUNET_assert (NULL != dst);
569  if (sizeof (struct GNUNET_TIME_Absolute) != *dst_size)
570  {
571  GNUNET_break (0);
572  return GNUNET_SYSERR;
573  }
574  if (sizeof (int64_t) !=
575  PQgetlength (result,
576  row,
577  fnum))
578  {
579  GNUNET_break (0);
580  return GNUNET_SYSERR;
581  }
582  res = (int64_t *) PQgetvalue (result,
583  row,
584  fnum);
585  if (INT64_MAX == *res)
587  else
588  udst->abs_value_us = GNUNET_ntohll ((uint64_t) *res);
589  return GNUNET_OK;
590 }
591 
592 
602  struct GNUNET_TIME_Absolute *at)
603 {
604  struct GNUNET_PQ_ResultSpec res =
605  { &extract_abs_time,
606  NULL,
607  NULL,
608  (void *) at, sizeof (*at), (name), NULL };
609  return res;
610 }
611 
612 
622  struct GNUNET_TIME_AbsoluteNBO *at)
623 {
624  struct GNUNET_PQ_ResultSpec res =
625  GNUNET_PQ_result_spec_auto_from_type(name, &at->abs_value_us__);
626  return res;
627 }
628 
629 
643 static int
645  PGresult *result,
646  int row,
647  const char *fname,
648  size_t *dst_size,
649  void *dst)
650 {
651  uint16_t *udst = dst;
652  const uint16_t *res;
653  int fnum;
654 
655  (void) cls;
656  fnum = PQfnumber (result,
657  fname);
658  if (fnum < 0)
659  {
660  GNUNET_break (0);
661  return GNUNET_SYSERR;
662  }
663  if (PQgetisnull (result,
664  row,
665  fnum))
666  {
667  GNUNET_break (0);
668  return GNUNET_SYSERR;
669  }
670  GNUNET_assert (NULL != dst);
671  if (sizeof (uint16_t) != *dst_size)
672  {
673  GNUNET_break (0);
674  return GNUNET_SYSERR;
675  }
676  if (sizeof (uint16_t) !=
677  PQgetlength (result,
678  row,
679  fnum))
680  {
681  GNUNET_break (0);
682  return GNUNET_SYSERR;
683  }
684  res = (uint16_t *) PQgetvalue (result,
685  row,
686  fnum);
687  *udst = ntohs (*res);
688  return GNUNET_OK;
689 }
690 
691 
701  uint16_t *u16)
702 {
703  struct GNUNET_PQ_ResultSpec res =
704  { &extract_uint16,
705  NULL,
706  NULL,
707  (void *) u16, sizeof (*u16), (name), NULL };
708  return res;
709 }
710 
711 
725 static int
727  PGresult *result,
728  int row,
729  const char *fname,
730  size_t *dst_size,
731  void *dst)
732 {
733  uint32_t *udst = dst;
734  const uint32_t *res;
735  int fnum;
736 
737  (void) cls;
738  fnum = PQfnumber (result,
739  fname);
740  if (fnum < 0)
741  {
742  GNUNET_break (0);
743  return GNUNET_SYSERR;
744  }
745  if (PQgetisnull (result,
746  row,
747  fnum))
748  {
749  GNUNET_break (0);
750  return GNUNET_SYSERR;
751  }
752  GNUNET_assert (NULL != dst);
753  if (sizeof (uint32_t) != *dst_size)
754  {
755  GNUNET_break (0);
756  return GNUNET_SYSERR;
757  }
758  if (sizeof (uint32_t) !=
759  PQgetlength (result,
760  row,
761  fnum))
762  {
763  GNUNET_break (0);
764  return GNUNET_SYSERR;
765  }
766  res = (uint32_t *) PQgetvalue (result,
767  row,
768  fnum);
769  *udst = ntohl (*res);
770  return GNUNET_OK;
771 }
772 
773 
783  uint32_t *u32)
784 {
785  struct GNUNET_PQ_ResultSpec res =
786  { &extract_uint32,
787  NULL,
788  NULL,
789  (void *) u32, sizeof (*u32), (name), NULL };
790  return res;
791 }
792 
793 
807 static int
809  PGresult *result,
810  int row,
811  const char *fname,
812  size_t *dst_size,
813  void *dst)
814 {
815  uint64_t *udst = dst;
816  const uint64_t *res;
817  int fnum;
818 
819  (void) cls;
820  fnum = PQfnumber (result,
821  fname);
822  if (fnum < 0)
823  {
824  GNUNET_break (0);
825  return GNUNET_SYSERR;
826  }
827  if (PQgetisnull (result,
828  row,
829  fnum))
830  {
831  GNUNET_break (0);
832  return GNUNET_SYSERR;
833  }
834  GNUNET_assert (NULL != dst);
835  if (sizeof (uint64_t) != *dst_size)
836  {
837  GNUNET_break (0);
838  return GNUNET_SYSERR;
839  }
840  if (sizeof (uint64_t) !=
841  PQgetlength (result,
842  row,
843  fnum))
844  {
845  GNUNET_break (0);
846  return GNUNET_SYSERR;
847  }
848  res = (uint64_t *) PQgetvalue (result,
849  row,
850  fnum);
851  *udst = GNUNET_ntohll (*res);
852  return GNUNET_OK;
853 }
854 
855 
865  uint64_t *u64)
866 {
867  struct GNUNET_PQ_ResultSpec res =
868  { &extract_uint64,
869  NULL,
870  NULL,
871  (void *) u64, sizeof (*u64), (name), NULL };
872  return res;
873 }
874 
875 
876 /* 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:63
void GNUNET_CRYPTO_rsa_signature_free(struct GNUNET_CRYPTO_RsaSignature *sig)
Free memory occupied by signature.
Definition: crypto_rsa.c:951
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.
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:78
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:51
#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.
#define GNUNET_memcpy(dst, src, n)
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:370
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:79
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
const char * name
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.
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:996
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:302
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...