Metropoli BBS
VIEWER: arpatime.c MODE: TEXT (ASCII)
/*
 * This part was written by Harald Kipp
 *
 * Bug reports should be sent to
 *
 *  harald@os2point.ping.de
 *  harald@sesam.com
 *  Fido: 2:2448/434
 *
 * This module contains routines to read the configuration file.
 *
 */

#undef STANDALONE

#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <string.h>
#include <time.h>

#include <fcntl.h>

#include <lprintf.h>
#include <dbm.h>
#include <history.h>
#include <active.h>

#include "config.h"
#include "expire.h"

static struct tz_table {
    char  *name;
    time_t tdiff;
} tzone[] = {
    { "acsst",    9 * 60 + 90,        }, /* Cent. Australia */
    { "acst",     9 * 60 + 30,        }, /* Cent. Australia */
    { "adt",      -4 * 60 + 60,       }, /* Atlantic (Canada) */
    { "aesst",    10 * 60 + 60,       }, /* E. Australia */
    { "aest",     10 * 60,            }, /* E. Australia */
    { "ast",      -4 * 60,            }, /* Atlantic (Canada) */
    { "awsst",    8 * 60 + 60,        }, /* W. Australia */
    { "awst",     8 * 60,             }, /* W. Australia */
    { "bst",      60,                 }, /* Great Britain summertime */
    { "cdt",      -6 * 60 + 60,       }, /* Central */
    { "cest",     60 + 60,            }, /* Central Europe */
    { "cet",      60,                 }, /* Central Europe */
    { "cetdst",   60 + 60,            }, /* Central Europe */
    { "cst",      -6 * 60,            }, /* Central */
    { "dnt",      60,                 }, /* Denmark */
    { "dst",      60 + 60,            }, /* Denmark */
    { "edt",      -5 * 60 + 60,       }, /* Eastern US */
    { "eest",     2 * 60 + 60,        }, /* Eastern Europe */
    { "eet",      2 * 60,             }, /* Eastern Europe */
    { "eetdst",   2 * 60 + 60,        }, /* Eastern Europe */
    { "est",      -5 * 60,            }, /* Eastern US */
    { "gmt",      0,                  }, /*  */
    { "hdt",      -10 * 60 + 60,      }, /* Hawaii/Alaska */
    { "hst",      -10 * 60,           }, /* Hawaii/Alaska */
    { "ist",      2 * 60,             }, /* Israel */
    { "jst",      9 * 60,             }, /* Japan */
    { "mdt",      -7 * 60 + 60,       }, /* Mountain US */
    { "mest",     60 + 60,            }, /* Central Europe */
    { "met",      60,                 }, /* Central Europe */
    { "metdst",   60 + 60,            }, /* Central Europe */
    { "mst",      -7 * 60,            }, /* Mountain */
    { "ndt",      -3 * 60 -30 + 60,   }, /* Nfld. (Canada) */
    { "nst",      -3 * 60 -30,        }, /* Nfld. (Canada) */
    { "pdt",      -8 * 60 + 60,       }, /* Pacific */
    { "pst",      -8 * 60,            }, /* Pacific */
    { "utc",      0,                  }, /* UTC */
    { "west",     60,                 }, /* Western Europe */
    { "wet",      0,                  }, /* Western Europe */
    { "wetdst",   60,                 }, /* Western Europe */
    { "ydt",      -9 * 60 + 60,       }, /* Yukon */
    { "yst",      -9 * 60,            }  /* Yukon */
};

/************************************************************************/
/*                                                                      */
/************************************************************************/
static int is_month(char *item)
{
    int result = 0;

    if(strlen(item) >= 3) {
        switch(toupper(*item)) {
        case 'J':
            if(stricmp(item + 1, "an") == 0)
                result = 1;
            else if(stricmp(item + 1, "un") == 0)
                result = 6;
            else if(stricmp(item + 1, "ul") == 0)
                result = 7;
            break;
        case 'F':
            if(stricmp(item + 1, "eb") == 0)
                result = 2;
            break;
        case 'M':
            if(stricmp(item + 1, "ar") == 0)
                result = 3;
            else if(stricmp(item + 1, "ay") == 0)
                result = 5;
            break;
        case 'A':
            if(stricmp(item + 1, "pr") == 0)
                result = 4;
            else if(stricmp(item + 1, "ug") == 0)
                result = 8;
            break;
        case 'S':
            if(stricmp(item + 1, "ep") == 0)
                result = 9;
            break;
        case 'O':
            if(stricmp(item + 1, "ct") == 0)
                result = 10;
            break;
        case 'N':
            if(stricmp(item + 1, "ov") == 0)
                result = 11;
            break;
        case 'D':
            if(stricmp(item + 1, "ec") == 0)
                result = 12;
            break;
        }
    }
    return(result);
}

