More minor IPI work.
[dragonfly/vkernel-mp.git] / usr.sbin / i4b / isdnd / rates.c
blob92a0af8540fceddc23e3d1720b39e6d3a9e319bd
1 /*
2 * Copyright (c) 1997 Gary Jennejohn. All rights reserved.
3 *
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
8 * are met:
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
31 * SUCH DAMAGE.
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
53 #include <stdio.h>
55 #define MAIN
57 #define ERROR (-1)
59 extern int got_rate;
61 int
62 main(int argc, char **argv)
64 int ret;
65 ret = readrates("/etc/isdn/isdnd.rates");
66 if(ret == ERROR)
67 fprintf(stderr, "readrates returns [%d], [%s]\n", ret, error);
68 else
70 int type = 0;
72 got_rate = 1;
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 );
83 return(ret);
86 #endif
88 #include "isdnd.h"
90 /*---------------------------------------------------------------------------*
91 * parse rates file
92 *---------------------------------------------------------------------------*/
93 int
94 readrates(char *filename)
96 char buffer[MAXPATHLEN];
97 char *bp;
98 struct rates *rt, *ort;
99 int rateindx;
100 int indx;
101 int line = 0;
102 FILE *fp;
103 int first;
104 #if DEBUG
105 int i, j;
106 #endif
108 indx = 0;
109 rt = ort = NULL;
111 if((fp = fopen(filename, "r")) == NULL)
113 snprintf(error, sizeof(error), "error open %s: %s", filename, sys_errlist[errno]);
114 rate_error = error;
115 return(WARNING);
118 while((fgets(buffer, MAXPATHLEN, fp)) != NULL)
120 line++;
122 /* comments */
123 if(buffer[0] == '#' || buffer[0] == ' ' ||
124 buffer[0] == '\t' || buffer[0] == '\n')
126 continue;
129 bp = &buffer[0];
131 /* rate type */
133 if (*bp == 'r' && *(bp+1) == 'a' && isdigit(*(bp+2)))
135 rateindx = *(bp+2) - '0';
136 bp += 3;
138 /* eat space delimiter */
140 while(isspace(*bp))
141 bp++;
143 else
145 snprintf(error, sizeof(error), "rates: invalid rate type %c%c%c in line %d", *bp, *(bp+1), *(bp+2), line);
146 goto rate_error;
148 if (rateindx >= NRATES)
150 snprintf(error, sizeof(error), "rates: invalid rate index %d in line %d", rateindx, line);
151 goto rate_error;
154 /* day */
156 if(isdigit(*bp) && *bp >= '0' && *bp <= '6')
158 indx = *bp - '0';
160 DBGL(DL_RATES, (log(LL_DBG, "rates: index = %d", indx)));
162 else
164 snprintf(error, sizeof(error), "rates: invalid day digit %c in line %d", *bp, line);
165 goto rate_error;
168 if(rates[rateindx][indx] == NULL)
170 rt = (struct rates *)malloc(sizeof (struct rates));
171 if (rt == NULL)
173 snprintf(error, sizeof(error), "rates: cannot malloc space for rate structure");
174 goto rate_error;
176 rt->next = NULL;
177 rates[rateindx][indx] = rt;
180 bp++;
182 /* eat space delimiter */
184 while(isspace(*bp))
185 bp++;
187 /* now loop to get the rates entries */
189 first = 1;
191 while(*bp && isdigit(*bp))
193 int hour = 0;
194 int min = 0;
196 if(first)
198 first = 0;
200 else
202 ort = rt;
204 rt = (struct rates *)malloc(sizeof (struct rates));
205 if (rt == NULL)
207 snprintf(error, sizeof(error), "rates: cannot malloc space2 for rate structure");
208 goto rate_error;
210 ort->next = rt;
211 rt->next = NULL;
214 /* start hour */
216 if(isdigit(*bp) && isdigit(*(bp+1)))
218 hour = atoi(bp);
219 bp += 2;
221 else
223 snprintf(error, sizeof(error), "rates: start_hr error in line %d", line);
224 goto rate_error;
227 /* point */
229 if(*bp == '.')
231 bp++;
233 else
235 snprintf(error, sizeof(error), "rates: no '.' after start_hr in line %d", line);
236 goto rate_error;
239 /* start minute */
241 if(isdigit(*bp) && isdigit(*(bp+1)))
243 min = atoi(bp);
244 bp += 2;
246 else
248 snprintf(error, sizeof(error), "rates: start_min error in line %d", line);
249 goto rate_error;
252 rt->start_time = hour*60 + min;
254 /* minus */
256 if(*bp == '-')
258 bp++;
260 else
262 snprintf(error, sizeof(error), "rates: no '-' after start_min in line %d", line);
263 goto rate_error;
266 /* end hour */
268 if(isdigit(*bp) && isdigit(*(bp+1)))
270 hour = atoi(bp);
271 bp += 2;
273 else
275 snprintf(error, sizeof(error), "rates: end_hr error in line %d", line);
276 goto rate_error;
279 /* point */
281 if(*bp == '.')
283 bp++;
285 else
287 snprintf(error, sizeof(error), "rates: no '.' after end_hr in line %d", line);
288 goto rate_error;
291 /* end minute */
293 if(isdigit(*bp) && isdigit(*(bp+1)))
295 min = atoi(bp);
296 bp += 2;
298 else
300 snprintf(error, sizeof(error), "rates: end_min error in line %d", line);
301 goto rate_error;
304 /* if hour is 0 assume it means midnight */
305 if( hour == 0 )
306 hour = 24;
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);
312 goto rate_error;
315 /* colon */
317 if(*bp == ':')
319 bp++;
321 else
323 snprintf(error, sizeof(error), "rates: no ':' after end_min in line %d", line);
324 goto rate_error;
327 /* time */
329 if(isdigit(*bp))
331 rt->rate = atoi(bp);
332 while(!isspace(*bp))
333 bp++;
335 else
337 snprintf(error, sizeof(error), "rates: first rate digit error in line %d", line);
338 goto rate_error;
341 /* eat space delimiter */
343 while(isspace(*bp))
344 bp++;
348 #if DEBUG
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)
357 rt = rates [j][i];
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);
365 else
367 log(LL_DBG, "rates: NO entry for day %d !!\n", i);
372 #endif
373 fclose(fp);
374 return(GOOD);
376 rate_error:
377 fclose(fp);
378 rate_error = error;
379 return(ERROR);
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)
390 int rt;
392 switch(cep->unitlengthsrc)
394 case ULSRC_CMDL: /* specified on commandline */
395 if(logit)
396 log(LL_CHD, "%05d %s rate %d sec/unit (cmdl)",
397 cep->cdid, cep->name, unit_length);
398 return(unit_length);
399 break;
401 case ULSRC_CONF: /* get it from config file */
402 if(logit)
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 ?? */
410 if(logit)
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))
418 if(logit)
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)
426 if(logit)
427 log(LL_CHD, "%05d %s rate %d sec/unit (rate)",
428 cep->cdid, cep->name, rt);
429 return(rt);
432 if(logit)
433 log(LL_CHD, "%05d %s rate %d sec/unit (ratescan fail)",
434 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
436 return(UNITLENGTH_DEFAULT);
437 break;
439 case ULSRC_DYN: /* dynamically calculated from AOC */
440 if((rt = getrate(cep->ratetype)) != -1)
442 if(logit)
443 log(LL_CHD, "%05d %s rate %d sec/unit (aocd, rate)",
444 cep->cdid, cep->name, rt);
445 return(rt);
447 if(logit)
448 log(LL_CHD, "%05d %s rate %d sec/unit (aocd, default)",
449 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
451 return(UNITLENGTH_DEFAULT);
452 break;
454 default:
455 if(logit)
456 log(LL_CHD, "%05d %s rate %d sec/unit (unitlen unknown)",
457 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
459 return(UNITLENGTH_DEFAULT);
460 break;
463 #endif /* PARSE_DEBUG_MAIN */
466 /*---------------------------------------------------------------------------*
467 * get the currently active rate
468 *---------------------------------------------------------------------------*/
469 static int
470 getrate(int rate_type)
472 struct tm *ptr;
473 time_t now;
474 struct rates *hd;
475 int time_now;
477 if((!got_rate) ||
478 (rate_type >= NRATES) ||
479 (rate_type == INVALID_RATE))
481 return -1;
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)",
499 hd->rate,
500 ptr->tm_wday,
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)));
505 return hd->rate;
508 return -1;
511 /* EOF */