24a25
> #include <sys/time.h>
32a34
> #include <ctype.h>
76a79,85
> 	/* Date - Time validity */
> 	int hastime;
> 	unsigned int monthmask;
> 	unsigned int daymask;
> 	unsigned int dowmask;
> 	unsigned int minmask[24];
> 	
81a91,387
> #define FIND_NEXT \
> do { \
> 	c = info; \
> 	while(*c && (*c != '|')) c++; \
> 	if (*c) { *c = '\0'; c++; } else c = NULL; \
> } while(0)
> 
> static void get_timerange(struct outgoing *i, char *times)
> {
> 	char *e;
> 	int x;
> 	int s1, s2;
> 	int e1, e2;
> 
> 	//[PHM 07/01/03]
> 	//start disabling all times, fill the fields with 0's, as they may contain garbage
> 	memset(i->minmask, 0, sizeof(i->minmask));
> 	
> 	/* Star is all times */
> 	if (!strlen(times) || !strcmp(times, "*")) {
> 		for (x=0;x<24;x++)
> 			i->minmask[x] = (1 << 30) - 1;
> 		return;
> 	}
> 	/* Otherwise expect a range */
> 	e = strchr(times, '-');
> 	if (!e) {
> 		ast_log(LOG_WARNING, "Time range is not valid. Assuming no time.\n");
> 		return;
> 	}
> 	*e = '\0';
> 	e++;
> 	while(*e && !isdigit(*e)) e++;
> 	if (!*e) {
> 		ast_log(LOG_WARNING, "Invalid time range.  Assuming no time.\n");
> 		return;
> 	}
> 	if (sscanf(times, "%d:%d", &s1, &s2) != 2) {
> 		ast_log(LOG_WARNING, "%s isn't a time.  Assuming no time.\n", times);
> 		return;
> 	}
> 	if (sscanf(e, "%d:%d", &e1, &e2) != 2) {
> 		ast_log(LOG_WARNING, "%s isn't a time.  Assuming no time.\n", e);
> 		return;
> 	}
> 	s1 = s1 * 30 + s2/2;
> 	if ((s1 < 0) || (s1 >= 24*30)) {
> 		ast_log(LOG_WARNING, "%s isn't a valid star time. Assuming no time.\n", times);
> 		return;
> 	}
> 	e1 = e1 * 30 + e2/2;
> 	if ((e1 < 0) || (e2 >= 24*30)) {
> 		ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times);
> 		return;
> 	}
> 	/* Go through the time and enable each appropriate bit */
> 	for (x=s1;x != e1;x = (x + 1) % (24 * 30)) {
> 		i->minmask[x/30] |= (1 << (x % 30));
> 	}
> 	/* Do the last one */
> 	i->minmask[x/30] |= (1 << (x % 30));
> 	/* All done */
> 	return;
> }
> 
> static char *days[] =
> {
> 	"sun",
> 	"mon",
> 	"tue",
> 	"wed",
> 	"thu",
> 	"fri",
> 	"sat",
> };
> 
> static unsigned int get_dow(char *dow)
> {
> 	char *c;
> 	/* The following line is coincidence, really! */
> 	int s, e, x;
> 	unsigned int mask;
> 	/* Check for all days */
> 	if (!strlen(dow) || !strcmp(dow, "*"))
> 		return (1 << 7) - 1;
> 	/* Get start and ending days */
> 	c = strchr(dow, '-');
> 	if (c) {
> 		*c = '\0';
> 		c++;
> 	} else
> 		c = NULL;
> 	/* Find the start */
> 	s = 0;
> 	while((s < 7) && strcasecmp(dow, days[s])) s++;
> 	if (s >= 7) {
> 		ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", dow);
> 		return 0;
> 	}
> 	if (c) {
> 		e = 0;
> 		while((e < 7) && strcasecmp(c, days[e])) e++;
> 		if (e >= 7) {
> 			ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c);
> 			return 0;
> 		}
> 	} else
> 		e = s;
> 	mask = 0;
> 	for (x=s;x!=e;x = (x + 1) % 7) {
> 		mask |= (1 << x);
> 	}
> 	/* One last one */
> 	mask |= (1 << x);
> 	return mask;
> }
> 
> static unsigned int get_day(char *day)
> {
> 	char *c;
> 	/* The following line is coincidence, really! */
> 	int s, e, x;
> 	unsigned int mask;
> 	/* Check for all days */
> 	if (!strlen(day) || !strcmp(day, "*")) {
> 		mask = (1 << 30)  + ((1 << 30) - 1);
> 		return mask;
> 	}
> 	/* Get start and ending days */
> 	c = strchr(day, '-');
> 	if (c) {
> 		*c = '\0';
> 		c++;
> 	}
> 	/* Find the start */
> 	if (sscanf(day, "%d", &s) != 1) {
> 		ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day);
> 		return 0;
> 	}
> 	if ((s < 1) || (s > 31)) {
> 		ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day);
> 		return 0;
> 	}
> 	s--;
> 	if (c) {
> 		if (sscanf(c, "%d", &e) != 1) {
> 			ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c);
> 			return 0;
> 		}
> 		if ((e < 1) || (e > 31)) {
> 			ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c);
> 			return 0;
> 		}
> 		e--;
> 	} else
> 		e = s;
> 	mask = 0;
> 	for (x=s;x!=e;x = (x + 1) % 31) {
> 		mask |= (1 << x);
> 	}
> 	mask |= (1 << x);
> 	return mask;
> }
> 
> static char *months[] =
> {
> 	"jan",
> 	"feb",
> 	"mar",
> 	"apr",
> 	"may",
> 	"jun",
> 	"jul",
> 	"aug",
> 	"sep",
> 	"oct",
> 	"nov",
> 	"dec",
> };
> 
> static unsigned int get_month(char *mon)
> {
> 	char *c;
> 	/* The following line is coincidence, really! */
> 	int s, e, x;
> 	unsigned int mask;
> 	/* Check for all days */
> 	if (!strlen(mon) || !strcmp(mon, "*")) 
> 		return (1 << 12) - 1;
> 	/* Get start and ending days */
> 	c = strchr(mon, '-');
> 	if (c) {
> 		*c = '\0';
> 		c++;
> 	}
> 	/* Find the start */
> 	s = 0;
> 	while((s < 12) && strcasecmp(mon, months[s])) s++;
> 	if (s >= 12) {
> 		ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", mon);
> 		return 0;
> 	}
> 	if (c) {
> 		e = 0;
> 		while((e < 12) && strcasecmp(mon, months[e])) e++;
> 		if (e >= 12) {
> 			ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", c);
> 			return 0;
> 		}
> 	} else
> 		e = s;
> 	mask = 0;
> 	for (x=s;x!=e;x = (x + 1) % 12) {
> 		mask |= (1 << x);
> 	}
> 	/* One last one */
> 	mask |= (1 << x);
> 	return mask;
> }
> 
> /* check datetime with current time */
> 
> static int date_check(struct outgoing *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;
> }
> 
> /* load the value of data in the struct outgoing */
> 
> static void build_time(struct outgoing *i, char *info)
> {
> 	char *c;
> 	/* Check for empty just in case */
> 	if (!strlen(info))
> 		return;
> 	i->hastime = 1;
> 	/* Assume everything except time */
> 	i->monthmask = (1 << 12) - 1;
> 	i->daymask = (1 << 30) - 1 + (1 << 30);
> 	i->dowmask = (1 << 7) - 1;
> 	/* Avoid using str tok */
> 	FIND_NEXT;
> 	/* Info has the time range, start with that */
> 	get_timerange(i, info);
> 	info = c;
> 	if (!info)
> 		return;
> 	FIND_NEXT;
> 	/* Now check for day of week */
> 	i->dowmask = get_dow(info);
> 	info = c;
> 	if (!info)
> 		return;
> 	FIND_NEXT;
> 	/* Now check for the day of the month */
> 	i->daymask = get_day(info);
> 	info = c;
> 	if (!info)
> 		return;
> 	FIND_NEXT;
> 	/* And finally go for the month */
> 	i->monthmask = get_month(info);
> }
> 
170a477,478
> 					} else if (!strcasecmp(buf, "nochanretry")) {
> 						o->callingpid = 0;
176a485,488
> 					} else if (!strcasecmp(buf, "datetime")) {
> 						c2 = strchr(c, '|');
> 						*c2 = '\0';
> 						build_time(o, c);
205c517
< 			fprintf(f, "%s: %ld %d (%ld)\n", s, (long)ast_mainpid, o->retries, (long) now);
---
> 			fprintf(f, "%s: %d (%ld) (%ld)\n", s, o->retries, (long)ast_mainpid, (long) now);
232c544
< 		if (o->retries >= o->maxretries + 1) {
---
> 		if (o->retries >= o->maxretries + 1 && reason != 0) {
238c550,551
< 			safe_append(o, time(NULL), "EndRetry");
---
> 			if(reason == 0) safe_append(o, time(NULL), "NoChanRetry");
> 			else safe_append(o, time(NULL), "EndRetry");
272c585
< 				printf("Filename: %s, Retries: %d, max: %d\n", fn, o->retries, o->maxretries);
---
> 				printf("Retries: %d, max: %d\n", o->retries, o->maxretries);
286,288c599,609
< 
< 						safe_append(o, now, "StartRetry");
< 						launch_service(o);
---
> 						
> 					 	/* if the datetime is not ok, don't increase the retry and don't try to call */
> 						
> 						if(!date_check(o)) {
> 							ast_log(LOG_NOTICE, "Don't CALL in this Date/Time! (Retry %d)\n",o->retries);
> 							safe_append(o, time(NULL), "NoChanRetry");
> 						} else {
> 							/* Add a retry line at the end */
> 							safe_append(o, now, "StartRetry");
> 							launch_service(o);
> 						}
301d621
< 				fclose(f);
