No empty .Rs/.Re
[netbsd-mini2440.git] / usr.sbin / isdn / isdnd / rates.c
blob13c8943c9f2fd3626449ffaea8754bdb564c789d
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.6 2004/10/30 08:19:30 dsl Exp $
40 * $FreeBSD$
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
52 #include <stdio.h>
54 #define MAIN
56 #define ERROR (-1)
58 extern int got_rate;
60 int main( int argc, char **argv )
62 int ret;
63 ret = readrates("/etc/isdn/isdnd.rates");
64 if (ret == ERROR)
65 fprintf(stderr, "readrates returns [%d], [%s]\n", ret, error);
66 else
68 int type = 0;
70 got_rate = 1;
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 );
81 return(ret);
84 #endif
86 #include "isdnd.h"
88 /*---------------------------------------------------------------------------*
89 * parse rates file
90 *---------------------------------------------------------------------------*/
91 int
92 readrates(char *filename)
94 char buffer[MAXPATHLEN];
95 register char *bp;
96 struct rates *rt, *ort;
97 int rateindx;
98 int indx;
99 int line = 0;
100 FILE *fp;
101 int first;
102 #if DEBUG
103 int i, j;
104 #endif
106 indx = 0;
107 rt = ort = NULL;
109 if ((fp = fopen(filename, "r")) == NULL)
111 snprintf(error, sizeof(error), "error open %s: %s", filename, sys_errlist[errno]);
112 rate_error = error;
113 return(WARNING);
116 while((fgets(buffer, MAXPATHLEN, fp)) != NULL)
118 line++;
120 /* comments */
121 if (buffer[0] == '#' || buffer[0] == ' ' ||
122 buffer[0] == '\t' || buffer[0] == '\n')
124 continue;
127 bp = &buffer[0];
129 /* rate type */
131 if (*bp == 'r' && *(bp+1) == 'a' && isdigit((unsigned char)*(bp+2)))
133 rateindx = *(bp+2) - '0';
134 bp += 3;
136 /* eat space delimiter */
138 while(isspace((unsigned char)*bp))
139 bp++;
141 else
143 snprintf(error, sizeof(error), "rates: invalid rate type %c%c%c in line %d", *bp, *(bp+1), *(bp+2), line);
144 goto rate_error;
146 if (rateindx >= NRATES)
148 snprintf(error, sizeof(error), "rates: invalid rate index %d in line %d", rateindx, line);
149 goto rate_error;
152 /* day */
154 if (isdigit((unsigned char)*bp) && *bp >= '0' && *bp <= '6')
156 indx = *bp - '0';
158 DBGL(DL_RATES, (logit(LL_DBG, "rates: index = %d", indx)));
160 else
162 snprintf(error, sizeof(error), "rates: invalid day digit %c in line %d", *bp, line);
163 goto rate_error;
166 if (rates[rateindx][indx] == NULL)
168 rt = (struct rates *)malloc(sizeof (struct rates));
169 if (rt == NULL)
171 snprintf(error, sizeof(error), "rates: cannot malloc space for rate structure");
172 goto rate_error;
174 rt->next = NULL;
175 rates[rateindx][indx] = rt;
178 bp++;
180 /* eat space delimiter */
182 while(isspace((unsigned char)*bp))
183 bp++;
185 /* now loop to get the rates entries */
187 first = 1;
189 while(*bp && isdigit((unsigned char)*bp))
191 int hour = 0;
192 int min = 0;
194 if (first)
196 first = 0;
198 else
200 ort = rt;
202 rt = (struct rates *)malloc(sizeof (struct rates));
203 if (rt == NULL)
205 snprintf(error, sizeof(error), "rates: cannot malloc space2 for rate structure");
206 goto rate_error;
208 ort->next = rt;
209 rt->next = NULL;
212 /* start hour */
214 if (isdigit((unsigned char)*bp) && isdigit((unsigned char)*(bp+1)))
216 hour = atoi(bp);
217 bp += 2;
219 else
221 snprintf(error, sizeof(error), "rates: start_hr error in line %d", line);
222 goto rate_error;
225 /* point */
227 if (*bp == '.')
229 bp++;
231 else
233 snprintf(error, sizeof(error), "rates: no '.' after start_hr in line %d", line);
234 goto rate_error;
237 /* start minute */
239 if (isdigit((unsigned char)*bp) && isdigit((unsigned char)*(bp+1)))
241 min = atoi(bp);
242 bp += 2;
244 else
246 snprintf(error, sizeof(error), "rates: start_min error in line %d", line);
247 goto rate_error;
250 rt->start_time = hour*60 + min;
252 /* minus */
254 if (*bp == '-')
256 bp++;
258 else
260 snprintf(error, sizeof(error), "rates: no '-' after start_min in line %d", line);
261 goto rate_error;
264 /* end hour */
266 if (isdigit((unsigned char)*bp) && isdigit((unsigned char)*(bp+1)))
268 hour = atoi(bp);
269 bp += 2;
271 else
273 snprintf(error, sizeof(error), "rates: end_hr error in line %d", line);
274 goto rate_error;
277 /* point */
279 if (*bp == '.')
281 bp++;
283 else
285 snprintf(error, sizeof(error), "rates: no '.' after end_hr in line %d", line);
286 goto rate_error;
289 /* end minute */
291 if (isdigit((unsigned char)*bp) && isdigit((unsigned char)*(bp+1)))
293 min = atoi(bp);
294 bp += 2;
296 else
298 snprintf(error, sizeof(error), "rates: end_min error in line %d", line);
299 goto rate_error;
302 /* if hour is 0 assume it means midnight */
303 if ( hour == 0 )
304 hour = 24;
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);
310 goto rate_error;
313 /* colon */
315 if (*bp == ':')
317 bp++;
319 else
321 snprintf(error, sizeof(error), "rates: no ':' after end_min in line %d", line);
322 goto rate_error;
325 /* time */
327 if (isdigit((unsigned char)*bp))
329 rt->rate = atoi(bp);
330 while(!isspace((unsigned char)*bp))
331 bp++;
333 else
335 snprintf(error, sizeof(error), "rates: first rate digit error in line %d", line);
336 goto rate_error;
339 /* eat space delimiter */
341 while(isspace((unsigned char)*bp))
342 bp++;
346 #if DEBUG
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)
355 rt = rates [j][i];
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);
363 else
365 logit(LL_DBG, "rates: NO entry for day %d !!\n", i);
370 #endif
371 fclose(fp);
372 return(GOOD);
374 rate_error:
375 fclose(fp);
376 rate_error = error;
377 return(ERROR);
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)
388 int rt;
390 switch (cep->unitlengthsrc)
392 case ULSRC_CMDL: /* specified on commandline */
393 if (dolog)
394 logit(LL_CHD, "%05d %s rate %d sec/unit (cmdl)",
395 cep->cdid, cep->name, unit_length);
396 return(unit_length);
397 break;
399 case ULSRC_CONF: /* get it from config file */
400 if (dolog)
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 ?? */
408 if (dolog)
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))
416 if (dolog)
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)
424 if (dolog)
425 logit(LL_CHD, "%05d %s rate %d sec/unit (rate)",
426 cep->cdid, cep->name, rt);
427 return(rt);
430 if (dolog)
431 logit(LL_CHD, "%05d %s rate %d sec/unit (ratescan fail)",
432 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
434 return(UNITLENGTH_DEFAULT);
435 break;
437 case ULSRC_DYN: /* dynamically calculated from AOC */
438 if ((rt = getrate(cep->ratetype)) != -1)
440 if (dolog)
441 logit(LL_CHD, "%05d %s rate %d sec/unit (aocd, rate)",
442 cep->cdid, cep->name, rt);
443 return(rt);
445 if (dolog)
446 logit(LL_CHD, "%05d %s rate %d sec/unit (aocd, default)",
447 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
449 return(UNITLENGTH_DEFAULT);
450 break;
452 default:
453 if (dolog)
454 logit(LL_CHD, "%05d %s rate %d sec/unit (unitlen unknown)",
455 cep->cdid, cep->name, UNITLENGTH_DEFAULT);
457 return(UNITLENGTH_DEFAULT);
458 break;
461 #endif /* PARSE_DEBUG_MAIN */
464 /*---------------------------------------------------------------------------*
465 * get the currently active rate
466 *---------------------------------------------------------------------------*/
467 static int
468 getrate(int rate_type )
470 struct tm *ptr;
471 time_t now;
472 register struct rates *hd;
473 int time_now;
475 if ((!got_rate) ||
476 (rate_type >= NRATES) ||
477 (rate_type == INVALID_RATE))
479 return -1;
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)",
497 hd->rate,
498 ptr->tm_wday,
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)));
503 return hd->rate;
506 return -1;
509 /* EOF */