- isdnlog Version 3.04

- general cleanup
- new layout for "rate-xx.dat" and "holiday-xx.dat" files from
    Michael Reinelt <reinelt@eunet.at>
    unused by now - it's a work-in-progress !
- bugfix for Wolfgang Siefert <siefert@wiwi.uni-frankfurt.de>
    The Agfeo AS 40 (Software release 2.1b) uses AOC_AMOUNT, not AOC_UNITS
- bugfix for Ralf G. R. Bergs <rabe@RWTH-Aachen.DE> - 0800/xxx numbers
    are free of charge ;-)
- tarif.dat V 1.08 - new mobil-rates DTAG
This commit is contained in:
akool 1999-03-14 12:15:56 +00:00
parent 886d3f9313
commit 284eac7595
15 changed files with 2255 additions and 54 deletions

View File

@ -1,4 +1,4 @@
## $Id: Makefile.in,v 1.56 1999/03/11 09:21:58 paul Exp $
## $Id: Makefile.in,v 1.57 1999/03/14 12:15:56 akool Exp $
##
## ISDN accounting for isdn4linux.
##
@ -19,6 +19,18 @@
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
## $Log: Makefile.in,v $
## Revision 1.57 1999/03/14 12:15:56 akool
## - isdnlog Version 3.04
## - general cleanup
## - new layout for "rate-xx.dat" and "holiday-xx.dat" files from
## Michael Reinelt <reinelt@eunet.at>
## unused by now - it's a work-in-progress !
## - bugfix for Wolfgang Siefert <siefert@wiwi.uni-frankfurt.de>
## The Agfeo AS 40 (Software release 2.1b) uses AOC_AMOUNT, not AOC_UNITS
## - bugfix for Ralf G. R. Bergs <rabe@RWTH-Aachen.DE> - 0800/xxx numbers
## are free of charge ;-)
## - tarif.dat V 1.08 - new mobil-rates DTAG
##
## Revision 1.56 1999/03/11 09:21:58 paul
## fixed problems with yesterday's commit
##
@ -436,7 +448,7 @@ SERVICEFILE = /etc/services
# DON'T EDIT BELOW THIS LINE
######################################################################
VERSION = 3.03
VERSION = 3.04
MANPAGES = isdnlog/callerid.conf.5 isdnlog/isdn.conf.5 isdnlog/isdnformat.5 isdnlog/isdnlog.5 isdnlog/isdnlog.8 isdnlog/isdnlog.users.5 isdnrep/isdnrep.1 isdnconf/isdnconf.1

23
isdnlog/holiday-at.dat Normal file
View File

@ -0,0 +1,23 @@
W:1 Montag
W:2 Dienstag
W:3 Mittwoch
W:4 Donnerstag
W:5 Freitag
W:6 Samstag
W:7 Sonntag
D:1.1 Neujahr
D:6.1 Hl. Drei Könige
D:easter Ostersonntag
D:easter+1 Ostermontag
D:1.5 1. Mai
D:easter+39 Christi Himmelfahrt
D:easter+49 Pfingstsonntag
D:easter+50 Pfingstmontag
#D:easter+60 Fronleichnam
#D:15.8 Maria Himmelfahrt
D:26.10 Nationalfeiertag
D:1.11 Allerheiligen
D:8.12 Maria Empfängnis
D:25.12 Christtag
D:26.12 2. Weihnachtstag

21
isdnlog/holiday-ch.dat Normal file
View File

@ -0,0 +1,21 @@
W:1 Montag
W:2 Dienstag
W:3 Mittwoch
W:4 Donnerstag
W:5 Freitag
W:6 Samstag
W:7 Sonntag
D:1.1 Neujahr
D:easter Ostersonntag
D:easter+1 Ostermontag
D:1.5 Maifeiertag
D:easter+39 Christi Himmelfahrt
D:easter+49 Pfingstsonntag
D:easter+50 Pfingstmontag
#D:easter+60 Fronleichnam
D:1.8 Bundesfeiertag
#D:15.8 Maria Himmelfahrt
#D:1.11 Allerheiligen
D:25.12 1. Weihnachtsfeiertag
D:26.12 2. Weihnachtsfeiertag

23
isdnlog/holiday-de.dat Normal file
View File

@ -0,0 +1,23 @@
W:1 Montag
W:2 Dienstag
W:3 Mittwoch
W:4 Donnerstag
W:5 Freitag
W:6 Samstag
W:7 Sonntag
D:1.1 Neujahr
#D:6.1 Erscheinungsfest
D:1.5 Maifeiertag
D:easter-2 Karfreitag
D:easter Ostersonntag
D:easter+1 Ostermontag
D:easter+39 Christi Himmelfahrt
D:easter+49 Pfingstsonntag
D:easter+50 Pfingstmontag
#D:easter+60 Fronleichnam
#D:15.8 Maria Himmelfahrt
D:3.10 Tag der deutschen Einheit
#D:1.11 Allerheiligen
D:25.12 1. Weihnachtsfeiertag
D:26.12 2. Weihnachtsfeiertag

19
isdnlog/holiday-nl.dat Normal file
View File

@ -0,0 +1,19 @@
W:1 Mondag
W:2 Thuesdag
W:3 Wednesdag
W:4 Thursdag
W:5 Fridag
W:6 Saturdag
W:7 Sundag
D:1.1 nieuwjaarsdag
D:easter-2 Goede Vrijdag
D:easter Pasen
D:easter+1 tweede Paasdag
D:30.4 Koninginnedag
D:5.5 Bevrijdingsdag
D:easter+39 Hemelvaart
D:easter+49 Pinksteren
D:easter+50 tweede Pinksterdag
D:25.12 Kerstmis
D:26.12 tweede Kerstdag

View File

