Clean up pbx_spool. So many nested if statements...

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@74704 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Joshua Colp
2007-07-11 20:40:33 +00:00
parent fde3d4b086
commit 1040d3f64b

View File

@@ -88,8 +88,8 @@ struct outgoing {
char data[256]; char data[256];
/* If extension/context/priority */ /* If extension/context/priority */
char exten[256]; char exten[AST_MAX_EXTENSION];
char context[256]; char context[AST_MAX_CONTEXT];
int priority; int priority;
/* CallerID Information */ /* CallerID Information */
@@ -111,7 +111,6 @@ struct outgoing {
static void init_outgoing(struct outgoing *o) static void init_outgoing(struct outgoing *o)
{ {
memset(o, 0, sizeof(struct outgoing));
o->priority = 1; o->priority = 1;
o->retrytime = 300; o->retrytime = 300;
o->waittime = 45; o->waittime = 45;
@@ -120,7 +119,7 @@ static void init_outgoing(struct outgoing *o)
static void free_outgoing(struct outgoing *o) static void free_outgoing(struct outgoing *o)
{ {
free(o); ast_free(o);
} }
static int apply_outgoing(struct outgoing *o, char *fn, FILE *f) static int apply_outgoing(struct outgoing *o, char *fn, FILE *f)
@@ -253,20 +252,21 @@ static void safe_append(struct outgoing *o, time_t now, char *s)
int fd; int fd;
FILE *f; FILE *f;
struct utimbuf tbuf; struct utimbuf tbuf;
fd = open(o->fn, O_WRONLY|O_APPEND);
if (fd > -1) { if ((fd = open(o->fn, O_WRONLY | O_APPEND)) < 0)
f = fdopen(fd, "a"); return;
if (f) {
fprintf(f, "\n%s: %ld %d (%ld)\n", s, (long)ast_mainpid, o->retries, (long) now); if ((f = fdopen(fd, "a"))) {
fclose(f); fprintf(f, "\n%s: %ld %d (%ld)\n", s, (long)ast_mainpid, o->retries, (long) now);
} else fclose(f);
close(fd); } else
/* Update the file time */ close(fd);
tbuf.actime = now;
tbuf.modtime = now + o->retrytime; /* Update the file time */
if (utime(o->fn, &tbuf)) tbuf.actime = now;
ast_log(LOG_WARNING, "Unable to set utime on %s: %s\n", o->fn, strerror(errno)); tbuf.modtime = now + o->retrytime;
} if (utime(o->fn, &tbuf))
ast_log(LOG_WARNING, "Unable to set utime on %s: %s\n", o->fn, strerror(errno));
} }
/*! /*!
@@ -285,34 +285,34 @@ static int remove_from_queue(struct outgoing *o, const char *status)
if (!ast_test_flag(&o->options, SPOOL_FLAG_ALWAYS_DELETE)) { if (!ast_test_flag(&o->options, SPOOL_FLAG_ALWAYS_DELETE)) {
struct stat current_file_status; struct stat current_file_status;
if (!stat(o->fn, &current_file_status)) if (!stat(o->fn, &current_file_status)) {
if (time(NULL) < current_file_status.st_mtime) if (time(NULL) < current_file_status.st_mtime)
return 0; return 0;
}
} }
if (!ast_test_flag(&o->options, SPOOL_FLAG_ARCHIVE)) { if (!ast_test_flag(&o->options, SPOOL_FLAG_ARCHIVE)) {
unlink(o->fn); unlink(o->fn);
return 0; return 0;
} }
if (ast_mkdir(qdonedir, 0777)) { if (ast_mkdir(qdonedir, 0777)) {
ast_log(LOG_WARNING, "Unable to create queue directory %s -- outgoing spool archiving disabled\n", qdonedir); ast_log(LOG_WARNING, "Unable to create queue directory %s -- outgoing spool archiving disabled\n", qdonedir);
unlink(o->fn); unlink(o->fn);
return -1; return -1;
} }
fd = open(o->fn, O_WRONLY|O_APPEND);
if (fd > -1) { if ((fd = open(o->fn, O_WRONLY | O_APPEND))) {
f = fdopen(fd, "a"); if ((f = fdopen(fd, "a"))) {
if (f) {
fprintf(f, "Status: %s\n", status); fprintf(f, "Status: %s\n", status);
fclose(f); fclose(f);
} else } else
close(fd); close(fd);
} }
bname = strrchr(o->fn,'/'); if (!(bname = strrchr(o->fn, '/')))
if (bname == NULL)
bname = o->fn; bname = o->fn;
else else
bname++; bname++;
snprintf(newfn, sizeof(newfn), "%s/%s", qdonedir, bname); snprintf(newfn, sizeof(newfn), "%s/%s", qdonedir, bname);
/* a existing call file the archive dir is overwritten */ /* a existing call file the archive dir is overwritten */
@@ -369,56 +369,63 @@ static void launch_service(struct outgoing *o)
static int scan_service(char *fn, time_t now, time_t atime) static int scan_service(char *fn, time_t now, time_t atime)
{ {
struct outgoing *o; struct outgoing *o = NULL;
FILE *f; FILE *f;
o = malloc(sizeof(struct outgoing)); int res = 0;
if (o) {
init_outgoing(o);
f = fopen(fn, "r+");
if (f) {
if (!apply_outgoing(o, fn, f)) {
#if 0
printf("Filename: %s, Retries: %d, max: %d\n", fn, o->retries, o->maxretries);
#endif
fclose(f);
if (o->retries <= o->maxretries) {
now += o->retrytime;
if (o->callingpid && (o->callingpid == ast_mainpid)) {
safe_append(o, time(NULL), "DelayedRetry");
ast_log(LOG_DEBUG, "Delaying retry since we're currently running '%s'\n", o->fn);
free_outgoing(o);
} else {
/* Increment retries */
o->retries++;
/* If someone else was calling, they're presumably gone now
so abort their retry and continue as we were... */
if (o->callingpid)
safe_append(o, time(NULL), "AbortRetry");
safe_append(o, now, "StartRetry"); if (!(o = ast_calloc(1, sizeof(*o)))) {
launch_service(o); ast_log(LOG_WARNING, "Out of memory ;(\n");
} return -1;
return now; }
} else {
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" : ""); init_outgoing(o);
remove_from_queue(o, "Expired");
free_outgoing(o); /* Attempt to open the file */
return 0; if (!(f = fopen(fn, "r+"))) {
} remove_from_queue(o, "Failed");
} else { free_outgoing(o);
remove_from_queue(o, "Failed"); ast_log(LOG_WARNING, "Unable to open %s: %s, deleting\n", fn, strerror(errno));
free_outgoing(o); return -1;
ast_log(LOG_WARNING, "Invalid file contents in %s, deleting\n", fn); }
fclose(f);
} /* Read in and verify the contents */
} else { if (apply_outgoing(o, fn, f)) {
remove_from_queue(o, "Failed"); remove_from_queue(o, "Failed");
free_outgoing(o);
ast_log(LOG_WARNING, "Invalid file contents in %s, deleting\n", fn);
fclose(f);
return -1;
}
#if 0
printf("Filename: %s, Retries: %d, max: %d\n", fn, o->retries, o->maxretries);
#endif
fclose(f);
if (o->retries <= o->maxretries) {
now += o->retrytime;
if (o->callingpid && (o->callingpid == ast_mainpid)) {
safe_append(o, time(NULL), "DelayedRetry");
ast_log(LOG_DEBUG, "Delaying retry since we're currently running '%s'\n", o->fn);
free_outgoing(o); free_outgoing(o);
ast_log(LOG_WARNING, "Unable to open %s: %s, deleting\n", fn, strerror(errno)); } else {
/* Increment retries */
o->retries++;
/* If someone else was calling, they're presumably gone now
so abort their retry and continue as we were... */
if (o->callingpid)
safe_append(o, time(NULL), "AbortRetry");
safe_append(o, now, "StartRetry");
launch_service(o);
} }
} else res = now;
ast_log(LOG_WARNING, "Out of memory :(\n"); } else {
return -1; 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" : "");
remove_from_queue(o, "Expired");
free_outgoing(o);
}
return res;
} }
static void *scan_thread(void *unused) static void *scan_thread(void *unused)
@@ -429,48 +436,57 @@ static void *scan_thread(void *unused)
char fn[256]; char fn[256];
int res; int res;
time_t last = 0, next = 0, now; time_t last = 0, next = 0, now;
for(;;) { for(;;) {
/* Wait a sec */ /* Wait a sec */
sleep(1); sleep(1);
time(&now); time(&now);
if (!stat(qdir, &st)) {
if ((st.st_mtime != last) || (next && (now > next))) { if (stat(qdir, &st)) {
#if 0
printf("atime: %ld, mtime: %ld, ctime: %ld\n", st.st_atime, st.st_mtime, st.st_ctime);
printf("Ooh, something changed / timeout\n");
#endif
next = 0;
last = st.st_mtime;
dir = opendir(qdir);
if (dir) {
while((de = readdir(dir))) {
snprintf(fn, sizeof(fn), "%s/%s", qdir, de->d_name);
if (!stat(fn, &st)) {
if (S_ISREG(st.st_mode)) {
if (st.st_mtime <= now) {
res = scan_service(fn, now, st.st_atime);
if (res > 0) {
/* Update next service time */
if (!next || (res < next)) {
next = res;
}
} else if (res)
ast_log(LOG_WARNING, "Failed to scan service '%s'\n", fn);
} else {
/* Update "next" update if necessary */
if (!next || (st.st_mtime < next))
next = st.st_mtime;
}
}
} else
ast_log(LOG_WARNING, "Unable to stat %s: %s\n", fn, strerror(errno));
}
closedir(dir);
} else
ast_log(LOG_WARNING, "Unable to open directory %s: %s\n", qdir, strerror(errno));
}
} else
ast_log(LOG_WARNING, "Unable to stat %s\n", qdir); ast_log(LOG_WARNING, "Unable to stat %s\n", qdir);
continue;
}
/* Make sure it is time for us to execute our check */
if ((st.st_mtime == last) && (next && (next > now)))
continue;
#if 0
printf("atime: %ld, mtime: %ld, ctime: %ld\n", st.st_atime, st.st_mtime, st.st_ctime);
printf("Ooh, something changed / timeout\n");
#endif
next = 0;
last = st.st_mtime;
if (!(dir = opendir(qdir))) {
ast_log(LOG_WARNING, "Unable to open directory %s: %s\n", qdir, strerror(errno));
continue;
}
while ((de = readdir(dir))) {
snprintf(fn, sizeof(fn), "%s/%s", qdir, de->d_name);
if (stat(fn, &st)) {
ast_log(LOG_WARNING, "Unable to stat %s: %s\n", fn, strerror(errno));
continue;
}
if (!S_ISREG(st.st_mode))
continue;
if (st.st_mtime <= now) {
res = scan_service(fn, now, st.st_atime);
if (res > 0) {
/* Update next service time */
if (!next || (res < next)) {
next = res;
}
} else if (res)
ast_log(LOG_WARNING, "Failed to scan service '%s'\n", fn);
} else {
/* Update "next" update if necessary */
if (!next || (st.st_mtime < next))
next = st.st_mtime;
}
}
closedir(dir);
} }
return NULL; return NULL;
} }