- added options to accounting to change format of output
[opensuse:smpppd.git] / smpppd / connection-config.cc
1
2
3 /*
4  *  Author: Arvin Schnell <arvin@suse.de>
5  */
6
7
8 #include <stdio.h>
9 #include <stdarg.h>
10
11 #include "defines.h"
12 #include "utils.h"
13 #include "parse.h"
14 #include "connection-config.h"
15 #include "dsl-config.h"
16 #include "modem-config.h"
17
18
19 ConnectionConfig::ConnectionConfig ()
20 {
21     dprintf ("%s\n", __PRETTY_FUNCTION__);
22
23     ifcfg_filename = provider_filename = "";
24     provider_menuname = "";
25
26     debug = false;
27
28     defaultroute = true;
29     demand = false;
30     idle_seconds = 600;
31
32     modify_dns = auto_dns = true;
33     dns1 = dns2 = "";
34
35     modify_ip = true;
36     local_ip = remote_ip = "";
37
38     username = password = "";
39     ask_password = false;
40
41     reconnect = false;
42     reconnect_delay = 15;
43     reconnect_exits = 256;
44
45     alive_interval = 15 * 60;
46 };
47
48
49 ConnectionConfig::~ConnectionConfig ()
50 {
51     dprintf ("%s\n", __PRETTY_FUNCTION__);
52 }
53
54
55 bool
56 ConnectionConfig::read_config (string ifcfg_arg, string provider_arg,
57                                string* error_message)
58 {
59     ifcfg_filename = ifcfg_arg;
60     provider_filename = provider_arg;
61
62     provider_menuname = provider_filename;
63
64     for (int i = 0; i < 2; i++)
65     {
66         if (i == 1 && provider_filename.empty ()) {
67             *error_message = "No provider file specified.";
68             return false;
69         }
70
71         const string filename = i == 0 ? IFCFG_PATH + ifcfg_filename
72             : PROVIDERS_PATH + provider_filename;
73
74         FILE* fin = fopen (filename.c_str (), "r");
75         if (!fin) {
76             *error_message = "Can't open " + filename + " for reading.";
77             return false;
78         }
79
80         string line, key, value;
81         while (getline (fin, &line))
82         {
83             if (parse_sh_keyvalue (line, &key, &value) != 1)
84                 continue;
85
86             eval_config (key, value, i == 0 ? IFCFG : PROVIDER);
87         }
88
89         fclose (fin);
90     }
91
92     return true;
93 }
94
95
96 void
97 ConnectionConfig::eval_config (const string& key, const string& value, Where where)
98 {
99     if (key == "DEBUG") {
100         debug = value == "yes";
101         return;
102     }
103
104     if (key == "DEFAULTROUTE") {
105         defaultroute = value == "yes";
106         return;
107     }
108
109     if (key == "DEMAND") {
110         demand = value == "yes";
111         return;
112     }
113
114     if (key == "IDLETIME") {
115         idle_seconds = atoi (value.c_str ());
116         return;
117     }
118
119     if (key == "MODIFYDNS") {
120         modify_dns = value == "yes";
121         return;
122     }
123
124     if (key == "AUTODNS") {
125         auto_dns = value == "yes";
126         return;
127     }
128
129     if (key == "DNS1") {
130         dns1 = value;
131         return;
132     }
133
134     if (key == "DNS2") {
135         dns2 = value;
136         return;
137     }
138
139     if (key == "MODIFYIP") {
140         modify_ip = value == "yes";
141         return;
142     }
143
144     if (key == "IPADDR") {
145         local_ip = value == "0.0.0.0" ? "" : value;
146         return;
147     }
148
149     if (key == "REMOTE_IPADDR" || key == "PTPADDR") {
150         remote_ip = value == "0.0.0.0" ? "" : value;
151         return;
152     }
153
154     if (key == "USERNAME") {
155         username = value;
156         return;
157     }
158
159     if (key == "PASSWORD") {
160         password = value;
161         return;
162     }
163
164     if (key == "ASKPASSWORD") {
165         ask_password = value == "yes";
166         return;
167     }
168
169     if (key == "AUTO_RECONNECT") {
170         reconnect = value == "yes";
171         return;
172     }
173
174     if (key == "AUTO_RECONNECT_DELAY") {
175         reconnect_delay = atoi (value.c_str ());
176         if (reconnect_delay < 5)
177             reconnect_delay = 5;
178         return;
179     }
180
181     if (key == "AUTO_RECONNECT_EXITS") {
182         reconnect_exits = 0;
183         char* buffer = strdup (value.c_str ());
184         char* tmp = buffer;
185         while (true) {
186             char* otmp = tmp;
187             int i = strtol (tmp, &tmp, 10);
188             if (tmp == otmp)
189                 break;
190             if (i >= 0 && i <= 20)
191                 bit_set (i, &reconnect_exits);
192         }
193         free (buffer);
194     }
195
196     if (key == "PROVIDER") {
197         switch (where) {
198             case IFCFG:
199                 if (provider_filename.empty ())
200                     provider_filename = value;
201                 return;
202             case PROVIDER:
203                 provider_menuname = value;
204                 return;
205         }
206     }
207 }
208
209
210 bool
211 ConnectionConfig::check_config (string* error_message)
212 {
213     if (username.empty ()) {
214         *error_message = "Configuration does not specify a username.";
215         return false;
216     }
217
218     return true;
219 }
220
221
222 void
223 ConnectionConfig::list_config (std::list <string>* config) const
224 {
225     config->push_back ("ifcfg-filename " + qap (ifcfg_filename));
226     config->push_back ("provider-filename " + qap (provider_filename));
227
228     config->push_back ("username " + qap (username));
229     config->push_back ("password " + qap ("<hidden>"));
230     config->push_back ("ask-password " + tostring (ask_password));
231
232     config->push_back ("defaultroute " + tostring (defaultroute));
233
234     config->push_back ("demand " + tostring (demand));
235     config->push_back ("idle-seconds " + tostring (idle_seconds));
236
237     config->push_back ("modify-dns " + tostring (modify_dns));
238     config->push_back ("auto-dns " + tostring (auto_dns));
239     config->push_back ("dns1 " + qap (dns1));
240     config->push_back ("dns2 " + qap (dns2));
241
242     config->push_back ("modify-ip " + tostring (modify_ip));
243     config->push_back ("local-ip " + qap (local_ip));
244     config->push_back ("remote-ip " + qap (remote_ip));
245
246     config->push_back ("auto-reconnect " + tostring (reconnect));
247     config->push_back ("auto-reconnect-delay " + tostring (reconnect_delay));
248
249     string tmp1;
250     for (int i = 0; i < 32; i++)
251         if (bit_test (i, reconnect_exits)) {
252             if (!tmp1.empty ())
253                 tmp1.append (" ");
254             tmp1.append (tostring (i));
255         }
256     config->push_back ("auto-reconnect-exits " + qap (tmp1));
257 }
258
259
260 ConnectionConfig*
261 ConnectionConfig::create (const string& ifcfg_filename,
262                           const string& provider_filename,
263                           string* error_message)
264 {
265     ConnectionConfig* conf = 0;
266
267     if (ifcfg_filename.substr (0, 9) == "ifcfg-dsl")
268         conf = new DSLConfig ();
269
270     if (ifcfg_filename.substr (0, 9) == "ifcfg-ppp")
271         conf = new ModemConfig ();
272
273     if (!conf) {
274         sprintf (*error_message, "Can't handle ifcfg-file %s.",
275                  ifcfg_filename.c_str ());
276         return 0;
277     }
278
279     if (!conf->read_config (ifcfg_filename, provider_filename, error_message) ||
280         !conf->check_config (error_message)) {
281         delete conf;
282         return 0;
283     }
284
285     return conf;
286 }