@ -1,4 +1,4 @@
/* $Id: processor.c,v 1.39 1999/03/07 18:18:55 akool Exp $
/* $Id: processor.c,v 1.40 1999/03/14 12:16:08 akool Exp $
*
* ISDN accounting for isdn4linux. (log-module)
*
@ -19,6 +19,18 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: processor.c,v $
* Revision 1.40 1999/03/14 12:16:08 akool
* - isdnlog Version 3.04
* - general cleanup
* - new layout for "rate-xx.dat" and "holiday-xx.dat" files from
* Michael Reinelt <reinelt@eunet.at>
* unused by now - it's a work-in-progress !
* - bugfix for Wolfgang Siefert <siefert@wiwi.uni-frankfurt.de>
* The Agfeo AS 40 (Software release 2.1b) uses AOC_AMOUNT, not AOC_UNITS
* - bugfix for Ralf G. R. Bergs <rabe@RWTH-Aachen.DE> - 0800/xxx numbers
* are free of charge ;-)
* - tarif.dat V 1.08 - new mobil-rates DTAG
*
* Revision 1.39 1999/03/07 18:18:55 akool
* - new 01805 tarif of DTAG
* - new March 1999 tarife
@ -1880,35 +1892,13 @@ static void decode(int chan, register char *p, int type, int version, int tei)
Q931dump(TYPE_STRING, c, s, version);
ps = s + sprintf(s, "Location: ");
switch (c & 0x0f) {
case 0x00 : sprintf(ps, "Nutzer"); break;
case 0x01 : sprintf(ps, "Privates Netz des Nutzers"); break;
case 0x02 : sprintf(ps, "Oeffentliches Netz des Nutzers"); break;
case 0x03 : sprintf(ps, "Transitnetz"); break;
case 0x04 : sprintf(ps, "Oeffentliches Netz beim fernen Nutzer"); break;
case 0x05 : sprintf(ps, "Privates Netz beim fernen Nutzer"); break;
case 0x07 : sprintf(ps, "Internationales Netz"); break;
case 0x0a : sprintf(ps, "Netzwerk jenseits des interworking point"); break;
default : sprintf(ps, "UNKNOWN #%d", c & 0x0f); break;
} /* switch */
ps = s + sprintf(s, "Location: %s", location(c & 0x0f));
Q931dump(TYPE_STRING, -1, s, version);
} /* if */
#endif
switch ((loc = (c & 0x0f))) {
case 0x00 : py = "User"; break;
case 0x01 : py = "Private network serving local user"; break;
case 0x02 : py = "Public network serving local user"; break;
case 0x03 : py = "Transit network"; break;
case 0x04 : py = "Public network serving remote user"; break;
case 0x05 : py = "Private network serving remote user"; break;
case 0x07 : py = "International network"; break;
case 0x0a : py = "Network beyond inter-working point"; break;
default : py = ""; break;
} /* switch */
py = location(loc = (c & 0x0f));
c = strtol(p + 6, NIL, 16);
cause = c & 0x7f;
@ -2057,11 +2047,17 @@ static void decode(int chan, register char *p, int type, int version, int tei)
aoc_debug(-2, s);
} /* if */
if (n < 0)
if (n < 0) {
if (call[chan].aoce == -1) /* Firsttime */
call[chan].aoce = 1;
else
call[chan].aoce++;
} /* if */
call[chan].pay = pay;
call[chan].aoce = n; /* AK:08-May-98 */
if (currency_mode == AOC_UNITS)
call[chan].aoce = n;
if (n < 0)
sprintf(s, "aOC-D=%d", -n);
@ -2399,7 +2395,13 @@ static void decode(int chan, register char *p, int type, int version, int tei)
else
strcpy(call[chan].onum[CALLED], s);
buildnumber(s, oc3, oc3a, call[chan].num[CALLED], version, &call[chan].provider, &call[chan].sondernummer[CALLED], &call[chan].intern[CALLED], 0, 0);
/* bei "national" numbers evtl. fuehrende "0" davor */
if (((oc3 & 0x70) == 0x20) && (*s != '0')) {
sprintf(s1, "0%s", s);
strcpy(s, s1);
} /* if */
buildnumber(s, oc3, oc3a, call[chan].num[CALLED], version, &call[chan].provider, &call[chan].sondernummer[CALLED], &call[chan].intern[CALLED], 0, CALLED);
if (!dual)
strcpy(call[chan].vnum[CALLED], vnum(chan, CALLED));
@ -2999,16 +3001,7 @@ escape: for (c = 0; c <= sxp; c++)
#ifdef Q931
if (!q931dmp)
#endif
px += sprintf(px, "PROGRESS: ");
switch (c) {
case 0x80 : px += sprintf(px, "Location: User"); break;
case 0x81 : px += sprintf(px, "Location: Local:private net"); break;
case 0x82 : px += sprintf(px, "Location: Local:public net"); break;
case 0x84 : px += sprintf(px, "Location: Remote:public net"); break;
case 0x85 : px += sprintf(px, "Location: Remote:private net"); break;
case 0x8a : px += sprintf(px, "Location: Interworking"); break;
} /* switch */
px += sprintf(px, "PROGRESS: %s", location(c & 0x80));
if (l > 1) {
px = sx[++sxp];
@ -4216,7 +4209,7 @@ static void processctrl(int card, char *s)
break;
case 0xaa : version = VERSION_UNKNOWN; /* Euracom Frames */
break;
return;
default : version = VERSION_UNKNOWN;
sprintf(sx, "Unexpected discriminator 0x%02x -- ignored!", i);
@ -4663,10 +4656,7 @@ doppelt:break;
((call[chan].pay == -1.0) ? "UNKNOWN" : double2str(call[chan].pay, 6, 2, DEB)),
double2clock((double)(call[chan].disconnect - call[chan].connect)), s2);
else
sprintf(sx, "HANGUP (%s%s) %s (%s)",
double2clock((double)(call[chan].disconnect - call[chan].connect)), s2,
qmsg(TYPE_CAUSE, version, call[chan].cause),
location(call[chan].loc));
sprintf(sx, "HANGUP (%s%s)", double2clock((double)(call[chan].disconnect - call[chan].connect)), s2);
} /* else */
if (!memcmp(sx, "HANGUP ( )", 17))
@ -4675,7 +4665,8 @@ doppelt:break;
if ((call[chan].cause != 0x10) && (call[chan].cause != 0x1f)) { /* "Normal call clearing", "Normal, unspecified" */
strcat(sx, " ");
strcat(sx, qmsg(TYPE_CAUSE, version, call[chan].cause));
if ((p = location(call[chan].loc))) {
if (((p = location(call[chan].loc) != ""))) {
strcat(sx, " (");
strcat(sx, location(call[chan].loc));
strcat(sx, ")");

7
isdnlog/rate-at.conf Normal file
View File

@ -0,0 +1,7 @@
# Tarifauswahl für PTA (Post & Telekom Austria)
# 1: Minimumtarif (ATS 1.116 je Impuls)
# 2: Standardtarif (ATS 1.056 je Impuls)
# 3: Geschäftstarif 1 (ATS 0.996 je Impuls)
# 4: Geschäftstarif 2 (ATS 0.936 je Impuls)
# 5: Geschäftstarif 3 (ATS 0.816 je Impuls)
P:00=2

1071
isdnlog/rate-at.dat Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
# @(#)tarif.dat 1.06 05-Mar-99 11:16
# @(#)tarif.dat 1.08 14-Mar-99 11:35
#
# Copyright 1995, 1999 by Andreas Kool (akool@isdn4linux.de)
#
V:1.07 [05-Mar-99]
V:1.08 [14-Mar-99]
#
# P: Provider
# G: tt.mm.jjjj Tarif g<>ltig ab
@ -168,6 +168,7 @@ C: pro Monat 2 Stunden Nutzungsentgelt frei
C: monatliche Grundgeb<65>hr DM 8,00
C:ISDN-Tarif
C:FIXME: Tarife überprüfen! 04-Mar-99
C:Quelle: http://www.telekom.de/untern/tarife/mobil/index.htm
I:0191011
Z:1,0.12
T:W02-05=240 # Nacht
@ -192,10 +193,14 @@ Z:5,60/60
T:W09-18=0.632 # Standard
T:W18-09=0.431 # Spar
T:E=0.431 # Spar
Z:7-9,60/60
T:W09-18=0.96 # Standard
T:W18-09=0.48 # Spar
T:E=0.60 # Spar
Z:8,60/60
T:W09-18=1.36 # Standard
T:W18-09=0.562 # Spar
T:E=0.562 # Spar
T:W09-18=1.44 # Standard
T:W18-09=0.60 # Spar
T:E=0.60 # Spar
################################################################
P:49=ACC
G:01.01.1999

304
isdnlog/tools/holiday.c Normal file
View File

@ -0,0 +1,304 @@
/* $Id: holiday.c,v 1.1 1999/03/14 12:16:23 akool Exp $
*
* Feiertagsberechnung
*
* Copyright 1999 by Michael Reinelt (reinelt@eunet.at)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: holiday.c,v $
* Revision 1.1 1999/03/14 12:16:23 akool
* - isdnlog Version 3.04
* - general cleanup
* - new layout for "rate-xx.dat" and "holiday-xx.dat" files from
* Michael Reinelt <reinelt@eunet.at>
* unused by now - it's a work-in-progress !
* - bugfix for Wolfgang Siefert <siefert@wiwi.uni-frankfurt.de>
* The Agfeo AS 40 (Software release 2.1b) uses AOC_AMOUNT, not AOC_UNITS
* - bugfix for Ralf G. R. Bergs <rabe@RWTH-Aachen.DE> - 0800/xxx numbers
* are free of charge ;-)
* - tarif.dat V 1.08 - new mobil-rates DTAG
*
*/
/*
* Schnittstelle:
*
* int initHoliday(char *path)
* initialisiert die Feiertagsberechnung, liest die Feiertagsdatei
* und gibt die Anzahl der Feiertage zurück, im Fehlerfall -1
*
* void exitHoliday()
* deinitialisiert die Feiertagsberechnung
*
* int isHoliday(struct tm *tm, char **name)
* 0 .. kein Feiertag
* 1 .. Feiertag, *name zeigt auf den Namen
*
* int getDay(struct tm *tm, char **name)
* 1 .. Montag
* 7 .. Sonntag
* 8 .. Feiertag
* *name zeigt auf den Namen
*/
#define _HOLIDAY_C_
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#include "holiday.h"
#define LENGTH 80 /* max length of lines in data file */
typedef unsigned int julian;
typedef struct {
int day;
int month;
char *name;
} HOLIDATE;
static int line = 0;
static char *Weekday[7] = { NULL, };
static int nHoliday = 0;
static HOLIDATE *Holiday = NULL;
static char *defaultWeekday[] = { "Monday",
"Thuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday" };
static void warning (char *fmt, ...)
{
va_list ap;
char msg[BUFSIZ];
va_start (ap, fmt);
vsnprintf (msg, BUFSIZ, fmt, ap);
va_end (ap);
#ifdef STANDALONE
fprintf(stderr, "WARNING: line %3d: %s\n", line, msg);
#else
print_msg(PRT_NORMAL, "WARNING: line %3d: %s\n", line, msg);
#endif
}
/* easter & julian calculations by Guenther Brunthaler (gbr001@yahoo.com) */
static julian date2julian(int y, int m, int d)
{
if (m<3) {m+=9; y--;} else m-=3;
return (146097*(y/100))/4+(1461*(y%100))/4+(153*m+2)/5+d;
}
static void julian2date(julian jd, int *yp, int *mp, int *dp)
{
julian j,c,y,m,d;
j=d*4-1;
c=(j/146097)*100;
d=(j%146097)/4;
y=(4*d+3)/1461;
d=(((4*d+3)%1461)+4)/4;
m=(5*d-3)/153;
d=(((5*d-3)%153)+5)/5;
if (m>9) {m-=9; y++;} else m+=3;
*yp=c+y;
*mp=m;
*dp=d;
}
static julian getEaster(int year)
{
int g, c, x, z, d, e, n, m;
g=year%19+1;
c=year/100+1;
x=3*c/4-12;
z=(8*c+5)/25-5;
d=5*year/4-x-10;
e=(11*g+20+z-x)%30;
if ((e==25 && g>11) || e==24) e++;
n=44-e;
if (n<21) n+=30;
n+=7-(d+n)%7;
if (n>31) {n-=31; m=4;} else m=3;
return date2julian(year,m,n);
}
static char *strip (char *s)
{
char *p;
while (*s==' ' || *s=='\t') s++;
for (p=s; *p; p++)
if (*p=='#' || *p=='\n') {
*p='\0';
break;
}
for (p--; p>s && (*p==' '||*p=='\t'); p--)
*p='\0';
return s;
}
void exitHoliday(void)
{
int i;
for (i=0; i<7; i++) {
if (Weekday[i]) {
free (Weekday[i]);
Weekday[i]=NULL;
}
}
for (i=0; i<nHoliday; i++) {
if (Holiday[i].name) free (Holiday[i].name);
}
if (Holiday) free (Holiday);
nHoliday=0;
Holiday=NULL;
}
int initHoliday(char *path)
{
FILE *stream;
char *s, *date, *name;
char buffer[LENGTH];
int i,m,d;
exitHoliday();
for (i=1; i<7; i++)
Weekday[i]=strdup(defaultWeekday[i]);
if (*path=='\0')
return 0;
if ((stream=fopen(path,"r"))==NULL)
return -1;
line=0;
while ((s=fgets(buffer,LENGTH,stream))!=NULL) {
line++;
if (*(s=strip(s))=='\0')
continue;
if (s[1]!=':') {
warning ("expected ':', got '%s'!", s+1);;
continue;
}
switch (*s) {
case 'W':
d=strtol(s+2,&s,10);
if (d<1 || d>7) {
warning("invalid weekday %d", d);
continue;
}
if (*(name=strip(s))=='\0') {
warning("empty weekday %d", d);
continue;
}
if (Weekday[d-1]) free(Weekday[d-1]);
Weekday[d-1]=strdup(name);
break;
case 'D':
name=s+2;
if ((date=strsep(&name," \t"))==NULL) {
warning("Syntax error");
continue;
}
if (strncmp(date,"easter",6)==0) {
m=-1;
d=atoi(date+6);
} else {
d=atof(strsep(&date,"."));
m=atof(strsep(&date,"."));
}
Holiday=(HOLIDATE*)realloc(Holiday,(nHoliday+1)*sizeof(HOLIDATE));
Holiday[nHoliday].day=d;
Holiday[nHoliday].month=m;
Holiday[nHoliday].name=strdup(strip(name));
nHoliday++;
break;
default:
warning("Unknown tag '%c'", *s);
}
}
fclose(stream);
return nHoliday;
}
int isHoliday(struct tm *tm, char **name)
{
int i;
julian easter, day;
day=date2julian(tm->tm_year,tm->tm_mon,tm->tm_mday);
easter=getEaster(tm->tm_year);
for (i=0; i<nHoliday; i++) {
if ((Holiday[i].month==-1 && Holiday[i].day==day-easter) ||
(Holiday[i].month==tm->tm_mon && Holiday[i].day==tm->tm_mday)) {
if(name)
*name=Holiday[i].name;
return 1;
}
}
return 0;
}
int getDay(struct tm *tm, char **name)
{
julian day;
if (isHoliday(tm, name))
return HOLIDAY;
day=(date2julian(tm->tm_year,tm->tm_mon,tm->tm_mday)-6)%7+1;
if (name)
*name=Weekday[day-1];
return day;
}
#ifdef STANDALONE
void main (int argc, char *argv[])
{
int i, d;
char *name;
struct tm tm;
printf ("%d Feiertage\n", initHoliday("../holiday-de.dat"));
for (i=1; i < argc; i++) {
tm.tm_mday=atoi(strsep(argv+i,"."));
tm.tm_mon=atoi(strsep(argv+i,"."));
tm.tm_year=atoi(strsep(argv+i,"."));
d=getDay(&tm,&name);
printf ("%d.%d.%d\t%d=%s\n", tm.tm_mday,tm.tm_mon, tm.tm_year,d,name);
}
}
#endif

53
isdnlog/tools/holiday.h Normal file
View File

@ -0,0 +1,53 @@
/* $Id: holiday.h,v 1.1 1999/03/14 12:16:41 akool Exp $
*
* Feiertagsberechnung
*
* Copyright 1999 by Michael Reinelt (reinelt@eunet.at)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: holiday.h,v $
* Revision 1.1 1999/03/14 12:16:41 akool
* - isdnlog Version 3.04
* - general cleanup
* - new layout for "rate-xx.dat" and "holiday-xx.dat" files from
* Michael Reinelt <reinelt@eunet.at>
* unused by now - it's a work-in-progress !
* - bugfix for Wolfgang Siefert <siefert@wiwi.uni-frankfurt.de>
* The Agfeo AS 40 (Software release 2.1b) uses AOC_AMOUNT, not AOC_UNITS
* - bugfix for Ralf G. R. Bergs <rabe@RWTH-Aachen.DE> - 0800/xxx numbers
* are free of charge ;-)
* - tarif.dat V 1.08 - new mobil-rates DTAG
*
*/
#ifndef _HOLIDAY_H_
#define _HOLIDAY_H_
#define MONDAY 1
#define THUESDAY 2
#define WEDNESDAY 3
#define THURSDAY 4
#define FRIDAY 5
#define SATURDAY 6
#define SUNDAY 7
#define HOLIDAY 8
int initHoliday(char *path);
void exitHoliday(void);
int isHoliday(struct tm *tm, char **name);
int getDay(struct tm *tm, char **name);
#endif

104
isdnlog/tools/rate-pta.c Normal file
View File

@ -0,0 +1,104 @@
#include <stdio.h>
#include <stdlib.h>
char *Name[5] = { "Minimumtarif",
"Standartarif",
"Geschäftstarif 1",
"Geschäftstarif 2",
"Geschäftstarif 3" };
double Tarif[5] = { 1.116,
1.056,
0.996,
0.936,
0.816 };
char *Zone[30] = { "Regionalzone",
"Fernzone 1",
"Fernzone 2",
"Online-Tarif",
"Mobilfunk",
"Ausland Zone 1",
"Ausland Zone 2",
"Ausland Zone 3",
"Ausland Zone 4",
"Ausland Zone 5",
"Ausland Zone 6",
"Ausland Zone 7",
"Ausland Zone 8",
"Ausland Zone 9",
"Ausland Zone 10",
"Ausland Zone 11",
"Ausland Zone 12",
"Ausland Zone 13",
"Ausland Zone 14",
"Ausland Zone 15",
"Handvermittelter Verkehr",
"Grenznahverkehr",
"Teleinfo 04570",
"Teleinfo 04500 ",
"Telebusiness 04590",
"Teleinfo 04580",
"Businessline 0711x",
"Businessline 0713x",
"Businessline 0714x",
"Votingline 0717x" };
/* Einheiten in 72 sec */
double Faktor [30][4] = {{ 1.25, 1.00, 0.66, 0.45 }, /* Regionalzone bis 50 km */
{ 3.60, 2.88, 1.44, 1.00 }, /* Fernzone 1 bis 200 km */
{ 4.80, 3.75, 1.80, 1.44 }, /* Fernzone 2 über 200 km */
{ 0.60, 0.60, 0.20, 0.20 }, /* Online-Tarif */
{ 6.00, 6.00, 3.75, 3.75 }, /* Mobilfunk */
{ 6.00, 6.00, 5.00, 5.00 }, /* Ausland Zone 1 */
{ 8.00, 8.00, 6.00, 6.00 }, /* Ausland Zone 2 */
{ 11.00, 11.00, 9.00, 9.00 }, /* Ausland Zone 3 */
{ 14.00, 14.00, 12.00, 12.00 }, /* Ausland Zone 4 */
{ 17.00, 17.00, 15.00, 15.00 }, /* Ausland Zone 5 */
{ 20.00, 20.00, 17.00, 17.00 }, /* Ausland Zone 6 */
{ 23.00, 23.00, 20.00, 20.00 }, /* Ausland Zone 7 */
{ 26.00, 26.00, 24.00, 24.00 }, /* Ausland Zone 8 */
{ 30.00, 30.00, 28.00, 28.00 }, /* Ausland Zone 9 */
{ 34.00, 34.00, 32.00, 32.00 }, /* Ausland Zone 10 */
{ 39.00, 39.00, 36.00, 36.00 }, /* Ausland Zone 11 */
{ 44.00, 44.00, 40.00, 40.00 }, /* Ausland Zone 12 */
{ 59.00, 59.00, 53.00, 53.00 }, /* Ausland Zone 13 */
{ 9.00, 9.00, 8.00, 8.00 }, /* Ausland Zone 14 */
{ 8.00, 8.00, 10.00, 10.00 }, /* Ausland Zone 15 */
{ 0.00, 0.00, 0.00, 0.00 }, /* Handvermittelter Verkehr */
{ 4.00, 4.00, 3.00, 3.00 }, /* Grenznahverkehr */
{ 6.67, 6.67, 6.67, 6.67 }, /* Teleinfo 04570 */
{ 10.00, 10.00, 10.00, 10.00 }, /* Teleinfo 04500 */
{ 16.00, 16.00, 16.00, 16.00 }, /* Telebusiness 04590 */
{ 26.67, 26.67, 26.67, 26.67 }, /* Teleinfo 04580 */
{ 1.25, 1.00, 0.66, 0.45 }, /* Businessline 0711x */
{ 2.25, 2.25, 2.25, 2.25 }, /* Businessline 0713x */
{ 4.80, 4.80, 4.80, 4.80 }, /* Businessline 0714x */
{ 4.80, 4.80, 4.80, 4.80 }}; /* Votingline 0717x */
void main (void)
{
int t, z;
printf ("# created by rate-pta.c\n\n");
printf ("V:1.0-Austria [11-Mar-1999]\n");
for (t=0; t<4; t++) {
printf ("\nP:00,%d\t\t\t\tPTA\n", t+1);
printf ("C:Name:\t\t\t\tPost & Telekom Austria\n");
printf ("C:Tarif:\t\t\t%s (ATS %.3f / Impuls)\n", Name[t], Tarif[t]);
for (z=0; z<30; z++) {
printf ("\nZ:%d\t\t\t\t%s\n", z+1, Zone[z]);
if (Faktor[z][2]) printf ("T:1-5/06-08,18-20=%.3f/%.5g\tSparzeit\n", Tarif[t], 72.0/Faktor[z][2]);
if (Faktor[z][0]) printf ("T:1-5/08-12=%.3f/%.5g\t\tTageszeit 1\n", Tarif[t], 72.0/Faktor[z][0]);
if (Faktor[z][0]) printf ("T:1-4/13-16=%.3f/%.5g\t\tTageszeit 1\n", Tarif[t], 72.0/Faktor[z][0]);
if (Faktor[z][1]) printf ("T:1-4/12-13,16-18=%.3f/%.5g\tTageszeit 2\n", Tarif[t], 72.0/Faktor[z][1]);
if (Faktor[z][1]) printf ("T:5/12-18=%.3f/%.5g\t\tTageszeit 2\n", Tarif[t], 72.0/Faktor[z][1]);
if (Faktor[z][2]) printf ("T:E,H/06-20=%.3f/%.5g\t\tSparzeit\n", Tarif[t], 72.0/Faktor[z][2]);
if (Faktor[z][3]) printf ("T:*/20-06=%.3f/%.5g\t\tSupersparzeit\n", Tarif[t], 72.0/Faktor[z][3]);
}
}
}

508
isdnlog/tools/rate.c Normal file
View File

@ -0,0 +1,508 @@
/* $Id: rate.c,v 1.1 1999/03/14 12:16:42 akool Exp $
*
* Tarifdatenbank
*
* 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: rate.c,v $
* Revision 1.1 1999/03/14 12:16:42 akool
* - isdnlog Version 3.04
* - general cleanup
* - new layout for "rate-xx.dat" and "holiday-xx.dat" files from
* Michael Reinelt <reinelt@eunet.at>
* unused by now - it's a work-in-progress !
* - bugfix for Wolfgang Siefert <siefert@wiwi.uni-frankfurt.de>
* The Agfeo AS 40 (Software release 2.1b) uses AOC_AMOUNT, not AOC_UNITS
* - bugfix for Ralf G. R. Bergs <rabe@RWTH-Aachen.DE> - 0800/xxx numbers
* are free of charge ;-)
* - tarif.dat V 1.08 - new mobil-rates DTAG
*
*/
/*
* Schnittstelle zur Tarifdatenbank:
*
* void exitRate(void)
* deinitialisiert die Tarifdatenbank
*
* void initRate(char *info)
* initialisiert die Tarifdatenbank, liefert Versionsinfo in `info'
* zurueck
*
* char *Providername(int prefix)
* liefert den Providernamen fuer Kennzahl `prefix', oder NULL, falls
* unbekannt
*
* char *Zonename(int prefix, int zone)
* liefert den Zonennamen fuer Provider `prefix', oder NULL, falls
* unbekannt
*
* int taktlaenge(int chan, char *why)
* liefert fuer die aktuell laufende Verbindung in `chan'
* die Laenge eines Tariftaktes in Sekunden, sowie evtl. in `why'
* eine textuelle Begruendung
*
* void preparecint(int chan, char *msg, char *hint)
* fuellt die aktuell laufende Verbindung in `chan' mit allen
* fuer die weitere Taktberechnung noetigen Daten
* liefert evtl. in `msg' sowie `hint' textuelle Informationen
* fuer die LCR-Optimierung
*
* void price(int chan, char *hint)
* berechnet fuer die gerade beendete Verbindung in `chan' den
* Endpreis, stellt diesen in `chan', und liefert in `hint' evtl.
* textuelle Informationen fuer die LCR-Optimierung
*
*/
#define _RATE_C_
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "rate.h"
#define MAXPROVIDER 100
#define LENGTH 250 /* max length of lines in data file */
#define UNKNOWN -1
typedef unsigned long bitfield;
typedef struct {
int Duration;
int Delay;
double Price;
} UNIT;
typedef struct {
char *Name;
bitfield Day;
bitfield Hour;
int nUnit;
UNIT *Unit;
} RATE;
typedef struct {
int used;
char *Name;
int nRate;
RATE *Rate;
} ZONE;
typedef struct {
int used;
char *Name;
char *Internet;
int nZone;
ZONE *Zone;
} PROVIDER;
static PROVIDER Provider[MAXPROVIDER];
static int use[MAXPROVIDER];
static int line=0;
static void warning (char *fmt, ...)
{
va_list ap;
char msg[BUFSIZ];
va_start (ap, fmt);
vsnprintf (msg, BUFSIZ, fmt, ap);
va_end (ap);
#ifdef STANDALONE
fprintf(stderr, "WARNING: line %3d: %s\n", line, msg);
#else
print_msg(PRT_NORMAL, "WARNING: line %3d: %s\n", line, msg);
#endif
}
static char *strip (char *s)
{
char *p;
while (*s==' ' || *s=='\t') s++;
for (p=s; *p; p++)
if (*p=='#' || *p=='\n') {
*p='\0';
break;
}
for (p--; p>s && (*p==' '||*p=='\t'); p--)
*p='\0';
return s;
}
void exitRate(void)
{
int i, j, k;
for (i=0; i<MAXPROVIDER; i++) {
if (Provider[i].used) {
for (j=0; j<Provider[i].nZone; i++)
if (Provider[i].Zone[j].used) {
Provider[i].Zone[j].used=0;
for (k=0; k<Provider[i].Zone[j].nRate; k++) {
if (Provider[i].Zone[j].Rate[k].Name) free (Provider[i].Zone[j].Rate[k].Name);
if (Provider[i].Zone[j].Rate[k].Unit) free (Provider[i].Zone[j].Rate[k].Unit);
}
if (Provider[i].Zone[j].Name) free (Provider[i].Zone[j].Name);
if (Provider[i].Zone[j].Rate) free (Provider[i].Zone[j].Rate);
}
if(Provider[i].Zone) free (Provider[i].Zone);
if (Provider[i].Name) free (Provider[i].Name);
if (Provider[i].Internet) free (Provider[i].Internet);
Provider[i].used=0;
}
}
}
int initRate(char *conf, char *dat, char *msg)
{
FILE *stream;
char buffer[LENGTH];
char Version[LENGTH]="";
int nProvider=0;
int nZone=0;
int nRate=0;
int ignore=0;
int prefix=UNKNOWN;
int version=UNKNOWN;
int zone1, zone2;
int day1, day2, hour1, hour2;
bitfield day, hour;
double price;
int duration, delay;
int i, t, u;
char *s;
for (i=0; i<MAXPROVIDER; i++) {
Provider[i].used=0;
use[i]=UNKNOWN;
}
if (conf && *conf && (stream=fopen(conf,"r"))) {
line=0;
while ((s=fgets(buffer,LENGTH,stream))!=NULL) {
line++;
if (*(s=strip(s))=='\0')
continue;
if (s[1]!=':') {
warning ("expected ':', got '%s'!", s+1);;
continue;
}
switch (*s) {
case 'P':
prefix = strtol(s+2, &s ,10);
if (*s != '=') {
warning ("expected '=', got '%s'!", s);
continue;
}
if ((prefix < 0) || (prefix >= MAXPROVIDER)) {
warning ("Invalid provider-number %d", prefix);
continue;
}
use[prefix] = atoi(s+1);
break;
default:
warning("Unknown tag '%c'", *s);
}
}
fclose (stream);
}
if (!dat || !*dat || (stream=fopen(dat,"r"))==NULL)
return -1;
line=0;
prefix=UNKNOWN;
while ((s=fgets(buffer,LENGTH,stream))!=NULL) {
line++;
if (*(s=strip(s))=='\0')
continue;
if (s[1]!=':') {
warning ("expected ':', got '%s'!", s+1);;
continue;
}
switch (*s) {
case 'P': /* P:nn[,v]=Bezeichnung */
ignore = 0;
version = UNKNOWN;
zone1 = zone2 = UNKNOWN;
prefix = strtol(s+2, &s ,10);
if (*s == ',') {
version = strtol(s+1, &s ,10);
}
if (*s == '=') s++;
if ((prefix < 0) || (prefix >= MAXPROVIDER)) {
warning ("Invalid provider-number %d", prefix);
continue;
}
if ((use[prefix]!=UNKNOWN) && (version!=UNKNOWN) && (use[prefix]!=version)) {
version = UNKNOWN;
ignore = 1;
continue;
}
if (Provider[prefix].used++) {
warning ("Duplicate entry for provider %d (%s)", prefix, Provider[prefix].Name);
if (Provider[prefix].Name) free(Provider[prefix].Name);
if (Provider[prefix].Internet) free(Provider[prefix].Internet);
}
Provider[prefix].Name=strdup(strip(s));
Provider[prefix].Internet=NULL;
Provider[prefix].nZone=0;
Provider[prefix].Zone=NULL;
nProvider++;
break;
case 'G': /* P:tt.mm.jjjj Rate gueltig ab */
if (ignore) continue;
break;
case 'C': /* C:Comment */
if (ignore) continue;
break;
case 'I': /* I:nnn Internet-Zugangsnummer */
if (ignore) continue;
if (prefix == UNKNOWN) {
warning ("Unexpected tag '%c'", *s);
break;
}
Provider[prefix].Internet = strdup(s+2);
break;
case 'Z': /* Z:n[-n][=]Bezeichnung */
if (ignore) continue;
if (prefix == UNKNOWN) {
warning ("Unexpected tag '%c'", *s);
break;
}
zone1=strtol(s+2,&s,10);
if (*s=='-') zone2=strtol(s+1,&s,10);
else zone2=zone1;
if (*s=='=')s++;
if (zone1>zone2) {
i=zone2; zone2=zone1; zone1=i;
}
if (zone2>=Provider[prefix].nZone) {
Provider[prefix].Zone=realloc(Provider[prefix].Zone, (zone2+1)*sizeof(ZONE));
Provider[prefix].nZone = zone2+1;
}
for (i=zone1; i<=zone2; i++) {
Provider[prefix].Zone[i].used=1;
Provider[prefix].Zone[i].Name=strdup(strip(s));
Provider[prefix].Zone[i].nRate=0;
Provider[prefix].Zone[i].Rate=NULL;
nZone++;
}
break;
case 'T': /* T:d-d/h-h=p/s:t[=]Bezeichnung */
if (ignore) continue;
if (zone1 == UNKNOWN) {
warning ("Unexpected tag '%c'", *s);
break;
}
s+=2;
day=0;
while (1) {
if (*s=='*') { /* jeder Tag */
day |= 0xff; /* 11111111 */
s++;
} else if (*s=='W') { /* Wochentag 1-5 */
day |= 0x1f; /* 00011111 */
s++;
} else if (*s=='E') { /* Wochenende 6-7 */
day |= 0x60; /* 01100000 */
s++;
} else if (*s=='F'||*s=='H') { /* Feiertag (Holiday) */
day |= 0x80; /* 10000000 */
s++;
} else if (isdigit(*s)) { /* 1,2,3 oder 1-5 oder 6,7,F */
day1=strtol(s,&s,10);
if (*s=='-') day2=strtol(++s,&s,10);
else day2=day1;
for (i=day1; i<=day2; i++) day|=(1<<(i-1));
} else if (*s==',') {
s++;
} else if (*s=='/') {
s++;
break;
} else {
warning ("invalid day format '%s'", s);
day=0;
break;
}
}
while (1) {
if (*s=='*') { /* jede Stunde */
hour |= 0xffffff; /* alles 1er */
s++;
} else if (isdigit(*s)) { /* 8-12 oder 1,5 */
hour1=strtol(s,&s,10);
if (*s=='-') hour2=strtol(s+1,&s,10);
else hour2=hour1+1;
if (hour2>=hour1)
for (i=hour1; i<hour2; i++) hour|=(1<<i);
else {
for (i=hour1; i<24; i++) hour|=(1<<i);
for (i=0; i<hour2; i++) hour|=(1<<i);
}
} else if (*s==',') {
s++;
} else if (*s=='=') {
s++;
break;
} else {
warning ("invalid hour format '%s'", s);
hour=0;
break;
}
}
if (day==0 || hour==0) {
warning ("I'm sorry, I don't understand this line...");
continue;
}
for (i=zone1; i<=zone2; i++) {
t=Provider[prefix].Zone[i].nRate++;
Provider[prefix].Zone[i].Rate = realloc(Provider[prefix].Zone[i].Rate, (t+1)*sizeof(RATE));
Provider[prefix].Zone[i].Rate[t].Name=NULL;
Provider[prefix].Zone[i].Rate[t].Day=day;
Provider[prefix].Zone[i].Rate[t].Hour=hour;
Provider[prefix].Zone[i].Rate[t].nUnit=0;
Provider[prefix].Zone[i].Rate[t].Unit=NULL;
}
while (1) {
price=strtod(s,&s);
duration=1;
delay=0;
if (*s=='/')
duration=strtol(s+1,&s,10);
if (*s==':')
delay=strtol(s+1,&s,10);
for (i=zone1; i<=zone2; i++) {
t=Provider[prefix].Zone[i].nRate-1;
u=Provider[prefix].Zone[i].Rate[t].nUnit++;
Provider[prefix].Zone[i].Rate[t].Unit=realloc(Provider[prefix].Zone[i].Rate[t].Unit, (u+1)*sizeof(UNIT));
Provider[prefix].Zone[i].Rate[t].Unit[u].Duration=duration;
Provider[prefix].Zone[i].Rate[t].Unit[u].Delay=delay;
Provider[prefix].Zone[i].Rate[t].Unit[u].Price=price;
nRate++;
}
if (*s!=',') break;
}
if (*s=='=') s++;
for (i=zone1; i<=zone2; i++) {
t=Provider[prefix].Zone[i].nRate-1;
Provider[prefix].Zone[i].Rate[t].Name=strdup(strip(s));
}
break;
case 'V': /* V:xxx Version der Ratedatenbank */
strcpy(Version, s+2);
break;
default:
warning ("Unknown tag '%c'", *s);
break;
}
}
fclose(stream);
sprintf (msg, "Rate Version %s loaded [%d Providers, %d Zones, %d Rates]",
Version, nProvider, nZone, nRate);
return 0;
}
char *Providername(int prefix)
{
if (!Provider[prefix].used) return(NULL);
return(Provider[prefix].Name);
}
char *Zonename(int prefix, int zone)
{
if (!Provider[prefix].used) return(NULL);
if (zone<1 || zone>=Provider[prefix].nZone) return (NULL);
if (!Provider[prefix].Zone[zone].used) return (NULL);
return(Provider[prefix].Zone[zone].Name);
}
static double tpreis(int prefix, int zone, int day, int hour, int duration)
{
bitfield dayMask, hourMask;
RATE *Rate;
UNIT *Unit;
double price;
int delay, i;
if (!Provider[prefix].used) return UNKNOWN;
if (!Provider[prefix].Zone[zone].used) return UNKNOWN ;
dayMask=1<<(day-1);
hourMask=1<<hour;
for (i=0; i<Provider[prefix].Zone[zone].nRate; i++) {
Rate = Provider[prefix].Zone[zone].Rate+i;
if ((Rate->Day & dayMask) && (Rate->Hour & hourMask))
break;
}
if (i==Provider[prefix].Zone[zone].nRate) return UNKNOWN;
i = 1;
price = 0.0;
delay = 0;
Unit = Rate->Unit;
while (duration>0) {
duration -= Unit->Duration;
delay += Unit->Duration;
price += Unit->Price;
if ((delay >= Unit->Delay) && (i < Rate->nUnit))
Unit++;
}
return price;
}
#ifdef STANDALONE
void main (int argc, char *argv[])
{
char msg[BUFSIZ];
int provider, zone, day, hour, duration;
initRate ("../rate-at.conf", "../rate-at.dat", msg);
printf ("%s\n", msg);
provider = 0;
zone = 1;
printf ("Providername(%d) = %s\n", provider, Providername(provider));
printf ("Zonename(%d,%d) = %s\n", provider, zone, Zonename(provider, zone));
day=1;
hour=12;
duration=300;
printf ("tpreis(%d,%d,%d,%d,%d)=%f\n", provider, zone, day, hour, duration, tpreis(provider, zone, day, hour, duration));
}
#endif

44
isdnlog/tools/rate.h Normal file
View File

@ -0,0 +1,44 @@
/* $Id: rate.h,v 1.1 1999/03/14 12:16:43 akool Exp $
*
* Tarifdatenbank
*
* 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: rate.h,v $
* Revision 1.1 1999/03/14 12:16:43 akool
* - isdnlog Version 3.04
* - general cleanup
* - new layout for "rate-xx.dat" and "holiday-xx.dat" files from
* Michael Reinelt <reinelt@eunet.at>
* unused by now - it's a work-in-progress !
* - bugfix for Wolfgang Siefert <siefert@wiwi.uni-frankfurt.de>
* The Agfeo AS 40 (Software release 2.1b) uses AOC_AMOUNT, not AOC_UNITS
* - bugfix for Ralf G. R. Bergs <rabe@RWTH-Aachen.DE> - 0800/xxx numbers
* are free of charge ;-)
* - tarif.dat V 1.08 - new mobil-rates DTAG
*
*/
#ifndef _RATE_H_
#define _RATE_H_
void exitRate(void);
int initRate(char *conf, char *dat, char *msg);
char *Providername(int prefix);
char *Zonename(int prefix, int zone);
#endif

View File

@ -1,4 +1,4 @@
/* $Id: tools.c,v 1.18 1999/02/28 19:33:48 akool Exp $
/* $Id: tools.c,v 1.19 1999/03/14 12:16:44 akool Exp $
*
* ISDN accounting for isdn4linux. (Utilities)
*
@ -19,6 +19,18 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: tools.c,v $
* Revision 1.19 1999/03/14 12:16:44 akool
* - isdnlog Version 3.04
* - general cleanup
* - new layout for "rate-xx.dat" and "holiday-xx.dat" files from
* Michael Reinelt <reinelt@eunet.at>
* unused by now - it's a work-in-progress !
* - bugfix for Wolfgang Siefert <siefert@wiwi.uni-frankfurt.de>
* The Agfeo AS 40 (Software release 2.1b) uses AOC_AMOUNT, not AOC_UNITS
* - bugfix for Ralf G. R. Bergs <rabe@RWTH-Aachen.DE> - 0800/xxx numbers
* are free of charge ;-)
* - tarif.dat V 1.08 - new mobil-rates DTAG
*
* Revision 1.18 1999/02/28 19:33:48 akool
* Fixed a typo in isdnconf.c from Andreas Jaeger <aj@arthur.rhein-neckar.de>
* CHARGEMAX fix from Oliver Lauer <Oliver.Lauer@coburg.baynet.de>
@ -511,7 +523,7 @@ char *double2clock(double n)
char *vnum(int chan, int who)
{
register int l = strlen(call[chan].num[who]), got = 0;
register int l = strlen(call[chan].num[who]), got = 0, l1;
register int flag = C_NO_WARN | C_NO_EXPAND;
auto char *ptr;
auto int ll, lx;
@ -550,8 +562,12 @@ char *vnum(int chan, int who)
if (cnf > -1)
strcpy(retstr[retnum], call[chan].alias[who]);
else if (call[chan].sondernummer[who] != -1)
else if (call[chan].sondernummer[who] != -1) {
if ((l1 = strlen(SN[call[chan].sondernummer[who]].number)) < l)
sprintf(retstr[retnum], "%s - %s", SN[call[chan].sondernummer[who]].info, call[chan].num[who] + l1);
else
strcpy(retstr[retnum], SN[call[chan].sondernummer[who]].info);
}
else
sprintf(retstr[retnum], "TN %s", call[chan].num[who]);