GNUnet debian-0.26.1-2-gb7dda1fc7
 
Loading...
Searching...
No Matches
strings.c File Reference

string functions More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include <unicase.h>
#include <unistr.h>
#include <uniconv.h>
Include dependency graph for strings.c:

Go to the source code of this file.

Data Structures

struct  ConversionTable
 Unit conversion table entry for 'convert_with_table'. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-strings", __VA_ARGS__)
 
#define LOG_STRERROR(kind, syscall)    GNUNET_log_from_strerror (kind, "util-strings", syscall)
 
#define FILLCHAR   '='
 ******************** Base64 encoding
 
#define cvtfind(a)
 
#define CHECK_CRLF
 

Functions

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).
 
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 (varargs) of type "const char**" to the locations of the respective strings in the buffer.
 
char * GNUNET_STRINGS_byte_size_fancy (unsigned long long size)
 Convert a given filesize into a fancy human-readable format.
 
size_t GNUNET_strlcpy (char *dst, const char *src, size_t n)
 Like strlcpy but portable.
 
static enum GNUNET_GenericReturnValue 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 then multiplying the numbers with the values associated with the respective unit from the conversion table.
 
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, unsigned long long *size)
 Convert a given fancy human-readable size to bytes.
 
enum GNUNET_GenericReturnValue 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.
 
enum GNUNET_GenericReturnValue 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.
 
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_time_to_timestamp (const char *fancy_time, struct GNUNET_TIME_Timestamp *atime)
 Convert a given fancy human-readable time to our internal representation.
 
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 to a string in given output charset.
 
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-8.
 
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.
 
char * GNUNET_STRINGS_utf8_normalize (const char *input)
 Normalize the utf-8 input string to NFC.
 
char * GNUNET_STRINGS_utf8_tolower (const char *input)
 Convert the utf-8 input string to lower case.
 
char * GNUNET_STRINGS_utf8_toupper (const char *input)
 Convert the utf-8 input string to upper case.
 
char * GNUNET_STRINGS_filename_expand (const char *fil)
 Complete filename (a la shell) from abbrevition.
 
const char * GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta, int do_round)
 Give relative time in human-readable fancy format.
 
const char * GNUNET_STRINGS_timestamp_to_string (struct GNUNET_TIME_Timestamp t)
 Like asctime, except for GNUnet time.
 
const char * GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t)
 Like asctime, except for GNUnet time.
 
const char * GNUNET_STRINGS_get_short_name (const char *filename)
 "man basename" Returns a pointer to a part of filename (allocates nothing)!
 
static unsigned int getValue__ (unsigned char a)
 Get the decoded value corresponding to a character according to Crockford Base32 encoding.
 
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 CrockfordBase32.
 
char * GNUNET_STRINGS_data_to_string_alloc (const void *buf, size_t size)
 Return the base32crockford encoding of the given buffer.
 
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data (const char *enc, size_t enclen, void *out, size_t out_size)
 Convert CrockfordBase32 encoding back to data.
 
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data_alloc (const char *enc, size_t enclen, void **out, size_t *out_size)
 Convert CrockfordBase32 encoding back to data.
 
enum GNUNET_GenericReturnValue GNUNET_STRINGS_parse_uri (const char *path, char **scheme_part, const char **path_part)
 Parse a path that might be an URI.
 
enum GNUNET_GenericReturnValue 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's an URI.
 
enum GNUNET_GenericReturnValue GNUNET_STRINGS_check_filename (const char *filename, enum GNUNET_STRINGS_FilenameCheck checks)
 Perform checks on filename.
 
enum GNUNET_GenericReturnValue GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr, size_t addrlen, struct sockaddr_in6 *r_buf)
 Tries to convert zt_addr string to an IPv6 address.
 
enum GNUNET_GenericReturnValue GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, size_t addrlen, struct sockaddr_in *r_buf)
 Tries to convert zt_addr string to an IPv4 address.
 
enum GNUNET_GenericReturnValue 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.
 
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.
 
static enum GNUNET_GenericReturnValue parse_port_policy (const char *port_policy, struct GNUNET_STRINGS_PortPolicy *pp)
 Parse the given port policy.
 
struct GNUNET_STRINGS_IPv4NetworkPolicyGNUNET_STRINGS_parse_ipv4_policy (const char *routeListX)
 Parse an IPv4 network policy.
 
struct GNUNET_STRINGS_IPv6NetworkPolicyGNUNET_STRINGS_parse_ipv6_policy (const char *routeListX)
 Parse an IPv6 network policy.
 
size_t GNUNET_STRINGS_base64_encode (const void *in, size_t len, char **output)
 Encode into Base64.
 
size_t GNUNET_STRINGS_base64url_encode (const void *in, size_t len, char **output)
 Encode into Base64url.
 
size_t GNUNET_STRINGS_base64_decode (const char *data, size_t len, void **out)
 Decode from Base64.
 
size_t GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out)
 Decode from Base64url.
 
size_t GNUNET_STRINGS_urldecode (const char *data, size_t len, char **out)
 url/percent encode (RFC3986).
 
size_t GNUNET_STRINGS_urlencode (size_t len, const char data[static len], char **out)
 url/percent encode (RFC3986).
 
char * GNUNET_STRINGS_get_suffix_from_binary_name (const char *argv0)
 Sometimes we use the binary name to determine which specific test to run.
 

Variables

static const char * cvt
 

Detailed Description

string functions

Author
Nils Durner
Christian Grothoff

Definition in file strings.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-strings", __VA_ARGS__)

Definition at line 36 of file strings.c.

◆ LOG_STRERROR

#define LOG_STRERROR (   kind,
  syscall 
)     GNUNET_log_from_strerror (kind, "util-strings", syscall)

Definition at line 38 of file strings.c.

