17
#define KEEPERS VAR"/lib/debfoster/keepers"
18
#define STATUSFILE VAR"/lib/dpkg/status"
19
#define AVAILABLEFILE VAR"/lib/dpkg/available"
20
#define CONFIG_FILE ETC"/debfoster.conf"
22
/* Only simple space-separated arguments can be given */
23
#define INSTALLCOMMAND "apt-get install"
24
#define REMOVECOMMAND "apt-get --purge remove"
25
#define INFOCOMMAND "dpkg -s"
27
/* Default policies for packages */
28
#define MAXPRIORITY "standard"
30
static AVLTree *options = NULL;
32
static void set_string(const char **holder, const char *val) {
33
if(*holder) free((char *)*holder);
34
*holder = xstrdup(val);
37
#define StringConfigVal(s) const char *s = NULL; \
38
static void set_##s(const char *str) { set_string(&s, str); }
40
static void set_bool(int *holder, const char *val) {
41
if(!strcasecmp(val, "y") || !strcasecmp(val, "yes")
42
|| !strcasecmp(val, "t") || !strcasecmp(val, "true")
43
|| !strcasecmp(val, "1") || !strcasecmp(val, "on"))
45
else if(!strcasecmp(val, "n") || !strcasecmp(val, "no")
46
|| !strcasecmp(val, "f") || !strcasecmp(val, "false")
47
|| !strcasecmp(val, "0") || !strcasecmp(val, "off"))
49
else error_exit(ERROR_CONFIG, _("Not a truth value: \"%s\"\n"), val);
52
#define BoolConfigVal(b) int b = 0; \
53
static void set_##b(const char *str) { set_bool(&b, str); }
55
StringConfigVal(KeeperFile)
56
StringConfigVal(DpkgStatus)
57
StringConfigVal(DpkgAvailable)
58
StringConfigVal(InstallCmd)
59
StringConfigVal(RemoveCmd)
60
StringConfigVal(InfoCmd)
61
StringConfigVal(MaxPriority)
62
StringConfigVal(KeepSections)
63
StringConfigVal(NokeepSections)
64
StringConfigVal(GuessDepends)
66
BoolConfigVal(UseHold)
67
BoolConfigVal(UseEssential)
68
BoolConfigVal(UsePreDepends)
69
BoolConfigVal(UseRecommends)
70
BoolConfigVal(UseSuggests)
71
BoolConfigVal(UseTasks)
73
BoolConfigVal(NegativeKeepers)
77
BoolConfigVal(Verbose)
79
static int optcmp(const option_t a, const option_t b) {
80
return strcasecmp(a->key, b->key);
83
option_t find_option(const char *key) {
89
c = AVLSearch(options, &o);
91
return c?c->item:NULL;
94
static void add_option(const char *key, void (*set)(const char *), const char *def) {
96
o = xmalloc(sizeof *o);
97
o->key = xstrdup(key);
100
if(!AVLInsert(options, o))
101
perror_exit(ERROR_CONFIG, key);
104
static void free_option(option_t opt) {
107
free((char *)opt->key);
112
void readconfig(const char *config) {
114
unsigned char buf[READBUF];
120
config = CONFIG_FILE;
123
AVLFreeNodes(options);
125
options = AVLAllocTree((AVLCompare)optcmp, (AVLFreeItem)free_option);
127
/* Seed tree with defaults for all options */
128
add_option("KeeperFile", set_KeeperFile, KEEPERS);
129
add_option("DpkgStatus", set_DpkgStatus, STATUSFILE);
130
add_option("DpkgAvailable", set_DpkgAvailable, AVAILABLEFILE);
131
add_option("InstallCmd", set_InstallCmd, INSTALLCOMMAND);
132
add_option("RemoveCmd", set_RemoveCmd, REMOVECOMMAND);
133
add_option("InfoCmd", set_InfoCmd, INFOCOMMAND);
134
add_option("MaxPriority", set_MaxPriority, MAXPRIORITY);
135
add_option("KeepSections", set_KeepSections, "");
136
add_option("NokeepSections", set_NokeepSections, "");
137
add_option("GuessDepends", set_GuessDepends, "");
139
add_option("UseHold", set_UseHold, "yes");
140
add_option("UseEssential", set_UseEssential, "yes");
141
add_option("UsePreDepends", set_UsePreDepends, "yes");
142
add_option("UseRecommends", set_UseRecommends, "yes");
143
add_option("UseSuggests", set_UseSuggests, "no");
144
add_option("UseTasks", set_UseTasks, "no");
146
add_option("NegativeKeepers", set_NegativeKeepers, "yes");
148
add_option("Quiet", set_Quiet, "no");
149
add_option("Force", set_Force, "no");
150
add_option("Verbose", set_Verbose, "no");
152
/* Read the options but fail if there's no default for it */
153
f = fopen(config, "r");
155
while(fgets(buf, READBUF, f)) {
158
if(*key && *key != '#') {
159
value = strchr(key, '=');
161
error_exit(ERROR_CONFIG, _("Syntax error in %s:%d\n"), CONFIG_FILE, lineno);
164
if(!(o = find_option(key)))
165
error_exit(ERROR_CONFIG, _("Unknown option `%s' at %s:%d\n"), key, CONFIG_FILE, lineno);