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
This commit is contained in:
Andreas Kool 1999-07-24 08:45:26 +00:00
parent 768c4f414a
commit f3c68a63bf
12 changed files with 1205 additions and 164 deletions

View File

@ -19,6 +19,12 @@
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
## $Log$
## Revision 1.94 1999/07/10 21:37:36 akool
## isdnlog-3.41
## rate-de.dat V:1.02-Germany [10-Jul-1999 23:32:27]
## country-de.dat V:1.02-Germany [10-Jul-1999 23:32:36]
## added all "zone-*" files in binary mode
##
## Revision 1.93 1999/07/03 10:23:55 akool
## fixed Makefile
##
@ -711,7 +717,7 @@ SERVICEFILE = /etc/services
# DON'T EDIT BELOW THIS LINE
######################################################################
VERSION = 3.41
VERSION = 3.42
MANPAGES = isdnlog/callerid.conf.5 isdnlog/isdn.conf.5 \
isdnlog/isdnformat.5 isdnlog/isdnlog.5 isdnlog/isdnlog.8 \

View File

@ -1,10 +1,10 @@
ISDNLOG - Version 3.32 - 13-Jun-99 14:46
ISDNLOG - Version 3.42 - 21-Jul-99 19:16
isdnlog ist ein Utility zur Auswertung des D-Kanals eines
ISDN-BRI Anschlusses.
isdnlog-3.32 wurde ausgiebig mit Linux-2.0.36 getestet.
isdnlog-3.42 wurde ausgiebig mit Linux-2.0.37 getestet.
Fuer alle, die es nun ueberhaupt nicht mehr abwarten koennen, hier das
@ -195,9 +195,7 @@ Ein Bitte noch:
Alle Anfragen zum isdnlog bitte nicht an meine Email-Adresse senden,
sondern an
i4l-isdnlog@franken.de
Bitte auch nicht mehr die alte Adresse isdnlog@Kool.f.EUnet.de verwenden.
akool@isdn4linux.de
So bekommen alle Entwickler die Anfragen direkt mit, und muessen nicht
von mir extra weitergeleitet werden. Dadurch wird die Anfrage mit
@ -2412,8 +2410,10 @@ angegeben werden.
die causes der an der Verbindung beteiligten Geraete angezeigt.
(other={yes|no})
-ux Unterdruecken der RR (Receiver ready) Frames.
Z.Zt. wird als value nur "1" erkannt.
-ux Unterdruecken von "unwichtigen" Frames.
Fuer "x" kann angegeben werden:
1 = keine RR (Receiver ready) Frames.
2 = keine EMP (Euracom Management Protokoll) Frames.
(ignoreRR="value")
-Ux Ignorieren der COLP/CLIP Frames.
@ -3074,7 +3074,7 @@ REPFMTWWW = "%X %D %17.17H %T %-17.17F %-20.20l SI: %S %9u %U %I %O %G %C"
Falls jemand andere/bessere Skripte/Loesungen hat, sollte er sie unbedingt an
i4l-isdnlog@franken.de
akool@isdn4linux.de
senden, damit diese in der naechsten Version vom isdnlog aufgenommen werden
koennen.
@ -4454,7 +4454,7 @@ sowie
Zeilen enthalten (resp. beim HiSax-Treiber nur noch die "HEX:" Zeilen),
der Rest wird von isdnlog nicht benoetigt!
Diese Fehlermeldung sollte bitte an "i4l-isdnlog@franken.de" geschickt
Diese Fehlermeldung sollte bitte an "akool@isdn4linux.de" geschickt
werden.
@ -4526,7 +4526,7 @@ entsprechenden Benutzers in der Datei /etc/isdn/isdnlog.users.
Wenn der isdnlog mit einem Segmentation-fault oder mit der Meldung
"Got signal 11" abbricht, dann sollten folgende Schritte durchgefuehrt
werden, um Debuginformationen zu erlangen, die an die
"i4l-isdnlog@franken.de" zu senden sind:
"akool@isdn4linux.de" zu senden sind:
Im isdnlog-Verzeichnis

View File

@ -1,4 +1,4 @@
V:1.02-Germany [12-Jul-1999 20:54:06]
V:1.02-Germany [21-Jul-1999 19:19:37]
N:Usbekistan
@ -394,7 +394,7 @@ A:New Zealand, New Zealand & Chatham Island
C:+64
N:Neuseeland Mobilfunk
C:+64 /*fixme*/
C:+6421
N:Philippinen
A:Phillipines,Phillippinen
@ -798,7 +798,7 @@ A:Luxembourg
C:+352
N:Luxemburg Mobilfunk
C:+352 /* fixme */
C:+352021
N:Azoren
C:+35196, +35195, +35192
@ -869,7 +869,7 @@ N:Spanien - Valencia
C:+346
N:Frankreich Mobilfunk
C:+336
C:+336, +33171
N:Paris
C:+331

View File