45{
46 size_t needed;
47 va_list ap;
48
49 needed = 0;
50 va_start (ap, count);
51 while (count > 0)
52 {
53 const char *s = va_arg (ap, const char *);
54 size_t slen = strlen (s) + 1;
55
56 GNUNET_assert (slen <= size - needed);
57 if (NULL != buffer)
58 GNUNET_memcpy (&buffer[needed],
59 s,
60 slen);
61 needed += slen;
62 count--;
63 }
64 va_end (ap);
65 return needed;
66}
67
68
69unsigned int
70GNUNET_STRINGS_buffer_tokenize (const char *buffer,
71 size_t size,
72 unsigned int count,
73 ...)
74{
75 unsigned int start;
76 unsigned int needed;
77 const char **r;
78 va_list ap;
79
80 needed = 0;
81 va_start (ap, count);
82 while (count > 0)
83 {
84 r = va_arg (ap, const char **);
85
86 start = needed;
87 while ((needed < size) && (buffer[needed] != '\0'))
88 needed++;
89 if (needed == size)
90 {
91 va_end (ap);
92 return 0; /* error */
93 }
94 *r = &buffer[start];
95 needed++; /* skip 0-termination */
96 count--;
97 }
98 va_end (ap);
99 return needed;
100}
101
102
103char *
104GNUNET_STRINGS_byte_size_fancy (unsigned long long size)
105{
106 const char *unit = /* size unit */ "b";
107 char *ret;
108
109 if (size > 5 * 1024)
110 {
111 size = size / 1024;
112 unit = "KiB";
113 if (size > 5 * 1024)
114 {
115 size = size / 1024;
116 unit = "MiB";
117 if (size > 5 * 1024)
118 {
119 size = size / 1024;
120 unit = "GiB";
121 if (size > 5 * 1024)
122 {
123 size = size / 1024;
124 unit = "TiB";
125 }
126 }
127 }
128 }
129 ret = GNUNET_malloc (32);
130 GNUNET_snprintf (ret, 32, "%llu %s", size, unit);
131 return ret;
132}
133
134
135size_t
136GNUNET_strlcpy (char *dst,
137 const char *src,
138 size_t n)
139{
140 size_t slen;
141
142 GNUNET_assert (0 != n);
143 slen = strnlen (src, n - 1);
144 memcpy (dst, src, slen);
145 dst[slen] = '\0';
146 return slen;
147}
148
149
153struct ConversionTable
154{
158 const char *name;
159
163 unsigned long long value;
164};
165
166
179convert_with_table (const char *input,
180 const struct ConversionTable *table,
181 unsigned long long *output)
182{
183 unsigned long long ret;
184 char *in;
185 const char *tok;
186 unsigned long long last;
187 unsigned int i;
188 char *sptr;
189
190 ret = 0;
191 last = 0;
192 in = GNUNET_strdup (input);
193 for (tok = strtok_r (in, " ", &sptr);
194 tok != NULL;
195 tok = strtok_r (NULL, " ", &sptr))
196 {
197 do
198 {
199 i = 0;
200 while ((table[i].name != NULL) && (0 != strcasecmp (table[i].name, tok)))
201 i++;
202 if (table[i].name != NULL)
203 {
204 last *= table[i].value;
205 break; /* next tok */
206 }
207 else
208 {
209 char *endptr;
210 ret += last;
211 errno = 0;
212 last = strtoull (tok, &endptr, 10);
213 if ((0 != errno) || (endptr == tok))
214 {
215 GNUNET_free (in);
216 return GNUNET_SYSERR; /* expected number */
217 }
218 if ('\0' == endptr[0])
219 break; /* next tok */
220 else
221 tok = endptr; /* and re-check (handles times like "10s") */
222 }
223 }
224 while (GNUNET_YES);
225 }
226 ret += last;
227 *output = ret;
228 GNUNET_free (in);
229 return GNUNET_OK;
230}
231
232
234GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
235 unsigned long long *size)
236{
237 static const struct ConversionTable table[] =
238 { { "B", 1 },
239 { "KiB", 1024 },
240 { "kB", 1000 },
241 { "MiB", 1024 * 1024 },
242 { "MB", 1000 * 1000 },
243 { "GiB", 1024 * 1024 * 1024 },
244 { "GB", 1000 * 1000 * 1000 },
245 { "TiB", 1024LL * 1024LL * 1024LL * 1024LL },
246 { "TB", 1000LL * 1000LL * 1000LL * 1024LL },
247 { "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL },
248 { "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL },
249 { "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL },
250 { "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL },
251 { NULL, 0 } };
252
253 return convert_with_table (fancy_size, table, size);
254}
255
256
258GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time,
259 struct GNUNET_TIME_Relative *rtime)
260{
261 static const struct ConversionTable table[] =
262 { { "us", 1 },
263 { "ms", 1000 },
264 { "s", 1000 * 1000LL },
265 { "second", 1000 * 1000LL },
266 { "seconds", 1000 * 1000LL },
267 { "\"", 1000 * 1000LL },
268 { "m", 60 * 1000 * 1000LL },
269 { "min", 60 * 1000 * 1000LL },
270 { "minute", 60 * 1000 * 1000LL },
271 { "minutes", 60 * 1000 * 1000LL },
272 { "'", 60 * 1000 * 1000LL },
273 { "h", 60 * 60 * 1000 * 1000LL },
274 { "hour", 60 * 60 * 1000 * 1000LL },
275 { "hours", 60 * 60 * 1000 * 1000LL },
276 { "d", 24 * 60 * 60 * 1000LL * 1000LL },
277 { "day", 24 * 60 * 60 * 1000LL * 1000LL },
278 { "days", 24 * 60 * 60 * 1000LL * 1000LL },
279 { "w", 7 * 24 * 60 * 60 * 1000LL * 1000LL },
280 { "week", 7 * 24 * 60 * 60 * 1000LL * 1000LL },
281 { "weeks", 7 * 24 * 60 * 60 * 1000LL * 1000LL },
282 { "year", 31536000000000LL /* year */ },
283 { "years", 31536000000000LL /* year */ },
284 { "y", 31536000000000LL /* year */ },
285 { "a", 31536000000000LL /* year */ },
286 { NULL, 0 } };
287 int ret;
288 unsigned long long val;
289
290 if (0 == strcasecmp ("forever", fancy_time))
291 {
293 return GNUNET_OK;
294 }
295 ret = convert_with_table (fancy_time, table, &val);
296 rtime->rel_value_us = (uint64_t) val;
297 return ret;
298}
299
300
302GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time,
303 struct GNUNET_TIME_Absolute *atime)
304{
305 struct tm tv;
306 time_t t;
307 const char *eos;
308 unsigned long long l;
309 char dummy;
310
311 if (0 == strcasecmp ("end of time",
312 fancy_time))
313 {
315 return GNUNET_OK;
316 }
317 if ( (1 == sscanf (fancy_time,
318 "%llu%c",
319 &l,
320 &dummy)) &&
321 (l > 9999) )
322 {
323 /* Time given in seconds after epoch, and not a year */
324 atime->abs_value_us = (uint64_t) ((uint64_t) l * 1000LL * 1000LL);
325 return GNUNET_OK;
326 }
327 eos = &fancy_time[strlen (fancy_time)];
328 memset (&tv, 0, sizeof(tv));
329 if ((eos != strptime (fancy_time, "%a %b %d %H:%M:%S %Y", &tv)) &&
330 (eos != strptime (fancy_time, "%c", &tv)) &&
331 (eos != strptime (fancy_time, "%Ec", &tv)) &&
332 (eos != strptime (fancy_time, "%Y-%m-%d %H:%M:%S", &tv)) &&
333 (eos != strptime (fancy_time, "%Y-%m-%d %H:%M", &tv)) &&
334 (eos != strptime (fancy_time, "%x", &tv)) &&
335 (eos != strptime (fancy_time, "%Ex", &tv)) &&
336 (eos != strptime (fancy_time, "%Y-%m-%d", &tv)) &&
337 (eos != strptime (fancy_time, "%Y-%m", &tv)) &&
338 (eos != strptime (fancy_time, "%Y", &tv)))
339 return GNUNET_SYSERR;
340 t = mktime (&tv);
341 atime->abs_value_us = (uint64_t) ((uint64_t) t * 1000LL * 1000LL);
342 return GNUNET_OK;
343}
344
345
347GNUNET_STRINGS_fancy_time_to_timestamp (const char *fancy_time,
348 struct GNUNET_TIME_Timestamp *atime)
349{
351
352 if (GNUNET_OK !=
354 &atime->abs_time)))
355 {
356 return ret;
357 }
359 {
360 atime->abs_time = GNUNET_TIME_UNIT_FOREVER_TS.abs_time;
361 }
362 return GNUNET_OK;
363}
364
365
366char *
367GNUNET_STRINGS_conv (const char *input,
368 size_t len,
369 const char *input_charset,
370 const char *output_charset)
371{
372 char *ret;
373 uint8_t *u8_string;
374 char *encoded_string;
375 size_t u8_string_length;
376 size_t encoded_string_length;
377
378 u8_string = u8_conv_from_encoding (input_charset,
379 iconveh_error,
380 input,
381 len,
382 NULL,
383 NULL,
384 &u8_string_length);
385 if (NULL == u8_string)
386 {
387 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "u8_conv_from_encoding");
388 goto fail;
389 }
390 if (0 == strcmp (output_charset, "UTF-8"))
391 {
392 ret = GNUNET_malloc (u8_string_length + 1);
393 GNUNET_memcpy (ret, u8_string, u8_string_length);
394 ret[u8_string_length] = '\0';
395 free (u8_string);
396 return ret;
397 }
398 encoded_string = u8_conv_to_encoding (output_charset,
399 iconveh_error,
400 u8_string,
401 u8_string_length,
402 NULL,
403 NULL,
404 &encoded_string_length);
405 free (u8_string);
406 if (NULL == encoded_string)
407 {
408 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "u8_conv_to_encoding");
409 goto fail;
410 }
411 ret = GNUNET_malloc (encoded_string_length + 1);
412 GNUNET_memcpy (ret, encoded_string, encoded_string_length);
413 ret[encoded_string_length] = '\0';
414 free (encoded_string);
415 return ret;
416fail:
418 _ ("Character sets requested were `%s'->`%s'\n"),
419 "UTF-8",
420 output_charset);
421 ret = GNUNET_malloc (len + 1);
422 GNUNET_memcpy (ret, input, len);
423 ret[len] = '\0';
424 return ret;
425}
426
427
428char *
429GNUNET_STRINGS_to_utf8 (const char *input,
430 size_t len,
431 const char *charset)
432{
433 return GNUNET_STRINGS_conv (input,
434 len,
435 charset,
436 "UTF-8");
437}
438
439
440char *
441GNUNET_STRINGS_from_utf8 (const char *input,
442 size_t len,
443 const char *charset)
444{
445 return GNUNET_STRINGS_conv (input,
446 len,
447 "UTF-8",
448 charset);
449}
450
451
452char *
453GNUNET_STRINGS_utf8_normalize (const char *input)
454{
455 uint8_t *tmp;
456 size_t len;
457 char *output;
458 tmp = u8_normalize (UNINORM_NFC,
459 (uint8_t *) input,
460 strlen ((char*) input),
461 NULL,
462 &len);
463 if (NULL == tmp)
464 return NULL;
465 output = GNUNET_malloc (len + 1);
466 GNUNET_memcpy (output, tmp, len);
467 output[len] = '\0';
468 free (tmp);
469 return output;
470}
471
472
473char *
474GNUNET_STRINGS_utf8_tolower (const char *input)
475{
476 uint8_t *tmp_in;
477 size_t len;
478 char *ret;
479
480 tmp_in = u8_tolower ((uint8_t *) input,
481 strlen ((char *) input),
482 NULL,
483 UNINORM_NFD,
484 NULL,
485 &len);
486
487 if (NULL == tmp_in)
488 return NULL;
489 ret = GNUNET_malloc (len + 1);
490 memcpy (ret,
491 tmp_in,
492 len);
493 free (tmp_in);
494 return ret;
495}
496
497
498char *
499GNUNET_STRINGS_utf8_toupper (const char *input)
500{
501 uint8_t *tmp_in;
502 size_t len;
503 char *ret;
504
505 tmp_in = u8_toupper ((uint8_t *) input,
506 strlen ((char *) input),
507 NULL,
508 UNINORM_NFD,
509 NULL,
510 &len);
511
512 if (NULL == tmp_in)
513 return NULL;
514 ret = GNUNET_malloc (len + 1);
515 memcpy (ret,
516 tmp_in,
517 len);
518 free (tmp_in);
519 return ret;
520}
521
522
523char *
524GNUNET_STRINGS_filename_expand (const char *fil)
525{
526 char *buffer;
527 size_t len;
528 char *fm;
529 const char *fil_ptr;
530
531 if (NULL == fil)
532 return NULL;
533
534 if (fil[0] == DIR_SEPARATOR)
535 /* absolute path, just copy */
536 return GNUNET_strdup (fil);
537 if (fil[0] == '~')
538 {
539 fm = getenv ("HOME");
540 if (fm == NULL)
541 {
543 _ ("Failed to expand `$HOME': environment variable `HOME' not set"));
544 return NULL;
545 }
546 fm = GNUNET_strdup (fm);
547 /* do not copy '~' */
548 fil_ptr = fil + 1;
549
550 /* skip over dir separator to be consistent */
551 if (fil_ptr[0] == DIR_SEPARATOR)
552 fil_ptr++;
553 }
554 else
555 {
556 /* relative path */
557 fil_ptr = fil;
558 len = 512;
559 fm = NULL;
560 while (1)
561 {
562 buffer = GNUNET_malloc (len);
563 if (NULL != getcwd (buffer,
564 len))
565 {
566 fm = buffer;
567 break;
568 }
569 if ( (errno == ERANGE) &&
570 (len < 1024 * 1024 * 4) )
571 {
572 len *= 2;
573 GNUNET_free (buffer);
574 continue;
575 }
576 GNUNET_free (buffer);
577 break;
578 }
579 if (NULL == fm)
580 {
582 "getcwd");
583 buffer = getenv ("PWD"); /* alternative */
584 if (buffer != NULL)
585 fm = GNUNET_strdup (buffer);
586 }
587 if (NULL == fm)
588 fm = GNUNET_strdup ("./"); /* give up */
589 }
590 GNUNET_asprintf (&buffer,
591 "%s%s%s",
592 fm,
593 (fm[strlen (fm) - 1] == DIR_SEPARATOR)
594 ? ""
596 fil_ptr);
597 GNUNET_free (fm);
598 return buffer;
599}
600
601
602const char *
604 int do_round)
605{
606 static GNUNET_THREAD_LOCAL char buf[128];
607 const char *unit = /* time unit */ "µs";
608 uint64_t dval = delta.rel_value_us;
609
611 return "forever";
612 if (0 == delta.rel_value_us)
613 return "0 ms";
614 if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000)))
615 {
616 dval = dval / 1000;
617 unit = /* time unit */ "ms";
618 if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000)))
619 {
620 dval = dval / 1000;
621 unit = /* time unit */ "s";
622 if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60)))
623 {
624 dval = dval / 60;
625 unit = /* time unit */ "m";
626 if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60)))
627 {
628 dval = dval / 60;
629 unit = /* time unit */ "h";
630 if (((GNUNET_YES == do_round) && (dval > 5 * 24)) ||
631 (0 == (dval % 24)))
632 {
633 dval = dval / 24;
634 if (1 == dval)
635 unit = /* time unit */ "day";
636 else
637 unit = /* time unit */ "days";
638 }
639 }
640 }
641 }
642 }
643 GNUNET_snprintf (buf, sizeof(buf), "%llu %s",
644 (unsigned long long) dval, unit);
645 return buf;
646}
647
648
649const char *
651{
652 struct GNUNET_TIME_Absolute av;
653
654 if (t.abs_time.abs_value_us == GNUNET_TIME_UNIT_FOREVER_TS.abs_time.
657 ;
658 av.abs_value_us = t.abs_time.abs_value_us;
660}
661
662
663const char *
665{
666 static GNUNET_THREAD_LOCAL char buf[255];
667 time_t tt;
668 struct tm *tp;
669
671 return "end of time";
672 tt = t.abs_value_us / 1000LL / 1000LL;
673 tp = localtime (&tt);
674 /* This is hacky, but i don't know a way to detect libc character encoding.
675 * Just expect utf8 from glibc these days.
676 * As for msvcrt, use the wide variant, which always returns utf16
677 * (otherwise we'd have to detect current codepage or use W32API character
678 * set conversion routines to convert to UTF8).
679 */
680 strftime (buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", tp);
681
682 return buf;
683}
684
685
686const char *
688{
689 const char *short_fn = filename;
690 const char *ss;
691
692 while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR)) && (ss[1] != '\0'))
693 short_fn = 1 + ss;
694 return short_fn;
695}
696
697
705static unsigned int
706getValue__ (unsigned char a)
707{
708 unsigned int dec;
709
710 switch (a)
711 {
712 case 'O':
713 case 'o':
714 a = '0';
715 break;
716
717 case 'i':
718 case 'I':
719 case 'l':
720 case 'L':
721 a = '1';
722 break;
723
724 /* also consider U to be V */
725 case 'u':
726 case 'U':
727 a = 'V';
728 break;
729
730 default:
731 break;
732 }
733 if ((a >= '0') && (a <= '9'))
734 return a - '0';
735 if ((a >= 'a') && (a <= 'z'))
736 a = toupper (a);
737 /* return (a - 'a' + 10); */
738 dec = 0;
739 if ((a >= 'A') && (a <= 'Z'))
740 {
741 if ('I' < a)
742 dec++;
743 if ('L' < a)
744 dec++;
745 if ('O' < a)
746 dec++;
747 if ('U' < a)
748 dec++;
749 return(a - 'A' + 10 - dec);
750 }
751 return -1;
752}
753
754
755char *
757 size_t size,
758 char *out,
759 size_t out_size)
760{
764 static const char *encTable__ = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
765 unsigned int wpos;
766 unsigned int rpos;
767 unsigned int bits;
768 unsigned int vbit;
769 const unsigned char *udata;
770
771 GNUNET_assert (size < SIZE_MAX / 8 - 4);
772 udata = data;
773 if (out_size < (size * 8 + 4) / 5)
774 {
775 GNUNET_break (0);
776 return NULL;
777 }
778 vbit = 0;
779 wpos = 0;
780 rpos = 0;
781 bits = 0;
782 while ((rpos < size) || (vbit > 0))
783 {
784 if ((rpos < size) && (vbit < 5))
785 {
786 bits = (bits << 8) | udata[rpos++]; /* eat 8 more bits */
787 vbit += 8;
788 }
789 if (vbit < 5)
790 {
791 bits <<= (5 - vbit); /* zero-padding */
792 GNUNET_assert (vbit == ((size * 8) % 5));
793 vbit = 5;
794 }
795 if (wpos >= out_size)
796 {
797 GNUNET_break (0);
798 return NULL;
799 }
800 out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
801 vbit -= 5;
802 }
803 GNUNET_assert (0 == vbit);
804 if (wpos < out_size)
805 out[wpos] = '\0';
806 return &out[wpos];
807}
808
809
810char *
811GNUNET_STRINGS_data_to_string_alloc (const void *buf, size_t size)
812{
813 char *str_buf;
814 size_t len = size * 8;
815 char *end;
816
817 if (len % 5 > 0)
818 len += 5 - len % 5;
819 len /= 5;
820 str_buf = GNUNET_malloc (len + 1);
822 size,
823 str_buf,
824 len);
825 if (NULL == end)
826 {
827 GNUNET_free (str_buf);
828 return NULL;
829 }
830 *end = '\0';
831 return str_buf;
832}
833
834
837 size_t enclen,
838 void *out,
839 size_t out_size)
840{
841 size_t rpos;
842 size_t wpos;
843 unsigned int bits;
844 unsigned int vbit;
845 int ret;
846 int shift;
847 unsigned char *uout;
848 size_t encoded_len;
849
850 if (0 == enclen)
851 {
852 if (0 == out_size)
853 return GNUNET_OK;
854 return GNUNET_SYSERR;
855 }
856 GNUNET_assert (out_size < SIZE_MAX / 8);
857 encoded_len = out_size * 8;
858 uout = out;
859 wpos = out_size;
860 rpos = enclen;
861 if ((encoded_len % 5) > 0)
862 {
863 vbit = encoded_len % 5; /* padding! */
864 shift = 5 - vbit;
865 bits = (ret = getValue__ (enc[--rpos])) >> shift;
866 }
867 else
868 {
869 vbit = 5;
870 shift = 0;
871 bits = (ret = getValue__ (enc[--rpos]));
872 }
873 if ((encoded_len + shift) / 5 != enclen)
874 return GNUNET_SYSERR;
875 if (-1 == ret)
876 return GNUNET_SYSERR;
877 while (wpos > 0)
878 {
879 if (0 == rpos)
880 {
881 GNUNET_break (0);
882 return GNUNET_SYSERR;
883 }
884 bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits;
885 if (-1 == ret)
886 return GNUNET_SYSERR;
887 vbit += 5;
888 if (vbit >= 8)
889 {
890 uout[--wpos] = (unsigned char) bits;
891 bits >>= 8;
892 vbit -= 8;
893 }
894 }
895 if ((0 != rpos) || (0 != vbit))
896 return GNUNET_SYSERR;
897 return GNUNET_OK;
898}
899
900
903 size_t enclen,
904 void **out,
905 size_t *out_size)
906{
907 size_t size;
908 void *data;
909 int res;
910
911 size = (enclen * 5) / 8;
913 {
914 GNUNET_break_op (0);
915 return GNUNET_SYSERR;
916 }
919 enclen,
920 data,
921 size);
922 if ( (0 < size) &&
923 (GNUNET_OK != res) )
924 {
925 size--;
927 enclen,
928 data,
929 size);
930 }
931 if (GNUNET_OK != res)
932 {
933 GNUNET_break_op (0);
935 return GNUNET_SYSERR;
936 }
937 *out = data;
938 *out_size = size;
939 return GNUNET_OK;
940}
941
942
944GNUNET_STRINGS_parse_uri (const char *path,
945 char **scheme_part,
946 const char **path_part)
947{
948 size_t len;
949 size_t i;
950 int end;
951 int pp_state = 0;
952 const char *post_scheme_part = NULL;
953
954 len = strlen (path);
955 for (end = 0, i = 0; ! end && i < len; i++)
956 {
957 switch (pp_state)
958 {
959 case 0:
960 if ((path[i] == ':') && (i > 0))
961 {
962 pp_state += 1;
963 continue;
964 }
965 if (! (((path[i] >= 'A') && (path[i] <= 'Z') ) ||
966 ((path[i] >= 'a') && (path[i] <= 'z') ) ||
967 ((path[i] >= '0') && (path[i] <= '9') ) || (path[i] == '+') ||
968 (path[i] == '-') || (path[i] == '.')))
969 end = 1;
970 break;
971
972 case 1:
973 case 2:
974 if (path[i] == '/')
975 {
976 pp_state += 1;
977 continue;
978 }
979 end = 1;
980 break;
981
982 case 3:
983 post_scheme_part = &path[i];
984 end = 1;
985 break;
986
987 default:
988 end = 1;
989 }
990 }
991 if (post_scheme_part == NULL)
992 return GNUNET_NO;
993 if (scheme_part)
994 {
995 *scheme_part = GNUNET_strndup (path,
996 post_scheme_part - path);
997 }
998 if (path_part)
999 *path_part = post_scheme_part;
1000 return GNUNET_YES;
1001}
1002
1003
1006 int can_be_uri,
1007 int *r_is_uri,
1008 char **r_uri_scheme)
1009{
1010 const char *post_scheme_path;
1011 int is_uri;
1012 char *uri;
1013 /* consider POSIX paths to be absolute too, even on W32,
1014 * as plibc expansion will fix them for us.
1015 */
1016 if (filename[0] == '/')
1017 return GNUNET_YES;
1018 if (can_be_uri)
1019 {
1020 is_uri = GNUNET_STRINGS_parse_uri (filename, &uri, &post_scheme_path);
1021 if (r_is_uri)
1022 *r_is_uri = is_uri;
1023 if (is_uri)
1024 {
1025 if (r_uri_scheme)
1026 *r_uri_scheme = uri;
1027 else
1028 GNUNET_free (uri);
1029
1030 return GNUNET_STRINGS_path_is_absolute (post_scheme_path,
1031 GNUNET_NO,
1032 NULL,
1033 NULL);
1034 }
1035 }
1036 else
1037 {
1038 if (r_is_uri)
1039 *r_is_uri = GNUNET_NO;
1040 }
1041
1042 return GNUNET_NO;
1043}
1044
1045
1048 enum GNUNET_STRINGS_FilenameCheck checks)
1049{
1050 struct stat st;
1051
1052 if ((NULL == filename) || (filename[0] == '\0'))
1053 return GNUNET_SYSERR;
1054 if (0 != (checks & GNUNET_STRINGS_CHECK_IS_ABSOLUTE))
1056 return GNUNET_NO;
1057 if (0 != (checks
1060 {
1061 if (0 != lstat (filename, &st))
1062 {
1063 if (0 != (checks & GNUNET_STRINGS_CHECK_EXISTS))
1064 return GNUNET_NO;
1065 else
1066 return GNUNET_SYSERR;
1067 }
1068 }
1069 if (0 != (checks & GNUNET_STRINGS_CHECK_IS_DIRECTORY))
1070 if (! S_ISDIR (st.st_mode))
1071 return GNUNET_NO;
1072 if (0 != (checks & GNUNET_STRINGS_CHECK_IS_LINK))
1073 if (! S_ISLNK (st.st_mode))
1074 return GNUNET_NO;
1075 return GNUNET_YES;
1076}
1077
1078
1080GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
1081 size_t addrlen,
1082 struct sockaddr_in6 *r_buf)
1083{
1084 if (addrlen < 6)
1085 return GNUNET_SYSERR;
1086 if (addrlen > 512)
1087 return GNUNET_SYSERR; /* sanity check to protect zbuf allocation,
1088 actual limit is not precise */
1089 {
1090 char zbuf[addrlen + 1];
1091 int ret;
1092 char *port_colon;
1093 unsigned int port;
1094 char dummy[2];
1095
1096 GNUNET_memcpy (zbuf, zt_addr, addrlen);
1097 if ('[' != zbuf[0])
1098 {
1100 _ ("IPv6 address did not start with `['\n"));
1101 return GNUNET_SYSERR;
1102 }
1103 zbuf[addrlen] = '\0';
1104 port_colon = strrchr (zbuf, ':');
1105 if (NULL == port_colon)
1106 {
1108 _ ("IPv6 address did contain ':' to separate port number\n"));
1109 return GNUNET_SYSERR;
1110 }
1111 if (']' != *(port_colon - 1))
1112 {
1113 GNUNET_log (
1115 _ (
1116 "IPv6 address did contain ']' before ':' to separate port number\n"));
1117 return GNUNET_SYSERR;
1118 }
1119 ret = sscanf (port_colon, ":%u%1s", &port, dummy);
1120 if ((1 != ret) || (port > 65535))
1121 {
1122 GNUNET_log (
1124 _ (
1125 "IPv6 address did contain a valid port number after the last ':'\n"));
1126 return GNUNET_SYSERR;
1127 }
1128 *(port_colon - 1) = '\0';
1129 memset (r_buf, 0, sizeof(struct sockaddr_in6));
1130 ret = inet_pton (AF_INET6, &zbuf[1], &r_buf->sin6_addr);
1131 if (ret <= 0)
1132 {
1134 _ ("Invalid IPv6 address `%s': %s\n"),
1135 &zbuf[1],
1136 strerror (errno));
1137 return GNUNET_SYSERR;
1138 }
1139 r_buf->sin6_port = htons (port);
1140 r_buf->sin6_family = AF_INET6;
1141#if HAVE_SOCKADDR_IN_SIN_LEN
1142 r_buf->sin6_len = (u_char) sizeof(struct sockaddr_in6);
1143#endif
1144 return GNUNET_OK;
1145 }
1146}
1147
1148
1150GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr,
1151 size_t addrlen,
1152 struct sockaddr_in *r_buf)
1153{
1154 unsigned int temps[4];
1155 unsigned int port;
1156 unsigned int cnt;
1157 char dummy[2];
1158
1159 if (addrlen < 9)
1160 return GNUNET_SYSERR;
1161 cnt = sscanf (zt_addr,
1162 "%u.%u.%u.%u:%u%1s",
1163 &temps[0],
1164 &temps[1],
1165 &temps[2],
1166 &temps[3],
1167 &port,
1168 dummy);
1169 if (5 != cnt)
1170 return GNUNET_SYSERR;
1171 for (cnt = 0; cnt < 4; cnt++)
1172 if (temps[cnt] > 0xFF)
1173 return GNUNET_SYSERR;
1174 if (port > 65535)
1175 return GNUNET_SYSERR;
1176 r_buf->sin_family = AF_INET;
1177 r_buf->sin_port = htons (port);
1178 r_buf->sin_addr.s_addr =
1179 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) + temps[3]);
1180#if HAVE_SOCKADDR_IN_SIN_LEN
1181 r_buf->sin_len = (u_char) sizeof(struct sockaddr_in);
1182#endif
1183 return GNUNET_OK;
1184}
1185
1186
1188GNUNET_STRINGS_to_address_ip (const char *addr,
1189 uint16_t addrlen,
1190 struct sockaddr_storage *r_buf)
1191{
1192 if (addr[0] == '[')
1193 return GNUNET_STRINGS_to_address_ipv6 (addr,
1194 addrlen,
1195 (struct sockaddr_in6 *) r_buf);
1196 return GNUNET_STRINGS_to_address_ipv4 (addr,
1197 addrlen,
1198 (struct sockaddr_in *) r_buf);
1199}
1200
1201
1202size_t
1203GNUNET_STRINGS_parse_socket_addr (const char *addr,
1204 uint8_t *af,
1205 struct sockaddr **sa)
1206{
1207 *af = AF_UNSPEC;
1208 if ('[' == *addr)
1209 {
1210 /* IPv6 */
1211 *sa = GNUNET_malloc (sizeof(struct sockaddr_in6));
1212 if (GNUNET_OK !=
1214 strlen (addr),
1215 (struct sockaddr_in6 *) *sa))
1216 {
1217 GNUNET_free (*sa);
1218 *sa = NULL;
1219 return 0;
1220 }
1221 *af = AF_INET6;
1222 return sizeof(struct sockaddr_in6);
1223 }
1224 else
1225 {
1226 /* IPv4 */
1227 *sa = GNUNET_malloc (sizeof(struct sockaddr_in));
1228 if (GNUNET_OK !=
1230 strlen (addr),
1231 (struct sockaddr_in *) *sa))
1232 {
1233 GNUNET_free (*sa);
1234 *sa = NULL;
1235 return 0;
1236 }
1237 *af = AF_INET;
1238 return sizeof(struct sockaddr_in);
1239 }
1240}
1241
1242
1252static enum GNUNET_GenericReturnValue
1253parse_port_policy (const char *port_policy,
1254 struct GNUNET_STRINGS_PortPolicy *pp)
1255{
1256 const char *pos;
1257 int s;
1258 int e;
1259 char eol[2];
1260
1261 pos = port_policy;
1262 if ('!' == *pos)
1263 {
1265 pos++;
1266 }
1267 if (2 == sscanf (pos, "%u-%u%1s", &s, &e, eol))
1268 {
1269 if ((0 == s) || (s > 0xFFFF) || (e < s) || (e > 0xFFFF))
1270 {
1271 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Port not in range\n"));
1272 return GNUNET_SYSERR;
1273 }
1274 pp->start_port = (uint16_t) s;
1275 pp->end_port = (uint16_t) e;
1276 return GNUNET_OK;
1277 }
1278 if (1 == sscanf (pos, "%u%1s", &s, eol))
1279 {
1280 if ((0 == s) || (s > 0xFFFF))
1281 {
1282 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Port not in range\n"));
1283 return GNUNET_SYSERR;
1284 }
1285
1286 pp->start_port = (uint16_t) s;
1287 pp->end_port = (uint16_t) s;
1288 return GNUNET_OK;
1289 }
1291 _ ("Malformed port policy `%s'\n"),
1292 port_policy);
1293 return GNUNET_SYSERR;
1294}
1295
1296
1298GNUNET_STRINGS_parse_ipv4_policy (const char *routeListX)
1299{
1300 size_t count;
1301 size_t len;
1302 size_t pos;
1303 unsigned int temps[8];
1305 char *routeList;
1306
1307 if (NULL == routeListX)
1308 return NULL;
1309 len = strlen (routeListX);
1310 if (0 == len)
1311 return NULL;
1312 routeList = GNUNET_strdup (routeListX);
1313 count = 0;
1314 for (size_t i = 0; i < len; i++)
1315 if (routeList[i] == ';')
1316 count++;
1317 GNUNET_assert (count < SIZE_MAX);
1318 result = GNUNET_new_array (count + 1,
1320 pos = 0;
1321 for (size_t i = 0; i < count; i++)
1322 {
1323 size_t colon;
1324 size_t end;
1325 char dummy;
1326
1327 for (colon = pos; ':' != routeList[colon]; colon++)
1328 if ((';' == routeList[colon]) || ('\0' == routeList[colon]))
1329 break;
1330 for (end = colon; ';' != routeList[end]; end++)
1331 if ('\0' == routeList[end])
1332 break;
1333 if ('\0' == routeList[end])
1334 break;
1335 routeList[end] = '\0';
1336 if (':' == routeList[colon])
1337 {
1338 routeList[colon] = '\0';
1339 if (GNUNET_OK != parse_port_policy (&routeList[colon + 1], &result[i].pp))
1340 break;
1341 }
1342 if (8 ==
1343 sscanf (&routeList[pos],
1344 "%u.%u.%u.%u/%u.%u.%u.%u%c",
1345 &temps[0],
1346 &temps[1],
1347 &temps[2],
1348 &temps[3],
1349 &temps[4],
1350 &temps[5],
1351 &temps[6],
1352 &temps[7],
1353 &dummy))
1354 {
1355 for (unsigned int j = 0; j < 8; j++)
1356 if (temps[j] > 0xFF)
1357 {
1359 _ ("Invalid format for IP: `%s'\n"),
1360 &routeList[pos]);
1362 GNUNET_free (routeList);
1363 return NULL;
1364 }
1365 result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1366 + (temps[2] << 8) + temps[3]);
1367 result[i].netmask.s_addr = htonl ((temps[4] << 24) + (temps[5] << 16)
1368 + (temps[6] << 8) + temps[7]);
1369 pos = end + 1;
1370 continue;
1371 }
1372
1373 /* try second notation */
1374 {
1375 unsigned int slash;
1376
1377 if (5 ==
1378 sscanf (&routeList[pos],
1379 "%u.%u.%u.%u/%u%c",
1380 &temps[0],
1381 &temps[1],
1382 &temps[2],
1383 &temps[3],
1384 &slash,
1385 &dummy))
1386 {
1387 for (unsigned int j = 0; j < 4; j++)
1388 if (temps[j] > 0xFF)
1389 {
1391 _ ("Invalid format for IP: `%s'\n"),
1392 &routeList[pos]);
1394 GNUNET_free (routeList);
1395 return NULL;
1396 }
1397 result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1398 + (temps[2] << 8) + temps[3]);
1399 if (slash <= 32)
1400 {
1401 result[i].netmask.s_addr = 0;
1402 while (slash > 0)
1403 {
1404 result[i].netmask.s_addr =
1405 (result[i].netmask.s_addr >> 1) + 0x80000000;
1406 slash--;
1407 }
1408 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
1409 pos = end + 1;
1410 continue;
1411 }
1412 else
1413 {
1415 _ (
1416 "Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
1417 slash);
1419 GNUNET_free (routeList);
1420 return NULL; /* error */
1421 }
1422 }
1423 }
1424
1425 /* try third notation */
1426 if (4 ==
1427 sscanf (&routeList[pos],
1428 "%u.%u.%u.%u%c",
1429 &temps[0],
1430 &temps[1],
1431 &temps[2],
1432 &temps[3],
1433 &dummy))
1434 {
1435 for (unsigned int j = 0; j < 4; j++)
1436 if (temps[j] > 0xFF)
1437 {
1439 _ ("Invalid format for IP: `%s'\n"),
1440 &routeList[pos]);
1442 GNUNET_free (routeList);
1443 return NULL;
1444 }
1445 result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1446 + (temps[2] << 8) + temps[3]);
1447 result[i].netmask.s_addr = htonl (0xffffffff); /* yeah, the htonl is useless */
1448 pos = end + 1;
1449 continue;
1450 }
1452 _ ("Invalid format for IP: `%s'\n"),
1453 &routeList[pos]);
1455 GNUNET_free (routeList);
1456 return NULL; /* error */
1457 }
1458 if (pos < strlen (routeList))
1459 {
1461 _ ("Invalid format: `%s'\n"),
1462 &routeListX[pos]);
1464 GNUNET_free (routeList);
1465 return NULL; /* oops */
1466 }
1467 GNUNET_free (routeList);
1468 return result; /* ok */
1469}
1470
1471
1473GNUNET_STRINGS_parse_ipv6_policy (const char *routeListX)
1474{
1475 size_t count;
1476 size_t len;
1477 size_t pos;
1478 int ret;
1479 char *routeList;
1481 unsigned int off;
1482
1483 if (NULL == routeListX)
1484 return NULL;
1485 len = strlen (routeListX);
1486 if (0 == len)
1487 return NULL;
1488 routeList = GNUNET_strdup (routeListX);
1489 count = 0;
1490 for (size_t j = 0; j < len; j++)
1491 if (';' == routeList[j])
1492 count++;
1493 if (';' != routeList[len - 1])
1494 {
1496 _ ("Invalid network notation (does not end with ';': `%s')\n"),
1497 routeList);
1498 GNUNET_free (routeList);
1499 return NULL;
1500 }
1501 GNUNET_assert (count < UINT_MAX);
1502 result = GNUNET_new_array (count + 1,
1504 pos = 0;
1505 for (size_t i = 0; i < count; i++)
1506 {
1507 size_t start;
1508 size_t slash;
1509
1510 start = pos;
1511 while (';' != routeList[pos])
1512 pos++;
1513 slash = pos;
1514 while ( (slash > start) &&
1515 (routeList[slash] != '/') )
1516 slash--;
1517 if (slash <= start)
1518 {
1519 memset (&result[i].netmask,
1520 0xFF,
1521 sizeof(struct in6_addr));
1522 slash = pos;
1523 }
1524 else
1525 {
1526 size_t colon;
1527
1528 routeList[pos] = '\0';
1529 for (colon = pos; ':' != routeList[colon]; colon--)
1530 if ('/' == routeList[colon])
1531 break;
1532 if (':' == routeList[colon])
1533 {
1534 routeList[colon] = '\0';
1535 if (GNUNET_OK !=
1536 parse_port_policy (&routeList[colon + 1],
1537 &result[i].pp))
1538 {
1540 GNUNET_free (routeList);
1541 return NULL;
1542 }
1543 }
1544 ret = inet_pton (AF_INET6,
1545 &routeList[slash + 1],
1546 &result[i].netmask);
1547 if (ret <= 0)
1548 {
1549 char dummy;
1550 unsigned int bits;
1551 int save = errno;
1552
1553 if ( (1 != sscanf (&routeList[slash + 1],
1554 "%u%c",
1555 &bits,
1556 &dummy)) ||
1557 (bits > 128))
1558 {
1559 if (0 == ret)
1560 {
1562 _ ("Wrong format `%s' for netmask\n"),
1563 &routeList[slash]);
1564 }
1565 else
1566 {
1567 errno = save;
1569 "inet_pton");
1570 }
1572 GNUNET_free (routeList);
1573 return NULL;
1574 }
1575 off = 0;
1576 while (bits > 8)
1577 {
1578 result[i].netmask.s6_addr[off++] = 0xFF;
1579 bits -= 8;
1580 }
1581 while (bits > 0)
1582 {
1583 result[i].netmask.s6_addr[off] =
1584 (result[i].netmask.s6_addr[off] >> 1) + 0x80;
1585 bits--;
1586 }
1587 }
1588 }
1589 routeList[slash] = '\0';
1590 ret = inet_pton (AF_INET6,
1591 &routeList[start],
1592 &result[i].network);
1593 if (ret <= 0)
1594 {
1595 if (0 == ret)
1597 _ ("Wrong format `%s' for network\n"),
1598 &routeList[slash + 1]);
1599 else
1601 "inet_pton");
1603 GNUNET_free (routeList);
1604 return NULL;
1605 }
1606 pos++;
1607 }
1608 GNUNET_free (routeList);
1609 return result;
1610}
1611
1612
1615#define FILLCHAR '='
1616static const char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1617 "abcdefghijklmnopqrstuvwxyz"
1618 "0123456789+/";
1619
1620
1621size_t
1622GNUNET_STRINGS_base64_encode (const void *in,
1623 size_t len,
1624 char **output)
1625{
1626 const unsigned char *data = in;
1627 size_t ret;
1628 char *opt;
1629
1630 ret = 0;
1631 GNUNET_assert (len < SIZE_MAX / 4);
1632 opt = GNUNET_malloc (2 + (len * 4 / 3) + 8);
1633 for (size_t i = 0; i < len; ++i)
1634 {
1635 char c;
1636
1637 c = (data[i] >> 2) & 0x3f;
1638 opt[ret++] = cvt[(int) c];
1639 c = (data[i] << 4) & 0x3f;
1640 if (++i < len)
1641 c |= (data[i] >> 4) & 0x0f;
1642 opt[ret++] = cvt[(int) c];
1643 if (i < len)
1644 {
1645 c = (data[i] << 2) & 0x3f;
1646 if (++i < len)
1647 c |= (data[i] >> 6) & 0x03;
1648 opt[ret++] = cvt[(int) c];
1649 }
1650 else
1651 {
1652 ++i;
1653 opt[ret++] = FILLCHAR;
1654 }
1655 if (i < len)
1656 {
1657 c = data[i] & 0x3f;
1658 opt[ret++] = cvt[(int) c];
1659 }
1660 else
1661 {
1662 opt[ret++] = FILLCHAR;
1663 }
1664 }
1665 *output = opt;
1666 return ret;
1667}
1668
1669
1670size_t
1671GNUNET_STRINGS_base64url_encode (const void *in,
1672 size_t len,
1673 char **output)
1674{
1675 char *enc;
1676 size_t pos;
1677
1679 len,
1680 output);
1681 enc = *output;
1682 /* Replace with correct characters for base64url */
1683 pos = 0;
1684 while ('\0' != enc[pos])
1685 {
1686 if ('+' == enc[pos])
1687 enc[pos] = '-';
1688 if ('/' == enc[pos])
1689 enc[pos] = '_';
1690 if ('=' == enc[pos])
1691 {
1692 enc[pos] = '\0';
1693 break;
1694 }
1695 pos++;
1696 }
1697 return strlen (enc);
1698}
1699
1700
1701#define cvtfind(a) \
1702 ((((a) >= 'A') && ((a) <= 'Z')) \
1703 ? (a) - 'A' \
1704 : (((a) >= 'a') && ((a) <= 'z')) \
1705 ? (a) - 'a' + 26 \
1706 : (((a) >= '0') && ((a) <= '9')) \
1707 ? (a) - '0' + 52 \
1708 : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1)
1709
1710
1711#define CHECK_CRLF \
1712 while ( (data[i] == '\r') || (data[i] == '\n') ) \
1713 { \
1714 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, \
1715 "ignoring CR/LF\n"); \
1716 i++; \
1717 if (i >= len) { \
1718 goto END; \
1719 } \
1720 }
1721
1722
1723size_t
1725 size_t len,
1726 void **out)
1727{
1728 unsigned char *output;
1729 size_t ret = 0;
1730
1731 GNUNET_assert (len / 3 < SIZE_MAX);
1732 output = GNUNET_malloc ((len * 3 / 4) + 8);
1734 "base64_decode decoding len=%d\n",
1735 (int) len);
1736 for (size_t i = 0; i < len; ++i)
1737 {
1738 unsigned char c;
1739 unsigned char c1;
1740
1741 CHECK_CRLF;
1742 if (FILLCHAR == data[i])
1743 break;
1744 c = (unsigned char) cvtfind (data[i]);
1745 ++i;
1746 CHECK_CRLF;
1747 c1 = (unsigned char) cvtfind (data[i]);
1748 c = (c << 2) | ((c1 >> 4) & 0x3);
1749 output[ret++] = c;
1750 if (++i < len)
1751 {
1752 CHECK_CRLF;
1753 c = data[i];
1754 if (FILLCHAR == c)
1755 break;
1756 c = (unsigned char) cvtfind (c);
1757 c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
1758 output[ret++] = c1;
1759 }
1760 if (++i < len)
1761 {
1762 CHECK_CRLF;
1763 c1 = data[i];
1764 if (FILLCHAR == c1)
1765 break;
1766
1767 c1 = (unsigned char) cvtfind (c1);
1768 c = ((c << 6) & 0xc0) | c1;
1769 output[ret++] = c;
1770 }
1771 }
1772END:
1773 *out = output;
1774 return ret;
1775}
1776
1777
1778#undef CHECK_CRLF
1779
1780
1781size_t
1783 size_t len,
1784 void **out)
1785{
1786 char *s;
1787 int padding;
1788 size_t ret;
1789
1790 /* make enough space for padding */
1791 GNUNET_assert (len < SIZE_MAX - 3);
1792 s = GNUNET_malloc (len + 3);
1793 memcpy (s,
1794 data,
1795 len);
1796 for (size_t i = 0; i < strlen (s); i++)
1797 {
1798 if (s[i] == '-')
1799 s[i] = '+';
1800 if (s[i] == '_')
1801 s[i] = '/';
1802 }
1803 padding = len % 4;
1804 switch (padding) // Pad with trailing '='s
1805 {
1806 case 0:
1807 break; // No pad chars in this case
1808 case 2:
1809 memcpy (&s[len],
1810 "==",
1811 2);
1812 len += 2;
1813 break; // Two pad chars
1814 case 3:
1815 s[len] = '=';
1816 len++;
1817 break; // One pad char
1818 default:
1819 GNUNET_assert (0);
1820 break;
1821 }
1823 len,
1824 out);
1825 GNUNET_free (s);
1826 return ret;
1827}
1828
1829
1830size_t
1831GNUNET_STRINGS_urldecode (const char *data,
1832 size_t len,
1833 char **out)
1834{
1835 const char *rpos = data;
1836 char *wpos;
1837 size_t resl = 0;
1838 *out = GNUNET_malloc (len + 1); /* output should always fit into input */
1839 wpos = *out;
1840
1841 while ( ('\0' != *rpos) &&
1842 (data + len != rpos) )
1843 {
1844 unsigned int num;
1845 switch (*rpos)
1846 {
1847 case '%':
1848 if (rpos + 3 > data + len)
1849 {
1850 GNUNET_break_op (0);
1851 GNUNET_free (*out);
1852 return 0;
1853 }
1854 if (1 != sscanf (rpos + 1,
1855 "%2x",
1856 &num))
1857 {
1858 /* Invalid URL encoding, try to continue anyway */
1859 GNUNET_break_op (0);
1860 *wpos = *rpos;
1861 wpos++;
1862 resl++;
1863 rpos++;
1864 break;
1865 }
1866 *wpos = (char) ((unsigned char) num);
1867 wpos++;
1868 resl++;
1869 rpos += 3;
1870 break;
1871 /* TODO: add bad sequence handling */
1872 /* intentional fall through! */
1873 default:
1874 *wpos = *rpos;
1875 wpos++;
1876 resl++;
1877 rpos++;
1878 }
1879 }
1880 *wpos = '\0'; /* add 0-terminator */
1881 return resl;
1882}
1883
1884
1885size_t
1886GNUNET_STRINGS_urlencode (size_t len,
1887 const char data[static len],
1888 char **out)
1889{
1890 struct GNUNET_Buffer buf = { 0 };
1891 const uint8_t *i8 = (uint8_t *) data;
1892 const uint8_t *end = (uint8_t *) (data + len);
1893
1894 while (end != i8)
1895 {
1896 if (0 == *i8)
1897 {
1898 /* invalid UTF-8 (or bad @a len): fail */
1899 GNUNET_break (0);
1900 GNUNET_buffer_clear (&buf);
1901 return 0;
1902 }
1903 if (0 == (0x80 & *i8))
1904 {
1905 /* traditional ASCII */
1906 if (isalnum (*i8) ||
1907 (*i8 == '-') ||
1908 (*i8 == '_') ||
1909 (*i8 == '.') ||
1910 (*i8 == '~') )
1911 GNUNET_buffer_write (&buf,
1912 (const char*) i8,
1913 1);
1914 else if (*i8 == ' ')
1915 GNUNET_buffer_write (&buf,
1916 "+",
1917 1);
1918 else
1920 "%%%X%X",
1921 *i8 >> 4,
1922 *i8 & 15);
1923 i8++;
1924 continue;
1925 }
1926 if (0x80 + 0x40 == ((0x80 + 0x40 + 0x20) & *i8))
1927 {
1928 /* 2-byte value, percent-encode */
1930 "%%%X%X",
1931 *i8 >> 4,
1932 *i8 & 15);
1933 i8++;
1934 if ( (end == i8) ||
1935 (0 == *i8) )
1936 {
1937 /* invalid UTF-8 (or bad @a len): fail */
1938 GNUNET_break (0);
1939 GNUNET_buffer_clear (&buf);
1940 return 0;
1941 }
1943 "%%%X%X",
1944 *i8 >> 4,
1945 *i8 & 15);
1946 i8++;
1947 continue;
1948 }
1949 if (0x80 + 0x40 + 0x20 == ((0x80 + 0x40 + 0x20 + 0x10) & *i8))
1950 {
1951 /* 3-byte value, percent-encode */
1952 for (unsigned int i = 0; i<3; i++)
1953 {
1954 if ( (end == i8) ||
1955 (0 == *i8) )
1956 {
1957 /* invalid UTF-8 (or bad @a len): fail */
1958 GNUNET_break (0);
1959 GNUNET_buffer_clear (&buf);
1960 return 0;
1961 }
1963 "%%%X%X",
1964 *i8 >> 4,
1965 *i8 & 15);
1966 i8++;
1967 }
1968 continue;
1969 }
1970 if (0x80 + 0x40 + 0x20 + 0x10 == ((0x80 + 0x40 + 0x20 + 0x10 + 0x08) & *i8))
1971 {
1972 /* 4-byte value, percent-encode */
1973 for (unsigned int i = 0; i<4; i++)
1974 {
1975 if ( (end == i8) ||
1976 (0 == *i8) )
1977 {
1978 /* invalid UTF-8 (or bad @a len): fail */
1979 GNUNET_break (0);
1980 GNUNET_buffer_clear (&buf);
1981 return 0;
1982 }
1984 "%%%X%X",
1985 *i8 >> 4,
1986 *i8 & 15);
1987 i8++;
1988 }
1989 continue;
1990 }
1991 if (0x80 + 0x40 + 0x20 + 0x10 + 0x08 == ((0x80 + 0x40 + 0x20 + 0x10 + 0x08
1992 + 0x04) & *i8))
1993 {
1994 /* 5-byte value, percent-encode (outside of UTF-8 modern standard, but so what) */
1995 for (unsigned int i = 0; i<5; i++)
1996 {
1997 if ( (end == i8) ||
1998 (0 == *i8) )
1999 {
2000 /* invalid UTF-8 (or bad @a len): fail */
2001 GNUNET_break (0);
2002 GNUNET_buffer_clear (&buf);
2003 return 0;
2004 }
2006 "%%%X%X",
2007 *i8 >> 4,
2008 *i8 & 15);
2009 i8++;
2010 }
2011 continue;
2012 }
2013 if (0x80 + 0x40 + 0x20 + 0x10 + 0x08 + 0x04 == ((0x80 + 0x40 + 0x20 + 0x10
2014 + 0x08 + 0x04 + 0x02)
2015 & *i8))
2016 {
2017 /* 6-byte value, percent-encode (outside of UTF-8 modern standard, but so what) */
2018 for (unsigned int i = 0; i<6; i++)
2019 {
2020 if ( (end == i8) ||
2021 (0 == *i8) )
2022 {
2023 /* invalid UTF-8 (or bad @a len): fail */
2024 GNUNET_break (0);
2025 GNUNET_buffer_clear (&buf);
2026 return 0;
2027 }
2029 "%%%X%X",
2030 *i8 >> 4,
2031 *i8 & 15);
2032 i8++;
2033 }
2034 continue;
2035 }
2036 /* really, really invalid UTF-8: fail */
2037 GNUNET_break (0);
2038 GNUNET_buffer_clear (&buf);
2039 return 0;
2040 }
2041 *out = GNUNET_buffer_reap_str (&buf);
2042 return strlen (*out);
2043}
2044
2045
2059char *
2061{
2062 const char *ret;
2063 const char *dot;
2064
2065 ret = strrchr (argv0, '_');
2066 if (NULL == ret)
2067 return NULL;
2068 ret++; /* skip underscore */
2069 dot = strchr (ret,
2070 '.');
2071 if (NULL != dot)
2072 return GNUNET_strndup (ret,
2073 dot - ret);
2074 return GNUNET_strdup (ret);
2075}
2076
2077
2078/* end of strings.c */
static size_t strnlen(const char *s, size_t n)
#define S_ISLNK(m)
Definition disk.c:61
char * getenv()
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static int end
Set if we are to shutdown all services (including ARM).
Definition gnunet-arm.c:33
static uint16_t port
Port number.
Definition gnunet-bcd.c:146
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
@ END
We're done processing.
static struct GNUNET_SCHEDULER_Task * tt
Task scheduled to handle timeout.
static char * data
The data to insert into the dht.
static char * filename
static OpusDecoder * dec
OPUS decoder.
static OpusEncoder * enc
OPUS encoder.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static char * name
Name (label) of the records to list.
static struct GNUNET_SCHEDULER_Task * t
Main task.
static char * res
Currently read line or NULL on EOF.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static int result
Global testing status.
static void do_round(void *cls)
Send out PUSHes and PULLs, possibly update #view, samplers.
static void save()
Write persistent statistics to disk.
#define GNUNET_log(kind,...)
char * GNUNET_buffer_reap_str(struct GNUNET_Buffer *buf)
Clear the buffer and return the string it contained.
Definition buffer.c:89
void GNUNET_buffer_write_fstr(struct GNUNET_Buffer *buf, const char *fmt,...) __attribute__((format(printf
Write a 0-terminated formatted string to a buffer, excluding the 0-terminator.
void GNUNET_buffer_write(struct GNUNET_Buffer *buf, const char *data, size_t len)
Write bytes to the buffer.
Definition buffer.c:63
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
void GNUNET_buffer_clear(struct GNUNET_Buffer *buf)
Free the backing memory of the given buffer.
Definition buffer.c:123
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_MAX_MALLOC_CHECKED
Maximum allocation with GNUNET_malloc macro.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data_alloc(const char *enc, size_t enclen, void **out, size_t *out_size)
Convert CrockfordBase32 encoding back to data.
Definition strings.c:903
size_t GNUNET_STRINGS_urlencode(size_t len, const char data[static len], char **out)
url/percent encode (RFC3986).
Definition strings.c:1887
size_t GNUNET_STRINGS_base64url_decode(const char *data, size_t len, void **out)
Decode from Base64url.
Definition strings.c:1783
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:1204
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 CrockfordBase32.
Definition strings.c:757
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:430
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition strings.c:812
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
Definition strings.c:1474
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:368
enum GNUNET_GenericReturnValue 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:1189
char * GNUNET_STRINGS_byte_size_fancy(unsigned long long size)
Convert a given filesize into a fancy human-readable format.
Definition strings.c:105
GNUNET_STRINGS_FilenameCheck
Flags for what we should check a file for.
char * GNUNET_STRINGS_utf8_toupper(const char *input)
Convert the utf-8 input string to upper case.
Definition strings.c:500
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition strings.c:525
enum GNUNET_GenericReturnValue GNUNET_STRINGS_to_address_ipv6(const char *zt_addr, size_t addrlen, struct sockaddr_in6 *r_buf)
Tries to convert zt_addr string to an IPv6 address.
Definition strings.c:1081
size_t GNUNET_STRINGS_urldecode(const char *data, size_t len, char **out)
url/percent encode (RFC3986).
Definition strings.c:1832
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition strings.c:837
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:71
enum GNUNET_GenericReturnValue 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's an URI.
Definition strings.c:1006
size_t GNUNET_STRINGS_base64url_encode(const void *in, size_t len, char **output)
Encode into Base64url.
Definition strings.c:1672
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition strings.c:1299
enum GNUNET_GenericReturnValue 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:945
enum GNUNET_GenericReturnValue 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:259
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **out)
Decode from Base64.
Definition strings.c:1725
char * GNUNET_STRINGS_utf8_tolower(const char *input)
Convert the utf-8 input string to lower case.
Definition strings.c:475
enum GNUNET_GenericReturnValue GNUNET_STRINGS_to_address_ipv4(const char *zt_addr, size_t addrlen, struct sockaddr_in *r_buf)
Tries to convert zt_addr string to an IPv4 address.
Definition strings.c:1151
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition strings.c:1623
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:442
enum GNUNET_GenericReturnValue GNUNET_STRINGS_check_filename(const char *filename, enum GNUNET_STRINGS_FilenameCheck checks)
Perform checks on filename.
Definition strings.c:1048
char * GNUNET_STRINGS_get_suffix_from_binary_name(const char *argv0)
Sometimes we use the binary name to determine which specific test to run.
Definition strings.c:2061
char * GNUNET_STRINGS_utf8_normalize(const char *input)
Normalize the utf-8 input string to NFC.
Definition strings.c:454
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition strings.c:137
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:688
enum GNUNET_GenericReturnValue 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:235
@ GNUNET_STRINGS_CHECK_IS_ABSOLUTE
Check that the path is an absolute path.
@ GNUNET_STRINGS_CHECK_IS_DIRECTORY
Check that it is a directory.
@ GNUNET_STRINGS_CHECK_EXISTS
Check that it exists.
@ GNUNET_STRINGS_CHECK_IS_LINK
Check that it is a link.
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_time_to_timestamp(const char *fancy_time, struct GNUNET_TIME_Timestamp *atime)
Convert a given fancy human-readable time to our internal representation.
Definition strings.c:348
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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:604
bool GNUNET_TIME_absolute_is_never(struct GNUNET_TIME_Absolute abs)
Test if abs is never.
Definition time.c:646
#define GNUNET_TIME_UNIT_FOREVER_TS
Constant used to specify "forever".
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition strings.c:665
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
const char * GNUNET_STRINGS_timestamp_to_string(struct GNUNET_TIME_Timestamp t)
Like asctime, except for GNUnet time.
Definition strings.c:651
enum GNUNET_GenericReturnValue 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:303
static struct PeerEntry ** table
Table with our interned peer IDs.
Definition peer.c:56
static unsigned int size
Size of the "table".
Definition peer.c:68
#define DIR_SEPARATOR
Definition platform.h:166
#define DIR_SEPARATOR_STR
Definition platform.h:167
#define _(String)
GNU gettext support macro.
Definition platform.h:179
#define SIZE_MAX
Definition platform.h:209
#define GNUNET_THREAD_LOCAL
Definition platform.h:248
static struct GNUNET_TIME_Relative delta
Definition speedup.c:36
static const char * cvt
Definition strings.c:1617
static enum GNUNET_GenericReturnValue parse_port_policy(const char *port_policy, struct GNUNET_STRINGS_PortPolicy *pp)
Parse the given port policy.
Definition strings.c:1254
static enum GNUNET_GenericReturnValue 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:180
#define FILLCHAR
******************** Base64 encoding
Definition strings.c:1616
#define CHECK_CRLF
Definition strings.c:1712
static unsigned int getValue__(unsigned char a)
Get the decoded value corresponding to a character according to Crockford Base32 encoding.
Definition strings.c:707
#define cvtfind(a)
Definition strings.c:1702
#define LOG(kind,...)
Definition strings.c:36
#define LOG_STRERROR(kind, syscall)
Definition strings.c:38
Unit conversion table entry for 'convert_with_table'.
Definition strings.c:155
const char * name
Name of the unit (or NULL for end of table).
Definition strings.c:159
unsigned long long value
Factor to apply for this unit.
Definition strings.c:164
Dynamically growing buffer.
IPV4 network in CIDR notation.
struct GNUNET_STRINGS_PortPolicy pp
Policy for port access.
struct in_addr netmask
IPv4 netmask.
network in CIDR notation for IPV6.
struct GNUNET_STRINGS_PortPolicy pp
Policy for port access.
struct in6_addr network
IPv6 address.
struct in6_addr netmask
IPv6 netmask.
uint16_t start_port
Starting port range (0 if none given).
int negate_portrange
GNUNET_YES if the port range should be negated ("!" in policy).
uint16_t end_port
End of port range (0 if none given).
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Time for timestamps used by GNUnet, in microseconds rounded to seconds.
struct GNUNET_TIME_Absolute abs_time
The actual value.

◆ FILLCHAR

#define FILLCHAR   '='

******************** Base64 encoding

Definition at line 1616 of file strings.c.

◆ cvtfind

#define cvtfind (   a)
Value:
((((a) >= 'A') && ((a) <= 'Z')) \
? (a) - 'A' \
: (((a) >= 'a') && ((a) <= 'z')) \
? (a) - 'a' + 26 \
: (((a) >= '0') && ((a) <= '9')) \
? (a) - '0' + 52 \
: ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1)

Definition at line 1702 of file strings.c.

1705 : (((a) >= 'a') && ((a) <= 'z')) \
1706 ? (a) - 'a' + 26 \
1707 : (((a) >= '0') && ((a) <= '9')) \
1708 ? (a) - '0' + 52 \
1709 : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1)

◆ CHECK_CRLF

#define CHECK_CRLF
Value:
while ( (data[i] == '\r') || (data[i] == '\n') ) \
{ \
"ignoring CR/LF\n"); \
i++; \
if (i >= len) { \
goto END; \
} \
}
@ GNUNET_ERROR_TYPE_BULK

