isdn4k-utils/lib/isdntools.c

1416 lines
34 KiB
C
Raw Normal View History

The modifications remove a bug which occurs when dealing with special numbers and the callerid.conf file. Regular numbers such as +4940555 can be noted in the following way in a NUMBER line: NUMBER=+49-40-555, +49-69-555 For special numbers prior to this modifications there are strong unmentioned limitations. Only one number per NUMBER line is allowed without any of the options shown above. Allowed: NUMBER=01802555 Not allowed/not working: NUMBER=01802-555 also not working: NUMBER=0180255, 0700555 This modification brings the later two examples in function. About the background of the problem: isdnlog/isdnrep and other know a sort of telephone numbers called `special numbers', which are noted with S: and N: Tags in the rate-file. These numbers are per definition only available within the country. In order to emphasize this and for other more practical reasons, the normalized format for this numbers is not the usual +<countrycode><areacode><local number> but the national format like 01802555. While the logged numbers in /var/log/isdn.log or so follow this convention, such entries in callerid.conf got internally converted to the normalized format (+49180255 in case of the last mentioned number) so that the comparison executed by isdnlog or isdnrep did not show the expected result. The modification activates the advanced feature in the notation of normal numbers for special numbers. IMPORTANT NOTE: As the resulting library is located outside the isdnlog subdirectory, this changes may influence other parts of the isdn4k-utils.
2003-07-23 20:55:39 +00:00
/* $Id: isdntools.c,v 1.29 2003/07/23 20:55:39 tobiasb Exp $
1997-03-03 04:23:12 +00:00
*
* ISDN accounting for isdn4linux. (Utilities)
*
1997-06-15 23:50:34 +00:00
* Copyright 1995, 1997 by Stefan Luethje (luethje@sl-gw.lake.de)
1997-03-03 04:23:12 +00:00
*
* 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.
*
* $Log: isdntools.c,v $
The modifications remove a bug which occurs when dealing with special numbers and the callerid.conf file. Regular numbers such as +4940555 can be noted in the following way in a NUMBER line: NUMBER=+49-40-555, +49-69-555 For special numbers prior to this modifications there are strong unmentioned limitations. Only one number per NUMBER line is allowed without any of the options shown above. Allowed: NUMBER=01802555 Not allowed/not working: NUMBER=01802-555 also not working: NUMBER=0180255, 0700555 This modification brings the later two examples in function. About the background of the problem: isdnlog/isdnrep and other know a sort of telephone numbers called `special numbers', which are noted with S: and N: Tags in the rate-file. These numbers are per definition only available within the country. In order to emphasize this and for other more practical reasons, the normalized format for this numbers is not the usual +<countrycode><areacode><local number> but the national format like 01802555. While the logged numbers in /var/log/isdn.log or so follow this convention, such entries in callerid.conf got internally converted to the normalized format (+49180255 in case of the last mentioned number) so that the comparison executed by isdnlog or isdnrep did not show the expected result. The modification activates the advanced feature in the notation of normal numbers for special numbers. IMPORTANT NOTE: As the resulting library is located outside the isdnlog subdirectory, this changes may influence other parts of the isdn4k-utils.
2003-07-23 20:55:39 +00:00
* Revision 1.29 2003/07/23 20:55:39 tobiasb
* The modifications remove a bug which occurs when dealing with special
* numbers and the callerid.conf file. Regular numbers such as +4940555
* can be noted in the following way in a NUMBER line:
* NUMBER=+49-40-555, +49-69-555
*
* For special numbers prior to this modifications there are strong
* unmentioned limitations. Only one number per NUMBER line is allowed
* without any of the options shown above.
* Allowed: NUMBER=01802555
* Not allowed/not working: NUMBER=01802-555
* also not working: NUMBER=0180255, 0700555
*
* This modification brings the later two examples in function. About the
* background of the problem: isdnlog/isdnrep and other know a sort of
* telephone numbers called `special numbers', which are noted with S: and
* N: Tags in the rate-file. These numbers are per definition only available
* within the country. In order to emphasize this and for other more
* practical reasons, the normalized format for this numbers is not the
* usual +<countrycode><areacode><local number> but the national format
* like 01802555.
*
* While the logged numbers in /var/log/isdn.log or so follow this convention,
* such entries in callerid.conf got internally converted to the normalized
* format (+49180255 in case of the last mentioned number) so that the
* comparison executed by isdnlog or isdnrep did not show the expected
* result.
*
* The modification activates the advanced feature in the notation of normal
* numbers for special numbers.
*
* IMPORTANT NOTE: As the resulting library is located outside the isdnlog
* subdirectory, this changes may influence other parts of the isdn4k-utils.
*
* Revision 1.28 2001/08/18 11:59:01 paul
* Added missing endpwent() call that meant /etc/passwd was being kept open;
* reorganized num_match() a bit; made the arrays in expand_number() one byte
* bigger to prevent possible off-by-one buffer overflow.
*
* Revision 1.27 2000/09/05 08:05:03 paul
* Now isdnlog doesn't use any more ISDN_XX defines to determine the way it works.
* It now uses the value of "COUNTRYCODE = 999" to determine the country, and sets
* a variable mycountrynum to that value. That is then used in the code to set the
* way isdnlog works.
* It works for me, please check it! No configure.in / doc changes yet until
* it has been checked to work.
* So finally a version of isdnlog that can be compiled and distributed
* internationally.
*
* Revision 1.26 1999/08/20 19:43:46 akool
* removed avon-, vorwahl- and areacodes-support
*
* Revision 1.25 1999/06/11 15:46:54 akool
* not required references to libndbm removed
*
* Revision 1.24 1998/12/16 20:57:30 akool
* - first try to add the 1999 tarif of the German Telekom
* - fix the areacode 2.0 support
*
1998-10-13 21:53:17 +00:00
* Revision 1.23 1998/10/13 21:53:26 luethje
* isdnrep and lib: bugfixes
*
* Revision 1.22 1998/09/26 18:30:30 akool
* - quick and dirty Call-History in "-m" Mode (press "h" for more info) added
* - eat's one more socket, Stefan: sockets[3] now is STDIN, FIRST_DESCR=4 !!
* - Support for tesion)) Baden-Wuerttemberg Tarif
* - more Providers
* - Patches from Wilfried Teiken <wteiken@terminus.cl-ki.uni-osnabrueck.de>
* - better zone-info support in "tools/isdnconf.c"
* - buffer-overrun in "isdntools.c" fixed
* - big Austrian Patch from Michael Reinelt <reinelt@eunet.at>
* - added $(DESTDIR) in any "Makefile.in"
* - new Configure-Switches "ISDN_AT" and "ISDN_DE"
* - splitted "takt.c" and "tools.c" into
* "takt_at.c" / "takt_de.c" ...
* "tools_at.c" / "takt_de.c" ...
* - new feature
* CALLFILE = /var/log/caller.log
* CALLFMT = %b %e %T %N7 %N3 %N4 %N5 %N6
* in "isdn.conf"
* - ATTENTION:
* 1. "isdnrep" dies with an seg-fault, if not HTML-Mode (Stefan?)
* 2. "isdnlog/Makefile.in" now has hardcoded "ISDN_DE" in "DEFS"
* should be fixed soon
*
* Revision 1.21 1998/06/07 21:03:26 akool
* Renamed old to new zone-names (CityCall, RegioCall, GermanCall, GlobalCall)
*
1998-05-11 19:43:43 +00:00
* Revision 1.20 1998/05/11 19:43:49 luethje
* Some changes for "vorwahlen.dat"
*
1998-05-10 22:11:47 +00:00
* Revision 1.19 1998/05/10 22:12:01 luethje
* Added support for VORWAHLEN2.EXE
*
1998-04-28 08:33:52 +00:00
* Revision 1.18 1998/04/28 08:34:36 paul
* Fixed compiler warnings from egcs.
*
1998-03-08 12:13:38 +00:00
* Revision 1.17 1998/03/08 12:13:49 luethje
* Patches by Paul Slootman
*
1997-06-22 22:57:08 +00:00
* Revision 1.16 1997/06/22 22:57:08 luethje
* bugfixes
*
1997-06-15 23:50:34 +00:00
* Revision 1.15 1997/06/15 23:50:34 luethje
* some bugfixes
*
1997-05-19 23:37:05 +00:00
* Revision 1.14 1997/05/19 23:37:05 luethje
* bugfix for isdnconf
*
* Revision 1.13 1997/05/19 22:58:28 luethje
* - bugfix: it is possible to install isdnlog now
* - improved performance for read files for vbox files and mgetty files.
* - it is possible to decide via config if you want to use avon or
* areacode.
*
* Revision 1.12 1997/05/09 23:31:06 luethje
* isdnlog: new switch -O
* isdnrep: new format %S
* bugfix in handle_runfiles()
*
* Revision 1.11 1997/04/15 00:20:17 luethje
* replace variables: some bugfixes, README comleted
*
* Revision 1.10 1997/04/08 21:57:04 luethje
* Create the file isdn.conf
* some bug fixes for pid and lock file
* make the prefix of the code in `isdn.conf' variable
*
* Revision 1.9 1997/04/08 00:02:24 luethje
* Bugfix: isdnlog is running again ;-)
* isdnlog creates now a file like /var/lock/LCK..isdnctrl0
* README completed
* Added some values (countrycode, areacode, lock dir and lock file) to
* the global menu
*
* Revision 1.8 1997/04/03 22:39:13 luethje
* bug fixes: environ variables are working again, no seg. 11 :-)
* improved performance for reading the config files.
*
* Revision 1.7 1997/03/20 00:19:27 luethje
* inserted the line #include <errno.h> in avmb1/avmcapictrl.c and imon/imon.c,
* some bugfixes, new structure in isdnlog/isdnrep/isdnrep.c.
*
* Revision 1.6 1997/03/19 00:08:43 luethje
* README and function expand_number() completed.
*
1997-03-18 23:01:47 +00:00
* Revision 1.5 1997/03/18 23:01:50 luethje
* Function Compare_Sections() completed.
*
* Revision 1.4 1997/03/07 23:34:49 luethje
* README.conffile completed, paranoid_check() used by read_conffiles(),
* policy.h will be removed by "make distclean".
*
* Revision 1.3 1997/03/06 20:36:34 luethje
* Problem in create_runfie() fixed. New function paranoia_check() implemented.
*
* Revision 1.2 1997/03/03 22:05:39 luethje
* merging of the current version and my tree
1997-03-03 04:23:12 +00:00
*
* Revision 2.6.26 1997/01/19 22:23:43 akool
* Weitere well-known number's hinzugefuegt
*
* Revision 2.6.24 1997/01/15 19:13:43 akool
* neue AreaCode Lib 0.99 integriert
*
* Revision 2.6.20 1997/01/05 20:06:43 akool
* atom() erkennt nun "non isdnlog" "/tmp/isdnctrl0" Output's
*
* Revision 2.6.19 1997/01/05 19:39:43 akool
* AREACODE Support added
*
* Revision 2.40 1996/06/16 10:06:43 akool
* double2byte(), time2str() added
*
* Revision 2.3.26 1996/05/05 12:09:16 akool
* known.interface added
*
* Revision 2.3.15 1996/04/22 21:10:16 akool
*
* Revision 2.3.4 1996/04/05 11:12:16 sl
* confdir()
*
* Revision 2.2.5 1996/03/25 19:41:16 akool
* 1TR6 causes implemented
*
* Revision 2.23 1996/03/14 20:29:16 akool
* Neue Routine i2a()
*
* Revision 2.17 1996/02/25 19:14:16 akool
* Soft-Error in atom() abgefangen
*
* Revision 2.06 1996/02/07 18:49:16 akool
* AVON-Handling implementiert
*
* Revision 2.01 1996/01/20 12:11:16 akool
* Um Einlesen der neuen isdnlog.conf Felder erweitert
* discardconfig() implementiert
*
* Revision 2.00 1996/01/10 20:11:16 akool
*
*/
/****************************************************************************/
#define PUBLIC /**/
#define _ISDNTOOLS_C_
1998-04-28 08:33:52 +00:00
#define _GNU_SOURCE
1997-03-03 04:23:12 +00:00
/****************************************************************************/
#include <errno.h>
1997-03-03 04:23:12 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
1998-05-10 22:11:47 +00:00
#include <netinet/in.h>
1997-03-03 04:23:12 +00:00
#include "libisdn.h"
/****************************************************************************/
1998-05-10 22:11:47 +00:00
#define GERMAN_CODE 49
/****************************************************************************/
typedef struct {
char code[15];
long int pointer;
} s_areacode;
/****************************************************************************/
1997-03-03 04:23:12 +00:00
static int (*print_msg)(const char *, ...) = printf;
#if 0 /* DELETE_ME AK:18-Aug-99 */
#ifdef LIBAREA
1997-03-03 04:23:12 +00:00
static char *_get_areacode(char *code, int *Len, int flag);
#else
static char *_get_avon(char *code, int *Len, int flag);
#endif
#endif
static int create_runfile(const char *file, const char *format);
#if 0 /* DELETE_ME AK:18-Aug-99 */
1998-05-10 22:11:47 +00:00
static long int area_read_value(FILE *fp, int size);
static int area_read_file(void);
static int area_get_index(char *code);
#endif
The modifications remove a bug which occurs when dealing with special numbers and the callerid.conf file. Regular numbers such as +4940555 can be noted in the following way in a NUMBER line: NUMBER=+49-40-555, +49-69-555 For special numbers prior to this modifications there are strong unmentioned limitations. Only one number per NUMBER line is allowed without any of the options shown above. Allowed: NUMBER=01802555 Not allowed/not working: NUMBER=01802-555 also not working: NUMBER=0180255, 0700555 This modification brings the later two examples in function. About the background of the problem: isdnlog/isdnrep and other know a sort of telephone numbers called `special numbers', which are noted with S: and N: Tags in the rate-file. These numbers are per definition only available within the country. In order to emphasize this and for other more practical reasons, the normalized format for this numbers is not the usual +<countrycode><areacode><local number> but the national format like 01802555. While the logged numbers in /var/log/isdn.log or so follow this convention, such entries in callerid.conf got internally converted to the normalized format (+49180255 in case of the last mentioned number) so that the comparison executed by isdnlog or isdnrep did not show the expected result. The modification activates the advanced feature in the notation of normal numbers for special numbers. IMPORTANT NOTE: As the resulting library is located outside the isdnlog subdirectory, this changes may influence other parts of the isdn4k-utils.
2003-07-23 20:55:39 +00:00
static char *expand_number_all (char *s, int add_prefix);
static char *expand_number_pure (char *s);
1997-03-03 04:23:12 +00:00
/****************************************************************************/
#if 0 /* DELETE_ME AK:18-Aug-99 */
1997-03-03 04:23:12 +00:00
static char areacodes[][2][30] = {
{"+49130", "Toll-free"},
{"+491802", "Service 180-2 (0,12/Anruf)"},
{"+491803", "Service 180-3 (DM 0,24/Anruf)"},
{"+491805", "Service 180-5 (DM 0,48/Anruf)"},
{"+491901", "Service 190 (DM 1,20/Minute)"},
{"+491902", "Service 190 (DM 1,20/Minute)"},
{"+491903", "Service 190 (DM 1,20/Minute)"},
{"+491904", "Service 190 (DM 0,80/Minute)"},
{"+491905", "Service 190 (DM 1,20/Minute)"},
{"+491906", "Service 190 (DM 0,80/Minute)"},
{"+491907", "Service 190 (DM 2,40/Minute)"},
{"+491908", "Service 190 (DM 3,60/Minute)"},
{"+491909", "Service 190 (DM 2,40/Minute)"},
{"+49161", "Mobilfunknetz C"},
{"+49171", "Mobilfunknetz D1"},
{"+49172", "Mobilfunknetz D2"},
{"+49177", "Mobilfunknetz E-Plus"},
{"+491188", "Auskunft Inland"},
{"+491910", "T-Online"},
{"", ""},
};
static char countrycodes[][2][30] = {
1998-03-08 12:13:38 +00:00
{"+30", "Greece"},
{"+31", "Netherlands"},
1997-03-03 04:23:12 +00:00
{"+32", "Belgium"},
{"+33", "France"},
{"+34", "Spain"},
{"+39", "Italy"},
1998-03-08 12:13:38 +00:00
{"+41", "Switzerland"},
1997-03-03 04:23:12 +00:00
{"+43", "Austria"},
{"+44", "Great Britain"},
1998-03-08 12:13:38 +00:00
{"+45", "Denmark"},
1997-03-03 04:23:12 +00:00
{"+46", "Sweden"},
{"+47", "Norway"},
{"+49", "Germany"},
1998-03-08 12:13:38 +00:00
{"+352", "Luxemburg"},
1997-03-03 04:23:12 +00:00
{"+1", "United States"},
{"", ""},
};
static char *avonlib = NULL;
static char *codelib = NULL;
1998-05-10 22:11:47 +00:00
static s_areacode *codes = NULL;
static int codes_number = 0;
#endif
1997-03-03 04:23:12 +00:00
/****************************************************************************/
void set_print_fct_for_lib(int (*new_print_msg)(const char *, ...))
1997-03-03 04:23:12 +00:00
{
print_msg = new_print_msg;
set_print_fct_for_conffile(new_print_msg);
set_print_fct_for_libtools(new_print_msg);
#if 0 /* DELETE_ME AK:18-Aug-99 */
set_print_fct_for_avon(new_print_msg);
#endif
1997-03-03 04:23:12 +00:00
}
/****************************************************************************/
int num_match(char* Pattern, char *number)
{
int RetCode = -1;
char **Ptr;
char **Array;
if (!strcmp(Pattern, number)) /* match */
return 0;
1997-03-03 04:23:12 +00:00
The modifications remove a bug which occurs when dealing with special numbers and the callerid.conf file. Regular numbers such as +4940555 can be noted in the following way in a NUMBER line: NUMBER=+49-40-555, +49-69-555 For special numbers prior to this modifications there are strong unmentioned limitations. Only one number per NUMBER line is allowed without any of the options shown above. Allowed: NUMBER=01802555 Not allowed/not working: NUMBER=01802-555 also not working: NUMBER=0180255, 0700555 This modification brings the later two examples in function. About the background of the problem: isdnlog/isdnrep and other know a sort of telephone numbers called `special numbers', which are noted with S: and N: Tags in the rate-file. These numbers are per definition only available within the country. In order to emphasize this and for other more practical reasons, the normalized format for this numbers is not the usual +<countrycode><areacode><local number> but the national format like 01802555. While the logged numbers in /var/log/isdn.log or so follow this convention, such entries in callerid.conf got internally converted to the normalized format (+49180255 in case of the last mentioned number) so that the comparison executed by isdnlog or isdnrep did not show the expected result. The modification activates the advanced feature in the notation of normal numbers for special numbers. IMPORTANT NOTE: As the resulting library is located outside the isdnlog subdirectory, this changes may influence other parts of the isdn4k-utils.
2003-07-23 20:55:39 +00:00
if (!strchr(Pattern,C_NUM_DELIM)) /* Pattern is a single number, not a list */
{
RetCode = match(expand_number(Pattern), number, 0);
if (RetCode != 0) /* try Pattern without additional prefix */
RetCode = match(expand_number_pure(Pattern), number, 0);
return RetCode;
}
Ptr = Array = String_to_Array(Pattern,C_NUM_DELIM);
1997-03-03 04:23:12 +00:00
while (*Ptr != NULL && RetCode != 0)
{
RetCode = match(expand_number(*Ptr), number, 0);
Ptr++;
1997-03-03 04:23:12 +00:00
}
The modifications remove a bug which occurs when dealing with special numbers and the callerid.conf file. Regular numbers such as +4940555 can be noted in the following way in a NUMBER line: NUMBER=+49-40-555, +49-69-555 For special numbers prior to this modifications there are strong unmentioned limitations. Only one number per NUMBER line is allowed without any of the options shown above. Allowed: NUMBER=01802555 Not allowed/not working: NUMBER=01802-555 also not working: NUMBER=0180255, 0700555 This modification brings the later two examples in function. About the background of the problem: isdnlog/isdnrep and other know a sort of telephone numbers called `special numbers', which are noted with S: and N: Tags in the rate-file. These numbers are per definition only available within the country. In order to emphasize this and for other more practical reasons, the normalized format for this numbers is not the usual +<countrycode><areacode><local number> but the national format like 01802555. While the logged numbers in /var/log/isdn.log or so follow this convention, such entries in callerid.conf got internally converted to the normalized format (+49180255 in case of the last mentioned number) so that the comparison executed by isdnlog or isdnrep did not show the expected result. The modification activates the advanced feature in the notation of normal numbers for special numbers. IMPORTANT NOTE: As the resulting library is located outside the isdnlog subdirectory, this changes may influence other parts of the isdn4k-utils.
2003-07-23 20:55:39 +00:00
if (RetCode != 0) /* second try in case of number list */
{
Ptr = Array;
while (*Ptr != NULL && RetCode != 0)
{
RetCode = match(expand_number_pure(*Ptr), number, 0);
Ptr++;
}
}
del_Array(Array);
1997-03-03 04:23:12 +00:00
return RetCode;
}
/****************************************************************************/
The modifications remove a bug which occurs when dealing with special numbers and the callerid.conf file. Regular numbers such as +4940555 can be noted in the following way in a NUMBER line: NUMBER=+49-40-555, +49-69-555 For special numbers prior to this modifications there are strong unmentioned limitations. Only one number per NUMBER line is allowed without any of the options shown above. Allowed: NUMBER=01802555 Not allowed/not working: NUMBER=01802-555 also not working: NUMBER=0180255, 0700555 This modification brings the later two examples in function. About the background of the problem: isdnlog/isdnrep and other know a sort of telephone numbers called `special numbers', which are noted with S: and N: Tags in the rate-file. These numbers are per definition only available within the country. In order to emphasize this and for other more practical reasons, the normalized format for this numbers is not the usual +<countrycode><areacode><local number> but the national format like 01802555. While the logged numbers in /var/log/isdn.log or so follow this convention, such entries in callerid.conf got internally converted to the normalized format (+49180255 in case of the last mentioned number) so that the comparison executed by isdnlog or isdnrep did not show the expected result. The modification activates the advanced feature in the notation of normal numbers for special numbers. IMPORTANT NOTE: As the resulting library is located outside the isdnlog subdirectory, this changes may influence other parts of the isdn4k-utils.
2003-07-23 20:55:39 +00:00
/* Introducing expand_number_pure as a variant of expand_number without
* adding countrycode or countrycode and areacode to numbers. This is
* needed for isdnlog/isdnrep where national special numbers such as
* 01805 in Germany are intentionally stored as 01805 and not as +491805.
* The orginal expand_number which remains unchanged has no idea about
* special numbers and adds the countrycode to all numbers without, so
* that a correct entry from callerid.conf for a special number gets
* falsified and does not match as intended.
* The work is done by expand_number_all, which is the slighty extented
* former expand_number. The aliasing for expand_number and
* expand_number_all might be done in a more efficient way.
* Tobias Becker, 2003-02-11.
*/
static char *expand_number_all(char *s, int add_prefix)
1997-03-03 04:23:12 +00:00
{
int all_allowed = 0;
1997-03-03 04:23:12 +00:00
char *Ptr;
1998-10-13 21:53:17 +00:00
int Index = 0;
char Help[NUMBER_SIZE+1];
static char Num[NUMBER_SIZE+1];
1997-03-03 04:23:12 +00:00
Help[0] = '\0';
Ptr = s;
if (Ptr == NULL || Ptr[0] == '\0')
return "";
while(isblank(*Ptr))
Ptr++;
if (*Ptr == '+')
{
1998-10-13 21:53:17 +00:00
Strncpy(Help,countryprefix,NUMBER_SIZE);
1997-03-03 04:23:12 +00:00
Ptr++;
}
1998-10-13 21:53:17 +00:00
Index = strlen(Help);
1997-03-03 04:23:12 +00:00
while(*Ptr != '\0')
{
1998-10-13 21:53:17 +00:00
if (*Ptr == ',' || Index >= NUMBER_SIZE)
break;
if (isdigit(*Ptr) || *Ptr == '?' || *Ptr == '*'||
*Ptr == '[' || *Ptr == ']' || all_allowed )
1997-03-03 04:23:12 +00:00
{
if (*Ptr == '[')
all_allowed = 1;
if (*Ptr == ']')
all_allowed = 0;
1998-10-13 21:53:17 +00:00
Help[Index++] = *Ptr;
1997-03-03 04:23:12 +00:00
}
Ptr++;
}
1998-10-13 21:53:17 +00:00
Help[Index] = '\0';
1997-05-19 23:37:05 +00:00
if (Help[0] == '\0')
return s;
The modifications remove a bug which occurs when dealing with special numbers and the callerid.conf file. Regular numbers such as +4940555 can be noted in the following way in a NUMBER line: NUMBER=+49-40-555, +49-69-555 For special numbers prior to this modifications there are strong unmentioned limitations. Only one number per NUMBER line is allowed without any of the options shown above. Allowed: NUMBER=01802555 Not allowed/not working: NUMBER=01802-555 also not working: NUMBER=0180255, 0700555 This modification brings the later two examples in function. About the background of the problem: isdnlog/isdnrep and other know a sort of telephone numbers called `special numbers', which are noted with S: and N: Tags in the rate-file. These numbers are per definition only available within the country. In order to emphasize this and for other more practical reasons, the normalized format for this numbers is not the usual +<countrycode><areacode><local number> but the national format like 01802555. While the logged numbers in /var/log/isdn.log or so follow this convention, such entries in callerid.conf got internally converted to the normalized format (+49180255 in case of the last mentioned number) so that the comparison executed by isdnlog or isdnrep did not show the expected result. The modification activates the advanced feature in the notation of normal numbers for special numbers. IMPORTANT NOTE: As the resulting library is located outside the isdnlog subdirectory, this changes may influence other parts of the isdn4k-utils.
2003-07-23 20:55:39 +00:00
if (Help[0] == '*' || !strncmp(Help,countryprefix,strlen(countryprefix)) || !add_prefix)
1997-03-03 04:23:12 +00:00
{
strcpy(Num,Help);
}
else
if (!strncmp(Help,areaprefix,strlen(areaprefix)))
1997-03-03 04:23:12 +00:00
{
strcpy(Num,mycountry);
strcat(Num,Help+strlen(areaprefix));
1997-03-03 04:23:12 +00:00
}
else
{
strcpy(Num,mycountry);
strcat(Num,myarea/*+strlen(areaprefix)*/);
1997-03-03 04:23:12 +00:00
strcat(Num,Help);
}
return Num;
}
The modifications remove a bug which occurs when dealing with special numbers and the callerid.conf file. Regular numbers such as +4940555 can be noted in the following way in a NUMBER line: NUMBER=+49-40-555, +49-69-555 For special numbers prior to this modifications there are strong unmentioned limitations. Only one number per NUMBER line is allowed without any of the options shown above. Allowed: NUMBER=01802555 Not allowed/not working: NUMBER=01802-555 also not working: NUMBER=0180255, 0700555 This modification brings the later two examples in function. About the background of the problem: isdnlog/isdnrep and other know a sort of telephone numbers called `special numbers', which are noted with S: and N: Tags in the rate-file. These numbers are per definition only available within the country. In order to emphasize this and for other more practical reasons, the normalized format for this numbers is not the usual +<countrycode><areacode><local number> but the national format like 01802555. While the logged numbers in /var/log/isdn.log or so follow this convention, such entries in callerid.conf got internally converted to the normalized format (+49180255 in case of the last mentioned number) so that the comparison executed by isdnlog or isdnrep did not show the expected result. The modification activates the advanced feature in the notation of normal numbers for special numbers. IMPORTANT NOTE: As the resulting library is located outside the isdnlog subdirectory, this changes may influence other parts of the isdn4k-utils.
2003-07-23 20:55:39 +00:00
char *expand_number(char *s)
{
return expand_number_all(s, 1);
}
static char *expand_number_pure(char *s)
{
return expand_number_all(s, 0);
}
1997-03-03 04:23:12 +00:00
/****************************************************************************/
char *expand_file(char *s)
{
char *Ptr;
uid_t id = -1;
char Help[PATH_MAX];
static char file[PATH_MAX];
struct passwd *password;
Help[0] = '\0';
file[0] = '\0';
if (s == NULL)
return NULL;
if (s[0] == '~')
{
if (s[1] == C_SLASH)
{
/* Ghandi, vielleicht kommt hier auch getuid() hin */
id = geteuid();
}
else
{
strcpy(Help,s+1);
if ((Ptr = strchr(Help,C_SLASH)) != NULL)
*Ptr = '\0';
else
return NULL;
}
setpwent();
while((password = getpwent()) != NULL &&
strcmp(password->pw_name,Help) &&
password->pw_uid != id)
;
endpwent();
1997-03-03 04:23:12 +00:00
if (password == NULL)
return NULL;
strcpy(file,password->pw_dir);
strcat(file,strchr(s,C_SLASH));
}
return (file[0] == '\0'?s:file);
1997-03-03 04:23:12 +00:00
}
/****************************************************************************/
char *confdir(void)
{
static char *confdirvar = NULL;
if (confdirvar == NULL && (confdirvar = getenv(CONFDIR_VAR)) == NULL)
confdirvar = I4LCONFDIR;
return(confdirvar);
} /* confdir */
/****************************************************************************/
int handle_runfiles(const char *_progname, char **_devices, int flag)
1997-03-03 04:23:12 +00:00
{
static char progname[SHORT_STRING_SIZE] = "";
static char **devices = NULL;
1997-06-22 22:57:08 +00:00
auto char **mydevices = NULL;
auto char string[PATH_MAX];
auto char string2[SHORT_STRING_SIZE];
auto char *Ptr = NULL;
auto int RetCode = -1;
auto FILE *fp;
1997-03-03 04:23:12 +00:00
if (progname[0] == '\0' || devices == NULL)
{
if (_progname == NULL || _devices == NULL)
return -1;
Ptr = strrchr(progname,C_SLASH);
strcpy(progname,Ptr?Ptr+1:_progname);
1997-03-03 04:23:12 +00:00
while (*_devices != NULL)
{
Ptr = strrchr(*_devices,C_SLASH);
append_element(&devices,Ptr?Ptr+1:*_devices);
_devices++;
}
}
if (flag == START_PROG)
{
sprintf(string,"%s%c%s.%s.pid",RUNDIR,C_SLASH,progname,devices[0]);
if ((RetCode = create_runfile(string,"%d\n")) != 0)
{
if (RetCode > 0)
1997-06-15 23:50:34 +00:00
{
print_msg("Another %s is running with pid %d!\n", progname, RetCode);
1997-06-22 22:57:08 +00:00
print_msg("If not delete the file `%s' and try it again!\n", string);
1997-06-15 23:50:34 +00:00
}
return RetCode;
}
1997-06-22 22:57:08 +00:00
mydevices = devices;
while (*mydevices != NULL)
{
1997-06-22 22:57:08 +00:00
sprintf(string,"%s%c%s%s",LOCKDIR,C_SLASH,LOCKFILE,*mydevices);
if ((RetCode = create_runfile(string,"%10d\n")) != 0)
{
if (RetCode > 0)
1997-06-22 22:57:08 +00:00
print_msg("Another process (pid=%d) is running on device %s!\n", RetCode, *mydevices);
return RetCode;
}
1997-06-22 22:57:08 +00:00
mydevices++;
}
RetCode = 0;
}
if (flag == STOP_PROG)
{
1997-06-22 22:57:08 +00:00
sprintf(string,"%s%c%s.%s.pid",RUNDIR,C_SLASH,progname,devices[0]);
if ((fp = fopen(string, "r")) != NULL)
{
if (fgets(string2,SHORT_STRING_SIZE,fp) != NULL)
{
if (atoi(string2) == (int)getpid())
{
if (unlink(string))
print_msg("Can not remove file %s (%s)!\n", string, strerror(errno));
else
print_msg("File %s removed!\n", string, strerror(errno));
}
else
print_msg("This is not my lock file `%s': Has PID %d!\n", string, atoi(string2));
}
fclose(fp);
}
while (*devices != NULL)
{
sprintf(string,"%s%c%s%s",LOCKDIR,C_SLASH,LOCKFILE,*devices);
if ((fp = fopen(string, "r")) != NULL)
{
if (fgets(string2,SHORT_STRING_SIZE,fp) != NULL)
{
if (atoi(string2) == (int)getpid())
{
if (unlink(string))
print_msg("Can not remove file %s (%s)!\n", string, strerror(errno));
1997-06-22 22:57:08 +00:00
else
print_msg("File %s removed!\n", string, strerror(errno));
}
1997-06-22 22:57:08 +00:00
else
print_msg("This is not my lock file `%s': Has PID %d!\n", string, atoi(string2));
}
fclose(fp);
}
devices++;
}
RetCode = 0;
}
return RetCode;
}
1997-03-03 04:23:12 +00:00
/****************************************************************************/
static int create_runfile(const char *file, const char *format)
1997-03-03 04:23:12 +00:00
{
auto char string[SHORT_STRING_SIZE];
auto int RetCode = -1;
auto int fd = -1;
auto FILE *fp;
1997-03-03 04:23:12 +00:00
if (file == NULL)
return -1;
1997-03-03 04:23:12 +00:00
if ((fd = open(file, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0644)) >= 0)
1997-03-03 04:23:12 +00:00
{
sprintf(string, format, (int)getpid());
1997-03-03 04:23:12 +00:00
if (write(fd, string, strlen(string)) != strlen(string) )
{
print_msg("Can not write to PID file `%s'!\n", file);
RetCode = -1;
}
else
RetCode = 0;
close(fd);
1997-03-03 04:23:12 +00:00
}
else
{
if ((fp = fopen(file, "r")) == NULL)
1997-03-03 04:23:12 +00:00
return -1;
if (fgets(string,SHORT_STRING_SIZE,fp) != NULL)
RetCode = atoi(string);
else
/* Datei ist leer. */
RetCode = -1;
if ( RetCode == -1 || (int)getpid() == RetCode ||
((int) getpid() != RetCode && kill(RetCode,0) != 0 && errno == ESRCH) )
/* Wenn der alte Prozess nicht mehr existiert! */
{
fclose(fp);
if (unlink(file))
1997-03-03 04:23:12 +00:00
return -1;
return create_runfile(file,format);
1997-03-03 04:23:12 +00:00
}
fclose(fp);
}
return RetCode;
} /* create_runfile */
/*****************************************************************************/
/*
* set_country_behaviour() - different countries have small differences in
* ISDN implementations. Use the COUNTRYCODE setting to select the behaviour
*/
static void set_country_behaviour(char *mycountry)
{
/* amazing, strtol will also accept "+0049" */
mycountrynum = strtol(mycountry, (char **)0, 10);
/*
* There's no real point in testing for a known country code.
* Setting an unknown countrycode to 49 (DE) is probably the worst
* thing you can do if you're not actually in Germany. You might
* give a warning, but do we really want that? So simply accept
* the given value - Paul Slootman 20010818
*/
#if 0
switch (mycountrynum) {
case CCODE_NL:
case CCODE_CH:
case CCODE_AT:
case CCODE_DE:
case CCODE_LU:
/* any more special cases ? */
/* these only need to have mycountrynum set correctly */
break;
default:
mycountrynum = 49; /* use Germany as default for now */
}
#endif /* 0 */
}
/****************************************************************************/
/*
* Sets the country codes that are used for the lib. This function must
* be called by each program!
*/
1997-03-03 04:23:12 +00:00
1998-05-10 22:11:47 +00:00
#define _MAX_VARS 8
1997-03-03 04:23:12 +00:00
int Set_Codes(section* Section)
{
1998-05-10 22:11:47 +00:00
static char *ptr[_MAX_VARS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
1997-03-03 04:23:12 +00:00
int i;
int RetCode = 0;
entry *Entry;
char *ptr2;
char s[SHORT_STRING_SIZE];
section *SPtr;
1997-03-03 04:23:12 +00:00
for (i=0; i < _MAX_VARS; i++)
if (ptr[i] != NULL)
{
1997-03-03 04:23:12 +00:00
free(ptr[i]);
ptr[i] = NULL;
}
1997-03-03 04:23:12 +00:00
if ((SPtr = Get_Section(Section,CONF_SEC_GLOBAL)) == NULL)
1997-03-03 04:23:12 +00:00
return -1;
#if 0 /* DELETE_ME AK:18-Aug-99 */
if ((Entry = Get_Entry(SPtr->entries,CONF_ENT_AREALIB)) != NULL &&
1997-03-03 04:23:12 +00:00
Entry->value != NULL )
ptr[0] = acFileName = strdup(Entry->value);
if ((Entry = Get_Entry(SPtr->entries,CONF_ENT_AVONLIB)) != NULL &&
1997-03-03 04:23:12 +00:00
Entry->value != NULL )
ptr[1] = avonlib = strdup(Entry->value);
1997-03-03 04:23:12 +00:00
else
{
sprintf(s, "%s%c%s", confdir(), C_SLASH, AVON);
ptr[1] = avonlib = strdup(s);
1997-03-03 04:23:12 +00:00
}
#endif
if ((Entry = Get_Entry(SPtr->entries,CONF_ENT_COUNTRY_PREFIX)) != NULL &&
Entry->value != NULL )
ptr[2] = countryprefix = strdup(Entry->value);
if ((Entry = Get_Entry(SPtr->entries,CONF_ENT_AREA_PREFIX)) != NULL &&
Entry->value != NULL )
ptr[3] = areaprefix = strdup(Entry->value);
#if 0 /* DELETE_ME AK:18-Aug-99 */
if ((Entry = Get_Entry(SPtr->entries,CONF_ENT_CODELIB)) != NULL &&
Entry->value != NULL )
ptr[4] = codelib = strdup(Entry->value);
#endif
if ((Entry = Get_Entry(SPtr->entries,CONF_ENT_AREA)) != NULL &&
1997-03-03 04:23:12 +00:00
Entry->value != NULL )
{
ptr2 = Entry->value;
if (strncmp(Entry->value,areaprefix,strlen(areaprefix)))
ptr[5] = myarea = strdup(ptr2);
1997-03-03 04:23:12 +00:00
else
ptr[5] = myarea = strdup(ptr2+strlen(areaprefix));
1997-03-03 04:23:12 +00:00
if (ptr[5] != NULL)
1997-03-03 04:23:12 +00:00
RetCode++;
else
print_msg("Error: Variable `%s' are not set!\n",CONF_ENT_AREA);
1997-03-03 04:23:12 +00:00
}
if ((Entry = Get_Entry(SPtr->entries,CONF_ENT_COUNTRY)) != NULL &&
1997-03-03 04:23:12 +00:00
Entry->value != NULL )
{
ptr2 = Entry->value;
if (strncmp(Entry->value,countryprefix,strlen(countryprefix)))
1997-03-03 04:23:12 +00:00
{
sprintf(s,"%s%s",countryprefix,
1997-03-03 04:23:12 +00:00
Entry->value[0]=='+'?(Entry->value)+1:Entry->value);
ptr2 = s;
}
if ((ptr[6] = mycountry = strdup(ptr2)) != NULL) {
1997-03-03 04:23:12 +00:00
RetCode++;
set_country_behaviour(mycountry);
}
else
print_msg("Error: Variable `%s' are not set!\n",CONF_ENT_COUNTRY);
}
#if 0 /* DELETE_ME AK:18-Aug-99 */
1998-05-10 22:11:47 +00:00
if ((Entry = Get_Entry(SPtr->entries,CONF_ENT_AREADIFF)) != NULL &&
Entry->value != NULL )
ptr[7] = areadifffile = strdup(Entry->value);
else
{
if ((areadifffile = (char*) calloc(strlen(confdir())+strlen(S_AREA_DIFF_FILE)+2,sizeof(char))) == NULL)
print_msg("Can not allocate memory!\n");
else
{
sprintf(areadifffile,"%s%c%s",confdir(),C_SLASH,S_AREA_DIFF_FILE);
if (access(areadifffile,R_OK))
{
free(areadifffile);
areadifffile = NULL;
}
else
ptr[7] = areadifffile;
}
}
#endif
SPtr = Section;
while ((SPtr = Get_Section(SPtr,CONF_SEC_VAR)) != NULL)
{
Entry = SPtr->entries;
while(Entry != NULL)
{
if (setenv(Entry->name, Entry->value, 1) != 0)
print_msg("Warning: Can not set environment variable `%s=%s'!\n", Entry->name, Entry->value);
Entry = Entry->next;
}
SPtr = SPtr->next;
1997-03-03 04:23:12 +00:00
}
return (RetCode==2?0:-1);
}
/****************************************************************************/
#if 0 /* DELETE_ME AK:18-Aug-99 */
1997-03-03 04:23:12 +00:00
char *get_areacode(char *code, int *Len, int flag)
{
auto char *Ptr;
auto int i = 0;
register int prefix = strlen(countryprefix);
1997-03-03 04:23:12 +00:00
if (Len != NULL)
*Len = -1;
if (code == NULL || code[0] =='\0')
return NULL;
if (!(flag & C_NO_EXPAND))
{
char *ptr = expand_number(code);
1998-10-13 21:53:17 +00:00
if ((code = alloca(strlen(ptr)+1)) == NULL)
1997-03-03 04:23:12 +00:00
print_msg("Can not allocate memory!\n");
strcpy(code,ptr);
}
while (areacodes[i][0][0] != '\0')
{
if (!memcmp(areacodes[i][0]+1,code+prefix,strlen(areacodes[i][0]+1)))
{
if (Len != NULL)
*Len = strlen(areacodes[i][0]) - 1 /* das "+" */ + prefix;
return areacodes[i][1];
}
i++;
}
#if 0 /* DELETE_ME AK:18-Aug-99 */
#ifdef LIBAREA
if (codelib != NULL && !strcasecmp(codelib,"AREACODE"))
Ptr = _get_areacode(code,Len,flag);
#else
if (codelib != NULL && !strcasecmp(codelib,"AVON"))
Ptr = _get_avon(code,Len,flag);
#endif
else
#ifdef LIBAREA
Ptr = _get_areacode(code,Len,flag);
#else
Ptr = _get_avon(code,Len,flag);
#endif
#endif
if (Ptr != NULL)
1997-03-03 04:23:12 +00:00
return Ptr;
i=0;
while (countrycodes[i][0][0] != '\0')
{
if (!memcmp(countrycodes[i][0]+1,code+prefix,strlen(countrycodes[i][0]+1)))
{
if (Len != NULL)
*Len = strlen(countrycodes[i][0]) - 1 /* das "+" */ + prefix;
return countrycodes[i][1];
}
i++;
}
if (!(flag & C_NO_WARN))
print_msg("Unknown areacode `%s'!\n", code);
return NULL;
}
/****************************************************************************/
#endif
1997-03-03 04:23:12 +00:00
#if 0 /* DELETE_ME AK:18-Aug-99 */
#ifndef LIBAREA
static char *_get_avon(char *code, int *Len, int flag)
1997-03-03 04:23:12 +00:00
{
static int opened = 0;
static char s[BUFSIZ];
int prefix = strlen(countryprefix);
1997-03-03 04:23:12 +00:00
int ll=0;
int l;
l = strlen(code) - prefix;
s[0] = '\0';
if (Len != NULL)
*Len = -1;
if (!opened)
{
if (avonlib == NULL && !(flag & C_NO_ERROR))
print_msg("No path for AVON library defined!\n");
if (!access(avonlib, R_OK))
{
createDB(avonlib,0);
openDB(avonlib,O_WRONLY);
1997-03-03 04:23:12 +00:00
}
opened = 1;
if (dbm == NULL && !(flag & C_NO_ERROR))
print_msg("!!! Problem with AVON database! - disabling AVON support!\n");
}
if (dbm != NULL && l > 3)
{
key.dptr = code+prefix;
do
{
ll++;
key.dsize = l--;
data = dbm_fetch(dbm, key);
if (data.dptr != NULL)
{
if (Len != NULL)
*Len = ll;
strcpy(s,data.dptr);
}
}
while(l > 1);
}
return (s[0]?s:NULL);
}
#endif
#endif
1997-03-03 04:23:12 +00:00
/****************************************************************************/
#if 0 /* DELETE_ME AK:18-Aug-99 */
1997-03-03 04:23:12 +00:00
static char *_get_areacode(char *code, int *Len, int flag)
{
auto int cc = 0;
auto char *err;
static acInfo ac;
static int warned = 0;
int prefix = strlen(countryprefix);
1997-03-03 04:23:12 +00:00
if (warned)
return(NULL);
if ((cc = GetAreaCodeInfo(&ac, code + prefix)) == acOk) {
if (ac.AreaCodeLen > 0) {
1997-03-03 04:23:12 +00:00
if (Len != NULL)
*Len = ac.AreaCodeLen + prefix;
return ac.Info;
}
}
else {
1997-03-03 04:23:12 +00:00
switch (cc) {
case acFileError : err = "Cannot open/read file";
break;
case acInvalidFile : err = "The file exists but is no area code data file";
break;
case acWrongVersion : err = "Wrong version of data file";
break;
case acInvalidInput : err = "Input string is not a number or empty";
break;
1997-03-03 04:23:12 +00:00
default : err = "Unknown AreaCode error";
break;
} /* switch */
if (!(flag & C_NO_ERROR)) {
print_msg("!!! Problem with AreaCode: %s", err);
1997-03-03 04:23:12 +00:00
if (cc != acInvalidInput) {
print_msg(" - disabling AreaCode support!\n");
1997-03-03 04:23:12 +00:00
warned = 1;
}
else
print_msg("\n");
} /* if */
} /* else */
1997-03-03 04:23:12 +00:00
return NULL;
}
#endif
1997-03-03 04:23:12 +00:00
/****************************************************************************/
int read_conffiles(section **Section, char *groupfile)
{
static section *conf_dat = NULL;
static int read_again = 0;
1997-03-18 23:01:47 +00:00
auto char s[6][BUFSIZ];
auto char **vars = NULL;
auto char **files = NULL;
auto int fileflag[6];
auto int i = 0;
auto int RetCode = -1;
*Section = NULL;
if (!read_again)
{
sprintf(s[0], "%s%c%s", confdir(), C_SLASH, CONFFILE);
sprintf(s[1], "%s%c%s", confdir(), C_SLASH, CALLERIDFILE);
if (paranoia_check(s[0]))
return -1;
if (paranoia_check(s[1]))
return -1;
append_element(&files,s[0]);
fileflag[i++] = MERGE_FILE;
append_element(&files,s[1]);
fileflag[i++] = APPEND_FILE;
if (groupfile != NULL)
{
strcpy(s[2],groupfile);
append_element(&files,s[2]);
fileflag[i++] = MERGE_FILE;
}
strcpy(s[3],expand_file(USERCONFFILE));
append_element(&files,s[3]);
fileflag[i++] = MERGE_FILE;
}
1997-03-18 23:01:47 +00:00
sprintf(s[4],"%s|%s/%s|!%s",CONF_SEC_MSN,CONF_SEC_NUM,CONF_ENT_NUM,CONF_ENT_SI);
append_element(&vars,s[4]);
/*
sprintf(s[5],"%s|%s/%s",CONF_SEC_MSN,CONF_SEC_NUM,CONF_ENT_ALIAS);
append_element(&vars,s[5]);
*/
if ((RetCode = read_files(&conf_dat, files, fileflag, vars, C_OVERWRITE|C_NOT_UNIQUE|C_NO_WARN_FILE)) > 0)
{
*Section = conf_dat;
if (Set_Codes(conf_dat) != 0)
return -1;
}
else
*Section = conf_dat;
if (!read_again)
delete_element(&files,0);
delete_element(&vars,0);
read_again = 1;
return RetCode;
}
/****************************************************************************/
int paranoia_check(char *cmd)
{
struct stat stbuf;
if (getuid() == 0)
{
if (stat(cmd, &stbuf))
{
if (errno == ENOENT)
return 0;
print_msg("stat() failed for file `%s', stay on the safe side!\n", cmd);
return -1;
}
if (stbuf.st_uid != 0)
{
print_msg("Owner of file `%s' is not root!\n", cmd);
return -1;
}
if ((stbuf.st_gid != 0 && (stbuf.st_mode & S_IWGRP)) ||
(stbuf.st_mode & S_IWOTH) )
{
print_msg("File `%s' is writable by group or world!\n", cmd);
return -1;
}
}
return 0;
}
/****************************************************************************/
#if 0 /* DELETE_ME AK:18-Aug-99 */
1998-05-10 22:11:47 +00:00
static long int area_read_value(FILE *fp, int size)
{
long value = 0;
static int endian = -1;
if (size != 2 && size != 4 && size != 1)
{
print_msg("Can not read lenght %d, only 1, 2, 4\n");
return -1;
}
if (endian == -1)
{
if (htons(0x0101) == 0x0101)
endian = 0;
else
endian = 1;
}
if (fread(&value,size,1,fp) != 1)
{
print_msg("Can not read from file `%s': Too less data!\n", areadifffile);
return -1;
}
if (endian)
{
if (size == 2)
value = ntohs(value);
else
if (size == 4)
value = ntohl(value);
}
return value;
}
/****************************************************************************/
const char* area_diff_string(char* number1, char* number2)
{
1998-05-11 19:43:43 +00:00
switch(area_diff(number1,number2))
{
case AREA_LOCAL : return "CityCall"; break;
case AREA_R50 : return "RegioCall"; break;
case AREA_FAR : return "GermanCall"; break;
case AREA_ABROAD: return "GlobalCall"; break;
1998-05-11 19:43:43 +00:00
default : break;
}
return "";
1998-05-10 22:11:47 +00:00
}
/****************************************************************************/
int area_diff(char* _code, char *_diffcode)
{
FILE *fp = NULL;
1998-10-13 21:53:17 +00:00
char code[NUMBER_SIZE];
char diffcode[NUMBER_SIZE];
1998-05-10 22:11:47 +00:00
char value[15];
int index;
int number;
int i = 0;
if (codes == NULL)
if (area_read_file() == -1)
return AREA_ERROR;
if (_code == NULL)
{
1998-10-13 21:53:17 +00:00
Strncpy(code,mycountry,NUMBER_SIZE);
Strncat(code,myarea,NUMBER_SIZE);
1998-05-10 22:11:47 +00:00
}
else
1998-10-13 21:53:17 +00:00
Strncpy(code,expand_number(_code),NUMBER_SIZE);
1998-05-10 22:11:47 +00:00
1998-05-11 19:43:43 +00:00
if (strncmp(mycountry,code,strlen(mycountry)))
return AREA_UNKNOWN;
1998-05-10 22:11:47 +00:00
if (_diffcode == NULL)
return AREA_ERROR;
else
1998-10-13 21:53:17 +00:00
Strncpy(diffcode,expand_number(_diffcode),NUMBER_SIZE);
1998-05-10 22:11:47 +00:00
if ((index = area_get_index(code)) == -1)
return AREA_ERROR;
if ((fp = fopen(areadifffile,"r")) == NULL)
{
print_msg("Can not open file `%s': %s\n", areadifffile, strerror(errno));
return -1;
}
fseek(fp,codes[index].pointer,SEEK_SET);
number = area_read_value(fp,2);
1998-05-11 19:43:43 +00:00
i = 0;
1998-05-10 22:11:47 +00:00
while(i++<number)
{
sprintf(value,"%s%d%ld",countryprefix,GERMAN_CODE,(area_read_value(fp,2)+32768)%65536);
if (!strncmp(value,diffcode,strlen(value)))
{
fclose(fp);
return AREA_LOCAL;
}
}
number = area_read_value(fp,2);
1998-05-11 19:43:43 +00:00
i = 0;
1998-05-10 22:11:47 +00:00
while(i++<number)
{
sprintf(value,"%s%d%ld",countryprefix,GERMAN_CODE,(area_read_value(fp,2)+32768)%65536);
if (!strncmp(value,diffcode,strlen(value)))
{
fclose(fp);
return AREA_R50;
}
}
fclose(fp);
if (!strncmp(mycountry,diffcode,strlen(mycountry)))
1998-05-11 19:43:43 +00:00
{
i = 0;
do
{
if (areacodes[i][0][0] != '\0')
{
strcpy(value, expand_number((char*) areacodes[i][0]));
if (!strncmp(diffcode,value,strlen(value)))
return AREA_UNKNOWN;
}
}
while (areacodes[++i][0][0] != '\0');
1998-05-10 22:11:47 +00:00
return AREA_FAR;
1998-05-11 19:43:43 +00:00
}
else
return AREA_ABROAD;
1998-05-10 22:11:47 +00:00
return AREA_UNKNOWN;
}
/****************************************************************************/
static int area_get_index(char *code)
{
int index = -1;
if (codes == NULL)
return -1;
while(++index < codes_number)
if (!strcmp(codes[index].code,code))
break;
if (index == codes_number)
{
print_msg("Can not find area code `%s'!\n", code);
index = -1;
}
return index;
}
/****************************************************************************/
static int area_read_file(void)
{
FILE *fp = NULL;
int i = 0;
if (areadifffile == NULL)
{
// print_msg("There is no file name for vorwahl database!\n");
return -1;
}
if ((fp = fopen(areadifffile,"r")) == NULL)
{
print_msg("Can not open file `%s': %s\n", areadifffile, strerror(errno));
return -1;
}
if ((codes_number = area_read_value(fp,2)) < 0)
{
print_msg("Number of areacodes is wrong: %d\n", codes_number);
return -1;
}
if (codes != NULL)
free(codes);
if ((codes = (s_areacode*) calloc(codes_number,sizeof(s_areacode))) == NULL)
{
print_msg("%s\n", strerror(errno));
return -1;
}
if (fseek(fp,3,SEEK_SET) != 0)
{
print_msg("Can not seek file `%s' to position %d: %s\n", areadifffile, 4*codes_number+3, strerror(errno));
return -1;
}
while (i<codes_number)
codes[i++].pointer = area_read_value(fp,4) -1;
if (fseek(fp,4*codes_number+3,SEEK_SET) != 0)
{
print_msg("Can not seek file `%s' to position %d: %s\n", areadifffile, 4*codes_number+3, strerror(errno));
return -1;
}
i = 0;
while (i<codes_number)
sprintf(codes[i++].code,"%s%d%ld",countryprefix,GERMAN_CODE,(area_read_value(fp,2)+32768)%65536);
fclose(fp);
return 0;
}
/****************************************************************************/
#endif