@ -19,6 +19,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log$
* Revision 1.77 1999/07/15 16:41:32 akool
* small enhancement's and fixes
*
* Revision 1.76 1999/07/11 15:30:55 akool
* Patch from Karsten (thanks a lot!)
*
@ -909,7 +912,7 @@ void buildnumber(char *num, int oc3, int oc3a, char *result, int version,
strcpy(n, num);
strcpy(result, "");
*intern = strlen(num) < interns0;
*intern = ((strlen(num) < interns0) || !isdigit(*num));
if (trim && !*intern) {
if (dir && (who == CALLING))
@ -951,14 +954,15 @@ void buildnumber(char *num, int oc3, int oc3a, char *result, int version,
if (!dir && (who == CALLED) && !memcmp(num, vbn, strlen(vbn))) { /* Provider */
register int l, c;
if (num[3] == '0') /* dreistellige Verbindungsnetzbetreiberkennzahl? */
l = 6;
l = strlen(vbn);
if (num[l] == '0') /* dreistellige Verbindungsnetzbetreiberkennzahl? */
l += 3;
else
l = 5;
l += 2;
c = num[l];
num[l] = 0;
*provider = atoi(num + 3);
*provider = atoi(num + strlen(vbn));
/* die dreistelligen Verbindungsnetzbetreiberkennzahlen werden
intern erst mal mit einem Offset von 100 verarbeitet
@ -968,7 +972,7 @@ void buildnumber(char *num, int oc3, int oc3a, char *result, int version,
vergeben werden ...
*/
if (l == 6)
if (l == 6) /* Fixme: German specific */
*provider += 100;
num[l] = c;
@ -1579,9 +1583,8 @@ static void decode(int chan, register char *p, int type, int version, int tei)
break;
#ifdef ISDN_DE /* Fixme: never defined! */
case 0x28 : /* DISPLAY ... z.b. Makelweg, AOC-E ... */
if (Q931dmp) {
{
auto char s[BUFSIZ];
register char *ps = s;
@ -1591,12 +1594,12 @@ static void decode(int chan, register char *p, int type, int version, int tei)
*ps = 0;
if (Q931dmp)
Q931dump(TYPE_STRING, -2, s, version);
}
else
p += (l * 3);
info(chan, PRT_SHOWNUMBERS, STATE_RING, s);
}
break;
#endif
case 0x2d : /* SUSPEND ACKNOWLEDGE (Parkweg) */
p += (l * 3);
@ -4432,7 +4435,7 @@ doppelt:break;
qmsg(TYPE_CAUSE, version, call[chan].cause));
} /* if */
if (OUTGOING) {
if (OUTGOING && call[chan].duration) {
processRate(chan);
if (call[chan].tarifknown) {
@ -4440,7 +4443,7 @@ doppelt:break;
processLCR(chan, h);
while (h)
while (h && *h)
info(chan, PRT_SHOWHANGUP, STATE_HANGUP, strsep(&h, "\n"));
} /* if */
} /* if */
@ -4691,6 +4694,7 @@ void processflow()
int morectrl(int card)
{
register char *p, *p1, *p2, *p3;
register int go;
static char s[MAXCARDS][BIGBUFSIZ * 2];
static char *ps[MAXCARDS] = { s[0], s[1] };
auto int n = 0;
@ -4754,9 +4758,15 @@ retry:
processctrl(atoi(p3), p3 + 3);
}
else {
if (ignoreRR && (strlen(p1) < 17))
;
else
go = 1;
if (((ignoreRR & 1) == 1) && (strlen(p1) < 17))
go = 0;
if (((ignoreRR & 2) == 2) && !memcmp(p1 + 14, "AA", 2))
go = 0;
if (go)
processctrl(card, p1);
} /* else */
@ -4950,7 +4960,7 @@ void processcint()
info(chan, PRT_SHOWCONNECT, STATE_CONNECT, sx);
processLCR(chan, h);
while (h)
while (h && *h)
info(chan, PRT_SHOWHANGUP, STATE_HANGUP, strsep(&h,"\n"));
huptime(chan, 0);

View File

@ -24,6 +24,9 @@
*
*
* $Log$
* Revision 1.72 1999/07/23 09:09:38 calle
* Bugfix: getProvider sometimes returns NULL and isdnrep crashed ...
*
* Revision 1.71 1999/07/18 08:40:17 akool
* fix from Michael
*
@ -1185,6 +1188,9 @@ static int print_bottom(double unit, char *start, char *stop)
strich(2);
print_sum_calls(&all_sum,0);
if (bill)
return(0);
if (all_com_sum.eh)
{
print_sum_calls(&all_com_sum,1);
@ -1304,8 +1310,10 @@ static int print_bottom(double unit, char *start, char *stop)
else
*sx = 0;
print_line3(NULL, "Provider", string,
getProvider(i) ? getProvider(i) : "",
if ((p = getProvider(i)) == NULL)
p = "UNKNOWN";
print_line3(NULL, "Provider", string, p,
usage_provider[i],
double2clock(duration_provider[i]),
print_currency(pay_provider[i], 0), sx);
@ -1859,7 +1867,7 @@ static int print_line(int status, one_call *cur_call, int computed, char *overla
static void numsplit(char *num)
{
register int l1, l3, zone;
register int l1, l3, l4, zone;
auto int l2;
register char *p;
auto char *s;
@ -1876,6 +1884,9 @@ static void numsplit(char *num)
print_msg(PRT_NORMAL, "%s, ", s);
if ((p = get_areacode(num, &l2, C_NO_WARN | C_NO_EXPAND | C_NO_ERROR)) && (l2 > 0)) {
l4 = l2 + 1 - l1;
if (l4 > 0)
Strncpy(area, num + l1, l2 + 1 - l1);
print_msg(PRT_NORMAL, "%s", p);
@ -1926,21 +1937,38 @@ static void numsplit(char *num)
static void bprint(one_call *call)
{
register char *p = call->num[CALLED];
auto char target[BUFSIZ];
if (call->duration) {
if (*p == '+') {
if (!memcmp(call->num[CALLED], mycountry, strlen(mycountry))) { /* eigenes Land */
p += strlen(mycountry);
sprintf(target, "0%s", p);
}
else
sprintf(target, "00%s", p + 1);
}
else
sprintf(target, "%s", p);
print_msg(PRT_NORMAL, "%s %s %-16s ",
get_time_value(0,NULL,GET_TIME),
get_time_value(0,NULL, GET_TIME),
double2clock(call->duration),
call->num[CALLED]);
target);
if (call->duration) {
print_msg(PRT_NORMAL, "%s %-15s",
print_currency(call->pay, 0),
getProvider(call->provider) ? getProvider(call->provider) : "");
print_currency(call->pay * 100.0 / 116.0, 0),
getProvider(call->provider));
numsplit(call->num[CALLED]);
print_msg(PRT_NORMAL, "\n");
}
else
print_msg(PRT_NORMAL, "%*s** %s\n", 30, "", qmsg(TYPE_CAUSE, VERSION_EDSS1, call->cause));
} /* if */
/*
int eh;
int cause;
@ -3141,7 +3169,7 @@ static char *print_currency(double money, int computed)
static char RetCode[256];
sprintf(RetCode,"%s %s%c", double2str(money,8,2,0),currency,computed?'*':' ');
sprintf(RetCode,"%s %s%c", double2str(money, 8, 4, 0), currency, computed ? '*' : ' ');
return RetCode;
}
@ -3154,6 +3182,9 @@ static int print_sum_calls(sum_calls *s, int computed)
int RetCode;
if (bill)
print_msg(PRT_NORMAL, "%*s%s\n", 36, "", print_currency(s->pay, 0));
else {
if ((tmp_call = (one_call*) calloc(1,sizeof(one_call))) == NULL)
{
print_msg(PRT_ERR, nomemory);
@ -3174,6 +3205,9 @@ static int print_sum_calls(sum_calls *s, int computed)
RetCode = print_line(F_BODY_BOTTOM1,tmp_call,computed,String);
free(tmp_call);
} /* else */
return RetCode;
}

View File

@ -11,7 +11,7 @@
# for collecting and preparing most of the call charges.
V:1.80-Austria [06-Jul-1999]
V:1.81-Austria [22-Jul-1999]
U:%.3f öS
@ -57,7 +57,7 @@ Z:4 Online-Tarif
T:1-5/08-18=1.116/120 Tageszeit
T:1-5/18-8=1.116/360 Sparzeit
T:E,H/*=1.116/360 Sparzeit
A:+437189, 19430, 19440
A:+437189, 19411, 19430, 19440
Z:5 Mobilfunk
T:1-5/08-18=1.116/12 Tageszeit
@ -283,7 +283,7 @@ Z:4 Online-Tarif
T:1-5/08-18=1.056/120 Tageszeit
T:1-5/18-8=1.056/360 Sparzeit
T:E,H/*=1.056/360 Sparzeit
A:+437189, 19430, 19440
A:+437189, 19411, 19430, 19440
Z:5 Mobilfunk
T:1-5/08-18=1.056/12 Tageszeit
@ -509,7 +509,7 @@ Z:4 Online-Tarif
T:1-5/08-18=0.996/120 Tageszeit
T:1-5/18-8=0.996/360 Sparzeit
T:E,H/*=0.996/360 Sparzeit
A:+437189, 19430, 19440
A:+437189, 19411, 19430, 19440
Z:5 Mobilfunk
T:1-5/08-18=0.996/12 Tageszeit
@ -735,7 +735,7 @@ Z:4 Online-Tarif
T:1-5/08-18=0.936/120 Tageszeit
T:1-5/18-8=0.936/360 Sparzeit
T:E,H/*=0.936/360 Sparzeit
A:+437189, 19430, 19440
A:+437189, 19411, 19430, 19440
Z:5 Mobilfunk
T:1-5/08-18=0.936/12 Tageszeit

View File

@ -1,4 +1,4 @@
V:1.02-Germany [18-Jul-1999 10:44:21]
V:1.02-Germany [23-Jul-1999 22:39:23]
# Währungsformat
U:%.3f DM
@ -748,6 +748,7 @@ T:W/06-18=0.18(60)/1 Tagestarif
T:W/18-21=0.12(60)/1 Abendtarif
T:E,H/06-21=0.12(60)/1 Tagestarif
T:*/21-06=0.08(60)/1 Nachttarif
A:+49
Z:10 C-Netz
A:+491618 # T-C-Tel Voice Mail
A:+491610,+491611,+491612,+491613,+491614,+491615,+491616,+491617,+491619 # C
@ -826,6 +827,7 @@ T:W/06-18=0.18(60)/1 Tagestarif
T:W/18-21=0.12(60)/1 Abendtarif
T:E,H/06-21=0.12(60)/1 Tagestarif
T:*/21-06=0.07(60)/1 Nachttarif
A:+49
Z:10 C-Netz
A:+491618 # T-C-Tel Voice Mail
A:+491610,+491611,+491612,+491613,+491614,+491615,+491616,+491617,+491619 # C
@ -904,6 +906,7 @@ T:W/06-18=0.18(60)/1 Tagestarif
T:W/18-21=0.12(60)/1 Abendtarif
T:E,H/06-21=0.12(60)/1 Tagestarif
T:*/21-06=0.06(60)/1 Nachttarif
A:+49
Z:10 C-Netz
A:+491618 # T-C-Tel Voice Mail
A:+491610,+491611,+491612,+491613,+491614,+491615,+491616,+491617,+491619 # C
@ -3987,6 +3990,7 @@ Z:4 Distanz
T:W/09-18=0.1044/15 Hauptzeit
T:W/18-09=0.1044/30 Nebenzeit
T:E,H/*=0.1044/30 Wochenende
A:+49
Z:5 isiFON-zu-isiFON
T:W/09-18=0.1044/300 Hauptzeit
T:W/18-09=0.1044/600 Nebenzeit
@ -4159,6 +4163,7 @@ Z:4 Distanz
T:W/09-18=0.1044/33 Hauptzeit
T:W/18-09=0.1044/69 Nebenzeit
T:E,H/*=0.1044/33 Wochenende
A:+49
Z:5 isiFON-zu-isiFON
T:W/09-18=0.1044/300 Hauptzeit
T:W/18-09=0.1044/600 Nebenzeit
@ -4328,6 +4333,7 @@ Z:4 Distanz
T:W/09-18=0.1044/33 Hauptzeit
T:W/18-09=0.1044/69 Nebenzeit
T:E,H/*=0.1044/69 Wochenende
A:+49
Z:10 Mobilfunk
A:+491618 # T-C-Tel Voice Mail
A:+491610,+491611,+491612,+491613,+491614,+491615,+491616,+491617,+491619 # C
@ -5656,6 +5662,7 @@ Z:4 CITYMS-100 plus
T:W/09-18=0.07/60 Hauptzeit
T:W/18-09=0.07/60 Nebenzeit
T:E,H/*=0.07/60 Nebenzeit
A:+49
Z:5 CITYMS-Jovel
T:W/09-18=0.056/60 Hauptzeit
T:*/18-21=0.056/106 Nebenzeit
@ -10123,6 +10130,7 @@ Z:4 Deutschland
T:W/08-18=0.22(60)/1 Hauptzeit
T:W/18-08=0.11(60)/1 Nebenzeit
T:E,H/*=0.11(60)/1 Nebenzeit
A:+49
Z:5 Unter Uns
T:*/*=0.02(60)/1
Z:10 Mobilfunk
@ -11100,6 +11108,7 @@ T:W/18-21=0.1044/60 Freizeit
T:E,H/05-21=0.1044/60 Freizeit
T:W/21-09=0.0522/60 Nacht
T:E,H/21-05=0.0522/60 Nacht
A:+49
Z:5 Surf-Tarif
T:W/09-18=0.0696/90 Tag
T:W/18-21=0.0696/150 Freizeit

588
isdnlog/tools/isdnrate Executable file
View File

@ -0,0 +1,588 @@
#!/usr/bin/perl
#
# Copyright 1999 by Leopold Toetsch <lt@toetsch.at>
#
# This program is free for private use. Private use means, you
# may install and run this program on your home/office computer(s).
# But you are not allowed to use this program on public webservers.
#
# For commercial usage on public webservers contact the author.
use CGI qw(:standard);
use strict;
use GD;
use IO::Handle;
my $use_sockets=1;
use Socket;
my $server='/tmp/isdnrate';
# configure adjusts these n/y :-(
my $MKTEMP= '/bin/mktemp';
my $ISDNRATE='/home/lt/src/testi4l/isdnlog/bin/isdnrate';
my $CODEF= '/home/lt/src/testi4l/isdnlog/tools/zone/de/code';
my $tempdir=$ENV{'DOCUMENT_ROOT'};
# end configurable
my $debug=0;
my $LEER='--kein--';
$tempdir = "$tempdir/tmp";
my $tempdir_url = '/tmp';
my $q=new CGI;
# some security things
$CGI::POST_MAX=400;
$CGI::DISABLE_UPLOADS=1;
# data
my @countries=($LEER, "Afghanistan","Ägypten","Alaska","Albanien","Algerien",
"Amerikanisch-Samoa","Amerikanische Jungferninseln","Andorra",
"Angola","Anguilla","Antarktis","Antigua und Barbuda","Äquatorial-Guinea",
"Argentinien","Armenien","Aruba","Ascension",
"Aserbaidschan","Äthiopien","Atlantischer Ozean (Ost)",
"Atlantischer Ozean (West)","Australien","Azoren",
"Bahamas","Bahrain","Bangladesch","Barbados","Belgien",
"Belize","Benin","Bermuda","Bhutan","Bilbao","Bolivien","Bosnien-Herzegowina",
"Botsuana Botswana","Brasilien","Britische Jungferninseln",
"Brunei","Bulgarien","Burkina Faso Obervolta","Burundi","Cape Verde",
"Chatham-Inseln","Chile","China","Cookinseln","Costa Rica",
"Deutschland","Diego Garcia","Dominica","Dominikanische Republik","Dschibuti",
"Dänemark","Ecuador","Edinburgh",
"El Salvador","Elfenbeinküste Cote de Ivoire",
"Eritrea","Estland","Falklandinseln","Fidschi","Finnland","Frankfurt",
"Frankreich","Französisch-Guayana","Französisch-Polynesien",
"Freephone Niederlande","Freephone Schweiz","Färöer-Inseln","Gabun",
"Gambia","Georgien","Gerona","Ghana","Gibraltar","Grenada","Griechenland",
"Großbritannien","Grönland","Guadeloupe","Guam",
"Guantanamo","Guantanamo Bay","Guatemala","Guinea","Guinea-Bissau","Guyana",
"Haiti","Hawaii","Honduras","Hongkong","Indien",
"Indischer Ozean","Indonesien","Inmarsat A","Inmarsat A Daten/Fax",
"Inmarsat Aero","Inmarsat B","Inmarsat B HSD","Inmarsat M","Inmarsat Mini-M",
"Irak","Iran","Iridium 008816","Iridium 008817","Irland",
"Island","Israel","Italien","Jamaika",
"Japan","Jemen (Arab. Republik)","Jordanien","Jugoslawien",
"Kaimaninseln","Kambodscha","Kamerun","Kanada","Kanarische Inseln","Kasachstan",
"Katar","Kenia","Kirgisien","Kirgistan","Kiribati","Kokosinseln","Kolumbien",
"Kongo","Korea Rep. (South)","Kroatien","Kuba",
"Kuwait","Laos","Lesotho","Lettland","Leuven","Libanon",
"Liberia","Libyen","Liechtenstein","Litauen","Luxemburg","Macao","Madagaskar",
"Madeira","Malawi","Malaysia","Malediven","Mali","Mallorca","Malta",
"Marianen (SaipanNord-)","Marokko","Marshallinseln","Martinique / Franz. Antillen",
"Mauretanien","Mauritius","Mayotte","Mazedonien","Mexiko","Midway-Inseln",
"Mikronesien","Moldavien Moldau (Republik)","Monaco","Mongolei","Montserrat",
"Mosambik","Myanmar Burma","Namibia","Nauru","Nepal","Neukaledonien",
"Neuseeland","Nicaragua","Niederl. Antillen","Niederlande",
"Niger","Nigeria","Niue-Inseln","Nordirland","Nordkorea","Norfolkinseln",
"Norwegen","Oman","Österreich","Pakistan","Palau /Belau","Panama",
"Papua-Neuguinea","Paraguay","Pazifischer Ozean",
"Peru","Philippinen","Pitcairn Inseln","Pitcairn Islands",
"Polen","Portugal","Puerto Rico","Reunion","Rotterdam","Ruanda","Rumänien",
"Russische Föderat. (westl.)","Russische Förderation (östl.)",
"Salomonen","Sambia","San Marino","Sao Tome und Principe","Saudi Arabien",
"Schweden","Schweiz","Senegal",
"Seyschellen","Sierra Leone","Simbabwe","Singapur","Slowakische Republik",
"Slowenien","Somalia","Spanien","Sri Lanka","St. Helena",
"St. Kitts und Nevis","St. Lucia","St. Pierre und Miquelon","St. Vincent und Grenadinen",
"Sudan","Suriname","Swasiland","Syrien","Südafrika","Südkorea",
"Tadschikistan","Taiwan","Tansania","Tarragona","Teneriffa",
"Thailand","Togo","Tokelan","Tokyo","Tonga","Trinidad und Tobago",
"Tristan da Cunha","Tschad","Tschechische Republik","Tunesien","Turkmenistan",
"Turks- und Caicosinseln","Tuvalu","Türkei","USA",
"Uganda","Ukraine","Ungarn","Uruguay","Usbekistan","Valencia","Vanuatu",
"Vatikan","Venezuela","Ver. Arabische Emirate",
"Vietnam","Wake Inseln","Wallis und Futuna","Weihnachtsinseln","Weissrussland",
"West-Samoa","Zaire","Zentralafrikanische Republik","Zypern");
my %towns = (0 => $LEER);
# main
&html_header;
&read_towns;
if ($debug==2) {
$q->print(hr, $q->dump());
$q->print(hr);
}
my ($weekly, $daily);
$weekly=param('graf') =~ /Wo/;
$daily=param('graf') =~ /Tag/;
&get_results if(param('tab') eq 'Tabelle');
&make_graf if(param('graf'));
&print_form;
&clean_up;
$q->print(end_html);
1;
# subs
sub html_header {
$q->print(header);
$q->print(start_html(-title=>'Telefon-Kosten', -bgcolor=>'#f0f0f0',
-script=> q(
tim = 0;
function start(but) {
if(document.form.Start.value=='Start') {
tim=setInterval("run()",1000);
document.form.len.value=0;
document.form.Start.value='Stop';
document.form.now.checked=false;
j=new Date();
document.form.day.value=j.getDate()+'.'+(j.getMonth()+1)+'.'+j.getYear();
document.form.hour.value=j.getHours()+':'+j.getMinutes()+':'+j.getSeconds();
}
else {
clearInterval(tim);
document.form.Start.value='Start';
}
}
function run() {
document.form.len.value++;
}
-->
</SCRIPT>
<STYLE>
<!--
.t {font-face:Sans Serif;font-size:10pt}
.sm {font-face:Sans Serif;font-size:9pt}
-->
</STYLE>
<SCRIPT>
<!--
) ),
h1({-align=>'center'},'Telefon-Kosten'));
}
sub read_towns {
my($c, $t);
open(IN, $CODEF) || $q->print("Can't read $CODEF");
while (<IN>) {
chomp;
($c, $t) = split(/\t/,$_,2);
$towns{$c}=$t;
}
close(IN);
}
sub print_form {
my($t, @cod);
foreach $t (sort {$towns{$a} cmp $towns{$b} } (keys(%towns))) {
push(@cod, $t)
}
if (param()) {
$q->print(p, hr, h3('Neue Eingabe'));
}
else {
param('now','on');
param('best',20);
}
$q->print(
start_form(-name=>'form'),
table({-border=>8},
Tr(td(table({-bgcolor=>'#ffffe0', -cellspacing=>0, -cellpadding=>0},
Tr([
td([ b("Ich wähle von: "),
textfield(-name=>'from', -size=>20, -maxlength=>20),'&nbsp;','&nbsp;']),
td({-colspan=>4},hr),
td(["<b>nach</b> TelefonNummer: ",
textfield(-name=>'tel', -size=>20, -maxlength=>20),'&nbsp;','&nbsp;']),
td(["oder Stadt: ",
popup_menu(-name=>'town', -values=> \@cod, -labels=> \%towns),
"oder Ausland: ",
popup_menu(-name=>'country', -values=> \@countries)]),
td({-colspan=>4},hr),
td(["<b>Dauer</b> (sec)",
textfield(-name=>'len', -size=>4, -maxlength=>4, -value=>60),
"Stoppuhr",
button(-name=>'Start',-value=>'Start', -onClick=>'start()')]),
td([checkbox(-name=>'now', -label=>'Jetzt - oder am'),
popup_menu(-name=>'dday', -values=> ['W','N','E'],
-labels=> {'W' =>'Wochentag-10 h','N'=>'Nacht','E'=>'Sonntag'}),
'&nbsp;','&nbsp;']),
td(["oder um (hh[:mm[:ss]]) ",
textfield(-name=>'hour', -size=>8, -maxlength=>8),
"am (dd[.mm[.jj]]) ",
textfield(-name=>'day', -size=>10, -maxlength=>10)]),
td({-colspan=>4},hr),
td({-bgcolor=>'#ffc080'},[b(" Ausgabe "),
submit('tab','Tabelle'),
"mit",
popup_menu(-name=>'explain', -values=> [0,1,2],
-labels=> {0 =>'Nur Kosten',1=>'Zonen',2=>'Details'})]),
td({-bgcolor=>'#00bfff'},["oder",
submit('graf',' Grafik '),
"Größe",
popup_menu(-name=>'swidth', -values=> ['1024','800','640'],
-labels=> {'1024' =>'groß','800'=>'mittel','640'=>'klein'})]),
td({-bgcolor=>'#ffdead'},[
"oder Tagespreise",
submit('graf',' Tag '),
"oder Wochenpreise",
submit('graf','Woche ')
]),
td({-colspan=>4},hr),
td([" der besten ",
textfield(-name=>'best', -size=>2, -maxlength=>2),
"Provider",'&nbsp;']),
td(['oder nur Provider',
textfield(-name=>'prov', -size=>20, -maxlength=>100),
'oder nicht Provider',
textfield(-name=>'xprov', -size=>20, -maxlength=>100)]),
td(['&nbsp;','&nbsp;',
reset('Reset'),
defaults('Löschen')])
]))))),
end_form,
p,
hr,
div({-class=>'sm'},
'Die Tarife der Provider ändern sich häufig und können daher ',
'eventuell ungenau sein. Wenn ein Tarif falsch sein sollte, wenden ',
'Sie sich bitte',
ul(li('in Österreich an ',
a({-href=>'mailto:reinelt@eunet.at?subject=Tarife'},
'Michael Reinelt')),
li('in Deutschland an ',
a({-href=>'mailto:rate-de@Joker.E.Ruhr.de?subject=Tarife'},
'die deutsche ISDN-Rate Crew'))),
' oder an den Autor dieses Pogrammes ',
a({-href=>'mailto:lt@toetsch.at?subject=Tarife'},'Leopold Tötsch.') ),
);
}
sub call_isdnrate {
my ($hour, $day);
my ($len, $lines) = @_;
my ($now, $explain, $tel, $from, $best, $prov);
if (param('town') != '0') {
param('country', $LEER);
$tel = '0'.param('town');
param('tel',$tel);
}
elsif (param('country') !~ /--/) {
param('tel','');
param('town', $LEER);
$tel=param('country');
$tel =~s/ /_/g; # preserv spaces
}
else {
$tel = param('tel') =~ /\d+/ ? $& : '';
}
return if($tel eq '');
my @args=($ISDNRATE,"-H", $tel);
unless (param('now')) {
push(@args, "-h$hour") if ($hour=param('hour'));
push(@args, "-d$day") if ($day=param('day')||param('hour')?param('day'):param('dday'));
}
if ($prov=param('xprov')) {
$prov =~ s/\s//g;
push(@args, "-x$prov");
}
elsif ($prov=param('prov')) {
$prov =~ s/\s//g;
push(@args, "-p$prov");
}
push(@args, "-f$from") if ($from=param('from'));
if (param('graf')) {
push(@args,$weekly? '-G98':$daily?'-G97':'-G99');
}
else {
push(@args, "-X$explain") if ($explain=param('explain'));
}
push(@args, "-l$len");
$best=param('best');
param('best', $best>0 ? $best: 20);
push(@args, "-b$best") ;
print "<pre>@args</pre>" if($debug==2);
if ($use_sockets) {
socket(SOCK, PF_UNIX, SOCK_STREAM, 0) || die("socket: $!");
connect(SOCK, sockaddr_un($server)) || die("connect: $!");
shift(@args);
foreach (@args) {
print SOCK "$_ ";
}
SOCK->autoflush(1);
my $line;
while (defined($line = <SOCK>)) {
push(@$lines, $line);
}
close(SOCK);
}
else {
open(PIPE, "-|") || exec(@args) == 0 or die "Can't @args: $?";
@$lines = <PIPE>;
close(PIPE);
}
}
sub get_results {
my (@lines, $len);
my($pnum, $prov, $cur, $charge, $bgcolor, $i, $rest);
$len=sprintf("%d",param('len')) || 60;
&call_isdnrate($len, \@lines);
param('len',$len);
$lines[0] = &fmt_date($lines[0]);
$q->print(hr, $lines[0], p);
shift(@lines); # -H
shift(@lines); # empty
(undef, $cur) = split(/ +/, $lines[0]);
$q->print("<table><tr><th>Nr.</th><th>Provider</th><th>$cur</th>");
$q->print("<th>Info</th>") if(param('explain'));
$q->print("</tr>\n");
$i=0;
foreach (@lines) {
($pnum, $prov, $cur, $charge, $rest) = &split_line($_);
$bgcolor=++$i&1?' bgcolor="#e0e0e0"':'';
$q->print(qq(<tr$bgcolor><td>$pnum</td><td>$prov</td><td align="right">$charge</td>));
$q->print(qq(<td><font size="-1">$rest</font></td>)) if(param('explain'));
$q->print("</tr>\n");
}
$q->print("</table>\n");
}
sub split_line {
my $l = $_[0];
my ($pnum,$prov, $cur, $charge, $rest);
($prov, $cur, $charge) = split(/ +/, $l);
($pnum,$prov) = split(/:/, $prov);
if(param('explain')) {
($charge,$rest) = split(/ /, $charge, 2);
$rest =~ s/0+s/0s/g;
}
($pnum,$prov, $cur, $charge, $rest);
}
sub fmt_date {
my %days=(Mon=>'Mo',Tue=>'Di',Wed=>'Mi',Thu=>'Do',Fri=>'Fr',Sat=>'Sa',Sun=>'So');
my %mons=(Mar=>'Mär',May=>'Mai',Oct=>'Okt',Dez=>'Dez');
my ($db, $m, $d, $t, $y, $k);
if ($_[0] =~ m/(\d+) Sekunden/) {
$k = $&;
$d = $1;
if ($d >= 60) {
$m = int($d / 60);
$d = $d % 60;
my $mn = $m > 1 ? 'n' : '';
my $sn = $d > 1 ? 'n' : '';
my $st = $d ? " $d Sekunde$sn": '';
$_[0] =~ s/$k/$m Minute$mn$st/;
}
}
if ($_[0] =~ s/(\w{3}) (\w{3}) (\d\d?) (\S{8}) (\d{4})//) {
($db, $m, $d, $t, $y) = ($1,$2,$3,$4,$5);
$db=$days{$db};
$m=$mons{$m} ? $mons{$m} : $m;
$_[0] .= "$db $d. $m $y um $t";
}
$_[0];
}
sub min {
$_[0] < $_[1] ? $_[0] : $_[1];
}
sub max {
$_[0] > $_[1] ? $_[0] : $_[1];
}
sub make_graf {
my ($W, $H, $LEG, $LIN, $white, $black, $lgrey, $llgrey, $tempf, $i);
my (@lines, $n, $xo, $yo, $dx, @rawcolors, @colors, %pstring, %unused);
my ($prov, $cur, $charge, $pnum, %pc, %pt, $r, $g, $bl, $len);
my ($swidth, %dim);
$swidth=param('swidth')||1024;
# dimensions
%dim = (1024=>[700,350,240], 800=>[500,250,200],640=>[300,200,200]);
$W=$dim{$swidth}[0];
$H=$dim{$swidth}[1];
$LEG=$dim{$swidth}[2];
$LIN=50;
$dx = 10;
$xo=25; $yo=20;
$len=min(param('len'), 600);
param('len', $len);
# make some colors
$n=0;
foreach $g ('00','33','66','99') {
foreach $r ('00','33','66','99') {
foreach $bl ('00','33','66','99') {
$i= ++$n*29 % (4*4*4);
push(@rawcolors, "$i-0x$r-0x$g-0x$bl");
}
}
}
@rawcolors=sort(@rawcolors);
# make img
my $im = new GD::Image($W+$LEG, $H);
$white = $im->colorAllocate(255,255,255);
$llgrey = $im->colorAllocate(0xf0,0xf0,0xf0);
$im->transparent($llgrey);
$lgrey = $im->colorAllocate(0xe0,0xe0,0xe0);
$black = $im->colorAllocate(0,0,0);
# draw axis region
my $poly = new GD::Polygon;
$poly->addPt(0,0);
$poly->addPt(0,$H-1);
$poly->addPt($W-1,$H-1);
$poly->addPt($W-1,$H-$yo);
$poly->addPt($xo,$H-$yo);
$poly->addPt($xo,0);
$im->filledPolygon($poly, $lgrey);
# get data
my ($c,$text);
&call_isdnrate($len, \@lines);
foreach (@lines) {
if (/^\@--+ (\S+) (\S.*)/) { # end
if ($pnum && $#{ $pc{$pnum} } == 0) { # any data
pop( @{ $pt{$pnum} } );
pop( @{ $pc{$pnum} } );
delete $pstring{$pnum};
$unused{$pnum}++;
next;
}
$pstring{$pnum} = $2;
$cur=$1;
$pnum = '';
}
elsif (/^\@ (\d+)/) { # start
$pnum=$1;
push( @{ $pt{$pnum} }, 0); # time
push( @{ $pc{$pnum} }, 0); # charge
}
elsif (/(\d+) (\d+\.\d+)/ && $pnum) {
push( @{ $pt{$pnum} }, $1==1?0.1:$1); # time
push( @{ $pc{$pnum} }, $2); # charge
}
elsif (/ekunden/) { # -H text
$text = $_;
}
}
# info
$text = &fmt_date($text);
$q->print(p({-class=>'t'},$text));
# alloc colors
my(%rcols);
$c = 0;
my ($p, $max, $dy, $my);
$max=$n=0;
foreach $p (sort { $pc{$a}[$#{$pc{$a}}] <=> $pc{$b}[$#{$pc{$b}}] } (keys(%pstring))) {
(undef, $r, $g, $b) = split(/-/, $rawcolors[$n]);
$rcols{$p} = $im->colorAllocate(eval($r), eval($g), eval($b));
# calc max
foreach $i (0 .. $#{ $pc{$p} }) {
$max = $pc{$p}[$i] if ($pc{$p}[$i] > $max);
}
last if (++$n >= param('best'));
}
return unless($n);
my ($xs, $ys, $font, $tx);
$font = GD::gdMediumBoldFont;
# y-axis
$my = $max>100?int(($max+99.9)/100)*100: $max>10?int(($max+9.9)/10)*10 :
$max>1 ? int($max+0.99) : int(($max+0.099)*10)/10;
$ys = ($H-$yo)/$my;
$dy=$my>=100?100:$my>=10?10:$my>=1?1:0.1;
for ($i = $dy; $i <= $my; $i+=$dy) {
$im->line($xo/2, $H-$yo-$i*$ys,$xo,$H-$yo-$i*$ys,$black); # tick
$im->dashedLine($xo+1, $H-$yo-$i*$ys,$W-1,$H-$yo-$i*$ys,$lgrey) if($i<$my);
$im->string($font, 4, $H-$yo-$i*$ys+2, $i, $black); # price
}
$im->string($font, 4, $H-$yo-$my*$ys+3+$font->height, $cur, $black);
# x-axis
if ($weekly) {
$len=7*24;
$dx=1;
}
elsif ($daily) {
$len=24;
$dx=1;
}
else {
$dx = $len>240 ? 60 : $len>=120 ? 20 : 10;
}
$xs = ($W-$xo)/($len-1);
my @days= qw(Mo Di Mi Do Fr Sa So);
for ($i = 0; $i < $len; $i+=$dx) {
if (($weekly && $i%4==0) || !$weekly) {
$im->dashedLine($xo+$i*$xs-1, $H-$yo-1, $xo+$i*$xs-1, 1, $lgrey);
$im->line($xo+$i*$xs-1, $H-$yo/2, $xo+$i*$xs-1, $H-$yo, $black); # tick
}
if ($weekly) {
$tx='';
if ($i % 4==0) {
$tx = $i % 24 == 0 ? $days[$i/24] : $i % 24;
}
}
elsif ($daily) {
$tx = $i;
}
else {
$tx = $i == int($len/$dx)-2 ? $i ." s" : $i; # nn s
}
$im->string($font, $xo+$i*$xs+3, $H-$yo+2, $tx, $black);
}
# data
my ($ii,$k);
foreach $p (sort { $pc{$a}[$#{$pc{$a}}] <=> $pc{$b}[$#{$pc{$b}}] } (keys(%rcols))) {
foreach $i (0 .. $#{ $pc{$p} }-1) {
$ii=$i+1;
for $k (0..1) {
if ($pt{$p}[$i]+1 == $pt{$p}[$ii] && !$daily && !$weekly) {
$im->line($k+$xo+$pt{$p}[$i]*$xs, $k+$H-$yo-$pc{$p}[$i]*$ys,
$k+$xo+$pt{$p}[$ii]*$xs, $k+$H-$yo-$pc{$p}[$ii]*$ys,$rcols{$p});
}
else {
$im->line($k+$xo+$pt{$p}[$i]*$xs, $k+$H-$yo-$pc{$p}[$i]*$ys,
$k+$xo+$pt{$p}[$ii]*$xs, $k+$H-$yo-$pc{$p}[$i]*$ys,$rcols{$p});
$im->line($k+$xo+$pt{$p}[$ii]*$xs, $k+$H-$yo-$pc{$p}[$i]*$ys,
$k+$xo+$pt{$p}[$ii]*$xs, $k+$H-$yo-$pc{$p}[$ii]*$ys,$rcols{$p});
}
}
}
}
# borders
$im->rectangle(0,0,$W-1,$H-1,$black); # 0.0 is left upper
$im->rectangle($xo,0,$W-1,$H-$yo,$black);
# legend
$im->filledRectangle($W+1,0,$W+$LEG-1,$H-1,$llgrey);
my ($ndy, $y, $sy);
$y=2;
$i=min($n,keys(%rcols));
$n=0;
foreach $p (sort { $pc{$a}[$#{$pc{$a}}] <=> $pc{$b}[$#{$pc{$b}}] } (keys(%rcols))) {
$ndy = $H-$yo-($font->height + 1)*$i;
$sy = $pc{$p}[$#{$pc{$p}}]*$ys;
$y = max($y,min($ndy,$sy));
$im->dashedLine($W+2,$H-$yo-$sy, $W+$LIN,$H-$yo-$y, $rcols{$p});
$im->dashedLine(1+$W+2,1+$H-$yo-$sy,1+$W+$LIN,1+$H-$yo-$y, $rcols{$p});
$im->string($font, $W+$LIN+5, $H-$yo-$y-$font->height/2, "$p ".$pstring{$p}, $rcols{$p});
$y += $font->height+1;
$i--;
# last if (++$n >= param('best'));
}
# write file
$tempf = `$MKTEMP -q "$tempdir/irXXXXXX"`;
chomp($tempf);
rename($tempf, "$tempf.gif") || $q->print(p,"Can't rename $tempf");;
$tempf = "$tempf.gif";
open(TEMP,">$tempf") || $q->print(p,"Can't write $tempf");
print(TEMP $im->gif);
close(TEMP);
# ret img tag
$tempf =~ s!^$tempdir/!!;
$q->print(img({-src=>"$tempdir_url/$tempf", -height=>$H,
-width=>$W+$LEG, -align=>'"CENTER"'}));
}
# del gifs older then 1 hour
sub clean_up {
my(@All, $file, $now);
opendir(DIR, $tempdir);
@All = readdir(DIR);
closedir(DIR);
$now=time();
foreach $file (@All) {
if($now - (stat("$tempdir/$file"))[9] > 3600 && $file =~ /^ir.{6}\.gif/) {
unlink("$tempdir/$file");
}
}
}

50
isdnlog/tools/isdnrate-Readme Executable file
View File

@ -0,0 +1,50 @@
Isdnrate CGI
------------
Installation
------------
- Automatic
$ ./configure
# make install
- Manual
edit isdnrate:
location of code file
location of isdnrate
location if mktemp
if your /tmp ist not writable by all users, turn of $use_sockets
or change the location of the unix socket in both isdnrate's.
make a tmp dir below htdocs
# mkdir /usr/local/httpd/htdocs/tmp
# chmod 700 /usr/local/httpd/htdocs/tmp
# chown wwwrun.nogrup tmp
(or whatever uid.gid your webserver runs with)
# cp isdnrate /usr/local/httpd/cgi-bin
# chmod 755 /usr/local/httpd/cgi-bin/isdnrate
# chmod 644 /etc/isdn/isdn.conf
edit isdnrate.c
first line defines LEO (AT) else DE is assumed
NB: isdnrate uses the following pel modules:
CGI, GD, IO::Handle
if you don't have these, point your browser to www.perl.org,
and look for CPAN mirrors near your location.
Running the Program
-------------------
if $use_sockets is on, start the server instance of isdnlog/bin/isdnrate with
options -D [-v]
as soon as you see "Setup sockets" you can point your browser to
/cgi-bin/isdnrate and fill the form with the desired destination.
Click on table or grafik
Enjoy

View File

@ -1,3 +1,4 @@
#undef LEOx
/* $Id$
*
* ISDN accounting for isdn4linux. (rate evaluation)
@ -19,6 +20,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log$
* Revision 1.11 1999/07/15 16:42:04 akool
* small enhancement's and fixes
*
* Revision 1.10 1999/07/07 19:44:07 akool
* patches from Michael and Leo
*
@ -56,23 +60,31 @@
#include "isdnlog.h"
#include "tools/zone.h"
#include <unistd.h>
#define WIDTH 19
#define MAXLAST 5
#define MAXLAST ((best>=20||best<=2)?5:best)
#define ZAUNPFAHL 1 /* FIXME: Michi: Offset */
static char *myname, *myshortname;
static char options[] = "Vvd:h:l:Hb:s:tx::u";
static char options[] = "b:d:f:h:l:p:vx:DG:HLTUVX::";
static char usage[] = "%s: usage: %s [ -%s ] Destination ...\n";
static int verbose = 0, header = 0, best = MAXPROVIDER, table = 0, explain = 0;
static int usestat = 0, provider = UNKNOWN;
static int duration = LCR_DURATION;
static time_t start;
static int day, month, year, hour, min;
static int day, month, year, hour, min, sec;
static char country[BUFSIZ], area[BUFSIZ], msn[BUFSIZ];
static char smyarea[BUFSIZ], sarea[BUFSIZ];
static char ignore[MAXPROVIDER];
static char * fromarea = 0;
static char wanted_day;
static int list = 0;
static int *providers=0; /* incl/ excl these */
static int n_providers=0;
static int exclude=0;
static int is_daemon=0;
typedef struct {
int prefix;
@ -87,37 +99,45 @@ typedef struct {
static SORT sort[MAXPROVIDER];
#define PRT_V 17 /* verbose */
#define PRT_A 18 /* always on stderr */
int print_msg(int Level, const char *fmt, ...)
{
auto va_list ap;
auto char String[BUFSIZ * 3];
if (Level == PRT_ERR || (Level == PRT_V && !verbose))
return(1);
va_start(ap, fmt);
(void)vsnprintf(String, BUFSIZ * 3, fmt, ap);
va_end(ap);
if (Level == PRT_ERR)
return(1);
fprintf(Level == PRT_ERR ? stderr : stdout, "%s", String);
fprintf(Level == PRT_NORMAL ? stdout : stderr, "%s", String);
return(0);
} /* print_msg */
#ifdef LEO
#undef DTAG
#define DTAG 1
static void pre_init()
{
preselect = DTAG; /* Telekomik */
vbn = strdup("10"); /* austria */
} /* pre_init */
#else
static void pre_init()
{
preselect = DTAG; /* Telekomik */
vbn = strdup("010"); /* Germany */
} /* pre_init */
#endif
static void init()
{
auto char *version, **message;
if (readconfig(myshortname) < 0)
exit(1);
@ -129,91 +149,167 @@ static void init()
initHoliday(holifile, message);
if (*version && verbose)
print_msg(PRT_NORMAL, "%s\n", version);
print_msg(PRT_V, "%s\n", version);
initCountry(countryfile, message);
if (*version && verbose)
print_msg(PRT_NORMAL, "%s\n", version);
print_msg(PRT_V, "%s\n", version);
initRate(rateconf, ratefile, zonefile, message);
if (*version && verbose)
print_msg(PRT_NORMAL, "%s\n", version);
print_msg(PRT_V, "%s\n", version);
} /* init */
/* calc a day/time W | E | H */
static void get_day(char d) {
struct tm *tm;
bitfield mask;
int what=0;
tm = localtime(&start); /* now */
switch(d) {
case 'W': /* we need a normal weekday, so we take today and inc. day
if today is holiday */
what = WORKDAY;
hour = 10;
break;
case 'N':
what = WORKDAY;
hour = 23;
break;
case 'E':
what = SUNDAY;
hour = 10;
break;
}
mask = 1 << what;
while (isDay(tm, mask, 0) != what) {
tm->tm_mday++;
}
min = sec = 0;
day = tm->tm_mday;
month = tm->tm_mon+1;
year = tm->tm_year+1900;
}
static void post_init()
{
auto char s[BUFSIZ];
if (fromarea) {
free(myarea);
myarea = fromarea;
}
if (wanted_day)
get_day(wanted_day);
*smyarea = 0;
sprintf(s, "%s%s", mycountry, myarea);
mynum = strdup(s);
} /* post_init */
static int opts(int argc, char *argv[])
{
register int c;
register char *p;
optind=0; /* make it repeatable */
while ((c = getopt(argc, argv, options)) != EOF) {
switch (c) {
case 'V' : print_version(myshortname);
exit(0);
case 'v' : verbose++;
break;
case 'l' : duration = strtol(optarg, NIL, 0); /* l wie lt */
break;
case 'H' : header++;
break;
case 'b' : best = strtol(optarg, NIL, 0);
break;
case 'd' : day = atoi(optarg);
if ((p = strchr(optarg, '/'))) {
month = atoi(p + 1);
/* case 'c': countr */
if ((p = strchr(p + 1, '/'))) {
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;
}
}
break;
case 'h': hour = atoi(optarg);
if ((p = strchr(p + 1, ':')))
min = atoi(p + 1);
} /* isdigit */
else {
wanted_day = *p;
}
break;
case 't' : table++;
case 'f': if (optarg) { /* from */
for (p=optarg; (isspace(*p) || *p == '0') && *p; p++);
;
fromarea = strdup(p);
}
break;
case 'h': hour = atoi(optarg);
if ((p = strchr(optarg + 1, ':'))) {
min = atoi(p + 1);
if ((p = strchr(p + 1, ':')))
sec = atoi(p + 1);
}
break;
case 'l' : duration = strtol(optarg, NIL, 0); /* l wie lt */
break;
case 'x' : explain++;
{
int x;
if (optarg && (x=atoi(optarg)))
explain=x;
case 'x': /* eXclude Poviders */
exclude = 1;
/* goon */
case 'p': /* Providers ... */
p = strtok(optarg, ",");
while (p) {
providers = realloc(providers, n_providers+1);
providers[n_providers] = atoi(p);
p = strtok(0, ",");
n_providers++;
}
break;
case 'v' : verbose++;
break;
/* Uppercase options are for output format */
case 'u' : usestat++;
case 'D' : is_daemon = 1;
break;
case '?' : print_msg(PRT_ERR, usage, myshortname, myshortname, options);
case 'G' : explain=atoi(optarg);
break;
case 'H' : header++;
break;
case 'L' : list++;
explain=9;
break;
case 'T' : table++;
break;
/* Fixme: check/warn illegal kombinations of options */
case 'U' : usestat++;
break;
case 'V' : print_version(myshortname);
exit(0);
case 'X' :
if (explain == 0) {
int x;
explain++;
if (optarg && (x=atoi(optarg)))
explain=x;
break;
}
/* follthrough */
case '?' : print_msg(PRT_A, usage, myshortname, myshortname, options);
break;
} /* switch */
} /* while */
if (argc > optind)
return(optind);
else
@ -282,8 +378,7 @@ static void buildtime()
{
auto struct tm tm;
tm.tm_sec = 0;
tm.tm_sec = sec;
tm.tm_min = min;
tm.tm_hour = hour;
tm.tm_mday = day;
@ -300,16 +395,14 @@ static void splittime()
auto struct tm *tm;
tm = localtime(&start);
sec = tm->tm_sec;
min = tm->tm_min;
hour = tm->tm_hour;
day = tm->tm_mday;
month = tm->tm_mon + 1;
year = tm->tm_year + 1900; /* ja, ja, ich weiá ;-) */
year = tm->tm_year + 1900;
} /* splittime */
static char *Provider(int prefix)
{
register char *p;
@ -337,33 +430,35 @@ static void numsplit(char *num)
{
register int l1, l3, zone;
auto int l2;
register char *p;
register char *p = 0;
auto char *s;
print_msg(PRT_NORMAL, "NUMSPLIT(%s)\n", num);
print_msg(PRT_V, "NUMSPLIT(%s)\n", num);
*country = *area = *msn = 0;
*sarea = 0;
if (verbose && (provider != UNKNOWN))
print_msg(PRT_NORMAL, " Provider %s\n", Provider(provider));
print_msg(PRT_V, " Provider %s\n", Provider(provider));
if ((l1 = getCountrycode(num, &s)) != UNKNOWN) {
Strncpy(country, num, l1 + 1);
if (verbose)
print_msg(PRT_NORMAL, " Country %s : %s\n", country, s);
print_msg(PRT_V, " Country %s : %s\n", country, s);
strcpy(sarea, s);
if ((p = get_areacode(num, &l2, C_NO_WARN | C_NO_EXPAND | C_NO_ERROR))) {
Strncpy(area, num + l1, l2 + 1 - l1);
if (verbose)
print_msg(PRT_NORMAL, " Area %s : %s\n", area, p);
print_msg(PRT_V, " Area %s : %s\n", area, p);
strcpy(msn, num + l2);
if (verbose && *msn)
print_msg(PRT_NORMAL, " Number %s\n", msn);
print_msg(PRT_V, " Number %s\n", msn);
} /* if */
p = country;
@ -373,31 +468,33 @@ static void numsplit(char *num)
l3 = getAreacode(atoi(p), num + l1, &s);
if (1 /* l3 != UNKNOWN */) {
print_msg(PRT_NORMAL, "getAreacode(%d, %s, %s)=%d\n", atoi(p), num + l1, s, l3);
if (l3 != UNKNOWN)
free(s);
if (1) {
print_msg(PRT_V, "getAreacode(%d, %s, %s)=%d\n", atoi(p), num + l1, s, l3);
zone = getZone(DTAG, myarea, num + l1);
print_msg(PRT_NORMAL, "getZone(%d,%s,%s)=%d\n", DTAG, myarea, num + l1, zone);
print_msg(PRT_V, "getZone(%d,%s,%s)=%d\n", DTAG, myarea, num + l1, zone);
switch (zone) {
case 1 : print_msg(PRT_NORMAL, "Ortszone\n"); break;
case 2 : print_msg(PRT_NORMAL, "Cityzone\n"); break;
case 3 : print_msg(PRT_NORMAL, "Regionalzone\n"); break;
case 4 : print_msg(PRT_NORMAL, "Fernzone\n"); break;
default : print_msg(PRT_NORMAL, "*** BUG ***\n"); break;
case 1 : print_msg(PRT_V, "Ortszone\n"); break;
case 2 : print_msg(PRT_V, "Cityzone\n"); break;
case 3 : print_msg(PRT_V, "Regionalzone\n"); break;
case 4 : print_msg(PRT_V, "Fernzone\n"); break;
default : print_msg(PRT_V, "*** BUG ***\n"); break;
} /* switch */
} /* if */
if (l3 != UNKNOWN) {
strcpy(sarea, s);
free(s);
}
}
else {
l3 = getAreacode(49, num, &s);
if (l3 != UNKNOWN) {
print_msg(PRT_NORMAL, "getAreacode(%d, %s, %s)=%d\n", atoi(p), num + l1, s, l3);
print_msg(PRT_V, "getAreacode(%d, %s, %s)=%d\n", atoi(p), num + l1, s, l3);
free(s);
zone = getZone(DTAG, mynum, num);
print_msg(PRT_NORMAL, "getZone=%d\n", zone);
print_msg(PRT_V, "getZone=%d\n", zone);
} /* if */
} /* else */
} /* numsplit */
@ -415,7 +512,7 @@ static int normalizeNumber(char *target)
if (getCountry(target, &Country) != UNKNOWN)
strcpy(num, Country->Code[0]);
else {
print_msg(PRT_NORMAL, "Unknown country \"%s\"\n", target);
print_msg(PRT_A, "Unknown country \"%s\"\n", target);
return(0);
} /* else */
}
@ -461,24 +558,53 @@ static int normalizeNumber(char *target)
return(1);
} /* normalizeNumber */
#define P_EMPTY(s) s ? s : ""
#define DEL ';'
static int compute()
{
register int i, n = 0;
register int low = 0, high = MAXPROVIDER - 1;
auto RATE Rate;
auto char s[BUFSIZ];
struct tm *tm;
if (provider != UNKNOWN) {
low = high = provider;
} /* if */
buildtime();
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);
if (explain == 98) {
while (tm->tm_wday) { /* find last monday */
start -= (60 * 60 * 24);
tm = localtime(&start);
} /* while */
start += (60 * 60 * 24);
}
}
for (i = low; i <= high; i++) {
int found, p;
if (ignore[i])
continue;
if (!getProvider(i))
continue;
found = 0;
if (n_providers) {
for (p=0; p < n_providers ; p++)
if (providers[p] == i) {
found = 1;
break;
}
if ((!found && !exclude) || (found && exclude))
continue;
}
clearRate(&Rate);
Rate.src[0] = mycountry;
Rate.src[1] = myarea;
@ -492,18 +618,63 @@ static int compute()
Rate.prefix = i;
buildtime();
Rate.start = start;
Rate.now = start + duration - ZAUNPFAHL;
if(verbose==2)
fprintf(stderr,"@ %s%0*d ", vbn, Rate.prefix>100?3:2,
Rate.prefix>100?Rate.prefix-100:Rate.prefix);
if (explain == 99) {
int j;
double oldCharge = -1.0;
printf("@ %s%0*d\n", vbn, Rate.prefix>100?3:2,
Rate.prefix>100?Rate.prefix-100:Rate.prefix);
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;
}
}
else
break;
Rate.now++;
}
printf("@----- %s %s\n", currency, Rate.Provider);
}
if (explain == 98||explain==97) { /* Minutenpreis fuer diese Woche/Tag */
int j;
printf("@ %s%0*d\n", vbn, Rate.prefix>100?3:2,
Rate.prefix>100?Rate.prefix-100:Rate.prefix);
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;
}
printf("@----- %s %s\n", currency, Rate.Provider);
}
else {
/* kludge to suppress "impossible" Rates */
if (!getRate(&Rate, NULL) && (Rate.Price != 99.99)) {
sort[n].prefix = Rate.prefix;
sort[n].rate = Rate.Charge;
if (explain == 2) {
if (explain == 9) { /* used by list */
double cpm = Rate.Duration > 0 ? 60 * Rate.Price / Rate.Duration : 99.99;
sprintf(s, "%s%0*d%c"
"%s%c%s%c%s%c%s%c"
"%s%c"
"%.3f%c%.4f%c%.2f%c%.3f",
vbn, Rate.prefix>100?3:2, Rate.prefix>100?Rate.prefix-100:Rate.prefix,DEL,
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.Price,DEL, Rate.Duration,DEL, cpm);
sort[n].explain = strdup(s);
}
else if (explain == 2) {
sprintf(s, " (%s)", printrate(&Rate));
sort[n].explain = strdup(s);
}
@ -516,13 +687,35 @@ static int compute()
n++;
} /* if */
} /* for */
} /* else 99 */
} /* for i */
if (explain <10)
qsort((void *)sort, n, sizeof(SORT), compare);
{ char *p;
char *a;
for (p=mycountry; !isdigit(*p); p++)
;
if (getAreacode(atoi(p), myarea, &a) != UNKNOWN) {
strcpy(smyarea, a);
free(a);
}}
return(n);
} /* compute */
#undef P_EMPTY
static void printList(char *target, int n) {
int i;
if (header)
print_msg(PRT_NORMAL, "Eine %d Sekunden lange Verbindung von %s %s (%s) nach %s %s %s (%s) kostet am %s\n",
duration, mycountry, myarea, smyarea, country, area, msn, sarea, ctime(&start));
if (n > best)
n = best;
for (i = 0; i < n; i++)
print_msg(PRT_NORMAL, "%s\n", sort[i].explain);
}
static void result(char *target, int n)
{
@ -534,12 +727,12 @@ static void result(char *target, int n)
*num = 0; /* FIXME */
if (header)
print_msg(PRT_NORMAL, "Eine %d Sekunden lange Verbindung von %s %s nach %s %s %s kostet am %s\n",
duration, mycountry, myarea, country, area, msn, ctime(&start));
print_msg(PRT_NORMAL, "Eine %d Sekunden lange Verbindung von %s %s (%s) nach %s %s %s (%s) kostet am %s\n",
duration, mycountry, myarea, smyarea, country, area, msn, sarea, ctime(&start));
if (n > best)
n = best;
if (explain < 10)
for (i = 0; i < n; i++)
print_msg(PRT_NORMAL, "%s %s %8.3f%s\n",
Provider(sort[i].prefix), currency, sort[i].rate, sort[i].explain);
@ -742,7 +935,7 @@ static void printTable()
} /* if */
if ((best < MAXPROVIDER) && (best < useds)) {
print_msg(PRT_NORMAL, "Retrying with only %d provider(s), eliminating %d provider(s)\n", best, useds - best);
print_msg(PRT_A, "Retrying with only %d provider(s), eliminating %d provider(s)\n", best, useds - best);
qsort((void *)wsort, useds, sizeof(SORT2), compare2);
@ -766,23 +959,23 @@ static void printTable()
} /* if */
} /* printTable */
static void clean_up() {
if (providers)
free(providers);
providers=0;
if (fromarea)
free(fromarea);
fromarea=0;
is_daemon=table=list=header=explain=0;
usestat = 0;
provider = UNKNOWN;
duration = LCR_DURATION;
wanted_day = '\0';
}
int main(int argc, char *argv[], char *envp[])
{
register int i, n;
myname = argv[0];
myshortname = basename(myname);
time(&start);
splittime();
if ((i = opts(argc, argv))) {
pre_init();
init();
static void doit(int i, int argc, char *argv[]) {
int n;
post_init();
memset(ignore, 0, sizeof(ignore));
while (i < argc) {
@ -791,27 +984,172 @@ int main(int argc, char *argv[], char *envp[])
printTable();
else {
n = compute();
if(list)
printList(argv[i], n);
else
result(argv[i], n);
purge(n);
} /* else */
} /* if */
i++;
} /* while */
clean_up();
}
static void err(char *s) {
fprintf(stderr, "%s - %s\n", s, strerror (errno));
exit(2);
}
static int handle_client(int fd) {
char buffer[BUFSIZ];
int argc, n, i;
char **argv;
char *p;
if ((n=read(fd, buffer, BUFSIZ)) < 0)
err("Read");
if (n) {
argv = calloc(sizeof(char*),20);
buffer[n] = '\0';
if(verbose==2)
fprintf(stderr, "got '%s' (bs=%d)\n", buffer, BUFSIZ);
argc = 0;
argv[argc++] = strdup(myname);
p = strtok(buffer, "\t\n ");
while (p) {
argv[argc++]=strdup(p);
p = strtok(0, "\t\n ");
if (argc >= 20)
break;
}
if ((i = opts(argc, argv))) {
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);
}
return n == 0 ? -1 : 0;
}
static void setup_daemon() {
int sock;
struct sockaddr_un sa;
struct sockaddr_in client;
fd_set active_fd_set, read_fd_set;
char sock_name[] = "/tmp/isdnrate";
size_t size;
struct stat stat_buf;
int i;
if(verbose)
fprintf(stderr,"Setup sockets\n");
if ((sock=socket(PF_FILE, SOCK_STREAM, 0)) < 0)
err("Can't open socket");
sa.sun_family = AF_FILE;
unlink(sock_name);
strcpy(sa.sun_path, sock_name);
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");
stat(sock_name, &stat_buf);
chmod(sock_name, stat_buf.st_mode | S_IWOTH | S_IWGRP); /* wwwrun nogroup */
/* if (listen(sock, 1) < 0) */
if (listen(sock, SOMAXCONN) < 0)
err("Can't listen");
FD_ZERO(&active_fd_set);
FD_SET(sock, &active_fd_set);
while (1) {
read_fd_set = active_fd_set;
if (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 {
print_msg(PRT_NORMAL, usage, myshortname, myshortname, options);
print_msg(PRT_NORMAL, "\n");
print_msg(PRT_NORMAL, "\t-V\t\tshow version infos\n");
print_msg(PRT_NORMAL, "\t-v\t\tverbose\n");
print_msg(PRT_NORMAL, "\t-l duration\t duration of call in seconds (default %d seconds)\n", LCR_DURATION);
print_msg(PRT_NORMAL, "\t-H\t\tshow a header\n");
print_msg(PRT_NORMAL, "\t-t\t\tshow a table\n");
print_msg(PRT_NORMAL, "\t-b best\tshow only the first <best> provider(s) (default %d)\n", MAXPROVIDER);
print_msg(PRT_NORMAL, "\t-d d/m/y\tstart date of call (default now)\n");
print_msg(PRT_NORMAL, "\t-h h:/m\tstart time of call (default now)\n");
print_msg(PRT_NORMAL, "\t-x\texplain each rate\n");
print_msg(PRT_NORMAL, "\t-x2\texplain more\n");
print_msg(PRT_NORMAL, "\t-u\tshow usage stats\n");
if(waitpid(pid, &status, 0) != pid)
err("waitpid");
close(i);
FD_CLR(i, &active_fd_set);
}
} /* if i */
} /* if ISSET */
} /* while */
}
int main(int argc, char *argv[], char *envp[])
{
register int i;
myname = argv[0];
myshortname = basename(myname);
time(&start);
splittime();
if ((i = opts(argc, argv)) || is_daemon) {
pre_init();
init();
if (is_daemon) {
clean_up();
setup_daemon();
}
else
doit(i, argc, argv);
}
else {
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");
print_msg(PRT_A, "\t-l duration\t duration of call in seconds (default %d seconds)\n", LCR_DURATION);
print_msg(PRT_A, "\t-p prov[,prov...]\t show only these providers\n");
print_msg(PRT_A, "\t-v\t\tverbose\n");
print_msg(PRT_A, "\t-x prov[,prov...]\t exclude these providers\n");
print_msg(PRT_A, "\n\tOutput options\n");
print_msg(PRT_A, "\t-D\trun as daemon\n");
print_msg(PRT_A, "\t-G which\tshow raw data\n");
print_msg(PRT_A, "\t-H\tshow a header\n");
print_msg(PRT_A, "\t-L\tshow a det. list\n");
print_msg(PRT_A, "\t-T\tshow a table of day/night week/weekend\n");
print_msg(PRT_A, "\t-U\tshow usage stats\n");
print_msg(PRT_A, "\t-V\tshow version infos\n");
print_msg(PRT_A, "\t-X\texplain each rate\n");
print_msg(PRT_A, "\t-X2\texplain more\n");
print_msg(PRT_A, "\n\te.g.\t%s -b5 -f31 -TH Zaire\n",myshortname);
} /* else */
return(0);

View File

@ -131,7 +131,7 @@ void rate_1001_old(void) {
{ "Regionalzone", "+43660" },
{ "Fernzone 1", "" },
{ "Fernzone 2", "Österreich" },
{ "Online-Tarif", "+437189,19430,19440" },
{ "Online-Tarif", "+437189,19411,19430,19440" },
{ "Mobilfunk", "+43663,+43664,+43676,+43699" },
{ "Ausland Zone 1", "Deutschland, Italien, Liechtenstein, Schweiz, Slowakei, Slowenien, Tschechien, Ungarn" },
{ "Ausland Zone 2", "Albanien, Andorra, Belarus, Belgien, Bosnien-Herzegowina, Bulgarien, Dänemark,Finnland, Frankreich, Großbritannien, Nordirland, Irland, Jugoslawien, Serbien, Montenegro, Kroatien, Luxemburg, Malta, Mazedonien, Monaco, Niederlande, Norwegen, Rumänien, San Marino, Schweden, Spanien, Ukraine, Vatikanstadt, Zypern" },
@ -244,12 +244,12 @@ void rate_1001(void) {
double Tarif[] = { 1.116, 1.056, 0.996, 0.936, 0.816 };
char *Zone[][2] = {{ "FreePhone", "112,122,133,141,142,144,+43800,+43800,+43801,+43802,+43803,+43804" },
char *Zone[][2] = {{ "FreePhone", "112,122,133,141,142,144,+43800,+43801,+43802,+43803,+43804" },
{ "Regionalzone", "111*,11820,15*,+437111,+437112,+437113,+437114,+43810" },
{ "Österreichzone", "Österreich" },
{ "Mobilfunk 1", "+43663,+43664,+43676" },
{ "Mobilfunk 2", "+43699" },
{ "Online", "+437189,19430,19440" },
{ "Online", "+437189,19411,19430,19440" },
{ "Ausland Zone 1", "Deutschland, Italien, Liechtenstein, Schweiz, Slowakei, Slowenien, Tschechien, Ungarn" },
{ "Ausland Zone 2", "Albanien, Andorra, Belarus, Belgien, Bosnien-Herzegowina, Bulgarien, Dänemark,Finnland, Frankreich, Großbritannien, Nordirland, Irland, Jugoslawien, Serbien, Montenegro, Kroatien, Luxemburg, Malta, Mazedonien, Monaco, Niederlande, Norwegen, Rumänien, San Marino, Schweden, Spanien, Ukraine, Vatikanstadt, Zypern" },
{ "Ausland Zone 3", "Algerien, Estland, Färöer-Inseln, Georgien, Gibraltar, Island, Israel, Lettland, Litauen, Marokko, Portugal, Russische Föderation, Tadschikistan, Turkmenistan, Usbekistan" },
@ -1030,7 +1030,7 @@ int main (int argc, char *argv[])
printf ("# Many thanks to Daniela Bruder <dbruder@sime.com>\n");
printf ("# for collecting and preparing most of the call charges.\n\n\n");
printf ("V:1.80-Austria [06-Jul-1999]\n\n");
printf ("V:1.81-Austria [22-Jul-1999]\n\n");
printf ("U:%%.3f öS\n");
#if 0

View File

@ -19,6 +19,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log$
* Revision 1.31 1999/06/22 19:41:25 akool
* zone-1.1 fixes
*
* Revision 1.30 1999/06/16 19:13:03 akool
* isdnlog Version 3.34
* fixed some memory faults
@ -1064,6 +1067,9 @@ go: if (!ndigit)
p = s + strlen(s);
break;
case 'S' : p = itoa(call[chan].si1, p, 10, 0);
break;
default : *p++ = c;
break;
} /* switch */