38{
43
48
53
58};
59
60
65{
70
75
80
85};
86
87
92{
97
102
107
115
120
125
130
135};
136
138{
143
148
150
152
158
163
168
173};
174
175
180{
185
190
195
200
205
210
217
222
227
234};
235
236
242{
244
246};
247
248
249void
252{
254}
255
256
259{
262
265
266
270 {
272 "PATHS",
273 "DATADIR",
276 }
280 {
282 "PATHS",
283 "LIBDIR",
286 }
290 {
292 "PATHS",
293 "BINDIR",
296 }
300 {
302 "PATHS",
303 "PREFIX",
306 }
310 {
312 "PATHS",
313 "LOCALEDIR",
316 }
320 {
322 "PATHS",
323 "ICONDIR",
326 }
330 {
332 "PATHS",
333 "DOCDIR",
336 }
340 {
342 "PATHS",
343 "LIBEXECDIR",
346 }
348}
349
350
351void
353{
356
360 {
365 cf);
367 }
370}
371
372
377 void *cb_cls)
378{
381
386 {
390 }
395}
396
397
402{
407
412};
413
414
427{
429
434}
435
436
446 const char *section)
447{
449
451 return NULL;
453 while ( (NULL != pos) &&
454 (0 != strcasecmp (section,
457 return pos;
458}
459
460
461static int
463 const void *b)
464{
465 return strcmp (*((const char **) a),
466 *((const char **) b));
467}
468
469
470static void
472 const char *section,
474
475
483 const char *path_or_glob,
484 bool path_is_glob,
485 const char *restrict_section,
486 const char *source_filename,
487 unsigned int source_lineno)
488{
489 char *inline_path = NULL;
493 .files_length = 0,
494 };
497
498
499 GNUNET_assert (! (path_is_glob && (NULL != restrict_section)));
500
501 if (NULL == source_filename)
502 {
504 "Refusing to parse inline configurations, "
505 "not allowed without source filename!\n");
508 }
509
510 if ('/' == *path_or_glob)
512 else
513 {
514
515
516
517 char *source_realpath;
518 char *endsep;
519
520 source_realpath = realpath (source_filename,
521 NULL);
522 if (NULL == source_realpath)
523 {
524
526
529 }
530 endsep = strrchr (source_realpath, '/');
532 *endsep = '\0';
534 "%s/%s",
535 source_realpath,
536 path_or_glob);
537 free (source_realpath);
538 }
539
540 if (path_is_glob)
541 {
542 int nret;
543
545 "processing config glob '%s'\n",
546 inline_path);
547
550 &igc);
551 if (-1 == nret)
552 {
555 }
559 sizeof (char *),
561 for (int i = 0; i < nret; i++)
562 {
566 {
569 }
570 }
572 }
573 else if (NULL != restrict_section)
574 {
578
580
582
583 if (NULL == cs)
584 {
590 }
592 {
593 const char *pwname;
594 const char *grname;
596 struct stat istat;
597
599 if (0 == stat (sfn, &istat))
600 {
601 struct passwd *pw = getpwuid (istat.st_uid);
602 struct group *gr = getgrgid (istat.st_gid);
603 pwname = (NULL == pw) ? "<unknown>" : pw->pw_name;
604 grname = (NULL == gr) ? "<unknown>" : gr->gr_name;
605
607 "%s:%s %o",
608 pwname,
609 grname,
610 istat.st_mode);
611 }
612 else
613 {
615 }
616 if (source_filename)
617 {
618
622 }
623 }
624
625
626 {
632 cf);
633 }
634
636 {
639
642 }
643
649 inline_path);
651 {
653 fun_ret = inner_ret;
655 }
656
658 restrict_section);
659 if (NULL == cs)
660 {
662 "Configuration file '%s' loaded with @inline-secret@ "
663 "does not contain section '%s'.\n",
664 inline_path,
665 restrict_section);
666
667
668
671 }
673 NULL != ce;
674 ce = ce->next)
676 restrict_section,
677 ce);
679 }
682 inline_path))
683 {
686 }
687 else
688 {
690 }
693 if (NULL != other_cfg)
697 {
701 }
702 return fun_ret;
703}
704
705
716 const char *section,
718{
720
722 section)))
723 return NULL;
725 pos != NULL;
727 if (0 == strcasecmp (
key,
728 pos->key))
729 return pos;
731 {
733 "Section '%s' is marked as inaccessible, because the configuration "
734 "file that contains the section can't be read. Attempts to use "
735 "option '%s' will fail.\n",
736 section,
738 return NULL;
739 }
740 return NULL;
741}
742
743
754static void
756 const char *section,
757 const char *option,
761{
764
766 return;
768 section,
769 option);
770 if (NULL == e)
771 return;
778}
779
780
789static void
791 const char *section,
793{
797
799 section,
804 return;
806 section,
810 NULL != pos;
812 {
814
817 copy->
lineno = pos->lineno;
818 if (NULL == tail)
819 head = copy;
820 else
822 tail = copy;
823 }
826}
827
828
831 const char *mem,
833 const char *source_filename)
834{
835 size_t line_size;
836 unsigned int nr;
837 size_t r_bytes;
838 size_t to_read;
840 char *section;
841 char *eq;
842 char *tag;
844 char *line_orig = NULL;
845
847 section = NULL;
848 nr = 0;
849 r_bytes = 0;
850 while (r_bytes <
size)
851 {
852 const char *pos;
854 bool emptyline;
855
857
858 to_read =
size - r_bytes;
859 pos = memchr (&mem[r_bytes], '\n', to_read);
860 if (NULL == pos)
861 {
863 line_size = to_read);
864 r_bytes += line_size;
865 }
866 else
867 {
869 line_size = (pos - &mem[r_bytes]));
870 r_bytes += line_size + 1;
871 }
873
874 nr++;
875
877 for (size_t i = 0; i < line_size; i++)
878 {
885 }
886
888 continue;
889
890
891 for (size_t i = line_size - 1;
892 (i >= 1) && (isspace ((
unsigned char)
line[i]));
893 i--)
895
896
897 for (;
line[0] !=
'\0' && (isspace ((
unsigned char)
line[0]));
line++)
898 ;
899
900
901 if ( (
'#' ==
line[0]) ||
903 continue;
904
905
907 {
908 char *
end = strchr (
line + 1,
'@');
909 char *directive;
911
913 {
915 "Illegal directive in line %u (parsing restricted section %s)\n",
916 nr,
919 break;
920 }
921
923 {
925 "Bad directive in line %u\n",
926 nr);
928 break;
929 }
931 directive =
line + 1;
932
933 if (0 == strcasecmp (directive,
934 "INLINE"))
935 {
936 const char *path =
end + 1;
937
938
939 for (; isspace (*path); path++)
940 ;
941
943 path,
944 false,
945 NULL,
946 source_filename,
947 nr);
948 }
949 else if (0 == strcasecmp (directive,
950 "INLINE-MATCHING"))
951 {
952 const char *path =
end + 1;
953
954
955 for (; isspace (*path); path++)
956 ;
957
959 path,
960 true,
961 NULL,
962 source_filename,
963 nr);
964 }
965 else if (0 == strcasecmp (directive,
966 "INLINE-SECRET"))
967 {
968 char *secname =
end + 1;
969 char *secname_end;
970 const char *path;
971
972
973 for (; isspace (*secname); secname++)
974 ;
975
976 secname_end = strchr (secname, ' ');
977
978 if (NULL == secname_end)
979 {
981 "Bad inline-secret directive in line %u\n",
982 nr);
984 break;
985 }
986 *secname_end = '\0';
987 path = secname_end + 1;
988
989
990 for (; isspace (*path); path++)
991 ;
992
994 path,
995 false,
996 secname,
997 source_filename,
998 nr);
999 }
1000 else
1001 {
1003 "Unknown or malformed directive '%s' in line %u\n",
1004 directive,
1005 nr);
1007 break;
1008 }
1010 {
1011 ret = directive_ret;
1012 break;
1013 }
1014 continue;
1015 }
1016 if ( (
'[' ==
line[0]) &&
1017 (
']' ==
line[line_size - 1]) )
1018 {
1019
1020 line[line_size - 1] =
'\0';
1024 continue;
1025 }
1026 if (NULL != (eq = strchr (
line,
'=')))
1027 {
1028
1029 if (NULL == section)
1030 {
1032 "Syntax error while deserializing in line %u (option without section)\n",
1033 nr);
1035 break;
1036 }
1037
1038
1040
1041 for (int i = strlen (tag) - 1;
1042 (i >= 1) && (isspace ((unsigned char) tag[i]));
1043 i--)
1044 tag[i] = '\0';
1045
1046
1048 while (isspace ((
unsigned char)
value[0]))
1050 for (
int i = strlen (
value) - 1;
1051 (i >= 1) && (isspace ((
unsigned char)
value[i]));
1052 i--)
1054
1055
1056 if ( (
'"' ==
value[0]) &&
1058 {
1061 }
1063 section,
1064 tag,
1067 {
1069 section,
1070 tag,
1072 source_filename
1073 ? source_filename
1074 : "<input>",
1075 nr);
1076 }
1078 continue;
1079 }
1080
1082 "Syntax error while deserializing in line %u\n",
1083 nr);
1085 break;
1086 }
1090 (r_bytes ==
size) );
1092}
1093
1094
1098{
1100 uint64_t fs64;
1102 char *fn;
1103 char *mem;
1104 int dirty;
1106 ssize_t sret;
1107
1110 "Asked to parse config file `%s'\n",
1111 fn);
1112 if (NULL == fn)
1114
1115
1116
1117 {
1121
1122
1123 for (; NULL != cf; parent = cf, cf = cf->
prev)
1124 {
1125
1126 if (cf->level >= lvl)
1127 continue;
1129 if ( (NULL == cf->source_filename) ||
1131 continue;
1132 if (0 == strcmp (cf->source_filename,
1134 {
1135 if (NULL == parent)
1136 {
1138 "Forbidden direct cyclic configuration import (%s -> %s)\n",
1139 cf->source_filename,
1141 }
1142 else
1144 "Forbidden indirect cyclic configuration import (%s -> ... -> %s -> %s)\n",
1145 cf->source_filename,
1150 }
1151 }
1152
1153 }
1154
1155
1156 {
1158
1162 : "<input>");
1165 loaded_file);
1166 }
1167
1171 &fs64,
1174 {
1176 "Error while determining the file size of `%s'\n",
1177 fn);
1180 }
1182 {
1186 }
1190 mem,
1192 if ((sret < 0) || (
fs != (
size_t) sret))
1193 {
1195 "Error while reading file `%s'\n",
1196 fn);
1200 }
1202 {
1206 }
1208 "Deserializing contents of file `%s'\n",
1209 fn);
1211 mem,
1213 fn);
1215 {
1217 _ (
"Failed to parse configuration file `%s'\n"),
1218 fn);
1219 }
1221 {
1223 }
1226
1227
1230}
1231
1232
1235{
1237}
1238
1239
1247static bool
1250{
1251 if (0 != strcasecmp ("PATHS",
1252 sec))
1253 return false;
1254 return ( (0 == strcasecmp ("DATADIR",
1256 (0 == strcasecmp ("LIBDIR",
1258 (0 == strcasecmp ("BINDIR",
1260 (0 == strcasecmp ("PREFIX",
1262 (0 == strcasecmp ("LOCALEDIR",
1264 (0 == strcasecmp ("ICONDIR",
1266 (0 == strcasecmp ("DOCDIR",
1268 (0 == strcasecmp ("DEFAULTCONFIG",
1270 (0 == strcasecmp ("LIBEXECDIR",
1272}
1273
1274
1275char *
1278{
1279 char *mem;
1280 char *cbuf;
1281 char *val;
1282 char *pos;
1283 size_t m_size;
1284 size_t c_size;
1285
1286
1287 m_size = 0;
1289 NULL != sec;
1290 sec = sec->next)
1291 {
1292 if (sec->inaccessible && (NULL == sec->entries))
1293 continue;
1294
1295 m_size += strlen (sec->name) + 3;
1297 NULL != ent;
1298 ent = ent->next)
1299 {
1301 ent->key))
1302 continue;
1303 if (NULL != ent->val)
1304 {
1305
1306 pos = ent->val;
1307 while (NULL != (pos = strstr (pos, "\n")))
1308 {
1309 m_size++;
1310 pos++;
1311 }
1312
1313
1314 m_size += strlen (ent->key) + strlen (ent->val) + 4;
1315 }
1316 }
1317
1318 m_size++;
1319 }
1320
1321
1323 c_size = 0;
1326 NULL != sec;
1327 sec = sec->next)
1328 {
1329 int len;
1330
1332 "[%s]\n",
1333 sec->name);
1336 cbuf,
1337 len);
1338 c_size += len;
1341 NULL != ent;
1342 ent = ent->next)
1343 {
1345 ent->key))
1346 continue;
1347 if (NULL != ent->val)
1348 {
1350 strcpy (val, ent->val);
1351 while (NULL != (pos = strstr (val, "\n")))
1352 {
1353 memmove (&pos[2], &pos[1], strlen (&pos[1]));
1354 pos[0] = '\\';
1355 pos[1] = 'n';
1356 }
1360 c_size += len;
1362 }
1363 }
1365 c_size++;
1366 }
1369 return mem;
1370}
1371
1372
1381static void
1386{
1388 ipk);
1389 const char *ipkname;
1390 switch (ipk)
1391 {
1393 ipkname = "IPK_DATADIR";
1394 break;
1396 ipkname = "IPK_BINDIR";
1397 break;
1399 ipkname = "IPK_LIBDIR";
1400 break;
1402 ipkname = "IPK_PREFIX";
1404 ipkname = "IPK_LOCALEDIR";
1405 break;
1407 ipkname = "IPK_ICONDIR";
1409 ipkname = "IPK_DOCDIR";
1410 break;
1412 ipkname = "IPK_LIBEXECDIR";
1413 break;
1415 ipkname = "IPK_SELF_PREFIX";
1416 break;
1417 default:
1418 ipkname = "??";
1419 break;
1420 }
1422 "# %s = %s\n",
1423 ipkname,
1424 v);
1426}
1427
1428
1436static char *
1439{
1441
1443 "#\n# Configuration file diagnostics\n#\n");
1445 "# Entry point: %s\n",
1447 "<none>");
1449 "#\n# Files Loaded:\n");
1450
1452 NULL != cfil;
1453 cfil = cfil->next)
1454 {
1456 "# ");
1457 for (unsigned int i = 0; i < cfil->level; i++)
1459 "+");
1460 if (0 != cfil->level)
1462 " ");
1463
1465 "%s",
1466 cfil->source_filename);
1467
1468 if (NULL != cfil->hint_restrict_section)
1470 " (%s secret section %s)",
1471 cfil->hint_inaccessible
1472 ? "inaccessible"
1473 : "loaded",
1474 cfil->hint_restrict_section);
1475
1477 "\n");
1478 }
1479
1481 "#\n# Installation paths:\n");
1482
1492
1493
1495 "#\n\n");
1496
1498 NULL != sec;
1499 sec = sec->next)
1500 {
1501 if (sec->hint_secret_filename)
1503 "# secret section from %s\n# secret file stat %s\n",
1504 sec->hint_secret_filename,
1505 sec->hint_secret_stat);
1506 if (sec->hint_inlined_from_filename)
1507 {
1509 "# inlined from %s:%u\n",
1510 sec->hint_inlined_from_filename,
1511 sec->hint_inlined_from_line);
1512 }
1514 "[%s]\n\n",
1515 sec->name);
1516 if (sec->inaccessible && (NULL == sec->entries))
1517 {
1519 "# <section contents inaccessible>\n\n\n");
1520 continue;
1521 }
1523 NULL != ent;
1524 ent = ent->next)
1525 {
1527 ent->key))
1528 continue;
1529 if (NULL != ent->val)
1530 {
1531 char *pos;
1533 strcpy (val, ent->val);
1534 while (NULL != (pos = strstr (val, "\n")))
1535 {
1536 memmove (&pos[2], &pos[1], strlen (&pos[1]));
1537 pos[0] = '\\';
1538 pos[1] = 'n';
1539 }
1540 if (NULL != ent->sources)
1541 {
1543 (NULL != ent->sources->next))
1544 {
1546 &buf,
1547 "# duplicate definitions (highest precedence first):\n");
1551 {
1553
1554 if (
source == ent->sources)
1556 else if (0 == strcmp (
source->value,
1557 ent->val))
1559 else
1560 status =
"different value";
1562 &buf,
1563 "# %s:%u (%s)\n",
1567 }
1568 }
1569 else
1570 {
1572 "# %s:%u\n",
1573 ent->sources->filename,
1574 ent->sources->lineno);
1575 }
1576 }
1578 "%s = %s\n",
1579 ent->key,
1580 val);
1582 }
1584 }
1585 if (sec->inaccessible)
1586 {
1588 "# <additional section contents inaccessible>\n\n\n");
1589 continue;
1590 }
1591
1593 }
1595}
1596
1597
1598char *
1601{
1603 false);
1604}
1605
1606
1607char *
1610{
1612 true);
1613}
1614
1615
1618 char **contents,
1620{
1621 uint64_t fs64;
1623
1626 &fs64,
1631 *
size = (size_t) fs64;
1634 *contents,
1637 {
1639 *contents = NULL;
1641 }
1643}
1644
1645
1653static bool
1656{
1658 char *contents;
1660
1662 &contents,
1664 return false;
1667 &actual);
1670 expected);
1671}
1672
1673
1685 const char *contents,
1688{
1689 char *fn;
1690 char *tfn;
1691
1693 if (fn == NULL)
1696 {
1699 }
1700 {
1701
1702
1703 char *rfn = realpath (fn,
1704 NULL);
1705
1706 if (NULL != rfn)
1707 {
1710 free (rfn);
1711 }
1712 }
1713
1714
1715
1716
1717
1718
1720 "%s.%u.tmp",
1721 fn,
1722 (unsigned int) getpid ());
1723 {
1725
1735 {
1739 }
1740 if (((ssize_t)
size) !=
1742 contents,
1744 {
1746 "write",
1747 tfn);
1749 (void) unlink (tfn);
1753 }
1754
1755
1757 {
1759 "fsync",
1760 tfn);
1762 (void) unlink (tfn);
1766 }
1768 {
1770 "close",
1771 tfn);
1772 (void) unlink (tfn);
1776 }
1777 }
1778 {
1779 struct stat sbuf;
1780
1781
1782
1783 if ( (0 == stat (fn,
1784 &sbuf)) &&
1785 (0 != chmod (tfn,
1786 sbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))) )
1788 "chmod",
1789 tfn);
1790 }
1791 if ( (NULL != expected_hash) &&
1793 expected_hash)) )
1794 {
1796 "Configuration file `%s' changed while it was being cleaned\n",
1797 fn);
1798 (void) unlink (tfn);
1802 }
1803 if (0 != rename (tfn,
1804 fn))
1805 {
1807 "rename",
1808 fn);
1809 (void) unlink (tfn);
1813 }
1817}
1818
1819
1824{
1826 char *cfg_buf;
1828
1832 cfg_buf,
1834 NULL);
1838}
1839
1840
1845{
1849 bool remove;
1850};
1851
1852
1858 unsigned int lines_length,
1860{
1861 for (unsigned int i = 0; i < lines_length; i++)
1863 return &lines[i];
1864 return NULL;
1865}
1866
1867
1871static bool
1873 const char *target,
1875 unsigned int lines_length)
1876{
1878
1879 if (0 != strcmp (
source->filename,
1880 target))
1881 return false;
1883 lines_length,
1885 return (NULL !=
line) &&
line->remove;
1886}
1887
1888
1892static int
1894 const void *b)
1895{
1898
1900 return -1;
1902 return 1;
1903 return 0;
1904}
1905
1906
1912 void *cb_cls,
1913 unsigned int *removed)
1914{
1916 unsigned int lines_length = 0;
1918 char *target;
1919 char *contents = NULL;
1920 char *cleaned = NULL;
1922 size_t cleaned_size = 0;
1924
1925 if (NULL != removed)
1926 *removed = 0;
1931 if (NULL == target)
1933
1935 NULL != cf;
1936 cf = cf->next)
1937 {
1939
1940 if (! cf->have_content_hash)
1941 continue;
1945 target)) )
1946 parsed_file = cf;
1948 }
1949 if (NULL == parsed_file)
1950 {
1952 "Configuration file `%s' was not parsed with diagnostics enabled\n",
1953 target);
1955 }
1957 &contents,
1959 {
1961 "Configuration file `%s' changed since it was parsed\n",
1962 target);
1964 }
1965 {
1967
1970 &actual);
1973 {
1975 "Configuration file `%s' changed since it was parsed\n",
1976 target);
1978 }
1979 }
1980
1981
1982
1984 NULL != sec;
1985 sec = sec->next)
1986 for (
const struct ConfigEntry *ent = sec->entries;
1987 NULL != ent;
1988 ent = ent->next)
1992 {
1993 bool duplicate = false;
1995
1996 if (0 != strcmp (
source->filename,
1997 target))
1998 continue;
2000 NULL != other;
2001 other = other->next)
2002 {
2003 if ( (0 == strcmp (
source->value,
2004 other->value)) &&
2005 ( (
source->lineno != other->lineno) ||
2006 (0 != strcmp (
source->filename,
2007 other->filename)) ) )
2008 {
2009 duplicate = true;
2010 break;
2011 }
2012 }
2013 if ( (! duplicate) ||
2015 lines_length,
2017 continue;
2019 line.option = ent->key;
2023 lines_length,
2025 }
2026
2027
2028
2030 NULL != sec;
2031 sec = sec->next)
2032 for (
const struct ConfigEntry *ent = sec->entries;
2033 NULL != ent;
2034 ent = ent->next)
2035 {
2037
2042 target,
2043 lines,
2044 lines_length))
2045 {
2047 break;
2048 }
2049 if ( (NULL != survivor) &&
2050 (0 == strcmp (survivor->
value,
2051 ent->val)) )
2052 continue;
2056 {
2058
2059 if ( (0 != strcmp (
source->filename,
2060 target)) ||
2061 (0 != strcmp (
source->value,
2062 ent->val)) )
2063 continue;
2065 lines_length,
2067 if ( (NULL !=
line) &&
line->remove)
2068 {
2069 line->remove =
false;
2070 break;
2071 }
2072 }
2073 }
2074
2075 if (lines_length > 1)
2076 qsort (lines,
2077 lines_length,
2078 sizeof (*lines),
2080 {
2081 unsigned int remove_count = 0;
2082
2083 for (unsigned int i = 0; i < lines_length; i++)
2084 if (lines[i].remove)
2085 remove_count++;
2086 if (0 == remove_count)
2087 {
2088 if (NULL != removed)
2089 *removed = 0;
2092 }
2093
2095 for (
size_t offset = 0, line_number = 1; offset <
size; line_number++)
2096 {
2097 size_t end = offset;
2099
2100 while ( (
end <
size) && (
'\n' != contents[
end]) )
2105 lines_length,
2106 (unsigned int) line_number);
2107 if ( (NULL ==
line) || (!
line->remove) )
2108 {
2110 &contents[offset],
2112 cleaned_size +=
end - offset;
2113 }
2115 }
2118 cleaned,
2119 cleaned_size,
2122 if (NULL != removed)
2123 *removed = remove_count;
2124 if (NULL != cb)
2125 for (unsigned int i = 0; i < lines_length; i++)
2126 if (lines[i].remove)
2127 cb (cb_cls,
2132 }
2133
2138 lines_length,
2139 0);
2142}
2143
2144
2145void
2149 void *iter_cls)
2150{
2152 NULL != spos;
2153 spos = spos->next)
2155 NULL != epos;
2156 epos = epos->next)
2157 if (NULL != epos->val)
2158 iter (iter_cls,
2159 spos->name,
2160 epos->key,
2161 epos->val);
2162}
2163
2164
2165void
2170 void *iter_cls)
2171{
2173
2175 while ((spos != NULL) && (0 != strcasecmp (spos->
name, section)))
2177 if (NULL == spos)
2178 return;
2180 NULL != epos;
2181 epos = epos->next)
2182 if (NULL != epos->val)
2183 iter (iter_cls,
2185 epos->key,
2186 epos->val);
2188 {
2190 "Section '%s' is marked as inaccessible, because a configuration "
2191 "file that contains the section can't be read.\n",
2192 section);
2193 return;
2194 }
2195}
2196
2197
2198void
2202 void *iter_cls)
2203{
2206
2208 while (NULL !=
next)
2209 {
2213 continue;
2214 iter (iter_cls,
2216 }
2217}
2218
2219
2220void
2222 const char *section)
2223{
2227
2228 prev = NULL;
2230 while (NULL != spos)
2231 {
2232 if (0 == strcasecmp (section,
2234 {
2235 if (NULL == prev)
2237 else
2239 while (NULL != (ent = spos->
entries))
2240 {
2242
2247 {
2252 }
2255 }
2261 return;
2262 }
2263 prev = spos;
2265 }
2266}
2267
2268
2278static void
2280 const char *section,
2281 const char *option,
2283{
2285
2287 section,
2288 option,
2290}
2291
2292
2296{
2298
2304}
2305
2306
2317static void
2319 const char *section,
2320 const char *option,
2322{
2325
2327 if ((NULL != entNew) && (NULL != entNew->
val) &&
2328 (0 == strcmp (entNew->
val,
value)))
2329 return;
2331 section,
2332 option,
2334}
2335
2336
2341{
2343
2349 &diffHandle);
2350 return diffHandle.cfgDiff;
2351}
2352
2353
2359{
2362
2367}
2368
2369
2370void
2373 const char *section,
2374 const char *option,
2376{
2379 char *nv;
2380
2382 if (NULL != e)
2383 {
2385 {
2388 }
2389 else
2390 {
2394 }
2395 return;
2396 }
2398 if (sec == NULL)
2399 {
2404 }
2410}
2411
2412
2413void
2415 const char *section,
2416 const char *option,
2417 unsigned long long number)
2418{
2419 char s[64];
2420
2422 64,
2423 "%llu",
2426 section,
2427 option,
2428 s);
2429}
2430
2431
2435 const char *section,
2436 const char *option,
2437 unsigned long long *
number)
2438{
2441
2443 section,
2444 option)))
2448 if (1 != sscanf (e->
val,
2449 "%llu%1s",
2454}
2455
2456
2457void
2459 const char *section,
2460 const char *option,
2462{
2463 char s[64];
2464
2465
2466 const locale_t cl = newlocale (LC_NUMERIC_MASK,
2467 "C",
2468 (locale_t) 0);
2469 locale_t old_locale = uselocale (cl);
2471 64,
2472 "%f",
2474 uselocale (old_locale);
2476 section,
2477 option,
2478 s);
2479}
2480
2481
2485 const char *section,
2486 const char *option,
2488{
2491
2493 section,
2494 option)))
2498
2499 {
2500 const locale_t cl = newlocale (LC_NUMERIC_MASK,
2501 "C",
2502 (locale_t) 0);
2503 locale_t old_locale = uselocale (cl);
2504
2505 if (1 != sscanf (e->
val,
2506 "%f%1s",
2510 uselocale (old_locale);
2511 }
2513}
2514
2515
2519 const char *section,
2520 const char *option,
2522{
2525
2527 section,
2528 option)))
2533 time);
2536 section,
2537 option,
2538 _ (
"Not a valid relative time specification"));
2540}
2541
2542
2546 const char *section,
2547 const char *option,
2548 unsigned long long *
size)
2549{
2551
2553 section,
2554 option)))
2560}
2561
2562
2576 const char *section,
2577 const char *option,
2579{
2581
2583 section,
2584 option))) ||
2586 {
2589 }
2592}
2593
2594
2598 const char *section,
2599 const char *option,
2600 const char *const *choices,
2602{
2604 unsigned int i;
2605
2607 section,
2608 option)))
2610 for (i = 0; NULL !=
choices[i]; i++)
2611 if (0 == strcasecmp (choices[i], e->
val))
2612 break;
2613 if (NULL == choices[i])
2614 {
2616 _ (
"Configuration value '%s' for '%s'"
2617 " in section '%s' is not in set of legal choices\n"),
2619 option,
2620 section);
2622 }
2625}
2626
2627
2630 const char *section,
2631 const char *option,
2632 void *buf,
2633 size_t buf_size)
2634{
2638
2642 section,
2643 option,
2648 {
2651 }
2655 buf,
2656 buf_size))
2657 {
2660 }
2663}
2664
2665
2668 const char *section,
2669 const char *option)
2670{
2672
2674 section,
2675 option))) ||
2679}
2680
2681
2697static char *
2699 char *orig,
2700 unsigned int depth)
2701{
2705 const char *post;
2707 char *def;
2709 unsigned int lopen;
2710 char erased_char;
2711 char *erased_pos;
2712 size_t len;
2713
2714 if (NULL == orig)
2715 return NULL;
2716 if (depth > 128)
2717 {
2719 "Recursive expansion suspected, aborting $-expansion for term `%s'\n",
2720 orig);
2721 return orig;
2722 }
2724 "Asked to $-expand %s\n",
2725 orig);
2726 if ('$' != orig[0])
2727 {
2729 "Doesn't start with $ - not expanding\n");
2730 return orig;
2731 }
2732 erased_char = 0;
2733 erased_pos = NULL;
2734 if ('{' == orig[1])
2735 {
2737 lopen = 1;
2739 while (lopen > 0)
2740 {
2743 {
2744 case '}':
2745 lopen--;
2746 break;
2747
2748 case '{':
2749 lopen++;
2750 break;
2751
2752 case '\0':
2754 "Missing closing `}' in option `%s'\n",
2755 orig);
2756 return orig;
2757
2758 default:
2759 break;
2760 }
2761 }
2766 def = strchr (orig, ':');
2767 if (NULL != def)
2768 {
2769 *def = '\0';
2770 def++;
2771 if (('-' == *def) || ('=' == *def))
2772 def++;
2774 }
2775 }
2776 else
2777 {
2778 int i;
2779
2781 def = NULL;
2782 i = 0;
2783 while ( (orig[i] != '/') &&
2784 (orig[i] != '\\') &&
2785 (orig[i] != '\0') &&
2786 (orig[i] != ' ') )
2787 i++;
2788 if (orig[i] == '\0')
2789 {
2790 post = "";
2791 }
2792 else
2793 {
2794 erased_char = orig[i];
2795 erased_pos = &orig[i];
2796 orig[i] = '\0';
2797 post = &orig[i + 1];
2798 }
2799 }
2801 "Split into `%s' and `%s' with default %s\n",
2803 post,
2804 def);
2807 "PATHS",
2810 {
2812 {
2813
2815 def,
2816 depth + 1);
2818 }
2820 {
2822 if (erased_pos)
2823 *erased_pos = erased_char;
2825 "Failed to expand `%s' in `%s' as it is neither found in [PATHS] nor defined as an environmental variable\n",
2827 orig);
2829 return orig;
2830 }
2832 }
2835 if ((erased_pos) && ('}' != erased_char))
2836 {
2837 len = strlen (
prefix) + 1;
2839 prefix[len - 1] = erased_char;
2841 }
2849}
2850
2851
2852char *
2855 char *orig)
2856{
2857 char *dup;
2858 size_t i;
2859 size_t len;
2860
2861 for (i = 0; '\0' != orig[i]; i++)
2862 {
2863 if ('$' != orig[i])
2864 continue;
2868 len = strlen (dup) + 1;
2872 }
2873 return orig;
2874}
2875
2876
2880 const char *section,
2881 const char *option,
2883{
2884 char *tmp;
2886
2888 section,
2889 option,
2890 &tmp);
2892 {
2894 "Failed to retrieve filename\n");
2897 }
2899 tmp);
2905}
2906
2907
2911 const char *section,
2912 const char *option)
2913{
2914 static const char *yesno[] = {
2915 "YES",
2916 "NO",
2917 NULL
2918 };
2921
2924 section,
2925 option,
2926 yesno,
2930 if (
val == yesno[0])
2933}
2934
2935
2936int
2939 const char *section,
2940 const char *option,
2942 void *cb_cls)
2943{
2945 char *pos;
2947 char old;
2949
2952 section,
2953 option,
2955 return 0;
2959 while (1)
2960 {
2961 while (pos[0] == ' ')
2962 pos++;
2963 if (strlen (pos) == 0)
2964 break;
2966 while ((
end[0] !=
' ') && (
end[0] !=
'\0'))
2967 {
2969 {
2971 {
2972 case '\\':
2973 case ' ':
2974 memmove (
end, &
end[1], strlen (&
end[1]) + 1);
2975
2976 case '\0':
2977
2978 break;
2979
2980 default:
2981
2982 break;
2983 }
2984 }
2986 }
2989 if (strlen (pos) > 0)
2990 {
2992 if ( (NULL != cb) &&
2994 pos)))
2995 {
2997 break;
2998 }
2999 }
3000 if (old == '\0')
3001 break;
3003 }
3006}
3007
3008
3015static char *
3017{
3018 char *escaped;
3019 const char *rpos;
3020 char *wpos;
3021
3023 memset (escaped, 0, strlen (
value) * 2 + 1);
3025 wpos = escaped;
3026 while (rpos[0] != '\0')
3027 {
3028 switch (rpos[0])
3029 {
3030 case '\\':
3031 case ' ':
3032 wpos[0] = '\\';
3033 wpos[1] = rpos[0];
3034 wpos += 2;
3035 break;
3036
3037 default:
3038 wpos[0] = rpos[0];
3039 wpos++;
3040 }
3041 rpos++;
3042 }
3043 return escaped;
3044}
3045
3046
3056 const char *fn)
3057{
3058 const char *of = cls;
3059
3060 return (0 == strcmp (of, fn))
3063}
3064
3065
3069 const char *section,
3070 const char *option,
3072{
3073 char *escaped;
3074 char *old;
3075 char *nw;
3076
3079 section,
3080 option,
3089 strcpy (nw, old);
3090 if (strlen (old) > 0)
3091 strcat (nw, " ");
3092 strcat (nw, escaped);
3094 section,
3095 option,
3096 nw);
3101}
3102
3103
3107 const char *section,
3108 const char *option,
3110{
3112 char *pos;
3114 char *match;
3115 char old;
3116
3119 section,
3120 option,
3125 while (1)
3126 {
3127 while (pos[0] == ' ')
3128 pos++;
3129 if (strlen (pos) == 0)
3130 break;
3132 while ((
end[0] !=
' ') && (
end[0] !=
'\0'))
3133 {
3135 {
3137 {
3138 case '\\':
3139 case ' ':
3141 break;
3142
3143 case '\0':
3144
3145 break;
3146
3147 default:
3148
3149 break;
3150 }
3151 }
3153 }
3156 if (0 == strcmp (pos, match))
3157 {
3158 if (old != '\0')
3159 memmove (pos,
3161 strlen (&
end[1]) + 1);
3162 else
3163 {
3165 pos[-1] = '\0';
3166 else
3167 pos[0] = '\0';
3168 }
3170 section,
3171 option,
3176 }
3177 if (old == '\0')
3178 break;
3181 }
3185}
3186
3187
3191 const char *defaults_d)
3192{
3195 .files_length = 0,
3196 };
3198
3202 &files_context))
3204 qsort (files_context.
files,
3206 sizeof (char *),
3208 for (
unsigned int i = 0; i < files_context.
files_length; i++)
3209 {
3210 const char *ext;
3212
3213
3215 if ( (NULL == ext) ||
3216 (0 != strcmp (ext,
3217 ".conf")) )
3218 {
3220 "Skipping file `%s'\n",
3223 continue;
3224 }
3228 break;
3229 }
3231 {
3232 for (
size_t i = 0; i < files_context.
files_length; i++)
3236 0);
3237 }
3238 return fun_ret;
3239}
3240
3241
3242char *
3245{
3246 char *cfg_fn;
3247 const char *xdg =
getenv (
"XDG_CONFIG_HOME");
3248
3249 if (NULL != xdg)
3251 "%s%s%s",
3252 xdg,
3255 else
3257
3259 return cfg_fn;
3261
3262
3263
3264
3266 "/etc/%s",
3270 return cfg_fn;
3272
3274 "/etc/%s/%s",
3279 return cfg_fn;
3280
3282 return NULL;
3283}
3284
3285
3290{
3291 char *baseconfig;
3292 const char *base_config_varname;
3293
3295 {
3296
3299 }
3302 {
3305 }
3306
3308
3309 if ((NULL != base_config_varname)
3310 && (NULL != (baseconfig =
getenv (base_config_varname))))
3311 {
3313 }
3314 else
3315 {
3316 char *ipath;
3317
3320 if (NULL == ipath)
3321 {
3324 }
3326 "%s%s",
3327 ipath,
3328 "config.d");
3330 }
3331
3332 {
3334
3336
3342 dname)))
3343 {
3345 "Failed to load base configuration from '%s'\n",
3349 }
3351 }
3356 {
3357
3359 "Failed to load configuration from file '%s'\n",
3362 }
3365 "PATHS",
3366 "DEFAULTCONFIG"))) &&
3369 "PATHS",
3370 "DEFAULTCONFIG",
3373}
3374
3375
3384static void
3386 const char *section,
3387 const char *option,
3389{
3391
3392 char *value_fn;
3393 char *fn;
3394
3397 section,
3398 option,
3399 &value_fn));
3401 if (NULL == fn)
3402 fn = value_fn;
3403 else
3405 fprintf (stdout,
3406 "%s = %s\n",
3407 option,
3408 fn);
3410}
3411
3412
3421static void
3423 const char *section,
3424 const char *option,
3426{
3427 (void) cls;
3428 (void) section;
3429
3430 fprintf (stdout,
3431 "%s = %s\n",
3432 option,
3434}
3435
3436
3443static void
3445 const char *section)
3446{
3447 (void) cls;
3448 fprintf (stdout,
3449 "%s\n",
3450 section);
3451}
3452
3453
3454void
3456 void *cls,
3457 char *const *args,
3458 const char *cfgfile,
3460{
3464
3465 (void) args;
3468 {
3469
3474 cfgfile))
3475 {
3476 fprintf (stderr,
3477 _ (
"Failed to load config file `%s'"),
3478 cfgfile);
3479 return;
3480 }
3482 }
3483
3487 {
3488 fprintf (stderr,
3489 _ (
"The following sections are available:\n"));
3492 NULL);
3493 return;
3494 }
3497 {
3498 char *serialization;
3499
3501 {
3502 fprintf (stderr,
3503 _ (
"%s, %s or %s argument is required\n"),
3504 "--section",
3505 "--list-sections",
3506 "--diagnostics");
3508 return;
3509 }
3513 fprintf (stdout,
3514 "%s",
3515 serialization);
3517 }
3518 else if ( (NULL != cs->
section) &&
3519 (NULL == cs->
value) )
3520 {
3522 {
3530 }
3531 else
3532 {
3534
3536 {
3542 {
3547 return;
3548 }
3549 }
3550 else
3551 {
3557 {
3562 return;
3563 }
3564 }
3565 fprintf (stdout,
3566 "%s\n",
3569 }
3570 }
3572 {
3574 {
3575 fprintf (stderr,
3576 _ (
"--option argument required to set value\n"));
3578 return;
3579 }
3586 }
3588 {
3589 char *cfg_fn = NULL;
3590
3591 if (NULL == out)
3593
3594 if (NULL == cfgfile)
3595 {
3596 const char *xdg =
getenv (
"XDG_CONFIG_HOME");
3597
3598 if (NULL != xdg)
3600 "%s%s%s",
3601 xdg,
3604 else
3606 cfgfile = cfg_fn;
3607 }
3608
3610 {
3612
3616 NULL))
3617 {
3618 fprintf (stderr,
3619 _ (
"failed to load configuration defaults"));
3624 return;
3625 }
3628 out,
3629 cfgfile))
3632 }
3633 else
3634 {
3637 cfgfile))
3639 }
3641 }
3642 if (NULL != out)
3644 if (NULL != ncfg)
3646}
3647
3648
3649void
3652{
3656}
3657
3658
3662{
3664}
3665
3666
3667char *
3669 pd,
3670 const struct
3672 const char *progname)
3673{
3674 static char *cache;
3675 char *binary = NULL;
3676 char *path = NULL;
3677 size_t path_len;
3678
3682 NULL,
3683 NULL))
3684 {
3686 }
3687 if (NULL != cache)
3688 path = cache;
3689 else
3691 "PATHS",
3692 "SUID_BINARY_PATH",
3693 &path);
3694 if ( (NULL == path) ||
3695 (0 == strlen (path)) )
3696 {
3697 if (NULL != path)
3699 cache = NULL;
3701 progname);
3702 }
3703 path_len = strlen (path);
3705 "%s%s%s",
3706 path,
3709 progname);
3710 cache = path;
3711 return binary;
3712}
3713
3714
3715
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 bool source_is_removed(const struct ConfigSource *source, const char *target, struct CleanLine *lines, unsigned int lines_length)
Return whether a source is a target line currently marked for removal.
static struct CleanLine * find_clean_line(struct CleanLine *lines, unsigned int lines_length, unsigned int line)
Find a cleanup record for a physical line.
static int clean_line_cmp(const void *a, const void *b)
Sort cleanup records by source line.
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 enum GNUNET_GenericReturnValue read_file(const char *filename, char **contents, size_t *size)
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 void add_entry_source(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value, const char *filename, unsigned int line)
Record the source of a configuration value.
static char * serialize_diagnostics(const struct GNUNET_CONFIGURATION_Handle *cfg, bool verbose)
Serialize configuration diagnostics.
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 enum GNUNET_GenericReturnValue write_buffer_atomic(const char *filename, const char *contents, size_t size, const struct GNUNET_HashCode *expected_hash)
Atomically replace a file with the given bytes.
static void copy_entry_with_sources(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const struct ConfigEntry *entry)
Copy an entry parsed through an @inline-secret@ directive, including all diagnostic source informatio...
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 bool file_hash_matches(const char *filename, const struct GNUNET_HashCode *expected)
Check that a file still has the expected contents.
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 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).
static unsigned int verbose
Be verbose.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_FS_Handle * fs
Handle to FS service.
static GstElement * source
Appsrc instance into which we write data for the pipeline.
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 status
The program status; 0 for success.
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.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_clean_file(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename, GNUNET_CONFIGURATION_CleanCallback cb, void *cb_cls, unsigned int *removed)
Remove redundant option definitions from a parsed configuration file.
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.
char * GNUNET_CONFIGURATION_serialize_diagnostics_verbose(const struct GNUNET_CONFIGURATION_Handle *cfg)
Serializes the given configuration with verbose diagnostics information, including all source definit...
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.
void(* GNUNET_CONFIGURATION_CleanCallback)(void *cls, const char *section, const char *option, unsigned int line)
Function called for each duplicate definition removed by GNUNET_CONFIGURATION_clean_file().
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.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
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.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
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".
One physical assignment line considered for removal.
Closure to collect_files_cb.
char ** files
Collected files from globbing.
unsigned int files_length
Size of the files array.
struct ConfigEntry * next
This is a linked list.
char * key
key for this entry
struct ConfigSource * sources
Source definitions retained for diagnostics.
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?
bool have_content_hash
Whether content_hash is available.
unsigned int level
Level in the tree of loaded config files.
struct GNUNET_HashCode content_hash
Hash of the file contents seen while parsing.
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.
source location of a configuration value
char * value
Value as normalized by the configuration parser.
unsigned int lineno
Line containing the definition.
char * filename
Filename containing the definition.
struct ConfigSource * next
Sources are ordered from highest to lowest precedence.
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 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.
unsigned int diagnostics
Diagnostics verbosity.
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.