|
|
1.1 root 1: /* load_cfg.c */
2:
3: /* Synchronet configuration load routines (exported) */
4:
1.1.1.2 ! root 5: /* $Id: load_cfg.c,v 1.60 2010/04/01 21:16:54 deuce Exp $ */
1.1 root 6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include "sbbs.h"
39: #include "text.h" /* TOTAL_TEXT */
40:
41: static void prep_cfg(scfg_t* cfg);
42: static void free_attr_cfg(scfg_t* cfg);
43:
1.1.1.2 ! root 44: int lprintf(int level, const char *fmt, ...); /* log output */
1.1 root 45:
46: /****************************************************************************/
47: /* Initializes system and node configuration information and data variables */
48: /****************************************************************************/
49: BOOL DLLCALL load_cfg(scfg_t* cfg, char* text[], BOOL prep, char* error)
50: {
51: int i;
52: long line=0L;
1.1.1.2 ! root 53: #ifdef SBBS
1.1 root 54: FILE *instream;
1.1.1.2 ! root 55: char str[256],fname[13];
! 56: #endif
1.1 root 57:
58: if(cfg->size!=sizeof(scfg_t)) {
59: sprintf(error,"cfg->size (%ld) != sizeof(scfg_t) (%d)"
60: ,cfg->size,sizeof(scfg_t));
61: return(FALSE);
62: }
63:
64: free_cfg(cfg); /* free allocated config parameters */
65:
66: cfg->prepped=FALSE; /* reset prepped flag */
67:
68: if(cfg->node_num<1)
69: cfg->node_num=1;
70:
71: backslash(cfg->ctrl_dir);
72: if(read_main_cfg(cfg, error)==FALSE)
73: return(FALSE);
74:
75: if(prep)
76: for(i=0;i<cfg->sys_nodes;i++)
77: prep_dir(cfg->ctrl_dir, cfg->node_path[i], sizeof(cfg->node_path[i]));
78:
79: SAFECOPY(cfg->node_dir,cfg->node_path[cfg->node_num-1]);
80: prep_dir(cfg->ctrl_dir, cfg->node_dir, sizeof(cfg->node_dir));
81: if(read_node_cfg(cfg, error)==FALSE)
82: return(FALSE);
83: if(read_msgs_cfg(cfg, error)==FALSE)
84: return(FALSE);
85: if(read_file_cfg(cfg, error)==FALSE)
86: return(FALSE);
87: if(read_xtrn_cfg(cfg, error)==FALSE)
88: return(FALSE);
89: if(read_chat_cfg(cfg, error)==FALSE)
90: return(FALSE);
91: if(read_attr_cfg(cfg, error)==FALSE)
92: return(FALSE);
93:
1.1.1.2 ! root 94: #ifdef SBBS
1.1 root 95: if(text!=NULL) {
96:
97: /* Free existing text if allocated */
98: free_text(text);
99:
100: strcpy(fname,"text.dat");
101: sprintf(str,"%s%s",cfg->ctrl_dir,fname);
102: if((instream=fnopen(NULL,str,O_RDONLY))==NULL) {
103: sprintf(error,"%d opening %s",errno,str);
104: return(FALSE);
105: }
1.1.1.2 ! root 106: for(i=0;i<TOTAL_TEXT;i++)
! 107: if((text[i]=readtext(&line,instream,i))==NULL) {
1.1 root 108: i--;
109: break;
110: }
111: fclose(instream);
112:
113: if(i<TOTAL_TEXT) {
114: sprintf(error,"line %lu in %s: Less than TOTAL_TEXT (%u) strings defined in %s."
115: ,i,fname
116: ,TOTAL_TEXT,fname);
117: return(FALSE);
118: }
119: }
1.1.1.2 ! root 120: #endif
1.1 root 121:
122: /* Override com-port settings */
123: cfg->com_base=0xf; /* All nodes use FOSSIL */
124: cfg->com_port=1; /* All nodes use "COM1" */
125:
126: if(prep)
127: prep_cfg(cfg);
128:
129: /* Auto-toggle daylight savings time in US time-zones */
130: sys_timezone(cfg);
131:
132: return(TRUE);
133: }
134:
135: /****************************************************************************/
136: /* Prepare configuration for run-time (resolve relative paths, etc) */
137: /****************************************************************************/
138: void prep_cfg(scfg_t* cfg)
139: {
140: int i;
141:
142: #if 0 /* def __unix__ */
143: strlwr(cfg->text_dir); /* temporary Unix-compatibility hack */
144: strlwr(cfg->temp_dir); /* temporary Unix-compatibility hack */
145: strlwr(cfg->data_dir); /* temporary Unix-compatibility hack */
146: strlwr(cfg->exec_dir); /* temporary Unix-compatibility hack */
147: #endif
148:
149: /* Fix-up paths */
150: prep_dir(cfg->ctrl_dir, cfg->data_dir, sizeof(cfg->data_dir));
151: prep_dir(cfg->ctrl_dir, cfg->logs_dir, sizeof(cfg->logs_dir));
152: prep_dir(cfg->ctrl_dir, cfg->exec_dir, sizeof(cfg->exec_dir));
153: prep_dir(cfg->ctrl_dir, cfg->mods_dir, sizeof(cfg->mods_dir));
154: prep_dir(cfg->ctrl_dir, cfg->text_dir, sizeof(cfg->text_dir));
155:
156: prep_dir(cfg->ctrl_dir, cfg->netmail_dir, sizeof(cfg->netmail_dir));
157: prep_dir(cfg->ctrl_dir, cfg->echomail_dir, sizeof(cfg->echomail_dir));
158: prep_dir(cfg->ctrl_dir, cfg->fidofile_dir, sizeof(cfg->fidofile_dir));
159:
160: prep_path(cfg->netmail_sem);
161: prep_path(cfg->echomail_sem);
162: prep_path(cfg->inetmail_sem);
163:
164: #if 0 /* def __unix__ */
165: /* temporary hack for Unix compatibility */
166: strlwr(cfg->logon_mod);
167: strlwr(cfg->logoff_mod);
168: strlwr(cfg->newuser_mod);
169: strlwr(cfg->login_mod);
170: strlwr(cfg->logout_mod);
171: strlwr(cfg->sync_mod);
172: strlwr(cfg->expire_mod);
173: #endif
174:
175: for(i=0;i<cfg->total_subs;i++) {
176:
177: if(!cfg->sub[i]->data_dir[0]) /* no data storage path specified */
178: sprintf(cfg->sub[i]->data_dir,"%ssubs",cfg->data_dir);
179: prep_dir(cfg->ctrl_dir, cfg->sub[i]->data_dir, sizeof(cfg->sub[i]->data_dir));
180:
181: /* default QWKnet tagline */
182: if(!cfg->sub[i]->tagline[0])
183: SAFECOPY(cfg->sub[i]->tagline,cfg->qnet_tagline);
184:
185: /* default origin line */
186: if(!cfg->sub[i]->origline[0])
187: SAFECOPY(cfg->sub[i]->origline,cfg->origline);
188:
189: /* A sub-board's internal code is the combination of the grp's code_prefix & the sub's code_suffix */
190: SAFEPRINTF2(cfg->sub[i]->code,"%s%s"
191: ,cfg->grp[cfg->sub[i]->grp]->code_prefix
192: ,cfg->sub[i]->code_suffix);
193:
194: strlwr(cfg->sub[i]->code); /* data filenames are all lowercase */
195:
196: prep_path(cfg->sub[i]->post_sem);
197: }
198:
199: for(i=0;i<cfg->total_libs;i++) {
200: if(cfg->lib[i]->parent_path[0])
201: prep_dir(cfg->ctrl_dir, cfg->lib[i]->parent_path, sizeof(cfg->lib[i]->parent_path));
202: }
203:
204: for(i=0;i<cfg->total_dirs;i++) {
205:
206: if(!cfg->dir[i]->data_dir[0]) /* no data storage path specified */
207: sprintf(cfg->dir[i]->data_dir,"%sdirs",cfg->data_dir);
208: prep_dir(cfg->ctrl_dir, cfg->dir[i]->data_dir, sizeof(cfg->dir[i]->data_dir));
209:
210: if(!cfg->dir[i]->path[0]) /* no file storage path specified */
211: sprintf(cfg->dir[i]->path,"%sdirs/%s/",cfg->data_dir,cfg->dir[i]->code);
212: else if(cfg->lib[cfg->dir[i]->lib]->parent_path[0])
213: prep_dir(cfg->lib[cfg->dir[i]->lib]->parent_path, cfg->dir[i]->path, sizeof(cfg->dir[i]->path));
214: else
215: prep_dir(cfg->ctrl_dir, cfg->dir[i]->path, sizeof(cfg->dir[i]->path));
216:
217: /* A directory's internal code is the combination of the lib's code_prefix & the dir's code_suffix */
218: sprintf(cfg->dir[i]->code,"%s%s"
219: ,cfg->lib[cfg->dir[i]->lib]->code_prefix
220: ,cfg->dir[i]->code_suffix);
221:
222: strlwr(cfg->dir[i]->code); /* data filenames are all lowercase */
223:
224: prep_path(cfg->dir[i]->upload_sem);
225: }
226:
227:
228: /* make data filenames are all lowercase */
229: for(i=0;i<cfg->total_shells;i++)
230: strlwr(cfg->shell[i]->code);
231:
232: for(i=0;i<cfg->total_gurus;i++)
233: strlwr(cfg->guru[i]->code);
234:
235: for(i=0;i<cfg->total_txtsecs;i++)
236: strlwr(cfg->txtsec[i]->code);
237:
238: for(i=0;i<cfg->total_xtrnsecs;i++)
239: strlwr(cfg->xtrnsec[i]->code);
240:
241: for(i=0;i<cfg->total_xtrns;i++)
242: {
243: strlwr(cfg->xtrn[i]->code);
244: prep_dir(cfg->ctrl_dir, cfg->xtrn[i]->path, sizeof(cfg->xtrn[i]->path));
245: }
246: for(i=0;i<cfg->total_events;i++) {
247: strlwr(cfg->event[i]->code); /* data filenames are all lowercase */
248: prep_dir(cfg->ctrl_dir, cfg->event[i]->dir, sizeof(cfg->event[i]->dir));
249: }
250: for(i=0;i<cfg->total_xedits;i++)
251: strlwr(cfg->xedit[i]->code);
252:
253: cfg->prepped=TRUE; /* data prepared for run-time, DO NOT SAVE TO DISK! */
254: }
255:
256: void DLLCALL free_cfg(scfg_t* cfg)
257: {
258: free_node_cfg(cfg);
259: free_main_cfg(cfg);
260: free_msgs_cfg(cfg);
261: free_file_cfg(cfg);
262: free_chat_cfg(cfg);
263: free_xtrn_cfg(cfg);
264: free_attr_cfg(cfg);
265: }
266:
267: void DLLCALL free_text(char* text[])
268: {
269: int i;
270:
271: if(text==NULL)
272: return;
273:
274: for(i=0;i<TOTAL_TEXT;i++) {
275: FREE_AND_NULL(text[i]);
276: }
277: }
278:
279: /****************************************************************************/
280: /* If the directory 'path' doesn't exist, create it. */
281: /****************************************************************************/
282: BOOL md(char *inpath)
283: {
284: DIR* dir;
285: char path[MAX_PATH+1];
286:
287: if(inpath[0]==0)
288: return(FALSE);
289:
290: SAFECOPY(path,inpath);
291:
292: /* Remove trailing '.' if present */
293: if(path[strlen(path)-1]=='.')
294: path[strlen(path)-1]=0;
295:
296: /* Remove trailing slash if present */
297: if(path[strlen(path)-1]=='\\' || path[strlen(path)-1]=='/')
298: path[strlen(path)-1]=0;
299:
300: dir=opendir(path);
301: if(dir==NULL) {
302: /* lprintf("Creating directory: %s",path); */
303: if(MKDIR(path)) {
304: lprintf(LOG_WARNING,"!ERROR %d creating directory: %s",errno,path);
305: return(FALSE);
306: }
307: }
308: else
309: closedir(dir);
310:
311: return(TRUE);
312: }
313:
314: /****************************************************************************/
315: /* Reads in ATTR.CFG and initializes the associated variables */
316: /****************************************************************************/
317: BOOL read_attr_cfg(scfg_t* cfg, char* error)
318: {
319: char* p;
320: char str[256],fname[13];
321: long offset=0;
322: FILE *instream;
323:
324: strcpy(fname,"attr.cfg");
325: sprintf(str,"%s%s",cfg->ctrl_dir,fname);
326: if((instream=fnopen(NULL,str,O_RDONLY))==NULL) {
327: sprintf(error,"%d opening %s",errno,str);
328: return(FALSE);
329: }
330: FREE_AND_NULL(cfg->color);
331: if((cfg->color=malloc(MIN_COLORS))==NULL) {
332: sprintf(error,"Error allocating memory (%u bytes) for colors"
333: ,MIN_COLORS);
334: return(FALSE);
335: }
336: memset(cfg->color,LIGHTGRAY|HIGH,MIN_COLORS);
337: for(cfg->total_colors=0;!feof(instream) && !ferror(instream);cfg->total_colors++) {
338: if(readline(&offset,str,4,instream)==NULL)
339: break;
340: if(cfg->total_colors>=MIN_COLORS) {
341: if((p=realloc(cfg->color,cfg->total_colors+1))==NULL)
342: break;
343: cfg->color=p;
344: }
345: cfg->color[cfg->total_colors]=attrstr(str);
346: }
347: fclose(instream);
348: if(cfg->total_colors<MIN_COLORS)
349: cfg->total_colors=MIN_COLORS;
350: return(TRUE);
351: }
352:
353: static void free_attr_cfg(scfg_t* cfg)
354: {
355: if(cfg->color!=NULL)
356: FREE_AND_NULL(cfg->color);
357: cfg->total_colors=0;
358: }
359:
360: char* DLLCALL prep_dir(char* base, char* path, size_t buflen)
361: {
362: #ifdef __unix__
363: char *p;
364: #endif
365: char str[MAX_PATH+1];
366: char abspath[MAX_PATH+1];
367: char ch;
368:
369: if(!path[0])
370: return(path);
371: if(path[0]!='\\' && path[0]!='/' && path[1]!=':') { /* Relative directory */
372: ch=*lastchar(base);
373: if(ch=='\\' || ch=='/')
374: sprintf(str,"%s%s",base,path);
375: else
376: sprintf(str,"%s%c%s",base,PATH_DELIM,path);
377: } else
378: strcpy(str,path);
379:
380: #ifdef __unix__ /* Change backslashes to forward slashes on Unix */
381: for(p=str;*p;p++)
382: if(*p=='\\')
383: *p='/';
384: #endif
385:
386: backslashcolon(str);
387: strcat(str,"."); /* Change C: to C:. and C:\SBBS\ to C:\SBBS\. */
388: FULLPATH(abspath,str,buflen); /* Change C:\SBBS\NODE1\..\EXEC to C:\SBBS\EXEC */
389: backslash(abspath);
390:
391: sprintf(path,"%.*s",(int)(buflen-1),abspath);
392: return(path);
393: }
394:
395: char* prep_path(char* path)
396: {
397: #ifdef __unix__ /* Change backslashes to forward slashes on Unix */
398: char *p;
399:
400: for(p=path;*p;p++)
401: if(*p=='\\')
402: *p='/';
403: #endif
404:
405: return(path);
406: }
407:
408: /****************************************************************************/
409: /* Auto-toggle daylight savings time in US time-zones */
410: /****************************************************************************/
411: ushort DLLCALL sys_timezone(scfg_t* cfg)
412: {
413: time_t now;
414: struct tm tm;
415:
416: if(cfg->sys_misc&SM_AUTO_DST && !OTHER_ZONE(cfg->sys_timezone) && cfg->sys_timezone&US_ZONE) {
417: now=time(NULL);
418: if(localtime_r(&now,&tm)!=NULL) {
419: if(tm.tm_isdst>0)
420: cfg->sys_timezone|=DAYLIGHT;
421: else if(tm.tm_isdst==0)
422: cfg->sys_timezone&=~DAYLIGHT;
423: }
424: }
425:
426: return(cfg->sys_timezone);
427: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.