Version 0.1.2 from FTP

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Mark Spencer 26 years ago
parent 5099c2edf7
commit aa07102df2

@ -11,7 +11,7 @@
# the GNU General Public License # the GNU General Public License
# #
APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_intercom.so app_mp3.so APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_intercom.so app_mp3.so app_system.so app_echo.so
CFLAGS+= CFLAGS+=

@ -0,0 +1,80 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Echo application -- play back what you hear to evaluate latency
*
* 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
*/
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
static char *tdesc = "Simple Echo Application";
static char *app = "Echo";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int skel_exec(struct ast_channel *chan, void *data)
{
int res=-1;
struct localuser *u;
struct ast_frame *f;
LOCAL_USER_ADD(u);
/* Do our thing here */
while((f = ast_read(chan))) {
if (f->frametype == AST_FRAME_VOICE) {
if (ast_write(chan, f))
break;
} else if (f->frametype == AST_FRAME_DTMF) {
if (f->subclass == '#') {
res = 0;
break;
} else
if (ast_write(chan, f))
break;
}
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, skel_exec);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}

@ -15,6 +15,7 @@
#include <asterisk/logger.h> #include <asterisk/logger.h>
#include <asterisk/channel.h> #include <asterisk/channel.h>
#include <asterisk/pbx.h> #include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
@ -22,63 +23,32 @@
#include <pthread.h> #include <pthread.h>
static pthread_mutex_t skellock = PTHREAD_MUTEX_INITIALIZER;
static int usecnt=0;
static char *tdesc = "Trivial skeleton Application"; static char *tdesc = "Trivial skeleton Application";
static char *app = "skel"; static char *app = "skel";
struct skeluser { STANDARD_LOCAL_USER;
struct ast_channel *chan;
struct skeluser *next; LOCAL_USER_DECL;
} *users = NULL;
static int skel_exec(struct ast_channel *chan, void *data) static int skel_exec(struct ast_channel *chan, void *data)
{ {
int res=0; int res=0;
struct skeluser *u, *ul=NULL; struct localuser *u;
if (!data) { if (!data) {
ast_log(LOG_WARNING, "skel requires an argument (filename)\n"); ast_log(LOG_WARNING, "skel requires an argument (filename)\n");
return -1; return -1;
} }
if (!(u=malloc(sizeof(struct skeluser)))) { LOCAL_USER_ADD(u);
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
pthread_mutex_lock(&skellock);
u->chan = chan;
u->next = users;
users = u;
usecnt++;
pthread_mutex_unlock(&skellock);
/* Do our thing here */ /* Do our thing here */
pthread_mutex_lock(&skellock); LOCAL_USER_REMOVE(u);
u = users;
while(u) {
if (ul)
ul->next = u->next;
else
users = u->next;
u = u->next;
}
usecnt--;
pthread_mutex_unlock(&skellock);
return res; return res;
} }
int unload_module(void) int unload_module(void)
{ {
struct skeluser *u; STANDARD_HANGUP_LOCALUSERS;
pthread_mutex_lock(&skellock);
u = users;
while(u) {
/* Hang up anybody who is using us */
ast_softhangup(u->chan);
u = u->next;
}
pthread_mutex_unlock(&skellock);
return ast_unregister_application(app); return ast_unregister_application(app);
} }
@ -95,8 +65,6 @@ char *description(void)
int usecount(void) int usecount(void)
{ {
int res; int res;
pthread_mutex_lock(&skellock); STANDARD_USECOUNT(res);
res = usecnt;
pthread_mutex_unlock(&skellock);
return res; return res;
} }

@ -0,0 +1,82 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Execute arbitrary system commands
*
* 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
*/
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
static char *tdesc = "Generic System() application";
static char *app = "System";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int skel_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
if (!data) {
ast_log(LOG_WARNING, "System requires an argument(command)\n");
return -1;
}
LOCAL_USER_ADD(u);
/* Do our thing here */
res = system((char *)data);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
res = -1;
} else if (res == 127) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
res = -1;
} else {
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101))
chan->priority+=100;
res = 0;
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, skel_exec);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}