Definition at line 1712 of file strings.c.

1714 { \
1716 "ignoring CR/LF\n"); \
1717 i++; \
1718 if (i >= len) { \
1719 goto END; \
1720 } \
1721 }

Function Documentation

◆ convert_with_table()

static enum GNUNET_GenericReturnValue convert_with_table ( const char *  input,
const struct ConversionTable table,
unsigned long long *  output 
)
static

Convert a string of the form "4 X 5 Y" into a numeric value by interpreting "X" and "Y" as units and then multiplying the numbers with the values associated with the respective unit from the conversion table.

Parameters
inputinput string to parse
tabletable with the conversion of unit names to numbers
outputwhere to store the result
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 180 of file strings.c.

183{
184 unsigned long long ret;
185 char *in;
186 const char *tok;
187 unsigned long long last;
188 unsigned int i;
189 char *sptr;
190
191 ret = 0;
192 last = 0;
193 in = GNUNET_strdup (input);
194 for (tok = strtok_r (in, " ", &sptr);
195 tok != NULL;
196 tok = strtok_r (NULL, " ", &sptr))
197 {
198 do
199 {
200 i = 0;
201 while ((table[i].name != NULL) && (0 != strcasecmp (table[i].name, tok)))
202 i++;
203 if (table[i].name != NULL)
204 {
205 last *= table[i].value;
206 break; /* next tok */
207 }
208 else
209 {
210 char *endptr;
211 ret += last;
212 errno = 0;
213 last = strtoull (tok, &endptr, 10);
214 if ((0 != errno) || (endptr == tok))
215 {
216 GNUNET_free (in);
217 return GNUNET_SYSERR; /* expected number */
218 }
219 if ('\0' == endptr[0])
220 break; /* next tok */
221 else
222 tok = endptr; /* and re-check (handles times like "10s") */
223 }
224 }
225 while (GNUNET_YES);
226 }
227 ret += last;
228 *output = ret;
229 GNUNET_free (in);
230 return GNUNET_OK;
231}