/************************************************************************/
/*                                                                      */
/************************************************************************/
static int is_wday(char *item)
{
    int result = 0;

    if(strlen(item) >= 3) {
        switch(toupper(*item)) {
        case 'M':
            if(stricmp(item + 1, "on") == 0)
                result = 1;
            break;
        case 'T':
            if(stricmp(item + 1, "ue") == 0)
                result = 2;
            else if(stricmp(item + 1, "hu") == 0)
                result = 4;
            break;
        case 'W':
            if(stricmp(item + 1, "ed") == 0)
                result = 3;
            break;
        case 'F':
            if(stricmp(item + 1, "ri") == 0)
                result = 5;
            break;
        case 'S':
            if(stricmp(item + 1, "at") == 0)
                result = 6;
            else if(stricmp(item + 1, "un") == 0)
                result = 7;
            break;
        }
    }
    return(result);
}

/************************************************************************/
/*                                                                      */
/************************************************************************/
static int cmptable(char *key, struct tz_table *tz)
{
    return(stricmp(key, tz->name));
}

/************************************************************************/
/*                                                                      */
/************************************************************************/
static time_t is_tzone(char *item)
{
    struct tz_table *tz;

    tz = bsearch(item, tzone, sizeof(tzone) / sizeof(tzone[0]),
                 sizeof(tzone[0]), cmptable);
    if(tz)
        return(tz->tdiff);
    return(0);
}

/************************************************************************/
/*                                                                      */
/*                                                                      */
/*  returns GMT                                                         */
/************************************************************************/
time_t getdate(char *date)
{
    register char *cp;
    register int  i;
    time_t result = 0;
    int  items = 0;
    char *itm[5];
    int  day = 0, month = 0, year = 0;
    int  hour = 0, minute = 0, second = 0;
    time_t tdiff = 0;
    int  got_wday = 0;
    struct tm tms;
    char *datebuf = strdup(date);

    cp = datebuf;
    while(*cp) {
        while(*cp && (*cp == ' ' || *cp == '\t' || *cp == ','))
            *cp++ = '\0';
        if(*cp) {
            if(got_wday || (got_wday = is_wday(cp)) == 0) {
                if(items < 6)
                    itm[items] = cp;
                items++;
            }
            while(*cp && *cp != ' ' && *cp != '\t' && *cp != ',')
                cp++;
        }
    }

    for(i = 0; i < items; i++) {
        if((month = is_month(itm[i])) != 0)
            break;
    }

    if(month) {
        if(i) {
            day = atoi(itm[i - 1]);
            year = atoi(itm[i + 1]);
        }
        else {
            day = atoi(itm[i + 1]);
            year = atoi(itm[i + 2]);
        }
    }
    else {
        for(i = 0; i < items; i++)
            if(strlen(itm[i]) >= 8 && itm[i][2] == '/' && itm[i][5] == '/')
                break;
        if(i < items) {
            month = atoi(itm[i]);
            if(month <= 12)
                day = atoi(&itm[i][3]);
            else {
                day = atoi(itm[i]);
                month = atoi(&itm[i][3]);
            }
            year  = atoi(&itm[i][6]);
        }
        else if(itm[0][0] >= '0' && itm[0][0] <= '9')
            sscanf(itm[0], "%02d%02d%02d%02d%02d%",
                   &year, &month, &day, &hour, &minute);
    }

    if(day && month && year) {
        for(i = 0; i < items; i++)
            if((cp = strchr(itm[i], ':')) != NULL) {
                *cp++ = '\0';
                hour = atoi(itm[i]);
                minute = atoi(cp);
                if((cp = strchr(cp, ':')) != NULL)
                    second = atoi(cp + 1);
                if(++i < items) {
                    if(itm[i][0] == '+' || itm[i][0] == '-')
                        tdiff = (atoi(itm[i]) / 100) * 60;
                    else
                        tdiff = is_tzone(itm[i]);
                }
                break;
            }
        if(year < 70)
            year += 100;
        else if(year > 1970)
            year -= 1900;

        tms.tm_sec = second;
        tms.tm_min = minute;
        tms.tm_hour = hour;
        tms.tm_mday = day;
        tms.tm_mon = month - 1;
        tms.tm_year = year;
        tms.tm_wday = 0;
        tms.tm_yday = 0;
        tms.tm_isdst = 0;
        result = mktime(&tms) - tdiff * 60;
    }
    free(datebuf);

    return(result);
}

#ifdef STANDALONE

/************************************************************************/
/*                                                                      */
/************************************************************************/
int main(int argc, char *argv[])
{
    int i;
    char line[128];
    time_t t;

    if(argc < 2)
        printf("Usage: %s <arpadate>\n", argv[0]);
    else {
        line[0] = '\0';
        for(i = 1; i < argc; i++) {
            strcat(line, argv[i]);
            strcat(line, " ");
        }
        printf("Input :\t%s\n", line);
        t = getdate(line);
        printf( "Result:\t%s", ctime(&t));
    }
    return(0);
}

#endif
[ RETURN TO DIRECTORY ]