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 $
42 * last edit-date: [Sat May 13 13:10:09 2006]
44 *---------------------------------------------------------------------------*/
46 static char error[256];
48 static int getrate(int rate_type);
50 #ifdef PARSE_DEBUG_MAIN
60 int main( int argc, char **argv )
63 ret = readrates("/etc/isdn/isdnd.rates");
65 fprintf(stderr, "readrates returns [%d], [%s]\n", ret, error);
72 fprintf(stderr, "readrates returns [%d]\n", ret);
74 for( type=0; type<4; type++ )
76 int unit = getrate( type );
77 fprintf(stderr, "getrate(%d) => %d\n", type, unit );
88 /*---------------------------------------------------------------------------*
90 *---------------------------------------------------------------------------*/
92 readrates(char *filename)
94 char buffer[MAXPATHLEN];
96 struct rates *rt, *ort;
109 if((fp = fopen(filename, "r")) == NULL)
111 snprintf(error, sizeof(error), "error open %s: %s", filename, sys_errlist[errno]);
116 while((fgets(buffer, MAXPATHLEN, fp)) != NULL)
121 if(buffer[0] == '#' || buffer[0] == ' ' ||
122 buffer[0] == '\t' || buffer[0] == '\n')
131 if (*bp == 'r' && *(bp+1) == 'a' && isdigit(*(bp+2)))
133 rateindx = *(bp+2) - '0';
136 /* eat space delimiter */
143 snprintf(error, sizeof(error), "rates: invalid rate type %c%c%c in line %d", *bp, *(bp+1), *(bp+2), line);
146 if (rateindx >= NRATES)
148 snprintf(error, sizeof(error), "rates: invalid rate index %d in line %d", rateindx, line);
154 if(isdigit(*bp) && *bp >= '0' && *bp <= '6')
158 DBGL(DL_RATES, (llog(LL_DBG, "rates: index = %d", indx)));
162 snprintf(error, sizeof(error), "rates: invalid day digit %c in line %d", *bp, line);
166 if(rates[rateindx][indx] == NULL)
168 rt = (struct rates *)malloc(sizeof (struct rates));
171 snprintf(error, sizeof(error), "rates: cannot malloc space for rate structure");
175 rates[rateindx][indx] = rt;
180 /* eat space delimiter */
185 /* now loop to get the rates entries */
189 while(*bp && isdigit(*bp))
202 rt = (struct rates *)malloc(sizeof (struct rates));
205 snprintf(error, sizeof(error), "rates: cannot malloc space2 for rate structure");
214 if(isdigit(*bp) && isdigit(*(bp+1)))
221 snprintf(error, sizeof(error), "rates: start_hr error in line %d", line);
233 snprintf(error, sizeof(error), "rates: no '.' after start_hr in line %d", line);
239 if(isdigit(*bp) && isdigit(*(bp+1)))
246 snprintf(error, sizeof(error), "rates: start_min error in line %d", line);
250 rt->start_time = hour*60 + min;
260 snprintf(error, sizeof(error), "rates: no '-' after start_min in line %d", line);
266 if(isdigit(*bp) && isdigit(*(bp+1)))
273 snprintf(error, sizeof(error), "rates: end_hr error in line %d", line);
285 snprintf(error, sizeof(error), "rates: no '.' after end_hr in line %d", line);
291 if(isdigit(*bp) && isdigit(*(bp+1)))
298 snprintf(error, sizeof(error), "rates: end_min error in line %d", line);
302 /* if hour is 0 assume it means midnight */
305 rt->end_time = hour * 60 + min;
307 if( rt->end_time <= rt->start_time )
309 snprintf(error, sizeof(error), "rates: end_time must be greater then start_time %d", line);
321 snprintf(error, sizeof(error), "rates: no ':' after end_min in line %d", line);
335 snprintf(error, sizeof(error), "rates: first rate digit error in line %d", line);
339 /* eat space delimiter */
347 if(debug_flags & DL_RATES)
349 for (j = 0; j < NRATES; j++)
351 for (i = 0; i < NDAYS; i++)
353 if (rates [j][i] != NULL)
356 for (; rt; rt = rt->next)
358 llog(LL_DBG, "rates: index %d day %d = %d.%2.2d-%d.%2.2d:%d",
359 j, i, rt->start_time/60, rt->start_time%60,
360 rt->end_time/60,rt->end_time%60,rt->rate);
365 llog(LL_DBG, "rates: NO entry for day %d !!\n", i);
380 #ifndef PARSE_DEBUG_MAIN
382 /*---------------------------------------------------------------------------*
383 * get unit length time from configured source
384 *---------------------------------------------------------------------------*/
386 get_current_rate(cfg_entry_t *cep, int logit)
390 switch(cep->unitlengthsrc)
392 case ULSRC_CMDL: /* specified on commandline */
394 llog(LL_CHD, "%05d %s rate %d sec/unit (cmdl)",
395 cep->cdid, cep->name, unit_length);
399 case ULSRC_CONF: /* get it from config file */
401 llog(LL_CHD, "%05d %s rate %d sec/unit (conf)",
402 cep->cdid, cep->name, cep->unitlength);
403 return(cep->unitlength);
405 case ULSRC_RATE: /* get it dynamic from ratesfile*/
406 if(!got_rate) /* got valid rates struct ?? */
409 llog(LL_CHD, "%05d %s rate %d sec/unit (no ratefile)",
410 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
411 return(UNITLENGTH_DEFAULT);
413 if((cep->ratetype >= NRATES) ||
414 (cep->ratetype == INVALID_RATE))
417 llog(LL_CHD, "%05d %s rate %d sec/unit (rate out of range)",
418 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
419 return(UNITLENGTH_DEFAULT);
422 if((rt = getrate(cep->ratetype)) != -1)
425 llog(LL_CHD, "%05d %s rate %d sec/unit (rate)",
426 cep->cdid, cep->name, rt);
431 llog(LL_CHD, "%05d %s rate %d sec/unit (ratescan fail)",
432 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
434 return(UNITLENGTH_DEFAULT);
437 case ULSRC_DYN: /* dynamically calculated from AOC */
438 if((rt = getrate(cep->ratetype)) != -1)
441 llog(LL_CHD, "%05d %s rate %d sec/unit (aocd, rate)",
442 cep->cdid, cep->name, rt);
446 llog(LL_CHD, "%05d %s rate %d sec/unit (aocd, default)",
447 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
449 return(UNITLENGTH_DEFAULT);
454 llog(LL_CHD, "%05d %s rate %d sec/unit (unitlen unknown)",
455 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
457 return(UNITLENGTH_DEFAULT);
461 #endif /* PARSE_DEBUG_MAIN */
464 /*---------------------------------------------------------------------------*
465 * get the currently active rate
466 *---------------------------------------------------------------------------*/
468 getrate(int rate_type )
472 register struct rates *hd;
476 (rate_type >= NRATES) ||
477 (rate_type == INVALID_RATE))
482 time(&now); /* get current time */
484 ptr = localtime(&now);
486 time_now = ptr->tm_hour*60 + ptr->tm_min;
488 /* walk thru the rates for weekday until rate for current time found */
490 for (hd = rates[rate_type][ptr->tm_wday]; hd; hd = hd->next)
492 /* current time within window ? */
493 if((time_now >= hd->start_time ) &&
494 (time_now < hd->end_time ))
496 DBGL(DL_RATES, (llog(LL_DBG, "rate=%d sec/unit (day=%d, beg=%d:%2.2d, end=%d:2.2d, current=%d:%2.2d)",
499 hd->start_time/60, hd->start_time%60,
500 hd->end_time/60, hd->end_time%60,
501 time_now/60, time_now%60)));