Sat Aug 6 00:40:02 2011

Asterisk developer's documentation


pbx_spool.c File Reference

Full-featured outgoing call spool support. More...

#include "asterisk.h"
#include <sys/stat.h>
#include <errno.h>
#include <time.h>
#include <utime.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"

Go to the source code of this file.

Data Structures

struct  outgoing

Enumerations

enum  { SPOOL_FLAG_ALWAYS_DELETE = (1 << 0), SPOOL_FLAG_ARCHIVE = (1 << 1) }

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int apply_outgoing (struct outgoing *o, char *fn, FILE *f)
static void * attempt_thread (void *data)
static void free_outgoing (struct outgoing *o)
static void init_outgoing (struct outgoing *o)
static void launch_service (struct outgoing *o)
static int load_module (void)
static int remove_from_queue (struct outgoing *o, const char *status)
 Remove a call file from the outgoing queue optionally moving it in the archive dir.
static void safe_append (struct outgoing *o, time_t now, char *s)
static int scan_service (char *fn, time_t now, time_t atime)
static void * scan_thread (void *unused)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Outgoing Spool Support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, }
static const struct ast_module_infoast_module_info = &__mod_info
static char qdir [255]
static char qdonedir [255]


Detailed Description

Full-featured outgoing call spool support.

Definition in file pbx_spool.c.


Enumeration Type Documentation

anonymous enum

Enumerator:
SPOOL_FLAG_ALWAYS_DELETE  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_ARCHIVE 

Definition at line 57 of file pbx_spool.c.