@ -141,7 +141,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent)
struct ast_config *cfg; struct ast_config *cfg;
char *copy, *name, *passwd, *email, *dir, *fmt, *fmts, *fn=NULL; char *copy, *name, *passwd, *email, *dir, *fmt, *fmts, *fn=NULL;
char comment[256]; char comment[256];
struct ast_filestream *writer, *others[MAX_OTHER_FORMATS]; struct ast_filestream *writer=NULL, *others[MAX_OTHER_FORMATS];
char *sfmt[MAX_OTHER_FORMATS]; char *sfmt[MAX_OTHER_FORMATS];
int res = -1, fmtcnt=0, x; int res = -1, fmtcnt=0, x;
int msgnum; int msgnum;
@ -182,8 +182,12 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent)
snprintf(comment, sizeof(comment), "Voicemail from %s to %s (%s) on %s\n", snprintf(comment, sizeof(comment), "Voicemail from %s to %s (%s) on %s\n",
(chan->callerid ? chan->callerid : "Unknown"), (chan->callerid ? chan->callerid : "Unknown"),
name, ext, chan->name); name, ext, chan->name);
if (ast_fileexists(fn, NULL) > 0) {
msgnum++;
continue;
}
writer = ast_writefile(fn, fmt, comment, O_EXCL, 1 /* check for other formats */, 0700); writer = ast_writefile(fn, fmt, comment, O_EXCL, 1 /* check for other formats */, 0700);
if (!writer && (errno != EEXIST)) if (!writer)
break; break;
msgnum++; msgnum++;
} while(!writer && (msgnum < MAXMSG)); } while(!writer && (msgnum < MAXMSG));
@ -221,9 +225,14 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent)
if (f->frametype == AST_FRAME_VOICE) { if (f->frametype == AST_FRAME_VOICE) {
/* Write the primary format */ /* Write the primary format */
res = ast_writestream(writer, f); res = ast_writestream(writer, f);
if (res) {
ast_log(LOG_WARNING, "Error writing primary frame\n");
break;
}
/* And each of the others */ /* And each of the others */
for (x=0;x<fmtcnt;x++) for (x=0;x<fmtcnt;x++) {
res |= ast_writestream(others[x], f); res |= ast_writestream(others[x], f);
}
ast_frfree(f); ast_frfree(f);
/* Exit on any error */ /* Exit on any error */
if (res) { if (res) {
@ -314,20 +323,30 @@ static int vm_execmain(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "No voicemail configuration\n"); ast_log(LOG_WARNING, "No voicemail configuration\n");
goto out; goto out;
} }
if (ast_streamfile(chan, "vm-login")) if (ast_streamfile(chan, "vm-login")) {
ast_log(LOG_WARNING, "Couldn't stream login file\n");
goto out; goto out;
}
do { do {
/* Prompt for, and read in the username */ /* Prompt for, and read in the username */
if (ast_readstring(chan, username, sizeof(username), 2000, 5000, "#")) if (ast_readstring(chan, username, sizeof(username), 2000, 5000, "#")) {
ast_log(LOG_WARNING, "Couldn't read username\n");
goto out; goto out;
}
if (!strlen(username)) { if (!strlen(username)) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");
res = 0; res = 0;
goto out; goto out;
} }
if (ast_streamfile(chan, "vm-password")) if (ast_streamfile(chan, "vm-password")) {
ast_log(LOG_WARNING, "Unable to stream password file\n");
goto out; goto out;
if (ast_readstring(chan, password, sizeof(password), 2000, 5000, "#")) }
if (ast_readstring(chan, password, sizeof(password), 2000, 5000, "#")) {
ast_log(LOG_WARNING, "Unable to read password\n");
goto out; goto out;
}
copy = ast_variable_retrieve(cfg, NULL, username); copy = ast_variable_retrieve(cfg, NULL, username);
if (copy) { if (copy) {
copy = strdup(copy); copy = strdup(copy);

@ -28,7 +28,9 @@ int option_verbose=0;
int option_debug=0; int option_debug=0;
int option_nofork=0; int option_nofork=0;
int option_quiet=0; int option_quiet=0;
int option_console=0;
int option_highpriority=0; int option_highpriority=0;
int fully_booted = 0;
#define HIGH_PRIORITY 1 #define HIGH_PRIORITY 1
#define HIGH_PRIORITY_SCHED SCHED_RR #define HIGH_PRIORITY_SCHED SCHED_RR
@ -39,6 +41,7 @@ static void urg_handler(int num)
system call. We don't actually need to do anything though. */ system call. We don't actually need to do anything though. */
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "Urgent handler\n"); ast_log(LOG_DEBUG, "Urgent handler\n");
signal(num, urg_handler);
return; return;
} }
@ -89,6 +92,7 @@ static void console_verboser(char *s, int pos, int replace, int complete)
if (!pos) if (!pos)
fprintf(stdout, "\r"); fprintf(stdout, "\r");
fprintf(stdout, s + pos); fprintf(stdout, s + pos);
fflush(stdout);
if (complete) if (complete)
/* Wake up a select()ing console */ /* Wake up a select()ing console */
pthread_kill(consolethread, SIGURG); pthread_kill(consolethread, SIGURG);
@ -99,8 +103,19 @@ static void consolehandler(char *s)
/* Called when readline data is available */ /* Called when readline data is available */
if (s && strlen(s)) if (s && strlen(s))
add_history(s); add_history(s);
if (s) /* Give the console access to the shell */
if (s) {
if (s[0] == '!') {
if (s[1])
system(s+1);
else
system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
} else
ast_cli_command(STDOUT_FILENO, s); ast_cli_command(STDOUT_FILENO, s);
if (!strcasecmp(s, "help"))
fprintf(stdout, " !<command> Executes a given shell command\n");
} else
fprintf(stdout, "\nUse \"quit\" to exit\n");
} }
static char quit_help[] = static char quit_help[] =
@ -138,17 +153,21 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
/* Check for options */ /* Check for options */
while((c=getopt(argc, argv, "dvqp")) != EOF) { while((c=getopt(argc, argv, "dvqpc")) != EOF) {
switch(c) { switch(c) {
case 'd': case 'd':
option_debug++; option_debug++;
option_nofork++; option_nofork++;
break; break;
case 'c':
option_console++;
option_nofork++;
case 'p': case 'p':
option_highpriority++; option_highpriority++;
break; break;
case 'v': case 'v':
option_verbose++; option_verbose++;
option_nofork++;
break; break;
case 'q': case 'q':
option_quiet++; option_quiet++;
@ -157,12 +176,15 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
} }
ast_register_verbose(console_verboser);
/* Print a welcome message if desired */ /* Print a welcome message if desired */
if (option_verbose) { if (option_verbose || option_console) {
ast_verbose( "Asterisk, Copyright (C) 1999 Mark Spencer\n"); ast_verbose( "Asterisk, Copyright (C) 1999 Mark Spencer\n");
ast_verbose( "Written by Mark Spencer <markster@linux-support.net>\n"); ast_verbose( "Written by Mark Spencer <markster@linux-support.net>\n");
ast_verbose( "=========================================================================\n"); ast_verbose( "=========================================================================\n");
} }
if (option_console && !option_verbose)
ast_verbose("[ Booting...");
signal(SIGURG, urg_handler); signal(SIGURG, urg_handler);
signal(SIGINT, quit_handler); signal(SIGINT, quit_handler);
signal(SIGTERM, quit_handler); signal(SIGTERM, quit_handler);
@ -177,14 +199,16 @@ int main(int argc, char *argv[])
exit(1); exit(1);
/* We might have the option of showing a console, but for now just /* We might have the option of showing a console, but for now just
do nothing... */ do nothing... */
if (option_console && !option_verbose)
ast_verbose(" ]\n");
if (option_verbose || option_console)
ast_verbose( "Asterisk Ready.\n");
fully_booted = 1;
if (option_console) {
/* Console stuff now... */ /* Console stuff now... */
/* Register our quit function */ /* Register our quit function */
ast_cli_register(&quit); ast_cli_register(&quit);
consolethread = pthread_self(); consolethread = pthread_self();
ast_register_verbose(console_verboser);
if (option_verbose)
ast_verbose( "Asterisk Ready.\n");
if (strlen(filename)) if (strlen(filename))
read_history(filename); read_history(filename);
rl_callback_handler_install(ASTERISK_PROMPT, consolehandler); rl_callback_handler_install(ASTERISK_PROMPT, consolehandler);
@ -200,5 +224,9 @@ int main(int argc, char *argv[])
} }
} }
} else {
/* Do nothing */
select(0,NULL,NULL,NULL,NULL);
}
return 0; return 0;
} }

