release 0.92.3
[cntlm.git] / config.c
blobe23ae20cf8dd356ecf5bf7bca2b299f6bf7cfcbc
1 /*
2 * These are very basic config file routines for the main module of CNTLM
4 * CNTLM is free software; you can redistribute it and/or modify it under the
5 * terms of the GNU General Public License as published by the Free Software
6 * Foundation; either version 2 of the License, or (at your option) any later
7 * version.
9 * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
16 * St, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Copyright (c) 2007 David Kubicek
22 #include <stdio.h>
23 #include <ctype.h>
24 #include <string.h>
25 #include <stdlib.h>
27 #include "globals.h"
28 #include "config.h"
29 #include "utils.h"
32 static const char *globals[] = {
33 "Allow",
34 "Deny",
35 "Gateway",
36 "Listen",
37 "SOCKS5Proxy",
38 "SOCKS5User",
39 "NTLMToBasic",
40 "Tunnel" };
43 config_t config_open(const char *fname) {
44 config_t rc;
45 FILE *fp;
46 char *buf, *tmp, *key, *value;
47 char section[MINIBUF_SIZE] = "global";
48 int i, j, slen, len, quote;
50 //printf("sizeof = %d\n", sizeof(globals) / sizeof(char *));
52 fp = fopen(fname, "r");
53 if (!fp)
54 return NULL;
56 buf = new(BUFSIZE);
57 rc = (config_t)new(sizeof(struct config_s));
58 rc->options = NULL;
60 while (!feof(fp)) {
61 quote = 0;
62 tmp = fgets(buf, BUFSIZE, fp);
63 if (!tmp)
64 break;
66 len = MIN(BUFSIZE, strlen(buf));
67 if (!len || feof(fp))
68 continue;
71 * Find first non-empty character
73 for (i = j = 0; j < len && isspace(buf[j]); ++j);
76 * Comment?
78 if (j >= len || buf[j] == '#' || buf[j] == ';')
79 continue;
82 * Find end of keyword
84 for (i = j; j < len && isalnum(buf[j]); ++j);
87 * Malformed?
89 if (j >= len)
90 continue;
93 * Is it a section?
95 if (buf[j] == '[') {
96 for (++j; j < len && isspace(buf[j]); ++j);
97 for (slen = j; j < len && j-slen < MINIBUF_SIZE-1 && buf[j] != ']' && !isspace(buf[j]); ++j);
98 if (j-slen > 0) {
99 strlcpy(section, buf+slen, j-slen+1);
101 continue;
105 * It's an OK keyword
107 key = substr(buf, i, j-i);
110 * Find next non-empty character
112 for (i = j; j < len && isspace(buf[j]); ++j);
113 if (j >= len || buf[j] == '#' || buf[j] == ';')
114 continue;
117 * Is value quoted?
119 if (buf[j] == '"') {
120 quote = 1;
121 for (i = ++j; j < len && buf[i] != '"'; ++i);
122 if (i >= len)
123 continue;
124 } else
125 i = len;
128 * Get value as quoted or until EOL/comment
130 value = substr(buf, j, i-j);
131 if (!quote) {
132 i = strcspn(value, "#");
133 if (i != strlen(value))
134 value[i] = 0;
135 trimr(value);
138 if (debug)
139 printf("section: %s, %s = '%s'\n", section, key, value);
140 rc->options = hlist_add(rc->options, key, value, HLIST_NOALLOC, HLIST_NOALLOC);
143 free(buf);
144 fclose(fp);
146 return rc;
149 void config_set(config_t cf, char *option, char *value) {
150 cf->options = hlist_mod(cf->options, option, value, 1);
153 char *config_pop(config_t cf, const char *option) {
154 char *tmp;
156 tmp = hlist_get(cf->options, option);
157 if (tmp) {
158 tmp = strdup(tmp);
159 cf->options = hlist_del(cf->options, option);
162 return tmp;
165 int config_count(config_t cf) {
166 return hlist_count(cf->options);
169 void config_close(config_t cf) {
170 if (cf == NULL)
171 return;
173 cf->options = hlist_free(cf->options);
174 free(cf);