References GNUNET_free, GNUNET_OK, GNUNET_strdup, GNUNET_SYSERR, GNUNET_YES, name, ret, and table.

Referenced by GNUNET_STRINGS_fancy_size_to_bytes(), and GNUNET_STRINGS_fancy_time_to_relative().

Here is the caller graph for this function:

◆ getValue__()

static unsigned int getValue__ ( unsigned char  a)
static

Get the decoded value corresponding to a character according to Crockford Base32 encoding.

Parameters
aa character
Returns
corresponding numeric value

Definition at line 707 of file strings.c.

708{
709 unsigned int dec;
710
711 switch (a)
712 {
713 case 'O':
714 case 'o':
715 a = '0';
716 break;
717
718 case 'i':
719 case 'I':
720 case 'l':
721 case 'L':
722 a = '1';
723 break;
724
725 /* also consider U to be V */
726 case 'u':
727 case 'U':
728 a = 'V';
729 break;
730
731 default:
732 break;
733 }
734 if ((a >= '0') && (a <= '9'))
735 return a - '0';
736 if ((a >= 'a') && (a <= 'z'))
737 a = toupper (a);
738 /* return (a - 'a' + 10); */
739 dec = 0;
740 if ((a >= 'A') && (a <= 'Z'))
741 {
742 if ('I' < a)
743 dec++;
744 if ('L' < a)
745 dec++;
746 if ('O' < a)
747 dec++;
748 if ('U' < a)
749 dec++;
750 return(a - 'A' + 10 - dec);
751 }
752 return -1;
753}

