Added memory-stored debug output to safe mode.
[cake.git] / workbench / prefs / network / prefsdata.c
blob801108ee7655f89ec3b38a3a6c992e84047b5bc3
1 /*
2 Copyright © 2009, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <proto/dos.h>
7 #include <proto/exec.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include "prefsdata.h"
13 static struct TCPPrefs prefs;
15 struct Tokenizer
17 STRPTR tokenizerLine;
18 STRPTR token;
19 FILE * tokenizedFile;
20 BOOL newline;
21 BOOL fend;
24 void OpenTokenFile(struct Tokenizer * tok, STRPTR FileName)
26 tok->tokenizedFile = fopen(FileName, "r");
27 tok->token = NULL;
28 tok->newline = TRUE;
29 if (!tok->tokenizedFile)
30 tok->fend = TRUE;
31 else{
32 tok->tokenizerLine = malloc(8192);
33 tok->fend = FALSE;
34 tok->newline = TRUE;
38 void CloseTokenFile(struct Tokenizer * tok)
40 if (tok->tokenizedFile) {
41 fclose(tok->tokenizedFile);
42 free(tok->tokenizerLine);
43 tok->fend = TRUE;
44 tok->token = NULL;
48 void GetNextToken(struct Tokenizer * tok, STRPTR tk)
50 tok->newline = FALSE;
51 if (tok->token != NULL) {
52 tok->token = strtok(NULL, tk);
53 if (!tok->token)
54 GetNextToken(tok, tk);
55 }else {
56 tok->newline = TRUE;
57 if (!feof(tok->tokenizedFile)) {
58 tok->tokenizerLine[0] = 0;
59 fgets(tok->tokenizerLine, 8192, tok->tokenizedFile);
60 if (tok->tokenizerLine == NULL) {
61 tok->token = NULL;
62 GetNextToken(tok, tk);
63 }else
64 tok->token = strtok(tok->tokenizerLine, tk);
65 }else
66 tok->fend = TRUE;
70 void SetDefaultNetworkPrefsValues()
72 SetIP("192.168.0.188");
73 SetMask("255.255.255.0");
74 SetGate("192.168.0.1");
75 SetDNS(0, "192.168.0.1");
76 SetDNS(1, "192.168.0.1");
77 SetDevice("DEVS:networks/pcnet32.device");
78 SetHost("arosbox");
79 SetDomain("arosnet");
80 SetDHCP(FALSE);
81 SetAutostart(FALSE);
84 /* Returns TRUE if directory has been created or already existed */
85 BOOL RecursiveCreateDir(CONST_STRPTR dirpath)
87 /* Will create directory even if top level directory does not exist */
89 BPTR lock = NULL;
90 ULONG lastdirseparator = 0;
91 ULONG dirpathlen = strlen(dirpath);
92 STRPTR tmpdirpath = AllocVec(dirpathlen + 2, MEMF_CLEAR | MEMF_PUBLIC);
94 CopyMem(dirpath, tmpdirpath, dirpathlen);
96 /* Recurvice directory creation */
97 while(TRUE)
99 if (lastdirseparator >= dirpathlen) break;
101 for (; lastdirseparator < dirpathlen; lastdirseparator++)
102 if (tmpdirpath[lastdirseparator] == '/') break;
104 tmpdirpath[lastdirseparator] = '\0'; /* cut */
106 /* Unlock any lock from previous interation. Last iteration lock will be returned. */
107 if (lock != NULL)
109 UnLock(lock);
110 lock = NULL;
113 /* Check if directory exists */
114 lock = Lock(tmpdirpath, SHARED_LOCK);
115 if (lock == NULL)
117 lock = CreateDir(tmpdirpath);
118 if (lock == NULL)
119 break; /* Error with creation */
122 tmpdirpath[lastdirseparator] = '/'; /* restore */
123 lastdirseparator++;
126 FreeVec(tmpdirpath);
128 if (lock == NULL)
129 return FALSE;
130 else
132 UnLock(lock);
133 lock = NULL;
134 return TRUE;
138 /* Puts part 1 into empy buffer */
139 VOID CombinePath1P(STRPTR dstbuffer, ULONG dstbufferlen, CONST_STRPTR part1)
141 dstbuffer[0] = '\0'; /* Make sure buffer is treated as empty */
142 AddPart(dstbuffer, part1, dstbufferlen);
145 /* Combines part1 with part2 into an empty buffer */
146 VOID CombinePath2P(STRPTR dstbuffer, ULONG dstbufferlen, CONST_STRPTR part1, CONST_STRPTR part2)
148 CombinePath1P(dstbuffer, dstbufferlen, part1);
149 AddPart(dstbuffer, part2, dstbufferlen);
152 /* Combines part1 with part2 with part3 into an empty buffer */
153 VOID CombinePath3P(STRPTR dstbuffer, ULONG dstbufferlen, CONST_STRPTR part1, CONST_STRPTR part2, CONST_STRPTR part3)
155 CombinePath2P(dstbuffer, dstbufferlen, part1, part2);
156 AddPart(dstbuffer, part3, dstbufferlen);
159 BOOL WriteNetworkPrefs(CONST_STRPTR destdir)
161 FILE *ConfFile;
162 ULONG filenamelen = strlen(destdir) + 4 + 20;
163 TEXT filename[filenamelen];
164 ULONG destdbdirlen = strlen(destdir) + 3 + 1;
165 TEXT destdbdir[destdbdirlen];
167 CombinePath2P(destdbdir, destdbdirlen, destdir, "db");
169 /* Create necessary directories */
170 if(!RecursiveCreateDir(destdir)) return FALSE;
171 if(!RecursiveCreateDir(destdbdir)) return FALSE;
173 /* Write variables */
174 CombinePath2P(filename, filenamelen, destdir, "Config");
175 ConfFile = fopen(filename, "w");
176 if (!ConfFile) return FALSE;
177 fprintf(ConfFile, "%s/db", PREFS_PATH_ENV);
178 fclose(ConfFile);
180 CombinePath2P(filename, filenamelen, destdir, "AutoRun");
181 ConfFile = fopen(filename, "w");
182 if (!ConfFile) return FALSE;
183 fprintf(ConfFile, "%s", (GetAutostart()) ? "True" : "False");
184 fclose(ConfFile);
186 /* Write configuration files */
187 CombinePath2P(filename, filenamelen, destdbdir, "general.config");
188 ConfFile = fopen(filename, "w");
189 if (!ConfFile) return FALSE;
190 fprintf(ConfFile, "USELOOPBACK=YES\n");
191 fprintf(ConfFile, "DEBUGSANA=NO\n");
192 fprintf(ConfFile, "USENS=SECOND\n");
193 fprintf(ConfFile, "GATEWAY=NO\n");
194 fprintf(ConfFile, "HOSTNAME=%s.%s\n", GetHost(), GetDomain());
195 fprintf(ConfFile, "LOG FILTERFILE=5\n");
196 fprintf(ConfFile, "GUI PANEL=MUI\n");
197 fprintf(ConfFile, "OPENGUI=YES\n");
198 fclose(ConfFile);
200 CombinePath2P(filename, filenamelen, destdbdir, "interfaces");
201 ConfFile = fopen(filename, "w");
202 if (!ConfFile) return FALSE;
203 fprintf(ConfFile,"eth0 DEV=%s UNIT=0 NOTRACKING IP=%s NETMASK=%s UP\n", GetDevice(),
204 (GetDHCP() ? (CONST_STRPTR)"DHCP" : GetIP()), GetMask());
206 fclose(ConfFile);
208 CombinePath2P(filename, filenamelen, destdbdir, "netdb-myhost");
209 ConfFile = fopen(filename, "w");
210 if (!ConfFile) return FALSE;
211 fprintf(ConfFile, "HOST %s %s.%s %s\n", GetIP(), GetHost(), GetDomain(), GetHost());
212 fprintf(ConfFile, "HOST %s gateway\n", GetGate());
213 fprintf(ConfFile, "; Domain names\n");
214 fprintf(ConfFile, "; Name servers\n");
215 fprintf(ConfFile, "NAMESERVER %s\n", GetDNS(0));
216 fprintf(ConfFile, "NAMESERVER %s\n", GetDNS(1));
217 fclose(ConfFile);
219 CombinePath2P(filename, filenamelen, destdbdir, "static-routes");
220 ConfFile = fopen(filename, "w");
221 if (!ConfFile) return FALSE;
222 fprintf(ConfFile, "DEFAULT GATEWAY %s\n", GetGate());
223 fclose(ConfFile);
225 return TRUE;
228 #define BUFSIZE 2048
229 BOOL CopyFile(CONST_STRPTR srcfile, CONST_STRPTR dstfile)
231 BPTR from = NULL, to = NULL;
232 TEXT buffer[BUFSIZE];
234 if((from = Open(srcfile, MODE_OLDFILE)))
236 if((to = Open(dstfile, MODE_NEWFILE)))
238 LONG s=0;
242 if ((s = Read(from, buffer, BUFSIZE)) == -1)
244 Close(to);
245 Close(from);
246 return FALSE;
249 if (Write(to, buffer, s) == -1)
251 Close(to);
252 Close(from);
253 return FALSE;
255 } while (s == BUFSIZE);
257 Close(to);
258 Close(from);
259 return TRUE;
262 Close(from);
265 return FALSE;
268 CONST_STRPTR GetDefaultStackLocation()
270 /* Use static variable so that it is initialized only once (and can be returned) */
271 static TEXT path [1024] = {0};
273 /* Load path if needed - this will happen only once */
274 if (path[0] == '\0')
276 GetVar(AROSTCP_PACKAGE_VARIABLE, path, 1024, LV_VAR);
279 return path;
282 BOOL IsStackRunning()
284 struct Library * socketlib = NULL;
286 if ((socketlib = OpenLibrary("bsdsocket.library", 0L)) != NULL)
288 CloseLibrary(socketlib);
289 return TRUE;
292 return FALSE;
295 BOOL RestartStack()
297 ULONG trycount = 0;
300 /* Shutdown */
301 if (IsStackRunning())
303 struct Task * arostcptask = FindTask("bsdsocket.library");
304 if (arostcptask != NULL)
305 Signal(arostcptask, SIGBREAKF_CTRL_C);
308 /* Check if shutdown successfull */
309 trycount = 0;
310 while(IsStackRunning())
312 if (trycount > 4) return FALSE;
313 Delay(50);
314 trycount++;
317 /* Startup */
319 CONST_STRPTR srcdir = GetDefaultStackLocation();
320 ULONG arostcppathlen = strlen(srcdir) + 3 + 20;
321 TEXT arostcppath[arostcppathlen];
322 struct TagItem tags[] =
324 { SYS_Input, (IPTR)NULL },
325 { SYS_Output, (IPTR)NULL },
326 { SYS_Error, (IPTR)NULL },
327 { SYS_Asynch, (IPTR)TRUE },
328 { TAG_DONE, 0 }
331 CombinePath3P(arostcppath, arostcppathlen, srcdir, "C", "AROSTCP");
333 SystemTagList(arostcppath, tags);
337 /* Check if startup successfull */
338 trycount = 0;
339 while(!IsStackRunning())
341 if (trycount > 9) return FALSE;
342 Delay(50);
343 trycount++;
346 /* All ok */
347 return TRUE;
350 /* This is not a general use function! It assumes destinations directory exists */
351 BOOL AddFileFromDefaultStackLocation(CONST_STRPTR filename, CONST_STRPTR dstdir)
353 /* Build paths */
354 CONST_STRPTR srcdir = GetDefaultStackLocation();
355 ULONG srcfilelen = strlen(srcdir) + 4 + strlen(filename) + 1;
356 TEXT srcfile[srcfilelen];
357 ULONG dstfilelen = strlen(dstdir) + 4 + strlen(filename) + 1;
358 TEXT dstfile[dstfilelen];
359 BPTR dstlock = NULL;
361 CombinePath3P(srcfile, srcfilelen, srcdir, "db", filename);
362 CombinePath3P(dstfile, dstfilelen, dstdir, "db", filename);
364 /* Check if the destination file already exists. If yes, do not copy */
365 dstlock = Lock(dstfile, SHARED_LOCK);
366 if (dstlock != NULL)
368 UnLock(dstlock);
369 return TRUE;
372 return CopyFile(srcfile, dstfile);
375 /* Copies files not created by prefs but needed to start stack */
376 BOOL CopyDefaultConfiguration(CONST_STRPTR destdir)
378 ULONG destdbdirlen = strlen(destdir) + 3 + 1;
379 TEXT destdbdir[destdbdirlen];
380 CombinePath2P(destdbdir, destdbdirlen, destdir, "db");
382 /* Create necessary directories */
383 if (!RecursiveCreateDir(destdir)) return FALSE;
384 if (!RecursiveCreateDir(destdbdir)) return FALSE;
386 /* Copy files */
387 if (!AddFileFromDefaultStackLocation("hosts", destdir)) return FALSE;
388 if (!AddFileFromDefaultStackLocation("inet.access", destdir)) return FALSE;
389 if (!AddFileFromDefaultStackLocation("netdb", destdir)) return FALSE;
390 if (!AddFileFromDefaultStackLocation("networks", destdir)) return FALSE;
391 if (!AddFileFromDefaultStackLocation("protocols", destdir)) return FALSE;
392 if (!AddFileFromDefaultStackLocation("services", destdir)) return FALSE;
394 return TRUE;
397 enum ErrorCode SaveNetworkPrefs()
399 if (!CopyDefaultConfiguration(PREFS_PATH_ENVARC)) return NOT_COPIED_FILES_ENVARC;
400 if (!WriteNetworkPrefs(PREFS_PATH_ENVARC)) return NOT_SAVED_PREFS_ENVARC;
401 return UseNetworkPrefs();
404 enum ErrorCode UseNetworkPrefs()
406 if (!CopyDefaultConfiguration(PREFS_PATH_ENV)) return NOT_COPIED_FILES_ENV;
407 if (!WriteNetworkPrefs(PREFS_PATH_ENV)) return NOT_SAVED_PREFS_ENV;
408 if (!RestartStack()) return NOT_RESTARTED_STACK;
409 return ALL_OK;
412 /* Directory points to top of config, so to AAA/AROSTCP not to AAA/AROSTCP/db */
413 void ReadNetworkPrefs(CONST_STRPTR directory)
415 ULONG filenamelen = strlen(directory) + 4 + 20;
416 TEXT filename[filenamelen];
417 BOOL comment = FALSE;
418 STRPTR tstring;
419 struct Tokenizer tok;
421 /* This function will not fail. It will load as much data as possible. Rest will be defaul values */
423 CombinePath3P(filename, filenamelen, directory, "db", "general.config");
424 OpenTokenFile(&tok, filename);
425 while (!tok.fend) {
426 if (tok.newline) { // read tokens from the beginning of line
427 if (tok.token) {
428 if (strcmp(tok.token, "HOSTNAME") == 0) {
429 GetNextToken(&tok, "=\n");
430 tstring = strchr(tok.token, '.');
431 SetDomain(tstring + 1);
432 tstring[0] = 0;
433 SetHost(tok.token);
437 GetNextToken(&tok, "=\n");
439 CloseTokenFile(&tok);
441 CombinePath3P(filename, filenamelen, directory, "db", "interfaces");
442 OpenTokenFile(&tok, filename);
443 /* Reads only first uncommented interface */
444 while (!tok.fend) {
445 GetNextToken(&tok, " \n");
446 if (tok.token) {
447 if (tok.newline) comment = FALSE;
448 if (strncmp(tok.token, "#", 1) == 0) comment = TRUE;
450 if (!comment) {
451 if (strncmp(tok.token, "DEV=", 4) == 0) {
452 tstring = strchr(tok.token, '=');
453 SetDevice(tstring + 1);
455 if (strncmp(tok.token, "IP=", 3) == 0) {
456 tstring = strchr(tok.token, '=');
457 if (strncmp(tstring + 1, "DHCP", 4) == 0)
459 SetDHCP(TRUE);
460 SetIP("192.168.0.188");
462 else
464 SetIP(tstring + 1);
465 SetDHCP(FALSE);
468 if (strncmp(tok.token, "NETMASK=", 8) == 0) {
469 tstring = strchr(tok.token, '=');
470 SetMask(tstring + 1);
475 CloseTokenFile(&tok);
477 CombinePath3P(filename, filenamelen, directory, "db", "netdb-myhost");
478 OpenTokenFile(&tok, filename);
479 int dnsc = 0;
480 while (!tok.fend) {
481 GetNextToken(&tok, " \n");
482 if (tok.token) {
483 if (strncmp(tok.token, "NAMESERVER", 4) == 0) {
484 GetNextToken(&tok, " \n");
485 SetDNS(dnsc, tok.token);
486 dnsc++;
487 if (dnsc > 1) dnsc = 1;
491 CloseTokenFile(&tok);
493 CombinePath3P(filename, filenamelen, directory, "db", "static-routes");
494 OpenTokenFile(&tok, filename);
495 while (!tok.fend) {
496 GetNextToken(&tok, " \n");
497 if (tok.token) {
498 if (strncmp(tok.token, "DEFAULT", 4) == 0) {
499 GetNextToken(&tok, " \n");
500 if (strncmp(tok.token, "GATEWAY", 4) == 0) {
501 GetNextToken(&tok, " \n");
502 SetGate(tok.token);
507 CloseTokenFile(&tok);
509 CombinePath2P(filename, filenamelen, directory, "Autorun");
510 OpenTokenFile(&tok, filename);
511 while (!tok.fend)
513 GetNextToken(&tok, " \n");
514 if (tok.token)
516 if (strncmp(tok.token, "True", 4) == 0)
518 SetAutostart(TRUE);
519 break;
521 else
523 SetAutostart(FALSE);
524 break;
528 CloseTokenFile(&tok);
531 void InitNetworkPrefs(CONST_STRPTR directory, BOOL use, BOOL save)
533 SetDefaultNetworkPrefsValues();
535 ReadNetworkPrefs(directory);
537 if (save)
539 SaveNetworkPrefs();
540 return; /* save equals to use */
543 if (use)
545 UseNetworkPrefs();
549 /* Getters */
551 STRPTR GetIP()
553 return prefs.IP;
556 STRPTR GetMask()
558 return prefs.mask;
561 STRPTR GetGate()
563 return prefs.gate;
566 STRPTR GetDNS(LONG m)
568 return prefs.DNS[m];
571 BOOL GetDHCP()
573 return prefs.DHCP;
576 STRPTR GetDevice()
578 return prefs.device;
581 STRPTR GetHost()
583 return prefs.host;
586 STRPTR GetDomain()
588 return prefs.domain;
591 BOOL GetAutostart()
593 return prefs.autostart;
596 void SetIP(STRPTR w)
598 strlcpy(prefs.IP, w,63);
601 /* Setters */
603 void SetMask(STRPTR w)
605 strlcpy(prefs.mask, w,63);
608 void SetGate(STRPTR w)
610 strlcpy(prefs.gate, w,63);
613 void SetDNS(LONG m, STRPTR w)
615 strlcpy(prefs.DNS[m], w,63);
618 void SetDHCP(BOOL w)
620 prefs.DHCP = w;
623 void SetDevice(STRPTR w)
625 strlcpy(prefs.device, w,511);
628 void SetHost(STRPTR w)
630 strlcpy(prefs.host, w,511);
633 void SetDomain(STRPTR w)
635 strlcpy(prefs.domain, w,511);
637 void SetAutostart(BOOL w)
639 prefs.autostart = w;