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
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)
489 output[len] = '\0';
492}
493
494
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)
510
512 output[len] = '\0';
515}
516
517
518char *
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
530
532 if (fil[0] == '~')
533 {
535 if (fm == NULL)
536 {
538 _ (
"Failed to expand `$HOME': environment variable `HOME' not set"));
539 return NULL;
540 }
542
543 fil_ptr = fil + 1;
544
545
547 fil_ptr++;
548 }
549 else
550 {
551
552 fil_ptr = fil;
553 len = 512;
554 fm = NULL;
555 while (1)
556 {
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;
569 continue;
570 }
572 break;
573 }
574 if (NULL == fm)
575 {
577 "getcwd");
579 if (buffer != NULL)
581 }
582 if (NULL == fm)
584 }
586 "%s%s%s",
587 fm,
589 ? ""
591 fil_ptr);
593 return buffer;
594}
595
596
597const char *
600{
602 const char *unit = "µs";
604
606 return "forever";
608 return "0 ms";
610 {
611 dval = dval / 1000;
612 unit = "ms";
614 {
615 dval = dval / 1000;
616 unit = "s";
618 {
619 dval = dval / 60;
620 unit = "m";
622 {
623 dval = dval / 60;
624 unit = "h";
626 (0 == (dval % 24)))
627 {
628 dval = dval / 24;
629 if (1 == dval)
630 unit = "day";
631 else
632 unit = "days";
633 }
634 }
635 }
636 }
637 }
639 (unsigned long long) dval, unit);
640 return buf;
641}
642
643
644const char *
646{
648
652 ;
653 av.abs_value_us =
t.abs_time.abs_value_us;
655}
656
657
658const char *
660{
663 struct tm *tp;
664
666 return "end of time";
667 tt =
t.abs_value_us / 1000LL / 1000LL;
668 tp = localtime (&
tt);
669
670
671
672
673
674
675 strftime (buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", tp);
676
677 return buf;
678}
679
680
681const char *
683{
685 const char *ss;
686
688 short_fn = 1 + ss;
689 return short_fn;
690}
691
692
700static unsigned int
702{
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
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
734 if ((a >= 'A') && (a <= 'Z'))
735 {
736 if ('I' < a)
738 if ('L' < a)
740 if ('O' < a)
742 if ('U' < a)
744 return(a -
'A' + 10 -
dec);
745 }
746 return -1;
747}
748
749
750char *
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
768 if (out_size < (
size * 8 + 4) / 5)
769 {
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++];
782 vbit += 8;
783 }
784 if (vbit < 5)
785 {
786 bits <<= (5 - vbit);
788 vbit = 5;
789 }
790 if (wpos >= out_size)
791 {
793 return NULL;
794 }
795 out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
796 vbit -= 5;
797 }
799 if (wpos < out_size)
800 out[wpos] = '\0';
801 return &out[wpos];
802}
803
804
805char *
807{
808 char *str_buf;
809 size_t len =
size * 8;
811
812 if (len % 5 > 0)
813 len += 5 - len % 5;
814 len /= 5;
818 str_buf,
819 len);
821 {
823 return NULL;
824 }
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;
841 int shift;
842 unsigned char *uout;
843 size_t encoded_len;
844
845 if (0 == enclen)
846 {
847 if (0 == out_size)
850 }
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;
859 shift = 5 - vbit;
861 }
862 else
863 {
864 vbit = 5;
865 shift = 0;
867 }
868 if ((encoded_len + shift) / 5 != enclen)
872 while (wpos > 0)
873 {
874 if (0 == rpos)
875 {
878 }
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))
893}
894
895
898 size_t enclen,
899 void **out,
900 size_t *out_size)
901{
905
906 size = (enclen * 5) / 8;
908 {
911 }
914 enclen,
919 {
922 enclen,
925 }
927 {
931 }
935}
936
937
940 char **scheme_part,
941 const char **path_part)
942{
943 size_t len;
944 size_t i;
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] == '.')))
965 break;
966
967 case 1:
968 case 2:
969 if (path[i] == '/')
970 {
971 pp_state += 1;
972 continue;
973 }
975 break;
976
977 case 3:
978 post_scheme_part = &path[i];
980 break;
981
982 default:
984 }
985 }
986 if (post_scheme_part == NULL)
988 if (scheme_part)
989 {
991 post_scheme_part - path);
992 }
993 if (path_part)
994 *path_part = post_scheme_part;
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;
1008
1009
1010
1013 if (can_be_uri)
1014 {
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
1024
1027 NULL,
1028 NULL);
1029 }
1030 }
1031 else
1032 {
1033 if (r_is_uri)
1035 }
1036
1038}
1039
1040
1044{
1046
1052 if (0 != (checks
1055 {
1057 {
1060 else
1062 }
1063 }
1065 if (! S_ISDIR (
st.st_mode))
1071}
1072
1073
1076 size_t addrlen,
1077 struct sockaddr_in6 *r_buf)
1078{
1079 if (addrlen < 6)
1081 if (addrlen > 512)
1083
1084 {
1085 char zbuf[addrlen + 1];
1087 char *port_colon;
1090
1092 if ('[' != zbuf[0])
1093 {
1095 _ (
"IPv6 address did not start with `['\n"));
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"));
1105 }
1106 if (']' != *(port_colon - 1))
1107 {
1111 "IPv6 address did contain ']' before ':' to separate port number\n"));
1113 }
1115 if ((1 !=
ret) || (
port > 65535))
1116 {
1120 "IPv6 address did contain a valid port number after the last ':'\n"));
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);
1127 {
1129 _ (
"Invalid IPv6 address `%s': %s\n"),
1130 &zbuf[1],
1131 strerror (errno));
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
1140 }
1141}
1142
1143
1146 size_t addrlen,
1147 struct sockaddr_in *r_buf)
1148{
1149 unsigned int temps[4];
1151 unsigned int cnt;
1153
1154 if (addrlen < 9)
1156 cnt = sscanf (zt_addr,
1157 "%u.%u.%u.%u:%u%1s",
1158 &temps[0],
1159 &temps[1],
1160 &temps[2],
1161 &temps[3],
1164 if (5 != cnt)
1166 for (cnt = 0; cnt < 4; cnt++)
1167 if (temps[cnt] > 0xFF)
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
1179}
1180
1181
1184 uint16_t addrlen,
1185 struct sockaddr_storage *r_buf)
1186{
1187 if (addr[0] == '[')
1189 addrlen,
1190 (struct sockaddr_in6 *) r_buf);
1192 addrlen,
1193 (struct sockaddr_in *) r_buf);
1194}
1195
1196
1197size_t
1199 uint8_t *af,
1200 struct sockaddr **sa)
1201{
1202 *af = AF_UNSPEC;
1203 if ('[' == *addr)
1204 {
1205
1209 strlen (addr),
1210 (struct sockaddr_in6 *) *sa))
1211 {
1213 *sa = NULL;
1214 return 0;
1215 }
1216 *af = AF_INET6;
1217 return sizeof(struct sockaddr_in6);
1218 }
1219 else
1220 {
1221
1225 strlen (addr),
1226 (struct sockaddr_in *) *sa))
1227 {
1229 *sa = NULL;
1230 return 0;
1231 }
1232 *af = AF_INET;
1233 return sizeof(struct sockaddr_in);
1234 }
1235}
1236
1237
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 {
1268 }
1272 }
1273 if (1 == sscanf (pos, "%u%1s", &s, eol))
1274 {
1275 if ((0 == s) || (s > 0xFFFF))
1276 {
1279 }
1280
1284 }
1286 _ (
"Malformed port policy `%s'\n"),
1287 port_policy);
1289}
1290
1291
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;
1308 count = 0;
1309 for (size_t i = 0; i < len; i++)
1310 if (routeList[i] == ';')
1311 count++;
1315 pos = 0;
1316 for (size_t i = 0; i < count; i++)
1317 {
1318 size_t colon;
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';
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],
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]);
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]);
1365 continue;
1366 }
1367
1368
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,
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]);
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 }
1405 continue;
1406 }
1407 else
1408 {
1411 "Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
1412 slash);
1415 return NULL;
1416 }
1417 }
1418 }
1419
1420
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],
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]);
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);
1444 continue;
1445 }
1447 _ (
"Invalid format for IP: `%s'\n"),
1448 &routeList[pos]);
1451 return NULL;
1452 }
1453 if (pos < strlen (routeList))
1454 {
1456 _ (
"Invalid format: `%s'\n"),
1457 &routeListX[pos]);
1460 return NULL;
1461 }
1464}
1465
1466
1469{
1470 size_t count;
1471 size_t len;
1472 size_t pos;
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;
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);
1494 return NULL;
1495 }
1499 pos = 0;
1500 for (size_t i = 0; i < count; i++)
1501 {
1503 size_t slash;
1504
1506 while (';' != routeList[pos])
1507 pos++;
1508 slash = pos;
1509 while ( (slash >
start) &&
1510 (routeList[slash] != '/') )
1511 slash--;
1513 {
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';
1533 {
1536 return NULL;
1537 }
1538 }
1539 ret = inet_pton (AF_INET6,
1540 &routeList[slash + 1],
1543 {
1545 unsigned int bits;
1547
1548 if ( (1 != sscanf (&routeList[slash + 1],
1549 "%u%c",
1550 &bits,
1552 (bits > 128))
1553 {
1555 {
1557 _ (
"Wrong format `%s' for netmask\n"),
1558 &routeList[slash]);
1559 }
1560 else
1561 {
1564 "inet_pton");
1565 }
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,
1589 {
1592 _ (
"Wrong format `%s' for network\n"),
1593 &routeList[slash + 1]);
1594 else
1596 "inet_pton");
1599 return NULL;
1600 }
1601 pos++;
1602 }
1605}
1606
1607
1610#define FILLCHAR '='
1611static const char *
cvt =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1612 "abcdefghijklmnopqrstuvwxyz"
1613 "0123456789+/";
1614
1615
1616size_t
1618 size_t len,
1619 char **output)
1620{
1621 const unsigned char *
data = in;
1623 char *opt;
1624
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;
1649 }
1650 if (i < len)
1651 {
1653 opt[
ret++] =
cvt[(int) c];
1654 }
1655 else
1656 {
1658 }
1659 }
1660 *output = opt;
1662}
1663
1664
1665size_t
1667 size_t len,
1668 char **output)
1669{
1671 size_t pos;
1672
1674 len,
1675 output);
1677
1678 pos = 0;
1679 while (
'\0' !=
enc[pos])
1680 {
1681 if (
'+' ==
enc[pos])
1683 if (
'/' ==
enc[pos])
1685 if (
'=' ==
enc[pos])
1686 {
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;
1725
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
1738 break;
1740 ++i;
1743 c = (c << 2) | ((c1 >> 4) & 0x3);
1745 if (++i < len)
1746 {
1750 break;
1751 c = (
unsigned char)
cvtfind (c);
1752 c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
1754 }
1755 if (++i < len)
1756 {
1760 break;
1761
1762 c1 = (
unsigned char)
cvtfind (c1);
1763 c = ((c << 6) & 0xc0) | c1;
1765 }
1766 }
1768 *out = output;
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;
1784
1785
1788 memcpy (s,
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)
1800 {
1801 case 0:
1802 break;
1803 case 2:
1804 memcpy (&s[len],
1805 "==",
1806 2);
1807 len += 2;
1808 break;
1809 case 3:
1810 s[len] = '=';
1811 len++;
1812 break;
1813 default:
1815 break;
1816 }
1818 len,
1819 out);
1822}
1823
1824
1825size_t
1827 size_t len,
1828 char **out)
1829{
1830 const char *rpos =
data;
1831 char *wpos;
1832 size_t resl = 0;
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 {
1847 return 0;
1848 }
1849 if (1 != sscanf (rpos + 1,
1850 "%2x",
1851 &num))
1852 {
1853
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
1867
1868 default:
1869 *wpos = *rpos;
1870 wpos++;
1871 resl++;
1872 rpos++;
1873 }
1874 }
1875 *wpos = '\0';
1876 return resl;
1877}
1878
1879
1880size_t
1882 const char data[
static len],
1883 char **out)
1884{
1886 const uint8_t *i8 = (uint8_t *)
data;
1887 const uint8_t *
end = (uint8_t *) (
data + len);
1888
1890 {
1891 if (0 == *i8)
1892 {
1893
1896 return 0;
1897 }
1898 if (0 == (0x80 & *i8))
1899 {
1900
1901 if (isalnum (*i8) ||
1902 (*i8 == '-') ||
1903 (*i8 == '_') ||
1904 (*i8 == '.') ||
1905 (*i8 == '~') )
1907 (const char*) i8,
1908 1);
1909 else if (*i8 == ' ')
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
1925 "%%%X%X",
1926 *i8 >> 4,
1927 *i8 & 15);
1928 i8++;
1930 (0 == *i8) )
1931 {
1932
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
1947 for (unsigned int i = 0; i<3; i++)
1948 {
1950 (0 == *i8) )
1951 {
1952
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
1968 for (unsigned int i = 0; i<4; i++)
1969 {
1971 (0 == *i8) )
1972 {
1973
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
1990 for (unsigned int i = 0; i<5; i++)
1991 {
1993 (0 == *i8) )
1994 {
1995
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
2013 for (unsigned int i = 0; i<6; i++)
2014 {
2016 (0 == *i8) )
2017 {
2018
2021 return 0;
2022 }
2024 "%%%X%X",
2025 *i8 >> 4,
2026 *i8 & 15);
2027 i8++;
2028 }
2029 continue;
2030 }
2031
2034 return 0;
2035 }
2037 return strlen (*out);
2038}
2039
2040
2054char *
2056{
2058 const char *dot;
2059
2060 ret = strrchr (argv0,
'_');
2062 return NULL;
2065 '.');
2066 if (NULL != dot)
2070}
2071
2072
2073
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 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.
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_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.
enum GNUNET_GenericReturnValue GNUNET_STRINGS_utf8_toupper(const char *input, char *output)
Convert the utf-8 input string to upper case.
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.
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.
enum GNUNET_GenericReturnValue GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
Convert the utf-8 input string to lower case.
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.