00057      {
00058    /*! Always delete the call file after a call succeeds or the
00059     * maximum number of retries is exceeded, even if the
00060     * modification time of the call file is in the future.
00061     */
00062    SPOOL_FLAG_ALWAYS_DELETE = (1 << 0),
00063    /* Don't unlink the call file after processing, move in qdonedir */
00064    SPOOL_FLAG_ARCHIVE = (1 << 1)
00065 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 536 of file pbx_spool.c.

static void __unreg_module ( void   )  [static]

Definition at line 536 of file pbx_spool.c.

static int apply_outgoing ( struct outgoing o,
char *  fn,
FILE *  f 
) [static]

Definition at line 133 of file pbx_spool.c.

References outgoing::account, outgoing::app, ast_callerid_split(), ast_copy_string(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_strlen_zero(), ast_true(), ast_variable_new(), outgoing::callingpid, outgoing::cid_name, outgoing::cid_num, outgoing::context, outgoing::data, outgoing::dest, outgoing::exten, outgoing::fn, outgoing::format, last, LOG_NOTICE, LOG_WARNING, outgoing::maxretries, sla_ringing_trunk::next, outgoing::options, outgoing::priority, outgoing::retries, outgoing::retrytime, SPOOL_FLAG_ALWAYS_DELETE, SPOOL_FLAG_ARCHIVE, outgoing::tech, var, outgoing::vars, and outgoing::waittime.

Referenced by scan_service().

00134 {
00135    char buf[256];
00136    char *c, *c2;
00137    int lineno = 0;
00138    struct ast_variable *var, *last = o->vars;
00139 
00140    while (last && last->next) {
00141       last = last->next;
00142    }
00143 
00144    while(fgets(buf, sizeof(buf), f)) {
00145       lineno++;
00146       /* Trim comments */
00147       c = buf;
00148       while ((c = strchr(c, '#'))) {
00149          if ((c == buf) || (*(c-1) == ' ') || (*(c-1) == '\t'))
00150             *c = '\0';
00151          else
00152             c++;
00153       }
00154 
00155       c = buf;
00156       while ((c = strchr(c, ';'))) {
00157          if ((c > buf) && (c[-1] == '\\')) {
00158             memmove(c - 1, c, strlen(c) + 1);
00159             c++;
00160          } else {
00161             *c = '\0';
00162             break;
00163          }
00164       }
00165 
00166       /* Trim trailing white space */
00167       while(!ast_strlen_zero(buf) && buf[strlen(buf) - 1] < 33)
00168          buf[strlen(buf) - 1] = '\0';
00169       if (!ast_strlen_zero(buf)) {
00170          c = strchr(buf, ':');
00171          if (c) {
00172             *c = '\0';
00173             c++;
00174             while ((*c) && (*c < 33))
00175                c++;
00176 #if 0
00177             printf("'%s' is '%s' at line %d\n", buf, c, lineno);
00178 #endif
00179             if (!strcasecmp(buf, "channel")) {
00180                ast_copy_string(o->tech, c, sizeof(o->tech));
00181                if ((c2 = strchr(o->tech, '/'))) {
00182                   *c2 = '\0';
00183                   c2++;
00184                   ast_copy_string(o->dest, c2, sizeof(o->dest));
00185                } else {
00186                   ast_log(LOG_NOTICE, "Channel should be in form Tech/Dest at line %d of %s\n", lineno, fn);
00187                   o->tech[0] = '\0';
00188                }
00189             } else if (!strcasecmp(buf, "callerid")) {
00190                ast_callerid_split(c, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
00191             } else if (!strcasecmp(buf, "application")) {
00192                ast_copy_string(o->app, c, sizeof(o->app));
00193             } else if (!strcasecmp(buf, "data")) {
00194                ast_copy_string(o->data, c, sizeof(o->data));
00195             } else if (!strcasecmp(buf, "maxretries")) {
00196                if (sscanf(c, "%30d", &o->maxretries) != 1) {
00197                   ast_log(LOG_WARNING, "Invalid max retries at line %d of %s\n", lineno, fn);
00198                   o->maxretries = 0;
00199                }
00200             } else if (!strcasecmp(buf, "codecs")) {
00201                ast_parse_allow_disallow(NULL, &o->format, c, 1);
00202             } else if (!strcasecmp(buf, "context")) {
00203                ast_copy_string(o->context, c, sizeof(o->context));
00204             } else if (!strcasecmp(buf, "extension")) {
00205                ast_copy_string(o->exten, c, sizeof(o->exten));
00206             } else if (!strcasecmp(buf, "priority")) {
00207                if ((sscanf(c, "%30d", &o->priority) != 1) || (o->priority < 1)) {
00208                   ast_log(LOG_WARNING, "Invalid priority at line %d of %s\n", lineno, fn);
00209                   o->priority = 1;
00210                }
00211             } else if (!strcasecmp(buf, "retrytime")) {
00212                if ((sscanf(c, "%30d", &o->retrytime) != 1) || (o->retrytime < 1)) {
00213                   ast_log(LOG_WARNING, "Invalid retrytime at line %d of %s\n", lineno, fn);
00214                   o->retrytime = 300;
00215                }
00216             } else if (!strcasecmp(buf, "waittime")) {
00217                if ((sscanf(c, "%30d", &o->waittime) != 1) || (o->waittime < 1)) {
00218                   ast_log(LOG_WARNING, "Invalid waittime at line %d of %s\n", lineno, fn);
00219                   o->waittime = 45;
00220                }
00221             } else if (!strcasecmp(buf, "retry")) {
00222                o->retries++;
00223             } else if (!strcasecmp(buf, "startretry")) {
00224                if (sscanf(c, "%30ld", &o->callingpid) != 1) {
00225                   ast_log(LOG_WARNING, "Unable to retrieve calling PID!\n");
00226                   o->callingpid = 0;
00227                }
00228             } else if (!strcasecmp(buf, "endretry") || !strcasecmp(buf, "abortretry")) {
00229                o->callingpid = 0;
00230                o->retries++;
00231             } else if (!strcasecmp(buf, "delayedretry")) {
00232             } else if (!strcasecmp(buf, "setvar") || !strcasecmp(buf, "set")) {
00233                c2 = c;
00234                strsep(&c2, "=");
00235                if (c2) {
00236                   var = ast_variable_new(c, c2);
00237                   if (var) {
00238                      /* Always insert at the end, because some people want to treat the spool file as a script */
00239                      if (last) {
00240                         last->next = var;
00241                      } else {
00242                         o->vars = var;
00243                      }
00244                      last = var;
00245                   }
00246                } else
00247                   ast_log(LOG_WARNING, "Malformed \"%s\" argument.  Should be \"%s: variable=value\"\n", buf, buf);
00248             } else if (!strcasecmp(buf, "account")) {
00249                ast_copy_string(o->account, c, sizeof(o->account));
00250             } else if (!strcasecmp(buf, "alwaysdelete")) {
00251                ast_set2_flag(&o->options, ast_true(c), SPOOL_FLAG_ALWAYS_DELETE);
00252             } else if (!strcasecmp(buf, "archive")) {
00253                ast_set2_flag(&o->options, ast_true(c), SPOOL_FLAG_ARCHIVE);
00254             } else {
00255                ast_log(LOG_WARNING, "Unknown keyword '%s' at line %d of %s\n", buf, lineno, fn);
00256             }
00257          } else
00258             ast_log(LOG_NOTICE, "Syntax error at line %d of %s\n", lineno, fn);
00259       }
00260    }
00261    ast_copy_string(o->fn, fn, sizeof(o->fn));
00262    if (ast_strlen_zero(o->tech) || ast_strlen_zero(o->dest) || (ast_strlen_zero(o->app) && ast_strlen_zero(o->exten))) {
00263       ast_log(LOG_WARNING, "At least one of app or extension must be specified, along with tech and dest in file %s\n", fn);
00264       return -1;
00265    }
00266    return 0;
00267 }

static void* attempt_thread ( void *  data  )  [static]

Definition at line 345 of file pbx_spool.c.

References outgoing::account, outgoing::app, ast_channel_reason2str(), ast_log(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), ast_verbose(), outgoing::cid_name, outgoing::cid_num, outgoing::context, outgoing::data, outgoing::dest, outgoing::exten, outgoing::format, free_outgoing(), LOG_EVENT, LOG_NOTICE, outgoing::maxretries, option_verbose, outgoing::priority, remove_from_queue(), outgoing::retries, safe_append(), outgoing::tech, outgoing::vars, VERBOSE_PREFIX_3, and outgoing::waittime.

Referenced by launch_service().

00346 {
00347    struct outgoing *o = data;
00348    int res, reason;
00349    if (!ast_strlen_zero(o->app)) {
00350       if (option_verbose > 2)
00351          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);
00352       res = ast_pbx_outgoing_app(o->tech, o->format, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL);
00353    } else {
00354       if (option_verbose > 2)
00355          ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries);
00356       res = ast_pbx_outgoing_exten(o->tech, o->format, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL);
00357    }
00358    o->vars = NULL;
00359    if (res) {
00360       ast_log(LOG_NOTICE, "Call failed to go through, reason (%d) %s\n", reason, ast_channel_reason2str(reason));
00361       if (o->retries >= o->maxretries + 1) {
00362          /* Max retries exceeded */
00363          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" : "");
00364          remove_from_queue(o, "Expired");
00365       } else {
00366          /* Notate that the call is still active */
00367          safe_append(o, time(NULL), "EndRetry");
00368       }
00369    } else {
00370       ast_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest);
00371       ast_log(LOG_EVENT, "Queued call to %s/%s completed\n", o->tech, o->dest);
00372       remove_from_queue(o, "Completed");
00373    }
00374    free_outgoing(o);
00375    return NULL;
00376 }