References dec.

Referenced by GNUNET_STRINGS_string_to_data().

Here is the caller graph for this function:

◆ parse_port_policy()

static enum GNUNET_GenericReturnValue parse_port_policy ( const char *  port_policy,
struct GNUNET_STRINGS_PortPolicy pp 
)
static

Parse the given port policy.

The format is "[!]SPORT[-DPORT]".

Parameters
port_policystring to parse
pppolicy to fill in
Returns
GNUNET_OK on success, GNUNET_SYSERR if the port_policy is malformed

Definition at line 1254 of file strings.c.

1256{
1257 const char *pos;
1258 int s;
1259 int e;
1260 char eol[2];
1261
1262 pos = port_policy;
1263 if ('!' == *pos)
1264 {
1266 pos++;
1267 }
1268 if (2 == sscanf (pos, "%u-%u%1s", &s, &e, eol))
1269 {
1270 if ((0 == s) || (s > 0xFFFF) || (e < s) || (e > 0xFFFF))
1271 {
1272 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Port not in range\n"));
1273 return GNUNET_SYSERR;
1274 }
1275 pp->start_port = (uint16_t) s;
1276 pp->end_port = (uint16_t) e;
1277 return GNUNET_OK;
1278 }
1279 if (1 == sscanf (pos, "%u%1s", &s, eol))
1280 {
1281 if ((0 == s) || (s > 0xFFFF))
1282 {
1283 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Port not in range\n"));
1284 return GNUNET_SYSERR;
1285 }
1286
1287 pp->start_port = (uint16_t) s;
1288 pp->end_port = (uint16_t) s;
1289 return GNUNET_OK;
1290 }
1292 _ ("Malformed port policy `%s'\n"),
1293 port_policy);
1294 return GNUNET_SYSERR;
1295}

References _, GNUNET_STRINGS_PortPolicy::end_port, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, GNUNET_STRINGS_PortPolicy::negate_portrange, and GNUNET_STRINGS_PortPolicy::start_port.

Referenced by GNUNET_STRINGS_parse_ipv4_policy(), and GNUNET_STRINGS_parse_ipv6_policy().

Here is the caller graph for this function:

Variable Documentation

◆ cvt

const char* cvt
static
Initial value:
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/"

Definition at line 1617 of file strings.c.

Referenced by GNUNET_STRINGS_base64_encode().