Thu Mar 25 12:10:06 2010

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 532 of file pbx_spool.c.

static void __unreg_module ( void   )  [static]

Definition at line 532 of file pbx_spool.c.

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

Definition at line 130 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().

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

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

Definition at line 342 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().

00343 {
00344    struct outgoing *o = data;
00345    int res, reason;
00346    if (!ast_strlen_zero(o->app)) {
00347       if (option_verbose > 2)
00348          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);
00349       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);
00350    } else {
00351       if (option_verbose > 2)
00352          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);
00353       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);
00354    }
00355    if (res) {
00356       ast_log(LOG_NOTICE, "Call failed to go through, reason (%d) %s\n", reason, ast_channel_reason2str(reason));
00357       if (o->retries >= o->maxretries + 1) {
00358          /* Max retries exceeded */
00359          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" : "");
00360          remove_from_queue(o, "Expired");
00361       } else {
00362          /* Notate that the call is still active */
00363          safe_append(o, time(NULL), "EndRetry");
00364       }
00365    } else {
00366       ast_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest);
00367       ast_log(LOG_EVENT, "Queued call to %s/%s completed\n", o->tech, o->dest);
00368       remove_from_queue(o, "Completed");
00369    }
00370    free_outgoing(o);
00371    return NULL;
00372 }

static void free_outgoing ( struct outgoing o  )  [static]

Definition at line 125 of file pbx_spool.c.

References free.

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

00126 {
00127    free(o);
00128 }

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 374 of file pbx_spool.c.

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

Referenced by scan_service().

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

static int load_module ( void   )  [static]

Definition at line 511 of file pbx_spool.c.

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

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

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 293 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.

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

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

Definition at line 266 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().

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

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

Definition at line 388 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().

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

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

Definition at line 442 of file pbx_spool.c.

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

Referenced by load_module().

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

static int unload_module ( void   )  [static]

Definition at line 506 of file pbx_spool.c.

00507 {
00508    return -1;
00509 }


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 532 of file pbx_spool.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 532 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 Thu Mar 25 12:10:06 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7