2 * timestr.c See if a string like 'Su2300-0700' matches (UUCP style).
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2000 The FreeRADIUS server project
21 * Copyright 2000 Alan DeKok <aland@ox.org>
24 static const char rcsid[] = "$Id$";
27 #include "libradius.h"
36 static const char *days[] =
37 { "su", "mo", "tu", "we", "th", "fr", "sa", "wk", "any", "al" };
39 #define DAYMIN (24*60)
40 #define WEEKMIN (24*60*7)
41 #define val(x) (( (x) < 48 || (x) > 57) ? 0 : ((x) - 48))
43 #if 0 /* Set to 1 if you're a developer and want to debug this code */
44 # define timestr_debug DEBUG2
45 # define do_timestr_debug 1
47 # define timestr_debug if (0) printf
53 static int strcode (const char **str)
58 timestr_debug("strcode %s called\n", *str);
60 for (i = 0; i < 10; i++) {
64 if (strncmp(*str, days[i], l) == 0) {
69 timestr_debug("strcode result %d\n", i);
71 return (i >= 10) ? -1 : i;
76 * Fill bitmap with hours/mins.
78 static int hour_fill(char *bitmap, const char *tm)
84 timestr_debug("hour_fill called for %s\n", tm);
87 * Get timerange in start and end.
90 if ((p = strchr(tm, '-')) != NULL) {
92 if (p - tm != 5 || strlen(p) < 4 || !isdigit((int) *p))
94 end = 600 * val(p[0]) + 60 * val(p[1]) + atoi(p + 2);
100 if (strlen(tm) < 4 || !isdigit((int) *tm))
102 start = 600 * val(tm[0]) + 60 * val(tm[1]) + atoi(tm + 2);
103 if (end < 0) end = start;
105 /* Treat 2400 as 0000, and do some more silent error checks. */
106 if (end < 0) end = 0;
107 if (start < 0) start = 0;
108 if (end >= DAYMIN) end = DAYMIN - 1;
109 if (start >= DAYMIN) start = DAYMIN - 1;
111 timestr_debug("hour_fill: range from %d to %d\n", start, end);
120 timestr_debug("setting byte %d, bit %d\n", byte, bit);
121 bitmap[byte] |= (1 << bit);
130 * Call the fill bitmap function for every day listed.
132 static int day_fill(char *bitmap, const char *tm)
138 for (hr = tm; *hr; hr++)
139 if (isdigit((int) *hr))
144 timestr_debug("dayfill: hr %s tm %s\n", hr, tm);
146 while ((start = strcode(&tm)) >= 0) {
148 * Find start and end weekdays and
149 * build a valid range 0 - 6.
153 if ((end = strcode(&tm)) < 0)
166 timestr_debug("day_fill: range from %d to %d\n", start, end);
168 hour_fill(bitmap + 180 * n, hr);
179 * Fill the week bitmap with allowed times.
181 static int week_fill(char *bitmap, char *tm)
186 strncpy(tmp, tm, 128);
188 for (s = tmp; *s; s++)
189 if (isupper(*s)) *s = tolower(*s);
191 s = strtok(tmp, ",|");
194 s = strtok(NULL, ",|");
201 * Match a timestring and return seconds left.
202 * -1 for no match, 0 for unlimited.
204 int timestr_match(char *tmstr, time_t t)
207 char bitmap[WEEKMIN / 8];
210 #ifdef do_timestr_debug
216 tm = localtime_r(&t, &s_tm);
217 now = tm->tm_wday * DAYMIN + tm->tm_hour * 60 + tm->tm_min;
219 memset(bitmap, 0, sizeof(bitmap));
220 week_fill(bitmap, tmstr);
222 #ifdef do_timestr_debug
224 for (i = 0; i < 7; i++) {
225 timestr_debug("%d: ", i);
226 s = bitmap + 180 * i;
227 for (y = 0; y < 23; y++) {
228 s = bitmap + 180 * i + (75 * y) / 10;
229 timestr_debug("%c", memcmp(s, null, 8) == 0 ? '.' : '#');
236 * See how many minutes we have.
242 timestr_debug("READ: checking byte %d bit %d\n", byte, bit);
243 if (!(bitmap[byte] & (1 << bit)))
255 return (i == now) ? 0 : tot;
260 int main(int argc, char **argv)
265 fprintf(stderr, "Usage: test timestring\n");
268 l = timestr_match(argv[1], time(NULL));
269 printf ("%s: %d seconds left\n", argv[1], l);