@ -18,6 +18,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <signal.h> #include <signal.h>
#include <errno.h> #include <errno.h>
#include <unistd.h>
#include <asterisk/sched.h> #include <asterisk/sched.h>
#include <asterisk/options.h> #include <asterisk/options.h>
#include <asterisk/channel.h> #include <asterisk/channel.h>
@ -26,6 +27,27 @@
#include <asterisk/file.h> #include <asterisk/file.h>
#include <asterisk/translate.h> #include <asterisk/translate.h>
#ifdef DEBUG_MUTEX
/* Convenient mutex debugging functions */
#define PTHREAD_MUTEX_LOCK(a) __PTHREAD_MUTEX_LOCK(__FUNCTION__, a)
#define PTHREAD_MUTEX_UNLOCK(a) __PTHREAD_MUTEX_UNLOCK(__FUNCTION__, a)
static int __PTHREAD_MUTEX_LOCK(char *f, pthread_mutex_t *a) {
ast_log(LOG_DEBUG, "Locking %p (%s)\n", a, f);
return pthread_mutex_lock(a);
}
static int __PTHREAD_MUTEX_UNLOCK(char *f, pthread_mutex_t *a) {
ast_log(LOG_DEBUG, "Unlocking %p (%s)\n", a, f);
return pthread_mutex_unlock(a);
}
#else
#define PTHREAD_MUTEX_LOCK(a) pthread_mutex_lock(a)
#define PTHREAD_MUTEX_UNLOCK(a) pthread_mutex_unlock(a)
#endif
struct chanlist { struct chanlist {
char type[80]; char type[80];
char description[80]; char description[80];
@ -33,7 +55,6 @@ struct chanlist {
struct ast_channel * (*requester)(char *type, int format, void *data); struct ast_channel * (*requester)(char *type, int format, void *data);
struct chanlist *next; struct chanlist *next;
} *backends = NULL; } *backends = NULL;
struct ast_channel *channels = NULL; struct ast_channel *channels = NULL;
/* Protect the channel list (highly unlikely that two things would change /* Protect the channel list (highly unlikely that two things would change
@ -45,7 +66,7 @@ int ast_channel_register(char *type, char *description, int capabilities,
struct ast_channel *(*requester)(char *type, int format, void *data)) struct ast_channel *(*requester)(char *type, int format, void *data))
{ {
struct chanlist *chan, *last=NULL; struct chanlist *chan, *last=NULL;
if (pthread_mutex_lock(&chlock)) { if (PTHREAD_MUTEX_LOCK(&chlock)) {
ast_log(LOG_WARNING, "Unable to lock channel list\n"); ast_log(LOG_WARNING, "Unable to lock channel list\n");
return -1; return -1;
} }
@ -53,7 +74,7 @@ int ast_channel_register(char *type, char *description, int capabilities,
while(chan) { while(chan) {
if (!strcasecmp(type, chan->type)) { if (!strcasecmp(type, chan->type)) {
ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type); ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type);
pthread_mutex_unlock(&chlock); PTHREAD_MUTEX_UNLOCK(&chlock);
return -1; return -1;
} }
last = chan; last = chan;
@ -62,7 +83,7 @@ int ast_channel_register(char *type, char *description, int capabilities,
chan = malloc(sizeof(struct chanlist)); chan = malloc(sizeof(struct chanlist));
if (!chan) { if (!chan) {
ast_log(LOG_WARNING, "Out of memory\n"); ast_log(LOG_WARNING, "Out of memory\n");
pthread_mutex_unlock(&chlock); PTHREAD_MUTEX_UNLOCK(&chlock);
return -1; return -1;
} }
strncpy(chan->type, type, sizeof(chan->type)); strncpy(chan->type, type, sizeof(chan->type));
@ -78,7 +99,7 @@ int ast_channel_register(char *type, char *description, int capabilities,
ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description); ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description);
else if (option_verbose > 1) else if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description); ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description);
pthread_mutex_unlock(&chlock); PTHREAD_MUTEX_UNLOCK(&chlock);
return 0; return 0;
} }
@ -86,7 +107,7 @@ struct ast_channel *ast_channel_alloc(void)
{ {
struct ast_channel *tmp; struct ast_channel *tmp;
struct ast_channel_pvt *pvt; struct ast_channel_pvt *pvt;
pthread_mutex_lock(&chlock); PTHREAD_MUTEX_LOCK(&chlock);
tmp = malloc(sizeof(struct ast_channel)); tmp = malloc(sizeof(struct ast_channel));
memset(tmp, 0, sizeof(struct ast_channel)); memset(tmp, 0, sizeof(struct ast_channel));
if (tmp) { if (tmp) {
@ -121,17 +142,17 @@ struct ast_channel *ast_channel_alloc(void)
} }
} else } else
ast_log(LOG_WARNING, "Out of memory\n"); ast_log(LOG_WARNING, "Out of memory\n");
pthread_mutex_unlock(&chlock); PTHREAD_MUTEX_UNLOCK(&chlock);
return tmp; return tmp;
} }
struct ast_channel *ast_channel_walk(struct ast_channel *prev) struct ast_channel *ast_channel_walk(struct ast_channel *prev)
{ {
struct ast_channel *l, *ret=NULL; struct ast_channel *l, *ret=NULL;
pthread_mutex_lock(&chlock); PTHREAD_MUTEX_LOCK(&chlock);
l = channels; l = channels;
if (!prev) { if (!prev) {
pthread_mutex_unlock(&chlock); PTHREAD_MUTEX_UNLOCK(&chlock);
return l; return l;
} }
while(l) { while(l) {
@ -139,7 +160,7 @@ struct ast_channel *ast_channel_walk(struct ast_channel *prev)
ret = l->next; ret = l->next;
l = l->next; l = l->next;
} }
pthread_mutex_unlock(&chlock); PTHREAD_MUTEX_UNLOCK(&chlock);
return ret; return ret;
} }
@ -147,7 +168,7 @@ struct ast_channel *ast_channel_walk(struct ast_channel *prev)
void ast_channel_free(struct ast_channel *chan) void ast_channel_free(struct ast_channel *chan)
{ {
struct ast_channel *last=NULL, *cur; struct ast_channel *last=NULL, *cur;
pthread_mutex_lock(&chlock); PTHREAD_MUTEX_LOCK(&chlock);
cur = channels; cur = channels;
while(cur) { while(cur) {
if (cur == chan) { if (cur == chan) {
@ -174,7 +195,7 @@ void ast_channel_free(struct ast_channel *chan)
free(chan->callerid); free(chan->callerid);
pthread_mutex_destroy(&chan->lock); pthread_mutex_destroy(&chan->lock);
free(chan); free(chan);
pthread_mutex_unlock(&chlock); PTHREAD_MUTEX_UNLOCK(&chlock);
} }
int ast_softhangup(struct ast_channel *chan) int ast_softhangup(struct ast_channel *chan)
@ -220,7 +241,7 @@ void ast_channel_unregister(char *type)
struct chanlist *chan, *last=NULL; struct chanlist *chan, *last=NULL;
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type); ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type);
if (pthread_mutex_lock(&chlock)) { if (PTHREAD_MUTEX_LOCK(&chlock)) {
ast_log(LOG_WARNING, "Unable to lock channel list\n"); ast_log(LOG_WARNING, "Unable to lock channel list\n");
return; return;
} }
@ -232,13 +253,13 @@ void ast_channel_unregister(char *type)
else else
backends = backends->next; backends = backends->next;
free(chan); free(chan);
pthread_mutex_unlock(&chlock); PTHREAD_MUTEX_UNLOCK(&chlock);
return; return;
} }
last = chan; last = chan;
chan = chan->next; chan = chan->next;
} }
pthread_mutex_unlock(&chlock); PTHREAD_MUTEX_UNLOCK(&chlock);
} }
int ast_answer(struct ast_channel *chan) int ast_answer(struct ast_channel *chan)
@ -392,7 +413,7 @@ struct ast_channel *ast_request(char *type, int format, void *data)
{ {
struct chanlist *chan; struct chanlist *chan;
struct ast_channel *c = NULL; struct ast_channel *c = NULL;
if (pthread_mutex_lock(&chlock)) { if (PTHREAD_MUTEX_LOCK(&chlock)) {
ast_log(LOG_WARNING, "Unable to lock channel list\n"); ast_log(LOG_WARNING, "Unable to lock channel list\n");
return NULL; return NULL;
} }
@ -402,15 +423,16 @@ struct ast_channel *ast_request(char *type, int format, void *data)
if (!(chan->capabilities & format)) { if (!(chan->capabilities & format)) {
format = ast_translator_best_choice(format, chan->capabilities); format = ast_translator_best_choice(format, chan->capabilities);
} }
PTHREAD_MUTEX_UNLOCK(&chlock);
if (chan->requester) if (chan->requester)
c = chan->requester(type, format, data); c = chan->requester(type, format, data);
pthread_mutex_unlock(&chlock); return c;
break;
} }
chan = chan->next; chan = chan->next;
} }
if (!chan) if (!chan)
ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
PTHREAD_MUTEX_UNLOCK(&chlock);
return c; return c;
} }
@ -433,9 +455,10 @@ int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int fti
if (!len) if (!len)
return -1; return -1;
do { do {
if (c->streamid > -1) { if ((c->streamid > -1) || (c->trans && (c->trans->streamid > -1))) {
d = ast_waitstream(c, AST_DIGIT_ANY); d = ast_waitstream(c, AST_DIGIT_ANY);
ast_stopstream(c); ast_stopstream(c);
usleep(1000);
if (!d) if (!d)
d = ast_waitfordigit(c, to); d = ast_waitfordigit(c, to);
} else { } else {

@ -200,7 +200,7 @@ static int g723tolin_framein(struct ast_translator_pvt *pvt, struct ast_frame *f
#ifdef ANNEX_B #ifdef ANNEX_B
Decod(&tmp->dec, tmpdata, f->data, 0); Decod(&tmp->dec, tmpdata, f->data, 0);
for (x=0;x<Frame;x++) for (x=0;x<Frame;x++)
(tmp->buf + tmp->tail)[x] = tmpdata[x]; (tmp->buf + tmp->tail)[x] = (short)tmpdata[x];
#else #else
Decod(&tmp->dec, tmp->buf + tmp->tail, f->data, 0); Decod(&tmp->dec, tmp->buf + tmp->tail, f->data, 0);
#endif #endif

@ -6,8 +6,10 @@
[interfaces] [interfaces]
; ;
; Lines for which we are the user termination. They accept incoming ; Lines for which we are the user termination. They accept incoming
; and outgoing calls. ; and outgoing calls. We use the default context on the first 8 lines
; used by internal phones.
; ;
context=default
;user=voice00 ;user=voice00
;user=voice01 ;user=voice01
;user=voice02 ;user=voice02
@ -16,15 +18,11 @@
;user=voice05 ;user=voice05
;user=voice06 ;user=voice06
;user=voice07 ;user=voice07
context=default
user=voice13
user=voice14
user=voice15
; Calls on 16 and 17 come from the outside world, so they get ; Calls on 16 and 17 come from the outside world, so they get
; a little bit special treatment ; a little bit special treatment
context=remote context=remote
user=voice16 ;user=voice16
user=voice17 ;user=voice17
; ;
; Next we have lines which we only accept calls on, and typically ; Next we have lines which we only accept calls on, and typically
; do not send outgoing calls on (i.e. these are where we are the ; do not send outgoing calls on (i.e. these are where we are the

@ -26,8 +26,8 @@ stripmsd=1
; ;
; Type of dialing ; Type of dialing
; ;
;dialtype=tone dialtype=tone
dialtype=pulse ;dialtype=pulse
; ;
; Mode selection. "Immediate" means that as soon as you dial, you're connected ; Mode selection. "Immediate" means that as soon as you dial, you're connected
; and the line is considered up. "Ring" means we wait until the ring cadence ; and the line is considered up. "Ring" means we wait until the ring cadence
@ -39,4 +39,4 @@ mode=immediate
; ;
; List all devices we can use. ; List all devices we can use.
; ;
device=/dev/ttyS3 ;device=/dev/ttyS3

@ -3,12 +3,26 @@
; ;
; Module Loader configuration file ; Module Loader configuration file
; ;
[modules] [modules]
autoload=yes autoload=yes
;load=pbx_gtkconsole.so ;
; If you want, load the GTK console right away.
; Don't load the KDE console since
; it's not as sophisticated right now.
;
noload=pbx_gtkconsole.so noload=pbx_gtkconsole.so
;load=pbx_gtkconsole.so
noload=pbx_kdeconsole.so noload=pbx_kdeconsole.so
;
; Intercom application is obsoleted by
; chan_oss. Don't load it.
;
noload=app_intercom.so noload=app_intercom.so
;load=chan_vofr.so
;load=chan_h323.so
;
; Module names listed in "global" section will have symbols globally
; exported to modules loaded after them.
;
[global]
chan_modem.so=yes

@ -2,13 +2,19 @@
; Voicemail Configuration ; Voicemail Configuration
; ;
[general] [general]
; Default format for writing Voicemail ; Default formats for writing Voicemail
; format=g723sf|rawgsm|mp3|wav ;format=g723sf|wav49|wav
format=g723sf|wav49|wav format=gsm|wav49|wav
;
; Each mailbox is listed in the form <mailbox>=<password>,<name>,<email>
; if the e-mail is specified, a message will be sent when a message is
; received, to the given mailbox.
;
[default] [default]
4200=2345,Mark Spencer,markster@linux-support.net 1234=4242,Example Mailbox,root@localhost
4300=2345,Ben Rigas,ben@american-computer.net ;4200=9855,Mark Spencer,markster@linux-support.net
4310=2345,Sales,sales@marko.net ;4300=3456,Ben Rigas,ben@american-computer.net
4069=2345,Matt Brooks,matt@marko.net ;4310=5432,Sales,sales@marko.net
4110=1379,Rob Flynn,rflynn@blueridge.net ;4069=6522,Matt Brooks,matt@marko.net
;4110=3443,Rob Flynn,rflynn@blueridge.net

@ -143,12 +143,14 @@ char ast_waitfordigit(struct ast_channel *c, int ms);
for the first digit */ for the first digit */
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders); int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders);
#define CHECK_BLOCKING(c) { \ #define CHECK_BLOCKING(c) { \
if ((c)->blocking) \ if ((c)->blocking) {\
ast_log(LOG_WARNING, "Blocking '%s', already blocked by thread %ld in procedure %s\n", (c)->name, (c)->blocker, (c)->blockproc); \ ast_log(LOG_WARNING, "Blocking '%s', already blocked by thread %ld in procedure %s\n", (c)->name, (c)->blocker, (c)->blockproc); \
else { \ /* *((int *)0)=0; */ \
} else { \
(c)->blocker = pthread_self(); \ (c)->blocker = pthread_self(); \
(c)->blockproc = __PRETTY_FUNCTION__; \ (c)->blockproc = __PRETTY_FUNCTION__; \
c->blocking = -1; } } c->blocking = -1; \
} }
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)
} }

