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.2 2003/06/17 04:29:54 dillon 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
61 int main( int argc, char **argv )
64 ret = readrates("/etc/isdn/isdnd.rates");
66 fprintf(stderr, "readrates returns [%d], [%s]\n", ret, error);
73 fprintf(stderr, "readrates returns [%d]\n", ret);
75 for( type=0; type<4; type++ )
77 int unit = getrate( type );
78 fprintf(stderr, "getrate(%d) => %d\n", type, unit );
89 /*---------------------------------------------------------------------------*
91 *---------------------------------------------------------------------------*/
93 readrates(char *filename)
95 char buffer[MAXPATHLEN];
97 struct rates *rt, *ort;
110 if((fp = fopen(filename, "r")) == NULL)
112 snprintf(error, sizeof(error), "error open %s: %s", filename, sys_errlist[errno]);
117 while((fgets(buffer, MAXPATHLEN, fp)) != NULL)
122 if(buffer[0] == '#' || buffer[0] == ' ' ||
123 buffer[0] == '\t' || buffer[0] == '\n')
132 if (*bp == 'r' && *(bp+1) == 'a' && isdigit(*(bp+2)))
134 rateindx = *(bp+2) - '0';
137 /* eat space delimiter */
144 snprintf(error, sizeof(error), "rates: invalid rate type %c%c%c in line %d", *bp, *(bp+1), *(bp+2), line);
147 if (rateindx >= NRATES)
149 snprintf(error, sizeof(error), "rates: invalid rate index %d in line %d", rateindx, line);
155 if(isdigit(*bp) && *bp >= '0' && *bp <= '6')
159 DBGL(DL_RATES, (log(LL_DBG, "rates: index = %d", indx)));
163 snprintf(error, sizeof(error), "rates: invalid day digit %c in line %d", *bp, line);
167 if(rates[rateindx][indx] == NULL)
169 rt = (struct rates *)malloc(sizeof (struct rates));
172 snprintf(error, sizeof(error), "rates: cannot malloc space for rate structure");
176 rates[rateindx][indx] = rt;
181 /* eat space delimiter */
186 /* now loop to get the rates entries */
190 while(*bp && isdigit(*bp))
203 rt = (struct rates *)malloc(sizeof (struct rates));
206 snprintf(error, sizeof(error), "rates: cannot malloc space2 for rate structure");
215 if(isdigit(*bp) && isdigit(*(bp+1)))
222 snprintf(error, sizeof(error), "rates: start_hr error in line %d", line);
234 snprintf(error, sizeof(error), "rates: no '.' after start_hr in line %d", line);
240 if(isdigit(*bp) && isdigit(*(bp+1)))
247 snprintf(error, sizeof(error), "rates: start_min error in line %d", line);
251 rt->start_time = hour*60 + min;
261 snprintf(error, sizeof(error), "rates: no '-' after start_min in line %d", line);
267 if(isdigit(*bp) && isdigit(*(bp+1)))
274 snprintf(error, sizeof(error), "rates: end_hr error in line %d", line);
286 snprintf(error, sizeof(error), "rates: no '.' after end_hr in line %d", line);
292 if(isdigit(*bp) && isdigit(*(bp+1)))
299 snprintf(error, sizeof(error), "rates: end_min error in line %d", line);
303 /* if hour is 0 assume it means midnight */
306 rt->end_time = hour * 60 + min;
308 if( rt->end_time <= rt->start_time )
310 snprintf(error, sizeof(error), "rates: end_time must be greater then start_time %d", line);
322 snprintf(error, sizeof(error), "rates: no ':' after end_min in line %d", line);
336 snprintf(error, sizeof(error), "rates: first rate digit error in line %d", line);
340 /* eat space delimiter */
348 if(debug_flags & DL_RATES)
350 for (j = 0; j < NRATES; j++)
352 for (i = 0; i < NDAYS; i++)
354 if (rates [j][i] != NULL)
357 for (; rt; rt = rt->next)
359 log(LL_DBG, "rates: index %d day %d = %d.%2.2d-%d.%2.2d:%d",
360 j, i, rt->start_time/60, rt->start_time%60,
361 rt->end_time/60,rt->end_time%60,rt->rate);
366 log(LL_DBG, "rates: NO entry for day %d !!\n", i);
381 #ifndef PARSE_DEBUG_MAIN
383 /*---------------------------------------------------------------------------*
384 * get unit length time from configured source
385 *---------------------------------------------------------------------------*/
387 get_current_rate(cfg_entry_t *cep, int logit)
391 switch(cep->unitlengthsrc)
393 case ULSRC_CMDL: /* specified on commandline */
395 log(LL_CHD, "%05d %s rate %d sec/unit (cmdl)",
396 cep->cdid, cep->name, unit_length);
400 case ULSRC_CONF: /* get it from config file */
402 log(LL_CHD, "%05d %s rate %d sec/unit (conf)",
403 cep->cdid, cep->name, cep->unitlength);
404 return(cep->unitlength);
406 case ULSRC_RATE: /* get it dynamic from ratesfile*/
407 if(!got_rate) /* got valid rates struct ?? */
410 log(LL_CHD, "%05d %s rate %d sec/unit (no ratefile)",
411 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
412 return(UNITLENGTH_DEFAULT);
414 if((cep->ratetype >= NRATES) ||
415 (cep->ratetype == INVALID_RATE))
418 log(LL_CHD, "%05d %s rate %d sec/unit (rate out of range)",
419 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
420 return(UNITLENGTH_DEFAULT);
423 if((rt = getrate(cep->ratetype)) != -1)
426 log(LL_CHD, "%05d %s rate %d sec/unit (rate)",
427 cep->cdid, cep->name, rt);
432 log(LL_CHD, "%05d %s rate %d sec/unit (ratescan fail)",
433 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
435 return(UNITLENGTH_DEFAULT);
438 case ULSRC_DYN: /* dynamically calculated from AOC */
439 if((rt = getrate(cep->ratetype)) != -1)
442 log(LL_CHD, "%05d %s rate %d sec/unit (aocd, rate)",
443 cep->cdid, cep->name, rt);
447 log(LL_CHD, "%05d %s rate %d sec/unit (aocd, default)",
448 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
450 return(UNITLENGTH_DEFAULT);
455 log(LL_CHD, "%05d %s rate %d sec/unit (unitlen unknown)",
456 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
458 return(UNITLENGTH_DEFAULT);
462 #endif /* PARSE_DEBUG_MAIN */
465 /*---------------------------------------------------------------------------*
466 * get the currently active rate
467 *---------------------------------------------------------------------------*/
469 getrate(int rate_type )
473 register struct rates *hd;
477 (rate_type >= NRATES) ||
478 (rate_type == INVALID_RATE))
483 time(&now); /* get current time */
485 ptr = localtime(&now);
487 time_now = ptr->tm_hour*60 + ptr->tm_min;
489 /* walk thru the rates for weekday until rate for current time found */
491 for (hd = rates[rate_type][ptr->tm_wday]; hd; hd = hd->next)
493 /* current time within window ? */
494 if((time_now >= hd->start_time ) &&
495 (time_now < hd->end_time ))
497 DBGL(DL_RATES, (log(LL_DBG, "rate=%d sec/unit (day=%d, beg=%d:%2.2d, end=%d:2.2d, current=%d:%2.2d)",
500 hd->start_time/60, hd->start_time%60,
501 hd->end_time/60, hd->end_time%60,
502 time_now/60, time_now%60)));