static void free_outgoing ( struct outgoing o  )  [static]

Definition at line 125 of file pbx_spool.c.

References ast_variables_destroy(), free, and outgoing::vars.

Referenced by attempt_thread(), launch_service(), and scan_service().

00126 {
00127    if (o->vars) {
00128       ast_variables_destroy(o->vars);
00129    }
00130    free(o);
00131 }

static void init_outgoing ( struct outgoing o  )  [static]

Definition at line 115 of file pbx_spool.c.

References AST_FORMAT_SLINEAR, ast_set_flag, outgoing::format, outgoing::options, outgoing::priority, outgoing::retrytime, SPOOL_FLAG_ALWAYS_DELETE, and outgoing::waittime.

Referenced by scan_service().

00116 {
00117    memset(o, 0, sizeof(struct outgoing));
00118    o->priority = 1;
00119    o->retrytime = 300;
00120    o->waittime = 45;
00121    o->format = AST_FORMAT_SLINEAR;
00122    ast_set_flag(&o->options, SPOOL_FLAG_ALWAYS_DELETE);
00123 }

static void launch_service ( struct outgoing o  )  [static]

Definition at line 378 of file pbx_spool.c.

References ast_log(), ast_pthread_create, attempt_thread(), free_outgoing(), LOG_WARNING, and t.

