GNUnet  0.11.x
strings.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2005-2017 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  */
27 #include "platform.h"
28 #if HAVE_ICONV
29 #include <iconv.h>
30 #endif
31 #include "gnunet_crypto_lib.h"
32 #include "gnunet_strings_lib.h"
33 #include <unicase.h>
34 #include <unistr.h>
35 #include <uniconv.h>
36 
37 #define LOG(kind, ...) GNUNET_log_from (kind, "util-strings", __VA_ARGS__)
38 
39 #define LOG_STRERROR(kind, syscall) \
40  GNUNET_log_from_strerror (kind, "util-strings", syscall)
41 
42 
64 size_t
65 GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count, ...)
66 {
67  size_t needed;
68  size_t slen;
69  const char *s;
70  va_list ap;
71 
72  needed = 0;
73  va_start (ap, count);
74  while (count > 0)
75  {
76  s = va_arg (ap, const char *);
77 
78  slen = strlen (s) + 1;
79  if (buffer != NULL)
80  {
81  GNUNET_assert (needed + slen <= size);
82  GNUNET_memcpy (&buffer[needed], s, slen);
83  }
84  needed += slen;
85  count--;
86  }
87  va_end (ap);
88  return needed;
89 }
90 
91 
99 char *
101  unsigned int num_pids)
102 {
103  char *buf;
104  size_t off;
105  size_t plen = num_pids * 5 + 1;
106 
107  off = 0;
108  buf = GNUNET_malloc (plen);
109  for (unsigned int i = 0; i < num_pids; i++)
110  {
111  off += GNUNET_snprintf (&buf[off],
112  plen - off,
113  "%s%s",
114  GNUNET_i2s (&pids[i]),
115  (i == num_pids - 1) ? "" : "-");
116  }
117  return buf;
118 }
119 
120 
134 unsigned int
135 GNUNET_STRINGS_buffer_tokenize (const char *buffer,
136  size_t size,
137  unsigned int count,
138  ...)
139 {
140  unsigned int start;
141  unsigned int needed;
142  const char **r;
143  va_list ap;
144 
145  needed = 0;
146  va_start (ap, count);
147  while (count > 0)
148  {
149  r = va_arg (ap, const char **);
150 
151  start = needed;
152  while ((needed < size) && (buffer[needed] != '\0'))
153  needed++;
154  if (needed == size)
155  {
156  va_end (ap);
157  return 0; /* error */
158  }
159  *r = &buffer[start];
160  needed++; /* skip 0-termination */
161  count--;
162  }
163  va_end (ap);
164  return needed;
165 }
166 
167 
174 char *
176 {
177  const char *unit = _ (/* size unit */ "b");
178  char *ret;
179 
180  if (size > 5 * 1024)
181  {
182  size = size / 1024;
183  unit = "KiB";
184  if (size > 5 * 1024)
185  {
186  size = size / 1024;
187  unit = "MiB";
188  if (size > 5 * 1024)
189  {
190  size = size / 1024;
191  unit = "GiB";
192  if (size > 5 * 1024)
193  {
194  size = size / 1024;
195  unit = "TiB";
196  }
197  }
198  }
199  }
200  ret = GNUNET_malloc (32);
201  GNUNET_snprintf (ret, 32, "%llu %s", size, unit);
202  return ret;
203 }
204 
205 
218 size_t
219 GNUNET_strlcpy (char *dst, const char *src, size_t n)
220 {
221  size_t slen;
222 
223  GNUNET_assert (0 != n);
224  slen = strnlen (src, n - 1);
225  memcpy (dst, src, slen);
226  dst[slen] = '\0';
227  return slen;
228 }
229 
230 
235 {
239  const char *name;
240 
244  unsigned long long value;
245 };
246 
247 
259 static int
260 convert_with_table (const char *input,
261  const struct ConversionTable *table,
262  unsigned long long *output)
263 {
264  unsigned long long ret;
265  char *in;
266  const char *tok;
267  unsigned long long last;
268  unsigned int i;
269  char *sptr;
270 
271  ret = 0;
272  last = 0;
273  in = GNUNET_strdup (input);
274  for (tok = strtok_r (in, " ", &sptr);
275  tok != NULL;
276  tok = strtok_r (NULL, " ", &sptr))
277  {
278  do
279  {
280  i = 0;
281  while ((table[i].name != NULL) && (0 != strcasecmp (table[i].name, tok)))
282  i++;
283  if (table[i].name != NULL)
284  {
285  last *= table[i].value;
286  break; /* next tok */
287  }
288  else
289  {
290  char *endptr;
291  ret += last;
292  errno = 0;
293  last = strtoull (tok, &endptr, 10);
294  if ((0 != errno) || (endptr == tok))
295  {
296  GNUNET_free (in);
297  return GNUNET_SYSERR; /* expected number */
298  }
299  if ('\0' == endptr[0])
300  break; /* next tok */
301  else
302  tok = endptr; /* and re-check (handles times like "10s") */
303  }
304  }
305  while (GNUNET_YES);
306  }
307  ret += last;
308  *output = ret;
309  GNUNET_free (in);
310  return GNUNET_OK;
311 }
312 
313 
321 int
322 GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
323  unsigned long long *size)
324 {
325  static const struct ConversionTable table[] =
326  { { "B", 1 },
327  { "KiB", 1024 },
328  { "kB", 1000 },
329  { "MiB", 1024 * 1024 },
330  { "MB", 1000 * 1000 },
331  { "GiB", 1024 * 1024 * 1024 },
332  { "GB", 1000 * 1000 * 1000 },
333  { "TiB", 1024LL * 1024LL * 1024LL * 1024LL },
334  { "TB", 1000LL * 1000LL * 1000LL * 1024LL },
335  { "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL },
336  { "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL },
337  { "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL },
338  { "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL },
339  { NULL, 0 } };
340 
341  return convert_with_table (fancy_size, table, size);
342 }
343 
344 
353 int
355  struct GNUNET_TIME_Relative *rtime)
356 {
357  static const struct ConversionTable table[] =
358  { { "us", 1 },
359  { "ms", 1000 },
360  { "s", 1000 * 1000LL },
361  { "second", 1000 * 1000LL },
362  { "seconds", 1000 * 1000LL },
363  { "\"", 1000 * 1000LL },
364  { "m", 60 * 1000 * 1000LL },
365  { "min", 60 * 1000 * 1000LL },
366  { "minute", 60 * 1000 * 1000LL },
367  { "minutes", 60 * 1000 * 1000LL },
368  { "'", 60 * 1000 * 1000LL },
369  { "h", 60 * 60 * 1000 * 1000LL },
370  { "hour", 60 * 60 * 1000 * 1000LL },
371  { "hours", 60 * 60 * 1000 * 1000LL },
372  { "d", 24 * 60 * 60 * 1000LL * 1000LL },
373  { "day", 24 * 60 * 60 * 1000LL * 1000LL },
374  { "days", 24 * 60 * 60 * 1000LL * 1000LL },
375  { "week", 7 * 24 * 60 * 60 * 1000LL * 1000LL },
376  { "weeks", 7 * 24 * 60 * 60 * 1000LL * 1000LL },
377  { "year", 31536000000000LL /* year */ },
378  { "years", 31536000000000LL /* year */ },
379  { "a", 31536000000000LL /* year */ },
380  { NULL, 0 } };
381  int ret;
382  unsigned long long val;
383 
384  if (0 == strcasecmp ("forever", fancy_time))
385  {
387  return GNUNET_OK;
388  }
389  ret = convert_with_table (fancy_time, table, &val);
390  rtime->rel_value_us = (uint64_t) val;
391  return ret;
392 }
393 
394 
404 int
406  struct GNUNET_TIME_Absolute *atime)
407 {
408  struct tm tv;
409  time_t t;
410  const char *eos;
411 
412  if (0 == strcasecmp ("end of time", fancy_time))
413  {
415  return GNUNET_OK;
416  }
417  eos = &fancy_time[strlen (fancy_time)];
418  memset (&tv, 0, sizeof(tv));
419  if ((eos != strptime (fancy_time, "%a %b %d %H:%M:%S %Y", &tv)) &&
420  (eos != strptime (fancy_time, "%c", &tv)) &&
421  (eos != strptime (fancy_time, "%Ec", &tv)) &&
422  (eos != strptime (fancy_time, "%Y-%m-%d %H:%M:%S", &tv)) &&
423  (eos != strptime (fancy_time, "%Y-%m-%d %H:%M", &tv)) &&
424  (eos != strptime (fancy_time, "%x", &tv)) &&
425  (eos != strptime (fancy_time, "%Ex", &tv)) &&
426  (eos != strptime (fancy_time, "%Y-%m-%d", &tv)) &&
427  (eos != strptime (fancy_time, "%Y-%m", &tv)) &&
428  (eos != strptime (fancy_time, "%Y", &tv)))
429  return GNUNET_SYSERR;
430  t = mktime (&tv);
431  atime->abs_value_us = (uint64_t) ((uint64_t) t * 1000LL * 1000LL);
432  return GNUNET_OK;
433 }
434 
435 
449 char *
450 GNUNET_STRINGS_conv (const char *input,
451  size_t len,
452  const char *input_charset,
453  const char *output_charset)
454 {
455  char *ret;
456  uint8_t *u8_string;
457  char *encoded_string;
458  size_t u8_string_length;
459  size_t encoded_string_length;
460 
461  u8_string = u8_conv_from_encoding (input_charset,
462  iconveh_error,
463  input,
464  len,
465  NULL,
466  NULL,
467  &u8_string_length);
468  if (NULL == u8_string)
469  {
470  LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "u8_conv_from_encoding");
471  goto fail;
472  }
473  if (0 == strcmp (output_charset, "UTF-8"))
474  {
475  ret = GNUNET_malloc (u8_string_length + 1);
476  GNUNET_memcpy (ret, u8_string, u8_string_length);
477  ret[u8_string_length] = '\0';
478  free (u8_string);
479  return ret;
480  }
481  encoded_string = u8_conv_to_encoding (output_charset,
482  iconveh_error,
483  u8_string,
484  u8_string_length,
485  NULL,
486  NULL,
487  &encoded_string_length);
488  free (u8_string);
489  if (NULL == encoded_string)
490  {
491  LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "u8_conv_to_encoding");
492  goto fail;
493  }
494  ret = GNUNET_malloc (encoded_string_length + 1);
495  GNUNET_memcpy (ret, encoded_string, encoded_string_length);
496  ret[encoded_string_length] = '\0';
497  free (encoded_string);
498  return ret;
499 fail:
501  _ ("Character sets requested were `%s'->`%s'\n"),
502  "UTF-8",
503  output_charset);
504  ret = GNUNET_malloc (len + 1);
505  GNUNET_memcpy (ret, input, len);
506  ret[len] = '\0';
507  return ret;
508 }
509 
510 
523 char *
524 GNUNET_STRINGS_to_utf8 (const char *input, size_t len, const char *charset)
525 {
526  return GNUNET_STRINGS_conv (input, len, charset, "UTF-8");
527 }
528 
529 
541 char *
542 GNUNET_STRINGS_from_utf8 (const char *input, size_t len, const char *charset)
543 {
544  return GNUNET_STRINGS_conv (input, len, "UTF-8", charset);
545 }
546 
547 
555 void
556 GNUNET_STRINGS_utf8_tolower (const char *input, char *output)
557 {
558  uint8_t *tmp_in;
559  size_t len;
560 
561  tmp_in = u8_tolower ((uint8_t *) input,
562  strlen ((char *) input),
563  NULL,
564  UNINORM_NFD,
565  NULL,
566  &len);
567  GNUNET_memcpy (output, tmp_in, len);
568  output[len] = '\0';
569  free (tmp_in);
570 }
571 
572 
580 void
581 GNUNET_STRINGS_utf8_toupper (const char *input, char *output)
582 {
583  uint8_t *tmp_in;
584  size_t len;
585 
586  tmp_in = u8_toupper ((uint8_t *) input,
587  strlen ((char *) input),
588  NULL,
589  UNINORM_NFD,
590  NULL,
591  &len);
592  GNUNET_memcpy (output, tmp_in, len);
593  output[len] = '\0';
594  free (tmp_in);
595 }
596 
597 
605 char *
607 {
608  char *buffer;
609  size_t len;
610  char *fm;
611  const char *fil_ptr;
612 
613  if (fil == NULL)
614  return NULL;
615 
616  if (fil[0] == DIR_SEPARATOR)
617  /* absolute path, just copy */
618  return GNUNET_strdup (fil);
619  if (fil[0] == '~')
620  {
621  fm = getenv ("HOME");
622  if (fm == NULL)
623  {
625  _ ("Failed to expand `$HOME': environment variable `HOME' not set"));
626  return NULL;
627  }
628  fm = GNUNET_strdup (fm);
629  /* do not copy '~' */
630  fil_ptr = fil + 1;
631 
632  /* skip over dir seperator to be consistent */
633  if (fil_ptr[0] == DIR_SEPARATOR)
634  fil_ptr++;
635  }
636  else
637  {
638  /* relative path */
639  fil_ptr = fil;
640  len = 512;
641  fm = NULL;
642  while (1)
643  {
644  buffer = GNUNET_malloc (len);
645  if (getcwd (buffer, len) != NULL)
646  {
647  fm = buffer;
648  break;
649  }
650  if ((errno == ERANGE) && (len < 1024 * 1024 * 4))
651  {
652  len *= 2;
653  GNUNET_free (buffer);
654  continue;
655  }
656  GNUNET_free (buffer);
657  break;
658  }
659  if (fm == NULL)
660  {
662  buffer = getenv ("PWD"); /* alternative */
663  if (buffer != NULL)
664  fm = GNUNET_strdup (buffer);
665  }
666  if (fm == NULL)
667  fm = GNUNET_strdup ("./"); /* give up */
668  }
669  GNUNET_asprintf (&buffer,
670  "%s%s%s",
671  fm,
672  (fm[strlen (fm) - 1] == DIR_SEPARATOR) ? ""
674  fil_ptr);
675  GNUNET_free (fm);
676  return buffer;
677 }
678 
679 
689 const char *
691  int do_round)
692 {
693  static char buf[128];
694  const char *unit = _ (/* time unit */ "┬Ás");
695  uint64_t dval = delta.rel_value_us;
696 
697  if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == delta.rel_value_us)
698  return _ ("forever");
699  if (0 == delta.rel_value_us)
700  return _ ("0 ms");
701  if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000)))
702  {
703  dval = dval / 1000;
704  unit = _ (/* time unit */ "ms");
705  if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000)))
706  {
707  dval = dval / 1000;
708  unit = _ (/* time unit */ "s");
709  if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60)))
710  {
711  dval = dval / 60;
712  unit = _ (/* time unit */ "m");
713  if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60)))
714  {
715  dval = dval / 60;
716  unit = _ (/* time unit */ "h");
717  if (((GNUNET_YES == do_round) && (dval > 5 * 24)) ||
718  (0 == (dval % 24)))
719  {
720  dval = dval / 24;
721  if (1 == dval)
722  unit = _ (/* time unit */ "day");
723  else
724  unit = _ (/* time unit */ "days");
725  }
726  }
727  }
728  }
729  }
730  GNUNET_snprintf (buf, sizeof(buf), "%llu %s", dval, unit);
731  return buf;
732 }
733 
734 
744 const char *
746 {
747  static char buf[255];
748  time_t tt;
749  struct tm *tp;
750 
751  if (t.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
752  return _ ("end of time");
753  tt = t.abs_value_us / 1000LL / 1000LL;
754  tp = localtime (&tt);
755  /* This is hacky, but i don't know a way to detect libc character encoding.
756  * Just expect utf8 from glibc these days.
757  * As for msvcrt, use the wide variant, which always returns utf16
758  * (otherwise we'd have to detect current codepage or use W32API character
759  * set conversion routines to convert to UTF8).
760  */strftime (buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", tp);
761 
762  return buf;
763 }
764 
765 
777 const char *
779 {
780  const char *short_fn = filename;
781  const char *ss;
782 
783  while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR)) && (ss[1] != '\0'))
784  short_fn = 1 + ss;
785  return short_fn;
786 }
787 
788 
796 static unsigned int
797 getValue__ (unsigned char a)
798 {
799  unsigned int dec;
800 
801  switch (a)
802  {
803  case 'O':
804  case 'o':
805  a = '0';
806  break;
807 
808  case 'i':
809  case 'I':
810  case 'l':
811  case 'L':
812  a = '1';
813  break;
814 
815  /* also consider U to be V */
816  case 'u':
817  case 'U':
818  a = 'V';
819  break;
820 
821  default:
822  break;
823  }
824  if ((a >= '0') && (a <= '9'))
825  return a - '0';
826  if ((a >= 'a') && (a <= 'z'))
827  a = toupper (a);
828  /* return (a - 'a' + 10); */
829  dec = 0;
830  if ((a >= 'A') && (a <= 'Z'))
831  {
832  if ('I' < a)
833  dec++;
834  if ('L' < a)
835  dec++;
836  if ('O' < a)
837  dec++;
838  if ('U' < a)
839  dec++;
840  return(a - 'A' + 10 - dec);
841  }
842  return -1;
843 }
844 
845 
858 char *
860  size_t size,
861  char *out,
862  size_t out_size)
863 {
867  static char *encTable__ = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
868  unsigned int wpos;
869  unsigned int rpos;
870  unsigned int bits;
871  unsigned int vbit;
872  const unsigned char *udata;
873 
874  udata = data;
875  if (out_size < (size * 8 + 4) / 5)
876  {
877  GNUNET_break (0);
878  return NULL;
879  }
880  vbit = 0;
881  wpos = 0;
882  rpos = 0;
883  bits = 0;
884  while ((rpos < size) || (vbit > 0))
885  {
886  if ((rpos < size) && (vbit < 5))
887  {
888  bits = (bits << 8) | udata[rpos++]; /* eat 8 more bits */
889  vbit += 8;
890  }
891  if (vbit < 5)
892  {
893  bits <<= (5 - vbit); /* zero-padding */
894  GNUNET_assert (vbit == ((size * 8) % 5));
895  vbit = 5;
896  }
897  if (wpos >= out_size)
898  {
899  GNUNET_break (0);
900  return NULL;
901  }
902  out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
903  vbit -= 5;
904  }
905  GNUNET_assert (0 == vbit);
906  if (wpos < out_size)
907  out[wpos] = '\0';
908  return &out[wpos];
909 }
910 
911 
922 char *
924 {
925  char *str_buf;
926  size_t len = size * 8;
927  char *end;
928 
929  if (len % 5 > 0)
930  len += 5 - len % 5;
931  len /= 5;
932  str_buf = GNUNET_malloc (len + 1);
933  end = GNUNET_STRINGS_data_to_string (buf, size, str_buf, len);
934  if (NULL == end)
935  {
936  GNUNET_free (str_buf);
937  return NULL;
938  }
939  *end = '\0';
940  return str_buf;
941 }
942 
943 
954 int
956  size_t enclen,
957  void *out,
958  size_t out_size)
959 {
960  unsigned int rpos;
961  unsigned int wpos;
962  unsigned int bits;
963  unsigned int vbit;
964  int ret;
965  int shift;
966  unsigned char *uout;
967  unsigned int encoded_len = out_size * 8;
968 
969  if (0 == enclen)
970  {
971  if (0 == out_size)
972  return GNUNET_OK;
973  return GNUNET_SYSERR;
974  }
975  uout = out;
976  wpos = out_size;
977  rpos = enclen;
978  if ((encoded_len % 5) > 0)
979  {
980  vbit = encoded_len % 5; /* padding! */
981  shift = 5 - vbit;
982  bits = (ret = getValue__ (enc[--rpos])) >> shift;
983  }
984  else
985  {
986  vbit = 5;
987  shift = 0;
988  bits = (ret = getValue__ (enc[--rpos]));
989  }
990  if ((encoded_len + shift) / 5 != enclen)
991  return GNUNET_SYSERR;
992  if (-1 == ret)
993  return GNUNET_SYSERR;
994  while (wpos > 0)
995  {
996  if (0 == rpos)
997  {
998  GNUNET_break (0);
999  return GNUNET_SYSERR;
1000  }
1001  bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits;
1002  if (-1 == ret)
1003  return GNUNET_SYSERR;
1004  vbit += 5;
1005  if (vbit >= 8)
1006  {
1007  uout[--wpos] = (unsigned char) bits;
1008  bits >>= 8;
1009  vbit -= 8;
1010  }
1011  }
1012  if ((0 != rpos) || (0 != vbit))
1013  return GNUNET_SYSERR;
1014  return GNUNET_OK;
1015 }
1016 
1017 
1034 int
1035 GNUNET_STRINGS_parse_uri (const char *path,
1036  char **scheme_part,
1037  const char **path_part)
1038 {
1039  size_t len;
1040  size_t i;
1041  int end;
1042  int pp_state = 0;
1043  const char *post_scheme_part = NULL;
1044 
1045  len = strlen (path);
1046  for (end = 0, i = 0; ! end && i < len; i++)
1047  {
1048  switch (pp_state)
1049  {
1050  case 0:
1051  if ((path[i] == ':') && (i > 0))
1052  {
1053  pp_state += 1;
1054  continue;
1055  }
1056  if (! (((path[i] >= 'A') && (path[i] <= 'Z') ) ||
1057  ((path[i] >= 'a') && (path[i] <= 'z') ) ||
1058  ((path[i] >= '0') && (path[i] <= '9') ) || (path[i] == '+') ||
1059  (path[i] == '-') || (path[i] == '.')))
1060  end = 1;
1061  break;
1062 
1063  case 1:
1064  case 2:
1065  if (path[i] == '/')
1066  {
1067  pp_state += 1;
1068  continue;
1069  }
1070  end = 1;
1071  break;
1072 
1073  case 3:
1074  post_scheme_part = &path[i];
1075  end = 1;
1076  break;
1077 
1078  default:
1079  end = 1;
1080  }
1081  }
1082  if (post_scheme_part == NULL)
1083  return GNUNET_NO;
1084  if (scheme_part)
1085  {
1086  *scheme_part = GNUNET_malloc (post_scheme_part - path + 1);
1087  GNUNET_memcpy (*scheme_part, path, post_scheme_part - path);
1088  (*scheme_part)[post_scheme_part - path] = '\0';
1089  }
1090  if (path_part)
1091  *path_part = post_scheme_part;
1092  return GNUNET_YES;
1093 }
1094 
1095 
1110 int
1112  int can_be_uri,
1113  int *r_is_uri,
1114  char **r_uri_scheme)
1115 {
1116  const char *post_scheme_path;
1117  int is_uri;
1118  char *uri;
1119  /* consider POSIX paths to be absolute too, even on W32,
1120  * as plibc expansion will fix them for us.
1121  */
1122  if (filename[0] == '/')
1123  return GNUNET_YES;
1124  if (can_be_uri)
1125  {
1126  is_uri = GNUNET_STRINGS_parse_uri (filename, &uri, &post_scheme_path);
1127  if (r_is_uri)
1128  *r_is_uri = is_uri;
1129  if (is_uri)
1130  {
1131  if (r_uri_scheme)
1132  *r_uri_scheme = uri;
1133  else
1134  GNUNET_free_non_null (uri);
1135 
1136  return GNUNET_STRINGS_path_is_absolute (post_scheme_path,
1137  GNUNET_NO,
1138  NULL,
1139  NULL);
1140  }
1141  }
1142  else
1143  {
1144  if (r_is_uri)
1145  *r_is_uri = GNUNET_NO;
1146  }
1147 
1148  return GNUNET_NO;
1149 }
1150 
1151 
1160 int
1162  enum GNUNET_STRINGS_FilenameCheck checks)
1163 {
1164  struct stat st;
1165 
1166  if ((NULL == filename) || (filename[0] == '\0'))
1167  return GNUNET_SYSERR;
1168  if (0 != (checks & GNUNET_STRINGS_CHECK_IS_ABSOLUTE))
1169  if (! GNUNET_STRINGS_path_is_absolute (filename, GNUNET_NO, NULL, NULL))
1170  return GNUNET_NO;
1171  if (0 != (checks
1174  {
1175  if (0 != stat (filename, &st))
1176  {
1177  if (0 != (checks & GNUNET_STRINGS_CHECK_EXISTS))
1178  return GNUNET_NO;
1179  else
1180  return GNUNET_SYSERR;
1181  }
1182  }
1183  if (0 != (checks & GNUNET_STRINGS_CHECK_IS_DIRECTORY))
1184  if (! S_ISDIR (st.st_mode))
1185  return GNUNET_NO;
1186  if (0 != (checks & GNUNET_STRINGS_CHECK_IS_LINK))
1187  if (! S_ISLNK (st.st_mode))
1188  return GNUNET_NO;
1189  return GNUNET_YES;
1190 }
1191 
1192 
1205 int
1206 GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
1207  uint16_t addrlen,
1208  struct sockaddr_in6 *r_buf)
1209 {
1210  char zbuf[addrlen + 1];
1211  int ret;
1212  char *port_colon;
1213  unsigned int port;
1214  char dummy[2];
1215 
1216  if (addrlen < 6)
1217  return GNUNET_SYSERR;
1218  GNUNET_memcpy (zbuf, zt_addr, addrlen);
1219  if ('[' != zbuf[0])
1220  {
1222  _ ("IPv6 address did not start with `['\n"));
1223  return GNUNET_SYSERR;
1224  }
1225  zbuf[addrlen] = '\0';
1226  port_colon = strrchr (zbuf, ':');
1227  if (NULL == port_colon)
1228  {
1230  _ ("IPv6 address did contain ':' to separate port number\n"));
1231  return GNUNET_SYSERR;
1232  }
1233  if (']' != *(port_colon - 1))
1234  {
1235  GNUNET_log (
1237  _ ("IPv6 address did contain ']' before ':' to separate port number\n"));
1238  return GNUNET_SYSERR;
1239  }
1240  ret = sscanf (port_colon, ":%u%1s", &port, dummy);
1241  if ((1 != ret) || (port > 65535))
1242  {
1243  GNUNET_log (
1245  _ ("IPv6 address did contain a valid port number after the last ':'\n"));
1246  return GNUNET_SYSERR;
1247  }
1248  *(port_colon - 1) = '\0';
1249  memset (r_buf, 0, sizeof(struct sockaddr_in6));
1250  ret = inet_pton (AF_INET6, &zbuf[1], &r_buf->sin6_addr);
1251  if (ret <= 0)
1252  {
1254  _ ("Invalid IPv6 address `%s': %s\n"),
1255  &zbuf[1],
1256  strerror (errno));
1257  return GNUNET_SYSERR;
1258  }
1259  r_buf->sin6_port = htons (port);
1260  r_buf->sin6_family = AF_INET6;
1261 #if HAVE_SOCKADDR_IN_SIN_LEN
1262  r_buf->sin6_len = (u_char) sizeof(struct sockaddr_in6);
1263 #endif
1264  return GNUNET_OK;
1265 }
1266 
1267 
1279 int
1280 GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr,
1281  uint16_t addrlen,
1282  struct sockaddr_in *r_buf)
1283 {
1284  unsigned int temps[4];
1285  unsigned int port;
1286  unsigned int cnt;
1287  char dummy[2];
1288 
1289  if (addrlen < 9)
1290  return GNUNET_SYSERR;
1291  cnt = sscanf (zt_addr,
1292  "%u.%u.%u.%u:%u%1s",
1293  &temps[0],
1294  &temps[1],
1295  &temps[2],
1296  &temps[3],
1297  &port,
1298  dummy);
1299  if (5 != cnt)
1300  return GNUNET_SYSERR;
1301  for (cnt = 0; cnt < 4; cnt++)
1302  if (temps[cnt] > 0xFF)
1303  return GNUNET_SYSERR;
1304  if (port > 65535)
1305  return GNUNET_SYSERR;
1306  r_buf->sin_family = AF_INET;
1307  r_buf->sin_port = htons (port);
1308  r_buf->sin_addr.s_addr =
1309  htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) + temps[3]);
1310 #if HAVE_SOCKADDR_IN_SIN_LEN
1311  r_buf->sin_len = (u_char) sizeof(struct sockaddr_in);
1312 #endif
1313  return GNUNET_OK;
1314 }
1315 
1316 
1328 int
1330  uint16_t addrlen,
1331  struct sockaddr_storage *r_buf)
1332 {
1333  if (addr[0] == '[')
1334  return GNUNET_STRINGS_to_address_ipv6 (addr,
1335  addrlen,
1336  (struct sockaddr_in6 *) r_buf);
1337  return GNUNET_STRINGS_to_address_ipv4 (addr,
1338  addrlen,
1339  (struct sockaddr_in *) r_buf);
1340 }
1341 
1342 
1352 size_t
1354  uint8_t *af,
1355  struct sockaddr **sa)
1356 {
1357  char *cp = GNUNET_strdup (addr);
1358 
1359  *af = AF_UNSPEC;
1360  if ('[' == *addr)
1361  {
1362  /* IPv6 */
1363  *sa = GNUNET_malloc (sizeof(struct sockaddr_in6));
1364  if (GNUNET_OK !=
1366  strlen (cp),
1367  (struct sockaddr_in6 *) *sa))
1368  {
1369  GNUNET_free (*sa);
1370  *sa = NULL;
1371  GNUNET_free (cp);
1372  return 0;
1373  }
1374  *af = AF_INET6;
1375  GNUNET_free (cp);
1376  return sizeof(struct sockaddr_in6);
1377  }
1378  else
1379  {
1380  /* IPv4 */
1381  *sa = GNUNET_malloc (sizeof(struct sockaddr_in));
1382  if (GNUNET_OK !=
1384  strlen (cp),
1385  (struct sockaddr_in *) *sa))
1386  {
1387  GNUNET_free (*sa);
1388  *sa = NULL;
1389  GNUNET_free (cp);
1390  return 0;
1391  }
1392  *af = AF_INET;
1393  GNUNET_free (cp);
1394  return sizeof(struct sockaddr_in);
1395  }
1396 }
1397 
1398 
1403 static char *const *
1404 _make_continuous_arg_copy (int argc, char *const *argv)
1405 {
1406  size_t argvsize = 0;
1407  int i;
1408  char **new_argv;
1409  char *p;
1410 
1411  for (i = 0; i < argc; i++)
1412  argvsize += strlen (argv[i]) + 1 + sizeof(char *);
1413  new_argv = GNUNET_malloc (argvsize + sizeof(char *));
1414  p = (char *) &new_argv[argc + 1];
1415  for (i = 0; i < argc; i++)
1416  {
1417  new_argv[i] = p;
1418  strcpy (p, argv[i]);
1419  p += strlen (argv[i]) + 1;
1420  }
1421  new_argv[argc] = NULL;
1422  return (char *const *) new_argv;
1423 }
1424 
1425 
1440 int
1442  char *const *argv,
1443  int *u8argc,
1444  char *const **u8argv)
1445 {
1446  char *const *new_argv =
1447  (char *const *) _make_continuous_arg_copy (argc, argv);
1448  *u8argv = new_argv;
1449  *u8argc = argc;
1450  return GNUNET_OK;
1451 }
1452 
1453 
1463 static int
1464 parse_port_policy (const char *port_policy,
1465  struct GNUNET_STRINGS_PortPolicy *pp)
1466 {
1467  const char *pos;
1468  int s;
1469  int e;
1470  char eol[2];
1471 
1472  pos = port_policy;
1473  if ('!' == *pos)
1474  {
1476  pos++;
1477  }
1478  if (2 == sscanf (pos, "%u-%u%1s", &s, &e, eol))
1479  {
1480  if ((0 == s) || (s > 0xFFFF) || (e < s) || (e > 0xFFFF))
1481  {
1482  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Port not in range\n"));
1483  return GNUNET_SYSERR;
1484  }
1485  pp->start_port = (uint16_t) s;
1486  pp->end_port = (uint16_t) e;
1487  return GNUNET_OK;
1488  }
1489  if (1 == sscanf (pos, "%u%1s", &s, eol))
1490  {
1491  if ((0 == s) || (s > 0xFFFF))
1492  {
1493  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Port not in range\n"));
1494  return GNUNET_SYSERR;
1495  }
1496 
1497  pp->start_port = (uint16_t) s;
1498  pp->end_port = (uint16_t) s;
1499  return GNUNET_OK;
1500  }
1502  _ ("Malformed port policy `%s'\n"),
1503  port_policy);
1504  return GNUNET_SYSERR;
1505 }
1506 
1507 
1521 GNUNET_STRINGS_parse_ipv4_policy (const char *routeListX)
1522 {
1523  unsigned int count;
1524  unsigned int i;
1525  unsigned int j;
1526  unsigned int len;
1527  int cnt;
1528  unsigned int pos;
1529  unsigned int temps[8];
1530  int slash;
1532  int colon;
1533  int end;
1534  char *routeList;
1535  char dummy[2];
1536 
1537  if (NULL == routeListX)
1538  return NULL;
1539  len = strlen (routeListX);
1540  if (0 == len)
1541  return NULL;
1542  routeList = GNUNET_strdup (routeListX);
1543  count = 0;
1544  for (i = 0; i < len; i++)
1545  if (routeList[i] == ';')
1546  count++;
1547  result = GNUNET_malloc (sizeof(struct GNUNET_STRINGS_IPv4NetworkPolicy)
1548  * (count + 1));
1549  i = 0;
1550  pos = 0;
1551  while (i < count)
1552  {
1553  for (colon = pos; ':' != routeList[colon]; colon++)
1554  if ((';' == routeList[colon]) || ('\0' == routeList[colon]))
1555  break;
1556  for (end = colon; ';' != routeList[end]; end++)
1557  if ('\0' == routeList[end])
1558  break;
1559  if ('\0' == routeList[end])
1560  break;
1561  routeList[end] = '\0';
1562  if (':' == routeList[colon])
1563  {
1564  routeList[colon] = '\0';
1565  if (GNUNET_OK != parse_port_policy (&routeList[colon + 1], &result[i].pp))
1566  break;
1567  }
1568  cnt = sscanf (&routeList[pos],
1569  "%u.%u.%u.%u/%u.%u.%u.%u%1s",
1570  &temps[0],
1571  &temps[1],
1572  &temps[2],
1573  &temps[3],
1574  &temps[4],
1575  &temps[5],
1576  &temps[6],
1577  &temps[7],
1578  dummy);
1579  if (8 == cnt)
1580  {
1581  for (j = 0; j < 8; j++)
1582  if (temps[j] > 0xFF)
1583  {
1585  _ ("Invalid format for IP: `%s'\n"),
1586  &routeList[pos]);
1587  GNUNET_free (result);
1588  GNUNET_free (routeList);
1589  return NULL;
1590  }
1591  result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1592  + (temps[2] << 8) + temps[3]);
1593  result[i].netmask.s_addr = htonl ((temps[4] << 24) + (temps[5] << 16)
1594  + (temps[6] << 8) + temps[7]);
1595  pos = end + 1;
1596  i++;
1597  continue;
1598  }
1599  /* try second notation */
1600  cnt = sscanf (&routeList[pos],
1601  "%u.%u.%u.%u/%u%1s",
1602  &temps[0],
1603  &temps[1],
1604  &temps[2],
1605  &temps[3],
1606  &slash,
1607  dummy);
1608  if (5 == cnt)
1609  {
1610  for (j = 0; j < 4; j++)
1611  if (temps[j] > 0xFF)
1612  {
1614  _ ("Invalid format for IP: `%s'\n"),
1615  &routeList[pos]);
1616  GNUNET_free (result);
1617  GNUNET_free (routeList);
1618  return NULL;
1619  }
1620  result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1621  + (temps[2] << 8) + temps[3]);
1622  if ((slash <= 32) && (slash >= 0))
1623  {
1624  result[i].netmask.s_addr = 0;
1625  while (slash > 0)
1626  {
1627  result[i].netmask.s_addr =
1628  (result[i].netmask.s_addr >> 1) + 0x80000000;
1629  slash--;
1630  }
1631  result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
1632  pos = end + 1;
1633  i++;
1634  continue;
1635  }
1636  else
1637  {
1639  _ ("Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
1640  slash);
1641  GNUNET_free (result);
1642  GNUNET_free (routeList);
1643  return NULL; /* error */
1644  }
1645  }
1646  /* try third notation */
1647  slash = 32;
1648  cnt = sscanf (&routeList[pos],
1649  "%u.%u.%u.%u%1s",
1650  &temps[0],
1651  &temps[1],
1652  &temps[2],
1653  &temps[3],
1654  dummy);
1655  if (4 == cnt)
1656  {
1657  for (j = 0; j < 4; j++)
1658  if (temps[j] > 0xFF)
1659  {
1661  _ ("Invalid format for IP: `%s'\n"),
1662  &routeList[pos]);
1663  GNUNET_free (result);
1664  GNUNET_free (routeList);
1665  return NULL;
1666  }
1667  result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1668  + (temps[2] << 8) + temps[3]);
1669  result[i].netmask.s_addr = 0;
1670  while (slash > 0)
1671  {
1672  result[i].netmask.s_addr = (result[i].netmask.s_addr >> 1) + 0x80000000;
1673  slash--;
1674  }
1675  result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
1676  pos = end + 1;
1677  i++;
1678  continue;
1679  }
1681  _ ("Invalid format for IP: `%s'\n"),
1682  &routeList[pos]);
1683  GNUNET_free (result);
1684  GNUNET_free (routeList);
1685  return NULL; /* error */
1686  }
1687  if (pos < strlen (routeList))
1688  {
1690  _ ("Invalid format: `%s'\n"),
1691  &routeListX[pos]);
1692  GNUNET_free (result);
1693  GNUNET_free (routeList);
1694  return NULL; /* oops */
1695  }
1696  GNUNET_free (routeList);
1697  return result; /* ok */
1698 }
1699 
1700 
1713 GNUNET_STRINGS_parse_ipv6_policy (const char *routeListX)
1714 {
1715  unsigned int count;
1716  unsigned int i;
1717  unsigned int len;
1718  unsigned int pos;
1719  int start;
1720  int slash;
1721  int ret;
1722  char *routeList;
1724  unsigned int bits;
1725  unsigned int off;
1726  int save;
1727  int colon;
1728  char dummy[2];
1729 
1730  if (NULL == routeListX)
1731  return NULL;
1732  len = strlen (routeListX);
1733  if (0 == len)
1734  return NULL;
1735  routeList = GNUNET_strdup (routeListX);
1736  count = 0;
1737  for (i = 0; i < len; i++)
1738  if (';' == routeList[i])
1739  count++;
1740  if (';' != routeList[len - 1])
1741  {
1743  _ ("Invalid network notation (does not end with ';': `%s')\n"),
1744  routeList);
1745  GNUNET_free (routeList);
1746  return NULL;
1747  }
1748 
1749  result = GNUNET_malloc (sizeof(struct GNUNET_STRINGS_IPv6NetworkPolicy)
1750  * (count + 1));
1751  i = 0;
1752  pos = 0;
1753  while (i < count)
1754  {
1755  start = pos;
1756  while (';' != routeList[pos])
1757  pos++;
1758  slash = pos;
1759  while ((slash >= start) && (routeList[slash] != '/'))
1760  slash--;
1761 
1762  if (slash < start)
1763  {
1764  memset (&result[i].netmask, 0xFF, sizeof(struct in6_addr));
1765  slash = pos;
1766  }
1767  else
1768  {
1769  routeList[pos] = '\0';
1770  for (colon = pos; ':' != routeList[colon]; colon--)
1771  if ('/' == routeList[colon])
1772  break;
1773  if (':' == routeList[colon])
1774  {
1775  routeList[colon] = '\0';
1776  if (GNUNET_OK !=
1777  parse_port_policy (&routeList[colon + 1], &result[i].pp))
1778  {
1779  GNUNET_free (result);
1780  GNUNET_free (routeList);
1781  return NULL;
1782  }
1783  }
1784  ret = inet_pton (AF_INET6, &routeList[slash + 1], &result[i].netmask);
1785  if (ret <= 0)
1786  {
1787  save = errno;
1788  if ((1 != sscanf (&routeList[slash + 1], "%u%1s", &bits, dummy)) ||
1789  (bits > 128))
1790  {
1791  if (0 == ret)
1793  _ ("Wrong format `%s' for netmask\n"),
1794  &routeList[slash + 1]);
1795  else
1796  {
1797  errno = save;
1798  LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "inet_pton");
1799  }
1800  GNUNET_free (result);
1801  GNUNET_free (routeList);
1802  return NULL;
1803  }
1804  off = 0;
1805  while (bits > 8)
1806  {
1807  result[i].netmask.s6_addr[off++] = 0xFF;
1808  bits -= 8;
1809  }
1810  while (bits > 0)
1811  {
1812  result[i].netmask.s6_addr[off] =
1813  (result[i].netmask.s6_addr[off] >> 1) + 0x80;
1814  bits--;
1815  }
1816  }
1817  }
1818  routeList[slash] = '\0';
1819  ret = inet_pton (AF_INET6, &routeList[start], &result[i].network);
1820  if (ret <= 0)
1821  {
1822  if (0 == ret)
1824  _ ("Wrong format `%s' for network\n"),
1825  &routeList[slash + 1]);
1826  else
1827  LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "inet_pton");
1828  GNUNET_free (result);
1829  GNUNET_free (routeList);
1830  return NULL;
1831  }
1832  pos++;
1833  i++;
1834  }
1835  GNUNET_free (routeList);
1836  return result;
1837 }
1838 
1839 
1842 #define FILLCHAR '='
1843 static char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1844  "abcdefghijklmnopqrstuvwxyz"
1845  "0123456789+/";
1846 
1847 
1857 size_t
1858 GNUNET_STRINGS_base64_encode (const void *in, size_t len, char **output)
1859 {
1860  const char *data = in;
1861  size_t ret;
1862  char *opt;
1863 
1864  ret = 0;
1865  opt = GNUNET_malloc (2 + (len * 4 / 3) + 8);
1866  for (size_t i = 0; i < len; ++i)
1867  {
1868  char c;
1869 
1870  c = (data[i] >> 2) & 0x3f;
1871  opt[ret++] = cvt[(int) c];
1872  c = (data[i] << 4) & 0x3f;
1873  if (++i < len)
1874  c |= (data[i] >> 4) & 0x0f;
1875  opt[ret++] = cvt[(int) c];
1876  if (i < len)
1877  {
1878  c = (data[i] << 2) & 0x3f;
1879  if (++i < len)
1880  c |= (data[i] >> 6) & 0x03;
1881  opt[ret++] = cvt[(int) c];
1882  }
1883  else
1884  {
1885  ++i;
1886  opt[ret++] = FILLCHAR;
1887  }
1888  if (i < len)
1889  {
1890  c = data[i] & 0x3f;
1891  opt[ret++] = cvt[(int) c];
1892  }
1893  else
1894  {
1895  opt[ret++] = FILLCHAR;
1896  }
1897  }
1898  *output = opt;
1899  return ret;
1900 }
1901 
1902 
1912 size_t
1913 GNUNET_STRINGS_base64url_encode (const void *in, size_t len, char **output)
1914 {
1915  char *enc;
1916  size_t pos;
1917 
1918  GNUNET_STRINGS_base64_encode (in, len, output);
1919  enc = *output;
1920  /* Replace with correct characters for base64url */
1921  pos = 0;
1922  while ('\0' != enc[pos])
1923  {
1924  if ('+' == enc[pos])
1925  enc[pos] = '-';
1926  if ('/' == enc[pos])
1927  enc[pos] = '_';
1928  if ('=' == enc[pos])
1929  {
1930  enc[pos] = '\0';
1931  break;
1932  }
1933  pos++;
1934  }
1935  return strlen (enc);
1936 }
1937 
1938 
1939 #define cvtfind(a) \
1940  ((((a) >= 'A') && ((a) <= 'Z')) \
1941  ? (a) - 'A' \
1942  : (((a) >= 'a') && ((a) <= 'z')) \
1943  ? (a) - 'a' + 26 \
1944  : (((a) >= '0') && ((a) <= '9')) \
1945  ? (a) - '0' + 52 \
1946  : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1)
1947 
1948 
1958 size_t
1959 GNUNET_STRINGS_base64_decode (const char *data, size_t len, void **out)
1960 {
1961  char *output;
1962  size_t ret = 0;
1963 
1964 #define CHECK_CRLF \
1965  while (data[i] == '\r' || data[i] == '\n') \
1966  { \
1967  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, \
1968  "ignoring CR/LF\n"); \
1969  i++; \
1970  if (i >= len) \
1971  goto END; \
1972  }
1973 
1974  output = GNUNET_malloc ((len * 3 / 4) + 8);
1976  "base64_decode decoding len=%d\n",
1977  (int) len);
1978  for (size_t i = 0; i < len; ++i)
1979  {
1980  char c;
1981  char c1;
1982 
1983  CHECK_CRLF;
1984  if (FILLCHAR == data[i])
1985  break;
1986  c = (char) cvtfind (data[i]);
1987  ++i;
1988  CHECK_CRLF;
1989  c1 = (char) cvtfind (data[i]);
1990  c = (c << 2) | ((c1 >> 4) & 0x3);
1991  output[ret++] = c;
1992  if (++i < len)
1993  {
1994  CHECK_CRLF;
1995  c = data[i];
1996  if (FILLCHAR == c)
1997  break;
1998  c = (char) cvtfind (c);
1999  c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
2000  output[ret++] = c1;
2001  }
2002  if (++i < len)
2003  {
2004  CHECK_CRLF;
2005  c1 = data[i];
2006  if (FILLCHAR == c1)
2007  break;
2008 
2009  c1 = (char) cvtfind (c1);
2010  c = ((c << 6) & 0xc0) | c1;
2011  output[ret++] = c;
2012  }
2013  }
2014 END:
2015  *out = output;
2016  return ret;
2017 }
2018 
2019 
2029 size_t
2030 GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out)
2031 {
2032  char *s;
2033  int padding;
2034  size_t ret;
2035 
2036  /* make enough space for padding */
2037  s = GNUNET_malloc (len + 3);
2038  memcpy (s, data, len);
2039 
2040  for (int i = 0; i < strlen (s); i++)
2041  {
2042  if (s[i] == '-')
2043  s[i] = '+';
2044  if (s[i] == '_')
2045  s[i] = '/';
2046  }
2047  padding = len % 4;
2048  switch (padding) // Pad with trailing '='s
2049  {
2050  case 0:
2051  break; // No pad chars in this case
2052  case 2:
2053  memcpy (&s[len],
2054  "==",
2055  2);
2056  len += 2;
2057  break; // Two pad chars
2058  case 3:
2059  s[len] = '=';
2060  len++;
2061  break; // One pad char
2062  default:
2063  GNUNET_assert (0);
2064  break;
2065  }
2066  ret = GNUNET_STRINGS_base64_decode (s, len, out);
2067  GNUNET_free (s);
2068  return ret;
2069 }
2070 
2071 
2072 /* end of strings.c */
static void do_round(void *cls)
Send out PUSHes and PULLs, possibly update #view, samplers.
unsigned long long value
Factor to apply for this unit.
Definition: strings.c:244
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1521
#define CHECK_CRLF
#define FILLCHAR
******************** Base64 encoding
Definition: strings.c:1842
uint64_t rel_value_us
The actual value.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
static int parse_port_policy(const char *port_policy, struct GNUNET_STRINGS_PortPolicy *pp)
Parse the given port policy.
Definition: strings.c:1464
char * GNUNET_STRINGS_conv(const char *input, size_t len, const char *input_charset, const char *output_charset)
Convert the len characters long character sequence given in input that is in the given input charset ...
Definition: strings.c:450
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
int GNUNET_STRINGS_parse_uri(const char *path, char **scheme_part, const char **path_part)
Parse a path that might be an URI.
Definition: strings.c:1035
struct GNUNET_STRINGS_PortPolicy pp
Policy for port access.
static struct GNUNET_SCHEDULER_Task * tt
Task scheduled to handle timeout.
Definition: gnunet-abd.c:76
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
char * GNUNET_STRINGS_byte_size_fancy(unsigned long long size)
Convert a given filesize into a fancy human-readable format.
Definition: strings.c:175
uint16_t start_port
Starting port range (0 if none given).
static int convert_with_table(const char *input, const struct ConversionTable *table, unsigned long long *output)
Convert a string of the form "4 X 5 Y" into a numeric value by interpreting "X" and "Y" as units and ...
Definition: strings.c:260
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
Definition: strings.c:1713
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1441
int GNUNET_STRINGS_path_is_absolute(const char *filename, int can_be_uri, int *r_is_uri, char **r_uri_scheme)
Check whether filename is absolute or not, and if it&#39;s an URI.
Definition: strings.c:1111
#define cvtfind(a)
Definition: strings.c:1939
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int GNUNET_STRINGS_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:354
Check that the path is an absolute path.
network in CIDR notation for IPV6.
int negate_portrange
GNUNET_YES if the port range should be negated ("!" in policy).
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
int GNUNET_STRINGS_fancy_time_to_absolute(const char *fancy_time, struct GNUNET_TIME_Absolute *atime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:405
static struct Experiment * e
struct in_addr netmask
IPv4 netmask.
We&#39;re done processing.
int GNUNET_STRINGS_fancy_size_to_bytes(const char *fancy_size, unsigned long long *size)
Convert a given fancy human-readable size to bytes.
Definition: strings.c:322
static char *const * _make_continuous_arg_copy(int argc, char *const *argv)
Makes a copy of argv that consists of a single memory chunk that can be freed with a single call to G...
Definition: strings.c:1404
#define GNUNET_NO
Definition: gnunet_common.h:86
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static struct GNUNET_SCHEDULER_Task * t
Main task.
Check that it exists.
static void save()
Write persistent statistics to disk.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct in6_addr netmask
IPv6 netmask.
uint64_t abs_value_us
The actual value.
static char * cvt
Definition: strings.c:1843
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
size_t GNUNET_STRINGS_base64url_encode(const void *in, size_t len, char **output)
Encode into Base64url.
Definition: strings.c:1913
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
struct in_addr network
IPv4 address.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
int GNUNET_STRINGS_to_address_ipv4(const char *zt_addr, uint16_t addrlen, struct sockaddr_in *r_buf)
Tries to convert &#39;zt_addr&#39; string to an IPv4 address.
Definition: strings.c:1280
unsigned int GNUNET_STRINGS_buffer_tokenize(const char *buffer, size_t size, unsigned int count,...)
Given a buffer of a given size, find "count" 0-terminated strings in the buffer and assign the count ...
Definition: strings.c:135
cryptographic primitives for GNUnet
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
void GNUNET_STRINGS_utf8_toupper(const char *input, char *output)
Convert the utf-8 input string to uppercase.
Definition: strings.c:581
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
static struct PeerEntry ** table
Table with our interned peer IDs.
Definition: peer.c:55
char * GNUNET_STRINGS_pp2s(const struct GNUNET_PeerIdentity *pids, unsigned int num_pids)
Convert a peer path to a human-readable string.
Definition: strings.c:100
#define DIR_SEPARATOR_STR
Definition: platform.h:167
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:690
IPV4 network in CIDR notation.
static char buf[2048]
static char * filename
static int result
Global testing status.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
char * GNUNET_STRINGS_from_utf8(const char *input, size_t len, const char *charset)
Convert the len bytes-long UTF-8 string given in input to the given charset.
Definition: strings.c:542
size_t GNUNET_STRINGS_buffer_fill(char *buffer, size_t size, unsigned int count,...)
Fill a buffer of the given size with count 0-terminated strings (given as varargs).
Definition: strings.c:65
Unit conversion table entry for &#39;convert_with_table&#39;.
Definition: strings.c:234
size_t GNUNET_STRINGS_parse_socket_addr(const char *addr, uint8_t *af, struct sockaddr **sa)
Parse an address given as a string into a struct sockaddr.
Definition: strings.c:1353
static OpusDecoder * dec
OPUS decoder.
#define LOG(kind,...)
Definition: strings.c:37
static unsigned int getValue__(unsigned char a)
Get the decoded value corresponding to a character according to Crockford Base32 encoding.
Definition: strings.c:797
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **out)
Decode from Base64.
Definition: strings.c:1959
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:1858
#define DIR_SEPARATOR
Definition: platform.h:166
const char * GNUNET_STRINGS_get_short_name(const char *filename)
"man basename" Returns a pointer to a part of filename (allocates nothing)!
Definition: strings.c:778
#define GNUNET_SYSERR
Definition: gnunet_common.h:84
static unsigned int size
Size of the "table".
Definition: peer.c:67
int GNUNET_STRINGS_check_filename(const char *filename, enum GNUNET_STRINGS_FilenameCheck checks)
Perform checks on filename.
Definition: strings.c:1161
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition: strings.c:606
char * getenv()
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
#define S_ISLNK(m)
Definition: disk.c:61
The identity of the host (wraps the signing key of the peer).
uint16_t end_port
End of port range (0 if none given).
#define LOG_STRERROR(kind, syscall)
Definition: strings.c:39
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
static OpusEncoder * enc
OPUS encoder.
int GNUNET_STRINGS_to_address_ipv6(const char *zt_addr, uint16_t addrlen, struct sockaddr_in6 *r_buf)
Tries to convert zt_addr string to an IPv6 address.
Definition: strings.c:1206
#define GNUNET_log(kind,...)
GNUNET_STRINGS_FilenameCheck
Flags for what we should check a file for.
char * GNUNET_STRINGS_to_utf8(const char *input, size_t len, const char *charset)
Convert the len characters long character sequence given in input that is in the given charset to UTF...
Definition: strings.c:524
struct GNUNET_STRINGS_PortPolicy pp
Policy for port access.
struct in6_addr network
IPv6 address.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:85
Check that it is a link.
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:923
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
"asctime", except for GNUnet time.
Definition: strings.c:745
uint32_t data
The data value.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:219
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * name
Name of the unit (or NULL for end of table).
Definition: strings.c:239
static size_t strnlen(const char *s, size_t n)
int GNUNET_STRINGS_to_address_ip(const char *addr, uint16_t addrlen, struct sockaddr_storage *r_buf)
Tries to convert addr string to an IP (v4 or v6) address.
Definition: strings.c:1329
size_t GNUNET_STRINGS_base64url_decode(const char *data, size_t len, void **out)
Decode from Base64url.
Definition: strings.c:2030
#define GNUNET_malloc(size)
Wrapper around malloc.
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert Crockford Base32hex encoding back to data.
Definition: strings.c:955
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using Crockford Base32 encoding.
Definition: strings.c:859
Check that it is a directory.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
void GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
Convert the utf-8 input string to lowercase.
Definition: strings.c:556
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...