Annotation of sbbs/src/sbbs3/load_cfg.c, revision 1.1

1.1     ! root        1: /* load_cfg.c */
        !             2: 
        !             3: /* Synchronet configuration load routines (exported) */
        !             4: 
        !             5: /* $Id: load_cfg.c,v 1.56 2006/01/09 23:41:13 rswindell Exp $ */
        !             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: 
        !            44: char * readtext(long *line, FILE *stream);
        !            45: int    lprintf(int level, char *fmt, ...);     /* log output */
        !            46: 
        !            47: /****************************************************************************/
        !            48: /* Initializes system and node configuration information and data variables */
        !            49: /****************************************************************************/
        !            50: BOOL DLLCALL load_cfg(scfg_t* cfg, char* text[], BOOL prep, char* error)
        !            51: {
        !            52:        char    str[256],fname[13];
        !            53:        int             i;
        !            54:        long    line=0L;
        !            55:        FILE    *instream;
        !            56: 
        !            57:        if(cfg->size!=sizeof(scfg_t)) {
        !            58:                sprintf(error,"cfg->size (%ld) != sizeof(scfg_t) (%d)"
        !            59:                        ,cfg->size,sizeof(scfg_t));
        !            60:                return(FALSE);
        !            61:        }
        !            62: 
        !            63:        free_cfg(cfg);  /* free allocated config parameters */
        !            64: 
        !            65:        cfg->prepped=FALSE;     /* reset prepped flag */
        !            66: 
        !            67:        if(cfg->node_num<1)
        !            68:                cfg->node_num=1;
        !            69: 
        !            70:        backslash(cfg->ctrl_dir);
        !            71:        if(read_main_cfg(cfg, error)==FALSE)
        !            72:                return(FALSE);
        !            73: 
        !            74:        if(prep)
        !            75:                for(i=0;i<cfg->sys_nodes;i++) 
        !            76:                        prep_dir(cfg->ctrl_dir, cfg->node_path[i], sizeof(cfg->node_path[i]));
        !            77: 
        !            78:        SAFECOPY(cfg->node_dir,cfg->node_path[cfg->node_num-1]);
        !            79:        prep_dir(cfg->ctrl_dir, cfg->node_dir, sizeof(cfg->node_dir));
        !            80:        if(read_node_cfg(cfg, error)==FALSE)
        !            81:                return(FALSE);
        !            82:        if(read_msgs_cfg(cfg, error)==FALSE)
        !            83:                return(FALSE);
        !            84:        if(read_file_cfg(cfg, error)==FALSE)
        !            85:                return(FALSE);
        !            86:        if(read_xtrn_cfg(cfg, error)==FALSE)
        !            87:                return(FALSE);
        !            88:        if(read_chat_cfg(cfg, error)==FALSE)
        !            89:                return(FALSE);
        !            90:        if(read_attr_cfg(cfg, error)==FALSE)
        !            91:                return(FALSE);
        !            92: 
        !            93:        if(text!=NULL) {
        !            94: 
        !            95:                /* Free existing text if allocated */
        !            96:                free_text(text);
        !            97: 
        !            98:                strcpy(fname,"text.dat");
        !            99:                sprintf(str,"%s%s",cfg->ctrl_dir,fname);
        !           100:                if((instream=fnopen(NULL,str,O_RDONLY))==NULL) {
        !           101:                        sprintf(error,"%d opening %s",errno,str);
        !           102:                        return(FALSE); 
        !           103:                }
        !           104:                for(i=0;i<TOTAL_TEXT && !feof(instream) && !ferror(instream);i++)
        !           105:                        if((text[i]=readtext(&line,instream))==NULL) {
        !           106:                                i--;
        !           107:                                break;
        !           108:                        }
        !           109:                fclose(instream);
        !           110: 
        !           111:                if(i<TOTAL_TEXT) {
        !           112:                        sprintf(error,"line %lu in %s: Less than TOTAL_TEXT (%u) strings defined in %s."
        !           113:                                ,i,fname
        !           114:                                ,TOTAL_TEXT,fname);
        !           115:                        return(FALSE); 
        !           116:                }
        !           117:        }
        !           118: 
        !           119:     /* Override com-port settings */
        !           120:     cfg->com_base=0xf; /* All nodes use FOSSIL */
        !           121:     cfg->com_port=1;   /* All nodes use "COM1" */
        !           122: 
        !           123:        if(prep)
        !           124:                prep_cfg(cfg);
        !           125: 
        !           126:        /* Auto-toggle daylight savings time in US time-zones */
        !           127:        sys_timezone(cfg);
        !           128: 
        !           129:        return(TRUE);
        !           130: }
        !           131: 
        !           132: /****************************************************************************/
        !           133: /* Prepare configuration for run-time (resolve relative paths, etc)                    */
        !           134: /****************************************************************************/
        !           135: void prep_cfg(scfg_t* cfg)
        !           136: {
        !           137:        int i;
        !           138: 
        !           139: #if 0 /* def __unix__ */
        !           140:        strlwr(cfg->text_dir);  /* temporary Unix-compatibility hack */
        !           141:        strlwr(cfg->temp_dir);  /* temporary Unix-compatibility hack */
        !           142:        strlwr(cfg->data_dir);  /* temporary Unix-compatibility hack */
        !           143:        strlwr(cfg->exec_dir);  /* temporary Unix-compatibility hack */
        !           144: #endif
        !           145: 
        !           146:        /* Fix-up paths */
        !           147:        prep_dir(cfg->ctrl_dir, cfg->data_dir, sizeof(cfg->data_dir));
        !           148:        prep_dir(cfg->ctrl_dir, cfg->logs_dir, sizeof(cfg->logs_dir));
        !           149:        prep_dir(cfg->ctrl_dir, cfg->exec_dir, sizeof(cfg->exec_dir));
        !           150:        prep_dir(cfg->ctrl_dir, cfg->mods_dir, sizeof(cfg->mods_dir));
        !           151:        prep_dir(cfg->ctrl_dir, cfg->text_dir, sizeof(cfg->text_dir));
        !           152: 
        !           153:        prep_dir(cfg->ctrl_dir, cfg->netmail_dir, sizeof(cfg->netmail_dir));
        !           154:        prep_dir(cfg->ctrl_dir, cfg->echomail_dir, sizeof(cfg->echomail_dir));
        !           155:        prep_dir(cfg->ctrl_dir, cfg->fidofile_dir, sizeof(cfg->fidofile_dir));
        !           156: 
        !           157:        prep_path(cfg->netmail_sem);
        !           158:        prep_path(cfg->echomail_sem);
        !           159:        prep_path(cfg->inetmail_sem);
        !           160: 
        !           161: #if 0 /* def __unix__ */
        !           162:        /* temporary hack for Unix compatibility */
        !           163:        strlwr(cfg->logon_mod);
        !           164:        strlwr(cfg->logoff_mod);
        !           165:        strlwr(cfg->newuser_mod);
        !           166:        strlwr(cfg->login_mod);
        !           167:        strlwr(cfg->logout_mod);
        !           168:        strlwr(cfg->sync_mod);
        !           169:        strlwr(cfg->expire_mod);
        !           170: #endif
        !           171: 
        !           172:        for(i=0;i<cfg->total_subs;i++) {
        !           173: 
        !           174:                if(!cfg->sub[i]->data_dir[0])   /* no data storage path specified */
        !           175:                        sprintf(cfg->sub[i]->data_dir,"%ssubs",cfg->data_dir);
        !           176:                prep_dir(cfg->ctrl_dir, cfg->sub[i]->data_dir, sizeof(cfg->sub[i]->data_dir));
        !           177: 
        !           178:                /* default QWKnet tagline */
        !           179:                if(!cfg->sub[i]->tagline[0])
        !           180:                        SAFECOPY(cfg->sub[i]->tagline,cfg->qnet_tagline);
        !           181: 
        !           182:                /* default origin line */
        !           183:                if(!cfg->sub[i]->origline[0])
        !           184:                        SAFECOPY(cfg->sub[i]->origline,cfg->origline);
        !           185: 
        !           186:                /* A sub-board's internal code is the combination of the grp's code_prefix & the sub's code_suffix */
        !           187:                SAFEPRINTF2(cfg->sub[i]->code,"%s%s"
        !           188:                        ,cfg->grp[cfg->sub[i]->grp]->code_prefix
        !           189:                        ,cfg->sub[i]->code_suffix);
        !           190: 
        !           191:                strlwr(cfg->sub[i]->code);              /* data filenames are all lowercase */
        !           192: 
        !           193:                prep_path(cfg->sub[i]->post_sem);
        !           194:        }
        !           195: 
        !           196:        for(i=0;i<cfg->total_libs;i++) {
        !           197:                if(cfg->lib[i]->parent_path[0])
        !           198:                        prep_dir(cfg->ctrl_dir, cfg->lib[i]->parent_path, sizeof(cfg->lib[i]->parent_path));
        !           199:        }
        !           200: 
        !           201:        for(i=0;i<cfg->total_dirs;i++) {
        !           202: 
        !           203:                if(!cfg->dir[i]->data_dir[0])   /* no data storage path specified */
        !           204:                        sprintf(cfg->dir[i]->data_dir,"%sdirs",cfg->data_dir);
        !           205:                prep_dir(cfg->ctrl_dir, cfg->dir[i]->data_dir, sizeof(cfg->dir[i]->data_dir));
        !           206: 
        !           207:                if(!cfg->dir[i]->path[0])               /* no file storage path specified */
        !           208:             sprintf(cfg->dir[i]->path,"%sdirs/%s/",cfg->data_dir,cfg->dir[i]->code);
        !           209:                else if(cfg->lib[cfg->dir[i]->lib]->parent_path[0])
        !           210:                        prep_dir(cfg->lib[cfg->dir[i]->lib]->parent_path, cfg->dir[i]->path, sizeof(cfg->dir[i]->path));
        !           211:                else
        !           212:                        prep_dir(cfg->ctrl_dir, cfg->dir[i]->path, sizeof(cfg->dir[i]->path));
        !           213: 
        !           214:                /* A directory's internal code is the combination of the lib's code_prefix & the dir's code_suffix */
        !           215:                sprintf(cfg->dir[i]->code,"%s%s"
        !           216:                        ,cfg->lib[cfg->dir[i]->lib]->code_prefix
        !           217:                        ,cfg->dir[i]->code_suffix);
        !           218: 
        !           219:                strlwr(cfg->dir[i]->code);              /* data filenames are all lowercase */
        !           220: 
        !           221:                prep_path(cfg->dir[i]->upload_sem);
        !           222:        }
        !           223: 
        !           224: 
        !           225:        /* make data filenames are all lowercase */
        !           226:        for(i=0;i<cfg->total_shells;i++)
        !           227:                strlwr(cfg->shell[i]->code);
        !           228: 
        !           229:        for(i=0;i<cfg->total_gurus;i++)
        !           230:                strlwr(cfg->guru[i]->code); 
        !           231: 
        !           232:        for(i=0;i<cfg->total_txtsecs;i++)
        !           233:                strlwr(cfg->txtsec[i]->code);
        !           234: 
        !           235:        for(i=0;i<cfg->total_xtrnsecs;i++)
        !           236:                strlwr(cfg->xtrnsec[i]->code);
        !           237: 
        !           238:        for(i=0;i<cfg->total_xtrns;i++) 
        !           239:        {
        !           240:                strlwr(cfg->xtrn[i]->code);
        !           241:                prep_dir(cfg->ctrl_dir, cfg->xtrn[i]->path, sizeof(cfg->xtrn[i]->path));
        !           242:        }
        !           243:        for(i=0;i<cfg->total_events;i++) {
        !           244:                strlwr(cfg->event[i]->code);    /* data filenames are all lowercase */
        !           245:                prep_dir(cfg->ctrl_dir, cfg->event[i]->dir, sizeof(cfg->event[i]->dir));
        !           246:        }
        !           247:        for(i=0;i<cfg->total_xedits;i++) 
        !           248:                strlwr(cfg->xedit[i]->code);
        !           249: 
        !           250:        cfg->prepped=TRUE;      /* data prepared for run-time, DO NOT SAVE TO DISK! */
        !           251: }
        !           252: 
        !           253: void DLLCALL free_cfg(scfg_t* cfg)
        !           254: {
        !           255:        free_node_cfg(cfg);
        !           256:        free_main_cfg(cfg);
        !           257:        free_msgs_cfg(cfg);
        !           258:        free_file_cfg(cfg);
        !           259:        free_chat_cfg(cfg);
        !           260:        free_xtrn_cfg(cfg);
        !           261:        free_attr_cfg(cfg);
        !           262: }
        !           263: 
        !           264: void DLLCALL free_text(char* text[])
        !           265: {
        !           266:        int i;
        !           267: 
        !           268:        if(text==NULL)
        !           269:                return;
        !           270: 
        !           271:        for(i=0;i<TOTAL_TEXT;i++) {
        !           272:                FREE_AND_NULL(text[i]); 
        !           273:        }
        !           274: }
        !           275: 
        !           276: /****************************************************************************/
        !           277: /* If the directory 'path' doesn't exist, create it.                           */
        !           278: /****************************************************************************/
        !           279: BOOL md(char *inpath)
        !           280: {
        !           281:        DIR*    dir;
        !           282:        char    path[MAX_PATH+1];
        !           283: 
        !           284:        if(inpath[0]==0)
        !           285:                return(FALSE);
        !           286: 
        !           287:        SAFECOPY(path,inpath);
        !           288: 
        !           289:        /* Remove trailing '.' if present */
        !           290:        if(path[strlen(path)-1]=='.')
        !           291:                path[strlen(path)-1]=0;
        !           292: 
        !           293:        /* Remove trailing slash if present */
        !           294:        if(path[strlen(path)-1]=='\\' || path[strlen(path)-1]=='/')
        !           295:                path[strlen(path)-1]=0;
        !           296: 
        !           297:        dir=opendir(path);
        !           298:        if(dir==NULL) {
        !           299:                /* lprintf("Creating directory: %s",path); */
        !           300:                if(MKDIR(path)) {
        !           301:                        lprintf(LOG_WARNING,"!ERROR %d creating directory: %s",errno,path);
        !           302:                        return(FALSE); 
        !           303:                } 
        !           304:        }
        !           305:        else
        !           306:                closedir(dir);
        !           307:        
        !           308:        return(TRUE);
        !           309: }
        !           310: 
        !           311: /****************************************************************************/
        !           312: /* Reads special TEXT.DAT printf style text lines, splicing multiple lines, */
        !           313: /* replacing escaped characters, and allocating the memory                                     */
        !           314: /****************************************************************************/
        !           315: char *readtext(long *line,FILE *stream)
        !           316: {
        !           317:        char buf[2048],str[2048],tmp[256],*p,*p2;
        !           318:        int i,j,k;
        !           319: 
        !           320:        if(!fgets(buf,256,stream))
        !           321:                return(NULL);
        !           322:        if(line)
        !           323:                (*line)++;
        !           324:        if(buf[0]=='#')
        !           325:                return(NULL);
        !           326:        p=strrchr(buf,'"');
        !           327:        if(!p) {
        !           328:                if(line) {
        !           329:                        lprintf(LOG_ERR,"No quotation marks in line %d of text.dat",*line);
        !           330:                        return(NULL); 
        !           331:                }
        !           332:                return(NULL); 
        !           333:        }
        !           334:        if(*(p+1)=='\\')        /* merge multiple lines */
        !           335:                while(strlen(buf)<2000) {
        !           336:                        if(!fgets(str,255,stream))
        !           337:                                return(NULL);
        !           338:                        if(line)
        !           339:                                (*line)++;
        !           340:                        p2=strchr(str,'"');
        !           341:                        if(!p2)
        !           342:                                continue;
        !           343:                        strcpy(p,p2+1);
        !           344:                        p=strrchr(p,'"');
        !           345:                        if(p && *(p+1)=='\\')
        !           346:                                continue;
        !           347:                        break; 
        !           348:                }
        !           349:        *(p)=0;
        !           350:        k=strlen(buf);
        !           351:        for(i=1,j=0;i<k;j++) {
        !           352:                if(buf[i]=='\\')        { /* escape */
        !           353:                        i++;
        !           354:                        if(isdigit(buf[i])) {
        !           355:                                str[j]=atoi(buf+i);     /* decimal, NOT octal */
        !           356:                                if(isdigit(buf[++i]))   /* skip up to 3 digits */
        !           357:                                        if(isdigit(buf[++i]))
        !           358:                                                i++;
        !           359:                                continue; 
        !           360:                        }
        !           361:                        switch(buf[i++]) {
        !           362:                                case '\\':
        !           363:                                        str[j]='\\';
        !           364:                                        break;
        !           365:                                case '?':
        !           366:                                        str[j]='?';
        !           367:                                        break;
        !           368:                                case 'x':
        !           369:                                        tmp[0]=buf[i++];        /* skip next character */
        !           370:                                        tmp[1]=0;
        !           371:                                        if(isxdigit(buf[i])) {  /* if another hex digit, skip too */
        !           372:                                                tmp[1]=buf[i++];
        !           373:                                                tmp[2]=0; 
        !           374:                                        }
        !           375:                                        str[j]=(char)ahtoul(tmp);
        !           376:                                        break;
        !           377:                                case '\'':
        !           378:                                        str[j]='\'';
        !           379:                                        break;
        !           380:                                case '"':
        !           381:                                        str[j]='"';
        !           382:                                        break;
        !           383:                                case 'r':
        !           384:                                        str[j]=CR;
        !           385:                                        break;
        !           386:                                case 'n':
        !           387:                                        str[j]=LF;
        !           388:                                        break;
        !           389:                                case 't':
        !           390:                                        str[j]=TAB;
        !           391:                                        break;
        !           392:                                case 'b':
        !           393:                                        str[j]=BS;
        !           394:                                        break;
        !           395:                                case 'a':
        !           396:                                        str[j]=BEL;
        !           397:                                        break;
        !           398:                                case 'f':
        !           399:                                        str[j]=FF;
        !           400:                                        break;
        !           401:                                case 'v':
        !           402:                                        str[j]=11;      /* VT */
        !           403:                                        break;
        !           404:                                default:
        !           405:                                        str[j]=buf[i];
        !           406:                                        break; 
        !           407:                        }
        !           408:                        continue; 
        !           409:                }
        !           410:                str[j]=buf[i++]; 
        !           411:        }
        !           412:        str[j]=0;
        !           413:        if((p=(char *)calloc(1,j+2))==NULL) { /* +1 for terminator, +1 for YNQX line */
        !           414:                lprintf(LOG_CRIT,"Error allocating %u bytes of memory from text.dat",j);
        !           415:                return(NULL); 
        !           416:        }
        !           417:        strcpy(p,str);
        !           418:        return(p);
        !           419: }
        !           420: 
        !           421: /****************************************************************************/
        !           422: /* Reads in ATTR.CFG and initializes the associated variables               */
        !           423: /****************************************************************************/
        !           424: BOOL read_attr_cfg(scfg_t* cfg, char* error)
        !           425: {
        !           426:        char*   p;
        !           427:     char    str[256],fname[13];
        !           428:        long    offset=0;
        !           429:     FILE    *instream;
        !           430: 
        !           431:        strcpy(fname,"attr.cfg");
        !           432:        sprintf(str,"%s%s",cfg->ctrl_dir,fname);
        !           433:        if((instream=fnopen(NULL,str,O_RDONLY))==NULL) {
        !           434:                sprintf(error,"%d opening %s",errno,str);
        !           435:                return(FALSE); 
        !           436:        }
        !           437:        FREE_AND_NULL(cfg->color);
        !           438:        if((cfg->color=malloc(MIN_COLORS))==NULL) {
        !           439:                sprintf(error,"Error allocating memory (%u bytes) for colors"
        !           440:                        ,MIN_COLORS);
        !           441:                return(FALSE);
        !           442:        }
        !           443:        memset(cfg->color,LIGHTGRAY|HIGH,MIN_COLORS);   
        !           444:        for(cfg->total_colors=0;!feof(instream) && !ferror(instream);cfg->total_colors++) {
        !           445:                if(readline(&offset,str,4,instream)==NULL)
        !           446:                        break;
        !           447:                if(cfg->total_colors>=MIN_COLORS) {
        !           448:                        if((p=realloc(cfg->color,cfg->total_colors+1))==NULL)
        !           449:                                break;
        !           450:                        cfg->color=p;
        !           451:                }
        !           452:                cfg->color[cfg->total_colors]=attrstr(str); 
        !           453:        }
        !           454:        fclose(instream);
        !           455:        if(cfg->total_colors<MIN_COLORS)
        !           456:                cfg->total_colors=MIN_COLORS;
        !           457:        return(TRUE);
        !           458: }
        !           459: 
        !           460: static void free_attr_cfg(scfg_t* cfg)
        !           461: {
        !           462:        if(cfg->color!=NULL)
        !           463:                FREE_AND_NULL(cfg->color);
        !           464:        cfg->total_colors=0;
        !           465: }
        !           466: 
        !           467: char* DLLCALL prep_dir(char* base, char* path, size_t buflen)
        !           468: {
        !           469: #ifdef __unix__
        !           470:        char    *p;
        !           471: #endif
        !           472:        char    str[MAX_PATH+1];
        !           473:        char    abspath[MAX_PATH+1];
        !           474:        char    ch;
        !           475: 
        !           476:        if(!path[0])
        !           477:                return(path);
        !           478:        if(path[0]!='\\' && path[0]!='/' && path[1]!=':') {     /* Relative directory */
        !           479:                ch=*lastchar(base);
        !           480:                if(ch=='\\' || ch=='/')
        !           481:                        sprintf(str,"%s%s",base,path);
        !           482:                else
        !           483:                        sprintf(str,"%s%c%s",base,PATH_DELIM,path);
        !           484:        } else
        !           485:                strcpy(str,path);
        !           486: 
        !           487: #ifdef __unix__                                /* Change backslashes to forward slashes on Unix */
        !           488:        for(p=str;*p;p++)
        !           489:                if(*p=='\\') 
        !           490:                        *p='/';
        !           491: #endif
        !           492: 
        !           493:        backslashcolon(str);
        !           494:        strcat(str,".");                /* Change C: to C:. and C:\SBBS\ to C:\SBBS\. */
        !           495:        FULLPATH(abspath,str,buflen);   /* Change C:\SBBS\NODE1\..\EXEC to C:\SBBS\EXEC */
        !           496:        backslash(abspath);
        !           497: 
        !           498:        sprintf(path,"%.*s",(int)(buflen-1),abspath);
        !           499:        return(path);
        !           500: }
        !           501: 
        !           502: char* prep_path(char* path)
        !           503: {
        !           504: #ifdef __unix__                                /* Change backslashes to forward slashes on Unix */
        !           505:        char    *p;
        !           506: 
        !           507:        for(p=path;*p;p++)
        !           508:                if(*p=='\\') 
        !           509:                        *p='/';
        !           510: #endif
        !           511: 
        !           512:        return(path);
        !           513: }
        !           514: 
        !           515: /****************************************************************************/
        !           516: /* Auto-toggle daylight savings time in US time-zones                                          */
        !           517: /****************************************************************************/
        !           518: ushort DLLCALL sys_timezone(scfg_t* cfg)
        !           519: {
        !           520:        time_t  now;
        !           521:        struct tm tm;
        !           522: 
        !           523:        if(cfg->sys_misc&SM_AUTO_DST && !OTHER_ZONE(cfg->sys_timezone) && cfg->sys_timezone&US_ZONE) {
        !           524:                now=time(NULL);
        !           525:                if(localtime_r(&now,&tm)!=NULL) {
        !           526:                        if(tm.tm_isdst>0)
        !           527:                                cfg->sys_timezone|=DAYLIGHT;
        !           528:                        else if(tm.tm_isdst==0)
        !           529:                                cfg->sys_timezone&=~DAYLIGHT;
        !           530:                }
        !           531:        }
        !           532: 
        !           533:        return(cfg->sys_timezone);
        !           534: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.