Referenced by scan_service().

00379 {
00380    pthread_t t;
00381    pthread_attr_t attr;
00382    int ret;
00383    pthread_attr_init(&attr);
00384    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00385    if ((ret = ast_pthread_create(&t,&attr,attempt_thread, o)) != 0) {
00386       ast_log(LOG_WARNING, "Unable to create thread :( (returned error: %d)\n", ret);
00387       free_outgoing(o);
00388    }
00389    pthread_attr_destroy(&attr);
00390 }

static int load_module ( void   )  [static]

Definition at line 515 of file pbx_spool.c.

References ast_config_AST_SPOOL_DIR, ast_log(), ast_pthread_create_background, errno, LOG_WARNING, scan_thread(), and thread.

00516 {
00517    pthread_t thread;
00518    pthread_attr_t attr;
00519    int ret;
00520    snprintf(qdir, sizeof(qdir), "%s/%s", ast_config_AST_SPOOL_DIR, "outgoing");
00521    if (mkdir(qdir, 0700) && (errno != EEXIST)) {
00522       ast_log(LOG_WARNING, "Unable to create queue directory %s -- outgoing spool disabled\n", qdir);
00523       return 0;
00524    }
00525    snprintf(qdonedir, sizeof(qdir), "%s/%s", ast_config_AST_SPOOL_DIR, "outgoing_done");
00526    pthread_attr_init(&attr);
00527    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00528    if ((ret = ast_pthread_create_background(&thread,&attr,scan_thread, NULL)) != 0) {
00529       ast_log(LOG_WARNING, "Unable to create thread :( (returned error: %d)\n", ret);
00530       return -1;
00531    }
00532    pthread_attr_destroy(&attr);
00533    return 0;
00534 }

static int remove_from_queue ( struct outgoing o,
const char *  status 
) [static]

Remove a call file from the outgoing queue optionally moving it in the archive dir.

Parameters:
o the pointer to outgoing struct
status the exit status of the call. Can be "Completed", "Failed" or "Expired"

Definition at line 296 of file pbx_spool.c.

References ast_log(), ast_test_flag, errno, f, outgoing::fn, LOG_WARNING, outgoing::options, SPOOL_FLAG_ALWAYS_DELETE, and SPOOL_FLAG_ARCHIVE.

