Add -fno-strict-aliasing to prevent compile warnings on some systems.
[polipo.git] / config.c
blob70a459119fa85068ffc8f41b852e2fd9f3280e8e
1 /*
2 Copyright (c) 2003-2006 by Juliusz Chroboczek
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
23 #include "polipo.h"
25 ConfigVariablePtr configVariables = NULL;
27 static ConfigVariablePtr
28 findConfigVariable(AtomPtr name)
30 ConfigVariablePtr var;
31 var = configVariables;
32 while(var != NULL) {
33 if(var->name == name)
34 break;
35 var = var->next;
37 return var;
40 void
41 declareConfigVariable(AtomPtr name, int type, void *value,
42 int (*setter)(ConfigVariablePtr, void*), char *help)
44 ConfigVariablePtr var, previous, next;
46 var = findConfigVariable(name);
48 if(var) {
49 do_log(L_ERROR,
50 "Configuration variable %s declared multiple times.\n",
51 name->string);
52 if(var->type != type) {
53 exit(1);
57 var = malloc(sizeof(ConfigVariableRec));
58 if(var == NULL) {
59 do_log(L_ERROR, "Couldn't allocate config variable.\n");
60 exit(1);
63 var->name = retainAtom(name);
64 var->type = type;
65 switch(type) {
66 case CONFIG_INT: case CONFIG_OCTAL: case CONFIG_HEX: case CONFIG_TIME:
67 case CONFIG_BOOLEAN: case CONFIG_TRISTATE: case CONFIG_TETRASTATE:
68 case CONFIG_PENTASTATE:
69 var->value.i = value; break;
70 case CONFIG_FLOAT: var->value.f = value; break;
71 case CONFIG_ATOM: case CONFIG_ATOM_LOWER: case CONFIG_PASSWORD:
72 var->value.a = value; break;
73 case CONFIG_INT_LIST:
74 var->value.il = value; break;
75 case CONFIG_ATOM_LIST: case CONFIG_ATOM_LIST_LOWER:
76 var->value.al = value; break;
77 default: abort();
79 var->setter = setter;
80 var->help = help;
82 previous = NULL;
83 next = configVariables;
84 while(next && strcmp(next->name->string, var->name->string) < 0) {
85 previous = next;
86 next = next->next;
88 if(next && strcmp(next->name->string, var->name->string) == 0) {
89 do_log(L_ERROR, "Variable %s declared multiple times.\n",
90 next->name->string);
91 abort();
93 if(previous == NULL) {
94 var->next = configVariables;
95 configVariables = var;
96 } else {
97 var->next = next;
98 previous->next = var;
102 static void
103 printString(FILE *out, char *string, int html)
105 if(html) {
106 char buf[512];
107 int i;
108 i = htmlString(buf, 0, 512, string, strlen(string));
109 if(i < 0) {
110 fprintf(out, "(overflow)");
111 return;
113 fwrite(buf, 1, i, out);
114 } else {
115 fprintf(out, "%s", string);
119 static void
120 printVariable(FILE *out, ConfigVariablePtr var, int html, int parseable)
122 int i;
124 switch(var->type) {
125 case CONFIG_INT: fprintf(out, "%d", *var->value.i); break;
126 case CONFIG_OCTAL: fprintf(out, "0%o", *var->value.i); break;
127 case CONFIG_HEX: fprintf(out, "0x%x", *var->value.i); break;
128 case CONFIG_TIME:
130 int v = *var->value.i;
131 if(v == 0) {
132 fprintf(out, "0s");
133 } else {
134 if(v >= 3600 * 24) fprintf(out, "%dd", v/(3600*24));
135 v = v % (3600 * 24);
136 if(v >= 3600) fprintf(out, "%dh", v / 3600);
137 v = v % 3600;
138 if(v >= 60) fprintf(out, "%dm", v / 60);
139 v = v % 60;
140 if(v > 0) fprintf(out, "%ds", v);
143 break;
144 case CONFIG_BOOLEAN:
145 switch(*var->value.i) {
146 case 0: fprintf(out, "false"); break;
147 case 1: fprintf(out, "true"); break;
148 default: fprintf(out, "???"); break;
150 break;
151 case CONFIG_TRISTATE:
152 switch(*var->value.i) {
153 case 0: fprintf(out, "false"); break;
154 case 1: fprintf(out, "maybe"); break;
155 case 2: fprintf(out, "true"); break;
156 default: fprintf(out, "???"); break;
158 break;
159 case CONFIG_TETRASTATE:
160 switch(*var->value.i) {
161 case 0: fprintf(out, "false"); break;
162 case 1: fprintf(out, "reluctantly"); break;
163 case 2: fprintf(out, "happily"); break;
164 case 3: fprintf(out, "true"); break;
165 default: fprintf(out, "???"); break;
167 break;
168 case CONFIG_PENTASTATE:
169 switch(*var->value.i) {
170 case 0: fprintf(out, "no"); break;
171 case 1: fprintf(out, "reluctantly"); break;
172 case 2: fprintf(out, "maybe"); break;
173 case 3: fprintf(out, "happily"); break;
174 case 4: fprintf(out, "true"); break;
175 default: fprintf(out, "???"); break;
177 break;
178 case CONFIG_FLOAT: fprintf(out, "%f", *var->value.f); break;
179 case CONFIG_ATOM: case CONFIG_ATOM_LOWER:
180 if(*var->value.a) {
181 if((*var->value.a)->length > 0) {
182 printString(out, (*var->value.a)->string, html);
183 } else {
184 if(!parseable)
185 fprintf(out, "(empty)");
187 } else {
188 if(!parseable)
189 fprintf(out, "(none)");
191 break;
192 case CONFIG_PASSWORD:
193 if(!parseable)
194 fprintf(out, "(hidden)");
195 break;
196 case CONFIG_INT_LIST:
197 if((*var->value.il) == NULL) {
198 if(!parseable)
199 fprintf(out, "(not set)");
200 } else if((*var->value.il)->length == 0) {
201 if(!parseable)
202 fprintf(out, "(empty list)");
203 } else {
204 for(i = 0; i < (*var->value.il)->length; i++) {
205 int from = (*var->value.il)->ranges[i].from;
206 int to = (*var->value.il)->ranges[i].to;
207 assert(from <= to);
208 if(from == to)
209 fprintf(out, "%d", from);
210 else
211 fprintf(out, "%d-%d", from, to);
212 if(i < (*var->value.il)->length - 1)
213 fprintf(out, ", ");
216 break;
217 case CONFIG_ATOM_LIST: case CONFIG_ATOM_LIST_LOWER:
218 if((*var->value.al) == NULL) {
219 if(!parseable)
220 fprintf(out, "(not set)");
221 } else if((*var->value.al)->length == 0) {
222 if(!parseable)
223 fprintf(out, "(empty list)");
224 } else {
225 for(i = 0; i < (*var->value.al)->length; i++) {
226 AtomPtr atom = (*var->value.al)->list[i];
227 if(atom) {
228 if(atom->length > 0)
229 printString(out, atom->string, html);
230 else {
231 if(!parseable)
232 fprintf(out, "(empty)");
234 } else {
235 if(!parseable)
236 fprintf(out, "(none)");
238 if(i < (*var->value.al)->length - 1)
239 fprintf(out, ", ");
242 break;
243 default: abort();
247 static void
248 printVariableForm(FILE *out, ConfigVariablePtr var)
250 char *disabled = "";
251 int i;
253 if(disableConfiguration || !var->setter) disabled = "disabled=true";
255 fprintf(out, "<form method=POST action=\"config?\">");
257 switch(var->type) {
258 case CONFIG_INT: case CONFIG_OCTAL: case CONFIG_HEX:
259 case CONFIG_TIME: case CONFIG_FLOAT: case CONFIG_ATOM:
260 case CONFIG_ATOM_LOWER: case CONFIG_PASSWORD:
261 case CONFIG_INT_LIST: case CONFIG_ATOM_LIST: case CONFIG_ATOM_LIST_LOWER:
262 fprintf(out, "<input value=\"");
263 printVariable(out, var, 1, 1);
264 fprintf(out, "\"%s size=14 name=%s %s>\n",
265 var->type == CONFIG_PASSWORD ? " type=password" : "",
266 var->name->string, disabled);
267 break;
269 case CONFIG_BOOLEAN:
271 static char *states[] = {"false", "true"};
273 fprintf(out, "<select name=%s %s>", var->name->string, disabled);
274 for(i=0; i < sizeof(states) / sizeof(states[0]); i++) {
275 if(*var->value.i == i) {
276 fprintf(out, "<option selected>%s</option>", states[i]);
277 } else {
278 fprintf(out, "<option>%s</option>", states[i]);
281 fprintf(out, "</select>");
282 if(var->setter)
283 fprintf(out, "<input type=\"submit\" value=\"set\"\n>");
284 break;
287 case CONFIG_TRISTATE:
289 static char *states[] = {"false", "maybe", "true"};
291 fprintf(out, "<select name=%s %s>", var->name->string, disabled);
292 for(i=0; i < sizeof(states) / sizeof(states[0]); i++) {
293 if(*var->value.i == i) {
294 fprintf(out, "<option selected>%s</option>", states[i]);
295 } else {
296 fprintf(out, "<option>%s</option>", states[i]);
299 fprintf(out, "</select>");
300 if(var->setter)
301 fprintf(out, "<input type=\"submit\" value=\"set\"\n>");
302 break;
305 case CONFIG_TETRASTATE:
307 static char *states[] =
308 {"false", "reluctantly", "happily", "true"};
310 fprintf(out, "<select name=%s %s>", var->name->string, disabled);
311 for(i=0; i <sizeof(states) / sizeof(states[0]); i++) {
312 if(*var->value.i == i) {
313 fprintf(out, "<option selected>%s</option>", states[i]);
314 } else {
315 fprintf(out, "<option>%s</option>", states[i]);
318 fprintf(out, "</select>");
319 if(var->setter)
320 fprintf(out, "<input type=\"submit\" value=\"set\"\n>");
321 break;
324 case CONFIG_PENTASTATE:
326 static char *states[] =
327 {"no", "reluctantly", "maybe", "happily", "true"};
329 fprintf(out, "<select name=%s %s>", var->name->string, disabled);
330 for(i=0; i < sizeof(states) / sizeof(states[0]); i++) {
331 if(*var->value.i == i) {
332 fprintf(out, "<option selected>%s</option>", states[i]);
333 } else {
334 fprintf(out, "<option>%s</option>", states[i]);
337 fprintf(out, "</select>");
338 if(var->setter)
339 fprintf(out,"<input type=\"submit\" value=\"set\"\n>");
340 break;
342 default: abort();
344 fprintf(out, "</form>");
351 void
352 printConfigVariables(FILE *out, int html)
354 ConfigVariablePtr var;
355 int entryno = 0;
357 #define PRINT_SEP() \
358 do {if(html) fprintf(out, "</td><td>"); else fprintf(out, " ");} while(0)
360 if(html) {
361 fprintf(out, "<table>\n");
362 fprintf(out, "<tbody>\n");
365 if(html) {
366 alternatingHttpStyle(out, "configlist");
367 fprintf(out,
368 "<table id=configlist>\n"
369 "<thead>\n"
370 "<tr><th>variable name</th>"
371 "<th>current value</th>"
372 "<th>new value</th>"
373 "<th>description</th>\n"
374 "</thead><tbody>\n"
378 /* configFile is not a config variable, for obvious bootstrapping reasons.
379 CHUNK_SIZE is hardwired for now. */
381 fprintf(out,
382 html ?
383 "<tr class=\"even\"><td>configFile</td><td>%s</td><td></td><td>"
384 "Configuration file.</td></tr>\n" :
385 "configFile %s Configuration file.\n",
386 configFile && configFile->length > 0 ?
387 configFile->string : "(none)");
388 fprintf(out,
389 html ?
390 "<tr class=\"odd\"><td>CHUNK_SIZE</td><td>%d</td><td></td><td>"
391 "Unit of chunk memory allocation.</td></tr>\n" :
392 "CHUNK_SIZE %d Unit of chunk memory allocation.\n", CHUNK_SIZE);
394 var = configVariables;
395 while(var != NULL) {
396 if(html) {
397 if(entryno % 2)
398 fprintf(out, "<tr class=odd>");
399 else
400 fprintf(out, "<tr class=even>");
401 fprintf(out, "<td>");
404 fprintf(out, "%s", var->name->string);
406 fprintf(out, html ? "<br/>" : " ");
408 fprintf(out, html ? "<i>" : "");
410 switch(var->type) {
411 case CONFIG_INT: case CONFIG_OCTAL: case CONFIG_HEX:
412 fprintf(out, "integer"); break;
413 case CONFIG_TIME: fprintf(out, "time"); break;
414 case CONFIG_BOOLEAN: fprintf(out, "boolean"); break;
415 case CONFIG_TRISTATE: fprintf(out, "tristate"); break;
416 case CONFIG_TETRASTATE: fprintf(out, "4-state"); break;
417 case CONFIG_PENTASTATE: fprintf(out, "5-state"); break;
418 case CONFIG_FLOAT: fprintf(out, "float"); break;
419 case CONFIG_ATOM: case CONFIG_ATOM_LOWER: case CONFIG_PASSWORD:
420 fprintf(out, "atom"); break;
421 case CONFIG_INT_LIST: fprintf(out, "intlist"); break;
422 case CONFIG_ATOM_LIST: case CONFIG_ATOM_LIST_LOWER:
423 fprintf(out, "list"); break;
424 default: abort();
427 fprintf(out, html ? "</i>" : "");
429 PRINT_SEP();
431 printVariable(out, var, html, 0);
433 PRINT_SEP();
435 if(html) {
436 printVariableForm(out, var);
437 PRINT_SEP();
440 fprintf(out, "%s", var->help?var->help:"");
441 if(html)
442 fprintf(out, "</td></tr>\n");
443 else
444 fprintf(out, "\n");
446 entryno++;
447 var = var->next;
449 if(html) {
450 fprintf(out, "</tbody>\n");
451 fprintf(out, "</table>\n");
453 return;
454 #undef PRINT_SEP
457 static int
458 skipWhitespace(char *buf, int i)
460 while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\r')
461 i++;
462 return i;
465 static struct config_state { char *name; int value; }
466 states[] =
467 { { "false", 0 },
468 { "no", 0 },
469 { "reluctantly", 1 },
470 { "seldom", 1 },
471 { "rarely", 1 },
472 { "lazily", 1 },
473 { "maybe", 2 },
474 { "perhaps", 2 },
475 { "happily", 3 },
476 { "often", 3 },
477 { "eagerly", 3 },
478 { "true", 4 },
479 { "yes", 4 } };
481 static int
482 parseState(char *buf, int offset, int kind)
484 int i = offset;
485 int n;
486 int state = -1;
488 while(letter(buf[i]))
489 i++;
490 for(n = 0; n < sizeof(states) / sizeof(states[0]); n++) {
491 if(strlen(states[n].name) == i - offset &&
492 lwrcmp(buf + offset, states[n].name, i - offset) == 0) {
493 state = states[n].value;
494 break;
497 if(state < 0)
498 return -1;
500 switch(kind) {
501 case CONFIG_BOOLEAN:
502 if(state == 0) return 0;
503 else if(state == 4) return 1;
504 else return -1;
505 break;
506 case CONFIG_TRISTATE:
507 if(state == 0) return 0;
508 else if(state == 2) return 1;
509 else if(state == 4) return 2;
510 else return -1;
511 break;
512 case CONFIG_TETRASTATE:
513 if(state == 0) return 0;
514 else if(state == 1) return 1;
515 else if(state == 3) return 2;
516 else if(state == 4) return 3;
517 else return -1;
518 break;
519 case CONFIG_PENTASTATE:
520 return state;
521 break;
522 default:
523 abort();
527 static int
528 parseAtom(char *buf, int offset, AtomPtr *value_return, int insensitive)
530 int y0, i, j, k;
531 AtomPtr atom;
532 int escape = 0;
533 char *s;
535 i = offset;
536 if(buf[i] == '\"') {
537 i++;
538 y0 = i;
539 while(buf[i] != '\"' && buf[i] != '\n' && buf[i] != '\0') {
540 if(buf[i] == '\\' && buf[i + 1] != '\0') {
541 escape = 1;
542 i += 2;
543 } else
544 i++;
546 if(buf[i] != '\"')
547 return -1;
548 j = i + 1;
549 } else {
550 y0 = i;
551 while(letter(buf[i]) || digit(buf[i]) ||
552 buf[i] == '_' || buf[i] == '-' || buf[i] == '~' ||
553 buf[i] == '.' || buf[i] == ':' || buf[i] == '/')
554 i++;
555 j = i;
558 if(escape) {
559 s = malloc(i - y0);
560 if(buf == NULL) return -1;
561 k = 0;
562 j = y0;
563 while(j < i) {
564 if(buf[j] == '\\' && j <= i - 2) {
565 s[k++] = buf[j + 1];
566 j += 2;
567 } else
568 s[k++] = buf[j++];
570 if(insensitive)
571 atom = internAtomLowerN(s, k);
572 else
573 atom = internAtomN(s, k);
574 free(s);
575 j++;
576 } else {
577 if(insensitive)
578 atom = internAtomLowerN(buf + y0, i - y0);
579 else
580 atom = internAtomN(buf + y0, i - y0);
582 *value_return = atom;
583 return j;
586 static int
587 parseTime(char *line, int i, int *value_return)
589 int v = 0, w;
590 while(1) {
591 if(!digit(line[i]))
592 break;
593 w = atoi(line + i);
594 while(digit(line[i])) i++;
595 switch(line[i]) {
596 case 'd': v += w * 24 * 3600; i++; break;
597 case 'h': v += w * 3600; i++; break;
598 case 'm': v += w * 60; i++; break;
599 case 's': v += w; i++; break;
600 default: v += w; goto done;
603 done:
604 *value_return = v;
605 return i;
609 parseConfigLine(char *line, char *filename, int lineno, int set)
611 int x0, x1;
612 int i, from, to;
613 AtomPtr name, value;
614 ConfigVariablePtr var;
615 int iv;
616 float fv;
617 AtomPtr av;
618 AtomListPtr alv;
619 IntListPtr ilv;
621 i = skipWhitespace(line, 0);
622 if(line[i] == '\n' || line[i] == '\0' || line[i] == '#')
623 return 0;
625 x0 = i;
626 while(letter(line[i]) || digit(line[i]))
627 i++;
628 x1 = i;
630 i = skipWhitespace(line, i);
631 if(line[i] != '=') {
632 goto syntax;
634 i++;
635 i = skipWhitespace(line, i);
637 name = internAtomN(line + x0, x1 - x0);
638 var = findConfigVariable(name);
639 releaseAtom(name);
641 if(set && var->setter == NULL)
642 return -2;
644 if(var == NULL) {
645 if(!set) {
646 do_log(L_ERROR, "%s:%d: unknown config variable ",
647 filename, lineno);
648 do_log_n(L_ERROR, line + x0, x1 - x0);
649 do_log(L_ERROR, "\n");
651 return -1;
654 i = skipWhitespace(line, i);
655 switch(var->type) {
656 case CONFIG_INT: case CONFIG_OCTAL: case CONFIG_HEX:
657 i = parseInt(line, i, INT_MIN, INT_MAX, 0, &iv);
658 if(i < 0) goto syntax;
659 if(set)
660 var->setter(var, &iv);
661 else
662 *var->value.i = iv;
663 break;
664 case CONFIG_TIME:
665 i = parseTime(line, i, &iv);
666 if(i < 0) goto syntax;
667 i = skipWhitespace(line, i);
668 if(line[i] != '\n' && line[i] != '\0' && line[i] != '#')
669 goto syntax;
670 if(set)
671 var->setter(var, &iv);
672 else
673 *var->value.i = iv;
674 break;
675 case CONFIG_BOOLEAN:
676 case CONFIG_TRISTATE:
677 case CONFIG_TETRASTATE:
678 case CONFIG_PENTASTATE:
679 iv = parseState(line, i, var->type);
680 if(iv < 0)
681 goto syntax;
682 if(set)
683 var->setter(var, &iv);
684 else
685 *var->value.i = iv;
686 break;
687 case CONFIG_FLOAT:
688 if(!digit(line[i]) && line[i] != '.')
689 goto syntax;
690 fv = atof(line + i);
691 if(set)
692 var->setter(var, &fv);
693 else
694 *var->value.f = fv;
695 break;
696 case CONFIG_ATOM: case CONFIG_ATOM_LOWER: case CONFIG_PASSWORD:
697 i = parseAtom(line, i, &av, (var->type == CONFIG_ATOM_LOWER));
698 if(i < 0) goto syntax;
699 if(!av) {
700 if(!set)
701 do_log(L_ERROR, "%s:%d: couldn't allocate atom.\n",
702 filename, lineno);
703 return -1;
705 i = skipWhitespace(line, i);
706 if(line[i] != '\n' && line[i] != '\0' && line[i] != '#') {
707 releaseAtom(av);
708 goto syntax;
710 if(set)
711 var->setter(var, &av);
712 else {
713 if(*var->value.a) releaseAtom(*var->value.a);
714 *var->value.a = av;
716 break;
717 case CONFIG_INT_LIST:
718 ilv = makeIntList(0);
719 if(ilv == NULL) {
720 if(!set)
721 do_log(L_ERROR, "%s:%d: couldn't allocate int list.\n",
722 filename, lineno);
723 return -1;
725 while(1) {
726 i = parseInt(line, i, INT_MIN, INT_MAX, 0, &from);
727 if(i < 0) goto syntax;
728 to = from;
729 i = skipWhitespace(line, i);
730 if(line[i] == '-') {
731 i = skipWhitespace(line, i + 1);
732 i = parseInt(line, i, INT_MIN, INT_MAX, 0, &to);
733 if(i < 0) {
734 destroyIntList(ilv);
735 goto syntax;
737 i = skipWhitespace(line, i);
739 intListCons(from, to, ilv);
740 if(line[i] == '\n' || line[i] == '\0' || line[i] == '#')
741 break;
742 if(line[i] != ',') {
743 destroyIntList(ilv);
744 goto syntax;
746 i = skipWhitespace(line, i + 1);
748 if(set)
749 var->setter(var, &ilv);
750 else {
751 if(*var->value.il) destroyIntList(*var->value.il);
752 *var->value.il = ilv;
754 break;
755 case CONFIG_ATOM_LIST: case CONFIG_ATOM_LIST_LOWER:
756 alv = makeAtomList(NULL, 0);
757 if(alv == NULL) {
758 if(!set)
759 do_log(L_ERROR, "%s:%d: couldn't allocate atom list.\n",
760 filename, lineno);
761 return -1;
763 while(1) {
764 i = parseAtom(line, i, &value,
765 (var->type == CONFIG_ATOM_LIST_LOWER));
766 if(i < 0) goto syntax;
767 if(!value) {
768 if(!set)
769 do_log(L_ERROR, "%s:%d: couldn't allocate atom.\n",
770 filename, lineno);
771 return -1;
773 atomListCons(value, alv);
774 i = skipWhitespace(line, i);
775 if(line[i] == '\n' || line[i] == '\0' || line[i] == '#')
776 break;
777 if(line[i] != ',') {
778 destroyAtomList(alv);
779 goto syntax;
781 i = skipWhitespace(line, i + 1);
783 if(set)
784 var->setter(var, &alv);
785 else {
786 if(*var->value.al) destroyAtomList(*var->value.al);
787 *var->value.al = alv;
789 break;
790 default: abort();
792 return 1;
794 syntax:
795 if(!set)
796 do_log(L_ERROR, "%s:%d: parse error.\n", filename, lineno);
797 return -1;
801 parseConfigFile(AtomPtr filename)
803 char buf[512];
804 int rc, lineno;
805 FILE *f;
807 if(!filename || filename->length == 0)
808 return 0;
809 f = fopen(filename->string, "r");
810 if(f == NULL) {
811 do_log(L_ERROR, "Couldn't open config file %s: %d.\n",
812 filename->string, errno);
813 return -1;
816 lineno = 1;
817 while(1) {
818 char *s;
819 s = fgets(buf, 512, f);
820 if(s == NULL) {
821 fclose(f);
822 return 1;
824 rc = parseConfigLine(buf, filename->string, lineno, 0);
825 lineno++;
830 configIntSetter(ConfigVariablePtr var, void* value)
832 assert(var->type <= CONFIG_PENTASTATE);
833 *var->value.i = *(int*)value;
834 return 1;
838 configFloatSetter(ConfigVariablePtr var, void* value)
840 assert(var->type == CONFIG_FLOAT);
841 *var->value.i = *(float*)value;
842 return 1;
847 configAtomSetter(ConfigVariablePtr var, void* value)
849 assert(var->type == CONFIG_ATOM || var->type == CONFIG_ATOM_LOWER ||
850 var->type == CONFIG_PASSWORD);
851 if(*var->value.a)
852 releaseAtom(*var->value.a);
853 *var->value.a = *(AtomPtr*)value;
854 return 1;