mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-06 12:36:58 +00:00
Make timing stuff generic (bug #2839)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4213 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -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);
|
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 {
|
struct ast_pbx {
|
||||||
int dtimeout; /* Timeout between digits (seconds) */
|
int dtimeout; /* Timeout between digits (seconds) */
|
||||||
int rtimeout; /* Timeout for response
|
int rtimeout; /* Timeout for response
|
||||||
|
104
pbx.c
104
pbx.c
@@ -85,10 +85,7 @@ struct ast_include {
|
|||||||
char *rname; /* Context to include */
|
char *rname; /* Context to include */
|
||||||
const char *registrar; /* Registrar */
|
const char *registrar; /* Registrar */
|
||||||
int hastime; /* If time construct exists */
|
int hastime; /* If time construct exists */
|
||||||
unsigned int monthmask; /* Mask for month */
|
struct ast_timing timing; /* time construct */
|
||||||
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_include *next; /* Link them together */
|
struct ast_include *next; /* Link them together */
|
||||||
char stuff[0];
|
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)
|
static inline int include_valid(struct ast_include *i)
|
||||||
{
|
{
|
||||||
struct tm tm;
|
|
||||||
time_t t;
|
|
||||||
|
|
||||||
if (!i->hastime)
|
if (!i->hastime)
|
||||||
return 1;
|
return 1;
|
||||||
time(&t);
|
|
||||||
localtime_r(&t,&tm);
|
|
||||||
|
|
||||||
/* If it's not the right month, return */
|
return ast_check_timing(&(i->timing));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pbx_destroy(struct ast_pbx *p)
|
static void pbx_destroy(struct ast_pbx *p)
|
||||||
@@ -3149,7 +3115,7 @@ do { \
|
|||||||
if (*c) { *c = '\0'; c++; } else c = NULL; \
|
if (*c) { *c = '\0'; c++; } else c = NULL; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
static void get_timerange(struct ast_include *i, char *times)
|
static void get_timerange(struct ast_timing *i, char *times)
|
||||||
{
|
{
|
||||||
char *e;
|
char *e;
|
||||||
int x;
|
int x;
|
||||||
@@ -3390,14 +3356,18 @@ static unsigned int get_month(char *mon)
|
|||||||
return mask;
|
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;
|
char *c;
|
||||||
|
|
||||||
/* Check for empty just in case */
|
/* Check for empty just in case */
|
||||||
if (ast_strlen_zero(info))
|
if (ast_strlen_zero(info_in))
|
||||||
return;
|
return 0;
|
||||||
i->hastime = 1;
|
/* 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 */
|
/* Assume everything except time */
|
||||||
i->monthmask = (1 << 12) - 1;
|
i->monthmask = (1 << 12) - 1;
|
||||||
i->daymask = (1 << 30) - 1 + (1 << 30);
|
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);
|
get_timerange(i, info);
|
||||||
info = c;
|
info = c;
|
||||||
if (!info)
|
if (!info)
|
||||||
return;
|
return 1;
|
||||||
FIND_NEXT;
|
FIND_NEXT;
|
||||||
/* Now check for day of week */
|
/* Now check for day of week */
|
||||||
i->dowmask = get_dow(info);
|
i->dowmask = get_dow(info);
|
||||||
|
|
||||||
info = c;
|
info = c;
|
||||||
if (!info)
|
if (!info)
|
||||||
return;
|
return 1;
|
||||||
FIND_NEXT;
|
FIND_NEXT;
|
||||||
/* Now check for the day of the month */
|
/* Now check for the day of the month */
|
||||||
i->daymask = get_day(info);
|
i->daymask = get_day(info);
|
||||||
info = c;
|
info = c;
|
||||||
if (!info)
|
if (!info)
|
||||||
return;
|
return 1;
|
||||||
FIND_NEXT;
|
FIND_NEXT;
|
||||||
/* And finally go for the month */
|
/* And finally go for the month */
|
||||||
i->monthmask = get_month(info);
|
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++;
|
while(*c && (*c != '|')) c++;
|
||||||
/* Process if it's there */
|
/* Process if it's there */
|
||||||
if (*c) {
|
if (*c) {
|
||||||
build_timing(new_include, c+1);
|
new_include->hastime = ast_build_timing(&(new_include->timing), c+1);
|
||||||
*c = '\0';
|
*c = '\0';
|
||||||
}
|
}
|
||||||
new_include->next = NULL;
|
new_include->next = NULL;
|
||||||
@@ -4730,7 +4739,7 @@ static int pbx_builtin_gotoiftime(struct ast_channel *chan, void *data)
|
|||||||
{
|
{
|
||||||
int res=0;
|
int res=0;
|
||||||
char *s, *ts;
|
char *s, *ts;
|
||||||
struct ast_include include;
|
struct ast_timing timing;
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>|<days of week>|<days of month>|<months>?[[context|]extension|]priority\n");
|
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,"?");
|
strsep(&ts,"?");
|
||||||
|
|
||||||
/* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
|
/* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
|
||||||
build_timing(&include, s);
|
if (ast_build_timing(&timing, s) && ast_check_timing(&timing))
|
||||||
if (include_valid(&include))
|
|
||||||
res = pbx_builtin_goto(chan, (void *)ts);
|
res = pbx_builtin_goto(chan, (void *)ts);
|
||||||
free(s);
|
free(s);
|
||||||
return res;
|
return res;
|
||||||
|
Reference in New Issue
Block a user