2 * Dolda Connect - Modular multiuser Direct Connect-style client
3 * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <sys/types.h>
30 #include <arpa/inet.h>
39 static struct configmod *modules = NULL;
42 static void dumpconfig(void)
44 struct configmod *mod;
45 struct configvar *var;
47 for(mod = modules; mod != NULL; mod = mod->next)
49 printf("%s:\n", mod->name);
50 for(var = mod->vars; var->type != CONF_VAR_END; var++)
55 printf("\t%s: %s\n", var->name, var->val.num?"t":"f");
58 printf("\t%s: %i\n", var->name, var->val.num);
61 printf("\t%s: \"%ls\" (%i)\n", var->name, var->val.str, wcslen(var->val.str));
64 printf("\t%s: %s\n", var->name, inet_ntoa(var->val.ipv4));
72 struct configvar *confgetvar(char *modname, char *varname)
77 for(m = modules; m != NULL; m = m->next)
79 if(!strcmp(m->name, modname))
81 for(v = m->vars; v->type != CONF_VAR_END; v++)
83 if(!strcmp(v->name, varname))
92 void confregmod(struct configmod *mod)
94 struct configvar *var;
96 for(var = mod->vars; var->type != CONF_VAR_END; var++)
102 var->val.num = var->defaults.num;
104 case CONF_VAR_STRING:
105 if(var->defaults.str != NULL)
107 var->val.str = swcsdup(var->defaults.str);
113 var->val.ipv4.s_addr = var->defaults.ipv4.s_addr;
116 CBCHAININIT(var, conf_update);
122 int runconfcmd(int argc, wchar_t **argv)
124 struct configmod *module;
125 struct configvar *var;
126 struct configcmd *cmd;
129 char *cmdn, *buf, *buf2, *valbuf;
131 struct in_addr newipv4;
136 if((cmdn = icwcstombs(argv[0], "us-ascii")) == NULL)
138 flog(LOG_WARNING, "could not convert %ls to us-ascii", argv[0]);
143 if(!strcmp(cmdn, "set"))
147 if((p = wcschr(argv[1], L'.')) == NULL)
149 flog(LOG_WARNING, "illegal configuration variable format: %ls", argv[1]);
155 if((buf = icwcstombs(argv[1], "us-ascii")) == NULL)
157 flog(LOG_WARNING, "could not convert %ls to us-ascii", argv[1]);
161 if((buf2 = icwcstombs(p, "us-ascii")) == NULL)
164 flog(LOG_WARNING, "could not convert %ls to us-ascii", p);
168 for(module = modules; module != NULL; module = module->next)
170 if(!strcmp(module->name, buf) && (module->vars != NULL))
172 for(var = module->vars; var->type != CONF_VAR_END; var++)
174 if(!strcmp(var->name, buf2))
181 if(!wcscmp(argv[2], L"off") ||
182 !wcscmp(argv[2], L"false") ||
183 !wcscmp(argv[2], L"no") ||
184 !wcscmp(argv[2], L"0"))
189 } else if(!wcscmp(argv[2], L"on") ||
190 !wcscmp(argv[2], L"true") ||
191 !wcscmp(argv[2], L"yes") ||
192 !wcscmp(argv[2], L"1")) {
197 flog(LOG_WARNING, "unrecognized boolean: %ls", argv[2]);
201 num = wcstol(argv[2], &p, 0);
204 flog(LOG_WARNING, "%ls: not a number, ignoring", argv[2]);
208 flog(LOG_WARNING, "%ls: could not entirely parse as a number, ignoring trailing garbage", argv[2]);
209 if(num != var->val.num)
214 case CONF_VAR_STRING:
215 if(wcscmp(var->val.str, argv[2]))
218 var->val.str = swcsdup(argv[2]);
221 if((valbuf = icwcstombs(argv[2], "us-ascii")) == NULL)
223 flog(LOG_WARNING, "could not convert IPv4 address to as-ascii in var %s, ignoring", buf2);
225 if(!inet_aton(valbuf, &newipv4))
227 flog(LOG_WARNING, "could not parse IPv4 address (%s), ignoring", valbuf);
228 memcpy(&var->val.ipv4, &var->defaults.ipv4, sizeof(var->val.ipv4));
230 if(memcmp(&newipv4, &var->val.ipv4, sizeof(newipv4)))
232 memcpy(&var->val.ipv4, &newipv4, sizeof(newipv4));
239 CBCHAINDOCB(var, conf_update, var);
244 flog(LOG_WARNING, "variable %s not found, ignoring set command", buf2);
249 flog(LOG_WARNING, "module %s not found, ignoring set command", buf);
253 for(module = modules; !handled && (module != NULL); module = module->next)
255 if(module->cmds != NULL)
257 for(cmd = module->cmds; cmd->name != NULL; cmd++)
259 if(!strcmp(cmd->name, cmdn))
262 ret = cmd->handler(argc, argv);
269 flog(LOG_WARNING, "command not found: %s", cmdn);
274 char *findconfigfile(void)
276 static char pathbuf[128];
279 if(getenv("HOME") != NULL)
281 snprintf(pathbuf, sizeof(pathbuf), "%s/.doldacond", getenv("HOME"));
282 if(!access(pathbuf, R_OK))
291 memcpy(pathbuf, p, p2 - p);
293 if(!access(pathbuf, R_OK))
304 void readconfig(FILE *stream)
309 wchar_t *buf, *p, *p2;
313 buf = smalloc(sizeof(wchar_t) * 1024);
325 while((c != WEOF) && (c != L'\n'));
336 if(runconfcmd(w, words))
337 flog(LOG_WARNING, "ignoring this command on line %i", line);
351 } else if(iswspace(c)) {
354 flog(LOG_WARNING, "too many words on config line %i, ignoring rest", line);
366 flog(LOG_WARNING, "too many characters on config line %i, ignoring rest", line);
381 flog(LOG_WARNING, "too many characters on config line %i, ignoring rest", line);
389 flog(LOG_WARNING, "error on configuration stream: %s", strerror(errno));
391 flog(LOG_WARNING, "unexpected end of file");