From da313b1c57fb4c1e31af0459c29de6a0b84ccb35 Mon Sep 17 00:00:00 2001 From: russell Date: Fri, 19 May 2006 22:51:44 +0000 Subject: [PATCH] Make the new behavior where the timestamp is checked on the call file before deleting it optional, defaulting to the old behavior, where it is always deleted (issue #6750, jcollie) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@28832 f38db490-d61c-443f-a65b-d21fe96a405b --- pbx/pbx_spool.c | 35 +++++++++++++++++++++++++++++------ sample.call | 11 +++++++++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/pbx/pbx_spool.c b/pbx/pbx_spool.c index 855001c15..3bab6c1f5 100644 --- a/pbx/pbx_spool.c +++ b/pbx/pbx_spool.c @@ -53,6 +53,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") * The spool file contains a header */ +enum { + /*! Always delete the call file after a call succeeds or the + * maximum number of retries is exceeded, even if the + * modification time of the call file is in the future. + */ + SPOOL_FLAG_ALWAYS_DELETE = (1 << 0) +}; + static char qdir[255]; struct outgoing { @@ -93,6 +101,9 @@ struct outgoing { /* Maximum length of call */ int maxlen; + + /* options */ + struct ast_flags options; }; static void init_outgoing(struct outgoing *o) @@ -101,6 +112,7 @@ static void init_outgoing(struct outgoing *o) o->priority = 1; o->retrytime = 300; o->waittime = 45; + ast_set_flag(&o->options, SPOOL_FLAG_ALWAYS_DELETE); } static void free_outgoing(struct outgoing *o) @@ -214,6 +226,8 @@ static int apply_outgoing(struct outgoing *o, char *fn, FILE *f) ast_log(LOG_WARNING, "Malformed \"%s\" argument. Should be \"%s: variable=value\"\n", buf, buf); } else if (!strcasecmp(buf, "account")) { ast_copy_string(o->account, c, sizeof(o->account)); + } else if (!strcasecmp(buf, "alwaysdelete")) { + ast_set2_flag(&o->options, ast_true(c), SPOOL_FLAG_ALWAYS_DELETE); } else { ast_log(LOG_WARNING, "Unknown keyword '%s' at line %d of %s\n", buf, lineno, fn); } @@ -250,11 +264,23 @@ static void safe_append(struct outgoing *o, time_t now, char *s) } } +static void check_unlink(struct outgoing *o) +{ + if (ast_test_flag(&o->options, SPOOL_FLAG_ALWAYS_DELETE)) + unlink(o->fn); + else { + struct stat current_file_status; + + if (!stat(o->fn, ¤t_file_status)) + if (time(NULL) >= current_file_status.st_mtime) + unlink(o->fn); + } +} + static void *attempt_thread(void *data) { struct outgoing *o = data; int res, reason; - struct stat current_file_status; if (!ast_strlen_zero(o->app)) { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries); @@ -269,7 +295,7 @@ static void *attempt_thread(void *data) if (o->retries >= o->maxretries + 1) { /* Max retries exceeded */ ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt%s\n", o->tech, o->dest, o->retries - 1, ((o->retries - 1) != 1) ? "s" : ""); - unlink(o->fn); + check_unlink(o); } else { /* Notate that the call is still active */ safe_append(o, time(NULL), "EndRetry"); @@ -277,10 +303,7 @@ static void *attempt_thread(void *data) } else { ast_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest); ast_log(LOG_EVENT, "Queued call to %s/%s completed\n", o->tech, o->dest); - if (!stat(o->fn, ¤t_file_status)) { - if (time(NULL) >= current_file_status.st_atime) - unlink(o->fn); - } + check_unlink(o); } free_outgoing(o); return NULL; diff --git a/sample.call b/sample.call index 464af406d..b0a13e7f9 100644 --- a/sample.call +++ b/sample.call @@ -49,6 +49,17 @@ Priority: 1 # #Account: mysuperfunaccountcode +# +# Normally, a call file is always deleted after the call is successful +# or the maximum number of tries is reached even if the modification +# time of the call file was changed during the call to be in the +# future. By Setting AlwaysDelete to No the modification time of the +# call file will be checked after the call is completed or the maximum +# number of retries is reached. If the modification time is in the +# future, the call file will not be deleted. +# +#AlwaysDelete: Yes + # # You can set channel variables that will be passed to the channel. # This includes writable dialplan functions. To set a writable dialplan