1999-11-02 21:01:56 +00:00
|
|
|
|
/* $Id: isdnrate.c,v 1.23 1999/11/02 21:01:57 akool Exp $
|
1999-09-09 11:21:04 +00:00
|
|
|
|
|
1999-06-28 19:14:59 +00:00
|
|
|
|
* ISDN accounting for isdn4linux. (rate evaluation)
|
|
|
|
|
*
|
|
|
|
|
* Copyright 1995, 1999 by Andreas Kool (akool@isdn4linux.de)
|
|
|
|
|
*
|
|
|
|
|
* 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: isdnrate.c,v $
|
1999-11-02 21:01:56 +00:00
|
|
|
|
* Revision 1.23 1999/11/02 21:01:57 akool
|
|
|
|
|
* isdnlog-3.62
|
|
|
|
|
* - many new rates
|
|
|
|
|
* - next try to fix "Sonderrufnummern"
|
|
|
|
|
*
|
1999-10-26 18:17:11 +00:00
|
|
|
|
* Revision 1.22 1999/10/26 18:17:14 akool
|
|
|
|
|
* isdnlog-3.58
|
|
|
|
|
* - big cleanup ( > 1.3 Mb removed!)
|
|
|
|
|
* - v0.02 of destination support - better, but not perfect
|
|
|
|
|
* (does't work with gcc-2.7.2.3 yet - use egcs!)
|
|
|
|
|
*
|
1999-10-25 18:30:03 +00:00
|
|
|
|
* Revision 1.21 1999/10/25 18:30:03 akool
|
|
|
|
|
* isdnlog-3.57
|
|
|
|
|
* WARNING: Experimental version!
|
|
|
|
|
* Please use isdnlog-3.56 for production systems!
|
|
|
|
|
*
|
1999-09-19 14:16:26 +00:00
|
|
|
|
* Revision 1.20 1999/09/19 14:16:27 akool
|
|
|
|
|
* isdnlog-3.53
|
|
|
|
|
*
|
1999-09-16 20:27:21 +00:00
|
|
|
|
* Revision 1.19 1999/09/16 20:27:21 akool
|
|
|
|
|
* isdnlog-3.52
|
|
|
|
|
*
|
1999-09-13 09:09:42 +00:00
|
|
|
|
* Revision 1.18 1999/09/13 09:09:44 akool
|
|
|
|
|
* isdnlog-3.51
|
|
|
|
|
* - changed getProvider() to not return NULL on unknown providers
|
|
|
|
|
* many thanks to Matthias Eder <mateder@netway.at>
|
|
|
|
|
* - corrected zone-processing when doing a internal -> world call
|
|
|
|
|
*
|
1999-09-09 11:21:04 +00:00
|
|
|
|
* Revision 1.17 1999/09/09 11:21:05 akool
|
|
|
|
|
* isdnlog-3.49
|
|
|
|
|
*
|
1999-08-04 23:06:52 +00:00
|
|
|
|
* Revision 1.16 1999/08/04 23:06:52 akool
|
|
|
|
|
* Better codeall for .at
|
|
|
|
|
*
|
1999-07-31 09:25:03 +00:00
|
|
|
|
* Revision 1.15 1999/07/31 09:25:36 akool
|
|
|
|
|
* getRate() speedup
|
|
|
|
|
*
|
1999-07-26 16:28:31 +00:00
|
|
|
|
* Revision 1.14 1999/07/26 16:28:41 akool
|
|
|
|
|
* getRate() speedup from Leo
|
|
|
|
|
*
|
1999-07-25 15:57:01 +00:00
|
|
|
|
* Revision 1.13 1999/07/25 15:57:46 akool
|
|
|
|
|
* isdnlog-3.43
|
|
|
|
|
* added "telnum" module
|
|
|
|
|
*
|
1999-07-24 08:43:38 +00:00
|
|
|
|
* Revision 1.12 1999/07/24 08:45:17 akool
|
|
|
|
|
* isdnlog-3.42
|
|
|
|
|
* rate-de.dat 1.02-Germany [18-Jul-1999 10:44:21]
|
|
|
|
|
* better Support for Ackermann Euracom
|
|
|
|
|
* WEB-Interface for isdnrate
|
|
|
|
|
* many small fixes
|
|
|
|
|
*
|
1999-07-15 16:41:22 +00:00
|
|
|
|
* Revision 1.11 1999/07/15 16:42:04 akool
|
|
|
|
|
* small enhancement's and fixes
|
|
|
|
|
*
|
1999-07-07 19:43:36 +00:00
|
|
|
|
* Revision 1.10 1999/07/07 19:44:07 akool
|
|
|
|
|
* patches from Michael and Leo
|
|
|
|
|
*
|
1999-07-04 20:46:39 +00:00
|
|
|
|
* Revision 1.9 1999/07/04 20:47:05 akool
|
|
|
|
|
* rate-de.dat V:1.02-Germany [04-Jul-1999 22:56:37]
|
|
|
|
|
*
|
1999-07-03 10:23:55 +00:00
|
|
|
|
* Revision 1.8 1999/07/03 10:24:14 akool
|
|
|
|
|
* fixed Makefile
|
|
|
|
|
*
|
1999-07-02 19:17:01 +00:00
|
|
|
|
* Revision 1.7 1999/07/02 19:18:00 akool
|
|
|
|
|
* rate-de.dat V:1.02-Germany [02-Jul-1999 21:27:20]
|
|
|
|
|
*
|
1999-07-02 18:20:20 +00:00
|
|
|
|
* Revision 1.6 1999/07/02 18:20:50 akool
|
|
|
|
|
* rate-de.dat V:1.02-Germany [02-Jul-1999 20:29:21]
|
|
|
|
|
* country-de.dat V:1.02-Germany [02-Jul-1999 19:13:54]
|
|
|
|
|
*
|
1999-07-01 20:38:57 +00:00
|
|
|
|
* Revision 1.5 1999/07/01 20:40:07 akool
|
|
|
|
|
* isdnrate optimized
|
|
|
|
|
*
|
1999-06-30 20:53:28 +00:00
|
|
|
|
* Revision 1.4 1999/06/30 20:53:28 akool
|
|
|
|
|
* added "-t" option to "isdnrate"
|
|
|
|
|
*
|
1999-06-30 17:17:10 +00:00
|
|
|
|
* Revision 1.3 1999/06/30 17:17:37 akool
|
|
|
|
|
* isdnlog Version 3.39
|
|
|
|
|
*
|
1999-06-29 20:10:18 +00:00
|
|
|
|
* Revision 1.2 1999/06/29 20:11:25 akool
|
|
|
|
|
* now compiles with ndbm
|
|
|
|
|
* (many thanks to Nima <nima_ghasseminejad@public.uni-hamburg.de>)
|
|
|
|
|
*
|
1999-06-28 19:14:59 +00:00
|
|
|
|
* Revision 1.1 1999/06/28 19:16:33 akool
|
|
|
|
|
* isdnlog Version 3.38
|
|
|
|
|
* - new utility "isdnrate" started
|
|
|
|
|
*
|
1999-06-29 20:10:18 +00:00
|
|
|
|
*/
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
|
|
|
|
#include "isdnlog.h"
|
1999-07-03 10:23:55 +00:00
|
|
|
|
#include "tools/zone.h"
|
1999-07-24 08:43:38 +00:00
|
|
|
|
#include <unistd.h>
|
1999-10-25 18:30:03 +00:00
|
|
|
|
#ifdef USE_DESTINATION
|
|
|
|
|
#include "dest.h"
|
|
|
|
|
#else
|
1999-07-25 15:57:01 +00:00
|
|
|
|
#include "telnum.h"
|
1999-10-25 18:30:03 +00:00
|
|
|
|
#endif
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-07-02 19:17:01 +00:00
|
|
|
|
#define WIDTH 19
|
1999-09-09 11:21:04 +00:00
|
|
|
|
#define _MAXLAST 20 /* the real max */
|
1999-07-25 15:57:01 +00:00
|
|
|
|
#define MAXLAST ((best>=_MAXLAST||best<=2)?5:best)
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
|
|
|
|
|
static void print_header(void);
|
1999-07-25 15:57:01 +00:00
|
|
|
|
|
1999-06-28 19:14:59 +00:00
|
|
|
|
static char *myname, *myshortname;
|
1999-10-25 18:30:03 +00:00
|
|
|
|
static char options[] = "b:d:f:h:l:p:t:v::x:CD::G:HLNS:TUVX::";
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static char usage[] = "%s: usage: %s [ -%s ] Destination ...\n";
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-09-19 14:16:26 +00:00
|
|
|
|
static int header = 0, best = MAXPROVIDER, table = 0,
|
1999-09-09 11:21:04 +00:00
|
|
|
|
explain = 0;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
int verbose = 0;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static int usestat = 0;
|
|
|
|
|
static int duration = LCR_DURATION;
|
1999-06-29 20:10:18 +00:00
|
|
|
|
static time_t start;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static int day, month, year, hour, min, sec;
|
|
|
|
|
static char ignore[MAXPROVIDER];
|
|
|
|
|
static char *fromarea = 0;
|
|
|
|
|
static char wanted_day;
|
|
|
|
|
static int list = 0;
|
|
|
|
|
static char *comment;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
static int *providers = 0; /* incl these */
|
|
|
|
|
static int n_providers = 0;
|
|
|
|
|
static int business=0;
|
|
|
|
|
static int *xproviders = 0; /* excl these */
|
|
|
|
|
static int nx_providers = 0;
|
|
|
|
|
static int xbusiness=0;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
|
|
|
|
|
#define SOCKNAME "/tmp/isdnrate"
|
|
|
|
|
static int is_daemon = 0;
|
|
|
|
|
static int is_client = 0;
|
|
|
|
|
static int we_are_daemon = 0;
|
|
|
|
|
static int takt = 99999;
|
|
|
|
|
static char sortby;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
static int need_dest;
|
|
|
|
|
static int h_param=0;
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-07-25 15:57:01 +00:00
|
|
|
|
static TELNUM srcnum, destnum;
|
1999-08-04 23:06:52 +00:00
|
|
|
|
|
1999-06-28 19:14:59 +00:00
|
|
|
|
typedef struct {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
int prefix;
|
|
|
|
|
double rate;
|
|
|
|
|
char *name;
|
|
|
|
|
char *explain;
|
1999-06-28 19:14:59 +00:00
|
|
|
|
} SORT;
|
|
|
|
|
|
1999-07-04 20:46:39 +00:00
|
|
|
|
typedef struct {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
int weight;
|
|
|
|
|
int index;
|
1999-07-04 20:46:39 +00:00
|
|
|
|
} SORT2;
|
|
|
|
|
|
1999-06-28 19:14:59 +00:00
|
|
|
|
static SORT sort[MAXPROVIDER];
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
#undef BUFSIZ /* sorry but 8192 is too much for me */
|
1999-07-25 15:57:01 +00:00
|
|
|
|
#define BUFSIZ 256
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
int print_msg(int Level, const char *fmt,...)
|
1999-06-28 19:14:59 +00:00
|
|
|
|
{
|
|
|
|
|
auto va_list ap;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
auto char String[BUFSIZ * 3];
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (verbose < 2)
|
|
|
|
|
if (Level == PRT_ERR || (Level == PRT_V && !verbose))
|
|
|
|
|
return (1);
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
(void) vsnprintf(String, BUFSIZ * 3, fmt, ap);
|
1999-06-28 19:14:59 +00:00
|
|
|
|
va_end(ap);
|
|
|
|
|
|
1999-07-24 08:43:38 +00:00
|
|
|
|
fprintf(Level == PRT_NORMAL ? stdout : stderr, "%s", String);
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
return (0);
|
|
|
|
|
} /* print_msg */
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void init()
|
|
|
|
|
{
|
1999-06-29 20:10:18 +00:00
|
|
|
|
auto char *version, **message;
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
|
|
|
|
if (readconfig(myshortname) < 0)
|
|
|
|
|
exit(1);
|
|
|
|
|
|
1999-06-29 20:10:18 +00:00
|
|
|
|
if (verbose)
|
|
|
|
|
message = &version;
|
|
|
|
|
else
|
|
|
|
|
message = NULL;
|
|
|
|
|
|
|
|
|
|
initHoliday(holifile, message);
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-07-25 15:57:01 +00:00
|
|
|
|
if (verbose && *version)
|
1999-07-24 08:43:38 +00:00
|
|
|
|
print_msg(PRT_V, "%s\n", version);
|
1999-10-25 18:30:03 +00:00
|
|
|
|
#ifdef USE_DESTINATION
|
|
|
|
|
initDest(destfile, message);
|
|
|
|
|
#else
|
1999-06-29 20:10:18 +00:00
|
|
|
|
initCountry(countryfile, message);
|
1999-10-25 18:30:03 +00:00
|
|
|
|
#endif
|
1999-07-25 15:57:01 +00:00
|
|
|
|
if (verbose && *version)
|
1999-07-24 08:43:38 +00:00
|
|
|
|
print_msg(PRT_V, "%s\n", version);
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-06-29 20:10:18 +00:00
|
|
|
|
initRate(rateconf, ratefile, zonefile, message);
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-07-25 15:57:01 +00:00
|
|
|
|
if (verbose && *version)
|
1999-07-24 08:43:38 +00:00
|
|
|
|
print_msg(PRT_V, "%s\n", version);
|
1999-08-04 23:06:52 +00:00
|
|
|
|
|
|
|
|
|
initTelNum();
|
1999-09-09 11:21:04 +00:00
|
|
|
|
} /* init */
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static void deinit(void)
|
|
|
|
|
{
|
|
|
|
|
exitRate();
|
1999-10-25 18:30:03 +00:00
|
|
|
|
#ifdef USE_DESTINATION
|
|
|
|
|
exitDest();
|
|
|
|
|
#else
|
1999-09-09 11:21:04 +00:00
|
|
|
|
exitCountry();
|
1999-10-25 18:30:03 +00:00
|
|
|
|
#endif
|
1999-09-09 11:21:04 +00:00
|
|
|
|
exitHoliday();
|
|
|
|
|
}
|
1999-07-24 08:43:38 +00:00
|
|
|
|
/* calc a day/time W | E | H */
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static void get_day(char d)
|
|
|
|
|
{
|
1999-07-24 08:43:38 +00:00
|
|
|
|
struct tm *tm;
|
|
|
|
|
bitfield mask;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
int what = 0;
|
|
|
|
|
|
|
|
|
|
tm = localtime(&start); /* now */
|
|
|
|
|
switch (d) {
|
1999-09-19 14:16:26 +00:00
|
|
|
|
case 'W': /* we need a normal weekday, so we take
|
1999-09-09 11:21:04 +00:00
|
|
|
|
|
|
|
|
|
today and inc. day if today is
|
|
|
|
|
holiday */
|
|
|
|
|
what = WORKDAY;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if(!h_param)
|
|
|
|
|
hour = 10;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
break;
|
|
|
|
|
case 'N':
|
|
|
|
|
what = WORKDAY;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if(!h_param)
|
|
|
|
|
hour = 23;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
break;
|
|
|
|
|
case 'E':
|
|
|
|
|
what = SUNDAY;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if(!h_param)
|
|
|
|
|
hour = 10;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
break;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
|
|
|
|
mask = 1 << what;
|
|
|
|
|
while (isDay(tm, mask, 0) != what) {
|
|
|
|
|
tm->tm_mday++;
|
|
|
|
|
}
|
|
|
|
|
min = sec = 0;
|
|
|
|
|
day = tm->tm_mday;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
month = tm->tm_mon + 1;
|
|
|
|
|
year = tm->tm_year + 1900;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
|
|
|
|
static void post_init()
|
|
|
|
|
{
|
|
|
|
|
|
1999-07-25 15:57:01 +00:00
|
|
|
|
clearNum(&srcnum);
|
1999-07-24 08:43:38 +00:00
|
|
|
|
if (fromarea) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
Strncpy(srcnum.area, fromarea, TN_MAX_AREA_LEN);
|
|
|
|
|
free(fromarea);
|
|
|
|
|
fromarea = 0;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
1999-07-25 15:57:01 +00:00
|
|
|
|
initNum(&srcnum);
|
1999-08-04 23:06:52 +00:00
|
|
|
|
|
1999-07-24 08:43:38 +00:00
|
|
|
|
if (wanted_day)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
get_day(wanted_day);
|
|
|
|
|
} /* post_init */
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-06-29 20:10:18 +00:00
|
|
|
|
static int opts(int argc, char *argv[])
|
1999-06-28 19:14:59 +00:00
|
|
|
|
{
|
1999-09-09 11:21:04 +00:00
|
|
|
|
register int c;
|
1999-06-29 20:10:18 +00:00
|
|
|
|
register char *p;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
int x;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
h_param=0;
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
optind = 0; /* make it repeatable */
|
1999-09-19 14:16:26 +00:00
|
|
|
|
need_dest=1;
|
1999-06-28 19:14:59 +00:00
|
|
|
|
while ((c = getopt(argc, argv, options)) != EOF) {
|
|
|
|
|
switch (c) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
case 'b':
|
|
|
|
|
best = strtol(optarg, NIL, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* case 'c': country */
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'd':
|
|
|
|
|
for (p = optarg; *p && isspace(*p); p++) ;
|
|
|
|
|
if (isdigit(*p)) {
|
|
|
|
|
wanted_day = '\0';
|
|
|
|
|
day = atoi(optarg);
|
|
|
|
|
if ((p = strchr(optarg, '.'))) {
|
|
|
|
|
month = atoi(p + 1);
|
|
|
|
|
if ((p = strchr(p + 1, '.'))) {
|
|
|
|
|
year = atoi(p + 1);
|
|
|
|
|
if (year < 50)
|
|
|
|
|
year += 2000;
|
|
|
|
|
else if (year < 100)
|
|
|
|
|
year += 1900;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} /* isdigit */
|
|
|
|
|
else {
|
|
|
|
|
wanted_day = *p;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'f':
|
|
|
|
|
if (optarg) { /* from */
|
|
|
|
|
for (p = optarg; (isspace(*p) || *p == '0') && *p; p++) ;
|
|
|
|
|
fromarea = strdup(p);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'h':
|
|
|
|
|
hour = atoi(optarg);
|
1999-09-19 14:16:26 +00:00
|
|
|
|
h_param++;
|
|
|
|
|
sec = 0;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if ((p = strchr(optarg + 1, ':'))) {
|
|
|
|
|
min = atoi(p + 1);
|
|
|
|
|
if ((p = strchr(p + 1, ':')))
|
|
|
|
|
sec = atoi(p + 1);
|
|
|
|
|
}
|
1999-09-19 14:16:26 +00:00
|
|
|
|
else
|
|
|
|
|
min=0;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'l':
|
|
|
|
|
duration = strtol(optarg, NIL, 0); /* l wie lt */
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 't':
|
1999-09-19 14:16:26 +00:00
|
|
|
|
x = strtol(optarg, NIL, 0);
|
|
|
|
|
if (x > 0)
|
|
|
|
|
takt = x;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'x': /* eXclude Poviders */
|
1999-09-19 14:16:26 +00:00
|
|
|
|
{
|
|
|
|
|
char *arg = strdup(optarg);
|
|
|
|
|
p = strtok(arg, ",");
|
|
|
|
|
while (p) {
|
|
|
|
|
if (*p == 'B') { /* Business Provider */
|
|
|
|
|
xbusiness=1;
|
|
|
|
|
p = strtok(0, ",");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
xproviders = realloc(xproviders, (nx_providers + 1) * sizeof(int));
|
|
|
|
|
xproviders[nx_providers] = atoi(p);
|
|
|
|
|
p = strtok(0, ",");
|
|
|
|
|
nx_providers++;
|
|
|
|
|
}
|
|
|
|
|
free(arg);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
case 'p': /* Providers ... */
|
1999-09-19 14:16:26 +00:00
|
|
|
|
{
|
|
|
|
|
char *arg = strdup(optarg);
|
|
|
|
|
p = strtok(arg, ",");
|
|
|
|
|
while (p) {
|
|
|
|
|
if (*p == 'B') { /* Business Provider */
|
|
|
|
|
business=1;
|
|
|
|
|
p = strtok(0, ",");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
providers = realloc(providers, (n_providers + 1) * sizeof(int));
|
|
|
|
|
providers[n_providers] = atoi(p);
|
|
|
|
|
p = strtok(0, ",");
|
|
|
|
|
n_providers++;
|
|
|
|
|
}
|
|
|
|
|
free(arg);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
case 'v':
|
|
|
|
|
verbose++;
|
|
|
|
|
if (optarg && (x = atoi(optarg)))
|
|
|
|
|
verbose = x;
|
|
|
|
|
break;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
/* Uppercase options are for output format */
|
1999-07-02 19:17:01 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
case 'C':
|
|
|
|
|
is_client = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'D':
|
|
|
|
|
is_daemon = 1;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
need_dest = 0;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (optarg) {
|
|
|
|
|
x = atoi(optarg);
|
|
|
|
|
is_daemon = x;
|
|
|
|
|
if (we_are_daemon && x == 3) {
|
|
|
|
|
kill(getppid(), SIGTERM);
|
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'G':
|
|
|
|
|
explain = atoi(optarg);
|
|
|
|
|
break;
|
|
|
|
|
case 'H':
|
|
|
|
|
header++;
|
|
|
|
|
break;
|
|
|
|
|
case 'L':
|
|
|
|
|
list++;
|
|
|
|
|
explain = 9;
|
|
|
|
|
break;
|
1999-10-25 18:30:03 +00:00
|
|
|
|
case 'N':
|
|
|
|
|
explain = 55;
|
|
|
|
|
break;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
case 'S':
|
|
|
|
|
sortby = *optarg;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
break;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
case 'T':
|
|
|
|
|
table++;
|
|
|
|
|
break;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
/* Fixme: check/warn illegal kombinations of options */
|
1999-09-09 11:21:04 +00:00
|
|
|
|
case 'U':
|
|
|
|
|
usestat++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'V':
|
|
|
|
|
print_version(myshortname);
|
|
|
|
|
exit(0);
|
|
|
|
|
|
|
|
|
|
case 'X':
|
|
|
|
|
if (explain == 0) {
|
|
|
|
|
explain++;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if (optarg && isdigit(*optarg) && (x = atoi(optarg))) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
explain = x;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if (x==50||x==51)
|
|
|
|
|
need_dest=0;
|
|
|
|
|
}
|
|
|
|
|
else if(optarg) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
comment = strdup(optarg);
|
|
|
|
|
explain = 8;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
need_dest=0;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
/* fallthrough */
|
|
|
|
|
case '?':
|
|
|
|
|
print_msg(PRT_A, usage, myshortname, myshortname, options);
|
|
|
|
|
break;
|
|
|
|
|
} /* switch */
|
|
|
|
|
} /* while */
|
|
|
|
|
if (is_client && is_daemon != 3 && is_daemon) {
|
|
|
|
|
is_daemon = 0;
|
|
|
|
|
print_msg(PRT_A, "Conflicting options, -D disabled\n");
|
|
|
|
|
}
|
|
|
|
|
if (list && table) {
|
|
|
|
|
table = 0;
|
|
|
|
|
print_msg(PRT_A, "Conflicting options, -T disabled\n");
|
|
|
|
|
}
|
|
|
|
|
if (usestat && !table)
|
|
|
|
|
print_msg(PRT_A, "Conflicting options, -U ignored\n");
|
|
|
|
|
if ((list || table) && explain >= 10) {
|
|
|
|
|
list = table = 0;
|
|
|
|
|
print_msg(PRT_A, "Conflicting options, -T, -L disabled\n");
|
|
|
|
|
}
|
|
|
|
|
if (best < 1) {
|
|
|
|
|
best = MAXPROVIDER;
|
|
|
|
|
print_msg(PRT_A, "Illegal options, -b ignored\n");
|
|
|
|
|
}
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if ((explain==50||explain==51) && header) {
|
|
|
|
|
print_msg(PRT_A, "Conflicting options, -H ignored\n");
|
|
|
|
|
}
|
1999-06-30 17:17:10 +00:00
|
|
|
|
if (argc > optind)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
return (optind);
|
1999-06-30 17:17:10 +00:00
|
|
|
|
else
|
1999-09-09 11:21:04 +00:00
|
|
|
|
return (0);
|
|
|
|
|
} /* opts */
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static int (*compare_func)(const void *s1, const void *s2);
|
1999-06-28 19:14:59 +00:00
|
|
|
|
static int compare(const void *s1, const void *s2)
|
|
|
|
|
{
|
1999-09-09 11:21:04 +00:00
|
|
|
|
return (((SORT *) s1)->rate > ((SORT *) s2)->rate);
|
|
|
|
|
} /* compare */
|
|
|
|
|
static int compare_vbn(const void *s1, const void *s2)
|
|
|
|
|
{
|
|
|
|
|
return (((SORT *) s1)->prefix > ((SORT *) s2)->prefix);
|
|
|
|
|
}
|
|
|
|
|
static int compare_name(const void *s1, const void *s2)
|
|
|
|
|
{
|
|
|
|
|
return strcasecmp(((SORT *) s1)->name, ((SORT *) s2)->name);
|
|
|
|
|
}
|
|
|
|
|
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
|
|
|
|
|
1999-07-04 20:46:39 +00:00
|
|
|
|
static int compare2(const void *s1, const void *s2)
|
|
|
|
|
{
|
1999-09-09 11:21:04 +00:00
|
|
|
|
return (((SORT2 *) s1)->weight < ((SORT2 *) s2)->weight);
|
|
|
|
|
} /* compare2 */
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
char *short_explainRate(RATE * Rate)
|
1999-07-15 16:41:22 +00:00
|
|
|
|
{
|
1999-09-09 11:21:04 +00:00
|
|
|
|
|
1999-07-15 16:41:22 +00:00
|
|
|
|
static char buffer[BUFSIZ];
|
1999-09-09 11:21:04 +00:00
|
|
|
|
char *p = buffer;
|
1999-07-15 16:41:22 +00:00
|
|
|
|
|
|
|
|
|
if (Rate->Zone && *Rate->Zone)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
p += sprintf(p, "%s", Rate->Zone);
|
1999-07-15 16:41:22 +00:00
|
|
|
|
else
|
1999-09-09 11:21:04 +00:00
|
|
|
|
p += sprintf(p, "Zone %d", Rate->zone);
|
1999-07-15 16:41:22 +00:00
|
|
|
|
|
|
|
|
|
if (!Rate->domestic && Rate->Country && *Rate->Country)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
p += sprintf(p, " (%s)", Rate->Country);
|
1999-07-15 16:41:22 +00:00
|
|
|
|
|
|
|
|
|
if (Rate->Day && *Rate->Day)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
p += sprintf(p, ", %s", Rate->Day);
|
1999-07-15 16:41:22 +00:00
|
|
|
|
|
|
|
|
|
if (Rate->Hour && *Rate->Hour)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
p += sprintf(p, ", %s", Rate->Hour);
|
1999-07-15 16:41:22 +00:00
|
|
|
|
|
|
|
|
|
return buffer;
|
|
|
|
|
}
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static char *printrate(RATE * Rate)
|
1999-06-28 19:14:59 +00:00
|
|
|
|
{
|
|
|
|
|
static char message[BUFSIZ];
|
|
|
|
|
|
|
|
|
|
|
1999-07-07 19:43:36 +00:00
|
|
|
|
if (Rate->Basic > 0)
|
1999-07-15 16:41:22 +00:00
|
|
|
|
sprintf(message, "%s + %s/%.4fs = %s + %s/Min (%s)",
|
1999-09-09 11:21:04 +00:00
|
|
|
|
printRate(Rate->Basic),
|
|
|
|
|
printRate(Rate->Price),
|
|
|
|
|
Rate->Duration,
|
|
|
|
|
printRate(Rate->Basic),
|
|
|
|
|
printRate(60 * Rate->Price / Rate->Duration),
|
|
|
|
|
short_explainRate(Rate));
|
1999-06-28 19:14:59 +00:00
|
|
|
|
else
|
1999-07-15 16:41:22 +00:00
|
|
|
|
sprintf(message, "%s/%.4fs = %s/Min (%s)",
|
1999-09-09 11:21:04 +00:00
|
|
|
|
printRate(Rate->Price),
|
|
|
|
|
Rate->Duration,
|
|
|
|
|
printRate(60 * Rate->Price / Rate->Duration),
|
|
|
|
|
short_explainRate(Rate));
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
return (message);
|
|
|
|
|
} /* printrate */
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
|
|
|
|
|
1999-06-29 20:10:18 +00:00
|
|
|
|
static void buildtime()
|
|
|
|
|
{
|
|
|
|
|
auto struct tm tm;
|
|
|
|
|
|
1999-07-24 08:43:38 +00:00
|
|
|
|
tm.tm_sec = sec;
|
1999-06-29 20:10:18 +00:00
|
|
|
|
tm.tm_min = min;
|
|
|
|
|
tm.tm_hour = hour;
|
|
|
|
|
tm.tm_mday = day;
|
|
|
|
|
tm.tm_mon = month - 1;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
tm.tm_year = year - 1900; /* ja, ja, ich wei<65> ;-) */
|
1999-06-29 20:10:18 +00:00
|
|
|
|
tm.tm_isdst = -1;
|
|
|
|
|
|
|
|
|
|
start = mktime(&tm);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
} /* buildtime */
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void splittime()
|
|
|
|
|
{
|
|
|
|
|
auto struct tm *tm;
|
|
|
|
|
|
|
|
|
|
tm = localtime(&start);
|
1999-07-24 08:43:38 +00:00
|
|
|
|
sec = tm->tm_sec;
|
1999-06-29 20:10:18 +00:00
|
|
|
|
min = tm->tm_min;
|
|
|
|
|
hour = tm->tm_hour;
|
|
|
|
|
day = tm->tm_mday;
|
|
|
|
|
month = tm->tm_mon + 1;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
year = tm->tm_year + 1900;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
} /* splittime */
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-07-04 20:46:39 +00:00
|
|
|
|
static char *Provider(int prefix)
|
|
|
|
|
{
|
1999-09-13 09:09:42 +00:00
|
|
|
|
register char *p, *p1;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
register int l;
|
|
|
|
|
static char s[BUFSIZ];
|
|
|
|
|
char prov[TN_MAX_PROVIDER_LEN];
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
|
|
|
|
if (prefix == UNKNOWN)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
return ("?");
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
|
|
|
|
p = getProvider(prefix);
|
|
|
|
|
|
|
|
|
|
l = max(WIDTH, strlen(p)) - strlen(p);
|
|
|
|
|
|
1999-10-25 18:30:03 +00:00
|
|
|
|
p1 = prefix2provider(prefix, prov);
|
1999-09-13 09:09:42 +00:00
|
|
|
|
|
|
|
|
|
l += (6 - strlen(p1));
|
|
|
|
|
|
|
|
|
|
sprintf(s, "%s:%s%*s", p1, p, l, "");
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
return (s);
|
|
|
|
|
} /* Provider */
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static char *takt_str(RATE * Rate)
|
|
|
|
|
{
|
|
|
|
|
static char s[BUFSIZ];
|
|
|
|
|
|
|
|
|
|
if (floor(Rate->Rhythm[0]) == Rate->Rhythm[0])
|
|
|
|
|
sprintf(s, "%.0f/", Rate->Rhythm[0]);
|
|
|
|
|
else
|
|
|
|
|
sprintf(s, "%.3f/", Rate->Rhythm[0]);
|
|
|
|
|
if (floor(Rate->Rhythm[1]) == Rate->Rhythm[1])
|
|
|
|
|
sprintf(s + strlen(s), "%.0f", Rate->Rhythm[1]);
|
|
|
|
|
else
|
|
|
|
|
sprintf(s + strlen(s), "%.3f", Rate->Rhythm[1]);
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-19 14:16:26 +00:00
|
|
|
|
static inline char * P_EMPTY(char *s)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
{
|
|
|
|
|
char *p = s;
|
|
|
|
|
return p ? p : "";
|
|
|
|
|
}
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-07-24 08:43:38 +00:00
|
|
|
|
#define DEL ';'
|
1999-07-25 15:57:01 +00:00
|
|
|
|
static int compute(char *num)
|
1999-06-30 20:53:28 +00:00
|
|
|
|
{
|
1999-09-09 11:21:04 +00:00
|
|
|
|
register int i, n = 0;
|
|
|
|
|
register int low = 0, high = MAXPROVIDER - 1;
|
|
|
|
|
auto RATE Rate;
|
|
|
|
|
auto char s[BUFSIZ];
|
1999-07-24 08:43:38 +00:00
|
|
|
|
struct tm *tm;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
char prov[TN_MAX_PROVIDER_LEN];
|
|
|
|
|
int first = 1;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
static char BUSINESS[] = "Business"; /* in C:GT:Tag */
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-07-25 15:57:01 +00:00
|
|
|
|
if (destnum.nprovider != UNKNOWN) {
|
|
|
|
|
low = high = destnum.nprovider;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
} /* if */
|
|
|
|
|
compare_func = compare;
|
|
|
|
|
switch (sortby) {
|
|
|
|
|
case 'v' : compare_func = compare_vbn; break;
|
|
|
|
|
case 'n' : compare_func = compare_name; break;
|
|
|
|
|
}
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-07-24 08:43:38 +00:00
|
|
|
|
buildtime();
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (explain == 98 || explain == 97) { /* Minutenpreis fuer
|
|
|
|
|
diese Woche */
|
|
|
|
|
tm = localtime(&start);
|
|
|
|
|
tm->tm_hour = 0;
|
|
|
|
|
tm->tm_min = 1;
|
|
|
|
|
tm->tm_sec = 0;
|
|
|
|
|
start = mktime(tm);
|
1999-07-24 08:43:38 +00:00
|
|
|
|
if (explain == 98) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
while (tm->tm_wday) { /* find last monday */
|
|
|
|
|
start -= (60 * 60 * 24);
|
|
|
|
|
tm = localtime(&start);
|
|
|
|
|
} /* while */
|
|
|
|
|
start += (60 * 60 * 24);
|
|
|
|
|
}
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
1999-07-04 20:46:39 +00:00
|
|
|
|
for (i = low; i <= high; i++) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
int found, p;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
char *t;
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
|
|
|
|
if (ignore[i])
|
|
|
|
|
continue;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
t = getProvider(i);
|
|
|
|
|
if (!t || t[strlen(t) - 1] == '?') /* UNKNOWN Provider */
|
1999-07-24 08:43:38 +00:00
|
|
|
|
continue;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
|
|
|
|
|
t = getComment(i, "GT"); /* get Geb. Text comment */
|
|
|
|
|
if (business) { /* only business wanted */
|
|
|
|
|
if (t == 0)
|
|
|
|
|
continue;
|
|
|
|
|
else if(strstr(t, BUSINESS) == 0)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (xbusiness) { /* no business wanted */
|
|
|
|
|
if(t && strstr(t, BUSINESS) > 0)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
1999-09-09 11:21:04 +00:00
|
|
|
|
found = 0;
|
|
|
|
|
if (n_providers) {
|
|
|
|
|
for (p = 0; p < n_providers; p++)
|
|
|
|
|
if (providers[p] == i) {
|
|
|
|
|
found = 1;
|
|
|
|
|
break;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if (!found)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (nx_providers) {
|
|
|
|
|
for (p = 0; p < nx_providers; p++)
|
|
|
|
|
if (xproviders[p] == i) {
|
|
|
|
|
found = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (found)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
1999-06-28 19:14:59 +00:00
|
|
|
|
clearRate(&Rate);
|
1999-10-25 18:30:03 +00:00
|
|
|
|
#ifdef USE_DESTINATION
|
|
|
|
|
Rate.src[0] = srcnum.country;
|
|
|
|
|
#else
|
1999-09-09 11:21:04 +00:00
|
|
|
|
Rate.src[0] = srcnum.country ? srcnum.country->Code[0] : "";
|
1999-10-25 18:30:03 +00:00
|
|
|
|
#endif
|
1999-07-25 15:57:01 +00:00
|
|
|
|
Rate.src[1] = srcnum.area;
|
1999-06-29 20:10:18 +00:00
|
|
|
|
Rate.src[2] = "";
|
|
|
|
|
|
1999-10-25 18:30:03 +00:00
|
|
|
|
destnum.nprovider = i;
|
|
|
|
|
Strncpy(destnum.provider,getProvider(i),TN_MAX_PROVIDER_LEN);
|
|
|
|
|
if (normalizeNumber(num, &destnum, TN_NO_PROVIDER) == UNKNOWN) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
1999-07-25 15:57:01 +00:00
|
|
|
|
|
1999-10-25 18:30:03 +00:00
|
|
|
|
#ifdef USE_DESTINATION
|
|
|
|
|
Rate.dst[0] = destnum.country;
|
|
|
|
|
#else
|
1999-09-09 11:21:04 +00:00
|
|
|
|
Rate.dst[0] = destnum.country ? destnum.country->Code[0] : "";
|
1999-10-25 18:30:03 +00:00
|
|
|
|
#endif
|
1999-09-09 11:21:04 +00:00
|
|
|
|
Rate.dst[1] = destnum.area;
|
|
|
|
|
Rate.dst[2] = destnum.msn;
|
|
|
|
|
print_msg(PRT_V, "Rate dst0='%s' dst1='%s' dst2='%s'\n", Rate.dst[0], Rate.dst[1], Rate.dst[2]);
|
1999-07-04 20:46:39 +00:00
|
|
|
|
/* Rate.Service = "Internet by call"; */
|
|
|
|
|
|
1999-06-28 19:14:59 +00:00
|
|
|
|
Rate.prefix = i;
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
|
|
|
|
Rate.start = start;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
Rate.now = start + duration - 1;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
if (explain == 99) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
int j;
|
|
|
|
|
double oldCharge = -1.0;
|
|
|
|
|
|
|
|
|
|
if (first && header)
|
|
|
|
|
print_header();
|
|
|
|
|
first = 0;
|
1999-10-25 18:30:03 +00:00
|
|
|
|
printf("@ %s\n", prefix2provider(Rate.prefix, prov));
|
1999-09-09 11:21:04 +00:00
|
|
|
|
Rate.now = start + 1;
|
|
|
|
|
for (j = 1; j < duration; j++) {
|
|
|
|
|
if (!getRate(&Rate, NULL) && (Rate.Price != 99.99)) {
|
|
|
|
|
if (Rate.Charge != oldCharge || j == duration - 1) {
|
|
|
|
|
printf("%d %.4f\n", j, Rate.Charge);
|
|
|
|
|
oldCharge = Rate.Charge;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
1999-09-09 11:21:04 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
Rate.now++;
|
1999-07-02 19:17:01 +00:00
|
|
|
|
}
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (Rate.Duration <= takt)
|
|
|
|
|
printf("@----- %s %s\n", currency, Rate.Provider);
|
|
|
|
|
}
|
|
|
|
|
if (explain == 98 || explain == 97) { /* Minutenpreis fuer
|
|
|
|
|
diese Woche/Tag */
|
|
|
|
|
int j;
|
|
|
|
|
|
|
|
|
|
if (first && header)
|
|
|
|
|
print_header();
|
|
|
|
|
first = 0;
|
1999-10-25 18:30:03 +00:00
|
|
|
|
printf("@ %s\n", prefix2provider(Rate.prefix, prov));
|
1999-09-09 11:21:04 +00:00
|
|
|
|
for (j = 0; j < (explain == 98 ? 7 * 24 : 24); j++) {
|
|
|
|
|
if (!getRate(&Rate, NULL) && (Rate.Price != 99.99)) {
|
|
|
|
|
printf("%d %.4f\n", j, Rate.Charge);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
Rate.now += 3600;
|
|
|
|
|
Rate.start += 3600;
|
1999-08-04 23:06:52 +00:00
|
|
|
|
}
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (Rate.Duration <= takt)
|
|
|
|
|
printf("@----- %s %s\n", currency, Rate.Provider);
|
|
|
|
|
}
|
1999-09-19 14:16:26 +00:00
|
|
|
|
else if (explain==50||explain==51) {
|
|
|
|
|
int fi=1;
|
|
|
|
|
while(getZoneRate(&Rate, explain-50,fi) == 0) {
|
|
|
|
|
double cpm = Rate.Duration > 0 ? 60 * Rate.Price / Rate.Duration : 99.99;
|
|
|
|
|
fi=0;
|
|
|
|
|
if (Rate.Price != 99.99)
|
1999-10-25 18:30:03 +00:00
|
|
|
|
printf("%s%c%s%c%s%c%.2f%c%.2f%c%s\n", prefix2provider(Rate.prefix, prov), DEL,
|
1999-09-19 14:16:26 +00:00
|
|
|
|
Rate.Provider,DEL,currency,DEL,Rate.Charge,DEL,cpm,DEL,
|
|
|
|
|
P_EMPTY(Rate.Country));
|
|
|
|
|
free(Rate.Country);
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-09-09 11:21:04 +00:00
|
|
|
|
else {
|
|
|
|
|
/* kludge to suppress "impossible" Rates */
|
|
|
|
|
if (!getRate(&Rate, NULL) && (Rate.Price != 99.99)) {
|
|
|
|
|
if (!(Rate.Duration <= takt))
|
|
|
|
|
continue;
|
|
|
|
|
sort[n].prefix = Rate.prefix;
|
|
|
|
|
sort[n].rate = Rate.Charge;
|
|
|
|
|
sort[n].name = Rate.Provider;
|
|
|
|
|
switch (explain) {
|
|
|
|
|
case 1:
|
|
|
|
|
sprintf(s, " (%s)", Rate.Zone);
|
|
|
|
|
sort[n].explain = strdup(s);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
sprintf(s, " (%s)", printrate(&Rate));
|
|
|
|
|
sort[n].explain = strdup(s);
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
sort[n].explain = strdup(P_EMPTY(getComment(i, comment)));
|
|
|
|
|
break;
|
|
|
|
|
case 9: /* used by list */
|
|
|
|
|
{
|
|
|
|
|
double cpm = Rate.Duration > 0 ? 60 * Rate.Price / Rate.Duration : 99.99;
|
|
|
|
|
|
|
|
|
|
sprintf(s, "%s%c"
|
|
|
|
|
"%s%c%s%c%s%c%s%c"
|
|
|
|
|
"%s%c"
|
|
|
|
|
"%.3f%c%.4f%c%.4f%c%.2f%c%.3f%c"
|
|
|
|
|
"%s%c%.2f",
|
1999-10-25 18:30:03 +00:00
|
|
|
|
prefix2provider(Rate.prefix, prov), DEL,
|
1999-09-09 11:21:04 +00:00
|
|
|
|
Rate.Provider, DEL, P_EMPTY(Rate.Zone), DEL, P_EMPTY(Rate.Day), DEL, P_EMPTY(Rate.Hour), DEL,
|
|
|
|
|
currency, DEL, /* Fixme: global or per
|
|
|
|
|
Provider?? wg. EURO */
|
|
|
|
|
Rate.Charge, DEL, Rate.Basic, DEL, Rate.Price, DEL, Rate.Duration, DEL, cpm, DEL,
|
|
|
|
|
takt_str(&Rate), DEL, Rate.Sales);
|
|
|
|
|
sort[n].explain = strdup(s);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
sort[n].explain = strdup("");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n++;
|
|
|
|
|
} /* if */
|
|
|
|
|
} /* else 99 */
|
|
|
|
|
} /* for i */
|
|
|
|
|
if (explain < 10)
|
|
|
|
|
qsort((void *) sort, n, sizeof(SORT), compare_func);
|
|
|
|
|
|
|
|
|
|
return (n);
|
|
|
|
|
} /* compute */
|
|
|
|
|
|
|
|
|
|
static void print_header(void)
|
|
|
|
|
{
|
|
|
|
|
print_msg(PRT_NORMAL, "Eine %d Sekunden lange Verbindung von %s nach %s kostet am %s\n",
|
1999-11-02 21:01:56 +00:00
|
|
|
|
duration, formatNumber("%F", &srcnum), formatNumber("%F", &destnum),
|
1999-09-09 11:21:04 +00:00
|
|
|
|
ctime(&start));
|
1999-07-25 15:57:01 +00:00
|
|
|
|
}
|
1999-09-09 11:21:04 +00:00
|
|
|
|
|
1999-09-19 14:16:26 +00:00
|
|
|
|
static void printList(int n)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
1999-07-24 08:43:38 +00:00
|
|
|
|
if (header)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_header();
|
1999-07-24 08:43:38 +00:00
|
|
|
|
if (n > best)
|
|
|
|
|
n = best;
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-07-24 08:43:38 +00:00
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
|
print_msg(PRT_NORMAL, "%s\n", sort[i].explain);
|
|
|
|
|
}
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-09-19 14:16:26 +00:00
|
|
|
|
static void result(int n)
|
1999-06-29 20:10:18 +00:00
|
|
|
|
{
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
register int i;
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-06-28 19:14:59 +00:00
|
|
|
|
if (header)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_header();
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
|
|
|
|
if (n > best)
|
|
|
|
|
n = best;
|
|
|
|
|
for (i = 0; i < n; i++)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_NORMAL, "%s %s %8.3f %s\n",
|
|
|
|
|
Provider(sort[i].prefix), currency, sort[i].rate, sort[i].explain);
|
|
|
|
|
} /* result */
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void purge(int n)
|
|
|
|
|
{
|
|
|
|
|
register int i;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < n; i++)
|
1999-07-02 19:17:01 +00:00
|
|
|
|
if (sort[i].explain)
|
|
|
|
|
free(sort[i].explain);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
} /* purge */
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
1999-09-09 11:21:04 +00:00
|
|
|
|
Werktag
|
|
|
|
|
Wochenende
|
|
|
|
|
Ortszone
|
|
|
|
|
Regionalzone
|
|
|
|
|
Fernzone
|
|
|
|
|
Handy
|
|
|
|
|
Internet
|
|
|
|
|
0..23 Uhr
|
|
|
|
|
*/
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-07-25 15:57:01 +00:00
|
|
|
|
static void printTable(char *num)
|
1999-06-29 20:10:18 +00:00
|
|
|
|
{
|
1999-09-09 11:21:04 +00:00
|
|
|
|
register int n, d, i, h, lasthour;
|
|
|
|
|
auto struct tm *tm;
|
|
|
|
|
auto SORT last[_MAXLAST];
|
|
|
|
|
auto int used[MAXPROVIDER];
|
|
|
|
|
auto int hours[MAXPROVIDER];
|
|
|
|
|
auto int weight[MAXPROVIDER];
|
|
|
|
|
auto int useds = 0, maxhour;
|
|
|
|
|
auto SORT2 wsort[MAXPROVIDER];
|
|
|
|
|
static int firsttime = 1;
|
|
|
|
|
int first;
|
1999-10-26 18:17:11 +00:00
|
|
|
|
int prefix;
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-07-03 10:23:55 +00:00
|
|
|
|
memset(used, 0, sizeof(used));
|
1999-07-04 20:46:39 +00:00
|
|
|
|
memset(hours, 0, sizeof(hours));
|
|
|
|
|
memset(weight, 0, sizeof(weight));
|
1999-07-03 10:23:55 +00:00
|
|
|
|
|
1999-06-30 17:17:10 +00:00
|
|
|
|
|
1999-06-30 20:53:28 +00:00
|
|
|
|
for (d = 0; d < 2; d++) {
|
|
|
|
|
last[0].prefix = UNKNOWN;
|
|
|
|
|
lasthour = UNKNOWN;
|
1999-06-30 17:17:10 +00:00
|
|
|
|
|
1999-06-30 20:53:28 +00:00
|
|
|
|
buildtime();
|
|
|
|
|
tm = localtime(&start);
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (!d) { /* Wochenende */
|
|
|
|
|
while (tm->tm_wday) { /* find next sunday */
|
|
|
|
|
start += (60 * 60 * 24);
|
|
|
|
|
tm = localtime(&start);
|
|
|
|
|
} /* while */
|
1999-06-30 20:53:28 +00:00
|
|
|
|
}
|
1999-09-09 11:21:04 +00:00
|
|
|
|
else /* Werktag (Montag) */
|
1999-06-30 20:53:28 +00:00
|
|
|
|
start += (60 * 60 * 24);
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-06-30 20:53:28 +00:00
|
|
|
|
splittime();
|
|
|
|
|
buildtime();
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-06-30 20:53:28 +00:00
|
|
|
|
hour = 7;
|
|
|
|
|
min = 0;
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
first = 1;
|
1999-06-30 20:53:28 +00:00
|
|
|
|
while (1) {
|
1999-10-26 18:17:11 +00:00
|
|
|
|
destnum.nprovider = UNKNOWN;
|
|
|
|
|
if(provider2prefix(num, &prefix)) /* set provider if it is in number */
|
|
|
|
|
normalizeNumber(num, &destnum, TN_PROVIDER);
|
1999-07-25 15:57:01 +00:00
|
|
|
|
n = compute(num);
|
1999-06-30 20:53:28 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (header && first && d == 0 && firsttime)
|
|
|
|
|
print_header();
|
|
|
|
|
if (header && first)
|
|
|
|
|
print_msg(PRT_NORMAL, "\n%s:\n", d ? "Werktag" : "Wochenende");
|
|
|
|
|
first = 0;
|
|
|
|
|
|
1999-06-30 20:53:28 +00:00
|
|
|
|
if (last[0].prefix == UNKNOWN) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
for (i = 0; i < min(n, MAXLAST); i++) {
|
|
|
|
|
if (sort[i].prefix) {
|
|
|
|
|
last[i].prefix = sort[i].prefix;
|
|
|
|
|
last[i].rate = sort[i].rate;
|
|
|
|
|
last[i].explain = strdup(sort[i].explain);
|
|
|
|
|
} /* if */
|
|
|
|
|
} /* for */
|
|
|
|
|
} /* if */
|
1999-06-30 20:53:28 +00:00
|
|
|
|
|
|
|
|
|
if (lasthour == UNKNOWN)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
lasthour = hour;
|
1999-06-30 20:53:28 +00:00
|
|
|
|
|
|
|
|
|
if (sort[0].prefix != last[0].prefix) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
for (i = 0; i < min(n, MAXLAST); i++) {
|
|
|
|
|
|
|
|
|
|
if (!i)
|
|
|
|
|
print_msg(PRT_NORMAL, " %02d:00 .. %02d:59 %s = %s %s%s\n",
|
|
|
|
|
lasthour, hour - 1, Provider(last[i].prefix),
|
|
|
|
|
currency,
|
|
|
|
|
double2str(last[i].rate, 5, 3, DEB),
|
|
|
|
|
last[i].explain);
|
|
|
|
|
else
|
|
|
|
|
print_msg(PRT_NORMAL, " %s = %s %s%s\n",
|
|
|
|
|
Provider(last[i].prefix),
|
|
|
|
|
currency,
|
|
|
|
|
double2str(last[i].rate, 5, 3, DEB),
|
|
|
|
|
last[i].explain);
|
|
|
|
|
} /* for */
|
|
|
|
|
|
|
|
|
|
used[last[0].prefix]++;
|
|
|
|
|
|
|
|
|
|
if (lasthour >= hour)
|
|
|
|
|
h = ((24 - lasthour) + hour);
|
|
|
|
|
else
|
|
|
|
|
h = hour - lasthour;
|
|
|
|
|
|
|
|
|
|
hours[last[0].prefix] += h;
|
|
|
|
|
|
|
|
|
|
if ((lasthour > 8) && (lasthour < 21))
|
|
|
|
|
h *= 2;
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
|
|
|
|
weight[last[0].prefix] += h * (d ? 5 : 2);
|
1999-06-30 20:53:28 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
for (i = 0; i < min(n, MAXLAST); i++) {
|
|
|
|
|
last[i].prefix = sort[i].prefix;
|
|
|
|
|
last[i].rate = sort[i].rate;
|
|
|
|
|
last[i].explain = strdup(sort[i].explain);
|
|
|
|
|
} /* for */
|
1999-06-30 20:53:28 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
lasthour = hour;
|
|
|
|
|
} /* if */
|
1999-06-30 20:53:28 +00:00
|
|
|
|
|
|
|
|
|
purge(n);
|
|
|
|
|
|
|
|
|
|
hour++;
|
|
|
|
|
|
|
|
|
|
if (hour == 24)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
hour = 0;
|
1999-06-30 20:53:28 +00:00
|
|
|
|
else if (hour == 7)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
break;
|
|
|
|
|
} /* while */
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
for (i = 0; i < min(n, MAXLAST); i++) {
|
1999-06-30 20:53:28 +00:00
|
|
|
|
|
1999-07-01 20:38:57 +00:00
|
|
|
|
if (!i) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if ((lasthour == 7) && (hour == 7))
|
|
|
|
|
print_msg(PRT_NORMAL, " immer %s = %s %s%s\n",
|
|
|
|
|
Provider(last[i].prefix),
|
|
|
|
|
currency,
|
|
|
|
|
double2str(last[i].rate, 5, 3, DEB),
|
|
|
|
|
last[i].explain);
|
|
|
|
|
else
|
|
|
|
|
print_msg(PRT_NORMAL, " %02d:00 .. %02d:59 %s = %s %s%s\n",
|
|
|
|
|
lasthour, hour - 1, Provider(last[i].prefix),
|
|
|
|
|
currency,
|
|
|
|
|
double2str(last[i].rate, 5, 3, DEB),
|
|
|
|
|
last[i].explain);
|
1999-07-01 20:38:57 +00:00
|
|
|
|
}
|
1999-06-30 20:53:28 +00:00
|
|
|
|
else
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_NORMAL, " %s = %s %s%s\n",
|
|
|
|
|
Provider(last[i].prefix),
|
|
|
|
|
currency,
|
|
|
|
|
double2str(last[i].rate, 5, 3, DEB),
|
|
|
|
|
last[i].explain);
|
|
|
|
|
} /* for */
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-07-04 20:46:39 +00:00
|
|
|
|
used[last[0].prefix]++;
|
1999-06-29 20:10:18 +00:00
|
|
|
|
|
1999-06-30 20:53:28 +00:00
|
|
|
|
if (lasthour >= hour)
|
1999-07-04 20:46:39 +00:00
|
|
|
|
h = ((24 - lasthour) + hour);
|
1999-06-30 20:53:28 +00:00
|
|
|
|
else
|
1999-07-04 20:46:39 +00:00
|
|
|
|
h = hour - lasthour;
|
|
|
|
|
|
|
|
|
|
hours[last[0].prefix] += h;
|
|
|
|
|
|
|
|
|
|
if ((lasthour > 8) && (lasthour < 21))
|
|
|
|
|
h *= 2;
|
|
|
|
|
|
|
|
|
|
weight[last[0].prefix] += h * (d ? 5 : 2);
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
} /* for */
|
1999-07-03 10:23:55 +00:00
|
|
|
|
|
|
|
|
|
if (usestat) {
|
|
|
|
|
print_msg(PRT_NORMAL, "\nProvider(s) used:\n");
|
|
|
|
|
|
|
|
|
|
maxhour = 9999999;
|
|
|
|
|
useds = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXPROVIDER; i++)
|
|
|
|
|
if (used[i]) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_NORMAL, "%s %d times, %d hours, weight = %d\n",
|
|
|
|
|
Provider(i), used[i], hours[i], weight[i]);
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
wsort[useds].weight = weight[i];
|
|
|
|
|
wsort[useds].index = i;
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
useds++;
|
1999-07-03 10:23:55 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (hours[i] < maxhour)
|
|
|
|
|
maxhour = hours[i];
|
|
|
|
|
} /* if */
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
|
|
|
|
if ((best < MAXPROVIDER) && (best < useds)) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_V, "Retrying with only %d provider(s), eliminating %d provider(s)\n", best, useds - best);
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
qsort((void *) wsort, useds, sizeof(SORT2), compare2);
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < useds; i++) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_NORMAL, "%s %d times, %d hours, weight = %d\n",
|
|
|
|
|
Provider(wsort[i].index), used[wsort[i].index], hours[wsort[i].index], weight[wsort[i].index]);
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (i == best - 1)
|
|
|
|
|
print_msg(PRT_NORMAL, "\n");
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (i >= best - 1)
|
|
|
|
|
ignore[wsort[i].index]++;
|
|
|
|
|
} /* for */
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
|
|
|
|
if (firsttime)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
printTable(num);
|
1999-07-04 20:46:39 +00:00
|
|
|
|
|
|
|
|
|
firsttime = 0;
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
} /* if */
|
|
|
|
|
} /* if */
|
|
|
|
|
} /* printTable */
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static void clean_up()
|
|
|
|
|
{
|
1999-07-24 08:43:38 +00:00
|
|
|
|
if (providers)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
free(providers);
|
|
|
|
|
providers = 0;
|
|
|
|
|
fromarea = 0;
|
|
|
|
|
table = list = header = explain = 0;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
usestat = 0;
|
|
|
|
|
duration = LCR_DURATION;
|
|
|
|
|
wanted_day = '\0';
|
1999-09-09 11:21:04 +00:00
|
|
|
|
takt = 99999;
|
|
|
|
|
if (comment)
|
|
|
|
|
free(comment);
|
|
|
|
|
comment = 0;
|
|
|
|
|
sortby = 0;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
need_dest=1;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-09-16 20:27:21 +00:00
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
static void viacode(char *target, TELNUM *destnum)
|
|
|
|
|
{
|
|
|
|
|
register char *p, *p1;
|
|
|
|
|
auto FILE *fi = fopen("/usr/lib/isdn/code-de.dat", "r");
|
|
|
|
|
auto char s[BUFSIZ];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fi != (FILE *)NULL) {
|
|
|
|
|
while (fgets(s, BUFSIZ, fi)) {
|
|
|
|
|
if ((p = strchr(s, '\n'))) {
|
|
|
|
|
|
|
|
|
|
*p-- = 0;
|
|
|
|
|
|
|
|
|
|
while ((p > s) && !isblank(*p))
|
|
|
|
|
p--;
|
|
|
|
|
|
|
|
|
|
if (p > s) {
|
|
|
|
|
if (!strcasecmp(p + 1, target)) {
|
|
|
|
|
p1 = s;
|
|
|
|
|
|
|
|
|
|
while (!isblank(*p1))
|
|
|
|
|
p1++;
|
|
|
|
|
|
|
|
|
|
*p1 = 0;
|
|
|
|
|
|
|
|
|
|
sprintf(destnum->msn, "0%s", s);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} /* if */
|
|
|
|
|
} /* if */
|
|
|
|
|
} /* while */
|
|
|
|
|
|
|
|
|
|
fclose(fi);
|
|
|
|
|
} /* if */
|
|
|
|
|
} /* viacode */
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static void doit(int i, int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
int n;
|
1999-10-25 18:30:03 +00:00
|
|
|
|
int prefix;
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
post_init();
|
|
|
|
|
memset(ignore, 0, sizeof(ignore));
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if (!need_dest && i==0) {
|
|
|
|
|
i=0; argc=1;
|
|
|
|
|
argv[0]="2345";
|
|
|
|
|
}
|
1999-09-09 11:21:04 +00:00
|
|
|
|
while (i < argc) {
|
1999-10-25 18:30:03 +00:00
|
|
|
|
if (explain == 55) {
|
|
|
|
|
if(n_providers) {
|
|
|
|
|
destnum.nprovider=providers[0];
|
|
|
|
|
Strncpy(destnum.provider,getProvider(providers[0]),TN_MAX_PROVIDER_LEN);
|
|
|
|
|
normalizeNumber(argv[i], &destnum, TN_NO_PROVIDER);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
normalizeNumber(argv[i], &destnum, TN_ALL);
|
|
|
|
|
printf("%s => %s \n",argv[i],formatNumber("%l - %p",&destnum));
|
|
|
|
|
i++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
1999-09-09 11:21:04 +00:00
|
|
|
|
destnum.nprovider = UNKNOWN;
|
1999-10-25 18:30:03 +00:00
|
|
|
|
if(provider2prefix(argv[i], &prefix)) /* set provider if it is in number */
|
|
|
|
|
normalizeNumber(argv[i], &destnum, TN_PROVIDER);
|
1999-09-16 20:27:21 +00:00
|
|
|
|
#if 0
|
|
|
|
|
if (isalpha(*destnum.msn))
|
|
|
|
|
viacode(argv[i], &destnum);
|
|
|
|
|
#endif
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (table)
|
1999-07-25 15:57:01 +00:00
|
|
|
|
printTable(argv[i]);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
else {
|
1999-07-25 15:57:01 +00:00
|
|
|
|
n = compute(argv[i]);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (list)
|
1999-09-19 14:16:26 +00:00
|
|
|
|
printList(n);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
else if (explain < 10)
|
1999-09-19 14:16:26 +00:00
|
|
|
|
result(n);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
purge(n);
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
} /* while */
|
|
|
|
|
clean_up();
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static void err(char *s)
|
|
|
|
|
{
|
|
|
|
|
print_msg(PRT_A, "%s - '%s'\n", s, strerror(errno));
|
|
|
|
|
if (is_daemon == 2)
|
|
|
|
|
kill(getppid(), SIGTERM);
|
1999-07-24 08:43:38 +00:00
|
|
|
|
exit(2);
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static int handle_client(int fd)
|
|
|
|
|
{
|
|
|
|
|
char buffer[BUFSIZ];
|
|
|
|
|
int argc, n, i;
|
|
|
|
|
char **argv;
|
|
|
|
|
char *p;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if ((n = read(fd, buffer, BUFSIZ)) < 0)
|
|
|
|
|
err("Read");
|
1999-07-24 08:43:38 +00:00
|
|
|
|
if (n) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
argv = calloc(sizeof(char *), 20);
|
|
|
|
|
|
|
|
|
|
buffer[n] = '\0';
|
|
|
|
|
if (verbose)
|
|
|
|
|
fprintf(stderr, "got '%s'\n", buffer);
|
1999-07-24 08:43:38 +00:00
|
|
|
|
argc = 0;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
argv[argc++] = strdup(myname);
|
|
|
|
|
p = strtok(buffer, "\t\n ");
|
1999-07-24 08:43:38 +00:00
|
|
|
|
while (p) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
argv[argc++] = strdup(p);
|
|
|
|
|
p = strtok(0, "\t\n ");
|
|
|
|
|
if (argc >= 20)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
time(&start); /* set time of call */
|
|
|
|
|
splittime(); /* date time my be overridden by opts */
|
|
|
|
|
we_are_daemon = 1;
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if ((i = opts(argc, argv))||need_dest==0) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (shutdown(fd, 0) < 0) /* no read any more */
|
|
|
|
|
err("shutdown");
|
|
|
|
|
if (dup2(fd, STDOUT_FILENO) < 0) /* stdout to sock */
|
|
|
|
|
err("dup");
|
|
|
|
|
doit(i, argc, argv);
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
fclose(stdout);
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; i < argc; i++)
|
|
|
|
|
free(argv[i]);
|
|
|
|
|
free(argv);
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
|
|
|
|
return n == 0 ? -1 : 0;
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
void catch_sig(int sig)
|
|
|
|
|
{
|
|
|
|
|
print_msg(PRT_A, "Signal %d\n", sig);
|
|
|
|
|
unlink(SOCKNAME);
|
|
|
|
|
err("Sig");
|
1999-07-31 09:25:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
static void del_sock(void)
|
|
|
|
|
{
|
|
|
|
|
if (getppid() > 0)
|
|
|
|
|
unlink(SOCKNAME);
|
|
|
|
|
}
|
|
|
|
|
static volatile sig_atomic_t stopped = 0, reinit = 0;
|
|
|
|
|
|
|
|
|
|
static void catch_term(int sig)
|
|
|
|
|
{
|
|
|
|
|
stopped = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void catch_hup(int sig)
|
|
|
|
|
{
|
|
|
|
|
reinit = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void do_reinit(void)
|
|
|
|
|
{
|
|
|
|
|
deinit();
|
|
|
|
|
init();
|
|
|
|
|
reinit=0;
|
|
|
|
|
}
|
1999-09-19 14:16:26 +00:00
|
|
|
|
|
|
|
|
|
/* thank's to Jochen Erwied for this: */
|
|
|
|
|
#ifndef TEMP_FAILURE_RETRY
|
|
|
|
|
# define TEMP_FAILURE_RETRY(expression) \
|
|
|
|
|
(__extension__ \
|
|
|
|
|
({ long int __result; \
|
|
|
|
|
do __result = (long int) (expression); \
|
|
|
|
|
while (__result == -1L && errno == EINTR); \
|
|
|
|
|
__result; })) \
|
1999-09-13 09:09:42 +00:00
|
|
|
|
|
1999-09-19 14:16:26 +00:00
|
|
|
|
#endif
|
1999-09-09 11:21:04 +00:00
|
|
|
|
|
|
|
|
|
static void setup_daemon()
|
|
|
|
|
{
|
|
|
|
|
int sock;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
struct sockaddr_un sa;
|
|
|
|
|
struct sockaddr_in client;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
fd_set active_fd_set, read_fd_set;
|
|
|
|
|
char sock_name[] = SOCKNAME;
|
|
|
|
|
size_t size;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
struct stat stat_buf;
|
1999-09-09 11:21:04 +00:00
|
|
|
|
int i;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (verbose)
|
|
|
|
|
fprintf(stderr, "Setup sockets\n");
|
|
|
|
|
signal(SIGTERM, catch_term);
|
|
|
|
|
signal(SIGINT, catch_sig);
|
|
|
|
|
signal(SIGHUP, catch_hup);
|
|
|
|
|
|
|
|
|
|
if (is_daemon == 2) { /* go background */
|
|
|
|
|
pid_t pid;
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "Going background\n");
|
|
|
|
|
verbose = 0;
|
|
|
|
|
pid = fork();
|
|
|
|
|
if (pid < 0)
|
|
|
|
|
err("Going bg failed");
|
|
|
|
|
else if (pid > 0)
|
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
|
}
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
err("Can't open socket");
|
1999-07-31 09:25:03 +00:00
|
|
|
|
sa.sun_family = AF_UNIX;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
strcpy(sa.sun_path, sock_name);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
size = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path) + 1;
|
|
|
|
|
|
|
|
|
|
if (bind(sock, (struct sockaddr *) &sa, size) < 0)
|
|
|
|
|
err("Can't bind sock");
|
|
|
|
|
|
1999-07-24 08:43:38 +00:00
|
|
|
|
stat(sock_name, &stat_buf);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
chmod(sock_name, stat_buf.st_mode | S_IWOTH | S_IWGRP);
|
|
|
|
|
/* should better have perm wwwrun.nogroup */
|
|
|
|
|
|
1999-07-24 08:43:38 +00:00
|
|
|
|
if (listen(sock, SOMAXCONN) < 0)
|
1999-09-09 11:21:04 +00:00
|
|
|
|
err("Can't listen");
|
|
|
|
|
atexit(del_sock);
|
1999-07-24 08:43:38 +00:00
|
|
|
|
FD_ZERO(&active_fd_set);
|
|
|
|
|
FD_SET(sock, &active_fd_set);
|
1999-09-09 11:21:04 +00:00
|
|
|
|
while (!stopped) {
|
|
|
|
|
if (reinit)
|
|
|
|
|
do_reinit();
|
|
|
|
|
read_fd_set = active_fd_set;
|
|
|
|
|
if (TEMP_FAILURE_RETRY(select(FD_SETSIZE, &read_fd_set, 0, 0, 0)) < 0)
|
|
|
|
|
err("select");
|
|
|
|
|
for (i = 0; i < FD_SETSIZE; i++)
|
|
|
|
|
if (FD_ISSET(i, &read_fd_set)) {
|
|
|
|
|
if (i == sock) { /* request on orig */
|
|
|
|
|
int new;
|
|
|
|
|
|
|
|
|
|
size = sizeof(client);
|
|
|
|
|
if ((new = accept(sock, (struct sockaddr *) &client, &size)) < 0)
|
|
|
|
|
err("accept");
|
|
|
|
|
if (verbose)
|
|
|
|
|
fprintf(stderr, "Accepted %d\n", new);
|
|
|
|
|
FD_SET(new, &active_fd_set);
|
|
|
|
|
}
|
|
|
|
|
else { /* already connected */
|
|
|
|
|
pid_t pid;
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
if (verbose)
|
|
|
|
|
fprintf(stderr, "Handle client %d\n", i);
|
|
|
|
|
pid = fork();
|
|
|
|
|
if (pid == 0) {
|
|
|
|
|
handle_client(i);
|
|
|
|
|
_exit(EXIT_SUCCESS);
|
|
|
|
|
}
|
|
|
|
|
else if (pid < 0)
|
|
|
|
|
err("fork");
|
|
|
|
|
else {
|
|
|
|
|
if (waitpid(pid, &status, 0) != pid)
|
|
|
|
|
err("waitpid");
|
|
|
|
|
close(i);
|
|
|
|
|
FD_CLR(i, &active_fd_set);
|
|
|
|
|
}
|
|
|
|
|
} /* if i */
|
|
|
|
|
} /* if ISSET */
|
|
|
|
|
} /* while */
|
|
|
|
|
del_sock();
|
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int connect_2_daemon(int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
int sock;
|
|
|
|
|
struct sockaddr_un sa;
|
|
|
|
|
char sock_name[] = SOCKNAME;
|
|
|
|
|
size_t size;
|
|
|
|
|
int i, c, len;
|
|
|
|
|
char *p, *q, buffer[BUFSIZ];
|
|
|
|
|
|
|
|
|
|
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
|
|
|
|
|
err("Can't open socket");
|
|
|
|
|
sa.sun_family = AF_UNIX;
|
|
|
|
|
strcpy(sa.sun_path, sock_name);
|
|
|
|
|
size = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path) + 1;
|
|
|
|
|
|
|
|
|
|
if (connect(sock, (struct sockaddr *) &sa, size) < 0)
|
|
|
|
|
err("Can't connect sock");
|
|
|
|
|
p = buffer;
|
|
|
|
|
optind = 0; /* reinit */
|
|
|
|
|
len = 0;
|
|
|
|
|
while ((c = getopt(argc, argv, options)) != EOF && len < BUFSIZ - 10) {
|
|
|
|
|
switch (c) {
|
|
|
|
|
case '?':
|
|
|
|
|
case 'C':
|
|
|
|
|
break;
|
|
|
|
|
case 'D':
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if (optarg && atoi(optarg) == 3) ; /* goon, kill a running
|
1999-09-09 11:21:04 +00:00
|
|
|
|
|
|
|
|
|
daemon */
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
*p++ = '-';
|
|
|
|
|
*p++ = c;
|
|
|
|
|
len += 3;
|
|
|
|
|
if (optarg)
|
|
|
|
|
for (q = optarg; *q && len < BUFSIZ - 10; len++)
|
|
|
|
|
*p++ = *q++;
|
|
|
|
|
*p++ = ' ';
|
|
|
|
|
break;
|
|
|
|
|
}
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
1999-09-09 11:21:04 +00:00
|
|
|
|
for (i = optind; i < argc; i++) {
|
|
|
|
|
for (q = argv[i]; *q && len < BUFSIZ - 10; len++)
|
|
|
|
|
*p++ = *q++;
|
|
|
|
|
*p++ = ' ';
|
|
|
|
|
len++;
|
|
|
|
|
}
|
|
|
|
|
*--p = '\x0';
|
|
|
|
|
i = write(sock, buffer, strlen(buffer) + 1);
|
|
|
|
|
if (i < 0)
|
|
|
|
|
err("Write sock");
|
|
|
|
|
while ((i = read(sock, buffer, BUFSIZ)) > 0)
|
|
|
|
|
write(1, buffer, i);
|
|
|
|
|
close(sock);
|
|
|
|
|
return EXIT_SUCCESS;
|
1999-07-24 08:43:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
int main(int argc, char *argv[], char *envp[])
|
1999-07-24 08:43:38 +00:00
|
|
|
|
{
|
|
|
|
|
register int i;
|
|
|
|
|
|
|
|
|
|
myname = argv[0];
|
|
|
|
|
myshortname = basename(myname);
|
|
|
|
|
|
|
|
|
|
time(&start);
|
|
|
|
|
splittime();
|
|
|
|
|
|
1999-09-19 14:16:26 +00:00
|
|
|
|
if ((i = opts(argc, argv)) || need_dest==0) {
|
1999-09-09 11:21:04 +00:00
|
|
|
|
if (is_client)
|
|
|
|
|
exit(connect_2_daemon(argc, argv));
|
|
|
|
|
else
|
|
|
|
|
init();
|
|
|
|
|
if (is_daemon) {
|
|
|
|
|
clean_up();
|
|
|
|
|
setup_daemon();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
doit(i, argc, argv);
|
1999-06-28 19:14:59 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
1999-07-24 08:43:38 +00:00
|
|
|
|
print_msg(PRT_A, usage, myshortname, myshortname, options);
|
|
|
|
|
print_msg(PRT_A, "\n");
|
|
|
|
|
print_msg(PRT_A, "\t-b best\tshow only the first <best> provider(s) (default %d)\n", MAXPROVIDER);
|
|
|
|
|
print_msg(PRT_A, "\t-d d[.m[.y]] | {W|N|E}\tstart date of call (default now)\n");
|
|
|
|
|
print_msg(PRT_A, "\t-f areacode\tyou are calling from <areacode>\n");
|
|
|
|
|
print_msg(PRT_A, "\t-h h[:m[:s]]\tstart time of call (default now)\n");
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_A, "\t-l duration\tduration of call in seconds (default %d seconds)\n", LCR_DURATION);
|
1999-09-19 14:16:26 +00:00
|
|
|
|
print_msg(PRT_A, "\t-p prov|B[,prov...]\t show only these providers\n");
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_A, "\t-t takt\t\tshow providers if chargeduration<=takt\n");
|
|
|
|
|
print_msg(PRT_A, "\t-v [level]\tverbose\n");
|
1999-09-19 14:16:26 +00:00
|
|
|
|
print_msg(PRT_A, "\t-x prov|B[,prov...]\t exclude these providers\n");
|
1999-07-24 08:43:38 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_A, "\tOutput and run options\n");
|
|
|
|
|
print_msg(PRT_A, "\t-C\trun as client, connecting to a running daemon\n");
|
|
|
|
|
print_msg(PRT_A, "\t-CD3\tkill a running daemon\n");
|
1999-07-24 08:43:38 +00:00
|
|
|
|
print_msg(PRT_A, "\t-D\trun as daemon\n");
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_A, "\t-D2\trun as daemon & go background\n");
|
1999-07-24 08:43:38 +00:00
|
|
|
|
print_msg(PRT_A, "\t-G which\tshow raw data\n");
|
|
|
|
|
print_msg(PRT_A, "\t-H\tshow a header\n");
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_A, "\t-L\tshow a detailed list\n");
|
1999-10-25 18:30:03 +00:00
|
|
|
|
print_msg(PRT_A, "\t-N\tparse the given telefon numbers\n");
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_A, "\t-S[v|n]\tsort by v=VBN, n=Name, default=Charge\n");
|
1999-07-24 08:43:38 +00:00
|
|
|
|
print_msg(PRT_A, "\t-T\tshow a table of day/night week/weekend\n");
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_A, "\t-U\tshow usage stats for table\n");
|
|
|
|
|
print_msg(PRT_A, "\t-V\tshow version info\n");
|
1999-07-24 08:43:38 +00:00
|
|
|
|
print_msg(PRT_A, "\t-X\texplain each rate\n");
|
|
|
|
|
print_msg(PRT_A, "\t-X2\texplain more\n");
|
1999-09-09 11:21:04 +00:00
|
|
|
|
print_msg(PRT_A, "\t-X comment\tprint <comment> from C:tag\n");
|
|
|
|
|
print_msg(PRT_A, "\n\te.g.\t%s -b5 -f30 -TH -t1 Zaire\n", myshortname);
|
|
|
|
|
} /* else */
|
1999-06-28 19:14:59 +00:00
|
|
|
|
|
1999-09-09 11:21:04 +00:00
|
|
|
|
return (0);
|
|
|
|
|
} /* isdnrate */
|