@ -92,6 +92,22 @@ int ast_load_resource(char *resource_name)
int errors=0; int errors=0;
int res; int res;
struct module *m; struct module *m;
int flags=0;
char *val;
int o;
struct ast_config *cfg;
/* Keep the module file parsing silent */
o = option_verbose;
option_verbose = 0;
cfg = ast_load(AST_MODULE_CONFIG);
option_verbose = o;
if (cfg) {
if ((val = ast_variable_retrieve(cfg, "global", resource_name))
&& ast_true(val))
flags |= RTLD_GLOBAL;
ast_destroy(cfg);
}
if (pthread_mutex_lock(&modlock)) if (pthread_mutex_lock(&modlock))
ast_log(LOG_WARNING, "Failed to lock\n"); ast_log(LOG_WARNING, "Failed to lock\n");
m = module_list; m = module_list;
@ -115,7 +131,7 @@ int ast_load_resource(char *resource_name)
} else { } else {
snprintf(fn, sizeof(fn), "%s/%s", AST_MODULE_DIR, resource_name); snprintf(fn, sizeof(fn), "%s/%s", AST_MODULE_DIR, resource_name);
} }
m->lib = dlopen(fn, RTLD_NOW | RTLD_GLOBAL); m->lib = dlopen(fn, RTLD_NOW | flags);
if (!m->lib) { if (!m->lib) {
ast_log(LOG_WARNING, "%s\n", dlerror()); ast_log(LOG_WARNING, "%s\n", dlerror());
free(m); free(m);
@ -149,16 +165,24 @@ int ast_load_resource(char *resource_name)
pthread_mutex_unlock(&modlock); pthread_mutex_unlock(&modlock);
return -1; return -1;
} }
if (!fully_booted) {
if (option_verbose) if (option_verbose)
ast_verbose( " => (%s)\n", m->description()); ast_verbose( " => (%s)\n", m->description());
if (option_console && !option_verbose)
ast_verbose( ".");
} else {
if (option_verbose)
ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description());
}
m->next = module_list;
module_list = m;
pthread_mutex_unlock(&modlock); pthread_mutex_unlock(&modlock);
if ((res = m->load_module())) { if ((res = m->load_module())) {
ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, fn, res); ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res);
ast_unload_resource(resource_name, 0); ast_unload_resource(resource_name, 0);
return -1; return -1;
} }
m->next = module_list; ast_update_use_count();
module_list = m;
return 0; return 0;
} }

