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