5d6437ff893556a477e5abd2a8ae9c2300c6b257
[tinc] / src / conf.c
1 /*
2     conf.c -- configuration code
3     Copyright (C) 1998 Emphyrio,
4     Copyright (C) 1998,1999,2000 Ivo Timmermans <itimmermans@bigfoot.com>
5                             2000 Guus Sliepen <guus@sliepen.warande.net>
6                             2000 Cris van Pelt <tribbel@arise.dhs.org>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22     $Id: conf.c,v 1.9.4.5 2000/06/30 11:45:14 guus Exp $
23 */
24
25
26 #include "config.h"
27
28 #include <ctype.h>
29 #include <errno.h>
30 #include <netdb.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include <xalloc.h>
36
37 #include "conf.h"
38 #include "netutl.h" /* for strtoip */
39 #include <utils.h> /* for cp */
40
41 #include "system.h"
42
43 config_t *config;
44 int debug_lvl = 0;
45 int timeout = 0; /* seconds before timeout */
46 char *configfilename = NULL;
47
48 /* Will be set if HUP signal is received. It will be processed when it is safe. */
49 int sighup = 0;
50
51 typedef struct internal_config_t {
52   char *name;
53   enum which_t which;
54   int argtype;
55 } internal_config_t;
56
57 /*
58   These are all the possible configurable values
59 */
60 static internal_config_t hazahaza[] = {
61   { "AllowConnect", allowconnect,   TYPE_BOOL },   /* Is not used anywhere. Remove? */
62   { "ConnectTo",    upstreamip,     TYPE_IP },
63   { "ConnectPort",  upstreamport,   TYPE_INT },
64   { "ListenPort",   listenport,     TYPE_INT },
65   { "MyOwnVPNIP",   myvpnip,        TYPE_IP },
66   { "MyVirtualIP",  myvpnip,        TYPE_IP },   /* an alias */
67   { "Passphrases",  passphrasesdir, TYPE_NAME },
68   { "PingTimeout",  pingtimeout,    TYPE_INT },
69   { "TapDevice",    tapdevice,      TYPE_NAME },
70   { "KeyExpire",    keyexpire,      TYPE_INT },
71   { "VpnMask",      vpnmask,        TYPE_IP },
72   { "Hostnames",    resolve_dns,    TYPE_BOOL },
73   { "IndirectData", indirectdata,   TYPE_BOOL },
74   { NULL, 0, 0 }
75 };
76
77 /*
78   Add given value to the list of configs cfg
79 */
80 config_t *
81 add_config_val(config_t **cfg, int argtype, char *val)
82 {
83   config_t *p, *r;
84   char *q;
85 cp
86   p = (config_t*)xmalloc(sizeof(*p));
87   p->data.val = 0;
88   
89   switch(argtype)
90     {
91     case TYPE_INT:
92       p->data.val = strtol(val, &q, 0);
93       if(q && *q)
94         p->data.val = 0;
95       break;
96     case TYPE_NAME:
97       p->data.ptr = xmalloc(strlen(val) + 1);
98       strcpy(p->data.ptr, val);
99       break;
100     case TYPE_IP:
101       p->data.ip = strtoip(val);
102       break;
103     case TYPE_BOOL:
104       if(!strcasecmp("yes", val))
105         p->data.val = stupid_true;
106       else if(!strcasecmp("no", val))
107         p->data.val = stupid_false;
108       else
109         p->data.val = 0;
110     }
111
112   p->argtype = argtype;
113
114   if(p->data.val)
115     {
116       if(*cfg)
117         {
118           r = *cfg;
119           while(r->next)
120             r = r->next;
121           r->next = p;
122         }
123       else
124         *cfg = p;
125       p->next = NULL;
126       return p;
127     }
128
129   free(p);
130 cp
131   return NULL;
132 }
133
134 /*
135   Get variable from a section in a configfile. returns -1 on failure.
136 */
137 int
138 readconfig(const char *fname, FILE *fp)
139 {
140   char *line, *temp_buf;
141   char *p, *q;
142   int i, lineno = 0;
143   config_t *cfg;
144 cp
145   line = (char *)xmalloc(80 * sizeof(char));
146   temp_buf = (char *)xmalloc(80 * sizeof(char));
147         
148   for(;;)
149     {
150       if(fgets(line, 80, fp) == NULL)
151         return 0;
152
153       while(!index(line, '\n'))
154         {
155           fgets(temp_buf, (strlen(line)+1) * 80, fp);
156           if(!temp_buf)
157             break;
158           strcat(line, temp_buf);
159           line = (char *)xrealloc(line, (strlen(line)+1) * sizeof(char));
160         }        
161       lineno++;
162
163       if((p = strtok(line, "\t\n\r =")) == NULL)
164         continue; /* no tokens on this line */
165
166       if(p[0] == '#')
167         continue; /* comment: ignore */
168
169       for(i = 0; hazahaza[i].name != NULL; i++)
170         if(!strcasecmp(hazahaza[i].name, p))
171           break;
172
173       if(!hazahaza[i].name)
174         {
175           fprintf(stderr, _("%s: %d: Invalid variable name `%s'.\n"),
176                   fname, lineno, p);
177           return -1;
178         }
179
180       if(((q = strtok(NULL, "\t\n\r =")) == NULL) || q[0] == '#')
181         {
182           fprintf(stderr, _("%s: %d: No value given for `%s'.\n"),
183                   fname, lineno, hazahaza[i].name);
184           return -1;
185         }
186
187       cfg = add_config_val(&config, hazahaza[i].argtype, q);
188       if(cfg == NULL)
189         {
190           fprintf(stderr, _("%s: %d: Invalid value `%s' for variable `%s'.\n"),
191                   fname, lineno, q, hazahaza[i].name);
192           return -1;
193         }
194
195       cfg->which = hazahaza[i].which;
196       if(!config)
197         config = cfg;
198     }
199 cp
200   return 0;
201 }
202
203 /*
204   wrapper function for readconfig
205 */
206 int
207 read_config_file(const char *fname)
208 {
209   int err;
210   FILE *fp;
211 cp
212   if((fp = fopen (fname, "r")) == NULL)
213     {
214       fprintf(stderr, _("Could not open %s: %s\n"), fname, sys_errlist[errno]);
215       return 1;
216     }
217
218   err = readconfig(fname, fp);
219   fclose (fp);
220 cp
221   return err;
222 }
223
224 /*
225   Look up the value of the config option type
226 */
227 const config_t *
228 get_config_val(which_t type)
229 {
230   config_t *p;
231 cp
232   for(p = config; p != NULL; p = p->next)
233     if(p->which == type)
234       return p;
235 cp
236   /* Not found */
237   return NULL;
238 }
239
240 /*
241   Support for multiple config lines.
242   Index is used to get a specific value, 0 being the first, 1 the second etc.
243 */
244 const config_t *
245 get_next_config_val(which_t type, int index)
246 {
247   config_t *p;
248 cp  
249   for(p = config; p != NULL; p = p->next)
250     if(p->which == type)
251       if(--index < 0)
252         return p;
253 cp  
254   /* Not found */
255   return NULL;
256 }
257
258 /*
259   Remove the complete configuration tree.
260 */
261 void clear_config()
262 {
263   config_t *p, *next;
264 cp
265   for(p = config; p != NULL; p = next)
266     {
267       next = p->next;
268       if(p->data.ptr && (p->argtype == TYPE_NAME))
269         {
270           free(p->data.ptr);
271         }
272       free(p);
273     }
274   config = NULL;
275 cp
276 }