isdnlog-3.53

This commit is contained in:
Andreas Kool 1999-09-19 14:16:28 +00:00
parent 78c73e20f8
commit e7d286465b
24 changed files with 4020 additions and 1679 deletions

View File

@ -19,6 +19,9 @@
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
## $Log$
## Revision 1.106 1999/09/16 20:27:21 akool
## isdnlog-3.52
##
## Revision 1.105 1999/09/13 09:09:42 akool
## isdnlog-3.51
## - changed getProvider() to not return NULL on unknown providers
@ -764,7 +767,7 @@ SERVICEFILE = /etc/services
# DON'T EDIT BELOW THIS LINE
######################################################################
VERSION = 3.52
VERSION = 3.53
MANPAGES = isdnlog/callerid.conf.5 isdnlog/isdn.conf.5 \
isdnlog/isdnformat.5 isdnlog/isdnlog.5 isdnlog/isdnlog.8 \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,85 @@
NEWS betreffend tools, (rate, isdnrate)
1999.09.15
isdnrate.c
neue Varianten
-X51 Inlandszonen
-X50 Auslandszonen
1999.09.07
rate-CC.dat: Syntaxerweiterung im C:Tag
C:TarifChanged:dd.mm.yyyy
(Datum der letzten Tarifwartung)
1999.09.05
telrate.cgi:
uses now gd 1.6.3, GD 1.21 with PNG instead of GIF
(smaller, no licence troubles)
requires
gd 1.6.3 which
requires
libz, libpng
(e.g. ln -s /usr/X11R6/lib/libz.so /usr/lib/libz.so
ln -s /usr/X11R6/lib/libpng.so /usr/lib/libpng.so
ln -s /usr/X11R6/include/png.h /usr/local/include/png.h
ln -s /usr/X11R6/include/pngconf.h /usr/local/include/pngconf.h
)
or from GD README
Make sure you have downloaded and installed the following packages:
a. Perl 5.004 or higher:
http://www.perl.com/
b. The gd graphics library, version 1.6.3 or higher:
http://www.boutell.com/gd/
c. The PNG graphics library:
http://www.cdrom.com/pub/png/
d. The zlib compression library:
http://www.cdrom.com/pub/infozip/zlib/
dann noch ein kleiner Patch in GD.c, weiss der Geier warum
--- GD.c Sat Sep 4 19:06:37 1999
+++ GD.c.leo Sat Sep 4 19:01:46 1999
@@ -1974,7 +1974,8 @@
#ifdef __cplusplus
extern "C"
#endif
-XS(boot__CAPI_entry)
+/* XS(boot__CAPI_entry) */
+XS(boot_GD)
{
dXSARGS;
char* file = __FILE__;
@@ -2039,7 +2040,7 @@
XSRETURN_YES;
}
-
+#if 0
#define XSCAPI(name) void name(CV* cv, void* pPerl)
#ifdef __cplusplus
@@ -2051,3 +2052,4 @@
boot__CAPI_entry(cv);
}
+#endif
1999.09.04
isdnrate.c:
-p, -x take now an additional argument 'B'
-pB ... show only business providers
-xB ... don't show
The provider is considered as a business-provider if the
C:GT:-Tag contains the string "Business" (uppercase)
1999.09.03
holiday.c: holiday-CC.dat

View File

