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 00: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, (dolog(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 dolog(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 dolog(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 dolog(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 dolog(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 dolog(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 dolog(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 dolog(LL_CHD, "%05d %s rate %d sec/unit (rate)",
428 cep->cdid, cep->name, rt);
433 dolog(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 dolog(LL_CHD, "%05d %s rate %d sec/unit (aocd, rate)",
444 cep->cdid, cep->name, rt);
448 dolog(LL_CHD, "%05d %s rate %d sec/unit (aocd, default)",
449 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
451 return(UNITLENGTH_DEFAULT);
456 dolog(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, (dolog(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)));