aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-08-21 02:11:39 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-08-21 02:11:39 +0000
commit8b0c007ad990aa27d9868da49215fd1076ac77cc (patch)
tree270b9c46c1e644483d6d2a35b509f43218ba3252 /utils
parenta42edc84034f91932a3e12d503e07f76a6eb498a (diff)
merge new_loader_completion branch, including (at least):
- restructured build tree and makefiles to eliminate recursion problems - support for embedded modules - support for static builds - simpler cross-compilation support - simpler module/loader interface (no exported symbols) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@40722 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'utils')
-rw-r--r--utils/Makefile34
-rw-r--r--utils/ael_main.c4
-rw-r--r--utils/muted.c688
3 files changed, 710 insertions, 16 deletions
diff --git a/utils/Makefile b/utils/Makefile
index 1d7a9512a..ad42e859e 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -16,7 +16,7 @@
UTILS:=astman smsq stereorize streamplayer aelparse
ifeq (${OSARCH},SunOS)
- LIBS+=../strcompat.o -lsocket -lnsl
+ LIBS+=../main/strcompat.o -lsocket -lnsl
endif
ifeq ($(POPT_LIB),)
@@ -51,23 +51,23 @@ clean-depend:
clean: clean-depend
rm -f *.o $(UTILS) check_expr
-$(eval $(call ast_make_final,astman,astman.o ../md5.o))
-astman: LIBS+=-lnewt
+$(eval $(call ast_make_final,astman,astman.o ../main/md5.o))
+astman: LIBS+=-lnewt -lslang -ldl
$(eval $(call ast_make_final,stereorize,stereorize.o frame.o))
stereorize: LIBS+=-lm
-../ast_expr2.c:
- @echo " [BISON] ../ast_expr2.y -> $@"
- @bison -o $@ -d --name-prefix=ast_yy ../ast_expr2.y
+../main/ast_expr2.c:
+ @echo " [BISON] ../main/ast_expr2.y -> $@"
+ @bison -o $@ -d --name-prefix=ast_yy ../main/ast_expr2.y
-../ast_expr2f.c:
- @echo " [FLEX] ../ast_expr2.fl -> $@"
- @flex -o $@ --full ../ast_expr2.fl
+../main/ast_expr2f.c:
+ @echo " [FLEX] ../main/ast_expr2.fl -> $@"
+ @flex -o $@ --full ../main/ast_expr2.fl
-$(eval $(call ast_make_o_c,ast_expr2.o,../ast_expr2.c))
+$(eval $(call ast_make_o_c,ast_expr2.o,../main/ast_expr2.c))
-$(eval $(call ast_make_o_c,ast_expr2f.o,../ast_expr2f.c))
+$(eval $(call ast_make_o_c,ast_expr2f.o,../main/ast_expr2f.c))
ast_expr2f.o: CFLAGS+=-DSTANDALONE
$(eval $(call ast_make_final,check_expr,check_expr.c ast_expr2.o ast_expr2f.o))
@@ -79,23 +79,27 @@ $(eval $(call ast_make_o_c,aelbison.o,../pbx/ael/ael.tab.c ../pbx/ael/ael.tab.h
aelbison.o: CFLAGS+=-I../pbx
$(eval $(call ast_make_o_c,pbx_ael.o,../pbx/pbx_ael.c))
+pbx_ael.o: CFLAGS+=-DSTANDALONE_AEL
$(eval $(call ast_make_final,aelparse,aelflex.o aelbison.o pbx_ael.o ael_main.o ast_expr2f.o ast_expr2.o))
$(eval $(call ast_make_o_c,ael_main.o,ael_main.c ../include/asterisk/ael_structs.h))
-testexpr2s: ../ast_expr2f.c ../ast_expr2.c ../ast_expr2.h
- $(CC) -g -c -I../include -DSTANDALONE ../ast_expr2f.c -o ast_expr2f.o
- $(CC) -g -c -I../include -DSTANDALONE ../ast_expr2.c -o ast_expr2.o
+testexpr2s: ../main/ast_expr2f.c ../main/ast_expr2.c ../main/ast_expr2.h
+ $(CC) -g -c -I../include -DSTANDALONE ../main/ast_expr2f.c -o ast_expr2f.o
+ $(CC) -g -c -I../include -DSTANDALONE ../main/ast_expr2.c -o ast_expr2.o
$(CC) -g -o testexpr2s ast_expr2f.o ast_expr2.o
rm ast_expr2.o ast_expr2f.o
./testexpr2s expr2.testinput
smsq: smsq.o
-smsq: LIBS+=-lpopt
+smsq: LIBS+=$(POPT_LIB)
streamplayer: streamplayer.o
+muted: muted.o
+muted: LIBS+=$(AUDIO_LIBS)
+
ifneq ($(wildcard .depend),)
include .depend
endif
diff --git a/utils/ael_main.c b/utils/ael_main.c
index b930ad56b..e89a4b456 100644
--- a/utils/ael_main.c
+++ b/utils/ael_main.c
@@ -15,7 +15,9 @@
#include <limits.h>
#include "asterisk/ast_expr.h"
+#include "asterisk/channel.h"
#include "asterisk/module.h"
+#include "asterisk/app.h"
#include "asterisk/ael_structs.h"
struct namelist
@@ -453,7 +455,7 @@ int main(int argc, char **argv)
FIRST_TIME = 1;
- mod_data.load_module(0);
+ ast_module_info->load();
ast_log(4, "ael2_parse", __LINE__, "main", "%d contexts, %d extensions, %d priorities\n", conts, extens, priors);
diff --git a/utils/muted.c b/utils/muted.c
new file mode 100644
index 000000000..73eadfa3d
--- /dev/null
+++ b/utils/muted.c
@@ -0,0 +1,688 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * Updated for Mac OSX CoreAudio
+ * by Josh Roberson <josh@asteriasgi.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Mute Daemon
+ *
+ * \author Mark Spencer <markster@digium.com>
+ *
+ * Updated for Mac OSX CoreAudio
+ * \arg Josh Roberson <josh@asteriasgi.com>
+ *
+ * \note Specially written for Malcolm Davenport, but I think I'll use it too
+ * Connects to the Asterisk Manager Interface, AMI, and listens for events
+ * on certain devices. If a phone call is connected to one of the devices (phones)
+ * the local sound is muted to a lower volume during the call.
+ *
+ */
+
+#ifndef __Darwin__
+#include <linux/soundcard.h>
+#else
+#include <CoreAudio/AudioHardware.h>
+#endif
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+static char *config = "/etc/muted.conf";
+
+static char host[256] = "";
+static char user[256] = "";
+static char pass[256] = "";
+static int smoothfade = 0;
+static int mutelevel = 20;
+static int muted = 0;
+static int needfork = 1;
+static int debug = 0;
+static int stepsize = 3;
+#ifndef __Darwin__
+static int mixchan = SOUND_MIXER_VOLUME;
+#endif
+
+struct subchannel {
+ char *name;
+ struct subchannel *next;
+};
+
+static struct channel {
+ char *tech;
+ char *location;
+ struct channel *next;
+ struct subchannel *subs;
+} *channels;
+
+static void add_channel(char *tech, char *location)
+{
+ struct channel *chan;
+ chan = malloc(sizeof(struct channel));
+ if (chan) {
+ memset(chan, 0, sizeof(struct channel));
+ chan->tech = strdup(tech);
+ chan->location = strdup(location);
+ chan->next = channels;
+ channels = chan;
+ }
+
+}
+
+static int load_config(void)
+{
+ FILE *f;
+ char buf[1024];
+ char *val;
+ char *val2;
+ int lineno=0;
+ int x;
+ f = fopen(config, "r");
+ if (!f) {
+ fprintf(stderr, "Unable to open config file '%s': %s\n", config, strerror(errno));
+ return -1;
+ }
+ while(!feof(f)) {
+ fgets(buf, sizeof(buf), f);
+ if (!feof(f)) {
+ lineno++;
+ val = strchr(buf, '#');
+ if (val) *val = '\0';
+ while(strlen(buf) && (buf[strlen(buf) - 1] < 33))
+ buf[strlen(buf) - 1] = '\0';
+ if (!strlen(buf))
+ continue;
+ val = buf;
+ while(*val) {
+ if (*val < 33)
+ break;
+ val++;
+ }
+ if (*val) {
+ *val = '\0';
+ val++;
+ while(*val && (*val < 33)) val++;
+ }
+ if (!strcasecmp(buf, "host")) {
+ if (val && strlen(val))
+ strncpy(host, val, sizeof(host) - 1);
+ else
+ fprintf(stderr, "host needs an argument (the host) at line %d\n", lineno);
+ } else if (!strcasecmp(buf, "user")) {
+ if (val && strlen(val))
+ strncpy(user, val, sizeof(user) - 1);
+ else
+ fprintf(stderr, "user needs an argument (the user) at line %d\n", lineno);
+ } else if (!strcasecmp(buf, "pass")) {
+ if (val && strlen(val))
+ strncpy(pass, val, sizeof(pass) - 1);
+ else
+ fprintf(stderr, "pass needs an argument (the password) at line %d\n", lineno);
+ } else if (!strcasecmp(buf, "smoothfade")) {
+ smoothfade = 1;
+ } else if (!strcasecmp(buf, "mutelevel")) {
+ if (val && (sscanf(val, "%d", &x) == 1) && (x > -1) && (x < 101)) {
+ mutelevel = x;
+ } else
+ fprintf(stderr, "mutelevel must be a number from 0 (most muted) to 100 (no mute) at line %d\n", lineno);
+ } else if (!strcasecmp(buf, "channel")) {
+ if (val && strlen(val)) {
+ val2 = strchr(val, '/');
+ if (val2) {
+ *val2 = '\0';
+ val2++;
+ add_channel(val, val2);
+ } else
+ fprintf(stderr, "channel needs to be of the format Tech/Location at line %d\n", lineno);
+ } else
+ fprintf(stderr, "channel needs an argument (the channel) at line %d\n", lineno);
+ } else {
+ fprintf(stderr, "ignoring unknown keyword '%s'\n", buf);
+ }
+ }
+ }
+ fclose(f);
+ if (!strlen(host))
+ fprintf(stderr, "no 'host' specification in config file\n");
+ else if (!strlen(user))
+ fprintf(stderr, "no 'user' specification in config file\n");
+ else if (!channels)
+ fprintf(stderr, "no 'channel' specifications in config file\n");
+ else
+ return 0;
+ return -1;
+}
+
+static FILE *astf;
+#ifndef __Darwin__
+static int mixfd;
+
+static int open_mixer(void)
+{
+ mixfd = open("/dev/mixer", O_RDWR);
+ if (mixfd < 0) {
+ fprintf(stderr, "Unable to open /dev/mixer: %s\n", strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+#endif /* !__Darwin */
+
+/*! Connect to the asterisk manager interface */
+static int connect_asterisk(void)
+{
+ int sock;
+ struct hostent *hp;
+ char *ports;
+ int port = 5038;
+ struct sockaddr_in sin;
+
+ ports = strchr(host, ':');
+ if (ports) {
+ *ports = '\0';
+ ports++;
+ if ((sscanf(ports, "%d", &port) != 1) || (port < 1) || (port > 65535)) {
+ fprintf(stderr, "'%s' is not a valid port number in the hostname\n", ports);
+ return -1;
+ }
+ }
+ hp = gethostbyname(host);
+ if (!hp) {
+ fprintf(stderr, "Can't find host '%s'\n", host);
+ return -1;
+ }
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
+ return -1;
+ }
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(port);
+ memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
+ if (connect(sock, &sin, sizeof(sin))) {
+ fprintf(stderr, "Failed to connect to '%s' port '%d': %s\n", host, port, strerror(errno));
+ close(sock);
+ return -1;
+ }
+ astf = fdopen(sock, "r+");
+ if (!astf) {
+ fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
+ close(sock);
+ return -1;
+ }
+ return 0;
+}
+
+static char *get_line(void)
+{
+ static char buf[1024];
+ if (fgets(buf, sizeof(buf), astf)) {
+ while(strlen(buf) && (buf[strlen(buf) - 1] < 33))
+ buf[strlen(buf) - 1] = '\0';
+ return buf;
+ } else
+ return NULL;
+}
+
+/*! Login to the asterisk manager interface */
+static int login_asterisk(void)
+{
+ char *welcome;
+ char *resp;
+ if (!(welcome = get_line())) {
+ fprintf(stderr, "disconnected (1)\n");
+ return -1;
+ }
+ fprintf(astf,
+ "Action: Login\r\n"
+ "Username: %s\r\n"
+ "Secret: %s\r\n\r\n", user, pass);
+ if (!(welcome = get_line())) {
+ fprintf(stderr, "disconnected (2)\n");
+ return -1;
+ }
+ if (strcasecmp(welcome, "Response: Success")) {
+ fprintf(stderr, "login failed ('%s')\n", welcome);
+ return -1;
+ }
+ /* Eat the rest of the event */
+ while((resp = get_line()) && strlen(resp));
+ if (!resp) {
+ fprintf(stderr, "disconnected (3)\n");
+ return -1;
+ }
+ fprintf(astf,
+ "Action: Status\r\n\r\n");
+ if (!(welcome = get_line())) {
+ fprintf(stderr, "disconnected (4)\n");
+ return -1;
+ }
+ if (strcasecmp(welcome, "Response: Success")) {
+ fprintf(stderr, "status failed ('%s')\n", welcome);
+ return -1;
+ }
+ /* Eat the rest of the event */
+ while((resp = get_line()) && strlen(resp));
+ if (!resp) {
+ fprintf(stderr, "disconnected (5)\n");
+ return -1;
+ }
+ return 0;
+}
+
+static struct channel *find_channel(char *channel)
+{
+ char tmp[256] = "";
+ char *s, *t;
+ struct channel *chan;
+ strncpy(tmp, channel, sizeof(tmp) - 1);
+ s = strchr(tmp, '/');
+ if (s) {
+ *s = '\0';
+ s++;
+ t = strrchr(s, '-');
+ if (t) {
+ *t = '\0';
+ }
+ if (debug)
+ printf("Searching for '%s' tech, '%s' location\n", tmp, s);
+ chan = channels;
+ while(chan) {
+ if (!strcasecmp(chan->tech, tmp) && !strcasecmp(chan->location, s)) {
+ if (debug)
+ printf("Found '%s'/'%s'\n", chan->tech, chan->location);
+ break;
+ }
+ chan = chan->next;
+ }
+ } else
+ chan = NULL;
+ return chan;
+}
+
+#ifndef __Darwin__
+static int getvol(void)
+{
+ int vol;
+
+ if (ioctl(mixfd, MIXER_READ(mixchan), &vol)) {
+#else
+static float getvol(void)
+{
+ float volumeL, volumeR, vol;
+ OSStatus err;
+ AudioDeviceID device;
+ UInt32 size;
+ UInt32 channels[2];
+
+ size = sizeof(device);
+ err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &device);
+ size = sizeof(channels);
+ if (!err)
+ err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyPreferredChannelsForStereo, &size, &channels);
+ size = sizeof(vol);
+ if (!err)
+ err = AudioDeviceGetProperty(device, channels[0], false, kAudioDevicePropertyVolumeScalar, &size, &volumeL);
+ if (!err)
+ err = AudioDeviceGetProperty(device, channels[1], false, kAudioDevicePropertyVolumeScalar, &size, &volumeR);
+ if (!err)
+ vol = (volumeL < volumeR) ? volumeR : volumeL;
+ else {
+#endif
+ fprintf(stderr, "Unable to read mixer volume: %s\n", strerror(errno));
+ return -1;
+ }
+ return vol;
+}
+
+#ifndef __Darwin__
+static int setvol(int vol)
+#else
+static int setvol(float vol)
+#endif
+{
+#ifndef __Darwin__
+ if (ioctl(mixfd, MIXER_WRITE(mixchan), &vol)) {
+#else
+ float volumeL = vol;
+ float volumeR = vol;
+ OSStatus err;
+ AudioDeviceID device;
+ UInt32 size;
+ UInt32 channels[2];
+
+ size = sizeof(device);
+ err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &device);
+ size = sizeof(channels);
+ err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyPreferredChannelsForStereo, &size, &channels);
+ size = sizeof(vol);
+ if (!err)
+ err = AudioDeviceSetProperty(device, 0, channels[0], false, kAudioDevicePropertyVolumeScalar, size, &volumeL);
+ if (!err)
+ err = AudioDeviceSetProperty(device, 0, channels[1], false, kAudioDevicePropertyVolumeScalar, size, &volumeR);
+ if (err) {
+#endif
+
+ fprintf(stderr, "Unable to write mixer volume: %s\n", strerror(errno));
+ return -1;
+
+ }
+ return 0;
+}
+
+#ifndef __Darwin__
+static int oldvol = 0;
+static int mutevol = 0;
+#else
+static float oldvol = 0;
+static float mutevol = 0;
+#endif
+
+#ifndef __Darwin__
+static int mutedlevel(int orig, int mutelevel)
+{
+ int l = orig >> 8;
+ int r = orig & 0xff;
+ l = (float)(mutelevel) * (float)(l) / 100.0;
+ r = (float)(mutelevel) * (float)(r) / 100.0;
+
+ return (l << 8) | r;
+#else
+static float mutedlevel(float orig, float mutelevel)
+{
+ float master = orig;
+ master = mutelevel * master / 100.0;
+ return master;
+#endif
+
+}
+
+static void mute(void)
+{
+#ifndef __Darwin__
+ int vol;
+ int start;
+ int x;
+#else
+ float vol;
+ float start = 1.0;
+ float x;
+#endif
+ vol = getvol();
+ oldvol = vol;
+ if (smoothfade)
+#ifdef __Darwin__
+ start = mutelevel;
+#else
+ start = 100;
+ else
+ start = mutelevel;
+#endif
+ for (x=start;x>=mutelevel;x-=stepsize) {
+ mutevol = mutedlevel(vol, x);
+ setvol(mutevol);
+ /* Wait 0.01 sec */
+ usleep(10000);
+ }
+ mutevol = mutedlevel(vol, mutelevel);
+ setvol(mutevol);
+ if (debug)
+#ifdef __Darwin__
+ printf("Mute from '%f' to '%f'!\n", oldvol, mutevol);
+#else
+ printf("Mute from '%04x' to '%04x'!\n", oldvol, mutevol);
+#endif
+ muted = 1;
+}
+
+static void unmute(void)
+{
+#ifdef __Darwin__
+ float vol;
+ float start;
+ float x;
+#else
+ int vol;
+ int start;
+ int x;
+#endif
+ vol = getvol();
+ if (debug)
+#ifdef __Darwin__
+ printf("Unmute from '%f' (should be '%f') to '%f'!\n", vol, mutevol, oldvol);
+ mutevol = vol;
+ if (vol == mutevol) {
+#else
+ printf("Unmute from '%04x' (should be '%04x') to '%04x'!\n", vol, mutevol, oldvol);
+ if ((int)vol == mutevol) {
+#endif
+ if (smoothfade)
+ start = mutelevel;
+ else
+#ifdef __Darwin__
+ start = 1.0;
+#else
+ start = 100;
+#endif
+ for (x=start;x<100;x+=stepsize) {
+ mutevol = mutedlevel(oldvol, x);
+ setvol(mutevol);
+ /* Wait 0.01 sec */
+ usleep(10000);
+ }
+ setvol(oldvol);
+ } else
+ printf("Whoops, it's already been changed!\n");
+ muted = 0;
+}
+
+static void check_mute(void)
+{
+ int offhook = 0;
+ struct channel *chan;
+ chan = channels;
+ while(chan) {
+ if (chan->subs) {
+ offhook++;
+ break;
+ }
+ chan = chan->next;
+ }
+ if (offhook && !muted)
+ mute();
+ else if (!offhook && muted)
+ unmute();
+}
+
+static void delete_sub(struct channel *chan, char *name)
+{
+ struct subchannel *sub, *prev;
+ prev = NULL;
+ sub = chan->subs;
+ while(sub) {
+ if (!strcasecmp(sub->name, name)) {
+ if (prev)
+ prev->next = sub->next;
+ else
+ chan->subs = sub->next;
+ free(sub->name);
+ free(sub);
+ return;
+ }
+ prev = sub;
+ sub = sub->next;
+ }
+}
+
+static void append_sub(struct channel *chan, char *name)
+{
+ struct subchannel *sub;
+ sub = chan->subs;
+ while(sub) {
+ if (!strcasecmp(sub->name, name))
+ return;
+ sub = sub->next;
+ }
+ sub = malloc(sizeof(struct subchannel));
+ if (sub) {
+ memset(sub, 0, sizeof(struct subchannel));
+ sub->name = strdup(name);
+ sub->next = chan->subs;
+ chan->subs = sub;
+ }
+}
+
+static void hangup_chan(char *channel)
+{
+ struct channel *chan;
+ if (debug)
+ printf("Hangup '%s'\n", channel);
+ chan = find_channel(channel);
+ if (chan)
+ delete_sub(chan, channel);
+ check_mute();
+}
+
+static void offhook_chan(char *channel)
+{
+ struct channel *chan;
+ if (debug)
+ printf("Offhook '%s'\n", channel);
+ chan = find_channel(channel);
+ if (chan)
+ append_sub(chan, channel);
+ check_mute();
+}
+
+static int wait_event(void)
+{
+ char *resp;
+ char event[120]="";
+ char channel[120]="";
+ char oldname[120]="";
+ char newname[120]="";
+
+ resp = get_line();
+ if (!resp) {
+ fprintf(stderr, "disconnected (6)\n");
+ return -1;
+ }
+ if (!strncasecmp(resp, "Event: ", strlen("Event: "))) {
+ strncpy(event, resp + strlen("Event: "), sizeof(event) - 1);
+ /* Consume the rest of the non-event */
+ while((resp = get_line()) && strlen(resp)) {
+ if (!strncasecmp(resp, "Channel: ", strlen("Channel: ")))
+ strncpy(channel, resp + strlen("Channel: "), sizeof(channel) - 1);
+ if (!strncasecmp(resp, "Newname: ", strlen("Newname: ")))
+ strncpy(newname, resp + strlen("Newname: "), sizeof(newname) - 1);
+ if (!strncasecmp(resp, "Oldname: ", strlen("Oldname: ")))
+ strncpy(oldname, resp + strlen("Oldname: "), sizeof(oldname) - 1);
+ }
+ if (strlen(channel)) {
+ if (!strcasecmp(event, "Hangup"))
+ hangup_chan(channel);
+ else
+ offhook_chan(channel);
+ }
+ if (strlen(newname) && strlen(oldname)) {
+ if (!strcasecmp(event, "Rename")) {
+ hangup_chan(oldname);
+ offhook_chan(newname);
+ }
+ }
+ } else {
+ /* Consume the rest of the non-event */
+ while((resp = get_line()) && strlen(resp));
+ }
+ if (!resp) {
+ fprintf(stderr, "disconnected (7)\n");
+ return -1;
+ }
+ return 0;
+}
+
+static void usage(void)
+{
+ printf("Usage: muted [-f] [-d]\n"
+ " -f : Do not fork\n"
+ " -d : Debug (implies -f)\n");
+}
+
+int main(int argc, char *argv[])
+{
+ int x;
+ while((x = getopt(argc, argv, "fhd")) > 0) {
+ switch(x) {
+ case 'd':
+ debug = 1;
+ needfork = 0;
+ break;
+ case 'f':
+ needfork = 0;
+ break;
+ case 'h':
+ /* Fall through */
+ default:
+ usage();
+ exit(1);
+ }
+ }
+ if (load_config())
+ exit(1);
+#ifndef __Darwin__
+ if (open_mixer())
+ exit(1);
+#endif
+ if (connect_asterisk()) {
+#ifndef __Darwin__
+ close(mixfd);
+#endif
+ exit(1);
+ }
+ if (login_asterisk()) {
+#ifndef __Darwin__
+ close(mixfd);
+#endif
+ fclose(astf);
+ exit(1);
+ }
+ if (needfork)
+ daemon(0,0);
+ for(;;) {
+ if (wait_event()) {
+ fclose(astf);
+ while(connect_asterisk()) {
+ sleep(5);
+ }
+ if (login_asterisk()) {
+ fclose(astf);
+ exit(1);
+ }
+ }
+ }
+ exit(0);
+}