@ -19,6 +19,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log$
* Revision 1.19 1999/09/16 20:27:21 akool
* isdnlog-3.52
*
* Revision 1.18 1999/09/13 09:09:44 akool
* isdnlog-3.51
* - changed getProvider() to not return NULL on unknown providers
@ -89,14 +92,11 @@
#include "isdnlog.h"
#include "tools/zone.h"
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include "telnum.h"
#define WIDTH 19
#define _MAXLAST 20 /* the real max */
#define MAXLAST ((best>=_MAXLAST||best<=2)?5:best)
#define ZAUNPFAHL 1 /* FIXME: Michi: Offset */
static void print_header(void);
@ -105,8 +105,9 @@ static char *myname, *myshortname;
static char options[] = "b:d:f:h:l:p:t:v::x:CD::G:HLS:TUVX::";
static char usage[] = "%s: usage: %s [ -%s ] Destination ...\n";
static int verbose = 0, header = 0, best = MAXPROVIDER, table = 0,
static int header = 0, best = MAXPROVIDER, table = 0,
explain = 0;
int verbose = 0;
static int usestat = 0;
static int duration = LCR_DURATION;
static time_t start;
@ -115,10 +116,13 @@ 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 char *comment;
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;
#define SOCKNAME "/tmp/isdnrate"
static int is_daemon = 0;
@ -126,6 +130,8 @@ static int is_client = 0;
static int we_are_daemon = 0;
static int takt = 99999;
static char sortby;
static int need_dest;
static int h_param=0;
static TELNUM srcnum, destnum;
@ -210,20 +216,23 @@ static void get_day(char d)
tm = localtime(&start); /* now */
switch (d) {
case 'W': /* we need a normal weekday, so we take
case 'W': /* we need a normal weekday, so we take
today and inc. day if today is
holiday */
what = WORKDAY;
hour = 10;
if(!h_param)
hour = 10;
break;
case 'N':
what = WORKDAY;
hour = 23;
if(!h_param)
hour = 23;
break;
case 'E':
what = SUNDAY;
hour = 10;
if(!h_param)
hour = 10;
break;
}
mask = 1 << what;
@ -256,8 +265,10 @@ static int opts(int argc, char *argv[])
register int c;
register char *p;
int x;
h_param=0;
optind = 0; /* make it repeatable */
need_dest=1;
while ((c = getopt(argc, argv, options)) != EOF) {
switch (c) {
case 'b':
@ -297,12 +308,15 @@ static int opts(int argc, char *argv[])
case 'h':
hour = atoi(optarg);
sec = min = 0;
h_param++;
sec = 0;
if ((p = strchr(optarg + 1, ':'))) {
min = atoi(p + 1);
if ((p = strchr(p + 1, ':')))
sec = atoi(p + 1);
}
else
min=0;
break;
case 'l':
@ -310,22 +324,49 @@ static int opts(int argc, char *argv[])
break;
case 't':
takt = strtol(optarg, NIL, 0);
x = strtol(optarg, NIL, 0);
if (x > 0)
takt = x;
break;
case 'x': /* eXclude Poviders */
exclude = 1;
/* goon */
case 'p': /* Providers ... */
p = strsep(&optarg, ",");
while (p) {
providers = realloc(providers, (n_providers + 1) * sizeof(int));
providers[n_providers] = atoi(p);
p = strsep(&optarg, ",");
n_providers++;
{
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;
case 'p': /* Providers ... */
{
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);
}
break;
case 'v':
verbose++;
if (optarg && (x = atoi(optarg)))
@ -339,6 +380,7 @@ static int opts(int argc, char *argv[])
case 'D':
is_daemon = 1;
need_dest = 0;
if (optarg) {
x = atoi(optarg);
is_daemon = x;
@ -361,7 +403,7 @@ static int opts(int argc, char *argv[])
break;
case 'S':
sortby = *optarg;
break;
break;
case 'T':
table++;
break;
@ -377,11 +419,15 @@ static int opts(int argc, char *argv[])
case 'X':
if (explain == 0) {
explain++;
if (optarg && isdigit(*optarg) && (x = atoi(optarg)))
if (optarg && isdigit(*optarg) && (x = atoi(optarg))) {
explain = x;
else if(optarg) {
if (x==50||x==51)
need_dest=0;
}
else if(optarg) {
comment = strdup(optarg);
explain = 8;
need_dest=0;
}
break;
}
@ -409,6 +455,9 @@ static int opts(int argc, char *argv[])
best = MAXPROVIDER;
print_msg(PRT_A, "Illegal options, -b ignored\n");
}
if ((explain==50||explain==51) && header) {
print_msg(PRT_A, "Conflicting options, -H ignored\n");
}
if (argc > optind)
return (optind);
else
@ -551,7 +600,7 @@ static char *takt_str(RATE * Rate)
return s;
}
static inline char * P_EMPTY(char *s)
static inline char * P_EMPTY(char *s)
{
char *p = s;
return p ? p : "";
@ -568,6 +617,7 @@ static int compute(char *num)
char prov[TN_MAX_PROVIDER_LEN];
int oldprov;
int first = 1;
static char BUSINESS[] = "Business"; /* in C:GT:Tag */
if (destnum.nprovider != UNKNOWN) {
low = high = destnum.nprovider;
@ -596,13 +646,25 @@ static int compute(char *num)
}
for (i = low; i <= high; i++) {
int found, p;
char *px;
char *t;
if (ignore[i])
continue;
px = getProvider(i);
if (px[strlen(px) - 1] == '?') /* UNKNOWN Provider */
t = getProvider(i);
if (!t || t[strlen(t) - 1] == '?') /* UNKNOWN Provider */
continue;
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;
}
found = 0;
if (n_providers) {
for (p = 0; p < n_providers; p++)
@ -610,7 +672,16 @@ static int compute(char *num)
found = 1;
break;
}
if ((!found && !exclude) || (found && exclude))
if (!found)
continue;
}
if (nx_providers) {
for (p = 0; p < nx_providers; p++)
if (xproviders[p] == i) {
found = 1;
break;
}
if (found)
continue;
}
clearRate(&Rate);
@ -636,7 +707,7 @@ static int compute(char *num)
Rate.prefix = i;
Rate.start = start;
Rate.now = start + duration - ZAUNPFAHL;
Rate.now = start + duration - 1;
if (explain == 99) {
int j;
double oldCharge = -1.0;
@ -680,6 +751,18 @@ static int compute(char *num)
if (Rate.Duration <= takt)
printf("@----- %s %s\n", currency, Rate.Provider);
}
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)
printf("%s%c%s%c%s%c%.2f%c%.2f%c%s\n", prefix2provider(Rate.prefix, prov, &destnum), DEL,
Rate.Provider,DEL,currency,DEL,Rate.Charge,DEL,cpm,DEL,
P_EMPTY(Rate.Country));
free(Rate.Country);
}
}
else {
/* kludge to suppress "impossible" Rates */
if (!getRate(&Rate, NULL) && (Rate.Price != 99.99)) {
@ -740,7 +823,7 @@ static void print_header(void)
ctime(&start));
}
static void printList(char *target, int n)
static void printList(int n)
{
int i;
@ -753,7 +836,7 @@ static void printList(char *target, int n)
print_msg(PRT_NORMAL, "%s\n", sort[i].explain);
}
static void result(char *target, int n)
static void result(int n)
{
register int i;
@ -1004,6 +1087,7 @@ static void clean_up()
free(comment);
comment = 0;
sortby = 0;
need_dest=1;
}
@ -1052,7 +1136,10 @@ static void doit(int i, int argc, char *argv[])
post_init();
memset(ignore, 0, sizeof(ignore));
if (!need_dest && i==0) {
i=0; argc=1;
argv[0]="2345";
}
while (i < argc) {
destnum.nprovider = UNKNOWN;
normalizeNumber(argv[i], &destnum, TN_PROVIDER);
@ -1065,9 +1152,9 @@ static void doit(int i, int argc, char *argv[])
else {
n = compute(argv[i]);
if (list)
printList(argv[i], n);
printList(n);
else if (explain < 10)
result(argv[i], n);
result(n);
purge(n);
}
i++;
@ -1110,7 +1197,7 @@ static int handle_client(int fd)
time(&start); /* set time of call */
splittime(); /* date time my be overridden by opts */
we_are_daemon = 1;
if ((i = opts(argc, argv))) {
if ((i = opts(argc, argv))||need_dest==0) {
if (shutdown(fd, 0) < 0) /* no read any more */
err("shutdown");
if (dup2(fd, STDOUT_FILENO) < 0) /* stdout to sock */
@ -1156,7 +1243,17 @@ static void do_reinit(void)
init();
reinit=0;
}
/* 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; })) \
#endif
static void setup_daemon()
{
@ -1186,7 +1283,7 @@ static void setup_daemon()
else if (pid > 0)
exit(EXIT_SUCCESS);
}
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
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);
@ -1274,7 +1371,7 @@ static int connect_2_daemon(int argc, char *argv[])
case 'C':
break;
case 'D':
if (optarg && atoi(optarg) == 3) ; /* goon, kill a running
if (optarg && atoi(optarg) == 3) ; /* goon, kill a running
daemon */
else
@ -1317,7 +1414,7 @@ int main(int argc, char *argv[], char *envp[])
time(&start);
splittime();
if ((i = opts(argc, argv)) || is_daemon) {
if ((i = opts(argc, argv)) || need_dest==0) {
if (is_client)
exit(connect_2_daemon(argc, argv));
else
@ -1337,10 +1434,10 @@ int main(int argc, char *argv[], char *envp[])
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\tduration 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-p prov|B[,prov...]\t show only these providers\n");
print_msg(PRT_A, "\t-t takt\t\tshow providers if chargeduration<=takt\n");
print_msg(PRT_A, "\t-v [level]\tverbose\n");
print_msg(PRT_A, "\t-x prov[,prov...]\t exclude these providers\n");
print_msg(PRT_A, "\t-x prov|B[,prov...]\t exclude these providers\n");
print_msg(PRT_A, "\tOutput and run options\n");
print_msg(PRT_A, "\t-C\trun as client, connecting to a running daemon\n");

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log$
* Revision 1.44 1999/09/16 20:27:22 akool
* isdnlog-3.52
*
* Revision 1.43 1999/09/13 09:09:44 akool
* isdnlog-3.51
* - changed getProvider() to not return NULL on unknown providers
@ -341,9 +344,11 @@ extern const char *basename (const char *name);
#endif
#define mycountry "+43"
#define vbn "010"
#define verbose 3
#else
#include "isdnlog.h"
#include "tools.h"
#define verbose 2 /* AK:17Sep99 (T'schuldigung, Michi :) */
#endif
#include "holiday.h"
@ -454,12 +459,14 @@ static void whimper (char *file, char *fmt, ...)
{
va_list ap;
char msg[BUFSIZ];
va_start (ap, fmt);
vsnprintf (msg, BUFSIZ, fmt, ap);
va_end (ap);
notice ("WHIMPER: %s line %3d: %s", basename(file), line, msg);
}
if (verbose>2) {
va_start (ap, fmt);
vsnprintf (msg, BUFSIZ, fmt, ap);
va_end (ap);
notice ("WHIMPER: %s line %3d: %s", basename(file), line, msg);
}
}
static char *strip (char *s)
{
@ -528,26 +535,28 @@ static char* strcat3 (char **s)
return buffer;
}
static int appendArea (int prefix, char *code, char *name, int zone, int *domestic, int *abroad, char *msg)
static int appendArea (int prefix, char *code, char *name, int zone, int *federal, int *domestic, int *abroad, char *msg)
{
int i;
char *fmt;
for (i=0; i<Provider[prefix].nArea; i++) {
if (strcmp (Provider[prefix].Area[i].Code,code)==0) {
if (msg)
if (name && *name)
whimper (msg, "Duplicate area %s (%s)", code, name);
else
whimper (msg, "Duplicate area %s", code);
if (Provider[prefix].Area[i].Zone!=zone && msg) {
fmt = name && *name ? "Duplicate area %s (%s)" : "Duplicate area %s";
warning (msg, fmt, code, name);
}
return 0;
}
}
if (strcmp(code, mycountry)==0)
if (*code!='+' || strncmp(code,mycountry,strlen(mycountry))==0) {
*domestic=1;
else if (*code=='+' && strncmp(code,mycountry,strlen(mycountry))==0)
if (strcmp(code, mycountry)==0)
*federal=1;
} else
*abroad=1;
Provider[prefix].Area=realloc(Provider[prefix].Area, (Provider[prefix].nArea+1)*sizeof(AREA));
Provider[prefix].Area[Provider[prefix].nArea].Code=strdup(code);
Provider[prefix].Area[Provider[prefix].nArea].Name=name?strdup(name):NULL;
@ -603,7 +612,7 @@ int initRate(char *conf, char *dat, char *dom, char **msg)
char *c, *s;
int booked[MAXPROVIDER], variant[MAXPROVIDER];
int Providers=0, Comments=0, Services=0, Areas=0, Specials=0, Zones=0, Hours=0;
int ignore=0, domestic=0, abroad=0, prefix=UNKNOWN;
int ignore=0, federal=0, domestic=0, abroad=0, prefix=UNKNOWN;
int zone, zone1, zone2, day1, day2, hour1, hour2, freeze, delay;
int *number, numbers;
int d, i, n, t, u, v, z;
@ -716,19 +725,20 @@ int initRate(char *conf, char *dat, char *dom, char **msg)
case 'P': /* P:nn[,v] Bezeichnung */
if (zone!=UNKNOWN && !ignore) {
if (Provider[prefix].Zone[zone].nHour==0) {
line--;
Provider[prefix].Zone[zone].Domestic=domestic;
line--;
if (Provider[prefix].Zone[zone].nHour==0)
whimper (dat, "Zone has no 'T:' Entries", zone);
line++;
}
if (!domestic)
if (domestic && abroad)
whimper (dat, "Zone contains domestic and abroad areas");
if (!federal)
whimper (dat, "Provider %d has no default domestic zone (missing 'A:%s')", prefix, mycountry);
if (!abroad)
Provider[prefix].Zone[zone].Domestic=1;
line++;
}
v = UNKNOWN;
zone = UNKNOWN;
ignore = 1;
federal = 0;
domestic = 0;
abroad = 0;
@ -836,16 +846,18 @@ int initRate(char *conf, char *dat, char *dom, char **msg)
break;
}
if (zone != UNKNOWN) {
Provider[prefix].Zone[zone].Domestic=!abroad;
if (Provider[prefix].Zone[zone].nHour==0) {
line--;
Provider[prefix].Zone[zone].Domestic=domestic;
line--;
if (Provider[prefix].Zone[zone].nHour==0)
whimper (dat, "Zone has no 'T:' Entries", zone);
line++;
}
if (domestic && abroad)
whimper (dat, "Zone contains domestic and abroad areas");
line++;
}
s+=2;
number=NULL;
numbers=0;
domestic=0;
abroad=0;
while (1) {
while (isblank(*s)) s++;
@ -875,12 +887,14 @@ int initRate(char *conf, char *dat, char *dom, char **msg)
}
}
for (i=zone1; i<=zone2; i++) {
for (z=0; z<Provider[prefix].nZone; z++)
for (n=0; n<Provider[prefix].Zone[z].nNumber; n++)
for (z=0; z<Provider[prefix].nZone; z++) {
for (n=0; n<Provider[prefix].Zone[z].nNumber; n++) {
if (Provider[prefix].Zone[z].Number[n]==i) {
warning (dat, "Duplicate zone %d", i);
goto skip;
}
}
}
numbers++;
number=realloc(number, numbers*sizeof(int));
number[numbers-1]=i;
@ -903,6 +917,9 @@ int initRate(char *conf, char *dat, char *dom, char **msg)
break;
}
if (*s=='\0')
whimper (dat, "Zone should have a name...");
zone=Provider[prefix].nZone++;
Provider[prefix].Zone=realloc(Provider[prefix].Zone, Provider[prefix].nZone*sizeof(ZONE));
Provider[prefix].Zone[zone].Name=*s?strdup(s):NULL;
@ -926,17 +943,17 @@ int initRate(char *conf, char *dat, char *dom, char **msg)
if (*(c=strip(str2list(&s)))) {
if (!isdigit(*c) && (d=getCountry(c, &Country)) != UNKNOWN) {
if (*c=='+') {
Areas += appendArea (prefix, c, Country->Name, zone, &domestic, &abroad, dat);
Areas += appendArea (prefix, c, Country->Name, zone, &federal, &domestic, &abroad, dat);
} else if (d>2) {
whimper (dat, "Unknown country '%s' (%s?), ignoring", c, Country->Name);
} else {
if (d>0)
whimper (dat, "Unknown country '%s', using '%s'", c, Country->Name);
for (i=0; i<Country->nCode; i++)
Areas += appendArea (prefix, Country->Code[i], Country->Name, zone, &domestic, &abroad, dat);
Areas += appendArea (prefix, Country->Code[i], Country->Name, zone, &federal, &domestic, &abroad, dat);
}
} else { /* unknown country or Sondernummer */
Areas += appendArea (prefix, c, NULL, zone, &domestic, &abroad, dat);
Areas += appendArea (prefix, c, NULL, zone, &federal, &domestic, &abroad, dat);
Specials++;
}
} else {
@ -1243,17 +1260,17 @@ int initRate(char *conf, char *dat, char *dom, char **msg)
fclose(stream);
if (zone!=UNKNOWN && !ignore) {
if (Provider[prefix].Zone[zone].nHour==0) {
line--;
warning (dat, "Zone has no 'T:' Entries", zone);
line++;
}
if (!domestic)
Provider[prefix].Zone[zone].Domestic=domestic;
line--;
if (Provider[prefix].Zone[zone].nHour==0)
whimper (dat, "Zone has no 'T:' Entries", zone);
if (domestic && abroad)
whimper (dat, "Zone contains domestic and abroad areas");
if (!federal)
whimper (dat, "Provider %d has no default domestic zone (missing 'A:%s')", prefix, mycountry);
if (!abroad)
Provider[prefix].Zone[zone].Domestic=1;
line++;
}
if (!*Version) {
warning (dat, "Database version could not be identified");
strcpy (Version, "<unknown>");

View File

@ -27,11 +27,11 @@ make it readable for your webserver
edit telrate.cgi:
--------------
location of code file ( .../tools/zone/CC/code )
location of telrate (only if pipe's are used not sockets)
country $CC='de' ...
location of code file ( /usr/lib/isdn/code-$CC.dat )
( this file is actually ./tools/zone/CC/code )
location of isdnrate (only if pipe's are used not sockets)
location of mktemp (should be ok)
@prob_zones should be areacodes of villages in zone 1-3
qw (from to to .. ) with leading '0'
location of index.html, info.html, pic, (default /telrate/ under htdocs)
@ -57,9 +57,9 @@ ScriptAlias /perl/ "/usr/local/httpd/cgi-bin/"
<Location /perl>
AddHandler perl-script .pl
AddHandler perl-script .cgi
PerlHandler Apache::Registry
PerlModule = CGI;
PerlSendHeader On
PerlModule = CGI GD IO::Handle
Options +ExecCGI
</Location>
@ -73,8 +73,6 @@ PerlSendHeader On
Options +ExecCGI
</Location>
NOTE: Running under mod_perl has still some bugs, therefor extension cgi
is used by now.
-----------------
End Apache config
@ -83,29 +81,29 @@ End Apache config
# chmod 755 /usr/local/httpd/cgi-bin/telrate.cgi
# chmod 644 /etc/isdn/isdn.conf
edit telnum.c (if not compiled with proper -D ISDN_CC )
first line defines TESTat or TEDTnl
NB: telrate.cgi uses the following perl modules:
CGI, GD, IO::Handle
if you don't have these, point your browser to www.perl.org,
CGI, GD, IO::Handle und Socket
if you don't have these, point your browser to www.perl.com,
and look for CPAN mirrors near your location.
index.html, info.html
---------------------
If your script-url ist not /perl/ change it to /cgi-bin in both files.
If you expanded to a different dirr then /telrate/ you have to adjust
If your script-url ist not /perl/ change it to /cgi-bin in both files or
configure apache to use /perl for your /cgi-bin.
If you expanded to a different dir then /telrate/ you have to adjust
IMG tags too.
Running the Program
-------------------
if $use_sockets is on, start the server instance of isdnlog/bin/telrate with
options -D [-v]
as soon as you see "Setup sockets" you can point your browser to
if $use_sockets is on, start the server instance of isdnlog/bin/isdnrate with
options -D2 [-v]
as soon as you see "Setup sockets" and "Going background" you can point
your browser to
/telrate/index.html

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -3,7 +3,7 @@
<HTML>
<HEAD>
<TITLE>Telefonkosten</TITLE>
<TITLE>Tel-R.at - Telefonkosten</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
NS4 = document.layers ? 1 : 0;
@ -34,20 +34,20 @@ document[what].src=eval(what+i+'.src');
.t {font-family:Sans Serif;font-size:10pt}
.sm {font-family:Sans Serif;font-size:9pt}
i {color:#000080}
//h1 {font-family:Courier New,Courier}
h1,p,td,th,body { font-family:Sans Serif,Arial }
h1 {font-family:Courier New,Courier}
p,td,th,body { font-family:Sans Serif,Arial }
-->
</STYLE>
</HEAD>
<BODY BGCOLOR="#ffffe0">
<H1 ALIGN="center">Telefonkosten</H1>
<P><I>Wieviel</I> kostet ein <I>wie</I> langes Telefongespr&auml;ch von <I>wo</I> <I>wohin</I> um <I>welche</I>Zeit mit
<H1 ALIGN="center">Tel-R.at - Telefonkosten</H1>
<P><I>Wieviel</I> kostet ein <I>wie</I> langes Telefongespr&auml;ch von <I>wo</I> <I>wohin</I> um <I>welche</I> Zeit mit
<I>welchem</I> Telefonprovider und <I>warum</I> eigentlich? <I>Wie</I> teuer kommt mir ein bestimmter Gespr&auml;chsmix
zu verschiedenen Zielen?</P>
<P>Und vorallem: &quot;<I>Wer</I> ist dabei der billigste?&quot;</P>
<P>Das und vieles mehr erfahren Sie hier &uuml;bersichtlich aufbereitet in Tabellen und Grafiken.</P>
zu verschiedenen Zielen? Und <I>wenn</I> man die Geb&uuml;hren dazurechnet, <I>was</I> kostet es dann?</P>
<P>Und vorallem: &quot;<I>Wer</I> ist dabei der billigste?&quot;<br>
Das und vieles mehr erfahren Sie hier, &uuml;bersichtlich aufbereitet in Tabellen und Grafiken.</P>
<BLOCKQUOTE><TABLE>
<TR>
<TD ALIGN="right"> <A HREF="/perl/telrate.cgi" ONMOUSEOVER="swap('eg',1)"
@ -66,13 +66,13 @@ ONMOUSEOVER="swap('info',1)" ONMOUSEOUT="swap('info',0)"><B>Info / Hilfe</B></A>
ONMOUSEOVER="swap('gm',true)"><B>Gespr&auml;chsmix</B></A><A HREF="/perl/telrate.cgi?mix=10" ONMOUSEOUT="swap('gm',false)"
ONMOUSEOVER="swap('gm',true)"><IMG SRC="gm0.jpg" ALT="Gespr&auml;chsmix" BORDER="0" WIDTH="80" HEIGHT="40" NAME="gm"
HSPACE="10"></A> </TD>
<TD ALIGN="left"> <A HREF="/perl/telrate.cgi/list=1" ONMOUSEOVER="swap('list',1)" ONMOUSEOUT="swap('list',0)"><IMG
<TD ALIGN="left"> <A HREF="/perl/telrate.cgi?list=1" ONMOUSEOVER="swap('list',1)" ONMOUSEOUT="swap('list',0)"><IMG
SRC="list0.jpg" ALT="Providerliste" BORDER="0" WIDTH="80" HEIGHT="40" NAME="list" HSPACE="10"></A><A HREF="/perl/telrate.cgi?list=1"
ONMOUSEOVER="swap('list',1)" ONMOUSEOUT="swap('list',0)"><B>Providerliste</B></A> </TD></TR>
</TABLE>
</BLOCKQUOTE>
<P></P>
<IMG SRC="hr.gif" WIDTH="600" HEIGHT="4"> <DIV ALIGN="RIGHT">
<P ALIGN="CENTER"><IMG SRC="hr.gif" WIDTH="600" HEIGHT="4"></P>
<DIV ALIGN="RIGHT">
<P CLASS="sm">This calculationengine is powered by <IMG SRC="tux.gif" ALT="Linux" BORDER="0"> , created by the
<A HREF="http://www.isdn4linux.de">Isdn-Crew</A>.<BR>
HTML page and CGI program created by <A HREF="http://www.toetsch.at">Leopold T&ouml;tsch</A>, (c) 1999 by

View File

@ -4,74 +4,126 @@
<!-- -*-html_mode-*- -->
<HEAD>
<TITLE>Telefonkosten - Info</TITLE>
<TITLE>Tel-R.at - Info</TITLE>
<script language="JavaScript">
<!--
NS4 = document.layers ? 1 : 0;
IE4 = document.all ? 1 : 0;
ver4 = (NS4 || IE4) ? 1 : 0;
function pl(img)
{if(!ver4) return 0;
var a=new Image(); a.src='/telrate/'+img+'.jpg'; return a;
}
eg0=pl("eg0");
eg1=pl("eg1");
gm0=pl("gm0");
gm1=pl("gm1");
list0=pl("list0");
list1=pl("list1");
start0=pl("start0");
start1=pl("start1");
function swap(what,on) {
if(!ver4) return;
var i=on?"1":"0";
document[what].src=eval(what+i+'.src');
}
// -->
</script>
<STYLE TYPE="text/css">
<!--
.t {font-family:Sans Serif;font-size:10pt}
.sm {font-family:Sans Serif;font-size:9pt}
.in {font-family:Sans Serif;font-size:18pt}
i {color:#000080}
h1,h2,h3,h4,p,td,th,body { font-family:Sans Serif,Arial }
h1 {font-family:Courier New,Courier}
h2,h3,h4,p,td,th,body { font-family:Sans Serif,Arial }
-->
</STYLE>
</HEAD>
<BODY BGCOLOR="#ffffe0">
<H1 ALIGN="center">Telefonkosten - Info</H1>
<H1 ALIGN="center">Tel-R.at - Info</H1>
<UL>
<LI><A HREF="#allg">Allgemein</A> </LI>
<LI><A HREF="#help">Hilfe</A> </LI>
<LI><A HREF="#calc">Berechnungsmethode</A> </LI>
<LI><A HREF="#gloss">Glossar</A> </LI>
<LI><A HREF="#autor">Datenpfleger</A> </LI>
<LI><A HREF="#prog">Programmautoren</A> </LI>
</UL>
<H2><A NAME="allg">Allgemein</A></H2>
<span class="in">H</span>ier werden Telefonkosten berechnet und zwar
<ul>
<li>f&uuml;r ein Einzelgespr&auml;ch
<li>f&uuml;r einen Gespr&auml;chsmix (mehrere unterschiedliche Gespr&auml;che verschiedener L&auml;nge)
<li>f&uuml;r einen Gespr&auml;chsmix inklusive allf&auml;lliger Geb&uuml;hren
</ul>
und das
<ul>
<li>sekundengenau (aber auch durchschittlichen Minutenpreise)
<li>von ihrem Standort zu einer beliebig anderen Vorwahl
</ul>
Das Ergebnis wird in Listen oder Grafiken &uuml;bersichtlich dargestellt.
<p><span class="in">D</span>etails wie alle Inlands- und Auslandspreise oder Kontaktinformation erhalten Sie jeweils
bei einem Klick auf die Providerbezeichnung.</p>
<H2><A NAME="help">Hilfe</A></H2>
<P>Die Eingabemasken f&uuml;r Einzelgespr&auml;che und Gespr&auml;chsmix bieten eine Vielzahl von Eingabe- und
<P><span class="in">D</span>ie Eingabemasken f&uuml;r Einzelgespr&auml;che und Gespr&auml;chsmix bieten eine Vielzahl von Eingabe- und
Auswahlm&ouml;glichkeiten. Die meisten davon sind aber eher selbsterkl&auml;rend. <BR>
Tats&auml;chlich eingeben m&uuml;ssen Sie nur die Vorwahl, von der aus Sie w&auml;hlen und die Vorwahl des
gew&uuml;nschten Zieles, alle anderen Felder haben eine Standardeinstellung.<BR>
Sollten Sie weitere Information ben&ouml;tigen, klicken Sie einfach auf das<IMG SRC="help.gif" HSPACE="4"
ALIGN="middle" ALT="Fragezeichen" WIDTH="24" HEIGHT="24"> neben dem fraglichen Feld.</P>
<P> Eine &Uuml;bersicht &uuml;ber alle Eingabem&ouml;glichkeiten erhalten Sie <A
<P><span class="in">E</span>ine &Uuml;bersicht &uuml;ber alle Eingabem&ouml;glichkeiten erhalten Sie <A
HREF="/perl/telrate.cgi?help=3">hier</A>. <IMG SRC="hr.gif" WIDTH="600" HEIGHT="4" ALT="-----"> </P>
<H2><A NAME="calc">Berechnungsmethode</A></H2>
<P> Die Berechnung der gew&uuml;nschten Verbindung erfolgt nach dem selben Takt- und Zonenmodell, wie es der jeweilige
<P><span class="in">D</span>ie Berechnung der gew&uuml;nschten Verbindung erfolgt nach dem selben Takt- und Zonenmodell, wie es der jeweilige
Provider verwendet. Dabei werden auch Takt- oder Geb&uuml;hrenwechsel wie z.B. um 18<SUP><FONT
SIZE="-1">00</FONT></SUP> ber&uuml;cksichtigt. <BR>
Bei Providern, die keinen Sekundentakt verwenden, sind die echten Gepr&auml;chskosten daher oft h&ouml;her als die
theoretischen, durchschnittlichen Minutenpreise, die normalerweise genannt werden.<BR>
Die Daten k&ouml;nnen nat&uuml;rlich nur so exakt sein, als die Provider Informationen zur Verf&uuml;gung stellen,
besonders die Zonentabellen sind h&auml;ufig ein Geheimnis der Firmen.</P>
<P>Wenn Sie also eine Ungenauigkeit feststellen sollten, teilen Sie <A HREF="#autor">uns</A> das bitte mit. Wir sind
theoretischen, durchschnittlichen Minutenpreise, die normalerweise genannt werden.</P>
<P><span class="in">D</span>ie Daten k&ouml;nnen nat&uuml;rlich nur so exakt sein, als die Provider Informationen zur Verf&uuml;gung stellen,
besonders die Zonentabellen sind h&auml;ufig ein Geheimnis der Firmen.
<BR>Wenn Sie also eine Ungenauigkeit feststellen sollten, teilen Sie <A HREF="#autor">uns</A> das bitte mit. Wir sind
bem&uuml;ht, die Daten immer auf dem letzten Stand zu halten, was nebenbei bemerkt durch die Dynamik des Marktes nicht
ganz einfach ist.</P>
<P> <IMG SRC="hr.gif" WIDTH="600" HEIGHT="4" ALT="-----"> </P>
<H2><A NAME="gloss">Glossar</A></H2>
<DL>
<DT>Gespr&auml;chsherstellungsgeb&uuml;hr</DT>
<DT><span class="in">D</span>urchschnittlicher Minutenpreis</DT>
<DD>siehe Minutenpreis</DD>
<DT><span class="in">G</span>espr&auml;chsherstellungsgeb&uuml;hr</DT>
<DD>F&auml;llt bei jedem Gespr&auml;ch zus&auml;tzlich zu der Gespr&auml;chsgeb&uuml;hr an - unabh&auml;ngig von der
Gespr&auml;chsl&auml;nge. </DD>
<DT>Mindestgespr&auml;chsgeb&uuml;hr</DT>
<DD>Sie zahlen zumindest diese Geb&uuml;hr - ist Ihr Gespr&auml;ch teurer fallen keine erh&ouml;hten Kosten an. </DD>
<DT><span class="in">M</span>indestgespr&auml;chsgeb&uuml;hr</DT>
<DD>Sie zahlen zumindest diese Geb&uuml;hr - ist Ihr Gespr&auml;ch teurer, fallen keine erh&ouml;hten Kosten an. </DD>
<DT>Minutenpreis</DT>
<DD>Vergleichswert f&uuml;r Gespr&auml;chskosten, ohne weitere Geb&uuml;hren - stimmt bestenfalls dann mit den
wirklichen Kosten &uuml;berein, wenn 60 durch den Takt ohne Rest teilbar ist. </DD>
<DT>Tag / Zeit</DT>
<DT><span class="in">S</span>chwund</DT>
<DD>Die durch die Taktung oder Mindestentgelte verursachte Gespr&auml;chsgeb&uuml;hr.
<br>Tip: versuchen Sie mal eine <a href ="/perl/telrate.cgi?tel=usa&len=5&now=on&tab=GO&_3D=on">5 Sekunden lange Verbindung in die USA</a> (z.B. es
meldet sich der Anrufbeantworter und Sie legen auf), ob Sie 30g oder 4 Schilling zahlen,
ist ein sch&ouml;ner Unterschied, besonders wenn das h&auml;ufiger passiert.
<DT><span class="in">T</span>ag / Zeit</DT>
<DD>Einige Povider verrechnen pro Tageszeit / Wochentag unterschiedliche Preise, andere haben Einheitspreise. </DD>
<DT>Takt</DT>
<DD>Bei jedem Taktimpuls erh&ouml;ht sich der Gespr&auml;chspreis um die Geb&uuml;hreneinheit. Je k&uuml;rzer der Takt,
umso genauer die Abrechnung. <BR>
Bei einem Takt von 60 Sekunden und einer durchschnittlichen Gespr&auml;chszeit von einer Minute sind die
Gespr&auml;chskosten im Schnitt um 50 % h&ouml;her, als bei sekundengenauer Abrechnung. </DD>
<br>Tip: versuchen Sie folgenden <a href ="/perl/telrate.cgi?from=01&tel0=01&len0=72&oft0=50&dday0=W&tel1=01&len1=%7E72&oft1=50&dday1=W&tab=Tabelle&mix=10&best=30&takt=9999&_3D=on">Gespr&auml;chsmix</a>.
<DT>Takt 60/1</DT>
<DD>Sie zahlen auf jeden Fall die erste Minute, auch wenn sie k&uuml;rzer telefonieren, nach der ersten Minute wird
sekundengenau abgerechnet. </DD>
<DT>Takt <I>n</I>/<I>m</I></DT>
<DD>Allgemein, sie zahlen zumindest <I>n</I> Sekunden, am Ende des Gespr&auml;chs ist der Takt dann <I>m</I> Sekunden.
</DD>
<DT>Variabler Takt</DT>
<DT><span class="in">V</span>ariabler Takt</DT>
<DD>Die Taktl&auml;nge ist nicht konstant, sondern &auml;ndert sich mit der Tageszeit. </DD>
<DT>Zone</DT>
<DT><span class="in">Z</span>one</DT>
<DD>Gebiet mit gleichen Geb&uuml;hren, von Provider zu Provider unterschiedlich. Im Inland verzichten immer mehr
Provider auf eine Unterteilung in Zonen. </DD>
</DL>
@ -100,14 +152,14 @@ Provider auf eine Unterteilung in Zonen. </DD>
</UL>
<IMG SRC="hr.gif" WIDTH="600" HEIGHT="4" ALT="-----">
<P>
<A HREF="/telrate/index.html">Startseite
<IMG WIDTH="80" HSPACE="4" HEIGHT="40" BORDER="0" SRC="/telrate/start.jpg" ALT="Startseite"></A> &nbsp;
<A HREF="/perl/telrate.cgi">Einzelgespr&auml;ch
<IMG WIDTH="80" HSPACE="4" HEIGHT="40" BORDER="0" SRC="/telrate/eg0.jpg" ALT="Einzelgespr&auml;ch"></A> &nbsp;
<A HREF="/perl/telrate.cgi?mix=10">Gespr&auml;chsmix
<IMG WIDTH="80" HSPACE="4" HEIGHT="40" BORDER="0" SRC="/telrate/gm0.jpg" ALT="Gespr&auml;chsmix"></A> &nbsp;
<A HREF="/perl/telrate.cgi?list=1">Providerliste
<IMG WIDTH="80" HSPACE="4" HEIGHT="40" BORDER="0" SRC="/telrate/list0.jpg" ALT="Providerliste"></A> </P>
<A HREF="/telrate/index.html" onmouseover="swap('start',1)" onmouseout="swap('start',0)">Startseite
<IMG WIDTH="80" HSPACE="4" HEIGHT="40" BORDER="0" NAME="start" SRC="/telrate/start0.jpg" ALT="Startseite"></A> &nbsp;
<A HREF="/perl/telrate.cgi" onmouseover="swap('eg',1)" onmouseout="swap('eg',0)">Einzelgespr&auml;ch
<IMG WIDTH="80" HSPACE="4" HEIGHT="40" BORDER="0" NAME="eg" SRC="/telrate/eg0.jpg" ALT="Einzelgespr&auml;ch"></A> &nbsp;
<A HREF="/perl/telrate.cgi?mix=10" onmouseover="swap('gm',1)" onmouseout="swap('gm',0)">Gespr&auml;chsmix
<IMG WIDTH="80" HSPACE="4" HEIGHT="40" BORDER="0" NAME="gm" SRC="/telrate/gm0.jpg" ALT="Gespr&auml;chsmix"></A> &nbsp;
<A HREF="/perl/telrate.cgi?list=1" onmouseover="swap('list',1)" onmouseout="swap('list',0)">Providerliste
<IMG WIDTH="80" HSPACE="4" HEIGHT="40" BORDER="0" NAME="list" SRC="/telrate/list0.jpg" ALT="Providerliste"></A> </P>
</BODY>
</HTML>

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

File diff suppressed because it is too large Load Diff

117
isdnlog/tools/telrate/tt.js Normal file
View File

@ -0,0 +1,117 @@
/*****************************************************************
Tooltips copyright by l.toetsch@magnet.at, http://www.vvg.or.at
if you use this script keep this note
*****************************************************************/
var a,tipEl,tim1=null,left,top;
function moveTo(xPos,yPos) {
this.style.pixelLeft=xPos;
this.style.pixelTop=yPos;
}
function showIt(on) {
if (NS4) {this.visibility = (on) ? "show" : "hide"}
else {this.style.visibility = (on) ? "visible" : "hidden"}
}
function getDocClientWidth() {
if (NS4)
return window.innerWidth;
else
return document.body.clientWidth;
}
function gHeight() {
if (NS4)
return this.document.height;
else
return this.offsetHeight;
}
function gWidth() {
if (NS4)
return this.document.width;
else
return this.offsetWidth;
}
function init_tt() {
for (i=0;i<document.links.length;i++) {
if(gettext(i)=='')
continue;
document.links[i].onmouseover=show;
document.links[i].onmouseout=hide;
document.links[i].num=i;
}
tipEl=IE4?eval(document.all['tip']):eval(document.layers.tip);
if(IE4) tipEl.moveTo=moveTo;
tipEl.showIt=showIt;
tipEl.getHeight=gHeight;
tipEl.getWidth=gWidth;
}
function show(e) {
a=this.num;
if (tim1) clearTimeout(tim1);
left = ((NS4) ? e.pageX : event.clientX+document.body.scrollLeft)+3;
top = ((NS4) ? e.pageY : event.clientY+document.body.scrollTop)-3;
tim1 = setTimeout("disp()", 500);
}
function hide() {
tipEl.showIt(false);
a = null;
if (tim1) clearTimeout(tim1);
}
function max(a,b){return a>b?a:b;}
function min(a,b){return a<b?a:b;}
function gettext(a) {
var i;
//a+' '+document.links[a].href;
for(i=0;i<refs.length;i++)
if(document.links[a].href.indexOf(refs[i])>0)
return txts[i];
return '';
}
function td(pic,w,h)
{ return '<TD><IMG SRC="http://lux.leo.home/telrate/r'+pic+'.gif" WIDTH="'+w+'" HEIGHT="'+h+'"></TD>';}
function disp() {
txt=gettext(a);
if(txt=='')
return;
txt+='<br><p>Klicken Sie f&uuml;r weitere Information!';
show1(0);
if(IE4)
setTimeout("show1(1)",1);
else
show1(1);
}
function show1(i) {
h=0;w=250;e=30;
tab='<TABLE CELLPADDING="0" CELLSPACING="0" border="0"><TR>';
if(i){
h=tipEl.getHeight();
tab+=td("liob",e,e);
tab+=td("ob",w,e)+td("reob",e,e)+'</TR>';
tab+='<TR>'+td("li",e,h);
}
tab+='<TD width="'+w+'" BGCOLOR="#f5f5dc" STYLE="'+sty+'">'+txt+'</TD>';
if(i){
x=getDocClientWidth()-2*e-w-10;y=top-h-2*e;
tab+=td("re",e,h)+'</TR><TR>'+td("liun",e,e);
tab+=td("un",w,e)+td("reun",e,e);
}
tab+='</TR></TABLE>';
if(IE4)
tipEl.innerHTML=tab;
else with(tipEl.document) { open();write(tab);close();}
if(i) {
o=IE4?document.body.scrollTop:window.pageYOffset;
tipEl.moveTo(min(x,left),max(10+o,y));
tipEl.showIt(true);
}
}
if (NS4) {
origWidth = innerWidth;
origHeight = innerHeight;
}
function reDo() {
if (innerWidth != origWidth || innerHeight != origHeight)
// init_tt();
location.reload();
}
if (NS4) window.onresize = reDo;

View File

@ -19,6 +19,12 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log$
* Revision 1.35 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
*
* Revision 1.34 1999/08/29 10:29:15 akool
* isdnlog-3.48
* cosmetics
@ -934,7 +940,19 @@ int iprintf(char *obuf, int chan, register char *fmt, ...)
} /* if */
if (c != '%') {
*op++ = c;
if (c == '\\') {
c = *fmt++;
switch (c) {
case 't':
*op++ = '\t';
break;
default:
*op++ = '\\';
*op++ = c;
}
} else {
*op++ = c;
}
continue;
} /* if */