summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-01-08 23:42:08 +0000
committerLennart Poettering <lennart@poettering.net>2004-01-08 23:42:08 +0000
commit7b3475368a1950d2adc638bdc4d0bbda4b3d1e18 (patch)
treed1fc1d203654943e09491f7f094bf78cf30801c8
parent5565b244c983bfbfd8b88077eda690fd630e3f1f (diff)
made ivamd a real daemon
git-svn-id: file:///home/lennart/svn/public/ivam2/trunk@20 dbf6933d-3bce-0310-9bcc-ed052ba35b35
-rwxr-xr-xclients/ivam-autobox22
-rwxr-xr-xclients/ivam-voicebox11
-rw-r--r--clients/ivamApi.py2
-rw-r--r--clients/ivamPipeConnector.py4
-rw-r--r--clients/ivamVoiceBox.py5
-rw-r--r--doc/TODO7
-rw-r--r--src/Makefile11
-rw-r--r--src/buffio.c6
-rw-r--r--src/ivamd.ggo29
-rw-r--r--src/main.c100
-rw-r--r--src/main.h6
-rw-r--r--src/modem.c10
-rw-r--r--src/modem.h2
-rw-r--r--src/modemman.c2
14 files changed, 176 insertions, 41 deletions
diff --git a/clients/ivam-autobox b/clients/ivam-autobox
index bb7fcfc..8b11f8e 100755
--- a/clients/ivam-autobox
+++ b/clients/ivam-autobox
@@ -4,14 +4,15 @@ import sys, os, getopt
from ivamCore import log
import ivamCore, ivamVoiceBox
+from optparse import OptionParser
def usage():
- log("%s [--record-time=SECS] [--pin=PIN] [--pin-file=PINFILE] [--debug] [DIRECTORY]" % sys.argv[0])
+ log("%s [--record-time=SECS] [--pin=PIN] [--pin-file=PINFILE] [--default-record-time=SECS] [--default-pin=PIN] [--default-pin-file=PINFILE] [--debug] [DIRECTORY]" % sys.argv[0])
def parseArgs(vb, argv):
try:
- opts, args = getopt.getopt(argv[1:], "ht:p:P:de:", ["help", "record-time=", "pin=", "pin-file=", "debug", "message-program"])
+ opts, args = getopt.getopt(argv[1:], "dh", ["help", "record-time=", "pin=", "pin-file=", "default-record-time=", "default-pin=", "default-pin-file=", "debug"])
except getopt.GetoptError:
usage()
sys.exit(1)
@@ -27,13 +28,13 @@ def parseArgs(vb, argv):
usage()
sys.exit()
- elif o in ("-t", "--record-time"):
+ elif o in ("--default-record-time"):
recordTime = int(a)
- elif o in ("-p", "--pin"):
+ elif o in ("--default-pin"):
pin = a
- elif o in ("-P", "--pin-file"):
+ elif o in ("--default-pin-file"):
pin = getContents(a)
dname = "msn-" + os.getenv("RINGMSN")
@@ -48,6 +49,17 @@ def parseArgs(vb, argv):
vb.setDirectory(dname)
+ for o, a in opts:
+ if o in ("--record-time"):
+ vb.recordTime = int(a)
+
+ elif o in ("--pin"):
+ vb.setPin(a)
+
+ elif o in ("--pin-file"):
+ vb.setPin(getContents(a))
+
+
def main():
vb = ivamVoiceBox.VoiceBox()
parseArgs(vb, sys.argv)
diff --git a/clients/ivam-voicebox b/clients/ivam-voicebox
index fbf6afa..1ec19d5 100755
--- a/clients/ivam-voicebox
+++ b/clients/ivam-voicebox
@@ -11,7 +11,7 @@ def usage():
def parseArgs(vb, argv):
try:
- opts, args = getopt.getopt(argv[1:], "ht:p:P:de:", ["help", "record-time=", "pin=", "pin-file=", "debug", "message-program"])
+ opts, args = getopt.getopt(argv[1:], "hd", ["help", "record-time=", "pin=", "pin-file=", "debug", "message-program="])
except getopt.GetoptError:
usage()
sys.exit(1)
@@ -32,19 +32,18 @@ def parseArgs(vb, argv):
usage()
sys.exit()
- elif o in ("-t", "--record-time"):
+ elif o in ("--record-time"):
vb.recordTime = int(a)
- elif o in ("-p", "--pin"):
+ elif o in ("--pin"):
vb.setPin(a)
- elif o in ("-P", "--pin-file"):
+ elif o in ("--pin-file"):
vb.setPin(getContents(a))
- elif o in ("-e", "--message-program"):
+ elif o in ("--message-program"):
vb.messageProgram = a
-
def main():
vb = ivamVoiceBox.VoiceBox()
parseArgs(vb, sys.argv)
diff --git a/clients/ivamApi.py b/clients/ivamApi.py
index 8cab6f9..97534ff 100644
--- a/clients/ivamApi.py
+++ b/clients/ivamApi.py
@@ -10,7 +10,7 @@ class Processor:
def onDtmfEvent(self, c, event):
pass
- def onClipFinish(self, c, fname):
+ def onClipFinish(self, c, fname, length):
pass
def onTimeout(self, c):
diff --git a/clients/ivamPipeConnector.py b/clients/ivamPipeConnector.py
index af302b8..bbaf9ed 100644
--- a/clients/ivamPipeConnector.py
+++ b/clients/ivamPipeConnector.py
@@ -92,6 +92,7 @@ class PipeConnector(ivamApi.Connector):
self.recordName = fname
self.recording = True
+ self.recordLength = 0
def stopRecording(self):
@@ -102,7 +103,7 @@ class PipeConnector(ivamApi.Connector):
self.recordFile.close()
self.recording = False
- self.processor.onRecordFinish(self, self.recordName)
+ self.processor.onRecordFinish(self, self.recordName, self.recordLength)
def setTimeout(self, t):
@@ -198,6 +199,7 @@ class PipeConnector(ivamApi.Connector):
self.quit = 1
elif self.recording:
self.recordFile.write(buf)
+ self.recordLength += len(buf)
def writeStdout(self):
diff --git a/clients/ivamVoiceBox.py b/clients/ivamVoiceBox.py
index 252ce98..9dc84f9 100644
--- a/clients/ivamVoiceBox.py
+++ b/clients/ivamVoiceBox.py
@@ -216,7 +216,7 @@ class VoiceBox(ivamApi.Processor):
self.currentState = self.STATE_FINISH
c.hangup()
- def onRecordFinish(self, c, fname):
+ def onRecordFinish(self, c, fname, length):
if ivamCore.DEBUG:
ivamCore.log("onRecordFinish(%s)" % fname)
@@ -224,6 +224,9 @@ class VoiceBox(ivamApi.Processor):
ivamCore.log("Sucessfully recorded new message '%s' from %s for MSN %s." % (fname, self.callerNumber, self.ringNumber))
os.environ["SPOOLDIR"] = self.directory
+ os.environ["LENGTH"] = `c.recordLength`
+ os.environ["SEC_LENGTH"] = "%0.1f" % (c.recordLength/8000.0)
+
ivamCore.log("Starting new message notification program.")
r=os.spawnvp(os.P_WAIT, self.messageProgram, (self.messageProgram, fname))
ivamCore.log("Program finished (return value is %i)." % r)
diff --git a/doc/TODO b/doc/TODO
index 874d9fe..78fc329 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -1,9 +1,14 @@
* implement shbuf support
* uid switching support
-* make it a daemon
* autoconf
* documentation
+* regexp support
+* @same support
+* uid switching for each client
+* init script
+* make it a daemon (DONE)
+* newmessage script (DONE)
* python part (DONE)
* implement msntab.c (DONE)
* dtmf fifo (DONE)
diff --git a/src/Makefile b/src/Makefile
index c689956..8dcb48e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,9 +1,14 @@
CC=gcc
-CFLAGS=`pkg-config --cflags libdaemon shbuf liboop` -Wall -O0 -pipe -g
-LIBS=`pkg-config --libs libdaemon shbuf liboop` -Wall -O0 -pipe -g
+CFLAGS=`pkg-config --cflags libdaemon liboop` -Wall -O0 -pipe -g
+LIBS=`pkg-config --libs libdaemon liboop` -Wall -O0 -pipe -g
-ivamd: modem.o main.o modemman.o buffio.o exec.o dle.o lock.o util.o msntab.o timevalarith.o dtmffifo.o
+ivamd: modem.o main.o modemman.o buffio.o exec.o dle.o lock.o util.o msntab.o timevalarith.o dtmffifo.o cmdline.o
$(CC) $(LIBS) -o $@ $^
+
+cmdline.c cmdline.h: ivamd.ggo
+ gengetopt < $<
+
clean:
rm -f *.o ivamd
+
diff --git a/src/buffio.c b/src/buffio.c
index 95e3dec..4771b1c 100644
--- a/src/buffio.c
+++ b/src/buffio.c
@@ -257,6 +257,7 @@ static void do_read(struct buffio *b) {
m = b->input_max_length-i;
s = read(b->ifd, b->input_buf+i, m);
+ buffio_set_readable(b, 0);
//daemon_log(LOG_INFO, "%p: Read %u (%u) bytes.", b, s, m);
if (s < 0) {
@@ -284,8 +285,6 @@ static void do_read(struct buffio *b) {
b->input_length += s;
buffio_normalize(b);
- buffio_set_readable(b, 0);
-
if (b->input_length)
buffio_sched_cb(b, BUFFIO_SCHED_CB_INPUT_READY);
}
@@ -310,6 +309,8 @@ static void do_write(struct buffio *b) {
m = b->output_max_length-b->output_index;
s = write(b->ofd, b->output_buf+b->output_index, m);
+ buffio_set_writable(b, 0);
+
//daemon_log(LOG_INFO, "%p: Wrote %u (%u) bytes.", b, s, m);
if (s < 0) {
@@ -338,7 +339,6 @@ static void do_write(struct buffio *b) {
b->output_length -= s;
buffio_normalize(b);
- buffio_set_writable(b, 0);
buffio_delay(b, s);
if (b->output_length < b->output_range)
diff --git a/src/ivamd.ggo b/src/ivamd.ggo
new file mode 100644
index 0000000..67e6f7e
--- /dev/null
+++ b/src/ivamd.ggo
@@ -0,0 +1,29 @@
+# $Id$
+
+# This file is part of ivamd.
+#
+# ivamd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# ivamd is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ivamd; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+purpose "ISDN Voice Box Answering Machine"
+package "ivam"
+version "0.1"
+
+option "kill" k "Kill a running daemon" flag off
+option "no-daemon" n "Do not daemonize" flag off
+option "no-syslog" s "Do not log to syslog" flag off
+option "check" c "Check if the daemon is currently running" flag off
+option "channels" C "Specify how many channels to allocate, defaults to 2" int default="2" no
+option "msntab" T "Specify non standard msntab file" string no
+option "listen" L "Specify a glob pattern matchin the MSNs to listen on" string no
diff --git a/src/main.c b/src/main.c
index 4f5a273..204fc69 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,17 +1,23 @@
#include <signal.h>
#include <assert.h>
+#include <string.h>
+#include <errno.h>
+
#include <libdaemon/dlog.h>
+#include <libdaemon/dfork.h>
+#include <libdaemon/dpid.h>
#include "main.h"
#include "exec.h"
#include "modemman.h"
#include "msntab.h"
-
-#define CHANNELS 1
+#include "cmdline.h"
oop_source* event_source = NULL;
+struct gengetopt_args_info args;
+const char *appname = NULL, *username = NULL;
-#define MSNTABLE "../conf/msntab"
+#define DEFAULT_MSNTABLE "../conf/msntab"
static void *oop_exit_cb(oop_source *source, int sig, void *user) {
daemon_log(LOG_ERR, "Recieved signal %s", sig == SIGINT ? "SIGINT" : (sig == SIGTERM ? "SIGTERM" : "UNKNWON"));
@@ -22,7 +28,7 @@ static void *oop_reload_cb(oop_source *source, int sig, void *user) {
daemon_log(LOG_ERR, "Reloading MSN table.");
msntab_flush();
- if (msntab_load(MSNTABLE) < 0) {
+ if (msntab_load(args.msntab_arg ? args.msntab_arg : DEFAULT_MSNTABLE) < 0) {
daemon_log(LOG_ERR, "Ignoring all calls.");
msntab_flush();
}
@@ -37,7 +43,7 @@ static void *oop_dump_cb(oop_source *source, int sig, void *user) {
int main_loop(void) {
- int r = -1;
+ int r = -1, retval_sent = 0;
oop_source_sys *sys = NULL;
daemon_log(LOG_INFO, "Starting up.");
@@ -53,10 +59,10 @@ int main_loop(void) {
if (child_process_init() < 0)
goto finish;
- if (msntab_load(MSNTABLE) < 0)
+ if (msntab_load(args.msntab_arg ? args.msntab_arg : DEFAULT_MSNTABLE) < 0)
goto finish;
- if (modem_manager_init(CHANNELS) < 0)
+ if (modem_manager_init(args.channels_arg) < 0)
goto finish;
event_source->on_signal(event_source, SIGINT, oop_exit_cb, NULL);
@@ -65,6 +71,11 @@ int main_loop(void) {
event_source->on_signal(event_source, SIGUSR1, oop_dump_cb, NULL);
signal(SIGPIPE, SIG_IGN);
+ if (!args.no_daemon_flag) {
+ daemon_retval_send(0);
+ retval_sent = 1;
+ }
+
daemon_log(LOG_INFO, "Start up complete.");
if (oop_sys_run(sys) == OOP_ERROR) {
@@ -73,11 +84,14 @@ int main_loop(void) {
}
r = 0;
-
+
finish:
-
+
daemon_log(LOG_INFO, "Shutting down.");
+ if (!retval_sent && !args.no_daemon_flag)
+ daemon_retval_send(1);
+
event_source->cancel_signal(event_source, SIGTERM, oop_exit_cb, NULL);
event_source->cancel_signal(event_source, SIGINT, oop_exit_cb, NULL);
event_source->cancel_signal(event_source, SIGHUP, oop_reload_cb, NULL);
@@ -99,5 +113,71 @@ finish:
}
int main(int argc, char*argv[]) {
- return main_loop() < 0 ? 1 : 0;
+ pid_t pid;
+ int ret;
+
+ appname = daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
+
+ cmdline_parser(argc, argv, &args);
+
+ if (args.no_syslog_flag)
+ daemon_log_use = DAEMON_LOG_STDERR;
+
+ if (args.kill_flag) {
+ int ret;
+
+ if ((ret = daemon_pid_file_kill_wait(SIGINT, 5)) < 0)
+ daemon_log(LOG_WARNING, "Failed to kill daemon.");
+
+ return ret < 0 ? 1 : 0;
+ }
+
+ if (args.check_flag) {
+ if ((pid = daemon_pid_file_is_running()) >= 0)
+ daemon_log(LOG_INFO, "Daemon running on PID %u.", pid);
+ else
+ daemon_log(LOG_INFO, "Daemon not running.");
+
+ return 1;
+ }
+
+ if ((pid = daemon_pid_file_is_running()) >= 0) {
+ daemon_log(LOG_ERR, "Daemon already running on PID %u.", pid);
+ return 1;
+ }
+
+ if (!args.no_daemon_flag) {
+ daemon_retval_init();
+
+ if ((pid = daemon_fork()) < 0) {
+ daemon_retval_done();
+ return 1;
+ } else if (pid) {
+ int ret;
+
+ if ((ret = daemon_retval_wait(20)) < 0) {
+ daemon_log(LOG_ERR, "Failed to recieve return value from daemon process.");
+ return 255;
+ }
+
+ if (ret)
+ daemon_log(LOG_ERR, "Daemon returned %i as return value.", ret);
+ return ret;
+ }
+ }
+
+ if (daemon_pid_file_create() < 0) {
+ daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno));
+
+ if (!args.no_daemon_flag)
+ daemon_retval_send(1);
+
+ return 1;
+ }
+
+ ret = main_loop() < 0 ? 1 : 0;
+
+ daemon_pid_file_remove();
+ return ret;
}
+
diff --git a/src/main.h b/src/main.h
index aa2f35a..c23d87d 100644
--- a/src/main.h
+++ b/src/main.h
@@ -3,8 +3,12 @@
#include <oop.h>
+#include "cmdline.h"
+
extern oop_source* event_source;
-const char *appname, *username;
+extern const char *appname, *username;
+
+extern struct gengetopt_args_info args;
#endif
diff --git a/src/modem.c b/src/modem.c
index ecc0019..3035969 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -132,7 +132,6 @@ struct modem *modem_open(const char *dev) {
m->child_pid = -1;
m->child_buffio = NULL;
- m->listen_msn = "41264179"; // "46";
m->tabentry = NULL;
if (modem_reopen(m) < 0)
@@ -214,7 +213,9 @@ static void modem_next_command(struct modem *m) {
if (m->command_index == 0)
buffio_command(m->buffio, hup_sequence);
else if (m->command_index == 15) {
- snprintf(tmp, sizeof(tmp), p, m->listen_msn);
+ char *l = args.listen_arg ? args.listen_arg : "*";
+ daemon_log(LOG_INFO, "Listening on '%s'.", l);
+ snprintf(tmp, sizeof(tmp), p, l);
p = tmp;
}
@@ -449,8 +450,8 @@ static int modem_start_child(struct modem *m) {
setenv("CALLERMSN", m->caller_number ? m->caller_number : "", 1);
assert(m->dtmf_fifo->fname);
setenv("DTMFFIFO", m->dtmf_fifo->fname, 1);
- if (m->listen_msn)
- setenv("LISTENMSN", m->listen_msn, 1);
+ if (args.listen_arg)
+ setenv("LISTENMSN", args.listen_arg, 1);
else
unsetenv("LISTENMSN");
@@ -552,7 +553,6 @@ static int modem_input_ready_cb(struct buffio *b, void *user) {
m->command_index++;
if (m->command_index >= INIT_AT_COMMANDS) {
- daemon_log(LOG_INFO, "Listening on '%s'.", m->listen_msn);
daemon_log(LOG_INFO, "Modem successfully initialised, waiting for calls.");
m->state = MODEM_STATE_CALLER_NUMBER_EXPECT;
modem_timeout(m, 0);
diff --git a/src/modem.h b/src/modem.h
index 8fed726..08e20b8 100644
--- a/src/modem.h
+++ b/src/modem.h
@@ -41,8 +41,6 @@ struct modem {
struct timeval timeout;
- char *listen_msn;
-
char *ring_number;
char *caller_number;
diff --git a/src/modemman.c b/src/modemman.c
index cccaef9..ba3c3e2 100644
--- a/src/modemman.c
+++ b/src/modemman.c
@@ -40,8 +40,6 @@ int modem_manager_init(int channels) {
assert(channels <= MAX_CHANNELS && channels > 0);
assert(n_llist == 0);
- modem_try_open("/dev/ttyz0");
-
for (i = TTY_START; i < TTY_START+MAX_CHANNELS && n_llist < channels; i++) {
char d[PATH_MAX];
snprintf(d, sizeof(d), "/dev/ttyI%i", i);