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

1700 : (((a) >= 'a') && ((a) <= 'z')) \
1701 ? (a) - 'a' + 26 \
1702 : (((a) >= '0') && ((a) <= '9')) \
1703 ? (a) - '0' + 52 \
1704 : ((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 1707 of file strings.c.

1709 { \
1711 "ignoring CR/LF\n"); \
1712 i++; \
1713 if (i >= len) { \
1714 goto END; \
1715 } \
1716 }

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

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

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

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

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

Referenced by GNUNET_STRINGS_base64_encode().