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.6 2004/10/30 08:19:30 dsl Exp $
42 * last edit-date: [Mon Dec 13 21:48:31 1999]
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((unsigned char)*(bp
+2)))
133 rateindx
= *(bp
+2) - '0';
136 /* eat space delimiter */
138 while(isspace((unsigned char)*bp
))
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((unsigned char)*bp
) && *bp
>= '0' && *bp
<= '6')
158 DBGL(DL_RATES
, (logit(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 */
182 while(isspace((unsigned char)*bp
))
185 /* now loop to get the rates entries */
189 while(*bp
&& isdigit((unsigned char)*bp
))
202 rt
= (struct rates
*)malloc(sizeof (struct rates
));
205 snprintf(error
, sizeof(error
), "rates: cannot malloc space2 for rate structure");
214 if (isdigit((unsigned char)*bp
) && isdigit((unsigned char)*(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((unsigned char)*bp
) && isdigit((unsigned char)*(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((unsigned char)*bp
) && isdigit((unsigned char)*(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((unsigned char)*bp
) && isdigit((unsigned char)*(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 than start_time %d", line
);
321 snprintf(error
, sizeof(error
), "rates: no ':' after end_min in line %d", line
);
327 if (isdigit((unsigned char)*bp
))
330 while(!isspace((unsigned char)*bp
))
335 snprintf(error
, sizeof(error
), "rates: first rate digit error in line %d", line
);
339 /* eat space delimiter */
341 while(isspace((unsigned char)*bp
))
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 logit(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 logit(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(struct cfg_entry
*cep
, int dolog
)
390 switch (cep
->unitlengthsrc
)
392 case ULSRC_CMDL
: /* specified on commandline */
394 logit(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 logit(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 logit(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 logit(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 logit(LL_CHD
, "%05d %s rate %d sec/unit (rate)",
426 cep
->cdid
, cep
->name
, rt
);
431 logit(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 logit(LL_CHD
, "%05d %s rate %d sec/unit (aocd, rate)",
442 cep
->cdid
, cep
->name
, rt
);
446 logit(LL_CHD
, "%05d %s rate %d sec/unit (aocd, default)",
447 cep
->cdid
, cep
->name
, UNITLENGTH_DEFAULT
);
449 return(UNITLENGTH_DEFAULT
);
454 logit(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
, (logit(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)));