00297 {
00298    int fd;
00299    FILE *f;
00300    char newfn[256];
00301    const char *bname;
00302 
00303    if (!ast_test_flag(&o->options, SPOOL_FLAG_ALWAYS_DELETE)) {
00304       struct stat current_file_status;
00305 
00306       if (!stat(o->fn, &current_file_status))
00307          if (time(NULL) < current_file_status.st_mtime)
00308             return 0;
00309    }
00310 
00311    if (!ast_test_flag(&o->options, SPOOL_FLAG_ARCHIVE)) {
00312       unlink(o->fn);
00313       return 0;
00314    }
00315    if (mkdir(qdonedir, 0700) && (errno != EEXIST)) {
00316       ast_log(LOG_WARNING, "Unable to create queue directory %s -- outgoing spool archiving disabled\n", qdonedir);
00317       unlink(o->fn);
00318       return -1;
00319    }
00320    fd = open(o->fn, O_WRONLY|O_APPEND);
00321    if (fd > -1) {
00322       f = fdopen(fd, "a");
00323       if (f) {
00324          fprintf(f, "Status: %s\n", status);
00325          fclose(f);
00326       } else
00327          close(fd);
00328    }
00329 
00330    bname = strrchr(o->fn,'/');
00331    if (bname == NULL) 
00332       bname = o->fn;
00333    else 
00334       bname++; 
00335    snprintf(newfn, sizeof(newfn), "%s/%s", qdonedir, bname);
00336    /* a existing call file the archive dir is overwritten */
00337    unlink(newfn);
00338    if (rename(o->fn, newfn) != 0) {
00339       unlink(o->fn);
00340       return -1;
00341    } else
00342       return 0;
00343 }

static void safe_append ( struct outgoing o,
time_t  now,
char *  s 
) [static]

Definition at line 269 of file pbx_spool.c.

References ast_log(), ast_mainpid, errno, f, outgoing::fn, LOG_WARNING, outgoing::retries, and outgoing::retrytime.

Referenced by attempt_thread(), and scan_service().

00270 {
00271    int fd;
00272    FILE *f;
00273    struct utimbuf tbuf;
00274    fd = open(o->fn, O_WRONLY|O_APPEND);
00275    if (fd > -1) {
00276       f = fdopen(fd, "a");
00277       if (f) {
00278          fprintf(f, "\n%s: %ld %d (%ld)\n", s, (long)ast_mainpid, o->retries, (long) now);
00279          fclose(f);
00280       } else
00281          close(fd);
00282       /* Update the file time */
00283       tbuf.actime = now;
00284       tbuf.modtime = now + o->retrytime;
00285       if (utime(o->fn, &tbuf))
00286          ast_log(LOG_WARNING, "Unable to set utime on %s: %s\n", o->fn, strerror(errno));
00287    }
00288 }

static int scan_service ( char *  fn,
time_t  now,
time_t  atime 
) [static]

Definition at line 392 of file pbx_spool.c.

References apply_outgoing(), ast_log(), ast_mainpid, errno, f, free_outgoing(), init_outgoing(), launch_service(), LOG_DEBUG, LOG_EVENT, LOG_WARNING, malloc, remove_from_queue(), and safe_append().

Referenced by scan_thread().

00393 {
00394    struct outgoing *o;
00395    FILE *f;
00396    o = malloc(sizeof(struct outgoing));
00397    if (o) {
00398       init_outgoing(o);
00399       f = fopen(fn, "r+");
00400       if (f) {
00401          if (!apply_outgoing(o, fn, f)) {
00402 #if 0
00403             printf("Filename: %s, Retries: %d, max: %d\n", fn, o->retries, o->maxretries);
00404 #endif
00405             fclose(f);
00406             if (o->retries <= o->maxretries) {
00407                now += o->retrytime;
00408                if (o->callingpid && (o->callingpid == ast_mainpid)) {
00409                   safe_append(o, time(NULL), "DelayedRetry");
00410                   ast_log(LOG_DEBUG, "Delaying retry since we're currently running '%s'\n", o->fn);
00411                   free_outgoing(o);
00412                } else {
00413                   /* Increment retries */
00414                   o->retries++;
00415                   /* If someone else was calling, they're presumably gone now
00416                      so abort their retry and continue as we were... */
00417                   if (o->callingpid)
00418                      safe_append(o, time(NULL), "AbortRetry");
00419 
00420                   safe_append(o, now, "StartRetry");
00421                   launch_service(o);
00422                }
00423                return now;
00424             } else {
00425                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" : "");
00426                remove_from_queue(o, "Expired");
00427                free_outgoing(o);
00428                return 0;
00429             }
00430          } else {
00431             ast_log(LOG_WARNING, "Invalid file contents in %s, deleting\n", fn);
00432             fclose(f);
00433             remove_from_queue(o, "Failed");
00434             free_outgoing(o);
00435          }
00436       } else {
00437          ast_log(LOG_WARNING, "Unable to open %s: %s, deleting\n", fn, strerror(errno));
00438          remove_from_queue(o, "Failed");
00439          free_outgoing(o);
00440       }
00441    } else
00442       ast_log(LOG_WARNING, "Out of memory :(\n");
00443    return -1;
00444 }

