38{
43
48
53
58
63};
64
65
70{
75
80
85
93
98
103
108
113};
114
116{
121
126
128
130
136
141};
142
143
148{
153
158
163
168
173
178
185
190
195
202};
203
204
210{
212
214};
215
216
217void
220{
222}
223
224
227{
230
233
234
238 {
240 "PATHS",
241 "DATADIR",
244 }
248 {
250 "PATHS",
251 "LIBDIR",
254 }
258 {
260 "PATHS",
261 "BINDIR",
264 }
268 {
270 "PATHS",
271 "PREFIX",
274 }
278 {
280 "PATHS",
281 "LOCALEDIR",
284 }
288 {
290 "PATHS",
291 "ICONDIR",
294 }
298 {
300 "PATHS",
301 "DOCDIR",
304 }
308 {
310 "PATHS",
311 "LIBEXECDIR",
314 }
316}
317
318
319void
321{
324
328 {
333 cf);
335 }
338}
339
340
345 void *cb_cls)
346{
349
354 {
358 }
363}
364
365
370{
375
380};
381
382
395{
397
402}
403
404
414 const char *section)
415{
417
419 return NULL;
421 while ( (NULL != pos) &&
422 (0 != strcasecmp (section,
425 return pos;
426}
427
428
429static int
431 const void *b)
432{
433 return strcmp (*((const char **) a),
434 *((const char **) b));
435}
436
437
445 const char *path_or_glob,
446 bool path_is_glob,
447 const char *restrict_section,
448 const char *source_filename,
449 unsigned int source_lineno)
450{
451 char *inline_path = NULL;
455 .files_length = 0,
456 };
459
460
461 GNUNET_assert (! (path_is_glob && (NULL != restrict_section)));
462
463 if (NULL == source_filename)
464 {
466 "Refusing to parse inline configurations, "
467 "not allowed without source filename!\n");
470 }
471
472 if ('/' == *path_or_glob)
474 else
475 {
476
477
478
479 char *source_realpath;
480 char *endsep;
481
482 source_realpath = realpath (source_filename,
483 NULL);
484 if (NULL == source_realpath)
485 {
486
488
491 }
492 endsep = strrchr (source_realpath, '/');
494 *endsep = '\0';
496 "%s/%s",
497 source_realpath,
498 path_or_glob);
499 free (source_realpath);
500 }
501
502 if (path_is_glob)
503 {
504 int nret;
505
507 "processing config glob '%s'\n",
508 inline_path);
509
512 &igc);
513 if (-1 == nret)
514 {
517 }
521 sizeof (char *),
523 for (int i = 0; i < nret; i++)
524 {
528 {
531 }
532 }
534 }
535 else if (NULL != restrict_section)
536 {
540
542
544
545 if (NULL == cs)
546 {
552 }
554 {
555 const char *pwname;
556 const char *grname;
558 struct stat istat;
559
561 if (0 == stat (sfn, &istat))
562 {
563 struct passwd *pw = getpwuid (istat.st_uid);
564 struct group *gr = getgrgid (istat.st_gid);
565 pwname = (NULL == pw) ? "<unknown>" : pw->pw_name;
566 grname = (NULL == gr) ? "<unknown>" : gr->gr_name;
567
569 "%s:%s %o",
570 pwname,
571 grname,
572 istat.st_mode);
573 }
574 else
575 {
577 }
578 if (source_filename)
579 {
580
584 }
585 }
586
587
588 {
594 cf);
595 }
596
598 {
601
604 }
605
609 inline_path);
611 {
613 fun_ret = inner_ret;
615 }
616
618 restrict_section);
619 if (NULL == cs)
620 {
622 "Configuration file '%s' loaded with @inline-secret@ "
623 "does not contain section '%s'.\n",
624 inline_path,
625 restrict_section);
626
627
628
631 }
633 NULL != ce;
634 ce = ce->next)
636 restrict_section,
637 ce->key,
638 ce->val);
640 }
643 inline_path))
644 {
647 }
648 else
649 {
651 }
654 if (NULL != other_cfg)
658 {
662 }
663 return fun_ret;
664}
665
666
677 const char *section,
679{
681
683 section)))
684 return NULL;
686 pos != NULL;
688 if (0 == strcasecmp (
key,
689 pos->key))
690 return pos;
692 {
694 "Section '%s' is marked as inaccessible, because the configuration "
695 "file that contains the section can't be read. Attempts to use "
696 "option '%s' will fail.\n",
697 section,
699 return NULL;
700 }
701 return NULL;
702}
703
704
714static void
716 const char *section,
717 const char *option,
718 const char *hint_filename,
719 unsigned int hint_line)
720{
723 return;
724 if (! e)
725 return;
728}
729
730
733 const char *mem,
735 const char *source_filename)
736{
737 size_t line_size;
738 unsigned int nr;
739 size_t r_bytes;
740 size_t to_read;
742 char *section;
743 char *eq;
744 char *tag;
746 char *line_orig = NULL;
747
749 section = NULL;
750 nr = 0;
751 r_bytes = 0;
752 while (r_bytes <
size)
753 {
754 const char *pos;
756 bool emptyline;
757
759
760 to_read =
size - r_bytes;
761 pos = memchr (&mem[r_bytes], '\n', to_read);
762 if (NULL == pos)
763 {
765 line_size = to_read);
766 r_bytes += line_size;
767 }
768 else
769 {
771 line_size = (pos - &mem[r_bytes]));
772 r_bytes += line_size + 1;
773 }
775
776 nr++;
777
779 for (size_t i = 0; i < line_size; i++)
780 {
787 }
788
790 continue;
791
792
793 for (size_t i = line_size - 1;
794 (i >= 1) && (isspace ((
unsigned char)
line[i]));
795 i--)
797
798
799 for (;
line[0] !=
'\0' && (isspace ((
unsigned char)
line[0]));
line++)
800 ;
801
802
803 if ( (
'#' ==
line[0]) ||
805 continue;
806
807
809 {
810 char *
end = strchr (
line + 1,
'@');
811 char *directive;
813
815 {
817 "Illegal directive in line %u (parsing restricted section %s)\n",
818 nr,
821 break;
822 }
823
825 {
827 "Bad directive in line %u\n",
828 nr);
830 break;
831 }
833 directive =
line + 1;
834
835 if (0 == strcasecmp (directive,
836 "INLINE"))
837 {
838 const char *path =
end + 1;
839
840
841 for (; isspace (*path); path++)
842 ;
843
845 path,
846 false,
847 NULL,
848 source_filename,
849 nr);
850 }
851 else if (0 == strcasecmp (directive,
852 "INLINE-MATCHING"))
853 {
854 const char *path =
end + 1;
855
856
857 for (; isspace (*path); path++)
858 ;
859
861 path,
862 true,
863 NULL,
864 source_filename,
865 nr);
866 }
867 else if (0 == strcasecmp (directive,
868 "INLINE-SECRET"))
869 {
870 char *secname =
end + 1;
871 char *secname_end;
872 const char *path;
873
874
875 for (; isspace (*secname); secname++)
876 ;
877
878 secname_end = strchr (secname, ' ');
879
880 if (NULL == secname_end)
881 {
883 "Bad inline-secret directive in line %u\n",
884 nr);
886 break;
887 }
888 *secname_end = '\0';
889 path = secname_end + 1;
890
891
892 for (; isspace (*path); path++)
893 ;
894
896 path,
897 false,
898 secname,
899 source_filename,
900 nr);
901 }
902 else
903 {
905 "Unknown or malformed directive '%s' in line %u\n",
906 directive,
907 nr);
909 break;
910 }
912 {
914 break;
915 }
916 continue;
917 }
918 if ( (
'[' ==
line[0]) &&
919 (
']' ==
line[line_size - 1]) )
920 {
921
922 line[line_size - 1] =
'\0';
926 continue;
927 }
928 if (NULL != (eq = strchr (
line,
'=')))
929 {
930
931 if (NULL == section)
932 {
934 "Syntax error while deserializing in line %u (option without section)\n",
935 nr);
937 break;
938 }
939
940
942
943 for (int i = strlen (tag) - 1;
944 (i >= 1) && (isspace ((unsigned char) tag[i]));
945 i--)
946 tag[i] = '\0';
947
948
950 while (isspace ((
unsigned char)
value[0]))
952 for (
int i = strlen (
value) - 1;
953 (i >= 1) && (isspace ((
unsigned char)
value[i]));
954 i--)
956
957
958 if ( (
'"' ==
value[0]) &&
960 {
963 }
965 section,
966 tag,
969 {
971 section,
972 tag,
973 source_filename
974 ? source_filename
975 : "<input>",
976 nr);
977 }
979 continue;
980 }
981
983 "Syntax error while deserializing in line %u\n",
984 nr);
986 break;
987 }
993}
994
995
999{
1000 uint64_t fs64;
1002 char *fn;
1003 char *mem;
1004 int dirty;
1006 ssize_t sret;
1007
1010 "Asked to parse config file `%s'\n",
1011 fn);
1012 if (NULL == fn)
1014
1015
1016
1017 {
1021
1022
1023 for (; NULL != cf; parent = cf, cf = cf->
prev)
1024 {
1025
1026 if (cf->level >= lvl)
1027 continue;
1029 if ( (NULL == cf->source_filename) ||
1031 continue;
1032 if (0 == strcmp (cf->source_filename,
1034 {
1035 if (NULL == parent)
1036 {
1038 "Forbidden direct cyclic configuration import (%s -> %s)\n",
1039 cf->source_filename,
1041 }
1042 else
1044 "Forbidden indirect cyclic configuration import (%s -> ... -> %s -> %s)\n",
1045 cf->source_filename,
1050 }
1051 }
1052
1053 }
1054
1055
1056 {
1058
1063 cf);
1064 }
1065
1069 &fs64,
1072 {
1074 "Error while determining the file size of `%s'\n",
1075 fn);
1078 }
1080 {
1084 }
1088 mem,
1090 if ((sret < 0) || (
fs != (
size_t) sret))
1091 {
1093 "Error while reading file `%s'\n",
1094 fn);
1098 }
1100 "Deserializing contents of file `%s'\n",
1101 fn);
1103 mem,
1105 fn);
1107 {
1109 _ (
"Failed to parse configuration file `%s'\n"),
1110 fn);
1111 }
1114
1115
1118}
1119
1120
1123{
1125}
1126
1127
1135static bool
1138{
1139 if (0 != strcasecmp ("PATHS",
1140 sec))
1141 return false;
1142 return ( (0 == strcasecmp ("DATADIR",
1144 (0 == strcasecmp ("LIBDIR",
1146 (0 == strcasecmp ("BINDIR",
1148 (0 == strcasecmp ("PREFIX",
1150 (0 == strcasecmp ("LOCALEDIR",
1152 (0 == strcasecmp ("ICONDIR",
1154 (0 == strcasecmp ("DOCDIR",
1156 (0 == strcasecmp ("DEFAULTCONFIG",
1158 (0 == strcasecmp ("LIBEXECDIR",
1160}
1161
1162
1163char *
1166{
1167 char *mem;
1168 char *cbuf;
1169 char *val;
1170 char *pos;
1171 size_t m_size;
1172 size_t c_size;
1173
1174
1175 m_size = 0;
1177 NULL != sec;
1178 sec = sec->next)
1179 {
1180 if (sec->inaccessible && (NULL == sec->entries))
1181 continue;
1182
1183 m_size += strlen (sec->name) + 3;
1185 NULL != ent;
1186 ent = ent->next)
1187 {
1189 ent->key))
1190 continue;
1191 if (NULL != ent->val)
1192 {
1193
1194 pos = ent->val;
1195 while (NULL != (pos = strstr (pos, "\n")))
1196 {
1197 m_size++;
1198 pos++;
1199 }
1200
1201
1202 m_size += strlen (ent->key) + strlen (ent->val) + 4;
1203 }
1204 }
1205
1206 m_size++;
1207 }
1208
1209
1211 c_size = 0;
1214 NULL != sec;
1215 sec = sec->next)
1216 {
1217 int len;
1218
1220 "[%s]\n",
1221 sec->name);
1224 cbuf,
1225 len);
1226 c_size += len;
1229 NULL != ent;
1230 ent = ent->next)
1231 {
1233 ent->key))
1234 continue;
1235 if (NULL != ent->val)
1236 {
1238 strcpy (val, ent->val);
1239 while (NULL != (pos = strstr (val, "\n")))
1240 {
1241 memmove (&pos[2], &pos[1], strlen (&pos[1]));
1242 pos[0] = '\\';
1243 pos[1] = 'n';
1244 }
1248 c_size += len;
1250 }
1251 }
1253 c_size++;
1254 }
1257 return mem;
1258}
1259
1260
1269static void
1274{
1276 ipk);
1277 const char *ipkname;
1278 switch (ipk)
1279 {
1281 ipkname = "IPK_DATADIR";
1282 break;
1284 ipkname = "IPK_BINDIR";
1285 break;
1287 ipkname = "IPK_LIBDIR";
1288 break;
1290 ipkname = "IPK_PREFIX";
1292 ipkname = "IPK_LOCALEDIR";
1293 break;
1295 ipkname = "IPK_ICONDIR";
1297 ipkname = "IPK_DOCDIR";
1298 break;
1300 ipkname = "IPK_LIBEXECDIR";
1301 break;
1303 ipkname = "IPK_SELF_PREFIX";
1304 break;
1305 default:
1306 ipkname = "??";
1307 break;
1308 }
1310 "# %s = %s\n",
1311 ipkname,
1312 v);
1314}
1315
1316
1317char *
1320{
1322
1324 "#\n# Configuration file diagnostics\n#\n");
1326 "# Entry point: %s\n",
1328 "<none>");
1330 "#\n# Files Loaded:\n");
1331
1333 NULL != cfil;
1334 cfil = cfil->next)
1335 {
1337 "# ");
1338 for (unsigned int i = 0; i < cfil->level; i++)
1340 "+");
1341 if (0 != cfil->level)
1343 " ");
1344
1346 "%s",
1347 cfil->source_filename);
1348
1349 if (NULL != cfil->hint_restrict_section)
1351 " (%s secret section %s)",
1352 cfil->hint_inaccessible
1353 ? "inaccessible"
1354 : "loaded",
1355 cfil->hint_restrict_section);
1356
1358 "\n");
1359 }
1360
1362 "#\n# Installation paths:\n");
1363
1373
1374
1376 "#\n\n");
1377
1379 NULL != sec;
1380 sec = sec->next)
1381 {
1382 if (sec->hint_secret_filename)
1384 "# secret section from %s\n# secret file stat %s\n",
1385 sec->hint_secret_filename,
1386 sec->hint_secret_stat);
1387 if (sec->hint_inlined_from_filename)
1388 {
1390 "# inlined from %s:%u\n",
1391 sec->hint_inlined_from_filename,
1392 sec->hint_inlined_from_line);
1393 }
1395 "[%s]\n\n",
1396 sec->name);
1397 if (sec->inaccessible && (NULL == sec->entries))
1398 {
1400 "# <section contents inaccessible>\n\n\n");
1401 continue;
1402 }
1404 NULL != ent;
1405 ent = ent->next)
1406 {
1408 ent->key))
1409 continue;
1410 if (NULL != ent->val)
1411 {
1412 char *pos;
1414 strcpy (val, ent->val);
1415 while (NULL != (pos = strstr (val, "\n")))
1416 {
1417 memmove (&pos[2], &pos[1], strlen (&pos[1]));
1418 pos[0] = '\\';
1419 pos[1] = 'n';
1420 }
1421 if (NULL != ent->hint_filename)
1422 {
1424 "# %s:%u\n",
1425 ent->hint_filename,
1426 ent->hint_lineno);
1427 }
1429 "%s = %s\n",
1430 ent->key,
1431 val);
1433 }
1435 }
1436 if (sec->inaccessible)
1437 {
1439 "# <additional section contents inaccessible>\n\n\n");
1440 continue;
1441 }
1442
1444 }
1446}
1447
1448
1453{
1454 char *fn;
1455 char *tfn;
1456 char *cfg_buf;
1458
1460 if (fn == NULL)
1463 {
1466 }
1467 {
1468
1469
1470 char *rfn = realpath (fn,
1471 NULL);
1472
1473 if (NULL != rfn)
1474 {
1477 free (rfn);
1478 }
1479 }
1482
1483
1484
1485
1486
1487
1489 "%s.%u.tmp",
1490 fn,
1491 (unsigned int) getpid ());
1492 {
1494
1504 {
1509 }
1510 if (((ssize_t)
size) !=
1512 cfg_buf,
1514 {
1516 "write",
1517 tfn);
1519 (void) unlink (tfn);
1525 }
1526
1527
1531 }
1532 {
1533 struct stat sbuf;
1534
1535
1536
1537 if ( (0 == stat (fn,
1538 &sbuf)) &&
1539 (0 != chmod (tfn,
1540 sbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))) )
1542 "chmod",
1543 tfn);
1544 }
1545 if (0 != rename (tfn,
1546 fn))
1547 {
1549 "rename",
1550 fn);
1551 (void) unlink (tfn);
1557 }
1563}
1564
1565
1566void
1570 void *iter_cls)
1571{
1573 NULL != spos;
1574 spos = spos->next)
1576 NULL != epos;
1577 epos = epos->next)
1578 if (NULL != epos->val)
1579 iter (iter_cls,
1580 spos->name,
1581 epos->key,
1582 epos->val);
1583}
1584
1585
1586void
1589 const char *section,
1591 void *iter_cls)
1592{
1594
1596 while ((spos != NULL) && (0 != strcasecmp (spos->
name, section)))
1598 if (NULL == spos)
1599 return;
1601 NULL != epos;
1602 epos = epos->next)
1603 if (NULL != epos->val)
1604 iter (iter_cls,
1606 epos->key,
1607 epos->val);
1609 {
1611 "Section '%s' is marked as inaccessible, because a configuration "
1612 "file that contains the section can't be read.\n",
1613 section);
1614 return;
1615 }
1616}
1617
1618
1619void
1623 void *iter_cls)
1624{
1627
1629 while (NULL !=
next)
1630 {
1634 continue;
1635 iter (iter_cls,
1637 }
1638}
1639
1640
1641void
1643 const char *section)
1644{
1648
1649 prev = NULL;
1651 while (NULL != spos)
1652 {
1653 if (0 == strcasecmp (section,
1655 {
1656 if (NULL == prev)
1658 else
1660 while (NULL != (ent = spos->
entries))
1661 {
1668 }
1674 return;
1675 }
1676 prev = spos;
1678 }
1679}
1680
1681
1691static void
1693 const char *section,
1694 const char *option,
1696{
1698
1700 section,
1701 option,
1703}
1704
1705
1709{
1711
1717}
1718
1719
1730static void
1732 const char *section,
1733 const char *option,
1735{
1738
1740 if ((NULL != entNew) && (NULL != entNew->
val) &&
1741 (0 == strcmp (entNew->
val,
value)))
1742 return;
1744 section,
1745 option,
1747}
1748
1749
1754{
1756
1762 &diffHandle);
1763 return diffHandle.cfgDiff;
1764}
1765
1766
1772{
1775
1780}
1781
1782
1783void
1786 const char *section,
1787 const char *option,
1789{
1792 char *nv;
1793
1795 if (NULL != e)
1796 {
1798 {
1801 }
1802 else
1803 {
1807 }
1808 return;
1809 }
1811 if (sec == NULL)
1812 {
1817 }
1823}
1824
1825
1826void
1828 const char *section,
1829 const char *option,
1830 unsigned long long number)
1831{
1832 char s[64];
1833
1835 64,
1836 "%llu",
1839 section,
1840 option,
1841 s);
1842}
1843
1844
1848 const char *section,
1849 const char *option,
1850 unsigned long long *
number)
1851{
1854
1856 section,
1857 option)))
1861 if (1 != sscanf (e->
val,
1862 "%llu%1s",
1867}
1868
1869
1870void
1872 const char *section,
1873 const char *option,
1875{
1876 char s[64];
1877
1878
1879 const locale_t cl = newlocale (LC_NUMERIC_MASK,
1880 "C",
1881 (locale_t) 0);
1882 locale_t old_locale = uselocale (cl);
1884 64,
1885 "%f",
1887 uselocale (old_locale);
1889 section,
1890 option,
1891 s);
1892}
1893
1894
1898 const char *section,
1899 const char *option,
1901{
1904
1906 section,
1907 option)))
1911
1912 {
1913 const locale_t cl = newlocale (LC_NUMERIC_MASK,
1914 "C",
1915 (locale_t) 0);
1916 locale_t old_locale = uselocale (cl);
1917
1918 if (1 != sscanf (e->
val,
1919 "%f%1s",
1923 uselocale (old_locale);
1924 }
1926}
1927
1928
1932 const char *section,
1933 const char *option,
1935{
1938
1940 section,
1941 option)))
1946 time);
1949 section,
1950 option,
1951 _ (
"Not a valid relative time specification"));
1953}
1954
1955
1959 const char *section,
1960 const char *option,
1961 unsigned long long *
size)
1962{
1964
1966 section,
1967 option)))
1973}
1974
1975
1989 const char *section,
1990 const char *option,
1992{
1994
1996 section,
1997 option))) ||
1999 {
2002 }
2005}
2006
2007
2011 const char *section,
2012 const char *option,
2013 const char *const *choices,
2015{
2017 unsigned int i;
2018
2020 section,
2021 option)))
2023 for (i = 0; NULL !=
choices[i]; i++)
2024 if (0 == strcasecmp (choices[i], e->
val))
2025 break;
2026 if (NULL == choices[i])
2027 {
2029 _ (
"Configuration value '%s' for '%s'"
2030 " in section '%s' is not in set of legal choices\n"),
2032 option,
2033 section);
2035 }
2038}
2039
2040
2043 const char *section,
2044 const char *option,
2045 void *buf,
2046 size_t buf_size)
2047{
2051
2055 section,
2056 option,
2061 {
2064 }
2068 buf,
2069 buf_size))
2070 {
2073 }
2076}
2077
2078
2081 const char *section,
2082 const char *option)
2083{
2085
2087 section,
2088 option))) ||
2092}
2093
2094
2110static char *
2112 char *orig,
2113 unsigned int depth)
2114{
2118 const char *post;
2120 char *def;
2122 unsigned int lopen;
2123 char erased_char;
2124 char *erased_pos;
2125 size_t len;
2126
2127 if (NULL == orig)
2128 return NULL;
2129 if (depth > 128)
2130 {
2132 "Recursive expansion suspected, aborting $-expansion for term `%s'\n",
2133 orig);
2134 return orig;
2135 }
2137 "Asked to $-expand %s\n",
2138 orig);
2139 if ('$' != orig[0])
2140 {
2142 "Doesn't start with $ - not expanding\n");
2143 return orig;
2144 }
2145 erased_char = 0;
2146 erased_pos = NULL;
2147 if ('{' == orig[1])
2148 {
2150 lopen = 1;
2152 while (lopen > 0)
2153 {
2156 {
2157 case '}':
2158 lopen--;
2159 break;
2160
2161 case '{':
2162 lopen++;
2163 break;
2164
2165 case '\0':
2167 "Missing closing `}' in option `%s'\n",
2168 orig);
2169 return orig;
2170
2171 default:
2172 break;
2173 }
2174 }
2179 def = strchr (orig, ':');
2180 if (NULL != def)
2181 {
2182 *def = '\0';
2183 def++;
2184 if (('-' == *def) || ('=' == *def))
2185 def++;
2187 }
2188 }
2189 else
2190 {
2191 int i;
2192
2194 def = NULL;
2195 i = 0;
2196 while ( (orig[i] != '/') &&
2197 (orig[i] != '\\') &&
2198 (orig[i] != '\0') &&
2199 (orig[i] != ' ') )
2200 i++;
2201 if (orig[i] == '\0')
2202 {
2203 post = "";
2204 }
2205 else
2206 {
2207 erased_char = orig[i];
2208 erased_pos = &orig[i];
2209 orig[i] = '\0';
2210 post = &orig[i + 1];
2211 }
2212 }
2214 "Split into `%s' and `%s' with default %s\n",
2216 post,
2217 def);
2220 "PATHS",
2223 {
2225 {
2226
2228 def,
2229 depth + 1);
2231 }
2233 {
2235 if (erased_pos)
2236 *erased_pos = erased_char;
2238 "Failed to expand `%s' in `%s' as it is neither found in [PATHS] nor defined as an environmental variable\n",
2240 orig);
2242 return orig;
2243 }
2245 }
2248 if ((erased_pos) && ('}' != erased_char))
2249 {
2250 len = strlen (
prefix) + 1;
2252 prefix[len - 1] = erased_char;
2254 }
2262}
2263
2264
2265char *
2268 char *orig)
2269{
2270 char *dup;
2271 size_t i;
2272 size_t len;
2273
2274 for (i = 0; '\0' != orig[i]; i++)
2275 {
2276 if ('$' != orig[i])
2277 continue;
2281 len = strlen (dup) + 1;
2285 }
2286 return orig;
2287}
2288
2289
2293 const char *section,
2294 const char *option,
2296{
2297 char *tmp;
2299
2301 section,
2302 option,
2303 &tmp);
2305 {
2307 "Failed to retrieve filename\n");
2310 }
2312 tmp);
2318}
2319
2320
2324 const char *section,
2325 const char *option)
2326{
2327 static const char *yesno[] = {
2328 "YES",
2329 "NO",
2330 NULL
2331 };
2334
2337 section,
2338 option,
2339 yesno,
2343 if (
val == yesno[0])
2346}
2347
2348
2349int
2352 const char *section,
2353 const char *option,
2355 void *cb_cls)
2356{
2358 char *pos;
2360 char old;
2362
2365 section,
2366 option,
2368 return 0;
2372 while (1)
2373 {
2374 while (pos[0] == ' ')
2375 pos++;
2376 if (strlen (pos) == 0)
2377 break;
2379 while ((
end[0] !=
' ') && (
end[0] !=
'\0'))
2380 {
2382 {
2384 {
2385 case '\\':
2386 case ' ':
2387 memmove (
end, &
end[1], strlen (&
end[1]) + 1);
2388
2389 case '\0':
2390
2391 break;
2392
2393 default:
2394
2395 break;
2396 }
2397 }
2399 }
2402 if (strlen (pos) > 0)
2403 {
2405 if ( (NULL != cb) &&
2407 pos)))
2408 {
2410 break;
2411 }
2412 }
2413 if (old == '\0')
2414 break;
2416 }
2419}
2420
2421
2428static char *
2430{
2431 char *escaped;
2432 const char *rpos;
2433 char *wpos;
2434
2436 memset (escaped, 0, strlen (
value) * 2 + 1);
2438 wpos = escaped;
2439 while (rpos[0] != '\0')
2440 {
2441 switch (rpos[0])
2442 {
2443 case '\\':
2444 case ' ':
2445 wpos[0] = '\\';
2446 wpos[1] = rpos[0];
2447 wpos += 2;
2448 break;
2449
2450 default:
2451 wpos[0] = rpos[0];
2452 wpos++;
2453 }
2454 rpos++;
2455 }
2456 return escaped;
2457}
2458
2459
2469 const char *fn)
2470{
2471 const char *of = cls;
2472
2473 return (0 == strcmp (of, fn))
2476}
2477
2478
2482 const char *section,
2483 const char *option,
2485{
2486 char *escaped;
2487 char *old;
2488 char *nw;
2489
2492 section,
2493 option,
2502 strcpy (nw, old);
2503 if (strlen (old) > 0)
2504 strcat (nw, " ");
2505 strcat (nw, escaped);
2507 section,
2508 option,
2509 nw);
2514}
2515
2516
2520 const char *section,
2521 const char *option,
2523{
2525 char *pos;
2527 char *match;
2528 char old;
2529
2532 section,
2533 option,
2538 while (1)
2539 {
2540 while (pos[0] == ' ')
2541 pos++;
2542 if (strlen (pos) == 0)
2543 break;
2545 while ((
end[0] !=
' ') && (
end[0] !=
'\0'))
2546 {
2548 {
2550 {
2551 case '\\':
2552 case ' ':
2554 break;
2555
2556 case '\0':
2557
2558 break;
2559
2560 default:
2561
2562 break;
2563 }
2564 }
2566 }
2569 if (0 == strcmp (pos, match))
2570 {
2571 if (old != '\0')
2572 memmove (pos,
2574 strlen (&
end[1]) + 1);
2575 else
2576 {
2578 pos[-1] = '\0';
2579 else
2580 pos[0] = '\0';
2581 }
2583 section,
2584 option,
2589 }
2590 if (old == '\0')
2591 break;
2594 }
2598}
2599
2600
2604 const char *defaults_d)
2605{
2608 .files_length = 0,
2609 };
2611
2615 &files_context))
2617 qsort (files_context.
files,
2619 sizeof (char *),
2621 for (
unsigned int i = 0; i < files_context.
files_length; i++)
2622 {
2623 const char *ext;
2625
2626
2628 if ( (NULL == ext) ||
2629 (0 != strcmp (ext,
2630 ".conf")) )
2631 {
2633 "Skipping file `%s'\n",
2636 continue;
2637 }
2641 break;
2642 }
2644 {
2645 for (
size_t i = 0; i < files_context.
files_length; i++)
2649 0);
2650 }
2651 return fun_ret;
2652}
2653
2654
2655char *
2658{
2659 char *cfg_fn;
2660 const char *xdg =
getenv (
"XDG_CONFIG_HOME");
2661
2662 if (NULL != xdg)
2664 "%s%s%s",
2665 xdg,
2668 else
2670
2672 return cfg_fn;
2674
2675
2676
2677
2679 "/etc/%s",
2683 return cfg_fn;
2685
2687 "/etc/%s/%s",
2692 return cfg_fn;
2693
2695 return NULL;
2696}
2697
2698
2703{
2704 char *baseconfig;
2705 const char *base_config_varname;
2706
2708 {
2709
2712 }
2715 {
2718 }
2719
2721
2722 if ((NULL != base_config_varname)
2723 && (NULL != (baseconfig =
getenv (base_config_varname))))
2724 {
2726 }
2727 else
2728 {
2729 char *ipath;
2730
2733 if (NULL == ipath)
2734 {
2737 }
2739 "%s%s",
2740 ipath,
2741 "config.d");
2743 }
2744
2745 {
2747
2749
2755 dname)))
2756 {
2758 "Failed to load base configuration from '%s'\n",
2762 }
2764 }
2769 {
2770
2772 "Failed to load configuration from file '%s'\n",
2775 }
2778 "PATHS",
2779 "DEFAULTCONFIG"))) &&
2782 "PATHS",
2783 "DEFAULTCONFIG",
2786}
2787
2788
2797static void
2799 const char *section,
2800 const char *option,
2802{
2804
2805 char *value_fn;
2806 char *fn;
2807
2810 section,
2811 option,
2812 &value_fn));
2814 if (NULL == fn)
2815 fn = value_fn;
2816 else
2818 fprintf (stdout,
2819 "%s = %s\n",
2820 option,
2821 fn);
2823}
2824
2825
2834static void
2836 const char *section,
2837 const char *option,
2839{
2840 (void) cls;
2841 (void) section;
2842
2843 fprintf (stdout,
2844 "%s = %s\n",
2845 option,
2847}
2848
2849
2856static void
2858 const char *section)
2859{
2860 (void) cls;
2861 fprintf (stdout,
2862 "%s\n",
2863 section);
2864}
2865
2866
2867void
2869 void *cls,
2870 char *const *args,
2871 const char *cfgfile,
2873{
2877
2878 (void) args;
2880 {
2881
2886 cfgfile))
2887 {
2888 fprintf (stderr,
2889 _ (
"Failed to load config file `%s'"),
2890 cfgfile);
2891 return;
2892 }
2894 }
2895
2899 {
2900 fprintf (stderr,
2901 _ (
"The following sections are available:\n"));
2904 NULL);
2905 return;
2906 }
2909 {
2910 char *serialization;
2911
2913 {
2914 fprintf (stderr,
2915 _ (
"%s, %s or %s argument is required\n"),
2916 "--section",
2917 "--list-sections",
2918 "--diagnostics");
2920 return;
2921 }
2923 fprintf (stdout,
2924 "%s",
2925 serialization);
2927 }
2928 else if ( (NULL != cs->
section) &&
2929 (NULL == cs->
value) )
2930 {
2932 {
2940 }
2941 else
2942 {
2944
2946 {
2952 {
2957 return;
2958 }
2959 }
2960 else
2961 {
2967 {
2972 return;
2973 }
2974 }
2975 fprintf (stdout,
2976 "%s\n",
2979 }
2980 }
2982 {
2984 {
2985 fprintf (stderr,
2986 _ (
"--option argument required to set value\n"));
2988 return;
2989 }
2996 }
2998 {
2999 char *cfg_fn = NULL;
3000
3001 if (NULL == out)
3003
3004 if (NULL == cfgfile)
3005 {
3006 const char *xdg =
getenv (
"XDG_CONFIG_HOME");
3007
3008 if (NULL != xdg)
3010 "%s%s%s",
3011 xdg,
3014 else
3016 cfgfile = cfg_fn;
3017 }
3018
3020 {
3022
3026 NULL))
3027 {
3028 fprintf (stderr,
3029 _ (
"failed to load configuration defaults"));
3034 return;
3035 }
3038 out,
3039 cfgfile))
3042 }
3043 else
3044 {
3047 cfgfile))
3049 }
3051 }
3052 if (NULL != out)
3054 if (NULL != ncfg)
3056}
3057
3058
3059void
3062{
3066}
3067
3068
3072{
3074}
3075
3076
3077char *
3079 pd,
3080 const struct
3082 const char *progname)
3083{
3084 static char *cache;
3085 char *binary = NULL;
3086 char *path = NULL;
3087 size_t path_len;
3088
3092 NULL,
3093 NULL))
3094 {
3096 }
3097 if (NULL != cache)
3098 path = cache;
3099 else
3101 "PATHS",
3102 "SUID_BINARY_PATH",
3103 &path);
3104 if ( (NULL == path) ||
3105 (0 == strlen (path)) )
3106 {
3107 if (NULL != path)
3109 cache = NULL;
3111 progname);
3112 }
3113 path_len = strlen (path);
3115 "%s%s%s",
3116 path,
3119 progname);
3120 cache = path;
3121 return binary;
3122}
3123
3124
3125
struct GNUNET_MQ_Envelope * env
static bool do_skip(const char *sec, const char *key)
Should we skip this configuration entry when serializing?
static void print_filename_option(void *cls, const char *section, const char *option, const char *value)
Print each option in a given section as a filename.
static struct ConfigEntry * find_entry(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *key)
Find an entry from a configuration.
static enum GNUNET_GenericReturnValue handle_inline(struct GNUNET_CONFIGURATION_Handle *cfg, const char *path_or_glob, bool path_is_glob, const char *restrict_section, const char *source_filename, unsigned int source_lineno)
Handle an inline directive.
static void print_section_name(void *cls, const char *section)
Print out given section name.
static char * escape_name(const char *value)
FIXME.
static void compare_entries(void *cls, const char *section, const char *option, const char *value)
A callback function, compares entries from two configurations (default against a new configuration) a...
static enum GNUNET_GenericReturnValue test_match(void *cls, const char *fn)
FIXME.
static struct ConfigSection * find_section(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
Find a section entry from a configuration.
static int pstrcmp(const void *a, const void *b)
static char * expand_dollar(const struct GNUNET_CONFIGURATION_Handle *cfg, char *orig, unsigned int depth)
Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where either in the "PATHS" section or...
static enum GNUNET_GenericReturnValue collect_files_cb(void *cls, const char *filename)
Function called with a filename.
static void copy_entry(void *cls, const char *section, const char *option, const char *value)
Copy a configuration value to the given target configuration.
static void print_option(void *cls, const char *section, const char *option, const char *value)
Print each option in a given section.
static void dump_os_ipk(const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_Buffer *buf, enum GNUNET_OS_InstallationPathKind ipk)
Dump an os installation path to a buffer.
static void set_entry_hint(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *hint_filename, unsigned int hint_line)
Set a configuration hint.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
static int start
Set if we are to start default services (including ARM).
static int list
Set if we should print a list of currently running services.
static int ret
Final status code.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static int end
Set if we are to shutdown all services (including ARM).
static int prefix
If printing the value of PREFIX has been requested.
static char * line
Desired phone line (string to be converted to a hash).
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_FS_Handle * fs
Handle to FS service.
static OpusEncoder * enc
OPUS encoder.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static char * res
Currently read line or NULL on EOF.
static char * value
Value of the record to add/remove.
static size_t data_size
Number of bytes in data.
static int result
Global testing status.
static void cleanup()
Cleanup task.
static struct GNUNET_Process * p
Helper process we started.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_data(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, void *buf, size_t buf_size)
Get Crockford32-encoded fixed-size binary data from a configuration.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(const struct GNUNET_OS_ProjectData *pd)
Create a new configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_is_dirty(const struct GNUNET_CONFIGURATION_Handle *cfg)
Test if there are configuration options that were changed since the last save.
void GNUNET_CONFIGURATION_set_value_string(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Set a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_append_value_filename(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Append a filename to a configuration value that represents a list of filenames.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
void GNUNET_CONFIGURATION_remove_section(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
Remove the given section and all options in it.
enum GNUNET_GenericReturnValue(* GNUNET_CONFIGURATION_Callback)(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Signature of a function to be run with a configuration.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_dup(const struct GNUNET_CONFIGURATION_Handle *cfg)
Duplicate an existing configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_SectionIterator iter, void *iter_cls)
Iterate over all sections in the configuration.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
char * GNUNET_CONFIGURATION_get_suid_binary_path(const struct GNUNET_OS_ProjectData *pd, const struct GNUNET_CONFIGURATION_Handle *cfg, const char *progname)
Given the name of a helper, service or daemon binary construct the full path to the binary using the ...
void GNUNET_CONFIGURATION_config_settings_free(struct GNUNET_CONFIGURATION_ConfigSettings *cs)
Free resources associated with cs.
void GNUNET_CONFIGURATION_iterate(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
Iterate over all options in the configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_remove_value_filename(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Remove a filename from a configuration value that represents a list of filenames.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse_and_run(const struct GNUNET_OS_ProjectData *pd, const char *filename, GNUNET_CONFIGURATION_Callback cb, void *cb_cls)
Parse a configuration file filename and run the function cb with the resulting configuration object.
void GNUNET_CONFIGURATION_config_tool_run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main task to run to perform operations typical for gnunet-config as per the configuration settings gi...
void(* GNUNET_CONFIGURATION_SectionIterator)(void *cls, const char *section)
Function to iterate over all configuration sections.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_deserialize(struct GNUNET_CONFIGURATION_Handle *cfg, const char *mem, size_t size, const char *source_filename)
De-serializes configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
char * GNUNET_CONFIGURATION_serialize(const struct GNUNET_CONFIGURATION_Handle *cfg, size_t *size)
Serializes the given configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
void GNUNET_CONFIGURATION_set_value_number(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long number)
Set a configuration value that should be a number.
char * GNUNET_CONFIGURATION_default_filename(const struct GNUNET_OS_ProjectData *pd)
Return the filename of the default configuration filename that is used when no explicit configuration...
char * GNUNET_CONFIGURATION_expand_dollar(const struct GNUNET_CONFIGURATION_Handle *cfg, char *orig)
Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where either in the "PATHS" section or...
void GNUNET_CONFIGURATION_set_value_float(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, float number)
Set a configuration value that should be a float.
const struct GNUNET_OS_ProjectData * GNUNET_CONFIGURATION_get_project_data(const struct GNUNET_CONFIGURATION_Handle *cfg)
Return the project data associated with this configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_get_diff(const struct GNUNET_CONFIGURATION_Handle *cfg_default, const struct GNUNET_CONFIGURATION_Handle *cfg_new)
Compute configuration with only entries that have been changed.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Parse a configuration file, add all of the options in the file to the configuration environment.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_float(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, float *number)
Get a configuration value that should be a floating point number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_load_from(struct GNUNET_CONFIGURATION_Handle *cfg, const char *defaults_d)
Load default configuration.
int GNUNET_CONFIGURATION_iterate_value_filenames(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, GNUNET_FileNameCallback cb, void *cb_cls)
Iterate over the set of filenames stored in a configuration value.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_choice(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *const *choices, const char **value)
Get a configuration value that should be in a set of predefined strings.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_write(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Write configuration file.
void(* GNUNET_CONFIGURATION_Iterator)(void *cls, const char *section, const char *option, const char *value)
Function to iterate over options.
void GNUNET_CONFIGURATION_iterate_section_values(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
Iterate over values of a section in the configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_write_diffs(const struct GNUNET_CONFIGURATION_Handle *cfg_default, const struct GNUNET_CONFIGURATION_Handle *cfg_new, const char *filename)
Write only configuration entries that have been changed to configuration file.
char * GNUNET_CONFIGURATION_serialize_diagnostics(const struct GNUNET_CONFIGURATION_Handle *cfg)
Serializes the given configuration with diagnostics information.
void GNUNET_CONFIGURATION_enable_diagnostics(struct GNUNET_CONFIGURATION_Handle *cfg)
Enable extra diagnostics.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
int GNUNET_DISK_glob(const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
Find all files matching a glob pattern.
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test_read(const char *fil)
Check that fil corresponds to a filename and the file has read permissions.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
@ GNUNET_DISK_OPEN_WRITE
Open the file for writing.
@ GNUNET_DISK_OPEN_TRUNCATE
Truncate file if it exists.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_GROUP_READ
Group can read.
@ GNUNET_DISK_PERM_GROUP_WRITE
Group can write.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
enum GNUNET_GenericReturnValue(* GNUNET_FileNameCallback)(void *cls, const char *filename)
Function called with a filename.
#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_str(struct GNUNET_Buffer *buf, const char *str)
Write a 0-terminated string to a buffer, excluding the 0-terminator.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
#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.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#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_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_OS_installation_get_path(const struct GNUNET_OS_ProjectData *pd, enum GNUNET_OS_InstallationPathKind dirkind)
Get the path to a specific GNUnet installation directory or, with GNUNET_OS_IPK_SELF_PREFIX,...
GNUNET_OS_InstallationPathKind
Possible installation paths to request.
char * GNUNET_OS_get_libexec_binary_path(const struct GNUNET_OS_ProjectData *pd, const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
@ GNUNET_OS_IPK_SELF_PREFIX
Return the installation directory of this application, not the one of the overall GNUnet installation...
@ GNUNET_OS_IPK_ICONDIR
Return the prefix of the path with application icons (share/icons/).
@ GNUNET_OS_IPK_DATADIR
Return the directory where data is installed (share/gnunet/)
@ GNUNET_OS_IPK_DOCDIR
Return the prefix of the path with documentation files, including the license (share/doc/gnunet/).
@ GNUNET_OS_IPK_LOCALEDIR
Return the directory where translations are installed (share/locale/)
@ GNUNET_OS_IPK_LIBDIR
Return the directory where libraries are installed.
@ GNUNET_OS_IPK_PREFIX
Return the "PREFIX" directory given to configure.
@ GNUNET_OS_IPK_BINDIR
Return the directory where the program binaries are installed.
@ GNUNET_OS_IPK_LIBEXECDIR
Return the directory where helper binaries are installed (lib/gnunet/libexec/)
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
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_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_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_size_to_bytes(const char *fancy_size, unsigned long long *size)
Convert a given fancy human-readable size to bytes.
static unsigned int size
Size of the "table".
Closure to collect_files_cb.
char ** files
Collected files from globbing.
unsigned int files_length
Size of the files array.
char * hint_filename
Diagnostics information for the filename.
struct ConfigEntry * next
This is a linked list.
char * key
key for this entry
unsigned int hint_lineno
Diagnostics information for the line number.
char * val
current, committed value
char * hint_restrict_section
Was this configuration file parsed via @inline-secret@?
char * source_filename
Source filename.
bool hint_inaccessible
Was this configuration file inaccessible?
unsigned int level
Level in the tree of loaded config files.
char * name
name of the section
char * hint_inlined_from_filename
For secret sections: Where was this inlined from?
struct ConfigEntry * entries
entries in the section
bool inaccessible
Is the configuration section marked as inaccessible?
struct ConfigSection * next
This is a linked list.
char * hint_secret_filename
Diagnostics hint for the secret file.
unsigned int hint_inlined_from_line
For secret sections: Where was this inlined from?
char * hint_secret_stat
Extra information regarding permissions of the secret file.
Used for diffing a configuration object against the default one.
const struct GNUNET_CONFIGURATION_Handle * cfg_default
struct GNUNET_CONFIGURATION_Handle * cfgDiff
Dynamically growing buffer.
Closure for GNUNET_CONFIGURATION_config_tool_run() with settings for what should be done with the con...
char * value
Value to set.
int full
Should the generated configuration file contain the whole configuration?
int global_ret
Return value from the operation, to be returned from 'main'.
int diagnostics
Should we give extra diagnostics?
int list_sections
Whether to show the sections.
int rewrite
Should we write out the configuration file, even if no value was changed?
char * option
Name of the option.
char * section
Name of the section.
int is_filename
Treat option as a filename.
struct ConfigFile * loaded_files_tail
Linked list of loaded files.
bool load_called
Was the configuration ever loaded via GNUNET_CONFIGURATION_load?
unsigned int current_nest_level
Current nesting level of file loading.
const struct GNUNET_OS_ProjectData * pd
Project data for this configuration object.
struct ConfigSection * sections
Configuration sections.
struct ConfigFile * loaded_files_head
Linked list of loaded files.
char * main_filename
Name of the entry point configuration file.
enum GNUNET_GenericReturnValue dirty
Modification indication since last save GNUNET_NO if clean, GNUNET_YES if dirty, GNUNET_SYSERR on err...
bool diagnostics
Enable diagnostics.
const char * restrict_section
When parsing into this configuration, and this value is non-NULL, only parse sections of the same nam...
Handle used to access files (and pipes).
Project-specific data used to help the OS subsystem find installation paths.
const char * base_config_varname
Name of an environment variable that can be used to override the location from which default configur...
const char * project_dirname
Name of the project that is used in the "libexec" prefix, For example, "gnunet".
const char * user_config_file
Configuration file name to use (if $XDG_CONFIG_HOME is not set).
const char * config_file
Configuration file name (in $XDG_CONFIG_HOME) to use.
Time for relative time used by GNUnet, in microseconds.