Make timing stuff generic (bug #2839)
authorMark Spencer <markster@digium.com>
Thu, 11 Nov 2004 21:23:45 +0000 (21:23 +0000)
committerMark Spencer <markster@digium.com>
Thu, 11 Nov 2004 21:23:45 +0000 (21:23 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4213 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/pbx.h
pbx.c

index ffd20a6..a83df1a 100755 (executable)
@@ -69,6 +69,17 @@ struct ast_switch {
        int (*matchmore)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
 };
 
+struct ast_timing {
+       int hastime;                            /* If time construct exists */
+       unsigned int monthmask;                 /* Mask for month */
+       unsigned int daymask;                   /* Mask for date */
+       unsigned int dowmask;                   /* Mask for day of week (mon-sun) */
+       unsigned int minmask[24];               /* Mask for minute */
+};
+
+extern int ast_build_timing(struct ast_timing *i, char *info);
+extern int ast_check_timing(struct ast_timing *i);
+
 struct ast_pbx {
         int dtimeout;                                   /* Timeout between digits (seconds) */
         int rtimeout;                                   /* Timeout for response
diff --git a/pbx.c b/pbx.c
index de29e10..e353845 100755 (executable)
--- a/pbx.c
+++ b/pbx.c
@@ -85,10 +85,7 @@ struct ast_include {
        char *rname;            /* Context to include */
        const char *registrar;                  /* Registrar */
        int hastime;                            /* If time construct exists */
-       unsigned int monthmask;                 /* Mask for month */
-       unsigned int daymask;                   /* Mask for date */
-       unsigned int dowmask;                   /* Mask for day of week (mon-sun) */
-       unsigned int minmask[24];               /* Mask for minute */
+        struct ast_timing timing;               /* time construct */
        struct ast_include *next;               /* Link them together */
        char stuff[0];
 };
@@ -541,41 +538,10 @@ static struct ast_switch *pbx_findswitch(const char *sw)
 
 static inline int include_valid(struct ast_include *i)
 {
-       struct tm tm;
-       time_t t;
-
        if (!i->hastime)
                return 1;
-       time(&t);
-       localtime_r(&t,&tm);
-
-       /* If it's not the right month, return */
-       if (!(i->monthmask & (1 << tm.tm_mon))) {
-               return 0;
-       }
 
-       /* If it's not that time of the month.... */
-       /* Warning, tm_mday has range 1..31! */
-       if (!(i->daymask & (1 << (tm.tm_mday-1))))
-               return 0;
-
-       /* If it's not the right day of the week */
-       if (!(i->dowmask & (1 << tm.tm_wday)))
-               return 0;
-
-       /* Sanity check the hour just to be safe */
-       if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
-               ast_log(LOG_WARNING, "Insane time...\n");
-               return 0;
-       }
-
-       /* Now the tough part, we calculate if it fits
-          in the right time based on min/hour */
-       if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
-               return 0;
-
-       /* If we got this far, then we're good */
-       return 1;
+       return ast_check_timing(&(i->timing));
 }
 
 static void pbx_destroy(struct ast_pbx *p)
@@ -3149,7 +3115,7 @@ do { \
        if (*c) { *c = '\0'; c++; } else c = NULL; \
 } while(0)
 
-static void get_timerange(struct ast_include *i, char *times)
+static void get_timerange(struct ast_timing *i, char *times)
 {
        char *e;
        int x;
@@ -3390,14 +3356,18 @@ static unsigned int get_month(char *mon)
        return mask;
 }
 
-static void build_timing(struct ast_include *i, char *info)
+int ast_build_timing(struct ast_timing *i, char *info_in)
 {
+        char info_save[256];
+        char *info;
        char *c;
 
        /* Check for empty just in case */
-       if (ast_strlen_zero(info))
-               return;
-       i->hastime = 1;
+       if (ast_strlen_zero(info_in))
+               return 0;
+       /* make a copy just in case we were passed a static string */
+       strncpy(info_save, info_in, sizeof(info_save));
+       info = info_save;
        /* Assume everything except time */
        i->monthmask = (1 << 12) - 1;
        i->daymask = (1 << 30) - 1 + (1 << 30);
@@ -3408,23 +3378,62 @@ static void build_timing(struct ast_include *i, char *info)
        get_timerange(i, info);
        info = c;
        if (!info)
-               return;
+               return 1;
        FIND_NEXT;
        /* Now check for day of week */
        i->dowmask = get_dow(info);
 
        info = c;
        if (!info)
-               return;
+               return 1;
        FIND_NEXT;
        /* Now check for the day of the month */
        i->daymask = get_day(info);
        info = c;
        if (!info)
-               return;
+               return 1;
        FIND_NEXT;
        /* And finally go for the month */
        i->monthmask = get_month(info);
+
+       return 1;
+}
+
+int ast_check_timing(struct ast_timing *i)
+{
+       struct tm tm;
+       time_t t;
+
+       time(&t);
+       localtime_r(&t,&tm);
+
+       /* If it's not the right month, return */
+       if (!(i->monthmask & (1 << tm.tm_mon))) {
+               return 0;
+       }
+
+       /* If it's not that time of the month.... */
+       /* Warning, tm_mday has range 1..31! */
+       if (!(i->daymask & (1 << (tm.tm_mday-1))))
+               return 0;
+
+       /* If it's not the right day of the week */
+       if (!(i->dowmask & (1 << tm.tm_wday)))
+               return 0;
+
+       /* Sanity check the hour just to be safe */
+       if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
+               ast_log(LOG_WARNING, "Insane time...\n");
+               return 0;
+       }
+
+       /* Now the tough part, we calculate if it fits
+          in the right time based on min/hour */
+       if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
+               return 0;
+
+       /* If we got this far, then we're good */
+       return 1;
 }
 
 /*
@@ -3466,7 +3475,7 @@ int ast_context_add_include2(struct ast_context *con, const char *value,
        while(*c && (*c != '|')) c++; 
        /* Process if it's there */
        if (*c) {
-               build_timing(new_include, c+1);
+               new_include->hastime = ast_build_timing(&(new_include->timing), c+1);
                *c = '\0';
        }
        new_include->next      = NULL;
@@ -4730,7 +4739,7 @@ static int pbx_builtin_gotoiftime(struct ast_channel *chan, void *data)
 {
        int res=0;
        char *s, *ts;
-       struct ast_include include;
+       struct ast_timing timing;
 
        if (!data) {
                ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n  <time range>|<days of week>|<days of month>|<months>?[[context|]extension|]priority\n");
@@ -4744,8 +4753,7 @@ static int pbx_builtin_gotoiftime(struct ast_channel *chan, void *data)
        strsep(&ts,"?");
 
        /* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
-       build_timing(&include, s);
-       if (include_valid(&include))
+       if (ast_build_timing(&timing, s) && ast_check_timing(&timing))
                res = pbx_builtin_goto(chan, (void *)ts);
        free(s);
        return res;