static void* scan_thread ( void *  unused  )  [static]

Definition at line 446 of file pbx_spool.c.

References ast_fully_booted, ast_log(), errno, last, LOG_WARNING, and scan_service().

Referenced by load_module().

00447 {
00448    struct stat st;
00449    DIR *dir;
00450    struct dirent *de;
00451    char fn[256];
00452    int res;
00453    time_t last = 0, next = 0, now;
00454    struct timespec ts = { .tv_sec = 1 };
00455   
00456    while (!ast_fully_booted) {
00457       nanosleep(&ts, NULL);
00458    }
00459 
00460    for(;;) {
00461       /* Wait a sec */
00462       nanosleep(&ts, NULL);
00463       time(&now);
00464       if (!stat(qdir, &st)) {
00465          if ((st.st_mtime != last) || (next && (now > next))) {
00466 #if 0
00467             printf("atime: %ld, mtime: %ld, ctime: %ld\n", st.st_atime, st.st_mtime, st.st_ctime);
00468             printf("Ooh, something changed / timeout\n");
00469 #endif
00470             next = 0;
00471             last = st.st_mtime;
00472             dir = opendir(qdir);
00473             if (dir) {
00474                while((de = readdir(dir))) {
00475                   snprintf(fn, sizeof(fn), "%s/%s", qdir, de->d_name);
00476                   if (!stat(fn, &st)) {
00477                      if (S_ISREG(st.st_mode)) {
00478                         if (st.st_mtime <= now) {
00479                            res = scan_service(fn, now, st.st_atime);
00480                            if (res > 0) {
00481                               /* Update next service time */
00482                               if (!next || (res < next)) {
00483                                  next = res;
00484                               }
00485                            } else if (res) {
00486                               ast_log(LOG_WARNING, "Failed to scan service '%s'\n", fn);
00487                            } else if (!next) {
00488                               /* Expired entry: must recheck on the next go-around */
00489                               next = st.st_mtime;
00490                            }
00491                         } else {
00492                            /* Update "next" update if necessary */
00493                            if (!next || (st.st_mtime < next))
00494                               next = st.st_mtime;
00495                         }
00496                      }
00497                   } else
00498                      ast_log(LOG_WARNING, "Unable to stat %s: %s\n", fn, strerror(errno));
00499                }
00500                closedir(dir);
00501             } else
00502                ast_log(LOG_WARNING, "Unable to open directory %s: %s\n", qdir, strerror(errno));
00503          }
00504       } else
00505          ast_log(LOG_WARNING, "Unable to stat %s\n", qdir);
00506    }
00507    return NULL;
00508 }

static int unload_module ( void   )  [static]

Definition at line 510 of file pbx_spool.c.

00511 {
00512    return -1;
00513 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Outgoing Spool Support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 536 of file pbx_spool.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 536 of file pbx_spool.c.

char qdir[255] [static]

Definition at line 67 of file pbx_spool.c.

char qdonedir[255] [static]

Definition at line 68 of file pbx_spool.c.


Generated on Sat Aug 6 00:40:02 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7