GNUnet 0.27.0-17-g14611e095
 
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 = GNUNET_TIME_absolute_from_s (l);
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 if (((time_t) -1) == t)
342 {
344 "mktime");
345 return GNUNET_SYSERR;
346 }
348 return GNUNET_OK;
349}
350
351
353GNUNET_STRINGS_fancy_time_to_timestamp (const char *fancy_time,
354 struct GNUNET_TIME_Timestamp *atime)
355{
357
358 if (GNUNET_OK !=
360 &atime->abs_time)))
361 {
362 return ret;
363 }
365 {
366 atime->abs_time = GNUNET_TIME_UNIT_FOREVER_TS.abs_time;
367 }
368 return GNUNET_OK;
369}
370
371
372char *
373GNUNET_STRINGS_conv (const char *input,
374 size_t len,
375 const char *input_charset,
376 const char *output_charset)
377{
378 char *ret;
379 uint8_t *u8_string;
380 char *encoded_string;
381 size_t u8_string_length;
382 size_t encoded_string_length;
383
384 u8_string = u8_conv_from_encoding (input_charset,
385 iconveh_error,
386 input,
387 len,
388 NULL,
389 NULL,
390 &u8_string_length);
391 if (NULL == u8_string)
392 {
393 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "u8_conv_from_encoding");
394 goto fail;
395 }
396 if (0 == strcmp (output_charset, "UTF-8"))
397 {
398 ret = GNUNET_malloc (u8_string_length + 1);
399 GNUNET_memcpy (ret, u8_string, u8_string_length);
400 ret[u8_string_length] = '\0';
401 free (u8_string);
402 return ret;
403 }
404 encoded_string = u8_conv_to_encoding (output_charset,
405 iconveh_error,
406 u8_string,
407 u8_string_length,
408 NULL,
409 NULL,
410 &encoded_string_length);
411 free (u8_string);
412 if (NULL == encoded_string)
413 {
414 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "u8_conv_to_encoding");
415 goto fail;
416 }
417 ret = GNUNET_malloc (encoded_string_length + 1);
418 GNUNET_memcpy (ret, encoded_string, encoded_string_length);
419 ret[encoded_string_length] = '\0';
420 free (encoded_string);
421 return ret;
422fail:
424 _ ("Character sets requested were `%s'->`%s'\n"),
425 "UTF-8",
426 output_charset);
427 ret = GNUNET_malloc (len + 1);
428 GNUNET_memcpy (ret, input, len);
429 ret[len] = '\0';
430 return ret;
431}
432
433
434char *
435GNUNET_STRINGS_to_utf8 (const char *input,
436 size_t len,
437 const char *charset)
438{
439 return GNUNET_STRINGS_conv (input,
440 len,
441 charset,
442 "UTF-8");
443}
444
445
446char *
447GNUNET_STRINGS_from_utf8 (const char *input,
448 size_t len,
449 const char *charset)
450{
451 return GNUNET_STRINGS_conv (input,
452 len,
453 "UTF-8",
454 charset);
455}
456
457
458char *
459GNUNET_STRINGS_utf8_normalize (const char *input)
460{
461 uint8_t *tmp;
462 size_t len;
463 char *output;
464 tmp = u8_normalize (UNINORM_NFC,
465 (uint8_t *) input,
466 strlen ((char*) input),
467 NULL,
468 &len);
469 if (NULL == tmp)
470 return NULL;
471 output = GNUNET_malloc (len + 1);
472 GNUNET_memcpy (output, tmp, len);
473 output[len] = '\0';
474 free (tmp);
475 return output;
476}
477
478
479char *
480GNUNET_STRINGS_utf8_tolower (const char *input)
481{
482 uint8_t *tmp_in;
483 size_t len;
484 char *ret;
485
486 tmp_in = u8_tolower ((uint8_t *) input,
487 strlen ((char *) input),
488 NULL,
489 UNINORM_NFD,
490 NULL,
491 &len);
492
493 if (NULL == tmp_in)
494 return NULL;
495 ret = GNUNET_malloc (len + 1);
496 memcpy (ret,
497 tmp_in,
498 len);
499 free (tmp_in);
500 return ret;
501}
502
503
504char *
505GNUNET_STRINGS_utf8_toupper (const char *input)
506{
507 uint8_t *tmp_in;
508 size_t len;
509 char *ret;
510
511 tmp_in = u8_toupper ((uint8_t *) input,
512 strlen ((char *) input),
513 NULL,
514 UNINORM_NFD,
515 NULL,
516 &len);
517
518 if (NULL == tmp_in)
519 return NULL;
520 ret = GNUNET_malloc (len + 1);
521 memcpy (ret,
522 tmp_in,
523 len);
524 free (tmp_in);
525 return ret;
526}
527
528
529char *
530GNUNET_STRINGS_filename_expand (const char *fil)
531{
532 char *buffer;
533 size_t len;
534 char *fm;
535 const char *fil_ptr;
536
537 if (NULL == fil)
538 return NULL;
539
540 if (fil[0] == DIR_SEPARATOR)
541 /* absolute path, just copy */
542 return GNUNET_strdup (fil);
543 if (fil[0] == '~')
544 {
545 fm = getenv ("HOME");
546 if (fm == NULL)
547 {
549 _ ("Failed to expand `$HOME': environment variable `HOME' not set"));
550 return NULL;
551 }
552 fm = GNUNET_strdup (fm);
553 /* do not copy '~' */
554 fil_ptr = fil + 1;
555
556 /* skip over dir separator to be consistent */
557 if (fil_ptr[0] == DIR_SEPARATOR)
558 fil_ptr++;
559 }
560 else
561 {
562 /* relative path */
563 fil_ptr = fil;
564 len = 512;
565 fm = NULL;
566 while (1)
567 {
568 buffer = GNUNET_malloc (len);
569 if (NULL != getcwd (buffer,
570 len))
571 {
572 fm = buffer;
573 break;
574 }
575 if ( (errno == ERANGE) &&
576 (len < 1024 * 1024 * 4) )
577 {
578 len *= 2;
579 GNUNET_free (buffer);
580 continue;
581 }
582 GNUNET_free (buffer);
583 break;
584 }
585 if (NULL == fm)
586 {
588 "getcwd");
589 buffer = getenv ("PWD"); /* alternative */
590 if (buffer != NULL)
591 fm = GNUNET_strdup (buffer);
592 }
593 if (NULL == fm)
594 fm = GNUNET_strdup ("./"); /* give up */
595 }
596 GNUNET_asprintf (&buffer,
597 "%s%s%s",
598 fm,
599 (fm[strlen (fm) - 1] == DIR_SEPARATOR)
600 ? ""
602 fil_ptr);
603 GNUNET_free (fm);
604 return buffer;
605}
606
607
608const char *
610 int do_round)
611{
612 static GNUNET_THREAD_LOCAL char buf[128];
613 const char *unit = /* time unit */ "µs";
614 uint64_t dval = delta.rel_value_us;
615
617 return "forever";
618 if (0 == delta.rel_value_us)
619 return "0 ms";
620 if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000)))
621 {
622 dval = dval / 1000;
623 unit = /* time unit */ "ms";
624 if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000)))
625 {
626 dval = dval / 1000;
627 unit = /* time unit */ "s";
628 if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60)))
629 {
630 dval = dval / 60;
631 unit = /* time unit */ "m";
632 if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60)))
633 {
634 dval = dval / 60;
635 unit = /* time unit */ "h";
636 if (((GNUNET_YES == do_round) && (dval > 5 * 24)) ||
637 (0 == (dval % 24)))
638 {
639 dval = dval / 24;
640 if (1 == dval)
641 unit = /* time unit */ "day";
642 else
643 unit = /* time unit */ "days";
644 }
645 }
646 }
647 }
648 }
649 GNUNET_snprintf (buf, sizeof(buf), "%llu %s",
650 (unsigned long long) dval, unit);
651 return buf;
652}
653
654
655const char *
657{
658 struct GNUNET_TIME_Absolute av;
659
660 if (t.abs_time.abs_value_us == GNUNET_TIME_UNIT_FOREVER_TS.abs_time.
663 ;
664 av.abs_value_us = t.abs_time.abs_value_us;
666}
667
668
669const char *
671{
672 static GNUNET_THREAD_LOCAL char buf[255];
673 time_t tt;
674 struct tm *tp;
675
677 return "end of time";
678 tt = t.abs_value_us / 1000LL / 1000LL;
679 tp = localtime (&tt);
680 /* This is hacky, but i don't know a way to detect libc character encoding.
681 * Just expect utf8 from glibc these days.
682 * As for msvcrt, use the wide variant, which always returns utf16
683 * (otherwise we'd have to detect current codepage or use W32API character
684 * set conversion routines to convert to UTF8).
685 */
686 strftime (buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", tp);
687
688 return buf;
689}
690
691
692const char *
694{
695 const char *short_fn = filename;
696 const char *ss;
697
698 while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR)) && (ss[1] != '\0'))
699 short_fn = 1 + ss;
700 return short_fn;
701}
702
703
711static unsigned int
712getValue__ (unsigned char a)
713{
714 unsigned int dec;
715
716 switch (a)
717 {
718 case 'O':
719 case 'o':
720 a = '0';
721 break;
722
723 case 'i':
724 case 'I':
725 case 'l':
726 case 'L':
727 a = '1';
728 break;
729
730 /* also consider U to be V */
731 case 'u':
732 case 'U':
733 a = 'V';
734 break;
735
736 default:
737 break;
738 }
739 if ((a >= '0') && (a <= '9'))
740 return a - '0';
741 if ((a >= 'a') && (a <= 'z'))
742 a = toupper (a);
743 /* return (a - 'a' + 10); */
744 dec = 0;
745 if ((a >= 'A') && (a <= 'Z'))
746 {
747 if ('I' < a)
748 dec++;
749 if ('L' < a)
750 dec++;
751 if ('O' < a)
752 dec++;
753 if ('U' < a)
754 dec++;
755 return(a - 'A' + 10 - dec);
756 }
757 return -1;
758}
759
760
761char *
763 size_t size,
764 char *out,
765 size_t out_size)
766{
770 static const char *encTable__ = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
771 unsigned int wpos;
772 unsigned int rpos;
773 unsigned int bits;
774 unsigned int vbit;
775 const unsigned char *udata;
776
777 GNUNET_assert (size < SIZE_MAX / 8 - 4);
778 udata = data;
779 if (out_size < (size * 8 + 4) / 5)
780 {
781 GNUNET_break (0);
782 return NULL;
783 }
784 vbit = 0;
785 wpos = 0;
786 rpos = 0;
787 bits = 0;
788 while ((rpos < size) || (vbit > 0))
789 {
790 if ((rpos < size) && (vbit < 5))
791 {
792 bits = (bits << 8) | udata[rpos++]; /* eat 8 more bits */
793 vbit += 8;
794 }
795 if (vbit < 5)
796 {
797 bits <<= (5 - vbit); /* zero-padding */
798 GNUNET_assert (vbit == ((size * 8) % 5));
799 vbit = 5;
800 }
801 if (wpos >= out_size)
802 {
803 GNUNET_break (0);
804 return NULL;
805 }
806 out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
807 vbit -= 5;
808 }
809 GNUNET_assert (0 == vbit);
810 if (wpos < out_size)
811 out[wpos] = '\0';
812 return &out[wpos];
813}
814
815
816char *
817GNUNET_STRINGS_data_to_string_alloc (const void *buf, size_t size)
818{
819 char *str_buf;
820 size_t len = size * 8;
821 char *end;
822
823 if (len % 5 > 0)
824 len += 5 - len % 5;
825 len /= 5;
826 str_buf = GNUNET_malloc (len + 1);
828 size,
829 str_buf,
830 len);
831 if (NULL == end)
832 {
833 GNUNET_free (str_buf);
834 return NULL;
835 }
836 *end = '\0';
837 return str_buf;
838}
839
840
843 size_t enclen,
844 void *out,
845 size_t out_size)
846{
847 size_t rpos;
848 size_t wpos;
849 unsigned int bits;
850 unsigned int vbit;
851 int ret;
852 int shift;
853 unsigned char *uout;
854 size_t encoded_len;
855
856 if (0 == enclen)
857 {
858 if (0 == out_size)
859 return GNUNET_OK;
860 return GNUNET_SYSERR;
861 }
862 GNUNET_assert (out_size < SIZE_MAX / 8);
863 encoded_len = out_size * 8;
864 uout = out;
865 wpos = out_size;
866 rpos = enclen;
867 if ((encoded_len % 5) > 0)
868 {
869 vbit = encoded_len % 5; /* padding! */
870 shift = 5 - vbit;
871 bits = (ret = getValue__ (enc[--rpos])) >> shift;
872 }
873 else
874 {
875 vbit = 5;
876 shift = 0;
877 bits = (ret = getValue__ (enc[--rpos]));
878 }
879 if ((encoded_len + shift) / 5 != enclen)
880 return GNUNET_SYSERR;
881 if (-1 == ret)
882 return GNUNET_SYSERR;
883 while (wpos > 0)
884 {
885 if (0 == rpos)
886 {
887 GNUNET_break (0);
888 return GNUNET_SYSERR;
889 }
890 bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits;
891 if (-1 == ret)
892 return GNUNET_SYSERR;
893 vbit += 5;
894 if (vbit >= 8)
895 {
896 uout[--wpos] = (unsigned char) bits;
897 bits >>= 8;
898 vbit -= 8;
899 }
900 }
901 if ((0 != rpos) || (0 != vbit))
902 return GNUNET_SYSERR;
903 return GNUNET_OK;
904}
905
906
909 size_t enclen,
910 void **out,
911 size_t *out_size)
912{
913 size_t size;
914 void *data;
915 int res;
916
917 size = (enclen * 5) / 8;
919 {
920 GNUNET_break_op (0);
921 return GNUNET_SYSERR;
922 }
925 enclen,
926 data,
927 size);
928 if ( (0 < size) &&
929 (GNUNET_OK != res) )
930 {
931 size--;
933 enclen,
934 data,
935 size);
936 }
937 if (GNUNET_OK != res)
938 {
939 GNUNET_break_op (0);
941 return GNUNET_SYSERR;
942 }
943 *out = data;
944 *out_size = size;
945 return GNUNET_OK;
946}
947
948
950GNUNET_STRINGS_parse_uri (const char *path,
951 char **scheme_part,
952 const char **path_part)
953{
954 size_t len;
955 size_t i;
956 int end;
957 int pp_state = 0;
958 const char *post_scheme_part = NULL;
959
960 len = strlen (path);
961 for (end = 0, i = 0; ! end && i < len; i++)
962 {
963 switch (pp_state)
964 {
965 case 0:
966 if ((path[i] == ':') && (i > 0))
967 {
968 pp_state += 1;
969 continue;
970 }
971 if (! (((path[i] >= 'A') && (path[i] <= 'Z') ) ||
972 ((path[i] >= 'a') && (path[i] <= 'z') ) ||
973 ((path[i] >= '0') && (path[i] <= '9') ) || (path[i] == '+') ||
974 (path[i] == '-') || (path[i] == '.')))
975 end = 1;
976 break;
977
978 case 1:
979 case 2:
980 if (path[i] == '/')
981 {
982 pp_state += 1;
983 continue;
984 }
985 end = 1;
986 break;
987
988 case 3:
989 post_scheme_part = &path[i];
990 end = 1;
991 break;
992
993 default:
994 end = 1;
995 }
996 }
997 if (post_scheme_part == NULL)
998 return GNUNET_NO;
999 if (scheme_part)
1000 {
1001 *scheme_part = GNUNET_strndup (path,
1002 post_scheme_part - path);
1003 }
1004 if (path_part)
1005 *path_part = post_scheme_part;
1006 return GNUNET_YES;
1007}
1008
1009
1012 int can_be_uri,
1013 int *r_is_uri,
1014 char **r_uri_scheme)
1015{
1016 const char *post_scheme_path;
1017 int is_uri;
1018 char *uri;
1019 /* consider POSIX paths to be absolute too, even on W32,
1020 * as plibc expansion will fix them for us.
1021 */
1022 if (filename[0] == '/')
1023 return GNUNET_YES;
1024 if (can_be_uri)
1025 {
1026 is_uri = GNUNET_STRINGS_parse_uri (filename, &uri, &post_scheme_path);
1027 if (r_is_uri)
1028 *r_is_uri = is_uri;
1029 if (is_uri)
1030 {
1031 if (r_uri_scheme)
1032 *r_uri_scheme = uri;
1033 else
1034 GNUNET_free (uri);
1035
1036 return GNUNET_STRINGS_path_is_absolute (post_scheme_path,
1037 GNUNET_NO,
1038 NULL,
1039 NULL);
1040 }
1041 }
1042 else
1043 {
1044 if (r_is_uri)
1045 *r_is_uri = GNUNET_NO;
1046 }
1047
1048 return GNUNET_NO;
1049}
1050
1051
1054 enum GNUNET_STRINGS_FilenameCheck checks)
1055{
1056 struct stat st;
1057
1058 if ((NULL == filename) || (filename[0] == '\0'))
1059 return GNUNET_SYSERR;
1060 if (0 != (checks & GNUNET_STRINGS_CHECK_IS_ABSOLUTE))
1062 return GNUNET_NO;
1063 if (0 != (checks
1066 {
1067 if (0 != lstat (filename, &st))
1068 {
1069 if (0 != (checks & GNUNET_STRINGS_CHECK_EXISTS))
1070 return GNUNET_NO;
1071 else
1072 return GNUNET_SYSERR;
1073 }
1074 }
1075 if (0 != (checks & GNUNET_STRINGS_CHECK_IS_DIRECTORY))
1076 if (! S_ISDIR (st.st_mode))
1077 return GNUNET_NO;
1078 if (0 != (checks & GNUNET_STRINGS_CHECK_IS_LINK))
1079 if (! S_ISLNK (st.st_mode))
1080 return GNUNET_NO;
1081 return GNUNET_YES;
1082}
1083
1084
1086GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
1087 size_t addrlen,
1088 struct sockaddr_in6 *r_buf)
1089{
1090 if (addrlen < 6)
1091 return GNUNET_SYSERR;
1092 if (addrlen > 512)
1093 return GNUNET_SYSERR; /* sanity check to protect zbuf allocation,
1094 actual limit is not precise */
1095 {
1096 char zbuf[addrlen + 1];
1097 int ret;
1098 char *port_colon;
1099 unsigned int port;
1100 char dummy[2];
1101
1102 GNUNET_memcpy (zbuf, zt_addr, addrlen);
1103 if ('[' != zbuf[0])
1104 {
1106 _ ("IPv6 address did not start with `['\n"));
1107 return GNUNET_SYSERR;
1108 }
1109 zbuf[addrlen] = '\0';
1110 port_colon = strrchr (zbuf, ':');
1111 if (NULL == port_colon)
1112 {
1114 _ ("IPv6 address did contain ':' to separate port number\n"));
1115 return GNUNET_SYSERR;
1116 }
1117 if (']' != *(port_colon - 1))
1118 {
1119 GNUNET_log (
1121 _ (
1122 "IPv6 address did contain ']' before ':' to separate port number\n"));
1123 return GNUNET_SYSERR;
1124 }
1125 ret = sscanf (port_colon, ":%u%1s", &port, dummy);
1126 if ((1 != ret) || (port > 65535))
1127 {
1128 GNUNET_log (
1130 _ (
1131 "IPv6 address did contain a valid port number after the last ':'\n"));
1132 return GNUNET_SYSERR;
1133 }
1134 *(port_colon - 1) = '\0';
1135 memset (r_buf, 0, sizeof(struct sockaddr_in6));
1136 ret = inet_pton (AF_INET6, &zbuf[1], &r_buf->sin6_addr);
1137 if (ret <= 0)
1138 {
1140 _ ("Invalid IPv6 address `%s': %s\n"),
1141 &zbuf[1],
1142 strerror (errno));
1143 return GNUNET_SYSERR;
1144 }
1145 r_buf->sin6_port = htons (port);
1146 r_buf->sin6_family = AF_INET6;
1147#if HAVE_SOCKADDR_IN_SIN_LEN
1148 r_buf->sin6_len = (u_char) sizeof(struct sockaddr_in6);
1149#endif
1150 return GNUNET_OK;
1151 }
1152}
1153
1154
1156GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr,
1157 size_t addrlen,
1158 struct sockaddr_in *r_buf)
1159{
1160 unsigned int temps[4];
1161 unsigned int port;
1162 unsigned int cnt;
1163 char dummy[2];
1164
1165 if (addrlen < 9)
1166 return GNUNET_SYSERR;
1167 cnt = sscanf (zt_addr,
1168 "%u.%u.%u.%u:%u%1s",
1169 &temps[0],
1170 &temps[1],
1171 &temps[2],
1172 &temps[3],
1173 &port,
1174 dummy);
1175 if (5 != cnt)
1176 return GNUNET_SYSERR;
1177 for (cnt = 0; cnt < 4; cnt++)
1178 if (temps[cnt] > 0xFF)
1179 return GNUNET_SYSERR;
1180 if (port > 65535)
1181 return GNUNET_SYSERR;
1182 r_buf->sin_family = AF_INET;
1183 r_buf->sin_port = htons (port);
1184 r_buf->sin_addr.s_addr =
1185 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) + temps[3]);
1186#if HAVE_SOCKADDR_IN_SIN_LEN
1187 r_buf->sin_len = (u_char) sizeof(struct sockaddr_in);
1188#endif
1189 return GNUNET_OK;
1190}
1191
1192
1194GNUNET_STRINGS_to_address_ip (const char *addr,
1195 uint16_t addrlen,
1196 struct sockaddr_storage *r_buf)
1197{
1198 if (addr[0] == '[')
1199 return GNUNET_STRINGS_to_address_ipv6 (addr,
1200 addrlen,
1201 (struct sockaddr_in6 *) r_buf);
1202 return GNUNET_STRINGS_to_address_ipv4 (addr,
1203 addrlen,
1204 (struct sockaddr_in *) r_buf);
1205}
1206
1207
1208size_t
1209GNUNET_STRINGS_parse_socket_addr (const char *addr,
1210 uint8_t *af,
1211 struct sockaddr **sa)
1212{
1213 *af = AF_UNSPEC;
1214 if ('[' == *addr)
1215 {
1216 /* IPv6 */
1217 *sa = GNUNET_malloc (sizeof(struct sockaddr_in6));
1218 if (GNUNET_OK !=
1220 strlen (addr),
1221 (struct sockaddr_in6 *) *sa))
1222 {
1223 GNUNET_free (*sa);
1224 *sa = NULL;
1225 return 0;
1226 }
1227 *af = AF_INET6;
1228 return sizeof(struct sockaddr_in6);
1229 }
1230 else
1231 {
1232 /* IPv4 */
1233 *sa = GNUNET_malloc (sizeof(struct sockaddr_in));
1234 if (GNUNET_OK !=
1236 strlen (addr),
1237 (struct sockaddr_in *) *sa))
1238 {
1239 GNUNET_free (*sa);
1240 *sa = NULL;
1241 return 0;
1242 }
1243 *af = AF_INET;
1244 return sizeof(struct sockaddr_in);
1245 }
1246}
1247
1248
1258static enum GNUNET_GenericReturnValue
1259parse_port_policy (const char *port_policy,
1260 struct GNUNET_STRINGS_PortPolicy *pp)
1261{
1262 const char *pos;
1263 int s;
1264 int e;
1265 char eol[2];
1266
1267 pos = port_policy;
1268 if ('!' == *pos)
1269 {
1271 pos++;
1272 }
1273 if (2 == sscanf (pos, "%u-%u%1s", &s, &e, eol))
1274 {
1275 if ((0 == s) || (s > 0xFFFF) || (e < s) || (e > 0xFFFF))
1276 {
1277 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Port not in range\n"));
1278 return GNUNET_SYSERR;
1279 }
1280 pp->start_port = (uint16_t) s;
1281 pp->end_port = (uint16_t) e;
1282 return GNUNET_OK;
1283 }
1284 if (1 == sscanf (pos, "%u%1s", &s, eol))
1285 {
1286 if ((0 == s) || (s > 0xFFFF))
1287 {
1288 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Port not in range\n"));
1289 return GNUNET_SYSERR;
1290 }
1291
1292 pp->start_port = (uint16_t) s;
1293 pp->end_port = (uint16_t) s;
1294 return GNUNET_OK;
1295 }
1297 _ ("Malformed port policy `%s'\n"),
1298 port_policy);
1299 return GNUNET_SYSERR;
1300}
1301
1302
1304GNUNET_STRINGS_parse_ipv4_policy (const char *routeListX)
1305{
1306 size_t count;
1307 size_t len;
1308 size_t pos;
1309 unsigned int temps[8];
1311 char *routeList;
1312
1313 if (NULL == routeListX)
1314 return NULL;
1315 len = strlen (routeListX);
1316 if (0 == len)
1317 return NULL;
1318 routeList = GNUNET_strdup (routeListX);
1319 count = 0;
1320 for (size_t i = 0; i < len; i++)
1321 if (routeList[i] == ';')
1322 count++;
1323 GNUNET_assert (count < SIZE_MAX);
1324 result = GNUNET_new_array (count + 1,
1326 pos = 0;
1327 for (size_t i = 0; i < count; i++)
1328 {
1329 size_t colon;
1330 size_t end;
1331 char dummy;
1332
1333 for (colon = pos; ':' != routeList[colon]; colon++)
1334 if ((';' == routeList[colon]) || ('\0' == routeList[colon]))
1335 break;
1336 for (end = colon; ';' != routeList[end]; end++)
1337 if ('\0' == routeList[end])
1338 break;
1339 if ('\0' == routeList[end])
1340 break;
1341 routeList[end] = '\0';
1342 if (':' == routeList[colon])
1343 {
1344 routeList[colon] = '\0';
1345 if (GNUNET_OK != parse_port_policy (&routeList[colon + 1], &result[i].pp))
1346 break;
1347 }
1348 if (8 ==
1349 sscanf (&routeList[pos],
1350 "%u.%u.%u.%u/%u.%u.%u.%u%c",
1351 &temps[0],
1352 &temps[1],
1353 &temps[2],
1354 &temps[3],
1355 &temps[4],
1356 &temps[5],
1357 &temps[6],
1358 &temps[7],
1359 &dummy))
1360 {
1361 for (unsigned int j = 0; j < 8; j++)
1362 if (temps[j] > 0xFF)
1363 {
1365 _ ("Invalid format for IP: `%s'\n"),
1366 &routeList[pos]);
1368 GNUNET_free (routeList);
1369 return NULL;
1370 }
1371 result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1372 + (temps[2] << 8) + temps[3]);
1373 result[i].netmask.s_addr = htonl ((temps[4] << 24) + (temps[5] << 16)
1374 + (temps[6] << 8) + temps[7]);
1375 pos = end + 1;
1376 continue;
1377 }
1378
1379 /* try second notation */
1380 {
1381 unsigned int slash;
1382
1383 if (5 ==
1384 sscanf (&routeList[pos],
1385 "%u.%u.%u.%u/%u%c",
1386 &temps[0],
1387 &temps[1],
1388 &temps[2],
1389 &temps[3],
1390 &slash,
1391 &dummy))
1392 {
1393 for (unsigned int j = 0; j < 4; j++)
1394 if (temps[j] > 0xFF)
1395 {
1397 _ ("Invalid format for IP: `%s'\n"),
1398 &routeList[pos]);
1400 GNUNET_free (routeList);
1401 return NULL;
1402 }
1403 result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1404 + (temps[2] << 8) + temps[3]);
1405 if (slash <= 32)
1406 {
1407 result[i].netmask.s_addr = 0;
1408 while (slash > 0)
1409 {
1410 result[i].netmask.s_addr =
1411 (result[i].netmask.s_addr >> 1) + 0x80000000;
1412 slash--;
1413 }
1414 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
1415 pos = end + 1;
1416 continue;
1417 }
1418 else
1419 {
1421 _ (
1422 "Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
1423 slash);
1425 GNUNET_free (routeList);
1426 return NULL; /* error */
1427 }
1428 }
1429 }
1430
1431 /* try third notation */
1432 if (4 ==
1433 sscanf (&routeList[pos],
1434 "%u.%u.%u.%u%c",
1435 &temps[0],
1436 &temps[1],
1437 &temps[2],
1438 &temps[3],
1439 &dummy))
1440 {
1441 for (unsigned int j = 0; j < 4; j++)
1442 if (temps[j] > 0xFF)
1443 {
1445 _ ("Invalid format for IP: `%s'\n"),
1446 &routeList[pos]);
1448 GNUNET_free (routeList);
1449 return NULL;
1450 }
1451 result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1452 + (temps[2] << 8) + temps[3]);
1453 result[i].netmask.s_addr = htonl (0xffffffff); /* yeah, the htonl is useless */
1454 pos = end + 1;
1455 continue;
1456 }
1458 _ ("Invalid format for IP: `%s'\n"),
1459 &routeList[pos]);
1461 GNUNET_free (routeList);
1462 return NULL; /* error */
1463 }
1464 if (pos < strlen (routeList))
1465 {
1467 _ ("Invalid format: `%s'\n"),
1468 &routeListX[pos]);
1470 GNUNET_free (routeList);
1471 return NULL; /* oops */
1472 }
1473 GNUNET_free (routeList);
1474 return result; /* ok */
1475}
1476
1477
1479GNUNET_STRINGS_parse_ipv6_policy (const char *routeListX)
1480{
1481 size_t count;
1482 size_t len;
1483 size_t pos;
1484 int ret;
1485 char *routeList;
1487 unsigned int off;
1488
1489 if (NULL == routeListX)
1490 return NULL;
1491 len = strlen (routeListX);
1492 if (0 == len)
1493 return NULL;
1494 routeList = GNUNET_strdup (routeListX);
1495 count = 0;
1496 for (size_t j = 0; j < len; j++)
1497 if (';' == routeList[j])
1498 count++;
1499 if (';' != routeList[len - 1])
1500 {
1502 _ ("Invalid network notation (does not end with ';': `%s')\n"),
1503 routeList);
1504 GNUNET_free (routeList);
1505 return NULL;
1506 }
1507 GNUNET_assert (count < UINT_MAX);
1508 result = GNUNET_new_array (count + 1,
1510 pos = 0;
1511 for (size_t i = 0; i < count; i++)
1512 {
1513 size_t start;
1514 size_t slash;
1515
1516 start = pos;
1517 while (';' != routeList[pos])
1518 pos++;
1519 slash = pos;
1520 while ( (slash > start) &&
1521 (routeList[slash] != '/') )
1522 slash--;
1523 if (slash <= start)
1524 {
1525 memset (&result[i].netmask,
1526 0xFF,
1527 sizeof(struct in6_addr));
1528 slash = pos;
1529 }
1530 else
1531 {
1532 size_t colon;
1533
1534 routeList[pos] = '\0';
1535 for (colon = pos; ':' != routeList[colon]; colon--)
1536 if ('/' == routeList[colon])
1537 break;
1538 if (':' == routeList[colon])
1539 {
1540 routeList[colon] = '\0';
1541 if (GNUNET_OK !=
1542 parse_port_policy (&routeList[colon + 1],
1543 &result[i].pp))
1544 {
1546 GNUNET_free (routeList);
1547 return NULL;
1548 }
1549 }
1550 ret = inet_pton (AF_INET6,
1551 &routeList[slash + 1],
1552 &result[i].netmask);
1553 if (ret <= 0)
1554 {
1555 char dummy;
1556 unsigned int bits;
1557 int save = errno;
1558
1559 if ( (1 != sscanf (&routeList[slash + 1],
1560 "%u%c",
1561 &bits,
1562 &dummy)) ||
1563 (bits > 128))
1564 {
1565 if (0 == ret)
1566 {
1568 _ ("Wrong format `%s' for netmask\n"),
1569 &routeList[slash]);
1570 }
1571 else
1572 {
1573 errno = save;
1575 "inet_pton");
1576 }
1578 GNUNET_free (routeList);
1579 return NULL;
1580 }
1581 off = 0;
1582 while (bits > 8)
1583 {
1584 result[i].netmask.s6_addr[off++] = 0xFF;
1585 bits -= 8;
1586 }
1587 while (bits > 0)
1588 {
1589 result[i].netmask.s6_addr[off] =
1590 (result[i].netmask.s6_addr[off] >> 1) + 0x80;
1591 bits--;
1592 }
1593 }
1594 }
1595 routeList[slash] = '\0';
1596 ret = inet_pton (AF_INET6,
1597 &routeList[start],
1598 &result[i].network);
1599 if (ret <= 0)
1600 {
1601 if (0 == ret)
1603 _ ("Wrong format `%s' for network\n"),
1604 &routeList[slash + 1]);
1605 else
1607 "inet_pton");
1609 GNUNET_free (routeList);
1610 return NULL;
1611 }
1612 pos++;
1613 }
1614 GNUNET_free (routeList);
1615 return result;
1616}
1617
1618
1621#define FILLCHAR '='
1622static const char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1623 "abcdefghijklmnopqrstuvwxyz"
1624 "0123456789+/";
1625
1626
1627size_t
1628GNUNET_STRINGS_base64_encode (const void *in,
1629 size_t len,
1630 char **output)
1631{
1632 const unsigned char *data = in;
1633 size_t ret;
1634 char *opt;
1635
1636 ret = 0;
1637 GNUNET_assert (len < SIZE_MAX / 4);
1638 opt = GNUNET_malloc (2 + (len * 4 / 3) + 8);
1639 for (size_t i = 0; i < len; ++i)
1640 {
1641 char c;
1642
1643 c = (data[i] >> 2) & 0x3f;
1644 opt[ret++] = cvt[(int) c];
1645 c = (data[i] << 4) & 0x3f;
1646 if (++i < len)
1647 c |= (data[i] >> 4) & 0x0f;
1648 opt[ret++] = cvt[(int) c];
1649 if (i < len)
1650 {
1651 c = (data[i] << 2) & 0x3f;
1652 if (++i < len)
1653 c |= (data[i] >> 6) & 0x03;
1654 opt[ret++] = cvt[(int) c];
1655 }
1656 else
1657 {
1658 ++i;
1659 opt[ret++] = FILLCHAR;
1660 }
1661 if (i < len)
1662 {
1663 c = data[i] & 0x3f;
1664 opt[ret++] = cvt[(int) c];
1665 }
1666 else
1667 {
1668 opt[ret++] = FILLCHAR;
1669 }
1670 }
1671 *output = opt;
1672 return ret;
1673}
1674
1675
1676size_t
1677GNUNET_STRINGS_base64url_encode (const void *in,
1678 size_t len,
1679 char **output)
1680{
1681 char *enc;
1682 size_t pos;
1683
1685 len,
1686 output);
1687 enc = *output;
1688 /* Replace with correct characters for base64url */
1689 pos = 0;
1690 while ('\0' != enc[pos])
1691 {
1692 if ('+' == enc[pos])
1693 enc[pos] = '-';
1694 if ('/' == enc[pos])
1695 enc[pos] = '_';
1696 if ('=' == enc[pos])
1697 {
1698 enc[pos] = '\0';
1699 break;
1700 }
1701 pos++;
1702 }
1703 return strlen (enc);
1704}
1705
1706
1707#define cvtfind(a) \
1708 ((((a) >= 'A') && ((a) <= 'Z')) \
1709 ? (a) - 'A' \
1710 : (((a) >= 'a') && ((a) <= 'z')) \
1711 ? (a) - 'a' + 26 \
1712 : (((a) >= '0') && ((a) <= '9')) \
1713 ? (a) - '0' + 52 \
1714 : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1)
1715
1716
1717#define CHECK_CRLF \
1718 while ( (data[i] == '\r') || (data[i] == '\n') ) \
1719 { \
1720 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, \
1721 "ignoring CR/LF\n"); \
1722 i++; \
1723 if (i >= len) { \
1724 goto END; \
1725 } \
1726 }
1727
1728
1729size_t
1731 size_t len,
1732 void **out)
1733{
1734 unsigned char *output;
1735 size_t ret = 0;
1736
1737 GNUNET_assert (len / 3 < SIZE_MAX);
1738 output = GNUNET_malloc ((len * 3 / 4) + 8);
1740 "base64_decode decoding len=%d\n",
1741 (int) len);
1742 for (size_t i = 0; i < len; ++i)
1743 {
1744 unsigned char c;
1745 unsigned char c1;
1746
1747 CHECK_CRLF;
1748 if (FILLCHAR == data[i])
1749 break;
1750 c = (unsigned char) cvtfind (data[i]);
1751 ++i;
1752 CHECK_CRLF;
1753 c1 = (unsigned char) cvtfind (data[i]);
1754 c = (c << 2) | ((c1 >> 4) & 0x3);
1755 output[ret++] = c;
1756 if (++i < len)
1757 {
1758 CHECK_CRLF;
1759 c = data[i];
1760 if (FILLCHAR == c)
1761 break;
1762 c = (unsigned char) cvtfind (c);
1763 c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
1764 output[ret++] = c1;
1765 }
1766 if (++i < len)
1767 {
1768 CHECK_CRLF;
1769 c1 = data[i];
1770 if (FILLCHAR == c1)
1771 break;
1772
1773 c1 = (unsigned char) cvtfind (c1);
1774 c = ((c << 6) & 0xc0) | c1;
1775 output[ret++] = c;
1776 }
1777 }
1778END:
1779 *out = output;
1780 return ret;
1781}
1782
1783
1784#undef CHECK_CRLF
1785
1786
1787size_t
1789 size_t len,
1790 void **out)
1791{
1792 char *s;
1793 int padding;
1794 size_t ret;
1795
1796 /* make enough space for padding */
1797 GNUNET_assert (len < SIZE_MAX - 3);
1798 s = GNUNET_malloc (len + 3);
1799 memcpy (s,
1800 data,
1801 len);
1802 for (size_t i = 0; i < strlen (s); i++)
1803 {
1804 if (s[i] == '-')
1805 s[i] = '+';
1806 if (s[i] == '_')
1807 s[i] = '/';
1808 }
1809 padding = len % 4;
1810 switch (padding) // Pad with trailing '='s
1811 {
1812 case 0:
1813 break; // No pad chars in this case
1814 case 2:
1815 memcpy (&s[len],
1816 "==",
1817 2);
1818 len += 2;
1819 break; // Two pad chars
1820 case 3:
1821 s[len] = '=';
1822 len++;
1823 break; // One pad char
1824 default:
1825 GNUNET_assert (0);
1826 break;
1827 }
1829 len,
1830 out);
1831 GNUNET_free (s);
1832 return ret;
1833}
1834
1835
1836size_t
1837GNUNET_STRINGS_urldecode (const char *data,
1838 size_t len,
1839 char **out)
1840{
1841 const char *rpos = data;
1842 char *wpos;
1843 size_t resl = 0;
1844 *out = GNUNET_malloc (len + 1); /* output should always fit into input */
1845 wpos = *out;
1846
1847 while ( ('\0' != *rpos) &&
1848 (data + len != rpos) )
1849 {
1850 unsigned int num;
1851 switch (*rpos)
1852 {
1853 case '%':
1854 if (rpos + 3 > data + len)
1855 {
1856 GNUNET_break_op (0);
1857 GNUNET_free (*out);
1858 return 0;
1859 }
1860 if (1 != sscanf (rpos + 1,
1861 "%2x",
1862 &num))
1863 {
1864 /* Invalid URL encoding, try to continue anyway */
1865 GNUNET_break_op (0);
1866 *wpos = *rpos;
1867 wpos++;
1868 resl++;
1869 rpos++;
1870 break;
1871 }
1872 *wpos = (char) ((unsigned char) num);
1873 wpos++;
1874 resl++;
1875 rpos += 3;
1876 break;
1877 /* TODO: add bad sequence handling */
1878 /* intentional fall through! */
1879 default:
1880 *wpos = *rpos;
1881 wpos++;
1882 resl++;
1883 rpos++;
1884 }
1885 }
1886 *wpos = '\0'; /* add 0-terminator */
1887 return resl;
1888}
1889
1890
1891size_t
1892GNUNET_STRINGS_urlencode (size_t len,
1893 const char data[static len],
1894 char **out)
1895{
1896 struct GNUNET_Buffer buf = { 0 };
1897 const uint8_t *i8 = (uint8_t *) data;
1898 const uint8_t *end = (uint8_t *) (data + len);
1899
1900 while (end != i8)
1901 {
1902 if (0 == *i8)
1903 {
1904 /* invalid UTF-8 (or bad @a len): fail */
1905 GNUNET_break (0);
1906 GNUNET_buffer_clear (&buf);
1907 return 0;
1908 }
1909 if (0 == (0x80 & *i8))
1910 {
1911 /* traditional ASCII */
1912 if (isalnum (*i8) ||
1913 (*i8 == '-') ||
1914 (*i8 == '_') ||
1915 (*i8 == '.') ||
1916 (*i8 == '~') )
1917 GNUNET_buffer_write (&buf,
1918 (const char*) i8,
1919 1);
1920 else if (*i8 == ' ')
1921 GNUNET_buffer_write (&buf,
1922 "+",
1923 1);
1924 else
1926 "%%%X%X",
1927 *i8 >> 4,
1928 *i8 & 15);
1929 i8++;
1930 continue;
1931 }
1932 if (0x80 + 0x40 == ((0x80 + 0x40 + 0x20) & *i8))
1933 {
1934 /* 2-byte value, percent-encode */
1936 "%%%X%X",
1937 *i8 >> 4,
1938 *i8 & 15);
1939 i8++;
1940 if ( (end == i8) ||
1941 (0 == *i8) )
1942 {
1943 /* invalid UTF-8 (or bad @a len): fail */
1944 GNUNET_break (0);
1945 GNUNET_buffer_clear (&buf);
1946 return 0;
1947 }
1949 "%%%X%X",
1950 *i8 >> 4,
1951 *i8 & 15);
1952 i8++;
1953 continue;
1954 }
1955 if (0x80 + 0x40 + 0x20 == ((0x80 + 0x40 + 0x20 + 0x10) & *i8))
1956 {
1957 /* 3-byte value, percent-encode */
1958 for (unsigned int i = 0; i<3; i++)
1959 {
1960 if ( (end == i8) ||
1961 (0 == *i8) )
1962 {
1963 /* invalid UTF-8 (or bad @a len): fail */
1964 GNUNET_break (0);
1965 GNUNET_buffer_clear (&buf);
1966 return 0;
1967 }
1969 "%%%X%X",
1970 *i8 >> 4,
1971 *i8 & 15);
1972 i8++;
1973 }
1974 continue;
1975 }
1976 if (0x80 + 0x40 + 0x20 + 0x10 == ((0x80 + 0x40 + 0x20 + 0x10 + 0x08) & *i8))
1977 {
1978 /* 4-byte value, percent-encode */
1979 for (unsigned int i = 0; i<4; i++)
1980 {
1981 if ( (end == i8) ||
1982 (0 == *i8) )
1983 {
1984 /* invalid UTF-8 (or bad @a len): fail */
1985 GNUNET_break (0);
1986 GNUNET_buffer_clear (&buf);
1987 return 0;
1988 }
1990 "%%%X%X",
1991 *i8 >> 4,
1992 *i8 & 15);
1993 i8++;
1994 }
1995 continue;
1996 }
1997 if (0x80 + 0x40 + 0x20 + 0x10 + 0x08 == ((0x80 + 0x40 + 0x20 + 0x10 + 0x08
1998 + 0x04) & *i8))
1999 {
2000 /* 5-byte value, percent-encode (outside of UTF-8 modern standard, but so what) */
2001 for (unsigned int i = 0; i<5; i++)
2002 {
2003 if ( (end == i8) ||
2004 (0 == *i8) )
2005 {
2006 /* invalid UTF-8 (or bad @a len): fail */
2007 GNUNET_break (0);
2008 GNUNET_buffer_clear (&buf);
2009 return 0;
2010 }
2012 "%%%X%X",
2013 *i8 >> 4,
2014 *i8 & 15);
2015 i8++;
2016 }
2017 continue;
2018 }
2019 if (0x80 + 0x40 + 0x20 + 0x10 + 0x08 + 0x04 == ((0x80 + 0x40 + 0x20 + 0x10
2020 + 0x08 + 0x04 + 0x02)
2021 & *i8))
2022 {
2023 /* 6-byte value, percent-encode (outside of UTF-8 modern standard, but so what) */
2024 for (unsigned int i = 0; i<6; i++)
2025 {
2026 if ( (end == i8) ||
2027 (0 == *i8) )
2028 {
2029 /* invalid UTF-8 (or bad @a len): fail */
2030 GNUNET_break (0);
2031 GNUNET_buffer_clear (&buf);
2032 return 0;
2033 }
2035 "%%%X%X",
2036 *i8 >> 4,
2037 *i8 & 15);
2038 i8++;
2039 }
2040 continue;
2041 }
2042 /* really, really invalid UTF-8: fail */
2043 GNUNET_break (0);
2044 GNUNET_buffer_clear (&buf);
2045 return 0;
2046 }
2047 *out = GNUNET_buffer_reap_str (&buf);
2048 return strlen (*out);
2049}
2050
2051
2065char *
2067{
2068 const char *ret;
2069 const char *dot;
2070
2071 ret = strrchr (argv0, '_');
2072 if (NULL == ret)
2073 return NULL;
2074 ret++; /* skip underscore */
2075 dot = strchr (ret,
2076 '.');
2077 if (NULL != dot)
2078 return GNUNET_strndup (ret,
2079 dot - ret);
2080 return GNUNET_strdup (ret);
2081}
2082
2083
2084/* 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.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ 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:909
size_t GNUNET_STRINGS_urlencode(size_t len, const char data[static len], char **out)
url/percent encode (RFC3986).
Definition strings.c:1893
size_t GNUNET_STRINGS_base64url_decode(const char *data, size_t len, void **out)
Decode from Base64url.
Definition strings.c:1789
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:1210
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:763
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:436
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition strings.c:818
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
Definition strings.c:1480
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:374
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:1195
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:506
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition strings.c:531
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:1087
size_t GNUNET_STRINGS_urldecode(const char *data, size_t len, char **out)
url/percent encode (RFC3986).
Definition strings.c:1838
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:843
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:1012
size_t GNUNET_STRINGS_base64url_encode(const void *in, size_t len, char **output)
Encode into Base64url.
Definition strings.c:1678
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition strings.c:1305
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:951
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:1731
char * GNUNET_STRINGS_utf8_tolower(const char *input)
Convert the utf-8 input string to lower case.
Definition strings.c:481
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:1157
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition strings.c:1629
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:448
enum GNUNET_GenericReturnValue GNUNET_STRINGS_check_filename(const char *filename, enum GNUNET_STRINGS_FilenameCheck checks)
Perform checks on filename.
Definition strings.c:1054
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:2067
char * GNUNET_STRINGS_utf8_normalize(const char *input)
Normalize the utf-8 input string to NFC.
Definition strings.c:460
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:694
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:354
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_from_s(uint64_t s_after_epoch)
Convert seconds after the UNIX epoch to absolute time.
Definition time.c:701
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:610
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:671
#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:657
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:1623
static enum GNUNET_GenericReturnValue parse_port_policy(const char *port_policy, struct GNUNET_STRINGS_PortPolicy *pp)
Parse the given port policy.
Definition strings.c:1260
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:1622
#define CHECK_CRLF
Definition strings.c:1718
static unsigned int getValue__(unsigned char a)
Get the decoded value corresponding to a character according to Crockford Base32 encoding.
Definition strings.c:713
#define cvtfind(a)
Definition strings.c:1708
#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 1622 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 1708 of file strings.c.

1711 : (((a) >= 'a') && ((a) <= 'z')) \
1712 ? (a) - 'a' + 26 \
1713 : (((a) >= '0') && ((a) <= '9')) \
1714 ? (a) - '0' + 52 \
1715 : ((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 1718 of file strings.c.

1720 { \
1722 "ignoring CR/LF\n"); \
1723 i++; \
1724 if (i >= len) { \
1725 goto END; \
1726 } \
1727 }

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 713 of file strings.c.

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

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 1260 of file strings.c.

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

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 1623 of file strings.c.

Referenced by GNUNET_STRINGS_base64_encode().