@ -25,12 +25,15 @@
#include <asterisk/module.h> #include <asterisk/module.h>
#include <asterisk/logger.h> #include <asterisk/logger.h>
#include <asterisk/options.h> #include <asterisk/options.h>
#include <asterisk/cli.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <glib.h> #include <glib.h>
@ -42,6 +45,9 @@ static pthread_mutex_t verb_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t console_thread; static pthread_t console_thread;
static int inuse=0; static int inuse=0;
static int clipipe[2];
static int cleanupid = -1;
static char *dtext = "Asterisk PBX Console (GTK Version)"; static char *dtext = "Asterisk PBX Console (GTK Version)";
static GtkWidget *window; static GtkWidget *window;
@ -50,6 +56,9 @@ static GtkWidget *closew;
static GtkWidget *verb; static GtkWidget *verb;
static GtkWidget *modules; static GtkWidget *modules;
static GtkWidget *statusbar; static GtkWidget *statusbar;
static GtkWidget *cli;
static struct timeval last;
static void update_statusbar(char *msg) static void update_statusbar(char *msg)
{ {
@ -65,26 +74,101 @@ int unload_module(void)
gdk_threads_enter(); gdk_threads_enter();
gtk_widget_destroy(window); gtk_widget_destroy(window);
gdk_threads_leave(); gdk_threads_leave();
close(clipipe[0]);
close(clipipe[1]);
} }
return 0; return 0;
} }
static int cleanup(void *useless)
{
gdk_threads_enter();
gtk_clist_thaw(GTK_CLIST(verb));
gtk_widget_queue_resize(verb->parent);
gtk_clist_moveto(GTK_CLIST(verb), GTK_CLIST(verb)->rows - 1, 0, 0, 0);
cleanupid = -1;
gdk_threads_leave();
return 0;
}
static void verboser(char *stuff, int opos, int replacelast, int complete) static void __verboser(char *stuff, int opos, int replacelast, int complete)
{ {
char *s2[2]; char *s2[2];
pthread_mutex_lock(&verb_lock); struct timeval tv;
int ms;
s2[0] = stuff; s2[0] = stuff;
s2[1] = NULL; s2[1] = NULL;
gdk_threads_enter(); gtk_clist_freeze(GTK_CLIST(verb));
if (replacelast) if (replacelast)
gtk_clist_remove(GTK_CLIST(verb), GTK_CLIST(verb)->rows - 1); gtk_clist_remove(GTK_CLIST(verb), GTK_CLIST(verb)->rows - 1);
gtk_clist_append(GTK_CLIST(verb), s2); gtk_clist_append(GTK_CLIST(verb), s2);
gtk_clist_moveto(GTK_CLIST(verb), GTK_CLIST(verb)->rows - 1, 0, 0, 0); if (last.tv_sec || last.tv_usec) {
gdk_threads_leave(); gdk_threads_leave();
gettimeofday(&tv, NULL);
if (cleanupid > -1)
gtk_timeout_remove(cleanupid);
ms = (tv.tv_sec - last.tv_sec) * 1000 + (tv.tv_usec - last.tv_usec) / 1000;
if (ms < 100) {
/* We just got a message within 100ms, so just schedule an update
in the near future */
cleanupid = gtk_timeout_add(200, cleanup, NULL);
} else {
cleanup(&cleanupid);
}
last = tv;
} else {
gettimeofday(&last, NULL);
}
}
static void verboser(char *stuff, int opos, int replacelast, int complete)
{
pthread_mutex_lock(&verb_lock);
/* Lock appropriately if we're really being called in verbose mode */
__verboser(stuff, opos, replacelast, complete);
pthread_mutex_unlock(&verb_lock); pthread_mutex_unlock(&verb_lock);
} }
static void cliinput(void *data, int source, GdkInputCondition ic)
{
static char buf[256];
static int offset = 0;
int res;
char *c;
char *l;
char n;
/* Read as much stuff is there */
res = read(source, buf + offset, sizeof(buf) - 1 - offset);
if (res > -1)
buf[res + offset] = '\0';
/* make sure we've null terminated whatever we have so far */
c = buf;
l = buf;
while(*c) {
if (*c == '\n') {
/* Keep the trailing \n */
c++;
n = *c;
*c = '\0';
__verboser(l, 0, 0, 1);
*(c - 1) = '\0';
*c = n;
l = c;
} else
c++;
}
if (strlen(l)) {
/* We have some left over */
memmove(buf, l, strlen(l) + 1);
offset = strlen(buf);
} else {
offset = 0;
}
}
static void remove_module() static void remove_module()
{ {
int res; int res;
@ -194,14 +278,12 @@ static int mod_update(void)
if (GTK_CLIST(modules)->selection) { if (GTK_CLIST(modules)->selection) {
module= (char *)gtk_clist_get_row_data(GTK_CLIST(modules), (int) GTK_CLIST(modules)->selection->data); module= (char *)gtk_clist_get_row_data(GTK_CLIST(modules), (int) GTK_CLIST(modules)->selection->data);
} }
gdk_threads_enter();
gtk_clist_freeze(GTK_CLIST(modules)); gtk_clist_freeze(GTK_CLIST(modules));
gtk_clist_clear(GTK_CLIST(modules)); gtk_clist_clear(GTK_CLIST(modules));
ast_update_module_list(add_mod); ast_update_module_list(add_mod);
if (module) if (module)
gtk_clist_select_row(GTK_CLIST(modules), gtk_clist_find_row_from_data(GTK_CLIST(modules), module), -1); gtk_clist_select_row(GTK_CLIST(modules), gtk_clist_find_row_from_data(GTK_CLIST(modules), module), -1);
gtk_clist_thaw(GTK_CLIST(modules)); gtk_clist_thaw(GTK_CLIST(modules));
gdk_threads_leave();
return 1; return 1;
} }
@ -220,8 +302,12 @@ static void exit_now(GtkWidget *widget, gpointer data)
static void exit_completely(GtkWidget *widget, gpointer data) static void exit_completely(GtkWidget *widget, gpointer data)
{ {
/* This is the wrong way to do this. We need an ast_clean_exit() routine */ #if 0
exit(0); /* Clever... */
ast_cli_command(clipipe[1], "quit");
#else
kill(getpid(), SIGTERM);
#endif
} }
static void exit_nicely(GtkWidget *widget, gpointer data) static void exit_nicely(GtkWidget *widget, gpointer data)
@ -239,6 +325,17 @@ static void *consolethread(void *data)
return NULL; return NULL;
} }
static int cli_activate()
{
char buf[256];
strncpy(buf, gtk_entry_get_text(GTK_ENTRY(cli)), sizeof(buf));
gtk_entry_set_text(GTK_ENTRY(cli), "");
if (strlen(buf)) {
ast_cli_command(clipipe[1], buf);
}
return TRUE;
}
static int show_console() static int show_console()
{ {
GtkWidget *hbox; GtkWidget *hbox;
@ -276,7 +373,7 @@ static int show_console()
gtk_container_add(GTK_CONTAINER(sw), verb); gtk_container_add(GTK_CONTAINER(sw), verb);
gtk_widget_show(verb); gtk_widget_show(verb);
gtk_widget_show(sw); gtk_widget_show(sw);
gtk_widget_set_usize(verb, 600, 400); gtk_widget_set_usize(verb, 640, 400);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), sw, gtk_label_new("Verbose Status")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), sw, gtk_label_new("Verbose Status"));
@ -334,13 +431,20 @@ static int show_console()
hbox = gtk_vbox_new(FALSE, 0); hbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(hbox); gtk_widget_show(hbox);
/* Command line */
cli = gtk_entry_new();
gtk_widget_show(cli);
gtk_signal_connect(GTK_OBJECT(cli), "activate",
GTK_SIGNAL_FUNC (cli_activate), NULL);
gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 5);
gtk_box_pack_start(GTK_BOX(hbox), wbox, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), wbox, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox), cli, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox), statusbar, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), statusbar, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), hbox); gtk_container_add(GTK_CONTAINER(window), hbox);
gtk_window_set_title(GTK_WINDOW(window), "Asterisk Console"); gtk_window_set_title(GTK_WINDOW(window), "Asterisk Console");
gtk_widget_grab_focus(cli);
pthread_create(&console_thread, NULL, consolethread, NULL); pthread_create(&console_thread, NULL, consolethread, NULL);
/* XXX Okay, seriously fix me! XXX */ /* XXX Okay, seriously fix me! XXX */
usleep(100000); usleep(100000);
@ -348,6 +452,7 @@ static int show_console()
gtk_clist_freeze(GTK_CLIST(verb)); gtk_clist_freeze(GTK_CLIST(verb));
ast_loader_register(mod_update); ast_loader_register(mod_update);
gtk_clist_thaw(GTK_CLIST(verb)); gtk_clist_thaw(GTK_CLIST(verb));
gdk_input_add(clipipe[0], GDK_INPUT_READ, cliinput, NULL);
mod_update(); mod_update();
update_statusbar("Asterisk Console Ready"); update_statusbar("Asterisk Console Ready");
return 0; return 0;
@ -356,6 +461,10 @@ static int show_console()
int load_module(void) int load_module(void)
{ {
if (pipe(clipipe)) {
ast_log(LOG_WARNING, "Unable to create CLI pipe\n");
return -1;
}
g_thread_init(NULL); g_thread_init(NULL);
if (gtk_init_check(NULL, NULL)) { if (gtk_init_check(NULL, NULL)) {
/* XXX Do we need to call this twice? XXX */ /* XXX Do we need to call this twice? XXX */

10
say.c

@ -42,8 +42,13 @@ int ast_say_digits(struct ast_channel *chan, int num)
int ast_say_number(struct ast_channel *chan, int num) int ast_say_number(struct ast_channel *chan, int num)
{ {
int res = 0; int res = 0;
int playh = 0;
char fn[256] = ""; char fn[256] = "";
while(num && !res) { while(num && !res) {
if (playh) {
snprintf(fn, sizeof(fn), "digits/hundred");
playh = 0;
} else
if (num < 20) { if (num < 20) {
snprintf(fn, sizeof(fn), "digits/%d", num); snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0; num = 0;
@ -51,10 +56,15 @@ int ast_say_number(struct ast_channel *chan, int num)
if (num < 100) { if (num < 100) {
snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10); snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
num -= ((num / 10) * 10); num -= ((num / 10) * 10);
} else {
if (num < 1000){
snprintf(fn, sizeof(fn), "digits/%d", (num/100));
playh++;
} else { } else {
ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num); ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
res = -1; res = -1;
} }
}
if (!res) { if (!res) {
res = ast_streamfile(chan, fn); res = ast_streamfile(chan, fn);
if (!res) if (!res)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,5 @@
Ó™ÕS^ÀͪUe ³M-WƒVÀ¹˜J[¬¡jm¶éÓè#àÀÖ­CKœá8ë1·äÁ8Ô±jMo!¡ú¿iÒv°sdH ±ÛebÂ,<2C>Ö…´Ûž%”^$)n8ÄÒkú¥k¤Å¨æòÓ¢ÈãGâµ ˜oŠ6åñ™Ú„Ód4 Ò5ª!kЦÛèØdŒÃÈ“•;?Œä‹‰×*<2A>$&Ür[„Ò1á¤ë¶ƒ%™¶<03>D9^Ô:Ü‘"‘Ú€Æ]#ÙðV½Ò4Ð᳉"ó"qÉ/!a&<26> €‡â'MðÛÆÃZi”Ò3èis…¹ ²U<14>ãÕ!ŽÇ ",Þ<>öÙ}âµ<C3A2>W ÒqÑe{{Ç)Ž;o{åƒT­²Âw¤4üE(s*(ÛMLþÓs“žyw<79>U¨¢rÑI¾-ÄâqPµ QúmkMá¤NÁÔ/”:qÎ/'je*o³§ט¤m2äÙ.'oo®+ÓçcÔmœ[xÛ°¶ä7@³ÙQÄêžS\kQ¸ÔjG=ÙPŠ”P¶ÕÔ,¬_pk¯¥Û磌k<C2AB><62>áCisÇ f·ÙÓMTÒp6%Ó¬¬_pkPߎUÆÔÓÏVü5wk®Êãxd5n<35>1´Óë“×:kp=ÚRÆ¡ÚíX+»è
ÜJHÉ…„æäÌÿJÇbÓêyÞkî©—“¯h<€Ç9[…¸×~Èh$‰Ê؃솲9[ÔjjîÅhÊôfÊ…#»ñD„¥ÈÄi·¬…^
r4ìÓjƒgq…¨9Rrþ4¼ˆÐœR„ˆ‰ÉW5AÙ“‰¯u0þÓ«d3©¨ò¿ŒÎÔ‰§Ä
‰=p‰(ÄÜQ½X“((͞ѤÓç„ghçLK¬h“˧cÔ;"<22>0ÂS¡ )\ééTÓ(Œç``«9km&£ ÉfªYc<59>¢Ä«'±2žEÓ)u3 ÈC>Uͯ réqR#¶BV¶Ü¯e¸M$îÒå„ê(´¤dÅr+cºÆ¶ã7À£ûe!¦ë¨ä5"•„ÒŸweà°ÄG.öSžÄFäÍÙ²£óZ±ÚÂb<C382>{[¹ŠÓW
³b •NÏd±Ôºî@ò·Ä£º<C2A3>{¢"× ÓN"™³5,ªÔ³"«'°«µãFÛ<46>´ŸZˆ—ÜâÓ]UÞY`!®ûQɱA<C2B1>«;v_AØÜ¹Ò<C2B9>³ÁB¦…ÔjÒ^†áT¢ªŽs[¢<>Ûe¨Ó¦@ç±îV“Ö@¨Š,S¥Ò^S¥"à ¾õ²ÄÓ¦Áäm´ãØ€Ùœ‰["À€£+mGYÓ s™Zž€¥¬µÉnÖ å£rE3| ¸ÓqÄ¥Ç@öá®Á-ÒÝjœÚfÀ¼ò­Ø´ÄàÏrMÌ¢Þ £T1†<31>À¯uš76Ô jaX” Çli,˜ ¶ÓLÕ“Õ@¤™<C2A4>Å!E"<22>"îÓßzÙQŒ ã6”·òªà·"ˆ´êÆ Ë!±¥SpÀÆòŠ8ÕÒÝZ\ÙX Æì®MZàºã‰\l §h*'@êÛE­Ò<C2AD>bÔ@8ì—[;ì`µK­bBÃó˜à_S}u

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,4 @@
Õ-£R¢4t`Ö¡f¢¤¥<C2A4>* Â¶«4;p¢Q²I^œÖ<C593>y`©»"ŸIVš˜<C5A1> <0A>c,ÒÀâU\OÚ« ÁË¥Uòó×èxÝÙ|¢(­V£™Œá™©sSŸ˜¢ÎÍ4¤Ö[xØØ¡†¥±FͺÂÙnD¨ÜÂ6ͦç(œâ¢5fÈÕœ`˜Y»#ÊÕfh ßøänÍCçbÔ¢7fY$´§i7&Ô<>r¡rw%(ª‰ÖƒÈÄãm¸6X…T0&Ë›+7,¶±%Ô¦dè_Í4äûÅ\lÿ¶6îy[uDny13#nJÆÕ&u8Šîà-`Â]wÐ;ðIÆ“wQ$‹ŽÚ+°°²¡Ôét¦øëRK„m8äw1”“q[ul&ä1…®u0ê,<2C>ÉLÓê|æ±ç/4¬ $èÐF̉IotÍŠ«iÆÚèï9%îãÔ*[ZrîÈÈ42',îÈ„³>™[}E¿åÓ&v¦Õa8äÔhdò}äô+if}ÈFãyÕâvÈà,V{¥C„qªÅÔ¦cß1{é9$×A%Žè
D)vw¬KD²'#wì¶íÓæcë0qh†ªE)Ws <%m·bçG7-¸.“æË%ZmË·Òålç(æ©#hÇè†Çc¿ˆ´ìç`­mÉ¿îÅŽeq¥iÒ%§™x¦9wÁ³=K¤ñCx49-zåÉm¢G#Ò&¦Xá ä¥Në{B€ËÆ4¥~û]ò&㢢(ÉvɧÒ'¥$é€Â-D<>°ÓÒatùK­àI +5ê<>ªõvù¤ÓàL ÚPág˜¤n°¡Lšój3ê<33>Rà)w¤¡èä•Ú×bš$¢’¡Û •1%<25>忏Þ.ÈĦD¿d<C2BF>XœØ¥%"ê¤=³m²£G Ú ÆËl¤8øµLÓ¹i(äÆÜØh‰]pj†Ý<15>Œ†ç;о¥„¨Ø<C2A8>½¹<¡«fnÞãØdp<64>qŒ§kœ}9i´ÆÉS´¦ÀÃãÀøþdå½­NhÂÕLrè<72>h8åûºdǶÁ@¸îƒ¯ËBmÆã}-H“È$ÕžD÷(˜ªI<08> ƒhÉò©¦Û<C2A6>h\M…7?…¨bìÉ=ÕE¾ØG'oÊœ¨¨%’²Ä<12>“7øYÔ¦
h"LÔÝU¾<55><C2BE>å²ún<ÑMUm“J²ÁÔ“e´ÛqÙwÔnyIÜ…´° ]—d´ãIÛX¦¦ZäMÉP¢É#³Ç¤Óžv¹
¶Ú<C2B6>Ç<10>dcšy¡"Äj¶[¡A$þxÒߥ¸œ¡Â.HË¡ÂZR?•Z£4<C2A3>$‚§PJ}QÔÝMù³Bò«ƒÜnYbRĉ%mÉ"¥¤jÁæ°fÓßf­Y¬¤Tq¦¤³"”e—-¶¤km8ܶâ6âmÂ2Ò$¥ì™·!Šæ¾é%laµÒݼÁ¡×ÊÉm¾!¤±ÇdÒŸfå Ç#·I½a×H²fÚ»a¹#jE̹AÅs²Q#Ò vd¢àÀÃR¶H¹!‡NJíT<C3AD>"ß©—"¹A&Øn¨Ü

Binary file not shown.

@ -0,0 +1 @@
Ô À¦írXS° ¦ì)ÔœºàZ¬Ú<C2AC>_œÀÉ&j¦âÒzXÐh€r‰ÁEþ†€Ôô<C394> ÙªY3” É#M8[Ôà‹ÙÖàÃQ¸ãÔ 'esYžà Ë­RFåtÀ N$<24>Ò]zœÙÄ€+!e#4êàÊÔ¾¹cr€æãÀÄâ<C384>ÂãÒÝj™RÀ¹8®€34Q…„àoóÕW—ðÀ¿q<>dÜâb@©]n=€·ªÉ<C2AA>ðà6ßhÁ¹ù¶ÑÒa‡]Ùua„“i˶ƒCJV8š‡c4Û“È%¹D&Y1£ÁÔhr§0ƒìÉlèÒª(ÐÙ>ƒM<C692>RvÄ܃Ìʼn¯Õkr_(<28>f'v­ér&£}î7$ŽÁڬȘ¥8çÕª—p{ÍXÏMÈêy­&š™ï†ŽÌá<18>†¯ñŽW¹m¶ÜÔè{XwL¤ÛpÞàéÎ(°gë-½DÒ'ul&ì›ÖÕh[_Ru(ˆ 1}éêô1P¼Ís+8ï¼lR;gÖ$K_aç j•´Üo͸ð<C2B8>X¥o+'¾Ñ*Ù ÜC¶(çÕ_LòØÛj±äÛ'š·p!ËÚÈ#<23>wîŒì)—N¹gÒ'¥ÙRÚ‰]Ò)ØÛÚDÆìÜD£ÜCÖÕÊ[pîBu+ÛÒcdâèƒ[e ¨ÜÚ <09>IéãÊ¡E]¯!¤Ü¢7ôÅTÓb|!RîÁ#Y$óª@è#Gäì4}’–ÔŒÀþ]ÏYjÒžc-Q¡DŒRÌêÁ'#i©!n ¥Ý9˜r «jØÓ×"r<>qA;JÇéÉÖ¤ÜzãFZq )ˆÅ±M),ØëpLêØ„*0ܤg9´íéfÆÝÛžwZÅ+¨ƒ©Ùêš)QHF*…º›¶¥<¾“»RÇEäv;\žÆG(}(ŒÙkiÉhÌ…ú<E280A6>:dÅæ-MªãÈÃIÚü«dz£¶€*Ö_$2à˜ƒ2 )Ûv€ãzÒ)¤¥ëˆ¹mŸ——ã<E28094>̽ýÖ^<öàƒdÌ©3uŠÊ°[M½´Ž„!<21>¡Y<59>F*íhÕ]E·è&¦Ò£g©ZX<E28099>ì<04>š&Ê¥%8T-¤ÕÝE;î„•€£$¥ä: iÁ}Vä<56>nnIš©ÃË-çTãÖ^<ûð¦z„u”«å¸âŽË7«Go[®Ç#©ÄE"x8œÕM{©DGõŽ´•žBÏYl(R«EÈ뾬¯ÇÇ#r63Ô˜¦„”Nµ¡ R¢™£\ °ãå»ú<C2BB>°ÂˆLq¶ÐÒ'Å¬šªƒ RjˬÂan×[¦á»+u[îîs:¨8¥Ò#Žä¢§dɪ'$VBÚ±¶í¾!WXMÄ´¡MdÇZÒßn]baÃIj Pƒ'/Ö¦å¯!Å,±<>ª¢ÜzéÒŸe]"«bQ)¨˜«A)«eÍfáORT˜«`³“UªÞÒt¥"ØÁK"Œe¦A&ÍŽ¨ãä€Ù<E282AC>¹ÉXà€©ªóÑÝK%šÀ¥*+Þ€Çd²ÌSTÀÆ)²"e¾À¶œnC+

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,4 @@
ÓßiŐ Ěé·Hśbŕ¶Űvó̠ÉӍʤnŔDáX˘oÓ]z"´ X$9»S˘ <[s(ÂęŔ©!vEUvŔ }¦@—ČüR YWú+\€<ËÂpŔ3®<>ÚŇ]zYŔ —*Q·+ć€Ů,§KzŔÔ­Qäh §v,ăÔß‚`Ůրɣ‰Ç$´€ÖԌȢfŔô«Ą€ŕ¦ËŇ8ŞŐˇzYĐŔ§aŃÉ"r`ß—Y¨ŔÄÜ”í$š€%ŠIŠÖéebćÁFŇQ"ŤńâÉ&·Ë¶_ËČͶAdRH1«M"šÓ1ž:ZD<5A>@)5$ęCW[ýľYĚG#mą/aÎÚ$dÔ•ÓđşÚ=]°9¨É$sÎ"ł÷+qĄYn qďC[v%ČÔŻĂŐ˝qϸ/ś9qQ8!ŤM <C2A0>äâˇ0*qńVă¦8¨ÔńĂ™üo­väĘÖ'mP7L))/oŤQ[ň*ťmí9'†¨ŮÔň»Ůűoş#V]Emm3<6D>¦%ŻŰĚĂÝĆ×>mÎÇ\8śÔółÖ:×ńĹm7ĎŮŽę”Ű"o©ŔÔ¦ŘŰQĆäĐHÜÔ±Ľ;oĚŽW*émÔęf1
oĚMn·cÝé*4·ĺ/Ôq
¤J)/qŹzr«#áđÇ#7#ß3Ľ*n=˘Ő2ł™»đ, ©ÜăpíĂÍĆés®XٞN[u hĆ"źŐ1´R:uŻ22†«Uu®™SŽtów,ÁaM#/í1Q]MGEŐ2Úyď©Ę*ă{yůr9|{­#âŤČ˘}Î'^ŤŐq”zľŃÖÚ'}1oErDě<44>O¶ˇŻůDĆŃI[l<10>Őm”y<>­ĆL˘Öއ®Č4ÍUÂŇqdP¦ë‰ĐH˘ŤÇ„Ő­<C590>ŢůزÉ#u&ĂŽ<C482>Á,ţ"N«ťQ†<14>ĐËőG#ŐŞ„"¸—0FÜc'$• } µÇ#—o6ŕ·%*Îu¬F“Őčt¸«Čúm <0C>ÜĚń}*<2A>fźjş¤˛]| ŠtdhşĚÖ§[Ňąˇë3K©6…ćŚzg„ČKŁIxsĚęŚo…PŐfKŢů§ĚVč­É¦¦}Nµ¬ ©5u8«H{Zj7ÔçBÚ+®ŞČŰlW°Ä­Ś";5¦bŻÝ@äÄcmľ»Ô"RŁŞŁÚĚŤM˛<>ä}ŰěĘ<C49B>ęâÇ đaÖ%l­k!˘ÁX¬QzćŕÜĺw•w¸<77>,¬-Ő+đÁDś6ŰÖ"z"Tá\qŤ%"|ÁY5ŽË'˛ˇY'DŽTÂI±OŐ¤ZÂfÓq‡Ş<E280A1>á,Ű­Ů®ČÁgbĄŰęÄA\rMS$Ô%QŮጡ—Cmȥ΀¨…˝­ĚÎA[j<Ěî öŠm Ó!iŕŕ¤Ó1,™ę<E284A2>f]ŠY[ś Ő5Ž&Ô´ ˘Ó<CB98>ČŁÓj]Ůę ĘÖČóÚŕÖôŽYcŘŕčäŽW[Ž€»
<EFBFBD>»cŇ]z<>âR Ř“ÉT¸€É${VěÔŔ*«CĚ­ˇ`Ç n'Ňťsbŕ·ŕŔë#ŽG,”€lĺ•răÚ€¦ĄŤšă

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,5 @@
ÔEP™ˆáZüSÉ]ŸÁX|ûÔÁ|<7C>Lo39\AT-»VÒfr¡Y„¡Í;2|­VN6ÓÊ€fGHðA(Ýi
Ò§zÙ—!)a]mRàó+u£
”Á"e$Kk”¡Eâ­eÒé•Q„<51>ŠJÙ¬p¡‡Q4<34>ÀÃfÁ%ÐÁ\ÜVëÒhƒQ!dmrL¯láj[°Ûu¡8S$Z<>XÁPl)ZûÒ£e¨cQe+Û·By%j¬Ê[#:Ýœ™kâÈŠqôÒ¤vlë¯%¤N1¢o&×|rÄ¢oC² OÖl)ÑoÒç…-ªoÃ÷££KáÊ©ŽTœk-µ$vÖ$kÌ:\<5C>´Ó©lz°iMÑuNÅk-;wU²ãi¬ LŽ££iéÌœ•Y˜Ôh\êøijyCÔ&×ÏìkD¤¸Ùg,š•ñKK͉ÂèK*Óèm£(g v• ѦeNÑ$jµË ƾÆâËMÔå—¶ÛÔhTâðË-4,R×z|«(ȃ®gLÌm4ãkHù5¿'#Ô¦Ri°Ê)ÒNÍkæEˆÀ§µÞ‡6MÆäÀ¤=b¿m|Õi¬¨»CHÄù1Œ¦Gñ'nÀ„§Ü©i¢Ê£½.ôkÕid©®ã!œt±¯$» Ù¯%x¥
«xã&%‹Ö€è°Ê㙌ÆtdâäËAÕ¤"Ö¤2!­(ý™%ÓvÇkÓãsq¸ge.Uy´oɨ;mwîšfÌ8mI7£)&#•Ó%e*øv¬³-Ø9"vêG¡)/}Èê,Úä<C39A>ÿ—äÓÓãL*x¦È㥀ö¨XàSfš„Æ3CWKiª‡Ðãr¶Óßbqû‡È­æXÃU(•Ž§Ú¦iÎÔŽ…Ï<>Òb£¬êrD}*2©ŒCµH‰Ù,î"¹X•âîâ"‚…:õÓž«mšV»ã)GBRU]r¤ÄAú׊ñ".f*­*ØZƒiâÜ¢ û»©#éîÎJßë¬1$m¶Û„¥É7y¥CÚ”q&°e´<65>š|öêF Ù¡ê§§Dm)¥z…òP<C3B2>(§ÕZr-pÉÙ­9+¿IÆÛ Æî<C386>îãZƤÈÙÍÄïÓ£m.q™l-Ñ<ä’å`j.ýÿP¤ˆ­V·[—FI“¶îÌÓ¤mjñhÊHãnDÄ—%!T¶êĘÅÅ$ÉÔ„—Ķ¬Òæ}æ°š†¦£m±š£#¯­;&ŸgÊÛmsZ<73>$ù¬íÆÓÒæefø ¢*ÁœÃNüÅúËÝEˆx ãÍä­¨ÜÓ¤c©ù¤Ä:ì–¬¥Å)LòµmP¢â«ÑÁ¨Âš²èBÔ_™i¢Üâ Qr˜±C½kù¹S¼ÂEoFêÀŠf¦Á×<15>éSÒæ<C383>U´¦èã[4—ÉfÕ$Tü2˜Ä^¥KrF+Õ˜aìár„$ÁáB¡R¢¶õŠüŦ¤MÕmÚßê£h˜1DÑÖXmazâ¥"mú©#·w†)Tæ1êƒâÜ„„ZÃ<5A>°Ò×”zeS¼"¶ÖXûšàM”{°äX5“Å­€¥McˆÛAÔØš%[Z³„ŒÓŠk%tlé®Ã5\z©°°ã'ýy(eÔ"¢a[¦¢Áj «T¡ù]N7ï¤PêºidÔKeŽ
©Õ“YÜÁñ&¯^åú§¬6ÛjáÙLßf„ƒ×±6Û

Binary file not shown.

Binary file not shown.

@ -0,0 +1 @@
ÒdŠ”ÛÆÀëŸB6ëªàËq4TŽR © ˆ ¡ZÝwUMÒ¤ƒÙ¼ÁE ü•k\`§ž†êçÂÁ9”)ÔÌÁÄØi©%Ñ,Ö!#kCÛîIÇtÂ&YjÚÁ¨ÃØ…U*ä‚»;ÅÌ¡ÑiÍ¥ªÂ¨\©Íþž¢àät´ ƒ% sÀ®lâw‰é£&ÑéÃõ°}"ÔÊdšyb±ÿH^{C%$m¸þy§ºäŒzÓ(„vøs*6ÜÞ„ËsÌÛh»|s¬©7ÆÞql;l¢õÔ(Œ.¸áÌ•4Skr¬ÔÐa0oŒKÞV>ìoªh¦œ‡Ó«„v¹q®W˜oJtM‰¨<E280B0>Ý.]âñ«cmÌ[؆@ÊÓk¤®©ÛLDŒE¡îmÌI6vþöÛ.7í=Y#ÛŒú¥<C3BA> Óªœn¹Ü°P4_o Ü~³wvqŒÛ­÷7á åt%…öÓé£îzs äÃI¼ÓåO·½V¶äw«nÙ<6E>$Ñë0FÔr8Ó+¬®iñ ƒ¼15}lËzyQ”<51>ÔÔrHØ<48> ¨k±†ÛÓ,”n±„«õLHHž… ß—½ÉUŒÍÈ,f[PÚɪin Ò줪r<C2AA> B··ìâKÉ¥•¡ ¯m¸×Tä©}K  ‰Òp«n¢“&}ëª'5Ž§Ã­襧T=€ªÙæÉ4ÄqËýÒn²®ª•dŒé˺”èDÔvûW°¦F <>È•E*Ï©,Ònâê#•#G-¿3•%´åú†²“âéa„Š•;;¢¸<C2A2>ÒpÓi¬ŒÄ÷Zm—5“¥éæn¶š<C2B6>H0ÒJ(ì‘$PrŠ8<C5A0>Òj³àì<C3A0>æ4ä¾]®£¨‹–€[އÆäQ\sc!bDÒ/kR*ˆ£é»F©Œ¡SS§…&ì‚&å(‘ð"»$·ÒåÒeœ<65>†áĤp,Œ¡ÀñI¬äÁYúêùsš!i“M6Ò%“X\ª¡”ÃFÒÍî¡M·4Þ|ÀïYñ'=à`S°¦™Ò!¢™ê<E28099>6ÞE·ZjÁWl½Ç5\áÇRÁY)a5Òf¢•z¡N¦Ö%]j¡)_Õ™Ô®ÁE= ˆá+q.K ÑbY³Aº£·Ý ¡5²UÆÜ<C386>¦ÜÔ€Õ¬zØMÑâ™Zƒas-Ë8ÛŽ<C39B>x]®fÛ|Á´#L¥ªÁI±Û,Ñ"™š¤<C5A1>)4uØ,ÌÁ$ÜQ‰š Æår=òÐ<C3B2>i²È¹,Ѥ‚ØÒðá £…ÆdcA5/ZSÈ Êô=[¦ái*±ÆìÑeŠ<65>Ûð!HڊǺàºY­JVŽ §iæÝ¬ÁH¯Î«ZÑer"pÁ<ØŒÅK¸Á'ÉÃ#RÁLæ‰i5àÀùŸ±¬áÒ©r“ÜáYaJá`¡3c*ˆÁÞÝS/vdÁ$´É 'Ô*«YRÖ¡¥znKÄpÁ†"@<40> Ó°¶ÁpÁ±/Eó

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save