2 * Copyright (c) 1997 Gary Jennejohn. All rights reserved.
4 * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the author nor the names of any co-contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 * 4. Altered versions must be plainly marked as such, and must not be
19 * misrepresented as being the original software and/or documentation.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 *---------------------------------------------------------------------------
35 * i4b daemon - charging rates description file handling
36 * -----------------------------------------------------
38 * $Id: rates.c,v 1.11 2000/10/09 12:53:29 hm Exp $
40 * $FreeBSD: src/usr.sbin/i4b/isdnd/rates.c,v 1.6.2.2 2001/08/01 17:45:03 obrien Exp $
41 * $DragonFly: src/usr.sbin/i4b/isdnd/rates.c,v 1.4 2004/03/26 01:30:12 cpressey Exp $
43 * last edit-date: [Mon Dec 13 21:48:31 1999]
45 *---------------------------------------------------------------------------*/
47 static char error
[256];
49 static int getrate(int rate_type
);
51 #ifdef PARSE_DEBUG_MAIN
62 main(int argc
, char **argv
)
65 ret
= readrates("/etc/isdn/isdnd.rates");
67 fprintf(stderr
, "readrates returns [%d], [%s]\n", ret
, error
);
74 fprintf(stderr
, "readrates returns [%d]\n", ret
);
76 for( type
=0; type
<4; type
++ )
78 int unit
= getrate( type
);
79 fprintf(stderr
, "getrate(%d) => %d\n", type
, unit
);
90 /*---------------------------------------------------------------------------*
92 *---------------------------------------------------------------------------*/
94 readrates(char *filename
)
96 char buffer
[MAXPATHLEN
];
98 struct rates
*rt
, *ort
;
111 if((fp
= fopen(filename
, "r")) == NULL
)
113 snprintf(error
, sizeof(error
), "error open %s: %s", filename
, sys_errlist
[errno
]);
118 while((fgets(buffer
, MAXPATHLEN
, fp
)) != NULL
)
123 if(buffer
[0] == '#' || buffer
[0] == ' ' ||
124 buffer
[0] == '\t' || buffer
[0] == '\n')
133 if (*bp
== 'r' && *(bp
+1) == 'a' && isdigit(*(bp
+2)))
135 rateindx
= *(bp
+2) - '0';
138 /* eat space delimiter */
145 snprintf(error
, sizeof(error
), "rates: invalid rate type %c%c%c in line %d", *bp
, *(bp
+1), *(bp
+2), line
);
148 if (rateindx
>= NRATES
)
150 snprintf(error
, sizeof(error
), "rates: invalid rate index %d in line %d", rateindx
, line
);
156 if(isdigit(*bp
) && *bp
>= '0' && *bp
<= '6')
160 DBGL(DL_RATES
, (log(LL_DBG
, "rates: index = %d", indx
)));
164 snprintf(error
, sizeof(error
), "rates: invalid day digit %c in line %d", *bp
, line
);
168 if(rates
[rateindx
][indx
] == NULL
)
170 rt
= (struct rates
*)malloc(sizeof (struct rates
));
173 snprintf(error
, sizeof(error
), "rates: cannot malloc space for rate structure");
177 rates
[rateindx
][indx
] = rt
;
182 /* eat space delimiter */
187 /* now loop to get the rates entries */
191 while(*bp
&& isdigit(*bp
))
204 rt
= (struct rates
*)malloc(sizeof (struct rates
));
207 snprintf(error
, sizeof(error
), "rates: cannot malloc space2 for rate structure");
216 if(isdigit(*bp
) && isdigit(*(bp
+1)))
223 snprintf(error
, sizeof(error
), "rates: start_hr error in line %d", line
);
235 snprintf(error
, sizeof(error
), "rates: no '.' after start_hr in line %d", line
);
241 if(isdigit(*bp
) && isdigit(*(bp
+1)))
248 snprintf(error
, sizeof(error
), "rates: start_min error in line %d", line
);
252 rt
->start_time
= hour
*60 + min
;
262 snprintf(error
, sizeof(error
), "rates: no '-' after start_min in line %d", line
);
268 if(isdigit(*bp
) && isdigit(*(bp
+1)))
275 snprintf(error
, sizeof(error
), "rates: end_hr error in line %d", line
);
287 snprintf(error
, sizeof(error
), "rates: no '.' after end_hr in line %d", line
);
293 if(isdigit(*bp
) && isdigit(*(bp
+1)))
300 snprintf(error
, sizeof(error
), "rates: end_min error in line %d", line
);
304 /* if hour is 0 assume it means midnight */
307 rt
->end_time
= hour
* 60 + min
;
309 if( rt
->end_time
<= rt
->start_time
)
311 snprintf(error
, sizeof(error
), "rates: end_time must be greater then start_time %d", line
);
323 snprintf(error
, sizeof(error
), "rates: no ':' after end_min in line %d", line
);
337 snprintf(error
, sizeof(error
), "rates: first rate digit error in line %d", line
);
341 /* eat space delimiter */
349 if(debug_flags
& DL_RATES
)
351 for (j
= 0; j
< NRATES
; j
++)
353 for (i
= 0; i
< NDAYS
; i
++)
355 if (rates
[j
][i
] != NULL
)
358 for (; rt
; rt
= rt
->next
)
360 log(LL_DBG
, "rates: index %d day %d = %d.%2.2d-%d.%2.2d:%d",
361 j
, i
, rt
->start_time
/60, rt
->start_time
%60,
362 rt
->end_time
/60,rt
->end_time
%60,rt
->rate
);
367 log(LL_DBG
, "rates: NO entry for day %d !!\n", i
);
382 #ifndef PARSE_DEBUG_MAIN
384 /*---------------------------------------------------------------------------*
385 * get unit length time from configured source
386 *---------------------------------------------------------------------------*/
388 get_current_rate(cfg_entry_t
*cep
, int logit
)
392 switch(cep
->unitlengthsrc
)
394 case ULSRC_CMDL
: /* specified on commandline */
396 log(LL_CHD
, "%05d %s rate %d sec/unit (cmdl)",
397 cep
->cdid
, cep
->name
, unit_length
);
401 case ULSRC_CONF
: /* get it from config file */
403 log(LL_CHD
, "%05d %s rate %d sec/unit (conf)",
404 cep
->cdid
, cep
->name
, cep
->unitlength
);
405 return(cep
->unitlength
);
407 case ULSRC_RATE
: /* get it dynamic from ratesfile*/
408 if(!got_rate
) /* got valid rates struct ?? */
411 log(LL_CHD
, "%05d %s rate %d sec/unit (no ratefile)",
412 cep
->cdid
, cep
->name
, UNITLENGTH_DEFAULT
);
413 return(UNITLENGTH_DEFAULT
);
415 if((cep
->ratetype
>= NRATES
) ||
416 (cep
->ratetype
== INVALID_RATE
))
419 log(LL_CHD
, "%05d %s rate %d sec/unit (rate out of range)",
420 cep
->cdid
, cep
->name
, UNITLENGTH_DEFAULT
);
421 return(UNITLENGTH_DEFAULT
);
424 if((rt
= getrate(cep
->ratetype
)) != -1)
427 log(LL_CHD
, "%05d %s rate %d sec/unit (rate)",
428 cep
->cdid
, cep
->name
, rt
);
433 log(LL_CHD
, "%05d %s rate %d sec/unit (ratescan fail)",
434 cep
->cdid
, cep
->name
, UNITLENGTH_DEFAULT
);
436 return(UNITLENGTH_DEFAULT
);
439 case ULSRC_DYN
: /* dynamically calculated from AOC */
440 if((rt
= getrate(cep
->ratetype
)) != -1)
443 log(LL_CHD
, "%05d %s rate %d sec/unit (aocd, rate)",
444 cep
->cdid
, cep
->name
, rt
);
448 log(LL_CHD
, "%05d %s rate %d sec/unit (aocd, default)",
449 cep
->cdid
, cep
->name
, UNITLENGTH_DEFAULT
);
451 return(UNITLENGTH_DEFAULT
);
456 log(LL_CHD
, "%05d %s rate %d sec/unit (unitlen unknown)",
457 cep
->cdid
, cep
->name
, UNITLENGTH_DEFAULT
);
459 return(UNITLENGTH_DEFAULT
);
463 #endif /* PARSE_DEBUG_MAIN */
466 /*---------------------------------------------------------------------------*
467 * get the currently active rate
468 *---------------------------------------------------------------------------*/
470 getrate(int rate_type
)
478 (rate_type
>= NRATES
) ||
479 (rate_type
== INVALID_RATE
))
484 time(&now
); /* get current time */
486 ptr
= localtime(&now
);
488 time_now
= ptr
->tm_hour
*60 + ptr
->tm_min
;
490 /* walk thru the rates for weekday until rate for current time found */
492 for (hd
= rates
[rate_type
][ptr
->tm_wday
]; hd
; hd
= hd
->next
)
494 /* current time within window ? */
495 if((time_now
>= hd
->start_time
) &&
496 (time_now
< hd
->end_time
))
498 DBGL(DL_RATES
, (log(LL_DBG
, "rate=%d sec/unit (day=%d, beg=%d:%2.2d, end=%d:2.2d, current=%d:%2.2d)",
501 hd
->start_time
/60, hd
->start_time
%60,
502 hd
->end_time
/60, hd
->end_time
%60,
503 time_now
/60, time_now
%60)));