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
57 if (NULL != buffer)
59 s,
60 slen);
61 needed += slen;
62 count--;
63 }
64 va_end (ap);
65 return needed;
66}
67
68
69unsigned int
72 unsigned int count,
73 ...)
74{
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
87 while ((needed <
size) && (buffer[needed] !=
'\0'))
88 needed++;
90 {
91 va_end (ap);
92 return 0;
93 }
95 needed++;
96 count--;
97 }
98 va_end (ap);
99 return needed;
100}
101
102
103char *
105{
106 const char *unit = "b";
108
110 {
112 unit = "KiB";
114 {
116 unit = "MiB";
118 {
120 unit = "GiB";
122 {
124 unit = "TiB";
125 }
126 }
127 }
128 }
132}
133
134
135size_t
137 const char *src,
138 size_t n)
139{
140 size_t slen;
141
144 memcpy (dst, src, slen);
145 dst[slen] = '\0';
146 return slen;
147}
148
149
154{
159
163 unsigned long long value;
164};
165
166
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
191 last = 0;
193 for (tok = strtok_r (in, " ", &sptr);
194 tok != NULL;
195 tok = strtok_r (NULL, " ", &sptr))
196 {
197 do
198 {
199 i = 0;
201 i++;
203 {
204 last *=
table[i].value;
205 break;
206 }
207 else
208 {
209 char *endptr;
211 errno = 0;
212 last = strtoull (tok, &endptr, 10);
213 if ((0 != errno) || (endptr == tok))
214 {
217 }
218 if ('\0' == endptr[0])
219 break;
220 else
221 tok = endptr;
222 }
223 }
225 }
230}
231
232
235 unsigned long long *
size)
236{
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
254}
255
256
260{
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 },
283 { "years", 31536000000000LL },
284 { "y", 31536000000000LL },
285 { "a", 31536000000000LL },
286 { NULL, 0 } };
288 unsigned long long val;
289
290 if (0 == strcasecmp ("forever", fancy_time))
291 {
294 }
298}
299
300
304{
305 struct tm tv;
307 const char *eos;
308 unsigned long long l;
310
311 if (0 == strcasecmp ("end of time",
312 fancy_time))
313 {
316 }
317 if ( (1 == sscanf (fancy_time,
318 "%llu%c",
319 &l,
321 (l > 9999) )
322 {
323
324 atime->
abs_value_us = (uint64_t) ((uint64_t) l * 1000LL * 1000LL);
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)))
341 atime->
abs_value_us = (uint64_t) ((uint64_t)
t * 1000LL * 1000LL);
343}
344
345
349{
351
355 {
357 }
359 {
361 }
363}
364
365
366char *
368 size_t len,
369 const char *input_charset,
370 const char *output_charset)
371{
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 {
388 goto fail;
389 }
390 if (0 == strcmp (output_charset, "UTF-8"))
391 {
394 ret[u8_string_length] =
'\0';
395 free (u8_string);
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 {
409 goto fail;
410 }
413 ret[encoded_string_length] =
'\0';
414 free (encoded_string);
416fail:
418 _ (
"Character sets requested were `%s'->`%s'\n"),
419 "UTF-8",
420 output_charset);
425}
426
427
428char *
430 size_t len,
431 const char *charset)
432{
434 len,
435 charset,
436 "UTF-8");
437}
438
439
440char *
442 size_t len,
443 const char *charset)
444{
446 len,
447 "UTF-8",
448 charset);
449}
450
451
452char *
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;
467 output[len] = '\0';
468 free (tmp);
469 return output;
470}
471
472
473char *
475{
476 uint8_t *tmp_in;
477 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
487 if (NULL == tmp_in)
488 return NULL;
491 tmp_in,
492 len);
493 free (tmp_in);
495}
496
497
498char *
500{
501 uint8_t *tmp_in;
502 size_t len;
504
505 tmp_in = u8_toupper ((uint8_t *) input,
506 strlen ((char *) input),
507 NULL,
508 UNINORM_NFD,
509 NULL,
510 &len);
511
512 if (NULL == tmp_in)
513 return NULL;
516 tmp_in,
517 len);
518 free (tmp_in);
520}
521
522
523char *
525{
526 char *buffer;
527 size_t len;
528 char *fm;
529 const char *fil_ptr;
530
531 if (NULL == fil)
532 return NULL;
533
535
537 if (fil[0] == '~')
538 {
540 if (fm == NULL)
541 {
543 _ (
"Failed to expand `$HOME': environment variable `HOME' not set"));
544 return NULL;
545 }
547
548 fil_ptr = fil + 1;
549
550
552 fil_ptr++;
553 }
554 else
555 {
556
557 fil_ptr = fil;
558 len = 512;
559 fm = NULL;
560 while (1)
561 {
563 if (NULL != getcwd (buffer,
564 len))
565 {
566 fm = buffer;
567 break;
568 }
569 if ( (errno == ERANGE) &&
570 (len < 1024 * 1024 * 4) )
571 {
572 len *= 2;
574 continue;
575 }
577 break;
578 }
579 if (NULL == fm)
580 {
582 "getcwd");
584 if (buffer != NULL)
586 }
587 if (NULL == fm)
589 }
591 "%s%s%s",
592 fm,
594 ? ""
596 fil_ptr);
598 return buffer;
599}
600
601
602const char *
605{
607 const char *unit = "µs";
609
611 return "forever";
613 return "0 ms";
615 {
616 dval = dval / 1000;
617 unit = "ms";
619 {
620 dval = dval / 1000;
621 unit = "s";
623 {
624 dval = dval / 60;
625 unit = "m";
627 {
628 dval = dval / 60;
629 unit = "h";
631 (0 == (dval % 24)))
632 {
633 dval = dval / 24;
634 if (1 == dval)
635 unit = "day";
636 else
637 unit = "days";
638 }
639 }
640 }
641 }
642 }
644 (unsigned long long) dval, unit);
645 return buf;
646}
647
648
649const char *
651{
653
657 ;
658 av.abs_value_us =
t.abs_time.abs_value_us;
660}
661
662
663const char *
665{
668 struct tm *tp;
669
671 return "end of time";
672 tt =
t.abs_value_us / 1000LL / 1000LL;
673 tp = localtime (&
tt);
674
675
676
677
678
679
680 strftime (buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", tp);
681
682 return buf;
683}
684
685
686const char *
688{
690 const char *ss;
691
693 short_fn = 1 + ss;
694 return short_fn;
695}
696
697
705static unsigned int
707{
709
710 switch (a)
711 {
712 case 'O':
713 case 'o':
714 a = '0';
715 break;
716
717 case 'i':
718 case 'I':
719 case 'l':
720 case 'L':
721 a = '1';
722 break;
723
724
725 case 'u':
726 case 'U':
727 a = 'V';
728 break;
729
730 default:
731 break;
732 }
733 if ((a >= '0') && (a <= '9'))
734 return a - '0';
735 if ((a >= 'a') && (a <= 'z'))
736 a = toupper (a);
737
739 if ((a >= 'A') && (a <= 'Z'))
740 {
741 if ('I' < a)
743 if ('L' < a)
745 if ('O' < a)
747 if ('U' < a)
749 return(a -
'A' + 10 -
dec);
750 }
751 return -1;
752}
753
754
755char *
758 char *out,
759 size_t out_size)
760{
764 static const char *encTable__ = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
765 unsigned int wpos;
766 unsigned int rpos;
767 unsigned int bits;
768 unsigned int vbit;
769 const unsigned char *udata;
770
773 if (out_size < (
size * 8 + 4) / 5)
774 {
776 return NULL;
777 }
778 vbit = 0;
779 wpos = 0;
780 rpos = 0;
781 bits = 0;
782 while ((rpos <
size) || (vbit > 0))
783 {
784 if ((rpos <
size) && (vbit < 5))
785 {
786 bits = (bits << 8) | udata[rpos++];
787 vbit += 8;
788 }
789 if (vbit < 5)
790 {
791 bits <<= (5 - vbit);
793 vbit = 5;
794 }
795 if (wpos >= out_size)
796 {
798 return NULL;
799 }
800 out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
801 vbit -= 5;
802 }
804 if (wpos < out_size)
805 out[wpos] = '\0';
806 return &out[wpos];
807}
808
809
810char *
812{
813 char *str_buf;
814 size_t len =
size * 8;
816
817 if (len % 5 > 0)
818 len += 5 - len % 5;
819 len /= 5;
823 str_buf,
824 len);
826 {
828 return NULL;
829 }
831 return str_buf;
832}
833
834
837 size_t enclen,
838 void *out,
839 size_t out_size)
840{
841 size_t rpos;
842 size_t wpos;
843 unsigned int bits;
844 unsigned int vbit;
846 int shift;
847 unsigned char *uout;
848 size_t encoded_len;
849
850 if (0 == enclen)
851 {
852 if (0 == out_size)
855 }
857 encoded_len = out_size * 8;
858 uout = out;
859 wpos = out_size;
860 rpos = enclen;
861 if ((encoded_len % 5) > 0)
862 {
863 vbit = encoded_len % 5;
864 shift = 5 - vbit;
866 }
867 else
868 {
869 vbit = 5;
870 shift = 0;
872 }
873 if ((encoded_len + shift) / 5 != enclen)
877 while (wpos > 0)
878 {
879 if (0 == rpos)
880 {
883 }
887 vbit += 5;
888 if (vbit >= 8)
889 {
890 uout[--wpos] = (unsigned char) bits;
891 bits >>= 8;
892 vbit -= 8;
893 }
894 }
895 if ((0 != rpos) || (0 != vbit))
898}
899
900
903 size_t enclen,
904 void **out,
905 size_t *out_size)
906{
910
911 size = (enclen * 5) / 8;
913 {
916 }
919 enclen,
924 {
927 enclen,
930 }
932 {
936 }
940}
941
942
945 char **scheme_part,
946 const char **path_part)
947{
948 size_t len;
949 size_t i;
951 int pp_state = 0;
952 const char *post_scheme_part = NULL;
953
954 len = strlen (path);
955 for (
end = 0, i = 0; !
end && i < len; i++)
956 {
957 switch (pp_state)
958 {
959 case 0:
960 if ((path[i] == ':') && (i > 0))
961 {
962 pp_state += 1;
963 continue;
964 }
965 if (! (((path[i] >= 'A') && (path[i] <= 'Z') ) ||
966 ((path[i] >= 'a') && (path[i] <= 'z') ) ||
967 ((path[i] >= '0') && (path[i] <= '9') ) || (path[i] == '+') ||
968 (path[i] == '-') || (path[i] == '.')))
970 break;
971
972 case 1:
973 case 2:
974 if (path[i] == '/')
975 {
976 pp_state += 1;
977 continue;
978 }
980 break;
981
982 case 3:
983 post_scheme_part = &path[i];
985 break;
986
987 default:
989 }
990 }
991 if (post_scheme_part == NULL)
993 if (scheme_part)
994 {
996 post_scheme_part - path);
997 }
998 if (path_part)
999 *path_part = post_scheme_part;
1001}
1002
1003
1006 int can_be_uri,
1007 int *r_is_uri,
1008 char **r_uri_scheme)
1009{
1010 const char *post_scheme_path;
1011 int is_uri;
1013
1014
1015
1018 if (can_be_uri)
1019 {
1021 if (r_is_uri)
1022 *r_is_uri = is_uri;
1023 if (is_uri)
1024 {
1025 if (r_uri_scheme)
1026 *r_uri_scheme =
uri;
1027 else
1029
1032 NULL,
1033 NULL);
1034 }
1035 }
1036 else
1037 {
1038 if (r_is_uri)
1040 }
1041
1043}
1044
1045
1049{
1051
1057 if (0 != (checks
1060 {
1062 {
1065 else
1067 }
1068 }
1070 if (! S_ISDIR (
st.st_mode))
1076}
1077
1078
1081 size_t addrlen,
1082 struct sockaddr_in6 *r_buf)
1083{
1084 if (addrlen < 6)
1086 if (addrlen > 512)
1088
1089 {
1090 char zbuf[addrlen + 1];
1092 char *port_colon;
1095
1097 if ('[' != zbuf[0])
1098 {
1100 _ (
"IPv6 address did not start with `['\n"));
1102 }
1103 zbuf[addrlen] = '\0';
1104 port_colon = strrchr (zbuf, ':');
1105 if (NULL == port_colon)
1106 {
1108 _ (
"IPv6 address did contain ':' to separate port number\n"));
1110 }
1111 if (']' != *(port_colon - 1))
1112 {
1116 "IPv6 address did contain ']' before ':' to separate port number\n"));
1118 }
1120 if ((1 !=
ret) || (
port > 65535))
1121 {
1125 "IPv6 address did contain a valid port number after the last ':'\n"));
1127 }
1128 *(port_colon - 1) = '\0';
1129 memset (r_buf, 0, sizeof(struct sockaddr_in6));
1130 ret = inet_pton (AF_INET6, &zbuf[1], &r_buf->sin6_addr);
1132 {
1134 _ (
"Invalid IPv6 address `%s': %s\n"),
1135 &zbuf[1],
1136 strerror (errno));
1138 }
1139 r_buf->sin6_port = htons (
port);
1140 r_buf->sin6_family = AF_INET6;
1141#if HAVE_SOCKADDR_IN_SIN_LEN
1142 r_buf->sin6_len = (u_char) sizeof(struct sockaddr_in6);
1143#endif
1145 }
1146}
1147
1148
1151 size_t addrlen,
1152 struct sockaddr_in *r_buf)
1153{
1154 unsigned int temps[4];
1156 unsigned int cnt;
1158
1159 if (addrlen < 9)
1161 cnt = sscanf (zt_addr,
1162 "%u.%u.%u.%u:%u%1s",
1163 &temps[0],
1164 &temps[1],
1165 &temps[2],
1166 &temps[3],
1169 if (5 != cnt)
1171 for (cnt = 0; cnt < 4; cnt++)
1172 if (temps[cnt] > 0xFF)
1176 r_buf->sin_family = AF_INET;
1177 r_buf->sin_port = htons (
port);
1178 r_buf->sin_addr.s_addr =
1179 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) + temps[3]);
1180#if HAVE_SOCKADDR_IN_SIN_LEN
1181 r_buf->sin_len = (u_char) sizeof(struct sockaddr_in);
1182#endif
1184}
1185
1186
1189 uint16_t addrlen,
1190 struct sockaddr_storage *r_buf)
1191{
1192 if (addr[0] == '[')
1194 addrlen,
1195 (struct sockaddr_in6 *) r_buf);
1197 addrlen,
1198 (struct sockaddr_in *) r_buf);
1199}
1200
1201
1202size_t
1204 uint8_t *af,
1205 struct sockaddr **sa)
1206{
1207 *af = AF_UNSPEC;
1208 if ('[' == *addr)
1209 {
1210
1214 strlen (addr),
1215 (struct sockaddr_in6 *) *sa))
1216 {
1218 *sa = NULL;
1219 return 0;
1220 }
1221 *af = AF_INET6;
1222 return sizeof(struct sockaddr_in6);
1223 }
1224 else
1225 {
1226
1230 strlen (addr),
1231 (struct sockaddr_in *) *sa))
1232 {
1234 *sa = NULL;
1235 return 0;
1236 }
1237 *af = AF_INET;
1238 return sizeof(struct sockaddr_in);
1239 }
1240}
1241
1242
1255{
1256 const char *pos;
1257 int s;
1258 int e;
1259 char eol[2];
1260
1261 pos = port_policy;
1262 if ('!' == *pos)
1263 {
1265 pos++;
1266 }
1267 if (2 == sscanf (pos, "%u-%u%1s", &s, &e, eol))
1268 {
1269 if ((0 == s) || (s > 0xFFFF) || (e < s) || (e > 0xFFFF))
1270 {
1273 }
1277 }
1278 if (1 == sscanf (pos, "%u%1s", &s, eol))
1279 {
1280 if ((0 == s) || (s > 0xFFFF))
1281 {
1284 }
1285
1289 }
1291 _ (
"Malformed port policy `%s'\n"),
1292 port_policy);
1294}
1295
1296
1299{
1300 size_t count;
1301 size_t len;
1302 size_t pos;
1303 unsigned int temps[8];
1305 char *routeList;
1306
1307 if (NULL == routeListX)
1308 return NULL;
1309 len = strlen (routeListX);
1310 if (0 == len)
1311 return NULL;
1313 count = 0;
1314 for (size_t i = 0; i < len; i++)
1315 if (routeList[i] == ';')
1316 count++;
1320 pos = 0;
1321 for (size_t i = 0; i < count; i++)
1322 {
1323 size_t colon;
1326
1327 for (colon = pos; ':' != routeList[colon]; colon++)
1328 if ((';' == routeList[colon]) || ('\0' == routeList[colon]))
1329 break;
1330 for (
end = colon;
';' != routeList[
end];
end++)
1331 if (
'\0' == routeList[
end])
1332 break;
1333 if (
'\0' == routeList[
end])
1334 break;
1335 routeList[
end] =
'\0';
1336 if (':' == routeList[colon])
1337 {
1338 routeList[colon] = '\0';
1340 break;
1341 }
1342 if (8 ==
1343 sscanf (&routeList[pos],
1344 "%u.%u.%u.%u/%u.%u.%u.%u%c",
1345 &temps[0],
1346 &temps[1],
1347 &temps[2],
1348 &temps[3],
1349 &temps[4],
1350 &temps[5],
1351 &temps[6],
1352 &temps[7],
1354 {
1355 for (unsigned int j = 0; j < 8; j++)
1356 if (temps[j] > 0xFF)
1357 {
1359 _ (
"Invalid format for IP: `%s'\n"),
1360 &routeList[pos]);
1363 return NULL;
1364 }
1365 result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1366 + (temps[2] << 8) + temps[3]);
1367 result[i].netmask.s_addr = htonl ((temps[4] << 24) + (temps[5] << 16)
1368 + (temps[6] << 8) + temps[7]);
1370 continue;
1371 }
1372
1373
1374 {
1375 unsigned int slash;
1376
1377 if (5 ==
1378 sscanf (&routeList[pos],
1379 "%u.%u.%u.%u/%u%c",
1380 &temps[0],
1381 &temps[1],
1382 &temps[2],
1383 &temps[3],
1384 &slash,
1386 {
1387 for (unsigned int j = 0; j < 4; j++)
1388 if (temps[j] > 0xFF)
1389 {
1391 _ (
"Invalid format for IP: `%s'\n"),
1392 &routeList[pos]);
1395 return NULL;
1396 }
1397 result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1398 + (temps[2] << 8) + temps[3]);
1399 if (slash <= 32)
1400 {
1401 result[i].netmask.s_addr = 0;
1402 while (slash > 0)
1403 {
1404 result[i].netmask.s_addr =
1405 (
result[i].netmask.s_addr >> 1) + 0x80000000;
1406 slash--;
1407 }
1410 continue;
1411 }
1412 else
1413 {
1416 "Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
1417 slash);
1420 return NULL;
1421 }
1422 }
1423 }
1424
1425
1426 if (4 ==
1427 sscanf (&routeList[pos],
1428 "%u.%u.%u.%u%c",
1429 &temps[0],
1430 &temps[1],
1431 &temps[2],
1432 &temps[3],
1434 {
1435 for (unsigned int j = 0; j < 4; j++)
1436 if (temps[j] > 0xFF)
1437 {
1439 _ (
"Invalid format for IP: `%s'\n"),
1440 &routeList[pos]);
1443 return NULL;
1444 }
1445 result[i].network.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16)
1446 + (temps[2] << 8) + temps[3]);
1447 result[i].netmask.s_addr = htonl (0xffffffff);
1449 continue;
1450 }
1452 _ (
"Invalid format for IP: `%s'\n"),
1453 &routeList[pos]);
1456 return NULL;
1457 }
1458 if (pos < strlen (routeList))
1459 {
1461 _ (
"Invalid format: `%s'\n"),
1462 &routeListX[pos]);
1465 return NULL;
1466 }
1469}
1470
1471
1474{
1475 size_t count;
1476 size_t len;
1477 size_t pos;
1479 char *routeList;
1481 unsigned int off;
1482
1483 if (NULL == routeListX)
1484 return NULL;
1485 len = strlen (routeListX);
1486 if (0 == len)
1487 return NULL;
1489 count = 0;
1490 for (size_t j = 0; j < len; j++)
1491 if (';' == routeList[j])
1492 count++;
1493 if (';' != routeList[len - 1])
1494 {
1496 _ (
"Invalid network notation (does not end with ';': `%s')\n"),
1497 routeList);
1499 return NULL;
1500 }
1504 pos = 0;
1505 for (size_t i = 0; i < count; i++)
1506 {
1508 size_t slash;
1509
1511 while (';' != routeList[pos])
1512 pos++;
1513 slash = pos;
1514 while ( (slash >
start) &&
1515 (routeList[slash] != '/') )
1516 slash--;
1518 {
1520 0xFF,
1521 sizeof(struct in6_addr));
1522 slash = pos;
1523 }
1524 else
1525 {
1526 size_t colon;
1527
1528 routeList[pos] = '\0';
1529 for (colon = pos; ':' != routeList[colon]; colon--)
1530 if ('/' == routeList[colon])
1531 break;
1532 if (':' == routeList[colon])
1533 {
1534 routeList[colon] = '\0';
1538 {
1541 return NULL;
1542 }
1543 }
1544 ret = inet_pton (AF_INET6,
1545 &routeList[slash + 1],
1548 {
1550 unsigned int bits;
1552
1553 if ( (1 != sscanf (&routeList[slash + 1],
1554 "%u%c",
1555 &bits,
1557 (bits > 128))
1558 {
1560 {
1562 _ (
"Wrong format `%s' for netmask\n"),
1563 &routeList[slash]);
1564 }
1565 else
1566 {
1569 "inet_pton");
1570 }
1573 return NULL;
1574 }
1575 off = 0;
1576 while (bits > 8)
1577 {
1578 result[i].netmask.s6_addr[off++] = 0xFF;
1579 bits -= 8;
1580 }
1581 while (bits > 0)
1582 {
1583 result[i].netmask.s6_addr[off] =
1584 (
result[i].netmask.s6_addr[off] >> 1) + 0x80;
1585 bits--;
1586 }
1587 }
1588 }
1589 routeList[slash] = '\0';
1590 ret = inet_pton (AF_INET6,
1594 {
1597 _ (
"Wrong format `%s' for network\n"),
1598 &routeList[slash + 1]);
1599 else
1601 "inet_pton");
1604 return NULL;
1605 }
1606 pos++;
1607 }
1610}
1611
1612
1615#define FILLCHAR '='
1616static const char *
cvt =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1617 "abcdefghijklmnopqrstuvwxyz"
1618 "0123456789+/";
1619
1620
1621size_t
1623 size_t len,
1624 char **output)
1625{
1626 const unsigned char *
data = in;
1628 char *opt;
1629
1633 for (size_t i = 0; i < len; ++i)
1634 {
1635 char c;
1636
1637 c = (
data[i] >> 2) & 0x3f;
1638 opt[
ret++] =
cvt[(int) c];
1639 c = (
data[i] << 4) & 0x3f;
1640 if (++i < len)
1641 c |= (
data[i] >> 4) & 0x0f;
1642 opt[
ret++] =
cvt[(int) c];
1643 if (i < len)
1644 {
1645 c = (
data[i] << 2) & 0x3f;
1646 if (++i < len)
1647 c |= (
data[i] >> 6) & 0x03;
1648 opt[
ret++] =
cvt[(int) c];
1649 }
1650 else
1651 {
1652 ++i;
1654 }
1655 if (i < len)
1656 {
1658 opt[
ret++] =
cvt[(int) c];
1659 }
1660 else
1661 {
1663 }
1664 }
1665 *output = opt;
1667}
1668
1669
1670size_t
1672 size_t len,
1673 char **output)
1674{
1676 size_t pos;
1677
1679 len,
1680 output);
1682
1683 pos = 0;
1684 while (
'\0' !=
enc[pos])
1685 {
1686 if (
'+' ==
enc[pos])
1688 if (
'/' ==
enc[pos])
1690 if (
'=' ==
enc[pos])
1691 {
1693 break;
1694 }
1695 pos++;
1696 }
1697 return strlen (
enc);
1698}
1699
1700
1701#define cvtfind(a) \
1702 ((((a) >= 'A') && ((a) <= 'Z')) \
1703 ? (a) - 'A' \
1704 : (((a) >= 'a') && ((a) <= 'z')) \
1705 ? (a) - 'a' + 26 \
1706 : (((a) >= '0') && ((a) <= '9')) \
1707 ? (a) - '0' + 52 \
1708 : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1)
1709
1710
1711#define CHECK_CRLF \
1712 while ( (data[i] == '\r') || (data[i] == '\n') ) \
1713 { \
1714 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, \
1715 "ignoring CR/LF\n"); \
1716 i++; \
1717 if (i >= len) { \
1718 goto END; \
1719 } \
1720 }
1721
1722
1723size_t
1725 size_t len,
1726 void **out)
1727{
1728 unsigned char *output;
1730
1734 "base64_decode decoding len=%d\n",
1735 (int) len);
1736 for (size_t i = 0; i < len; ++i)
1737 {
1738 unsigned char c;
1739 unsigned char c1;
1740
1743 break;
1745 ++i;
1748 c = (c << 2) | ((c1 >> 4) & 0x3);
1750 if (++i < len)
1751 {
1755 break;
1756 c = (
unsigned char)
cvtfind (c);
1757 c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
1759 }
1760 if (++i < len)
1761 {
1765 break;
1766
1767 c1 = (
unsigned char)
cvtfind (c1);
1768 c = ((c << 6) & 0xc0) | c1;
1770 }
1771 }
1773 *out = output;
1775}
1776
1777
1778#undef CHECK_CRLF
1779
1780
1781size_t
1783 size_t len,
1784 void **out)
1785{
1786 char *s;
1787 int padding;
1789
1790
1793 memcpy (s,
1795 len);
1796 for (size_t i = 0; i < strlen (s); i++)
1797 {
1798 if (s[i] == '-')
1799 s[i] = '+';
1800 if (s[i] == '_')
1801 s[i] = '/';
1802 }
1803 padding = len % 4;
1804 switch (padding)
1805 {
1806 case 0:
1807 break;
1808 case 2:
1809 memcpy (&s[len],
1810 "==",
1811 2);
1812 len += 2;
1813 break;
1814 case 3:
1815 s[len] = '=';
1816 len++;
1817 break;
1818 default:
1820 break;
1821 }
1823 len,
1824 out);
1827}
1828
1829
1830size_t
1832 size_t len,
1833 char **out)
1834{
1835 const char *rpos =
data;
1836 char *wpos;
1837 size_t resl = 0;
1839 wpos = *out;
1840
1841 while ( ('\0' != *rpos) &&
1842 (
data + len != rpos) )
1843 {
1844 unsigned int num;
1845 switch (*rpos)
1846 {
1847 case '%':
1848 if (rpos + 3 >
data + len)
1849 {
1852 return 0;
1853 }
1854 if (1 != sscanf (rpos + 1,
1855 "%2x",
1856 &num))
1857 {
1858
1860 *wpos = *rpos;
1861 wpos++;
1862 resl++;
1863 rpos++;
1864 break;
1865 }
1866 *wpos = (char) ((unsigned char) num);
1867 wpos++;
1868 resl++;
1869 rpos += 3;
1870 break;
1871
1872
1873 default:
1874 *wpos = *rpos;
1875 wpos++;
1876 resl++;
1877 rpos++;
1878 }
1879 }
1880 *wpos = '\0';
1881 return resl;
1882}
1883
1884
1885size_t
1887 const char data[
static len],
1888 char **out)
1889{
1891 const uint8_t *i8 = (uint8_t *)
data;
1892 const uint8_t *
end = (uint8_t *) (
data + len);
1893
1895 {
1896 if (0 == *i8)
1897 {
1898
1901 return 0;
1902 }
1903 if (0 == (0x80 & *i8))
1904 {
1905
1906 if (isalnum (*i8) ||
1907 (*i8 == '-') ||
1908 (*i8 == '_') ||
1909 (*i8 == '.') ||
1910 (*i8 == '~') )
1912 (const char*) i8,
1913 1);
1914 else if (*i8 == ' ')
1916 "+",
1917 1);
1918 else
1920 "%%%X%X",
1921 *i8 >> 4,
1922 *i8 & 15);
1923 i8++;
1924 continue;
1925 }
1926 if (0x80 + 0x40 == ((0x80 + 0x40 + 0x20) & *i8))
1927 {
1928
1930 "%%%X%X",
1931 *i8 >> 4,
1932 *i8 & 15);
1933 i8++;
1935 (0 == *i8) )
1936 {
1937
1940 return 0;
1941 }
1943 "%%%X%X",
1944 *i8 >> 4,
1945 *i8 & 15);
1946 i8++;
1947 continue;
1948 }
1949 if (0x80 + 0x40 + 0x20 == ((0x80 + 0x40 + 0x20 + 0x10) & *i8))
1950 {
1951
1952 for (unsigned int i = 0; i<3; i++)
1953 {
1955 (0 == *i8) )
1956 {
1957
1960 return 0;
1961 }
1963 "%%%X%X",
1964 *i8 >> 4,
1965 *i8 & 15);
1966 i8++;
1967 }
1968 continue;
1969 }
1970 if (0x80 + 0x40 + 0x20 + 0x10 == ((0x80 + 0x40 + 0x20 + 0x10 + 0x08) & *i8))
1971 {
1972
1973 for (unsigned int i = 0; i<4; i++)
1974 {
1976 (0 == *i8) )
1977 {
1978
1981 return 0;
1982 }
1984 "%%%X%X",
1985 *i8 >> 4,
1986 *i8 & 15);
1987 i8++;
1988 }
1989 continue;
1990 }
1991 if (0x80 + 0x40 + 0x20 + 0x10 + 0x08 == ((0x80 + 0x40 + 0x20 + 0x10 + 0x08
1992 + 0x04) & *i8))
1993 {
1994
1995 for (unsigned int i = 0; i<5; i++)
1996 {
1998 (0 == *i8) )
1999 {
2000
2003 return 0;
2004 }
2006 "%%%X%X",
2007 *i8 >> 4,
2008 *i8 & 15);
2009 i8++;
2010 }
2011 continue;
2012 }
2013 if (0x80 + 0x40 + 0x20 + 0x10 + 0x08 + 0x04 == ((0x80 + 0x40 + 0x20 + 0x10
2014 + 0x08 + 0x04 + 0x02)
2015 & *i8))
2016 {
2017
2018 for (unsigned int i = 0; i<6; i++)
2019 {
2021 (0 == *i8) )
2022 {
2023
2026 return 0;
2027 }
2029 "%%%X%X",
2030 *i8 >> 4,
2031 *i8 & 15);
2032 i8++;
2033 }
2034 continue;
2035 }
2036
2039 return 0;
2040 }
2042 return strlen (*out);
2043}
2044
2045
2059char *
2061{
2063 const char *dot;
2064
2065 ret = strrchr (argv0,
'_');
2067 return NULL;
2070 '.');
2071 if (NULL != dot)
2075}
2076
2077
2078
static size_t strnlen(const char *s, size_t n)
static int start
Set if we are to start default services (including ARM).
static int ret
Final status code.
static int end
Set if we are to shutdown all services (including ARM).
static uint16_t port
Port number.
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 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.
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.
#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.
GNUNET_GenericReturnValue
Named constants for return values.
#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.
size_t GNUNET_STRINGS_urlencode(size_t len, const char data[static len], char **out)
url/percent encode (RFC3986).
size_t GNUNET_STRINGS_base64url_decode(const char *data, size_t len, void **out)
Decode from Base64url.
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.
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_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...
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
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 ...
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.
char * GNUNET_STRINGS_byte_size_fancy(unsigned long long size)
Convert a given filesize into a fancy human-readable format.
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.
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
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.
size_t GNUNET_STRINGS_urldecode(const char *data, size_t len, char **out)
url/percent encode (RFC3986).
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.
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 ...
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.
size_t GNUNET_STRINGS_base64url_encode(const void *in, size_t len, char **output)
Encode into Base64url.
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
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_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **out)
Decode from Base64.
char * GNUNET_STRINGS_utf8_tolower(const char *input)
Convert the utf-8 input string to lower case.
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.
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
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.
enum GNUNET_GenericReturnValue GNUNET_STRINGS_check_filename(const char *filename, enum GNUNET_STRINGS_FilenameCheck checks)
Perform checks on filename.
char * GNUNET_STRINGS_get_suffix_from_binary_name(const char *argv0)
Sometimes we use the binary name to determine which specific test to run.
char * GNUNET_STRINGS_utf8_normalize(const char *input)
Normalize the utf-8 input string to NFC.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
const char * GNUNET_STRINGS_get_short_name(const char *filename)
"man basename" Returns a pointer to a part of filename (allocates nothing)!
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.
@ 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.
#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.
bool GNUNET_TIME_absolute_is_never(struct GNUNET_TIME_Absolute abs)
Test if abs is never.
#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.
#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.
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.
static struct PeerEntry ** table
Table with our interned peer IDs.
static unsigned int size
Size of the "table".
static struct GNUNET_TIME_Relative delta
static enum GNUNET_GenericReturnValue parse_port_policy(const char *port_policy, struct GNUNET_STRINGS_PortPolicy *pp)
Parse the given port policy.
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 ...
#define FILLCHAR
******************** Base64 encoding
static unsigned int getValue__(unsigned char a)
Get the decoded value corresponding to a character according to Crockford Base32 encoding.
#define LOG_STRERROR(kind, syscall)
Unit conversion table entry for 'convert_with_table'.
const char * name
Name of the unit (or NULL for end of table).
unsigned long long value
Factor to apply for this unit.
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.