Version 0.3.0 from FTP

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@593 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Mark Spencer 23 years ago
parent 60c5f7a1fb
commit 63ff352808

104
app.c

@ -19,9 +19,15 @@
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <asterisk/channel.h>
#include <asterisk/file.h>
#include <asterisk/app.h>
#include <asterisk/dsp.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include "asterisk.h"
#include "astconf.h"
/* set timeout to 0 for "standard" timeouts. Set timeout to -1 for
"ludicrous time" (essentially never times out) */
@ -41,3 +47,101 @@ int ast_app_getdata(struct ast_channel *c, char *prompt, char *s, int maxlen, in
return res;
}
int ast_app_getvoice(struct ast_channel *c, char *dest, char *dstfmt, char *prompt, int silence, int maxsec)
{
int res;
struct ast_filestream *writer;
int rfmt;
int totalms, total;
struct ast_frame *f;
struct ast_dsp *sildet;
/* Play prompt if requested */
if (prompt) {
res = ast_streamfile(c, prompt, c->language);
if (res < 0)
return res;
res = ast_waitstream(c,"");
if (res < 0)
return res;
}
rfmt = c->readformat;
res = ast_set_read_format(c, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
return -1;
}
sildet = ast_dsp_new();
if (!sildet) {
ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
return -1;
}
writer = ast_writefile(dest, dstfmt, "Voice file", 0, 0, 0666);
if (!writer) {
ast_log(LOG_WARNING, "Unable to open file '%s' in format '%s' for writing\n", dest, dstfmt);
ast_dsp_free(sildet);
return -1;
}
for(;;) {
if ((res = ast_waitfor(c, 2000)) < 0) {
ast_log(LOG_NOTICE, "Waitfor failed while recording file '%s' format '%s'\n", dest, dstfmt);
break;
}
if (res) {
f = ast_read(c);
if (!f) {
ast_log(LOG_NOTICE, "Hungup while recording file '%s' format '%s'\n", dest, dstfmt);
break;
}
if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
/* Ended happily with DTMF */
ast_frfree(f);
break;
} else if (f->frametype == AST_FRAME_VOICE) {
ast_dsp_silence(sildet, f, &total);
if (total > silence) {
/* Ended happily with silence */
ast_frfree(f);
break;
}
totalms += f->samples / 8;
if (totalms > maxsec * 1000) {
/* Ended happily with too much stuff */
ast_log(LOG_NOTICE, "Constraining voice on '%s' to %d seconds\n", c->name, maxsec);
ast_frfree(f);
break;
}
}
ast_frfree(f);
}
}
res = ast_set_read_format(c, rfmt);
if (res)
ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", c->name);
ast_dsp_free(sildet);
ast_closestream(writer);
return 0;
}
int ast_app_has_voicemail(char *mailbox)
{
DIR *dir;
struct dirent *de;
char fn[256];
/* If no mailbox, return immediately */
if (!strlen(mailbox))
return 0;
snprintf(fn, sizeof(fn), "%s/vm/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, mailbox);
dir = opendir(fn);
if (!dir)
return 0;
while ((de = readdir(dir))) {
if (!strncasecmp(de->d_name, "msg", 3))
break;
}
closedir(dir);
if (de)
return 1;
return 0;
}

@ -25,6 +25,7 @@
#include <pthread.h>
#include <stdio.h>
#include "../asterisk.h"
#include "../astconf.h"
static char *tdesc = "Extension Directory";
static char *app = "Directory";
@ -127,13 +128,12 @@ static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *
struct ast_variable *v;
int res;
int found=0;
char *start, *pos, *conv;
char *start, *pos, *conv,*stringp=NULL;
char fn[256];
memset(ext, 0, sizeof(ext));
ext[0] = digit;
res = 0;
if (ast_readstring(chan, ext + 1, NUMDIGITS - 1, 3000, 3000, "#") < 0) res = -1;
printf("Res: %d, ext: %s\n", res, ext);
if (!res) {
/* Search for all names which start with those digits */
v = ast_variable_browse(cfg, context);
@ -143,8 +143,9 @@ static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *
/* Find a candidate extension */
start = strdup(v->value);
if (start) {
strtok(start, ",");
pos = strtok(NULL, ",");
stringp=start;
strsep(&stringp, ",");
pos = strsep(&stringp, ",");
if (pos) {
/* Grab the last name */
if (strrchr(pos, ' '))
@ -167,7 +168,7 @@ static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *
}
if (v) {
/* We have a match -- play a greeting if they have it */
snprintf(fn, sizeof(fn), "%s/vm/%s/greet", AST_SPOOL_DIR, v->name);
snprintf(fn, sizeof(fn), "%s/vm/%s/greet", (char *)ast_config_AST_SPOOL_DIR, v->name);
if (ast_fileexists(fn, NULL, chan->language) > 0) {
res = ast_streamfile(chan, fn, chan->language);
if (!res)

@ -71,8 +71,9 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/file.h>
#include "../astconf.h"
const char *qdir="/var/spool/asterisk/qcall";
char qdir[255];
static char *tdesc = "Call from Queue";
static pthread_t qcall_thread;
static int debug = 0;
@ -132,7 +133,7 @@ pthread_attr_t attr;
/* if not a regular file, skip it */
if ((mystat.st_mode & S_IFMT) != S_IFREG) continue;
/* if not yet .... */
if (mystat.st_atime == mystat.st_ctime)
if (mystat.st_atime == mystat.st_mtime)
{ /* first time */
if ((mystat.st_atime + INITIALONE) > t)
continue;
@ -361,6 +362,7 @@ int unload_module(void)
int load_module(void)
{
snprintf((char *)qdir,sizeof(qdir)-1,"%s/%s",(char *)ast_config_AST_SPOOL_DIR,"qcall");
mkdir(qdir,0660);
pthread_create(&qcall_thread,NULL,qcall,NULL);
return 0;

@ -21,6 +21,7 @@
#include <asterisk/say.h>
#include <asterisk/module.h>
#include <asterisk/adsi.h>
#include <asterisk/app.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
@ -33,6 +34,7 @@
#include <pthread.h>
#include "../asterisk.h"
#include "../astconf.h"
#define COMMAND_TIMEOUT 5000
@ -95,8 +97,10 @@ static char *synopsis_vmain =
"Enter voicemail system";
static char *descrip_vmain =
" VoiceMailMain(): Enters the main voicemail system for the checking of voicemail. Returns\n"
" -1 if the user hangs up or 0 otherwise.\n";
" VoiceMailMain(): Enters the main voicemail system for the checking of voicemail. The mailbox\n"
"can be passed as the option, which will stop the voicemail system from prompting the user\n"
"for the mailbox. If the mailbox is preceeded by 's' then the passsword check will be skipped.\n"
"Returns -1 if the user hangs up or 0 otherwise.\n";
/* Leave a message */
static char *app = "VoiceMail";
@ -110,7 +114,7 @@ LOCAL_USER_DECL;
static int make_dir(char *dest, int len, char *ext, char *mailbox)
{
return snprintf(dest, len, "%s/%s/%s", VM_SPOOL_DIR, ext, mailbox);
return snprintf(dest, len, "%s/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR,"vm", ext, mailbox);
}
static int make_file(char *dest, int len, char *dir, int num)
@ -127,9 +131,13 @@ static int vm_change_password(char *username, char *password, char *newpassword)
FILE *configout;
char inbuf[256];
char orig[256];
char tmpin[AST_CONFIG_MAX_PATH];
char tmpout[AST_CONFIG_MAX_PATH];
char *user, *pass, *rest, *trim;
configin = fopen("/etc/asterisk/voicemail.conf","r");
configout = fopen("/etc/asterisk/voicemail.conf.new","w+");
snprintf((char *)tmpin, sizeof(tmpin)-1, "%s/voicemail.conf",(char *)ast_config_AST_CONFIG_DIR);
snprintf((char *)tmpout, sizeof(tmpout)-1, "%s/voicemail.conf.new",(char *)ast_config_AST_CONFIG_DIR);
configin = fopen((char *)tmpin,"r");
configout = fopen((char *)tmpout,"w+");
while (!feof(configin)) {
/* Read in the line */
@ -185,38 +193,11 @@ static int vm_change_password(char *username, char *password, char *newpassword)
fclose(configin);
fclose(configout);
unlink("/etc/asterisk/voicemail.conf");
rename("/etc/asterisk/voicemail.conf.new","/etc/asterisk/voicemail.conf");
unlink((char *)tmpin);
rename((char *)tmpout,(char *)tmpin);
return(1);
}
#if 0
static int announce_message(struct ast_channel *chan, char *dir, int msgcnt)
{
char *fn;
int res;
res = ast_streamfile(chan, "vm-message", chan->language);
if (!res) {
res = ast_waitstream(chan, AST_DIGIT_ANY);
if (!res) {
res = ast_say_number(chan, msgcnt+1, chan->language);
if (!res) {
fn = get_fn(dir, msgcnt);
if (fn) {
res = ast_streamfile(chan, fn, chan->language);
free(fn);
}
}
}
}
if (res < 0)
ast_log(LOG_WARNING, "Unable to announce message\n");
return res;
}
#endif
static int
inbuf(FILE *fi)
{
@ -351,13 +332,17 @@ static int sendmail(char *srcemail, char *email, char *name, int msgnum, char *m
char dur[256];
time_t t;
struct tm *tm;
char *astattach;
struct ast_config *cfg;
p = popen(SENDMAIL, "w");
cfg = ast_load(VOICEMAIL_CONFIG);
if (!(astattach = ast_variable_retrieve(cfg, "general", "attach")))
astattach = "yes";
if (p) {
gethostname(host, sizeof(host));
if (strchr(srcemail, '@'))
strncpy(who, srcemail, sizeof(who)-1);
else {
gethostname(host, sizeof(host));
snprintf(who, sizeof(who), "%s@%s", srcemail, host);
}
snprintf(dur, sizeof(dur), "%ld:%02ld", duration / 60, duration % 60);
@ -370,30 +355,32 @@ static int sendmail(char *srcemail, char *email, char *name, int msgnum, char *m
fprintf(p, "Subject: [PBX]: New message %d in mailbox %s\n", msgnum, mailbox);
fprintf(p, "Message-ID: <Asterisk-%d-%s-%d@%s>\n", msgnum, mailbox, getpid(), host);
fprintf(p, "MIME-Version: 1.0\n");
if (ast_true(astattach)) {
// Something unique.
snprintf(bound, sizeof(bound), "Boundary=%d%s%d", msgnum, mailbox, getpid());
// Something unique.
snprintf(bound, sizeof(bound), "Boundary=%d%s%d", msgnum, mailbox, getpid());
fprintf(p, "Content-Type: MULTIPART/MIXED; BOUNDARY=\"%s\"\n\n\n", bound);
fprintf(p, "Content-Type: MULTIPART/MIXED; BOUNDARY=\"%s\"\n\n\n", bound);
fprintf(p, "--%s\n", bound);
fprintf(p, "Content-Type: TEXT/PLAIN; charset=US-ASCII\n\n");
strftime(date, sizeof(date), "%A, %B %d, %Y at %r", tm);
fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message (number %d)\n"
fprintf(p, "--%s\n", bound);
}
fprintf(p, "Content-Type: TEXT/PLAIN; charset=US-ASCII\n\n");
strftime(date, sizeof(date), "%A, %B %d, %Y at %r", tm);
fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message (number %d)\n"
"in mailbox %s from %s, on %s so you might\n"
"want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", name,
dur, msgnum, mailbox, (callerid ? callerid : "an unknown caller"), date);
fprintf(p, "--%s\n", bound);
fprintf(p, "Content-Type: audio/x-wav; name=\"msg%04d\"\n", msgnum);
fprintf(p, "Content-Transfer-Encoding: BASE64\n");
fprintf(p, "Content-Description: Voicemail sound attachment.\n");
fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"\n\n", msgnum, format);
snprintf(fname, sizeof(fname), "%s.%s", attach, format);
base_encode(fname, p);
fprintf(p, "\n\n--%s--\n.\n", bound);
dur, msgnum, mailbox, (callerid ? callerid : "an unknown caller"), date);
if (ast_true(astattach)) {
fprintf(p, "--%s\n", bound);
fprintf(p, "Content-Type: audio/x-wav; name=\"msg%04d.%s\"\n", msgnum, format);
fprintf(p, "Content-Transfer-Encoding: BASE64\n");
fprintf(p, "Content-Description: Voicemail sound attachment.\n");
fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"\n\n", msgnum, format);
snprintf(fname, sizeof(fname), "%s.%s", attach, format);
base_encode(fname, p);
fprintf(p, "\n\n--%s--\n.\n", bound);
}
pclose(p);
} else {
ast_log(LOG_WARNING, "Unable to launch '%s'\n", SENDMAIL);
@ -411,7 +398,7 @@ static int get_date(char *s, int len)
return strftime(s, len, "%a %b %e %r %Z %Y", tm);
}
static int invent_message(struct ast_channel *chan, char *ext, int busy)
static int invent_message(struct ast_channel *chan, char *ext, int busy, char *ecodes)
{
int res;
char fn[256];
@ -420,17 +407,17 @@ static int invent_message(struct ast_channel *chan, char *ext, int busy)
res = ast_streamfile(chan, fn, chan->language);
if (res)
return -1;
res = ast_waitstream(chan, "#");
res = ast_waitstream(chan, ecodes);
if (res)
return res;
} else {
res = ast_streamfile(chan, "vm-theperson", chan->language);
if (res)
return -1;
res = ast_waitstream(chan, "#");
res = ast_waitstream(chan, ecodes);
if (res)
return res;
res = ast_say_digit_str(chan, ext, "#", chan->language);
res = ast_say_digit_str(chan, ext, ecodes, chan->language);
if (res)
return res;
}
@ -440,7 +427,7 @@ static int invent_message(struct ast_channel *chan, char *ext, int busy)
res = ast_streamfile(chan, "vm-isunavail", chan->language);
if (res)
return -1;
res = ast_waitstream(chan, "#");
res = ast_waitstream(chan, ecodes);
return res;
}
@ -457,12 +444,15 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
int msgnum;
int outmsg=0;
int wavother=0;
int maxmessage=0;
struct ast_frame *f;
char date[256];
char dir[256];
char fn[256];
char prefile[256]="";
char *astemail;
char *ecodes = "#";
char *s;
time_t start;
time_t end;
@ -473,7 +463,15 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
}
if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail")))
astemail = ASTERISK_USERNAME;
if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
if (sscanf(s, "%d", &x) == 1) {
maxmessage = x;
} else {
ast_log(LOG_WARNING, "Invalid max message time length\n");
}
}
if ((copy = ast_variable_retrieve(cfg, NULL, ext))) {
char *stringp=NULL;
/* Setup pre-file if appropriate */
if (busy)
snprintf(prefile, sizeof(prefile), "vm/%s/busy", ext);
@ -481,9 +479,10 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
snprintf(prefile, sizeof(prefile), "vm/%s/unavail", ext);
/* Make sure they have an entry in the config */
copy = strdup(copy);
passwd = strtok(copy, ",");
name = strtok(NULL, ",");
email = strtok(NULL, ",");
stringp=copy;
passwd = strsep(&stringp, ",");
name = strsep(&stringp, ",");
email = strsep(&stringp, ",");
make_dir(dir, sizeof(dir), ext, "");
/* It's easier just to try to make it than to check for its existence */
if (mkdir(dir, 0700) && (errno != EEXIST))
@ -491,14 +490,16 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
make_dir(dir, sizeof(dir), ext, "INBOX");
if (mkdir(dir, 0700) && (errno != EEXIST))
ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno));
if (ast_exists_extension(chan, chan->context, "o", 1, chan->callerid))
ecodes = "#0";
/* Play the beginning intro if desired */
if (strlen(prefile)) {
if (ast_fileexists(prefile, NULL, NULL) > 0) {
if (ast_streamfile(chan, prefile, chan->language) > -1)
silent = ast_waitstream(chan, "#");
silent = ast_waitstream(chan, "#0");
} else {
ast_log(LOG_DEBUG, "%s doesn't exist, doing what we can\n", prefile);
silent = invent_message(chan, ext, busy);
silent = invent_message(chan, ext, busy, ecodes);
}
if (silent < 0) {
ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
@ -515,15 +516,29 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
free(copy);
return -1;
}
} else if (silent == '0') {
strncpy(chan->exten, "0", sizeof(chan->exten) - 1);
chan->priority = 0;
free(copy);
return 0;
}
/* Stream an info message */
if (silent || !ast_streamfile(chan, INTRO, chan->language)) {
/* Wait for the message to finish */
if (silent || !ast_waitstream(chan, "")) {
if (!ast_streamfile(chan, "beep", chan->language) < 0)
silent = 1;
if (ast_waitstream(chan, "") <0) {
ast_log(LOG_DEBUG, "Hangup during beep\n");
free(copy);
return -1;
}
fmt = ast_variable_retrieve(cfg, "general", "format");
if (fmt) {
char *stringp=NULL;
fmts = strdup(fmt);
fmt = strtok(fmts, "|");
stringp=fmts;
fmt = strsep(&stringp, "|");
msgnum = 0;
do {
make_file(fn, sizeof(fn), dir, msgnum);
@ -540,6 +555,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
msgnum++;
} while(!writer && (msgnum < MAXMSG));
if (writer) {
char *stringp=NULL;
/* Store information */
snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
txt = fopen(txtfile, "w+");
@ -573,8 +589,9 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
free(fmts);
fmt = ast_variable_retrieve(cfg, "general", "format");
fmts = strdup(fmt);
strtok(fmts, "|");
while((fmt = strtok(NULL, "|"))) {
stringp=fmts;
strsep(&stringp, "|");
while((fmt = strsep(&stringp, "|"))) {
if (fmtcnt > MAX_OTHER_FORMATS - 1) {
ast_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app_voicemail.c\n");
break;
@ -604,8 +621,13 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
for(;;) {
res = ast_waitfor(chan, 2000);
if (!res) {
ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name);
res = -1;
ast_log(LOG_DEBUG, "One waitfor failed, trying another\n");
/* Try one more time in case of masq */
res = ast_waitfor(chan, 2000);
if (!res) {
ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name);
res = -1;
}
}
if (res < 0) {
@ -639,10 +661,19 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
ast_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
outmsg=2;
ast_frfree(f);
res = 0;
break;
}
}
ast_frfree(f);
time(&end);
if (maxmessage && (end - start > maxmessage)) {
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Message is too long, ending it now...\n");
outmsg = 2;
res = 0;
break;
}
}
if (!f) {
if (option_verbose > 2)
@ -674,6 +705,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
fclose(txt);
}
/* Send e-mail if applicable */
if (email)
sendmail(astemail, email, name, msgnum, ext, chan->callerid, fn, wavother ? "wav" : fmts, end - start);
}
} else {
@ -1069,8 +1101,10 @@ static void adsi_message(struct ast_channel *chan, char *folder, int msg, int la
while(!feof(f)) {
fgets(buf, sizeof(buf), f);
if (!feof(f)) {
strtok(buf, "=");
val = strtok(NULL, "=");
char *stringp=NULL;
stringp=buf;
strsep(&stringp, "=");
val = strsep(&stringp, "=");
if (val && strlen(val)) {
if (!strcmp(buf, "callerid"))
strncpy(cid, val, sizeof(cid) - 1);
@ -1326,7 +1360,7 @@ forward_message(struct ast_channel *chan, struct ast_config *cfg, char *dir, int
if (play_and_wait(chan, "vm-savedto"))
break;
snprintf(todir, sizeof(todir), "%s/%s/INBOX", VM_SPOOL_DIR, username);
snprintf(todir, sizeof(todir), "%s/%s/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR,"vm", username);
snprintf(sys, sizeof(sys), "mkdir -p %s\n", todir);
puts(sys);
system(sys);
@ -1434,7 +1468,7 @@ forward_message(struct ast_channel *chan, struct ast_config *cfg, char *dir, int
snprintf(vmbox, sizeof(vmbox), "vm-%s", curbox); \
} while (0)
static int play_and_record(struct ast_channel *chan, char *playfile, char *recordfile)
static int play_and_record(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime)
{
char d, *fmt, *fmts;
char comment[256];
@ -1443,6 +1477,9 @@ static int play_and_record(struct ast_channel *chan, char *playfile, char *recor
struct ast_config *cfg;
struct ast_filestream *others[MAX_OTHER_FORMATS];
char *sfmt[MAX_OTHER_FORMATS];
char *stringp=NULL;
time_t start, end;
ast_log(LOG_DEBUG,"play_and_record: %s, %s\n", playfile, recordfile);
snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile, recordfile, chan->name);
@ -1461,11 +1498,12 @@ static int play_and_record(struct ast_channel *chan, char *playfile, char *recor
ast_destroy(cfg);
strtok(fmts, "|");
stringp=fmts;
strsep(&stringp, "|");
ast_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts);
sfmt[0] = strdup(fmts);
while((fmt = strtok(NULL, "|"))) {
while((fmt = strsep(&stringp, "|"))) {
if (fmtcnt > MAX_OTHER_FORMATS - 1) {
ast_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app_voicemail.c\n");
break;
@ -1473,6 +1511,8 @@ static int play_and_record(struct ast_channel *chan, char *playfile, char *recor
sfmt[fmtcnt++] = strdup(fmt);
}
if (maxtime)
time(&start);
for (x=0;x<fmtcnt;x++) {
others[x] = ast_writefile(recordfile, sfmt[x], comment, 0, 0, 0700);
ast_verbose( VERBOSE_PREFIX_3 "x=%i, open writing: %s format: %s\n", x, recordfile, sfmt[x]);
@ -1496,14 +1536,19 @@ static int play_and_record(struct ast_channel *chan, char *playfile, char *recor
for(;;) {
res = ast_waitfor(chan, 2000);
if (!res) {
ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name);
res = -1;
ast_log(LOG_DEBUG, "One waitfor failed, trying another\n");
/* Try one more time in case of masq */
res = ast_waitfor(chan, 2000);
if (!res) {
ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name);
res = -1;
}
}
if (res < 0) {
f = NULL;
break;
}
}
f = ast_read(chan);
if (!f)
@ -1527,6 +1572,15 @@ static int play_and_record(struct ast_channel *chan, char *playfile, char *recor
break;
}
}
if (maxtime) {
time(&end);
if (maxtime < (end - start)) {
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n");
outmsg=2;
break;
}
}
ast_frfree(f);
}
if (!f) {
@ -1567,9 +1621,12 @@ static int vm_execmain(struct ast_channel *chan, void *data)
like I'm back in my GWBASIC days. XXX */
int res=-1;
int valid = 0;
int prefix = 0;
char d;
struct localuser *u;
char username[80] ="";
char prefixstr[80] ="";
char empty[80] = "";
char password[80] = "", *copy;
char newpassword[80] = "";
char newpassword2[80] = "";
@ -1592,6 +1649,10 @@ static int vm_execmain(struct ast_channel *chan, void *data)
int starting = 1;
int box;
int useadsi = 0;
int skipuser = 0;
char *s;
int maxgreet = 0;
char tmp[256], *ext;
struct ast_config *cfg;
LOCAL_USER_ADD(u);
@ -1600,26 +1661,63 @@ static int vm_execmain(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "No voicemail configuration\n");
goto out;
}
if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
if (sscanf(s, "%d", &x) == 1) {
maxgreet = x;
} else {
ast_log(LOG_WARNING, "Invalid max message greeting length\n");
}
}
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
if (strlen(data)) {
strncpy(tmp, data, sizeof(tmp) - 1);
ext = tmp;
switch (*ext) {
case 's':
/* We should skip the user's password */
valid++;
ext++;
break;
case 'p':
/* We should prefix the mailbox with the supplied data */
prefix++;
ext++;
break;
}
if (prefix)
strncpy(prefixstr, ext, sizeof(prefixstr) - 1);
else
strncpy(username, ext, sizeof(username) - 1);
/* make sure username passed as an option is valid */
if (ast_variable_retrieve(cfg, NULL, username))
skipuser++;
else
valid = 0;
}
/* If ADSI is supported, setup login screen */
adsi_begin(chan, &useadsi);
if (useadsi)
if (!skipuser && useadsi)
adsi_login(chan);
if (ast_streamfile(chan, "vm-login", chan->language)) {
if (!skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
ast_log(LOG_WARNING, "Couldn't stream login file\n");
goto out;
}
/* Authenticate them and get their mailbox/password */
do {
while (!valid) {
/* Prompt for, and read in the username */
if (ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0) {
if (!skipuser && ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0) {
ast_log(LOG_WARNING, "Couldn't read username\n");
goto out;
}
}
if (!strlen(username)) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");
@ -1636,17 +1734,32 @@ static int vm_execmain(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "Unable to read password\n");
goto out;
}
if (prefix) {
char fullusername[80] = "";
strncpy(fullusername, prefixstr, sizeof(fullusername) - 1);
strncat(fullusername, username, sizeof(fullusername) - 1);
strncpy(username, fullusername, sizeof(username) - 1);
}
copy = ast_variable_retrieve(cfg, NULL, username);
if (copy) {
char *stringp=NULL;
copy = strdup(copy);
strtok(copy, ",");
stringp=copy;
strsep(&stringp, ",");
if (!strcmp(password,copy))
valid++;
else if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s'\n", password, username);
else {
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s'\n", password, username);
if (prefix)
strncpy(username, empty, sizeof(username) -1);
}
free(copy);
} else if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "No such user '%s' in config file\n", username);
} else {
skipuser = 0;
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "No such user '%s' in config file\n", username);
}
if (!valid) {
if (useadsi)
adsi_login(chan);
@ -1657,9 +1770,11 @@ static int vm_execmain(struct ast_channel *chan, void *data)
break;
#endif
}
} while (!valid);
}
if (valid) {
snprintf(curdir, sizeof(curdir), "%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR,"vm", username);
mkdir(curdir, 0700);
OPEN_MAILBOX(1);
oldmessages = lastmsg + 1;
/* Start in INBOX */
@ -1879,15 +1994,15 @@ vm_options:
case '1':
snprintf(prefile,sizeof(prefile),"vm/%s/unavail",username);
play_and_record(chan,"vm-rec-unv",prefile);
play_and_record(chan,"vm-rec-unv",prefile, maxgreet);
break;
case '2':
snprintf(prefile,sizeof(prefile),"vm/%s/busy",username);
play_and_record(chan,"vm-rec-busy",prefile);
play_and_record(chan,"vm-rec-busy",prefile, maxgreet);
break;
case '3':
snprintf(prefile,sizeof(prefile),"vm/%s/greet",username);
play_and_record(chan,"vm-rec-name",prefile);
play_and_record(chan,"vm-rec-name",prefile, maxgreet);
break;
case '4':
newpassword[1] = '\0';
@ -1930,14 +2045,21 @@ static int vm_exec(struct ast_channel *chan, void *data)
{
int res=0, silent=0, busy=0, unavail=0;
struct localuser *u;
char *ext = (char *)data;
char tmp[256], *ext;
if (!data) {
ast_log(LOG_WARNING, "vm requires an argument (extension)\n");
return -1;
}
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
if (data)
strncpy(tmp, data, sizeof(tmp) - 1);
else {
res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
if (res < 0)
return res;
if (!strlen(tmp))
return 0;
}
ext = tmp;
if (*ext == 's') {
silent++;
ext++;
@ -1948,8 +2070,6 @@ static int vm_exec(struct ast_channel *chan, void *data)
unavail++;
ext++;
}
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
res = leave_voicemail(chan, ext, silent, busy, unavail);
LOCAL_USER_REMOVE(u);
return res;

@ -0,0 +1,32 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* General Definitions for Asterisk top level program
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#ifndef _ASTCONF_H
#define _ASTCONF_H
#define AST_CONFIG_MAX_PATH 255
extern char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_CONFIG_FILE[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_MODULE_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_AGI_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_DB[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_KEY_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_PID[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_RUN_DIR[AST_CONFIG_MAX_PATH];
#endif

@ -16,17 +16,20 @@
#define DEFAULT_LANGUAGE "en"
#define AST_CONFIG_DIR "/etc/asterisk"
#define AST_SOCKET "/var/run/asterisk.ctl"
#define AST_PID "/var/run/asterisk.pid"
#define AST_MODULE_DIR "/usr/lib/asterisk/modules"
#define AST_SPOOL_DIR "/var/spool/asterisk"
#define AST_VAR_DIR "/var/lib/asterisk"
#define AST_LOG_DIR "/var/log/asterisk"
#define AST_AGI_DIR "/var/lib/asterisk/agi-bin"
#define AST_KEY_DIR "/var/lib/asterisk/keys"
#define AST_CONFIG_MAX_PATH 255
#define AST_CONFIG_DIR ASTETCDIR
#define AST_RUN_DIR ASTVARRUNDIR
#define AST_SOCKET ASTVARRUNDIR "/asterisk.ctl"
#define AST_PID ASTVARRUNDIR "/asterisk.pid"
#define AST_MODULE_DIR ASTMODDIR
#define AST_SPOOL_DIR ASTSPOOLDIR
#define AST_VAR_DIR ASTVARLIBDIR
#define AST_LOG_DIR ASTLOGDIR
#define AST_AGI_DIR ASTAGIDIR
#define AST_KEY_DIR ASTVARLIBDIR "/keys"
#define AST_DB ASTVARLIBDIR "/astdb"
#define AST_CONFIG_FILE "asterisk.conf"
#define AST_CONFIG_FILE ASTCONFPATH
#define AST_SOUNDS AST_VAR_DIR "/sounds"
#define AST_IMAGES AST_VAR_DIR "/images"
@ -43,4 +46,7 @@ extern int init_framer(void);
extern int reload_logger(void);
/* Provided by term.c */
extern int term_init(void);
/* Provided by db.c */
extern int astdb_init(void);
#endif

@ -1,15 +1,17 @@
TARGET=$(shell if [ -f /usr/include/newt.h ]; then echo "astman"; fi)
TARGET=$(shell if [ -f /usr/include/newt.h ]; then echo "astman"; else echo "none" ; fi)
all: $(TARGET)
install:
mkdir -p /usr/sbin
if [ "$(TARGET)" != "" ]; then \
if [ "$(TARGET)" != "none" ]; then \
for x in $(TARGET); do \
install -m 755 $$x /usr/sbin/astman; \
install -m 755 $$x $(ASTSBINDIR)/astman; \
done ; \
fi
none:
@echo Not building the Asterisk Manager "astman"
clean:
rm -f *.o astman

@ -19,9 +19,10 @@
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include "../asterisk.h"
#include "../astconf.h"
#define CSV_LOG_DIR AST_LOG_DIR "/cdr-csv"
#define CSV_MASTER CSV_LOG_DIR "/Master.csv"
#define CSV_LOG_DIR "/cdr-csv"
#define CSV_MASTER "/Master.csv"
#define DATE_FORMAT "%Y-%m-%d %T"
@ -35,22 +36,26 @@
/* The values are as follows:
"accountcode",
"accountcode", // accountcode is the account name of detail records, Master.csv contains all records
// Detail records are configured on a channel basis, IAX and SIP are determined by user
// Zap is determined by channel in zaptel.conf
"source",
"destination",
"destination context",
"callerid",
"channel",
"destination channel", (if applicable)
"last application",
"last app argument",
"last application", // Last application run on the channel
"last app argument", // argument to the last channel
"start time",
"answer time",
"end time",
duration,
billable seconds,
"disposition",
"amaflags",
duration, // Duration is the whole length that the entire call lasted. ie. call rx'd to hangup
// "end time" minus "start time"
billable seconds, // the duration that a call was up after other end answered which will be <= to duration
// "end time" minus "answer time"
"disposition", // ANSWERED, NO ANSWER, BUSY
"amaflags", // DOCUMENTATION, BILL, IGNORE etc, specified on a per channel basis like accountcode.
*/
@ -170,7 +175,7 @@ static int writefile(char *s, char *acc)
ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc);
return -1;
}
snprintf(tmp, sizeof(tmp), "%s/%s.csv", CSV_LOG_DIR, acc);
snprintf(tmp, sizeof(tmp), "%s/%s/%s.csv", (char *)ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
f = fopen(tmp, "a");
if (!f)
return -1;
@ -184,6 +189,8 @@ static int csv_log(struct ast_cdr *cdr)
{
/* Make sure we have a big enough buf */
char buf[1024];
char csvmaster[AST_CONFIG_MAX_PATH];
snprintf((char *)csvmaster,sizeof(csvmaster)-1,"%s/%s/%s",(char *)ast_config_AST_LOG_DIR,CSV_LOG_DIR,CSV_MASTER);
#if 0
printf("[CDR] %s ('%s' -> '%s') Dur: %ds Bill: %ds Disp: %s Flags: %s Account: [%s]\n", cdr->channel, cdr->src, cdr->dst, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), cdr->accountcode);
#endif
@ -193,9 +200,9 @@ static int csv_log(struct ast_cdr *cdr)
/* because of the absolutely unconditional need for the
highest reliability possible in writing billing records,
we open write and close the log file each time */
mf = fopen(CSV_MASTER, "a");
mf = fopen(csvmaster, "a");
if (!mf) {
ast_log(LOG_ERROR, "Unable to re-open master file %s\n", CSV_MASTER);
ast_log(LOG_ERROR, "Unable to re-open master file %s\n", csvmaster);
}
if (mf) {
fputs(buf, mf);

132
cli.c

@ -25,15 +25,15 @@
#include <string.h>
#include <pthread.h>
/* For rl_filename_completion */
#include <readline/readline.h>
#include "editline/readline/readline.h"
/* For module directory */
#include "asterisk.h"
#include "build.h"
#include "astconf.h"
#define VERSION_INFO "Asterisk " ASTERISK_VERSION " built by " BUILD_USER "@" BUILD_HOSTNAME \
" on a " BUILD_MACHINE " running " BUILD_OS
void ast_cli(int fd, char *fmt, ...)
{
char stuff[4096];
@ -219,6 +219,16 @@ static char commandcomplete_help[] =
" This function is used internally to help with command completion and should.\n"
" never be called by the user directly.\n";
static char commandnummatches_help[] =
"Usage: _command nummatches \"<line>\" text \n"
" This function is used internally to help with command completion and should.\n"
" never be called by the user directly.\n";
static char commandmatchesarray_help[] =
"Usage: _command matchesarray \"<line>\" text \n"
" This function is used internally to help with command completion and should.\n"
" never be called by the user directly.\n";
static int handle_softhangup(int fd, int argc, char *argv[])
{
struct ast_channel *c=NULL;
@ -240,6 +250,56 @@ static int handle_softhangup(int fd, int argc, char *argv[])
static char *__ast_cli_generator(char *text, char *word, int state, int lock);
static int handle_commandmatchesarray(int fd, int argc, char *argv[])
{
char buf[2048];
int len = 0;
char **matches;
int x;
if (argc != 4)
return RESULT_SHOWUSAGE;
buf[len] = '\0';
matches = ast_cli_completion_matches(argv[2], argv[3]);
if (matches) {
for (x=0; matches[x]; x++) {
#if 0
printf("command matchesarray for '%s' %s got '%s'\n", argv[2], argv[3], matches[x]);
#endif
len += sprintf( buf + len, "%s ", matches[x]);
}
}
#if 0
printf("array for '%s' %s got '%s'\n", argv[2], argv[3], buf);
#endif
if (buf) {
ast_cli(fd, buf);
} else
ast_cli(fd, "NULL\n");
return RESULT_SUCCESS;
}
static int handle_commandnummatches(int fd, int argc, char *argv[])
{
int matches = 0;
if (argc != 4)
return RESULT_SHOWUSAGE;
matches = ast_cli_generatornummatches(argv[2], argv[3]);
#if 0
printf("Search for '%s' %s got '%d'\n", argv[2], argv[3], matches);
#endif
ast_cli(fd, "%d", matches);
return RESULT_SUCCESS;
}
static int handle_commandcomplete(int fd, int argc, char *argv[])
{
char *buf;
@ -276,10 +336,12 @@ static int handle_showchan(int fd, int argc, char *argv[])
" DNID Digits: %s\n"
" State: %s (%d)\n"
" Rings: %d\n"
" NativeFormat: %d\n"
" WriteFormat: %d\n"
" ReadFormat: %d\n"
" NativeFormat: %d\n"
"1st File Descriptor: %d\n"
" Frames in: %d\n"
" Frames out: %d\n"
" -- PBX --\n"
" Context: %s\n"
" Extension: %s\n"
@ -291,7 +353,7 @@ static int handle_showchan(int fd, int argc, char *argv[])
c->name, c->type,
(c->callerid ? c->callerid : "(N/A)"),
(c->dnid ? c->dnid : "(N/A)" ), ast_state2str(c->_state), c->_state, c->rings, c->nativeformats, c->writeformat, c->readformat,
c->fds[0], c->context, c->exten, c->priority, ( c->appl ? c->appl : "(N/A)" ),
c->fds[0], c->fin, c->fout, c->context, c->exten, c->priority, ( c->appl ? c->appl : "(N/A)" ),
( c-> data ? (strlen(c->data) ? c->data : "(Empty)") : "(None)"),
c->stack, (c->blocking ? c->blockproc : "(Not Blocking)"));
@ -328,10 +390,10 @@ static char *complete_fn(char *line, char *word, int pos, int state)
if (word[0] == '/')
strncpy(filename, word, sizeof(filename)-1);
else
snprintf(filename, sizeof(filename), "%s/%s", AST_MODULE_DIR, word);
snprintf(filename, sizeof(filename), "%s/%s", (char *)ast_config_AST_MODULE_DIR, word);
c = (char*)filename_completion_function(filename, state);
if (c && word[0] != '/')
c += (strlen(AST_MODULE_DIR) + 1);
c += (strlen((char*)ast_config_AST_MODULE_DIR) + 1);
return c ? strdup(c) : c;
}
@ -341,6 +403,8 @@ static struct ast_cli_entry builtins[] = {
/* Keep alphabetized */
{ { "help", NULL }, handle_help, "Display help list, or specific help on a command", help_help },
{ { "_command", "complete", NULL }, handle_commandcomplete, "Command complete", commandcomplete_help },
{ { "_command", "nummatches", NULL }, handle_commandnummatches, "Returns number of command matches", commandnummatches_help },
{ { "_command", "matchesarray", NULL }, handle_commandmatchesarray, "Returns command matches array", commandmatchesarray_help },
{ { "load", NULL }, handle_load, "Load a dynamic module by name", load_help, complete_fn },
{ { "reload", NULL }, handle_reload, "Reload configuration", reload_help },
{ { "set", "verbose", NULL }, handle_set_verbose, "Set level of verboseness", set_verbose_help },
@ -637,6 +701,62 @@ normal:
return dup;
}
/* This returns the number of unique matches for the generator */
int ast_cli_generatornummatches(char *text, char *word)
{
int matches = 0, i = 0;
char *buf, *oldbuf;
while ( (buf = ast_cli_generator(text, word, i)) ) {
if (++i > 1 && strcmp(buf,oldbuf) == 0)
continue;
oldbuf = buf;
matches++;
}
return matches;
}
char **ast_cli_completion_matches(char *text, char *word)
{
char **match_list = NULL, *retstr, *prevstr;
size_t match_list_len, max_equal, which, i;
int matches = 0;
match_list_len = 1;
while ((retstr = ast_cli_generator(text, word, matches)) != NULL) {
if (matches + 1 >= match_list_len) {
match_list_len <<= 1;
match_list = realloc(match_list, match_list_len * sizeof(char *));
}
match_list[++matches] = retstr;
}
if (!match_list)
return (char **) NULL;
which = 2;
prevstr = match_list[1];
max_equal = strlen(prevstr);
for (; which <= matches; which++) {
for (i = 0; i < max_equal && prevstr[i] == match_list[which][i]; i++)
continue;
max_equal = i;
}
retstr = malloc(max_equal + 1);
(void) strncpy(retstr, match_list[1], max_equal);
retstr[max_equal] = '\0';
match_list[0] = retstr;
if (matches + 1 >= match_list_len)
match_list = realloc(match_list, (match_list_len + 1) * sizeof(char *));
match_list[matches + 1] = (char *) NULL;
return (match_list);
}
static char *__ast_cli_generator(char *text, char *word, int state, int lock)
{
char *argv[AST_MAX_ARGS];

@ -20,6 +20,7 @@
#include <asterisk/options.h>
#include <asterisk/logger.h>
#include "asterisk.h"
#include "astconf.h"
#define MAX_INCLUDE_LEVEL 10
@ -228,6 +229,8 @@ static int cfg_process(struct ast_config *tmp, struct ast_category **_tmpc, stru
if (!*_tmpc) {
ast_log(LOG_WARNING,
"parse error: No category context for line %d of %s\n", lineno, configfile);
ast_destroy(tmp);
return -1;
}
c = strchr(cur, '=');
if (c) {
@ -272,7 +275,7 @@ static struct ast_config *__ast_load(char *configfile, struct ast_config *tmp, s
if (configfile[0] == '/') {
strncpy(fn, configfile, sizeof(fn)-1);
} else {
snprintf(fn, sizeof(fn), "%s/%s", AST_CONFIG_DIR, configfile);
snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, configfile);
}
if ((option_verbose > 1) && !option_debug) {
ast_verbose( VERBOSE_PREFIX_2 "Parsing '%s': ", fn);

355
db.c

@ -0,0 +1,355 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Channel Management
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
/* DB3 is licensed under Sleepycat Public License and is thus incompatible
with GPL. To avoid having to make another exception (and complicate
licensing even further) we elect to use DB1 which is BSD licensed */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <asterisk/channel.h>
#include <asterisk/file.h>
#include <asterisk/app.h>
#include <asterisk/dsp.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/astdb.h>
#include <asterisk/cli.h>
#include "db1-ast/include/db.h"
#include "asterisk.h"
#include "astconf.h"
static DB *astdb;
static pthread_mutex_t dblock = AST_MUTEX_INITIALIZER;
static int dbinit(void)
{
if (!astdb) {
if (!(astdb = dbopen((char *)ast_config_AST_DB, O_CREAT | O_RDWR, 0664, DB_BTREE, NULL))) {
ast_log(LOG_WARNING, "Unable to open Asterisk database\n");
}
}
if (astdb)
return 0;
return -1;
}
static inline int keymatch(const char *key, const char *prefix)
{
if (!strlen(prefix))
return 1;
if (!strcasecmp(key, prefix))
return 1;
if ((strlen(key) > strlen(prefix)) &&
!strncasecmp(key, prefix, strlen(prefix))) {
if (key[strlen(prefix)] == '/')
return 1;
}
return 0;
}
int ast_db_deltree(const char *family, const char *keytree)
{
char prefix[256];
DBT key, data;
char *keys;
int res;
int pass;
if (family) {
if (keytree)
snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
else
snprintf(prefix, sizeof(prefix), "/%s", family);
} else if (keytree)
return -1;
else
strcpy(prefix, "");
ast_pthread_mutex_lock(&dblock);
if (dbinit())
return -1;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
pass = 0;
while(!(res = astdb->seq(astdb, &key, &data, pass++ ? R_NEXT : R_FIRST))) {
if (key.size) {
keys = key.data;
keys[key.size - 1] = '\0';
} else
keys = "<bad key>";
if (keymatch(keys, prefix)) {
astdb->del(astdb, &key, 0);
}
}
astdb->sync(astdb, 0);
ast_pthread_mutex_unlock(&dblock);
return 0;
}
int ast_db_put(const char *family, const char *keys, char *value)
{
char fullkey[256];
DBT key, data;
int res;
ast_pthread_mutex_lock(&dblock);
if (dbinit()) {
ast_pthread_mutex_unlock(&dblock);
return -1;
}
snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys);
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = fullkey;
key.size = strlen(fullkey) + 1;
data.data = value;
data.size = strlen(value) + 1;
res = astdb->put(astdb, &key, &data, 0);
astdb->sync(astdb, 0);
ast_pthread_mutex_unlock(&dblock);
if (res)
ast_log(LOG_WARNING, "Unable to put value '%s' for key '%s' in family '%s'\n", value, keys, family);
return res;
}
int ast_db_get(const char *family, const char *keys, char *value, int valuelen)
{
char fullkey[256];
DBT key, data;
int res;
ast_pthread_mutex_lock(&dblock);
if (dbinit()) {
ast_pthread_mutex_unlock(&dblock);
return -1;
}
snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys);
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = fullkey;
key.size = strlen(fullkey) + 1;
res = astdb->get(astdb, &key, &data, 0);
ast_pthread_mutex_unlock(&dblock);
/* Be sure to NULL terminate our data either way */
if (res) {
value[0] = 0;
ast_log(LOG_DEBUG, "Unable to find key '%s' in family '%s'\n", keys, family);
} else {
printf("Got value of size %d\n", data.size);
if (data.size) {
((char *)data.data)[data.size - 1] = '\0';
strncpy(value, data.data, valuelen - 1);
value[valuelen - 1] = '\0';
} else {
ast_log(LOG_NOTICE, "Strange, empty value for /%s/%s\n", family, keys);
value[0] = '\0';
}
}
return res;
}
int ast_db_del(const char *family, const char *keys)
{
char fullkey[256];
DBT key;
int res;
ast_pthread_mutex_lock(&dblock);
if (dbinit()) {
ast_pthread_mutex_unlock(&dblock);
return -1;
}
snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys);
memset(&key, 0, sizeof(key));
key.data = fullkey;
key.size = strlen(fullkey) + 1;
res = astdb->del(astdb, &key, 0);
astdb->sync(astdb, 0);
ast_pthread_mutex_unlock(&dblock);
if (res)
ast_log(LOG_DEBUG, "Unable to find key '%s' in family '%s'\n", keys, family);
return res;
}
static int database_put(int fd, int argc, char *argv[])
{
int res;
if (argc != 5)
return RESULT_SHOWUSAGE;
res = ast_db_put(argv[2], argv[3], argv[4]);
if (res)
ast_cli(fd, "Failed to update entry\n");
else
ast_cli(fd, "Updated database successfully\n");
return RESULT_SUCCESS;
}
static int database_get(int fd, int argc, char *argv[])
{
int res;
char tmp[256];
if (argc != 4)
return RESULT_SHOWUSAGE;
res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp));
if (res)
ast_cli(fd, "Database entry not found.\n");
else
ast_cli(fd, "Value: %s\n", tmp);
return RESULT_SUCCESS;
}
static int database_del(int fd, int argc, char *argv[])
{
int res;
if (argc != 4)
return RESULT_SHOWUSAGE;
res = ast_db_del(argv[2], argv[3]);
if (res)
ast_cli(fd, "Database entry does not exist.\n");
else
ast_cli(fd, "Database entry removed.\n");
return RESULT_SUCCESS;
}
static int database_deltree(int fd, int argc, char *argv[])
{
int res;
if ((argc < 3) || (argc > 4))
return RESULT_SHOWUSAGE;
if (argc == 4)
res = ast_db_deltree(argv[2], argv[3]);
else
res = ast_db_deltree(argv[2], NULL);
if (res)
ast_cli(fd, "Database entries do not exist.\n");
else
ast_cli(fd, "Database entries removed.\n");
return RESULT_SUCCESS;
}
static int database_show(int fd, int argc, char *argv[])
{
char prefix[256];
DBT key, data;
char *keys, *values;
int res;
int pass;
if (argc == 4) {
/* Family and key tree */
snprintf(prefix, sizeof(prefix), "/%s/%s", argv[2], argv[3]);
} else if (argc == 3) {
/* Family only */
snprintf(prefix, sizeof(prefix), "/%s", argv[2]);
} else if (argc == 2) {
/* Neither */
strcpy(prefix, "");
} else
return RESULT_SHOWUSAGE;
ast_pthread_mutex_lock(&dblock);
if (dbinit()) {
ast_pthread_mutex_unlock(&dblock);
ast_cli(fd, "Database unavailable\n");
return RESULT_SUCCESS;
}
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
pass = 0;
while(!(res = astdb->seq(astdb, &key, &data, pass++ ? R_NEXT : R_FIRST))) {
if (key.size) {
keys = key.data;
keys[key.size - 1] = '\0';
} else
keys = "<bad key>";
if (data.size) {
values = data.data;
values[data.size - 1]='\0';
} else
values = "<vad value>";
if (keymatch(keys, prefix)) {
ast_cli(fd, "%-50s: %-25s\n", keys, values);
}
}
ast_pthread_mutex_unlock(&dblock);
return RESULT_SUCCESS;
}
static char database_show_usage[] =
"Usage: database show [family [keytree]]\n"
" Shows Asterisk database contents, optionally restricted\n"
"to a given family, or family and keytree.\n";
static char database_put_usage[] =
"Usage: database put <family> <key> <value>\n"
" Adds or updates an entry in the Asterisk database for\n"
"a given family, key, and value.\n";
static char database_get_usage[] =
"Usage: database get <family> <key>\n"
" Retrieves an entry in the Asterisk database for a given\n"
"family and key.\n";
static char database_del_usage[] =
"Usage: database del <family> <key>\n"
" Deletes an entry in the Asterisk database for a given\n"
"family and key.\n";
static char database_deltree_usage[] =
"Usage: database deltree <family> [keytree]\n"
" Deletes a family or specific keytree within a family\n"
"in the Asterisk database.\n";
struct ast_cli_entry cli_database_show =
{ { "database", "show", NULL }, database_show, "Shows database contents", database_show_usage };
struct ast_cli_entry cli_database_get =
{ { "database", "get", NULL }, database_get, "Gets database value", database_get_usage };
struct ast_cli_entry cli_database_put =
{ { "database", "put", NULL }, database_put, "Adds/updates database value", database_put_usage };
struct ast_cli_entry cli_database_del =
{ { "database", "del", NULL }, database_del, "Removes database key/value", database_del_usage };
struct ast_cli_entry cli_database_deltree =
{ { "database", "deltree", NULL }, database_deltree, "Removes database keytree/values", database_deltree_usage };
int astdb_init(void)
{
dbinit();
ast_cli_register(&cli_database_show);
ast_cli_register(&cli_database_get);
ast_cli_register(&cli_database_put);
ast_cli_register(&cli_database_del);
ast_cli_register(&cli_database_deltree);
return 0;
}

@ -30,6 +30,7 @@
#include <asterisk/translate.h>
#include <asterisk/cli.h>
#include "asterisk.h"
#include "astconf.h"
static struct ast_imager *list;
static pthread_mutex_t listlock = AST_MUTEX_INITIALIZER;
@ -94,9 +95,9 @@ static void make_filename(char *buf, int len, char *filename, char *preflang, ch
snprintf(buf, len, "%s.%s", filename, ext);
} else {
if (preflang && strlen(preflang))
snprintf(buf, len, "%s/%s-%s.%s", AST_IMAGES, filename, preflang, ext);
snprintf(buf, len, "%s/%s/%s-%s.%s", ast_config_AST_VAR_DIR, "images", filename, preflang, ext);
else
snprintf(buf, len, "%s/%s.%s", AST_IMAGES, filename, ext);
snprintf(buf, len, "%s/%s/%s.%s", ast_config_AST_VAR_DIR, "images", filename, ext);
}
}
@ -116,8 +117,10 @@ struct ast_frame *ast_read_image(char *filename, char *preflang, int format)
i = list;
while(!found && i) {
if (i->format & format) {
char *stringp=NULL;
strncpy(tmp, i->exts, sizeof(tmp)-1);
e = strtok(tmp, "|");
stringp=tmp;
e = strsep(&stringp, "|");
while(e) {
make_filename(buf, sizeof(buf), filename, preflang, e);
if ((len = file_exists(buf))) {
@ -129,7 +132,7 @@ struct ast_frame *ast_read_image(char *filename, char *preflang, int format)
found = i;
break;
}
e = strtok(NULL, "|");
e = strsep(&stringp, "|");
}
}
i = i->next;

@ -28,6 +28,7 @@
#define __USE_GNU
#include <pthread.h>
#include "asterisk.h"
#include "astconf.h"
static char expected_key[] =
{ 0x8e, 0x93, 0x22, 0x83, 0xf5, 0xc3, 0xc0, 0x75,
@ -204,7 +205,7 @@ int ast_load_resource(char *resource_name)
if (resource_name[0] == '/') {
strncpy(fn, resource_name, sizeof(fn)-1);
} else {
snprintf(fn, sizeof(fn), "%s/%s", AST_MODULE_DIR, resource_name);
snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_MODULE_DIR, resource_name);
}
m->lib = dlopen(fn, flags);
if (!m->lib) {
@ -331,7 +332,7 @@ int load_modules()
int x;
/* Make two passes. First, load any resource modules, then load the others. */
for (x=0;x<2;x++) {
mods = opendir(AST_MODULE_DIR);
mods = opendir((char *)ast_config_AST_MODULE_DIR);
if (mods) {
while((d = readdir(mods))) {
/* Must end in .so to load it. */
@ -374,7 +375,7 @@ int load_modules()
closedir(mods);
} else {
if (!option_quiet)
ast_log(LOG_WARNING, "Unable to open modules directory " AST_MODULE_DIR ".\n");
ast_log(LOG_WARNING, "Unable to open modules directory %s.\n", (char *)ast_config_AST_MODULE_DIR);
}
}
}

@ -27,8 +27,7 @@
#include <pthread.h>
#include <sys/stat.h>
#include "asterisk.h"
#define AST_EVENT_LOG AST_LOG_DIR "/" EVENTLOG
#include "astconf.h"
#define MAX_MSG_QUEUE 200
@ -73,7 +72,9 @@ static int make_components(char *s, int lineno)
{
char *w;
int res = 0;
w = strtok(s, ",");
char *stringp=NULL;
stringp=s;
w = strsep(&stringp, ",");
while(w) {
while(*w && (*w < 33))
w++;
@ -88,7 +89,7 @@ static int make_components(char *s, int lineno)
else {
fprintf(stderr, "Logfile Warning: Unknown keyword '%s' at line %d of logger.conf\n", w, lineno);
}
w = strtok(NULL, ",");
w = strsep(&stringp, ",");
}
return res;
}
@ -111,7 +112,7 @@ static struct logfile *make_logfile(char *fn, char *components, int lineno)
if (fn[0] == '/')
strncpy(tmp, fn, sizeof(tmp) - 1);
else
snprintf(tmp, sizeof(tmp), "%s/%s", AST_LOG_DIR, fn);
snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_LOG_DIR, fn);
f->f = fopen(tmp, "a");
if (!f->f) {
/* Can't log here, since we're called with a lock */
@ -179,14 +180,15 @@ static struct verb {
int init_logger(void)
{
mkdir(AST_LOG_DIR, 0755);
eventlog = fopen(AST_EVENT_LOG, "a");
char tmp[AST_CONFIG_MAX_PATH];
mkdir((char *)ast_config_AST_LOG_DIR, 0755);
snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_LOG_DIR, EVENTLOG);
eventlog = fopen((char *)tmp, "a");
if (eventlog) {
init_logger_chain();
ast_log(LOG_EVENT, "Started Asterisk Event Logger\n");
if (option_verbose)
ast_verbose("Asterisk Event Logger Started\n");
ast_verbose("Asterisk Event Logger Started %s\n",(char *)tmp);
return 0;
} else
ast_log(LOG_ERROR, "Unable to create event log: %s\n", strerror(errno));
@ -196,11 +198,13 @@ int init_logger(void)
int reload_logger(void)
{
char tmp[AST_CONFIG_MAX_PATH];
ast_pthread_mutex_lock(&loglock);
if (eventlog)
fclose(eventlog);
mkdir(AST_LOG_DIR, 0755);
eventlog = fopen(AST_EVENT_LOG, "a");
mkdir((char *)ast_config_AST_LOG_DIR, 0755);
snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_LOG_DIR, EVENTLOG);
eventlog = fopen((char *)tmp, "a");
ast_pthread_mutex_unlock(&loglock);
if (eventlog) {

@ -23,6 +23,7 @@
#include <errno.h>
/* For where to put dynamic tables */
#include "../asterisk.h"
#include "../astconf.h"
static char *dtext = "Text Extension Configuration";
static char *config = "extensions.conf";
@ -919,7 +920,7 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
} else
/* no config file, default one */
snprintf(filename, sizeof(filename), "%s/%s",
AST_CONFIG_DIR, config);
(char *)ast_config_AST_CONFIG_DIR, config);
/* try to lock contexts list */
if (ast_lock_contexts()) {
@ -1463,7 +1464,6 @@ static int pbx_load_module(void)
{
struct ast_config *cfg;
struct ast_variable *v;
char *ptrptr;
char *cxt, *ext, *pri, *appl, *data, *tc, *cidmatch;
struct ast_context *con;
@ -1485,36 +1485,41 @@ static int pbx_load_module(void)
v = ast_variable_browse(cfg, cxt);
while(v) {
if (!strcasecmp(v->name, "exten")) {
char *stringp=NULL;
tc = strdup(v->value);
ext = strtok_r(tc, ",",&ptrptr);
if (!ext)
ext="";
pri = strtok_r(NULL, ",",&ptrptr);
if (!pri)
pri="";
appl = strtok_r(NULL, ",",&ptrptr);
if (!appl)
appl="";
if (*ptrptr=='"') {
ptrptr++;
data = strtok_r(NULL, "\"",&ptrptr);
ptrptr++;
} else {
data = strtok_r(NULL, ",",&ptrptr);
}
cidmatch = strchr(ext, '/');
if (cidmatch) {
*cidmatch = '\0';
cidmatch++;
}
strtok(ext, "/");
if(tc!=NULL){
stringp=tc;
ext = strsep(&stringp, ",");
if (!ext)
ext="";
pri = strsep(&stringp, ",");
if (!pri)
pri="";
appl = strsep(&stringp, ",");
if (!appl)
appl="";
if (stringp!=NULL && *stringp=='"') {
stringp++;
data = strsep(&stringp, "\"");
stringp++;
} else {
data = strsep(&stringp, ",");
}
cidmatch = strchr(ext, '/');
if (cidmatch) {
*cidmatch = '\0';
cidmatch++;
}
stringp=ext;
strsep(&stringp, "/");
if (!data)
data="";
if (ast_add_extension2(con, 0, ext, atoi(pri), cidmatch, appl, strdup(data), free, registrar)) {
ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
}
free(tc);
if (!data)
data="";
if (ast_add_extension2(con, 0, ext, atoi(pri), cidmatch, appl, strdup(data), free, registrar)) {
ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
}
free(tc);
} else fprintf(stderr,"Error strdup returned NULL in %s\n",__PRETTY_FUNCTION__);
} else if(!strcasecmp(v->name, "include")) {
if (ast_context_add_include2(con, v->value, registrar))
ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s'\n", v->value, cxt);
@ -1522,9 +1527,11 @@ static int pbx_load_module(void)
if (ast_context_add_ignorepat2(con, v->value, registrar))
ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
} else if (!strcasecmp(v->name, "switch")) {
char *stringp=NULL;
tc = strdup(v->value);
appl = strtok(tc, "/");
data = strtok(NULL, "");
stringp=tc;
appl = strsep(&stringp, "/");
data = strsep(&stringp, "");
if (!data)
data = "";
if (ast_context_add_switch2(con, appl, data, registrar))

@ -39,6 +39,7 @@
#include <glib.h>
/* For where to put dynamic tables */
#include "../asterisk.h"
#include "../astconf.h"
static pthread_mutex_t verb_lock = AST_MUTEX_INITIALIZER;
@ -228,10 +229,12 @@ static void reload_module()
static void file_ok_sel(GtkWidget *w, GtkFileSelection *fs)
{
char tmp[AST_CONFIG_MAX_PATH];
char *module = gtk_file_selection_get_filename(fs);
char buf[256];
if (!strncmp(module, AST_MODULE_DIR "/", strlen(AST_MODULE_DIR "/")))
module += strlen(AST_MODULE_DIR "/");
snprintf((char *)tmp,sizeof(tmp)-1,"%s/",(char *)ast_config_AST_MODULE_DIR);
if (!strncmp(module, (char *)tmp, strlen(tmp)))
module += strlen(tmp);
gdk_threads_leave();
if (ast_load_resource(module)) {
snprintf(buf, sizeof(buf), "Error loading module '%s'.", module);
@ -246,13 +249,15 @@ static void file_ok_sel(GtkWidget *w, GtkFileSelection *fs)
static void add_module()
{
char tmp[AST_CONFIG_MAX_PATH];
GtkWidget *filew;
snprintf((char *)tmp,sizeof(tmp)-1,"%s/*.so",(char *)ast_config_AST_MODULE_DIR);
filew = gtk_file_selection_new("Load Module");
gtk_signal_connect(GTK_OBJECT (GTK_FILE_SELECTION(filew)->ok_button),
"clicked", GTK_SIGNAL_FUNC(file_ok_sel), filew);
gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION(filew)->cancel_button),
"clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(filew));
gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew), AST_MODULE_DIR "/*.so");
gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew), (char *)tmp);
gtk_widget_show(filew);
}

@ -31,10 +31,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "../astconf.h"
// Globals
const char *dialfile="/var/run/autodial.ctl";
const char dialfile[255];
static char *tdesc = "Wil Cal U (Auto Dialer)";
static pthread_t autodialer_thread;
static char buf[257];
@ -245,6 +246,7 @@ int unload_module(void)
int load_module(void)
{
int val;
snprintf((char *)dialfile,sizeof(dialfile)-1,"%s/%s",(char *)ast_config_AST_RUN_DIR,"autodial.ctl");
if((val=mkfifo(dialfile, 0700))){
if(errno!=EEXIST){
printf("Error:%d Creating Autodial FIFO\n",errno);

Loading…
Cancel
Save