#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fn_zonetab.h"
char *
zt_readfile(char *buf, int len, FILE *f) {
int i = 0;
char *cs;
cs = buf;
while (--len > 0 && (i = getc(f)) != EOF)
*(cs++) = i;
*cs = '\0';
return((i == EOF && buf == cs) ? NULL : buf);
}
void
zt_get_token(struct zt_parse *zp) {
int i = 0;
while (*(zp->buf) != '\0' && *(zp->buf) != '\n' && *(zp->buf) != '\t') {
switch (*(zp->buf)) {
case '#':
while (*(zp->buf) != '\n')
zp->buf++;
zp->buf++;
break;
default:
while (*(zp->buf) != '\n' && *(zp->buf) != '\t' &&
*(zp->buf) != '\0') {
if (*(zp->buf) == '/' && zp->state == ZT_REGION) {
zp->tok[i] = '\0';
return;
}
zp->tok[i++] = *(zp->buf++);
}
zp->tok[i] = '\0';
if (zp->state == ZT_LOCALE && *(zp->buf) == '\n')
zp->state = ZT_LOCALE_ENDL;
else if (*(zp->buf) == '\0')
zp->state = ZT_NOTOK;
break;
}
}
}
void
zt_parse(struct zonetab *head) {
FILE *zone_tab;
struct stat sb;
struct zonetab *c;
struct zt_parse zp;
char *file;
zone_tab = fopen(ZONETAB_FILE, "r");
stat(ZONETAB_FILE, &sb);
file = malloc(sb.st_size + 1);
file = zt_readfile(file, sb.st_size, zone_tab);
zp.buf = file;
zp.state = ZT_CC;
c = head;
do {
zt_get_token(&zp);
switch (zp.state) {
case ZT_CC:
c->zt_cc = strdup(zp.tok);
zp.state = ZT_COORDS;
break;
case ZT_COORDS:
c->zt_coords = strdup(zp.tok);
zp.state = ZT_REGION;
break;
case ZT_REGION:
c->zt_region = strdup(zp.tok);
zp.state = ZT_LOCALE;
break;
case ZT_LOCALE:
c->zt_locale = strdup(zp.tok);
zp.state = ZT_COMMENTS;
break;
case ZT_LOCALE_ENDL:
c->zt_locale = strdup(zp.tok);
c->zt_comments = NULL;
c->next = malloc(sizeof(struct zonetab));
c = c->next;
zp.state = ZT_CC;
break;
case ZT_COMMENTS:
c->zt_comments = strdup(zp.tok);
c->next = malloc(sizeof(struct zonetab));
c = c->next;
zp.state = ZT_CC;
break;
case ZT_NOTOK:
goto done;
}
zp.buf++;
} while (1);
done:
c->next = NULL;
free(file);
}