GNUnet  0.10.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
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 
238  const char *name;
239 
243  unsigned long long value;
244 };
245 
246 
258 static int
259 convert_with_table(const char *input,
260  const struct ConversionTable *table,
261  unsigned long long *output)
262 {
263  unsigned long long ret;
264  char *in;
265  const char *tok;
266  unsigned long long last;
267  unsigned int i;
268 
269  ret = 0;
270  last = 0;
271  in = GNUNET_strdup(input);
272  for (tok = strtok(in, " "); tok != NULL; tok = strtok(NULL, " "))
273  {
274  do
275  {
276  i = 0;
277  while ((table[i].name != NULL) && (0 != strcasecmp(table[i].name, tok)))
278  i++;
279  if (table[i].name != NULL)
280  {
281  last *= table[i].value;
282  break; /* next tok */
283  }
284  else
285  {
286  char *endptr;
287  ret += last;
288  errno = 0;
289  last = strtoull(tok, &endptr, 10);
290  if ((0 != errno) || (endptr == tok))
291  {
292  GNUNET_free(in);
293  return GNUNET_SYSERR; /* expected number */
294  }
295  if ('\0' == endptr[0])
296  break; /* next tok */
297  else
298  tok = endptr; /* and re-check (handles times like "10s") */
299  }
300  }
301  while (GNUNET_YES);
302  }
303  ret += last;
304  *output = ret;
305  GNUNET_free(in);
306  return GNUNET_OK;
307 }
308 
309 
317 int
318 GNUNET_STRINGS_fancy_size_to_bytes(const char *fancy_size,
319  unsigned long long *size)
320 {
321  static const struct ConversionTable table[] =
322  { { "B", 1 },
323  { "KiB", 1024 },
324  { "kB", 1000 },
325  { "MiB", 1024 * 1024 },
326  { "MB", 1000 * 1000 },
327  { "GiB", 1024 * 1024 * 1024 },
328  { "GB", 1000 * 1000 * 1000 },
329  { "TiB", 1024LL * 1024LL * 1024LL * 1024LL },
330  { "TB", 1000LL * 1000LL * 1000LL * 1024LL },
331  { "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL },
332  { "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL },
333  { "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL },
334  { "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL },
335  { NULL, 0 } };
336 
337  return convert_with_table(fancy_size, table, size);
338 }
339 
340 
349 int
351  struct GNUNET_TIME_Relative *rtime)
352 {
353  static const struct ConversionTable table[] =
354  { { "us", 1 },
355  { "ms", 1000 },
356  { "s", 1000 * 1000LL },
357  { "second", 1000 * 1000LL },
358  { "seconds", 1000 * 1000LL },
359  { "\"", 1000 * 1000LL },
360  { "m", 60 * 1000 * 1000LL },
361  { "min", 60 * 1000 * 1000LL },
362  { "minute", 60 * 1000 * 1000LL },
363  { "minutes", 60 * 1000 * 1000LL },
364  { "'", 60 * 1000 * 1000LL },
365  { "h", 60 * 60 * 1000 * 1000LL },
366  { "hour", 60 * 60 * 1000 * 1000LL },
367  { "hours", 60 * 60 * 1000 * 1000LL },
368  { "d", 24 * 60 * 60 * 1000LL * 1000LL },
369  { "day", 24 * 60 * 60 * 1000LL * 1000LL },
370  { "days", 24 * 60 * 60 * 1000LL * 1000LL },
371  { "week", 7 * 24 * 60 * 60 * 1000LL * 1000LL },
372  { "weeks", 7 * 24 * 60 * 60 * 1000LL * 1000LL },
373  { "year", 31536000000000LL /* year */ },
374  { "years", 31536000000000LL /* year */ },
375  { "a", 31536000000000LL /* year */ },
376  { NULL, 0 } };
377  int ret;
378  unsigned long long val;
379 
380  if (0 == strcasecmp("forever", fancy_time))
381  {
383  return GNUNET_OK;
384  }
385  ret = convert_with_table(fancy_time, table, &val);
386  rtime->rel_value_us = (uint64_t)val;
387  return ret;
388 }
389 
390 
400 int
402  struct GNUNET_TIME_Absolute *atime)
403 {
404  struct tm tv;
405  time_t t;
406  const char *eos;
407 
408  if (0 == strcasecmp("end of time", fancy_time))
409  {
411  return GNUNET_OK;
412  }
413  eos = &fancy_time[strlen(fancy_time)];
414  memset(&tv, 0, sizeof(tv));
415  if ((eos != strptime(fancy_time, "%a %b %d %H:%M:%S %Y", &tv)) &&
416  (eos != strptime(fancy_time, "%c", &tv)) &&
417  (eos != strptime(fancy_time, "%Ec", &tv)) &&
418  (eos != strptime(fancy_time, "%Y-%m-%d %H:%M:%S", &tv)) &&
419  (eos != strptime(fancy_time, "%Y-%m-%d %H:%M", &tv)) &&
420  (eos != strptime(fancy_time, "%x", &tv)) &&
421  (eos != strptime(fancy_time, "%Ex", &tv)) &&
422  (eos != strptime(fancy_time, "%Y-%m-%d", &tv)) &&
423  (eos != strptime(fancy_time, "%Y-%m", &tv)) &&
424  (eos != strptime(fancy_time, "%Y", &tv)))
425  return GNUNET_SYSERR;
426  t = mktime(&tv);
427  atime->abs_value_us = (uint64_t)((uint64_t)t * 1000LL * 1000LL);
428  return GNUNET_OK;
429 }
430 
431 
445 char *
446 GNUNET_STRINGS_conv(const char *input,
447  size_t len,
448  const char *input_charset,
449  const char *output_charset)
450 {
451  char *ret;
452  uint8_t *u8_string;
453  char *encoded_string;
454  size_t u8_string_length;
455  size_t encoded_string_length;
456 
457  u8_string = u8_conv_from_encoding(input_charset,
458  iconveh_error,
459  input,
460  len,
461  NULL,
462  NULL,
463  &u8_string_length);
464  if (NULL == u8_string)
465  {
466  LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "u8_conv_from_encoding");
467  goto fail;
468  }
469  if (0 == strcmp(output_charset, "UTF-8"))
470  {
471  ret = GNUNET_malloc(u8_string_length + 1);
472  GNUNET_memcpy(ret, u8_string, u8_string_length);
473  ret[u8_string_length] = '\0';
474  free(u8_string);
475  return ret;
476  }
477  encoded_string = u8_conv_to_encoding(output_charset,
478  iconveh_error,
479  u8_string,
480  u8_string_length,
481  NULL,
482  NULL,
483  &encoded_string_length);
484  free(u8_string);
485  if (NULL == encoded_string)
486  {
487  LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "u8_conv_to_encoding");
488  goto fail;
489  }
490  ret = GNUNET_malloc(encoded_string_length + 1);
491  GNUNET_memcpy(ret, encoded_string, encoded_string_length);
492  ret[encoded_string_length] = '\0';
493  free(encoded_string);
494  return ret;
495 fail:
497  _("Character sets requested were `%s'->`%s'\n"),
498  "UTF-8",
499  output_charset);
500  ret = GNUNET_malloc(len + 1);
501  GNUNET_memcpy(ret, input, len);
502  ret[len] = '\0';
503  return ret;
504 }
505 
506 
519 char *
520 GNUNET_STRINGS_to_utf8(const char *input, size_t len, const char *charset)
521 {
522  return GNUNET_STRINGS_conv(input, len, charset, "UTF-8");
523 }
524 
525 
537 char *
538 GNUNET_STRINGS_from_utf8(const char *input, size_t len, const char *charset)
539 {
540  return GNUNET_STRINGS_conv(input, len, "UTF-8", charset);
541 }
542 
543 
551 void
552 GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
553 {
554  uint8_t *tmp_in;
555  size_t len;
556 
557  tmp_in = u8_tolower((uint8_t *)input,
558  strlen((char *)input),
559  NULL,
560  UNINORM_NFD,
561  NULL,
562  &len);
563  GNUNET_memcpy(output, tmp_in, len);
564  output[len] = '\0';
565  free(tmp_in);
566 }
567 
568 
576 void
577 GNUNET_STRINGS_utf8_toupper(const char *input, char *output)
578 {
579  uint8_t *tmp_in;
580  size_t len;
581 
582  tmp_in = u8_toupper((uint8_t *)input,
583  strlen((char *)input),
584  NULL,
585  UNINORM_NFD,
586  NULL,
587  &len);
588  GNUNET_memcpy(output, tmp_in, len);
589  output[len] = '\0';
590  free(tmp_in);
591 }
592 
593 
601 char *
603 {
604  char *buffer;
605  size_t len;
606  char *fm;
607  const char *fil_ptr;
608 
609  if (fil == NULL)
610  return NULL;
611 
612  if (fil[0] == DIR_SEPARATOR)
613  /* absolute path, just copy */
614  return GNUNET_strdup(fil);
615  if (fil[0] == '~')
616  {
617  fm = getenv("HOME");
618  if (fm == NULL)
619  {
621  _("Failed to expand `$HOME': environment variable `HOME' not set"));
622  return NULL;
623  }
624  fm = GNUNET_strdup(fm);
625  /* do not copy '~' */
626  fil_ptr = fil + 1;
627 
628  /* skip over dir seperator to be consistent */
629  if (fil_ptr[0] == DIR_SEPARATOR)
630  fil_ptr++;
631  }
632  else
633  {
634  /* relative path */
635  fil_ptr = fil;
636  len = 512;
637  fm = NULL;
638  while (1)
639  {
640  buffer = GNUNET_malloc(len);
641  if (getcwd(buffer, len) != NULL)
642  {
643  fm = buffer;
644  break;
645  }
646  if ((errno == ERANGE) && (len < 1024 * 1024 * 4))
647  {
648  len *= 2;
649  GNUNET_free(buffer);
650  continue;
651  }
652  GNUNET_free(buffer);
653  break;
654  }
655  if (fm == NULL)
656  {
658  buffer = getenv("PWD"); /* alternative */
659  if (buffer != NULL)
660  fm = GNUNET_strdup(buffer);
661  }
662  if (fm == NULL)
663  fm = GNUNET_strdup("./"); /* give up */
664  }
665  GNUNET_asprintf(&buffer,
666  "%s%s%s",
667  fm,
668  (fm[strlen(fm) - 1] == DIR_SEPARATOR) ? ""
670  fil_ptr);
671  GNUNET_free(fm);
672  return buffer;
673 }
674 
675 
685 const char *
687  int do_round)
688 {
689  static char buf[128];
690  const char *unit = _(/* time unit */ "┬Ás");
691  uint64_t dval = delta.rel_value_us;
692 
693  if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == delta.rel_value_us)
694  return _("forever");
695  if (0 == delta.rel_value_us)
696  return _("0 ms");
697  if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000)))
698  {
699  dval = dval / 1000;
700  unit = _(/* time unit */ "ms");
701  if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000)))
702  {
703  dval = dval / 1000;
704  unit = _(/* time unit */ "s");
705  if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60)))
706  {
707  dval = dval / 60;
708  unit = _(/* time unit */ "m");
709  if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60)))
710  {
711  dval = dval / 60;
712  unit = _(/* time unit */ "h");
713  if (((GNUNET_YES == do_round) && (dval > 5 * 24)) ||
714  (0 == (dval % 24)))
715  {
716  dval = dval / 24;
717  if (1 == dval)
718  unit = _(/* time unit */ "day");
719  else
720  unit = _(/* time unit */ "days");
721  }
722  }
723  }
724  }
725  }
726  GNUNET_snprintf(buf, sizeof(buf), "%llu %s", dval, unit);
727  return buf;
728 }
729 
730 
740 const char *
742 {
743  static char buf[255];
744  time_t tt;
745  struct tm *tp;
746 
747  if (t.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
748  return _("end of time");
749  tt = t.abs_value_us / 1000LL / 1000LL;
750  tp = localtime(&tt);
751  /* This is hacky, but i don't know a way to detect libc character encoding.
752  * Just expect utf8 from glibc these days.
753  * As for msvcrt, use the wide variant, which always returns utf16
754  * (otherwise we'd have to detect current codepage or use W32API character
755  * set conversion routines to convert to UTF8).
756  */
757 
758  strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", tp);
759 
760  return buf;
761 }
762 
763 
775 const char *
777 {
778  const char *short_fn = filename;
779  const char *ss;
780 
781  while (NULL != (ss = strstr(short_fn, DIR_SEPARATOR_STR)) && (ss[1] != '\0'))
782  short_fn = 1 + ss;
783  return short_fn;
784 }
785 
786 
794 static unsigned int
795 getValue__(unsigned char a)
796 {
797  unsigned int dec;
798 
799  switch (a)
800  {
801  case 'O':
802  case 'o':
803  a = '0';
804  break;
805 
806  case 'i':
807  case 'I':
808  case 'l':
809  case 'L':
810  a = '1';
811  break;
812 
813  /* also consider U to be V */
814  case 'u':
815  case 'U':
816  a = 'V';
817  break;
818 
819  default:
820  break;
821  }
822  if ((a >= '0') && (a <= '9'))
823  return a - '0';
824  if ((a >= 'a') && (a <= 'z'))
825  a = toupper(a);
826  /* return (a - 'a' + 10); */
827  dec = 0;
828  if ((a >= 'A') && (a <= 'Z'))
829  {
830  if ('I' < a)
831  dec++;
832  if ('L' < a)
833  dec++;
834  if ('O' < a)
835  dec++;
836  if ('U' < a)
837  dec++;
838  return(a - 'A' + 10 - dec);
839  }
840  return -1;
841 }
842 
843 
856 char *
858  size_t size,
859  char *out,
860  size_t out_size)
861 {
865  static char *encTable__ = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
866  unsigned int wpos;
867  unsigned int rpos;
868  unsigned int bits;
869  unsigned int vbit;
870  const unsigned char *udata;
871 
872  udata = data;
873  if (out_size < (size * 8 + 4) / 5)
874  {
875  GNUNET_break(0);
876  return NULL;
877  }
878  vbit = 0;
879  wpos = 0;
880  rpos = 0;
881  bits = 0;
882  while ((rpos < size) || (vbit > 0))
883  {
884  if ((rpos < size) && (vbit < 5))
885  {
886  bits = (bits << 8) | udata[rpos++]; /* eat 8 more bits */
887  vbit += 8;
888  }
889  if (vbit < 5)
890  {
891  bits <<= (5 - vbit); /* zero-padding */
892  GNUNET_assert(vbit == ((size * 8) % 5));
893  vbit = 5;
894  }
895  if (wpos >= out_size)
896  {
897  GNUNET_break(0);
898  return NULL;
899  }
900  out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
901  vbit -= 5;
902  }
903  GNUNET_assert(0 == vbit);
904  if (wpos < out_size)
905  out[wpos] = '\0';
906  return &out[wpos];
907 }
908 
909 
920 char *
922 {
923  char *str_buf;
924  size_t len = size * 8;
925  char *end;
926 
927  if (len % 5 > 0)
928  len += 5 - len % 5;
929  len /= 5;
930  str_buf = GNUNET_malloc(len + 1);
931  end = GNUNET_STRINGS_data_to_string(buf, size, str_buf, len);
932  if (NULL == end)
933  {
934  GNUNET_free(str_buf);
935  return NULL;
936  }
937  *end = '\0';
938  return str_buf;
939 }
940 
941 
952 int
954  size_t enclen,
955  void *out,
956  size_t out_size)
957 {
958  unsigned int rpos;
959  unsigned int wpos;
960  unsigned int bits;
961  unsigned int vbit;
962  int ret;
963  int shift;
964  unsigned char *uout;
965  unsigned int encoded_len = out_size * 8;
966 
967  if (0 == enclen)
968  {
969  if (0 == out_size)
970  return GNUNET_OK;
971  return GNUNET_SYSERR;
972  }
973  uout = out;
974  wpos = out_size;
975  rpos = enclen;
976  if ((encoded_len % 5) > 0)
977  {
978  vbit = encoded_len % 5; /* padding! */
979  shift = 5 - vbit;
980  bits = (ret = getValue__(enc[--rpos])) >> shift;
981  }
982  else
983  {
984  vbit = 5;
985  shift = 0;
986  bits = (ret = getValue__(enc[--rpos]));
987  }
988  if ((encoded_len + shift) / 5 != enclen)
989  return GNUNET_SYSERR;
990  if (-1 == ret)
991  return GNUNET_SYSERR;
992  while (wpos > 0)
993  {
994  if (0 == rpos)
995  {
996  GNUNET_break(0);
997  return GNUNET_SYSERR;
998  }
999  bits = ((ret = getValue__(enc[--rpos])) << vbit) | bits;
1000  if (-1 == ret)
1001  return GNUNET_SYSERR;
1002  vbit += 5;
1003  if (vbit >= 8)
1004  {
1005  uout[--wpos] = (unsigned char)bits;
1006  bits >>= 8;
1007  vbit -= 8;
1008  }
1009  }
1010  if ((0 != rpos) || (0 != vbit))
1011  return GNUNET_SYSERR;
1012  return GNUNET_OK;
1013 }
1014 
1015 
1032 int
1033 GNUNET_STRINGS_parse_uri(const char *path,
1034  char **scheme_part,
1035  const char **path_part)
1036 {
1037  size_t len;
1038  size_t i;
1039  int end;
1040  int pp_state = 0;
1041  const char *post_scheme_part = NULL;
1042 
1043  len = strlen(path);
1044  for (end = 0, i = 0; !end && i < len; i++)
1045  {
1046  switch (pp_state)
1047  {
1048  case 0:
1049  if ((path[i] == ':') && (i > 0))
1050  {
1051  pp_state += 1;
1052  continue;
1053  }
1054  if (!((path[i] >= 'A' && path[i] <= 'Z') ||
1055  (path[i] >= 'a' && path[i] <= 'z') ||
1056  (path[i] >= '0' && path[i] <= '9') || path[i] == '+' ||
1057  path[i] == '-' || (path[i] == '.')))
1058  end = 1;
1059  break;
1060 
1061  case 1:
1062  case 2:
1063  if (path[i] == '/')
1064  {
1065  pp_state += 1;
1066  continue;
1067  }
1068  end = 1;
1069  break;
1070 
1071  case 3:
1072  post_scheme_part = &path[i];
1073  end = 1;
1074  break;
1075 
1076  default:
1077  end = 1;
1078  }
1079  }
1080  if (post_scheme_part == NULL)
1081  return GNUNET_NO;
1082  if (scheme_part)
1083  {
1084  *scheme_part = GNUNET_malloc(post_scheme_part - path + 1);
1085  GNUNET_memcpy(*scheme_part, path, post_scheme_part - path);
1086  (*scheme_part)[post_scheme_part - path] = '\0';
1087  }
1088  if (path_part)
1089  *path_part = post_scheme_part;
1090  return GNUNET_YES;
1091 }
1092 
1093 
1108 int
1110  int can_be_uri,
1111  int *r_is_uri,
1112  char **r_uri_scheme)
1113 {
1114  const char *post_scheme_path;
1115  int is_uri;
1116  char *uri;
1117  /* consider POSIX paths to be absolute too, even on W32,
1118  * as plibc expansion will fix them for us.
1119  */
1120  if (filename[0] == '/')
1121  return GNUNET_YES;
1122  if (can_be_uri)
1123  {
1124  is_uri = GNUNET_STRINGS_parse_uri(filename, &uri, &post_scheme_path);
1125  if (r_is_uri)
1126  *r_is_uri = is_uri;
1127  if (is_uri)
1128  {
1129  if (r_uri_scheme)
1130  *r_uri_scheme = uri;
1131  else
1132  GNUNET_free_non_null(uri);
1133 
1134  return GNUNET_STRINGS_path_is_absolute(post_scheme_path,
1135  GNUNET_NO,
1136  NULL,
1137  NULL);
1138  }
1139  }
1140  else
1141  {
1142  if (r_is_uri)
1143  *r_is_uri = GNUNET_NO;
1144  }
1145 
1146  return GNUNET_NO;
1147 }
1148 
1149 
1158 int
1160  enum GNUNET_STRINGS_FilenameCheck checks)
1161 {
1162  struct stat st;
1163 
1164  if ((NULL == filename) || (filename[0] == '\0'))
1165  return GNUNET_SYSERR;
1166  if (0 != (checks & GNUNET_STRINGS_CHECK_IS_ABSOLUTE))
1167  if (!GNUNET_STRINGS_path_is_absolute(filename, GNUNET_NO, NULL, NULL))
1168  return GNUNET_NO;
1169  if (0 != (checks &
1172  {
1173  if (0 != stat(filename, &st))
1174  {
1175  if (0 != (checks & GNUNET_STRINGS_CHECK_EXISTS))
1176  return GNUNET_NO;
1177  else
1178  return GNUNET_SYSERR;
1179  }
1180  }
1181  if (0 != (checks & GNUNET_STRINGS_CHECK_IS_DIRECTORY))
1182  if (!S_ISDIR(st.st_mode))
1183  return GNUNET_NO;
1184  if (0 != (checks & GNUNET_STRINGS_CHECK_IS_LINK))
1185  if (!S_ISLNK(st.st_mode))
1186  return GNUNET_NO;
1187  return GNUNET_YES;
1188 }
1189 
1190 
1203 int
1205  uint16_t addrlen,
1206  struct sockaddr_in6 *r_buf)
1207 {
1208  char zbuf[addrlen + 1];
1209  int ret;
1210  char *port_colon;
1211  unsigned int port;
1212  char dummy[2];
1213 
1214  if (addrlen < 6)
1215  return GNUNET_SYSERR;
1216  GNUNET_memcpy(zbuf, zt_addr, addrlen);
1217  if ('[' != zbuf[0])
1218  {
1220  _("IPv6 address did not start with `['\n"));
1221  return GNUNET_SYSERR;
1222  }
1223  zbuf[addrlen] = '\0';
1224  port_colon = strrchr(zbuf, ':');
1225  if (NULL == port_colon)
1226  {
1228  _("IPv6 address did contain ':' to separate port number\n"));
1229  return GNUNET_SYSERR;
1230  }
1231  if (']' != *(port_colon - 1))
1232  {
1233  GNUNET_log(
1235  _("IPv6 address did contain ']' before ':' to separate port number\n"));
1236  return GNUNET_SYSERR;
1237  }
1238  ret = sscanf(port_colon, ":%u%1s", &port, dummy);
1239  if ((1 != ret) || (port > 65535))
1240  {
1241  GNUNET_log(
1243  _("IPv6 address did contain a valid port number after the last ':'\n"));
1244  return GNUNET_SYSERR;
1245  }
1246  *(port_colon - 1) = '\0';
1247  memset(r_buf, 0, sizeof(struct sockaddr_in6));
1248  ret = inet_pton(AF_INET6, &zbuf[1], &r_buf->sin6_addr);
1249  if (ret <= 0)
1250  {
1252  _("Invalid IPv6 address `%s': %s\n"),
1253  &zbuf[1],
1254  strerror(errno));
1255  return GNUNET_SYSERR;
1256  }
1257  r_buf->sin6_port = htons(port);
1258  r_buf->sin6_family = AF_INET6;
1259 #if HAVE_SOCKADDR_IN_SIN_LEN
1260  r_buf->sin6_len = (u_char)sizeof(struct sockaddr_in6);
1261 #endif
1262  return GNUNET_OK;
1263 }
1264 
1265 
1277 int
1279  uint16_t addrlen,
1280  struct sockaddr_in *r_buf)
1281 {
1282  unsigned int temps[4];
1283  unsigned int port;
1284  unsigned int cnt;
1285  char dummy[2];
1286 
1287  if (addrlen < 9)
1288  return GNUNET_SYSERR;
1289  cnt = sscanf(zt_addr,
1290  "%u.%u.%u.%u:%u%1s",
1291  &temps[0],
1292  &temps[1],
1293  &temps[2],
1294  &temps[3],
1295  &port,
1296  dummy);
1297  if (5 != cnt)
1298  return GNUNET_SYSERR;
1299  for (cnt = 0; cnt < 4; cnt++)
1300  if (temps[cnt] > 0xFF)
1301  return GNUNET_SYSERR;
1302  if (port > 65535)
1303  return GNUNET_SYSERR;
1304  r_buf->sin_family = AF_INET;
1305  r_buf->sin_port = htons(port);
1306  r_buf->sin_addr.s_addr =
1307  htonl((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) + temps[3]);
1308 #if HAVE_SOCKADDR_IN_SIN_LEN
1309  r_buf->sin_len = (u_char)sizeof(struct sockaddr_in);
1310 #endif
1311  return GNUNET_OK;
1312 }
1313 
1314 
1326 int
1328  uint16_t addrlen,
1329  struct sockaddr_storage *r_buf)
1330 {
1331  if (addr[0] == '[')
1332  return GNUNET_STRINGS_to_address_ipv6(addr,
1333  addrlen,
1334  (struct sockaddr_in6 *)r_buf);
1335  return GNUNET_STRINGS_to_address_ipv4(addr,
1336  addrlen,
1337  (struct sockaddr_in *)r_buf);
1338 }
1339 
1340 
1350 size_t
1352  uint8_t *af,
1353  struct sockaddr **sa)
1354 {
1355  char *cp = GNUNET_strdup(addr);
1356 
1357  *af = AF_UNSPEC;
1358  if ('[' == *addr)
1359  {
1360  /* IPv6 */
1361  *sa = GNUNET_malloc(sizeof(struct sockaddr_in6));
1362  if (GNUNET_OK !=
1364  strlen(cp),
1365  (struct sockaddr_in6 *)*sa))
1366  {
1367  GNUNET_free(*sa);
1368  *sa = NULL;
1369  GNUNET_free(cp);
1370  return 0;
1371  }
1372  *af = AF_INET6;
1373  GNUNET_free(cp);
1374  return sizeof(struct sockaddr_in6);
1375  }
1376  else
1377  {
1378  /* IPv4 */
1379  *sa = GNUNET_malloc(sizeof(struct sockaddr_in));
1380  if (GNUNET_OK !=
1382  strlen(cp),
1383  (struct sockaddr_in *)*sa))
1384  {
1385  GNUNET_free(*sa);
1386  *sa = NULL;
1387  GNUNET_free(cp);
1388  return 0;
1389  }
1390  *af = AF_INET;
1391  GNUNET_free(cp);
1392  return sizeof(struct sockaddr_in);
1393  }
1394 }
1395 
1396 
1401 static char *const *
1402 _make_continuous_arg_copy(int argc, char *const *argv)
1403 {
1404  size_t argvsize = 0;
1405  int i;
1406  char **new_argv;
1407  char *p;
1408 
1409  for (i = 0; i < argc; i++)
1410  argvsize += strlen(argv[i]) + 1 + sizeof(char *);
1411  new_argv = GNUNET_malloc(argvsize + sizeof(char *));
1412  p = (char *)&new_argv[argc + 1];
1413  for (i = 0; i < argc; i++)
1414  {
1415  new_argv[i] = p;
1416  strcpy(p, argv[i]);
1417  p += strlen(argv[i]) + 1;
1418  }
1419  new_argv[argc] = NULL;
1420  return (char *const *)new_argv;
1421 }
1422 
1423 
1438 int
1440  char *const *argv,
1441  int *u8argc,
1442  char *const **u8argv)
1443 {
1444  char *const *new_argv =
1445  (char *const *)_make_continuous_arg_copy(argc, argv);
1446  *u8argv = new_argv;
1447  *u8argc = argc;
1448  return GNUNET_OK;
1449 }
1450 
1451 
1461 static int
1462 parse_port_policy(const char *port_policy,
1463  struct GNUNET_STRINGS_PortPolicy *pp)
1464 {
1465  const char *pos;
1466  int s;
1467  int e;
1468  char eol[2];
1469 
1470  pos = port_policy;
1471  if ('!' == *pos)
1472  {
1474  pos++;
1475  }
1476  if (2 == sscanf(pos, "%u-%u%1s", &s, &e, eol))
1477  {
1478  if ((0 == s) || (s > 0xFFFF) || (e < s) || (e > 0xFFFF))
1479  {
1480  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, _("Port not in range\n"));
1481  return GNUNET_SYSERR;
1482  }
1483  pp->start_port = (uint16_t)s;
1484  pp->end_port = (uint16_t)e;
1485  return GNUNET_OK;
1486  }
1487  if (1 == sscanf(pos, "%u%1s", &s, eol))
1488  {
1489  if ((0 == s) || (s > 0xFFFF))
1490  {
1491  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, _("Port not in range\n"));
1492  return GNUNET_SYSERR;
1493  }
1494 
1495  pp->start_port = (uint16_t)s;
1496  pp->end_port = (uint16_t)s;
1497  return GNUNET_OK;
1498  }
1500  _("Malformed port policy `%s'\n"),
1501  port_policy);
1502  return GNUNET_SYSERR;
1503 }
1504 
1505 
1519 GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
1520 {
1521  unsigned int count;
1522  unsigned int i;
1523  unsigned int j;
1524  unsigned int len;
1525  int cnt;
1526  unsigned int pos;
1527  unsigned int temps[8];
1528  int slash;
1530  int colon;
1531  int end;
1532  char *routeList;
1533  char dummy[2];
1534 
1535  if (NULL == routeListX)
1536  return NULL;
1537  len = strlen(routeListX);
1538  if (0 == len)
1539  return NULL;
1540  routeList = GNUNET_strdup(routeListX);
1541  count = 0;
1542  for (i = 0; i < len; i++)
1543  if (routeList[i] == ';')
1544  count++;
1545  result = GNUNET_malloc(sizeof(struct GNUNET_STRINGS_IPv4NetworkPolicy) *
1546  (count + 1));
1547  i = 0;
1548  pos = 0;
1549  while (i < count)
1550  {
1551  for (colon = pos; ':' != routeList[colon]; colon++)
1552  if ((';' == routeList[colon]) || ('\0' == routeList[colon]))
1553  break;
1554  for (end = colon; ';' != routeList[end]; end++)
1555  if ('\0' == routeList[end])
1556  break;
1557  if ('\0' == routeList[end])
1558  break;
1559  routeList[end] = '\0';
1560  if (':' == routeList[colon])
1561  {
1562  routeList[colon] = '\0';
1563  if (GNUNET_OK != parse_port_policy(&routeList[colon + 1], &result[i].pp))
1564  break;
1565  }
1566  cnt = sscanf(&routeList[pos],
1567  "%u.%u.%u.%u/%u.%u.%u.%u%1s",
1568  &temps[0],
1569  &temps[1],
1570  &temps[2],
1571  &temps[3],
1572  &temps[4],
1573  &temps[5],
1574  &temps[6],
1575  &temps[7],
1576  dummy);
1577  if (8 == cnt)
1578  {
1579  for (j = 0; j < 8; j++)
1580  if (temps[j] > 0xFF)
1581  {
1583  _("Invalid format for IP: `%s'\n"),
1584  &routeList[pos]);
1585  GNUNET_free(result);
1586  GNUNET_free(routeList);
1587  return NULL;
1588  }
1589  result[i].network.s_addr = htonl((temps[0] << 24) + (temps[1] << 16) +
1590  (temps[2] << 8) + temps[3]);
1591  result[i].netmask.s_addr = htonl((temps[4] << 24) + (temps[5] << 16) +
1592  (temps[6] << 8) + temps[7]);
1593  pos = end + 1;
1594  i++;
1595  continue;
1596  }
1597  /* try second notation */
1598  cnt = sscanf(&routeList[pos],
1599  "%u.%u.%u.%u/%u%1s",
1600  &temps[0],
1601  &temps[1],
1602  &temps[2],
1603  &temps[3],
1604  &slash,
1605  dummy);
1606  if (5 == cnt)
1607  {
1608  for (j = 0; j < 4; j++)
1609  if (temps[j] > 0xFF)
1610  {
1612  _("Invalid format for IP: `%s'\n"),
1613  &routeList[pos]);
1614  GNUNET_free(result);
1615  GNUNET_free(routeList);
1616  return NULL;
1617  }
1618  result[i].network.s_addr = htonl((temps[0] << 24) + (temps[1] << 16) +
1619  (temps[2] << 8) + temps[3]);
1620  if ((slash <= 32) && (slash >= 0))
1621  {
1622  result[i].netmask.s_addr = 0;
1623  while (slash > 0)
1624  {
1625  result[i].netmask.s_addr =
1626  (result[i].netmask.s_addr >> 1) + 0x80000000;
1627  slash--;
1628  }
1629  result[i].netmask.s_addr = htonl(result[i].netmask.s_addr);
1630  pos = end + 1;
1631  i++;
1632  continue;
1633  }
1634  else
1635  {
1637  _("Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
1638  slash);
1639  GNUNET_free(result);
1640  GNUNET_free(routeList);
1641  return NULL; /* error */
1642  }
1643  }
1644  /* try third notation */
1645  slash = 32;
1646  cnt = sscanf(&routeList[pos],
1647  "%u.%u.%u.%u%1s",
1648  &temps[0],
1649  &temps[1],
1650  &temps[2],
1651  &temps[3],
1652  dummy);
1653  if (4 == cnt)
1654  {
1655  for (j = 0; j < 4; j++)
1656  if (temps[j] > 0xFF)
1657  {
1659  _("Invalid format for IP: `%s'\n"),
1660  &routeList[pos]);
1661  GNUNET_free(result);
1662  GNUNET_free(routeList);
1663  return NULL;
1664  }
1665  result[i].network.s_addr = htonl((temps[0] << 24) + (temps[1] << 16) +
1666  (temps[2] << 8) + temps[3]);
1667  result[i].netmask.s_addr = 0;
1668  while (slash > 0)
1669  {
1670  result[i].netmask.s_addr = (result[i].netmask.s_addr >> 1) + 0x80000000;
1671  slash--;
1672  }
1673  result[i].netmask.s_addr = htonl(result[i].netmask.s_addr);
1674  pos = end + 1;
1675  i++;
1676  continue;
1677  }
1679  _("Invalid format for IP: `%s'\n"),
1680  &routeList[pos]);
1681  GNUNET_free(result);
1682  GNUNET_free(routeList);
1683  return NULL; /* error */
1684  }
1685  if (pos < strlen(routeList))
1686  {
1688  _("Invalid format: `%s'\n"),
1689  &routeListX[pos]);
1690  GNUNET_free(result);
1691  GNUNET_free(routeList);
1692  return NULL; /* oops */
1693  }
1694  GNUNET_free(routeList);
1695  return result; /* ok */
1696 }
1697 
1698 
1711 GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
1712 {
1713  unsigned int count;
1714  unsigned int i;
1715  unsigned int len;
1716  unsigned int pos;
1717  int start;
1718  int slash;
1719  int ret;
1720  char *routeList;
1722  unsigned int bits;
1723  unsigned int off;
1724  int save;
1725  int colon;
1726  char dummy[2];
1727 
1728  if (NULL == routeListX)
1729  return NULL;
1730  len = strlen(routeListX);
1731  if (0 == len)
1732  return NULL;
1733  routeList = GNUNET_strdup(routeListX);
1734  count = 0;
1735  for (i = 0; i < len; i++)
1736  if (';' == routeList[i])
1737  count++;
1738  if (';' != routeList[len - 1])
1739  {
1741  _("Invalid network notation (does not end with ';': `%s')\n"),
1742  routeList);
1743  GNUNET_free(routeList);
1744  return NULL;
1745  }
1746 
1747  result = GNUNET_malloc(sizeof(struct GNUNET_STRINGS_IPv6NetworkPolicy) *
1748  (count + 1));
1749  i = 0;
1750  pos = 0;
1751  while (i < count)
1752  {
1753  start = pos;
1754  while (';' != routeList[pos])
1755  pos++;
1756  slash = pos;
1757  while ((slash >= start) && (routeList[slash] != '/'))
1758  slash--;
1759 
1760  if (slash < start)
1761  {
1762  memset(&result[i].netmask, 0xFF, sizeof(struct in6_addr));
1763  slash = pos;
1764  }
1765  else
1766  {
1767  routeList[pos] = '\0';
1768  for (colon = pos; ':' != routeList[colon]; colon--)
1769  if ('/' == routeList[colon])
1770  break;
1771  if (':' == routeList[colon])
1772  {
1773  routeList[colon] = '\0';
1774  if (GNUNET_OK !=
1775  parse_port_policy(&routeList[colon + 1], &result[i].pp))
1776  {
1777  GNUNET_free(result);
1778  GNUNET_free(routeList);
1779  return NULL;
1780  }
1781  }
1782  ret = inet_pton(AF_INET6, &routeList[slash + 1], &result[i].netmask);
1783  if (ret <= 0)
1784  {
1785  save = errno;
1786  if ((1 != sscanf(&routeList[slash + 1], "%u%1s", &bits, dummy)) ||
1787  (bits > 128))
1788  {
1789  if (0 == ret)
1791  _("Wrong format `%s' for netmask\n"),
1792  &routeList[slash + 1]);
1793  else
1794  {
1795  errno = save;
1797  }
1798  GNUNET_free(result);
1799  GNUNET_free(routeList);
1800  return NULL;
1801  }
1802  off = 0;
1803  while (bits > 8)
1804  {
1805  result[i].netmask.s6_addr[off++] = 0xFF;
1806  bits -= 8;
1807  }
1808  while (bits > 0)
1809  {
1810  result[i].netmask.s6_addr[off] =
1811  (result[i].netmask.s6_addr[off] >> 1) + 0x80;
1812  bits--;
1813  }
1814  }
1815  }
1816  routeList[slash] = '\0';
1817  ret = inet_pton(AF_INET6, &routeList[start], &result[i].network);
1818  if (ret <= 0)
1819  {
1820  if (0 == ret)
1822  _("Wrong format `%s' for network\n"),
1823  &routeList[slash + 1]);
1824  else
1825  LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "inet_pton");
1826  GNUNET_free(result);
1827  GNUNET_free(routeList);
1828  return NULL;
1829  }
1830  pos++;
1831  i++;
1832  }
1833  GNUNET_free(routeList);
1834  return result;
1835 }
1836 
1837 
1840 #define FILLCHAR '='
1841 static char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1842  "abcdefghijklmnopqrstuvwxyz"
1843  "0123456789+/";
1844 
1845 
1855 size_t
1856 GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
1857 {
1858  const char *data = in;
1859  size_t ret;
1860  char *opt;
1861 
1862  ret = 0;
1863  opt = GNUNET_malloc(2 + (len * 4 / 3) + 8);
1864  for (size_t i = 0; i < len; ++i)
1865  {
1866  char c;
1867 
1868  c = (data[i] >> 2) & 0x3f;
1869  opt[ret++] = cvt[(int)c];
1870  c = (data[i] << 4) & 0x3f;
1871  if (++i < len)
1872  c |= (data[i] >> 4) & 0x0f;
1873  opt[ret++] = cvt[(int)c];
1874  if (i < len)
1875  {
1876  c = (data[i] << 2) & 0x3f;
1877  if (++i < len)
1878  c |= (data[i] >> 6) & 0x03;
1879  opt[ret++] = cvt[(int)c];
1880  }
1881  else
1882  {
1883  ++i;
1884  opt[ret++] = FILLCHAR;
1885  }
1886  if (i < len)
1887  {
1888  c = data[i] & 0x3f;
1889  opt[ret++] = cvt[(int)c];
1890  }
1891  else
1892  {
1893  opt[ret++] = FILLCHAR;
1894  }
1895  }
1896  *output = opt;
1897  return ret;
1898 }
1899 
1900 #define cvtfind(a) \
1901  ((((a) >= 'A') && ((a) <= 'Z')) \
1902  ? (a) - 'A' \
1903  : (((a) >= 'a') && ((a) <= 'z')) \
1904  ? (a) - 'a' + 26 \
1905  : (((a) >= '0') && ((a) <= '9')) \
1906  ? (a) - '0' + 52 \
1907  : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1)
1908 
1909 
1919 size_t
1920 GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **out)
1921 {
1922  char *output;
1923  size_t ret = 0;
1924 
1925 #define CHECK_CRLF \
1926  while (data[i] == '\r' || data[i] == '\n') \
1927  { \
1928  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, \
1929  "ignoring CR/LF\n"); \
1930  i++; \
1931  if (i >= len) \
1932  goto END; \
1933  }
1934 
1935  output = GNUNET_malloc((len * 3 / 4) + 8);
1937  "base64_decode decoding len=%d\n",
1938  (int)len);
1939  for (size_t i = 0; i < len; ++i)
1940  {
1941  char c;
1942  char c1;
1943 
1944  CHECK_CRLF;
1945  if (FILLCHAR == data[i])
1946  break;
1947  c = (char)cvtfind(data[i]);
1948  ++i;
1949  CHECK_CRLF;
1950  c1 = (char)cvtfind(data[i]);
1951  c = (c << 2) | ((c1 >> 4) & 0x3);
1952  output[ret++] = c;
1953  if (++i < len)
1954  {
1955  CHECK_CRLF;
1956  c = data[i];
1957  if (FILLCHAR == c)
1958  break;
1959  c = (char)cvtfind(c);
1960  c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
1961  output[ret++] = c1;
1962  }
1963  if (++i < len)
1964  {
1965  CHECK_CRLF;
1966  c1 = data[i];
1967  if (FILLCHAR == c1)
1968  break;
1969 
1970  c1 = (char)cvtfind(c1);
1971  c = ((c << 6) & 0xc0) | c1;
1972  output[ret++] = c;
1973  }
1974  }
1975 END:
1976  *out = output;
1977  return ret;
1978 }
1979 
1980 
1981 /* 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:243
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1519
#define CHECK_CRLF
#define FILLCHAR
******************** Base64 encoding
Definition: strings.c:1840
static struct GNUNET_SCHEDULER_Task * tt
Task scheduled to handle timeout.
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:1462
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:446
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:1033
struct GNUNET_STRINGS_PortPolicy pp
Policy for port access.
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:259
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
Definition: strings.c:1711
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:1439
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:1109
#define cvtfind(a)
Definition: strings.c:1900
#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:350
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.
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:401
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:318
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:1402
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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 int ret
Final status code.
Definition: gnunet-arm.c:89
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:1841
#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".
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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:1278
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:577
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:54
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:168
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:686
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:538
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:1351
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:795
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **out)
Decode from Base64.
Definition: strings.c:1920
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:1856
#define DIR_SEPARATOR
Definition: platform.h:167
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:776
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
int GNUNET_STRINGS_check_filename(const char *filename, enum GNUNET_STRINGS_FilenameCheck checks)
Perform checks on filename.
Definition: strings.c:1159
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition: strings.c:602
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:1204
#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:520
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:77
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:921
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
"asctime", except for GNUnet time.
Definition: strings.c:741
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:238
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:1327
#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:953
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:857
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:552
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...