1999-06-21 19:32:08 +00:00
|
|
|
|
/* $Id: zone.c,v 1.5 1999/06/21 19:35:04 akool Exp $
|
1999-06-09 20:58:09 +00:00
|
|
|
|
*
|
1999-06-09 19:57:22 +00:00
|
|
|
|
* Zonenberechnung
|
|
|
|
|
*
|
|
|
|
|
* Copyright 1999 by Leopold Toetsch <lt@toetsch.at>
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
*
|
1999-06-09 20:58:09 +00:00
|
|
|
|
* $Log: zone.c,v $
|
1999-06-21 19:32:08 +00:00
|
|
|
|
* Revision 1.5 1999/06/21 19:35:04 akool
|
|
|
|
|
* isdnlog Version 3.35
|
|
|
|
|
* zone data for .nl (many thanks to Paul!)
|
|
|
|
|
*
|
|
|
|
|
* WARNING: This version of isdnlog dont even compile! *EXPERIMENTAL*!!
|
|
|
|
|
*
|
1999-06-18 12:41:57 +00:00
|
|
|
|
* Revision 1.4 1999/06/18 12:41:57 akool
|
|
|
|
|
* zone V1.0
|
|
|
|
|
*
|
1999-06-15 20:02:54 +00:00
|
|
|
|
* Revision 1.3 1999/06/15 20:05:25 akool
|
|
|
|
|
* isdnlog Version 3.33
|
|
|
|
|
* - big step in using the new zone files
|
|
|
|
|
* - *This*is*not*a*production*ready*isdnlog*!!
|
|
|
|
|
* - Maybe the last release before the I4L meeting in Nuernberg
|
|
|
|
|
*
|
1999-06-09 20:58:09 +00:00
|
|
|
|
* Revision 1.2 1999/06/09 20:58:09 akool
|
|
|
|
|
* CVS-Tags added
|
|
|
|
|
*
|
|
|
|
|
*
|
1999-06-09 19:57:22 +00:00
|
|
|
|
* Interface:
|
|
|
|
|
*
|
|
|
|
|
* int initZone(int provider, char *path, char **msg)
|
|
|
|
|
* initialize returns -1 on error, 0 if ok
|
|
|
|
|
*
|
|
|
|
|
* void exitZone(int provider)
|
|
|
|
|
* deinitialize
|
|
|
|
|
*
|
|
|
|
|
* int getZone(int provider, char *from, char *to)
|
1999-06-18 12:41:57 +00:00
|
|
|
|
* returns zone for provider, UNKNOWN on not found, -2 on error
|
|
|
|
|
*
|
1999-06-21 19:32:08 +00:00
|
|
|
|
* int getAreacode(int countrycode, char *num, char **text)
|
1999-06-18 12:41:57 +00:00
|
|
|
|
* returns len of areacode in num and in text a malloced string
|
|
|
|
|
* UNKNOWN on not found
|
1999-06-09 19:57:22 +00:00
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define _ZONE_C_
|
|
|
|
|
|
|
|
|
|
#ifdef STANDALONE
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
/* Fixme: basename() ist bei libc5 anscheinend nicht definiert
|
|
|
|
|
* k<EFBFBD>nnte da mal jemand ein passende #ifdef herumstricken?
|
|
|
|
|
*/
|
1999-06-15 20:02:54 +00:00
|
|
|
|
/* lt: folgendes funkt bei mir */
|
|
|
|
|
#ifndef __USE_MISC
|
1999-06-09 20:58:09 +00:00
|
|
|
|
extern const char *basename (const char *name);
|
1999-06-15 20:02:54 +00:00
|
|
|
|
#endif
|
1999-06-09 19:57:22 +00:00
|
|
|
|
#else
|
|
|
|
|
#include "isdnlog.h"
|
|
|
|
|
#include "tools.h"
|
|
|
|
|
#endif
|
1999-06-18 12:41:57 +00:00
|
|
|
|
|
1999-06-09 19:57:22 +00:00
|
|
|
|
#include "zone.h"
|
1999-06-18 12:41:57 +00:00
|
|
|
|
/* this config (from config.in) could go in global policy */
|
|
|
|
|
#include "zone/config.h"
|
|
|
|
|
#include "zone/common.h"
|
1999-06-21 19:32:08 +00:00
|
|
|
|
#include <dirent.h>
|
1999-06-09 19:57:22 +00:00
|
|
|
|
|
|
|
|
|
struct sth {
|
1999-06-18 12:41:57 +00:00
|
|
|
|
_DB fh;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
char *path;
|
|
|
|
|
int provider;
|
|
|
|
|
int used;
|
|
|
|
|
int real;
|
|
|
|
|
int *table;
|
|
|
|
|
char pack_key, pack_table;
|
|
|
|
|
int table_size;
|
1999-06-18 12:41:57 +00:00
|
|
|
|
int oz;
|
|
|
|
|
int numlen;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
int cc;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
} ;
|
|
|
|
|
#define min(a,b) (a) < (b) ? (a) : (b)
|
|
|
|
|
|
|
|
|
|
static struct sth *sthp;
|
|
|
|
|
static int count;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
static char version[] = "1.10";
|
|
|
|
|
static bool area_read = false;
|
|
|
|
|
|
1999-06-09 19:57:22 +00:00
|
|
|
|
#define LINK 127
|
|
|
|
|
#define INFO_LEN 80
|
1999-06-21 19:32:08 +00:00
|
|
|
|
#define LENGTH 160
|
1999-06-09 19:57:22 +00:00
|
|
|
|
#define BUFSIZE 200
|
|
|
|
|
|
|
|
|
|
#ifdef STANDALONE
|
|
|
|
|
#define UNKNOWN -1
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static void warning (char *file, char *fmt, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list ap;
|
|
|
|
|
char msg[BUFSIZ];
|
|
|
|
|
|
|
|
|
|
va_start (ap, fmt);
|
|
|
|
|
vsnprintf (msg, BUFSIZ, fmt, ap);
|
|
|
|
|
va_end (ap);
|
|
|
|
|
#ifdef STANDALONE
|
|
|
|
|
fprintf(stderr, "WARNING: %s %s\n", basename(file), msg);
|
|
|
|
|
#else
|
|
|
|
|
print_msg(PRT_NORMAL, "WARNING: %s %s\n", basename(file), msg);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
1999-06-21 19:32:08 +00:00
|
|
|
|
static void _exitZone(int provider);
|
|
|
|
|
|
|
|
|
|
void exitZone(int provider) {
|
|
|
|
|
int i;
|
|
|
|
|
_exitZone(provider);
|
|
|
|
|
for (i=0; i<count; i++)
|
|
|
|
|
if(sthp[i].provider>=10000)
|
|
|
|
|
_exitZone(sthp[i].provider);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void _exitZone(int provider)
|
1999-06-09 19:57:22 +00:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
bool any = false;
|
|
|
|
|
bool found = false;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
for (i=0; i<count; i++)
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (sthp[i].provider == provider) {
|
|
|
|
|
found = true;
|
|
|
|
|
if (sthp[i].real >= 0)
|
|
|
|
|
sthp[sthp[i].real].used--;
|
|
|
|
|
else if (sthp[i].path && sthp[i].used == 0) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
free(sthp[i].path);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
sthp[i].path = 0;
|
|
|
|
|
free(sthp[i].table);
|
|
|
|
|
sthp[i].table = 0;
|
1999-06-18 12:41:57 +00:00
|
|
|
|
CLOSE(sthp[i].fh);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
sthp[i].fh = 0;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (i == count-1) /* last released ? */
|
1999-06-09 20:58:09 +00:00
|
|
|
|
count--;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (!found) {
|
|
|
|
|
warning(sthp[i].path ? sthp[i].path : sthp[sthp[i].real].path,
|
|
|
|
|
"ExitZone for unknown provider %d", provider);
|
|
|
|
|
}
|
1999-06-09 20:58:09 +00:00
|
|
|
|
for (i=0; i<count; i++)
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (sthp[i].used || sthp[i].path) {
|
|
|
|
|
any=true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!any) {
|
|
|
|
|
free(sthp);
|
|
|
|
|
sthp = 0;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
}
|
1999-06-21 19:32:08 +00:00
|
|
|
|
#define ZONES 0
|
|
|
|
|
#define AREACODES 1
|
|
|
|
|
static int _initZone(int provider, char *path, char **msg, bool area_only);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
|
|
|
|
|
int initZone(int provider, char *path, char **msg)
|
|
|
|
|
{
|
|
|
|
|
static char message[LENGTH];
|
1999-06-21 19:32:08 +00:00
|
|
|
|
int res;
|
|
|
|
|
char * dir;
|
|
|
|
|
char * file;
|
|
|
|
|
char *p;
|
|
|
|
|
DIR *dp;
|
|
|
|
|
struct dirent *ep;
|
|
|
|
|
int len, i;
|
|
|
|
|
|
|
|
|
|
if (msg)
|
|
|
|
|
*(*msg=message)='\0';
|
|
|
|
|
res = _initZone(provider, path, msg, ZONES);
|
|
|
|
|
if (area_read)
|
|
|
|
|
return res;
|
|
|
|
|
|
|
|
|
|
area_read = true;
|
|
|
|
|
if ((dir = strdup(path)) == 0) {
|
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
|
|
|
|
"Zone V%s: Error: Out of mem 10", version);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
p = strrchr(dir, '/');
|
|
|
|
|
if ((file = strdup(p+1)) == 0) {
|
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
|
|
|
|
"Zone V%s: Error: Out of mem 11", version);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
p[1] = '\0';
|
|
|
|
|
if ((dp = opendir(dir)) == 0) {
|
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
|
|
|
|
"Zone V%s: Error: Out of mem 11", version);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
len = strchr(file,'-')-file;
|
|
|
|
|
i = 0;
|
|
|
|
|
while ((ep = readdir(dp))) { /* zone-cc-xx */
|
|
|
|
|
if (memcmp(ep->d_name, file, len) == 0 && memcmp(ep->d_name, file, len+3) != 0) {
|
|
|
|
|
int l=strlen(dir)+strlen(ep->d_name)+1;
|
|
|
|
|
char *npath=malloc(l);
|
|
|
|
|
strcpy(npath, dir);
|
|
|
|
|
strcat(npath, ep->d_name);
|
|
|
|
|
_initZone(10000+i, npath, 0, AREACODES);
|
|
|
|
|
i++;
|
|
|
|
|
free(npath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
closedir(dp);
|
|
|
|
|
free(dir);
|
|
|
|
|
free(file);
|
|
|
|
|
if (msg && strlen(message) < LENGTH-5) {
|
|
|
|
|
strcat(message, " - ");
|
|
|
|
|
for (i=0; i<count; i++)
|
|
|
|
|
if(sthp[i].provider>=10000 && sthp[i].cc && strlen(message) < LENGTH-5)
|
|
|
|
|
sprintf(message+strlen(message),"%d ",sthp[i].cc);
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int _initZone(int provider, char *path, char **msg, bool area_only)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
struct sth *newsthp;
|
|
|
|
|
bool found;
|
|
|
|
|
int ocount;
|
|
|
|
|
int csize=0, tsize=0, n;
|
|
|
|
|
datum key, value;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
char *message;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
|
|
|
|
|
if (msg)
|
1999-06-21 19:32:08 +00:00
|
|
|
|
message = *msg;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (!path || !*path) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
1999-06-09 19:57:22 +00:00
|
|
|
|
"Zone V%s: Error: no zone database specified!", version);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ocount = count;
|
|
|
|
|
if (sthp == 0) {
|
|
|
|
|
if ((sthp = calloc(++count, sizeof(struct sth))) == 0) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
1999-06-09 19:57:22 +00:00
|
|
|
|
"Zone V%s: Error: Out of mem 0", version);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* look if we can reuse some space */
|
|
|
|
|
found = false;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
for (i=0; i<ocount; i++)
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (sthp[i].fh == 0) {
|
|
|
|
|
ocount = i;
|
|
|
|
|
found = true;
|
|
|
|
|
break;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
|
|
|
|
if (!found) {
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if ((newsthp = realloc(sthp, sizeof(struct sth) * ++count)) == 0) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
1999-06-09 19:57:22 +00:00
|
|
|
|
"Zone V%s: Error: Out of mem 1", version);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
sthp = newsthp;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
sthp[ocount].path=0;
|
|
|
|
|
sthp[ocount].table=0;
|
|
|
|
|
sthp[ocount].used=0;
|
|
|
|
|
sthp[ocount].fh=0;
|
|
|
|
|
sthp[ocount].real = -1;
|
1999-06-18 12:41:57 +00:00
|
|
|
|
sthp[ocount].oz=1;
|
|
|
|
|
sthp[ocount].numlen=0;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
sthp[ocount].cc=0;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
/* now search for same path */
|
1999-06-09 19:57:22 +00:00
|
|
|
|
found = false;
|
|
|
|
|
for (i=0; i<count-1; i++) {
|
|
|
|
|
if (sthp[i].path && strcmp(sthp[i].path, path) == 0) {
|
|
|
|
|
sthp[ocount].fh = sthp[i].fh;
|
1999-06-18 12:41:57 +00:00
|
|
|
|
sthp[ocount].oz = sthp[i].oz;
|
|
|
|
|
sthp[ocount].numlen = sthp[i].numlen;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
sthp[ocount].pack_key = sthp[i].pack_key;
|
|
|
|
|
sthp[ocount].pack_table = sthp[i].pack_table;
|
|
|
|
|
sthp[ocount].table = sthp[i].table;
|
|
|
|
|
sthp[i].used++;
|
|
|
|
|
sthp[ocount].real = i;
|
|
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sthp[ocount].provider = provider;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (!found) {
|
1999-06-09 19:57:22 +00:00
|
|
|
|
char vinfo[] = "vErSiO";
|
|
|
|
|
char table[] = "_tAbLe";
|
|
|
|
|
char dversion[6];
|
|
|
|
|
char *p, *q;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
|
1999-06-09 19:57:22 +00:00
|
|
|
|
*dversion = '\0';
|
|
|
|
|
if((sthp[ocount].path = strdup(path)) == 0) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
1999-06-09 19:57:22 +00:00
|
|
|
|
"Zone V%s: Error: Out of mem 2", version);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
1999-06-18 12:41:57 +00:00
|
|
|
|
if((sthp[ocount].fh = OPEN(path, READ)) == 0) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
|
|
|
|
"Zone V%s: Error: gdbm_open '%s': '%s'",
|
1999-06-18 12:41:57 +00:00
|
|
|
|
version, path, GET_ERR);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
/* read info */
|
|
|
|
|
key.dptr = vinfo;
|
|
|
|
|
key.dsize = 7;
|
1999-06-18 12:41:57 +00:00
|
|
|
|
value = FETCH(sthp[ocount].fh, key);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (value.dptr == 0) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
1999-06-09 19:57:22 +00:00
|
|
|
|
"Zone V%s: Error: Provider %d File '%s': no Vinfo",
|
|
|
|
|
version, provider, path);
|
|
|
|
|
exitZone(provider);
|
|
|
|
|
return -1;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
for (p=value.dptr; *p; p++) {
|
|
|
|
|
switch (*p) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
case 'V' :
|
1999-06-09 19:57:22 +00:00
|
|
|
|
for (p++,n=0,q=dversion; n<6 && *p != ' '; n++)
|
|
|
|
|
*q++ = *p++;
|
|
|
|
|
*q = '\0';
|
1999-06-18 12:41:57 +00:00
|
|
|
|
if (*dversion != *version) {
|
1999-06-21 19:32:08 +00:00
|
|
|
|
if (msg)
|
1999-06-18 12:41:57 +00:00
|
|
|
|
snprintf (message, LENGTH,
|
|
|
|
|
"Zone V%s: Error: Provider %d File '%s': incompatible Dataversion %s",
|
|
|
|
|
version, provider, path, dversion);
|
|
|
|
|
exitZone(provider);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
1999-06-09 20:58:09 +00:00
|
|
|
|
break;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
case 'K' :
|
|
|
|
|
sthp[ocount].pack_key = *(++p);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
break;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
case 'C' :
|
|
|
|
|
sthp[ocount].pack_table = *(++p);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
break;
|
|
|
|
|
case 'N' :
|
1999-06-09 19:57:22 +00:00
|
|
|
|
p++;
|
|
|
|
|
csize = strtol(p, &p, 10);
|
|
|
|
|
break;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
case 'T' :
|
1999-06-09 19:57:22 +00:00
|
|
|
|
p++;
|
|
|
|
|
tsize = strtol(p, &p, 10);
|
|
|
|
|
break;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
case 'O' :
|
1999-06-18 12:41:57 +00:00
|
|
|
|
p++;
|
|
|
|
|
sthp[ocount].oz = strtol(p, &p, 10);
|
|
|
|
|
break;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
case 'L' :
|
1999-06-18 12:41:57 +00:00
|
|
|
|
p++;
|
|
|
|
|
sthp[ocount].numlen = strtol(p, &p, 10);
|
|
|
|
|
break;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
case 'A' : /* this provider has the areacodes for county A */
|
|
|
|
|
p++;
|
|
|
|
|
sthp[ocount].cc = strtol(p, &p, 10);
|
|
|
|
|
break;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
|
|
|
|
} /* for */
|
1999-06-09 19:57:22 +00:00
|
|
|
|
free (value.dptr);
|
|
|
|
|
/* check it */
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (strlen(dversion) == 0 ||
|
1999-06-09 19:57:22 +00:00
|
|
|
|
sthp[ocount].pack_key == '\x0' ||
|
|
|
|
|
strchr("SL", sthp[ocount].pack_key) == 0 ||
|
|
|
|
|
sthp[ocount].pack_table == '\x0' ||
|
|
|
|
|
strchr("CSL", sthp[ocount].pack_table) == 0 ||
|
1999-06-18 12:41:57 +00:00
|
|
|
|
sthp[ocount].numlen == 0 ||
|
1999-06-09 19:57:22 +00:00
|
|
|
|
csize == 0 ||
|
|
|
|
|
tsize == 0) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
1999-06-18 12:41:57 +00:00
|
|
|
|
"Zone V%s: Error: Provider %d File '%s' seems to be corrupted:\n%s",
|
|
|
|
|
version, provider, path, value.dptr);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
exitZone(provider);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
1999-06-09 20:58:09 +00:00
|
|
|
|
sthp[ocount].pack_table = sthp[ocount].pack_table == 'C' ? sizeof(char) :
|
1999-06-09 19:57:22 +00:00
|
|
|
|
sthp[ocount].pack_table == 'S' ? sizeof(short) : sizeof(long);
|
|
|
|
|
sthp[ocount].pack_key = sthp[ocount].pack_key == 'S' ? sizeof(short) : sizeof(long);
|
1999-06-21 19:32:08 +00:00
|
|
|
|
|
|
|
|
|
if (area_only) {
|
|
|
|
|
if (sthp[ocount].cc == 0)
|
|
|
|
|
_exitZone(provider); /* discard this one */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* alloc & read table */
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if ( (sthp[ocount].table = calloc(csize > 256 ? 256 : csize,
|
1999-06-09 19:57:22 +00:00
|
|
|
|
sizeof(int)) ) == 0) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
1999-06-09 19:57:22 +00:00
|
|
|
|
"Zone V%s: Error: Out of mem 3", version);
|
|
|
|
|
exitZone(provider);
|
|
|
|
|
return -1;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
key.dptr = table;
|
|
|
|
|
key.dsize = 7;
|
1999-06-18 12:41:57 +00:00
|
|
|
|
value = FETCH(sthp[ocount].fh, key);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (value.dptr == 0) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
1999-06-09 19:57:22 +00:00
|
|
|
|
"Zone V%s: Error: Provider %d File '%s': no NTable",
|
|
|
|
|
version, provider, path);
|
|
|
|
|
exitZone(provider);
|
|
|
|
|
return -1;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
|
|
|
|
for (p = value.dptr, i=0; i< (csize > 256 ? 256 : csize); i++)
|
1999-06-09 19:57:22 +00:00
|
|
|
|
sthp[ocount].table[i] =
|
|
|
|
|
sthp[ocount].pack_table == 1 ? (int)(UC)*((UC*)p)++ :
|
|
|
|
|
sthp[ocount].pack_table == 2 ? (int)(US)*((US*)p)++ :
|
|
|
|
|
(int)(UL)*((UL*)p)++;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
free(value.dptr);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (msg) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
snprintf (message, LENGTH,
|
1999-06-09 19:57:22 +00:00
|
|
|
|
"Zone V%s: Provider %d File '%s' opened fine - "
|
1999-06-21 19:32:08 +00:00
|
|
|
|
"V%s K%d C%d N%d T%d O%d L%d A%d",
|
1999-06-09 19:57:22 +00:00
|
|
|
|
version, provider, path,
|
|
|
|
|
dversion, sthp[ocount].pack_key, sthp[ocount].pack_table,
|
1999-06-21 19:32:08 +00:00
|
|
|
|
csize, tsize, sthp[ocount].oz, sthp[ocount].numlen, sthp[ocount].cc);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (msg)
|
|
|
|
|
snprintf (message, LENGTH,
|
1999-06-09 19:57:22 +00:00
|
|
|
|
"Zone V%s: Provider %d is open as '%s' for provider %d",
|
|
|
|
|
version, provider, path, sthp[sthp[ocount].real].provider);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int _getZ(struct sth *sthp, char *from, char *sto) {
|
|
|
|
|
GDBM_FILE fh = sthp->fh;
|
|
|
|
|
datum key, value;
|
|
|
|
|
static char newfrom[LENGTH];
|
|
|
|
|
bool found = false;
|
|
|
|
|
char *temp;
|
1999-06-18 12:41:57 +00:00
|
|
|
|
int res;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
|
1999-06-21 19:32:08 +00:00
|
|
|
|
if ((res=strcmp(from, sto)) == 0)
|
1999-06-18 12:41:57 +00:00
|
|
|
|
return sthp->oz;
|
|
|
|
|
else if (res > 0) {
|
1999-06-09 19:57:22 +00:00
|
|
|
|
temp=from;
|
|
|
|
|
from=sto;
|
|
|
|
|
sto=temp;
|
|
|
|
|
}
|
1999-06-09 20:58:09 +00:00
|
|
|
|
strncpy(newfrom, from, LENGTH-1);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
while (strlen(newfrom)) {
|
1999-06-15 20:02:54 +00:00
|
|
|
|
UL lifrom = (UL) atol(newfrom); /* keys could be long */
|
1999-06-21 19:32:08 +00:00
|
|
|
|
US ifrom = (US) lifrom;
|
1999-06-15 20:02:54 +00:00
|
|
|
|
if (sthp->pack_key == 2) {
|
1999-06-09 20:58:09 +00:00
|
|
|
|
key.dptr = (char *) &ifrom;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
key.dsize = sizeof(US);
|
1999-06-15 20:02:54 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
key.dptr = (char *) &lifrom;
|
|
|
|
|
key.dsize = sizeof(UL);
|
|
|
|
|
}
|
1999-06-18 12:41:57 +00:00
|
|
|
|
value = FETCH(fh, key);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (value.dptr) {
|
|
|
|
|
char *p = value.dptr;
|
|
|
|
|
char to[10];
|
|
|
|
|
US count;
|
|
|
|
|
int ito;
|
|
|
|
|
unsigned char z=0;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
if (sthp->cc) /* if areacodes */
|
1999-06-18 12:41:57 +00:00
|
|
|
|
/* here is since 1.00 a zero-terminated strring */
|
|
|
|
|
while (*p++);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
count = *((US*)p)++;
|
|
|
|
|
while (count--) {
|
|
|
|
|
bool ind = true;
|
|
|
|
|
int len=1;
|
|
|
|
|
z = *p++;
|
|
|
|
|
if (z >= 128) {
|
|
|
|
|
z -= 128;
|
|
|
|
|
ind = false;
|
|
|
|
|
len = sthp->pack_key;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
|
|
|
|
ito = len==1 ? (int)*((UC*)p)++ :
|
1999-06-09 19:57:22 +00:00
|
|
|
|
len==2 ? (int)*((US*)p)++ : (int)*((UL*)p)++;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if (ind)
|
1999-06-09 19:57:22 +00:00
|
|
|
|
ito = sthp->table[ito];
|
|
|
|
|
if (z == LINK) {
|
|
|
|
|
sprintf(newfrom, "%d", ito);
|
|
|
|
|
free(value.dptr);
|
|
|
|
|
return _getZ(sthp, newfrom, sto);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
else {
|
|
|
|
|
sprintf(to, "%d", ito);
|
|
|
|
|
if (memcmp(to, sto, strlen(to))==0) {
|
|
|
|
|
found = true;
|
|
|
|
|
break;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
free(value.dptr);
|
|
|
|
|
if (found)
|
|
|
|
|
return z;
|
|
|
|
|
} /* if dptr */
|
|
|
|
|
newfrom[strlen(newfrom)-1] = '\0';
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-18 12:41:57 +00:00
|
|
|
|
return UNKNOWN;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
|
|
|
|
|
int getZone(int provider, char *from, char *to)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
for (i=0; i<count; i++)
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (sthp[i].provider == provider) {
|
|
|
|
|
if (sthp[i].fh == 0)
|
|
|
|
|
return UNKNOWN;
|
|
|
|
|
return _getZ(&sthp[i], from, to);
|
|
|
|
|
}
|
1999-06-09 20:58:09 +00:00
|
|
|
|
return UNKNOWN;
|
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
|
1999-06-18 12:41:57 +00:00
|
|
|
|
static int _getAreacode(struct sth *sthp, char *from, char **text) {
|
|
|
|
|
_DB fh = sthp->fh;
|
|
|
|
|
datum key, value;
|
|
|
|
|
static char newfrom[LENGTH];
|
|
|
|
|
bool found = false;
|
|
|
|
|
int len;
|
|
|
|
|
strncpy(newfrom, from, sthp->numlen);
|
|
|
|
|
newfrom[sthp->numlen] = '\0';
|
|
|
|
|
while ((len=strlen(newfrom))) {
|
|
|
|
|
UL lifrom = (UL) atol(newfrom); /* keys could be long */
|
1999-06-21 19:32:08 +00:00
|
|
|
|
US ifrom = (US) lifrom;
|
1999-06-18 12:41:57 +00:00
|
|
|
|
if (sthp->pack_key == 2) {
|
1999-06-21 19:32:08 +00:00
|
|
|
|
if (lifrom >= 0x10000) { /* can't be, so cut a digit */
|
|
|
|
|
newfrom[strlen(newfrom) - 1] = '\0';
|
|
|
|
|
continue;
|
|
|
|
|
} /* if */
|
1999-06-18 12:41:57 +00:00
|
|
|
|
key.dptr = (char *) &ifrom;
|
|
|
|
|
key.dsize = sizeof(US);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
key.dptr = (char *) &lifrom;
|
|
|
|
|
key.dsize = sizeof(UL);
|
|
|
|
|
}
|
|
|
|
|
value = FETCH(fh, key);
|
|
|
|
|
if (value.dptr) {
|
|
|
|
|
if (!*value.dptr) {/* found shortcut */
|
|
|
|
|
if (*dbv == 'G') /* GDBM has a malloced string in dptr */
|
|
|
|
|
free(value.dptr);
|
|
|
|
|
return UNKNOWN;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
}
|
1999-06-18 12:41:57 +00:00
|
|
|
|
if (*dbv == 'G') /* GDBM has a malloced string in dptr */
|
|
|
|
|
*text = value.dptr;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
else
|
1999-06-18 12:41:57 +00:00
|
|
|
|
*text = strdup(value.dptr);
|
|
|
|
|
return len;
|
|
|
|
|
} /* if dptr */
|
|
|
|
|
newfrom[strlen(newfrom)-1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
return UNKNOWN;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
}
|
1999-06-18 12:41:57 +00:00
|
|
|
|
|
|
|
|
|
int getAreacode(int provider, char *from, char **text)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
char *path=NULL;
|
|
|
|
|
for (i=0; i<count; i++)
|
|
|
|
|
if (sthp[i].provider == provider) {
|
|
|
|
|
path = sthp[i].path ? sthp[i].path : sthp[sthp[i].real].path;
|
|
|
|
|
if (sthp[i].fh == 0)
|
|
|
|
|
return UNKNOWN;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
return _getAreacode(&sthp[i], from, text);
|
|
|
|
|
}
|
1999-06-18 12:41:57 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
|
1999-06-18 12:41:57 +00:00
|
|
|
|
#ifdef STANDALONE
|
1999-06-09 19:57:22 +00:00
|
|
|
|
|
1999-06-09 20:58:09 +00:00
|
|
|
|
static int checkZone(char *zf, char* df,int num1,int num2, bool verbose)
|
1999-06-09 19:57:22 +00:00
|
|
|
|
{
|
|
|
|
|
char *msg;
|
|
|
|
|
int z, ret=0;
|
|
|
|
|
char from[10];
|
|
|
|
|
char to[10];
|
|
|
|
|
if (initZone(1, df, &msg)) {
|
|
|
|
|
fprintf(stderr,"%s\n", msg);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
1999-06-18 12:41:57 +00:00
|
|
|
|
if(verbose)
|
|
|
|
|
printf("%s\n", msg);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (num1 && num2) {
|
|
|
|
|
snprintf(from, 9, "%d",num1);
|
|
|
|
|
snprintf(to, 9, "%d",num2);
|
|
|
|
|
ret = getZone(1, from, to);
|
|
|
|
|
printf("%s %s = %d\n", from, to, ret);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
else {
|
|
|
|
|
FILE *fp;
|
|
|
|
|
char line[40];
|
|
|
|
|
char *p, *q;
|
|
|
|
|
int rz, i, n;
|
|
|
|
|
if ((fp = fopen(zf, "r")) == 0) {
|
|
|
|
|
fprintf(stderr, "Can't read %s\n", zf);
|
|
|
|
|
exitZone(1);
|
|
|
|
|
exit(1);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
n=0;
|
|
|
|
|
while (!feof(fp)) {
|
|
|
|
|
if((++n % 1000) == 0 && verbose) {
|
|
|
|
|
fprintf(stderr,"%d\r",n);
|
|
|
|
|
fflush(stderr);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
fgets(line, 39, fp);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
p=line;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
q=from;
|
|
|
|
|
if (!isdigit(*p))
|
|
|
|
|
continue;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
i=0;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
while (isdigit(*p) && ++i<9) {
|
|
|
|
|
*q++ = *p++;
|
|
|
|
|
}
|
|
|
|
|
*q = '\0';
|
1999-06-09 20:58:09 +00:00
|
|
|
|
p++;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
q=to;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
i=0;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
while (isdigit(*p) && ++i<9) {
|
|
|
|
|
*q++ = *p++;
|
|
|
|
|
}
|
|
|
|
|
*q = '\0';
|
|
|
|
|
p++;
|
|
|
|
|
rz = atoi(p);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
if ((z=getZone(1, from, to)) != rz) {
|
|
|
|
|
if(verbose)
|
1999-06-09 19:57:22 +00:00
|
|
|
|
printf("Err: %s %s = %d not %d\n", from, to, rz, z);
|
|
|
|
|
ret = -1;
|
|
|
|
|
break;
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
}
|
1999-06-09 20:58:09 +00:00
|
|
|
|
fclose(fp);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
if (verbose)
|
1999-06-18 12:41:57 +00:00
|
|
|
|
printf("'%s' verified %s.\n", df, ret==0? "Ok": "NoNo");
|
|
|
|
|
}
|
|
|
|
|
exitZone(1);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
1999-06-21 19:32:08 +00:00
|
|
|
|
static int checkArea(char *df, int cc, char *from, int verbose) {
|
1999-06-18 12:41:57 +00:00
|
|
|
|
char *msg, *text;
|
|
|
|
|
int ret=0;
|
|
|
|
|
|
|
|
|
|
if (initZone(1, df, &msg)) {
|
|
|
|
|
fprintf(stderr,"%s\n", msg);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
if(verbose)
|
|
|
|
|
printf("%s\n", msg);
|
1999-06-21 19:32:08 +00:00
|
|
|
|
ret = getAreacode(cc, from, &text);
|
1999-06-18 12:41:57 +00:00
|
|
|
|
if(ret != UNKNOWN) {
|
1999-06-21 19:32:08 +00:00
|
|
|
|
printf("%s:%d '%s'\n", from, ret, text);
|
1999-06-18 12:41:57 +00:00
|
|
|
|
free(text);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
}
|
1999-06-18 12:41:57 +00:00
|
|
|
|
else
|
1999-06-21 19:32:08 +00:00
|
|
|
|
printf("%s - UNKNOWN\n", from);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
exitZone(1);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
return ret;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main (int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
int verbose=false;
|
|
|
|
|
char *df=0;
|
|
|
|
|
char *zf=0;
|
|
|
|
|
int c;
|
|
|
|
|
int num1=0, num2=0;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
int cc=0;
|
1999-06-18 12:41:57 +00:00
|
|
|
|
char snum1[LENGTH];
|
1999-06-21 19:32:08 +00:00
|
|
|
|
while ( (c=getopt(argc, argv, "vVd:z:a:")) != EOF) {
|
1999-06-09 19:57:22 +00:00
|
|
|
|
switch (c) {
|
|
|
|
|
case 'v' : verbose = true; break;
|
|
|
|
|
case 'V' : printf("%s: V%s\n", basename(argv[0]), version); exit(1);
|
|
|
|
|
case 'd' : df = strdup(optarg); break;
|
|
|
|
|
case 'z' : zf = strdup(optarg); break;
|
1999-06-21 19:32:08 +00:00
|
|
|
|
case 'a' : cc = atoi(optarg); break;
|
1999-06-09 19:57:22 +00:00
|
|
|
|
}
|
1999-06-09 20:58:09 +00:00
|
|
|
|
}
|
1999-06-09 19:57:22 +00:00
|
|
|
|
while (optind < argc) {
|
|
|
|
|
if (!num1 && isdigit(*argv[optind])) {
|
|
|
|
|
num1 = atoi(argv[optind]);
|
1999-06-18 12:41:57 +00:00
|
|
|
|
strncpy(snum1, argv[optind], LENGTH);
|
1999-06-09 19:57:22 +00:00
|
|
|
|
optind++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (!num2 && isdigit(*argv[optind])) {
|
|
|
|
|
num2 = atoi(argv[optind]);
|
|
|
|
|
optind++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
optind++;
|
|
|
|
|
}
|
|
|
|
|
if (df && (zf || (num1 && num2)))
|
1999-06-09 20:58:09 +00:00
|
|
|
|
return checkZone(zf, df, num1, num2, verbose);
|
1999-06-18 12:41:57 +00:00
|
|
|
|
if (df && num1)
|
1999-06-21 19:32:08 +00:00
|
|
|
|
return checkArea(df, snum1, verbose);
|
1999-06-09 20:58:09 +00:00
|
|
|
|
fprintf(stderr, "Usage:\n%s -d DBfile -v -V { -z Zonefile | num1 num2 }\n", basename(argv[0]));
|
1999-06-18 12:41:57 +00:00
|
|
|
|
fprintf(stderr, "\t-d DBfile -v -V num1\n");
|
1999-06-09 19:57:22 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|