Inital code to support a daemon like program 'amodemd' to handle at least

the DSP and link-level parts of a G3-fax transfer, and possibly standard
modem connections at a later time.
This commit is contained in:
Morten Rolland 1999-01-31 20:54:55 +00:00
parent 18dd32f03e
commit d9da365a39
13 changed files with 871 additions and 3 deletions

View File

@ -1,3 +1,4 @@
v21_softmodem
test
amodemd
*.o

View File

@ -1,11 +1,11 @@
LDFLAGS=-lm
CFLAGS=-O2 -g -Wall -pedantic -Iinclude
SUBDIRS = lib modules
SUBDIRS = lib modules misc
MODULES = modules/modules.a lib/isdnlib.a
MODULES = modules/modules.a lib/isdnlib.a misc/misc.a
PROGRAMS = v21_softmodem test
PROGRAMS = v21_softmodem test amodemd
all: subdirs $(PROGRAMS)
@ -18,6 +18,12 @@ v21_softmodem: v21_softmodem.o $(OBJECTS) $(MODULES)
test: test.o $(OBJECTS) $(MODULES)
$(CC) -o $@ $^ $(LDFLAGS)
amodemd: amodemd.o $(MODULES)
$(CC) -o $@ $^ $(LDFLAGS)
misc/misc.a: misc/*.o
make -C misc
clean:
rm -f $(OBJECTS) $(MODULES) $(PROGRAMS) *~ *.o
for a in $(SUBDIRS) ; do make -C $$a clean; done

125
amodemd.c Normal file
View File

@ -0,0 +1,125 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Initial startup of daemon 'amodemd' - contains main() etc.
Copyright (C) 1998 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
/* This file holds the 'main()' function for the 'amodemd' daemon program
* that enables communication with analog modems and faxes without the
* use of a dedicated modem. This is made possible by collecting all the
* digital signal processing algorithms usually found in modems inside
* this daemon program. This daemon will as a result of this, consume
* significant resources when communication is commencing.
*/
#include <stdio.h>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h>
#include <ifax/misc/globals.h>
#include <ifax/misc/readconfig.h>
#include <ifax/misc/environment.h>
#include <ifax/misc/watchdog.h>
/* Parse command-line arguments and bail out with an error message if
* something is wrong.
*/
static void usage(void)
{
fprintf(stderr,"Usage: %s [-d] [-c <config-file>]\n",progname);
exit(1);
}
static void parse_arguments(int argc, char **argv)
{
int t;
if ( argc > 0 && argv[0] != 0 ) {
progname = rindex(argv[0],'/');
if ( progname != 0 ) {
progname++;
} else {
progname = argv[0];
}
}
t = 1;
while ( t < argc ) {
if ( !strcmp("-c",argv[t]) ) {
t++;
if ( t >= argc )
usage();
config_file = argv[t];
t++;
}
if ( !strcmp("-d",argv[t]) ) {
t++;
run_as_daemon = 1;
}
}
}
/* Startup point for 'amodemd' - parse args, initialize and off we go */
void main(int argc, char **argv)
{
int t;
parse_arguments(argc,argv);
read_configuration_file();
if ( run_as_daemon )
start_daemon();
if ( watchdog_timeout > 0 ) {
initialize_watchdog_timer();
reset_watchdog_timer();
}
/* Next up is:
* initialize_fax();
* and later maybe:
* initialize_v34();
* ...
*/
initialize_realtime();
/* main_loop(); */
/* Waste some cycles to test watchdog timer.... */
for ( t=0; t < 1000000000; t++ )
;
check_stack_usage();
exit(0);
}

56
doc/amodemd.conf Normal file
View File

@ -0,0 +1,56 @@
# File: /etc/amodemd.conf
#
# Example of a configuration file for 'amodemd'.
#
# When the 'amodemd' starts as a daemon, it writes a pid-file to make it
# easy to kill the daemon off again at a later stage:
pidfile = /var/run/amodemd.pid
# When 'amodemd' is used on top of ISDN supporting audio, the device has
# to be specified, the phone-number to use (MSN), etc.:
isdn-device = /dev/ttyI5 # /dev/ttyI* are used for ISDN-audio
isdn-msn = 5551234 # Full number when using Euro-ISDN
country = 47 # Country of installation
international-prefix = 00 # Prefix to reach foreign destinations
# The daemon 'amodemd' performs a lot of timing critical digital signal
# processing. In order to get enough CPU-resources to avoid dropping
# a connection when the system load increases, the daemon installs
# itself as a "Real-Time" process. This way, it is guaranteed to get
# enough attention from the CPU. The realtime-priority option indicates
# which real-time level it should run at. Valid values are 0-99.
# When there are other real-time processes on the system, their
# individual priorities may have to be adjusted. A value of 0 disables
# real-time scheduling of 'amodemd', which is safer, but has a much
# higher chance of dropping a connection.
#
# If a real-time process goes wild, using all of the CPU, the system will
# be left completely unusable. Do not install a real-time daemon like
# 'amodemd' on a production system without being aware of the possibility
# of a system crash.
#
# In order to minimize the risk of having to reset a system as a result
# of a wild-running daemon, 'amodemd' features a watchdog timer that will
# kill itself off if there seems to be a problem. The watchdog timer
# period is in seconds, and is reset regularly when 'amodemd' thinks that
# it is behaving nicely.
#
# Please observe that the watchdog timer period must expire before it
# triggers, so leave the system alone for the timeout period (at least)
# before resetting or other dramatic action is taken (the system may
# recover by 'amodemd' committing suicide).
realtime-priority = 1 # Valid values: 0 => off, 1-99 => real-time run-level
watchdog-timer = 60 # 60 seconds of hung system => abort 'amodemd'
# If you try to run this daemon as a non-root user, it will not be able
# to fix its memory pages to always stay in main memory (no swapping),
# so the 'lock-memory' option must be used ( 0 => Don't lock, 1 => lock ):
lock-memory = 0

View File

@ -0,0 +1,40 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Set up environment for a real-time daemon process like the 'amodemd'
Copyright (C) 1999 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
/* Sufficient space (in bytes) to hold the machine-stack with
* auto-variables, arguments and return addresses. Modify if
* more space is needed, or the current value is too large.
* However; it should never be smaller than the actual maximum
* stack-usage. One megabyte is probably generous.
*/
#define TOTAL_STACK_USAGE 1048576
#define MINIMUM_FREE_STACK_SAFETY_MARGIN 20480
extern void initialize_realtime(void);
extern void start_daemon(void);
extern void check_stack_usage(void);

View File

@ -0,0 +1,30 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Definition of common globals
Copyright (C) 1999 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
extern char *progname; /* Name of executable/program */
extern int run_as_daemon; /* nonzero if running as daemon */

View File

@ -0,0 +1,39 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Read the configuration file.
Copyright (C) 1999 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
extern char *config_file;
extern char *pid_file;
extern char *isdn_device;
extern char *isdn_msn;
extern char *home_country;
extern char *int_prefix;
extern int watchdog_timeout;
extern int realtime_priority;
extern int do_lock_memory;
extern void read_configuration_file(void);

View File

@ -0,0 +1,30 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Watchdog timer in case of misbehaving real-time process.
Copyright (C) 1999 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
extern void initialize_watchdog_timer(void);
extern void reset_watchdog_timer(void);

11
misc/Makefile Normal file
View File

@ -0,0 +1,11 @@
CFLAGS=-O2 -g -Wall -pedantic -I../include
OBJECTS = globals.o readconfig.o watchdog.o environment.o
all: misc.a
misc.a: $(OBJECTS)
$(AR) rcs $@ $^
clean:
rm -f $(OBJECTS) misc.a *~

139
misc/environment.c Normal file
View File

@ -0,0 +1,139 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Set up environment for a real-time daemon process like the 'amodemd'
Copyright (C) 1999 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
#include <stdio.h>
#include <sys/mman.h>
#include <sched.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <ifax/misc/globals.h>
#include <ifax/misc/environment.h>
#include <ifax/misc/readconfig.h>
char *bottom_unused_stack = 0; /* This part of the stack shouldn't be used */
char *top_used_stack = 0; /* Top of stack, used a lot */
/* The following function puts this daemon into a mode of operation
* where it will get the CPU-power needed to carry out its task.
* This is needed since generating and interpreting the audio-
* signals must be carried out "live", and with no pauses.
* The remaining CPU-resources is available to other programs.
*
* This function should be called after all allocations have completed,
* and if possible, initialized (so all memory is mapped).
*/
void initialize_realtime(void)
{
char stack_initialization[TOTAL_STACK_USAGE];
struct sched_param schedparams;
/* In order to get predictable response-times, we lock this daemon and
* its data into RAM, and tell the OS to avoid paging. The assumed
* stack-usage is 1MB, which is probably way to much, but RAM is cheap.
* We have to initialize the stack-segment to make sure all pages
* making up the stack is mapped.
*/
if ( do_lock_memory ) {
memset(stack_initialization,TOTAL_STACK_USAGE,0);
if ( mlockall(MCL_CURRENT|MCL_FUTURE) != 0 ) {
fprintf(stderr,"Can't lock memory\n");
exit(1);
}
bottom_unused_stack = &stack_initialization[0];
top_used_stack = &stack_initialization[TOTAL_STACK_USAGE-1];
}
/* Next up is requesting the full attention of the CPU. This
* basically means that our program will start to run when data
* is available, no matter how badly other standard programs wants
* to run. NOTE: This will work since this daemon waits for
* data regularly. During these waits, other processes are
* allowed to run, so the system can operate normally.
* However: If this daemon fails to wait, the entire system will
* become useless, since all other programs will be blocked.
* A watchdog timer is implemented to try avoid a hard reset.
*/
if ( realtime_priority > 0 ) {
schedparams.sched_priority = realtime_priority;
if ( sched_setscheduler((pid_t)0,SCHED_FIFO,&schedparams) < 0 ) {
fprintf(stderr,"Couldn't enable real-time scheduling\n");
exit(1);
}
}
}
/* When running as daemon, there are a few things we need to do.
* Most important is disconnecting the tty.
*/
void start_daemon(void)
{
pid_t child_pid;
if ( (child_pid=fork()) < 0 ) {
fprintf(stderr,"%s: Unable to fork a daemon\n",progname);
exit(1);
}
if ( child_pid )
exit(0);
setsid();
}
void check_stack_usage(void)
{
char *p;
int unused_stack;
if ( bottom_unused_stack == 0 )
return;
for ( p = bottom_unused_stack; p < top_used_stack; p++ )
if ( *p != 0 )
break;
unused_stack = p - bottom_unused_stack;
if ( unused_stack < MINIMUM_FREE_STACK_SAFETY_MARGIN ) {
fprintf(stderr,"%s: Internal error - only %d bytes of headroom on stack\n",
progname,unused_stack);
exit(1);
}
fprintf(stderr,"%s: INFO - There is %d bytes of headroom on stack\n",
progname,unused_stack);
}

30
misc/globals.c Normal file
View File

@ -0,0 +1,30 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Common globals.
Copyright (C) 1999 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
char *progname = "amodemd";
int run_as_daemon = 0;

294
misc/readconfig.c Normal file
View File

@ -0,0 +1,294 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Read the configuration file.
Copyright (C) 1999 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
/* Open and read the configuration file, parse it, and set
* the relevnt variables accordingly.
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <ifax/misc/readconfig.h>
#include <ifax/misc/globals.h>
#ifndef DEFAULT_CONFIG_FILE
#define DEFAULT_CONFIG_FILE "/etc/amodemd.conf"
#endif
#ifndef DEFAULT_PID_FILE
#define DEFAULT_PID_FILE "/var/run/amodemd.pid"
#endif
#ifndef DEFAULT_ISDN_DEVICE
#define DEFAULT_ISDN_DEVICE "/dev/ttyI5"
#endif
#ifndef DEFAULT_WATCHDOG_TIMEOUT
#define DEFAULT_WATCHDOG_TIMEOUT 0
#endif
#ifndef DEFAULT_REALTIME_PRIORITY
#define DEFAULT_REALTIME_PRIORITY 0
#endif
#ifndef DEFAULT_ISDN_MSN
#define DEFAULT_ISDN_MSN "5551234"
#endif
#ifndef DEFAULT_COUNTRY
#define DEFAULT_COUNTRY "47"
#endif
#ifndef DEFAULT_INT_PREFIX
#define DEFAULT_INT_PREFIX "00"
#endif
char *config_file = DEFAULT_CONFIG_FILE;
char *pid_file = DEFAULT_PID_FILE;
char *isdn_device = DEFAULT_ISDN_DEVICE;
char *isdn_msn = DEFAULT_ISDN_MSN;
char *home_country = DEFAULT_COUNTRY;
char *int_prefix = DEFAULT_INT_PREFIX;
int watchdog_timeout = DEFAULT_WATCHDOG_TIMEOUT;
int realtime_priority = DEFAULT_REALTIME_PRIORITY;
int do_lock_memory = 1;
#define MAXCFGLINE 128
static int cmd_match(char *cmd, char **pp)
{
char *c, *p;
c = cmd;
p = *pp;
while ( *c && *p ) {
if ( tolower(*c) != tolower(*p) )
return 0;
c++, p++;
}
if ( *c )
return 0;
*pp = p;
return 1;
}
static void skip_assignment(char **pp)
{
char *p = *pp;
while ( isspace(*p) )
p++;
if ( *p++ != '=' ) {
fprintf(stderr,"%s: Missing assigment operator in config file\n",progname);
exit(1);
}
while ( isspace(*p) )
p++;
*pp = p;
}
static int get_int(char **pp)
{
int t;
char buffer[32];
char *p = *pp;
if ( !isdigit(*p) ) {
fprintf(stderr,"%s: Bad integer in config file\n",progname);
exit(1);
}
for ( t=0; t < 30; t++ ) {
if ( !isdigit(*p) ) {
buffer[t] = 0;
*pp = p;
return atoi(buffer);
}
buffer[t] = *p++;
}
fprintf(stderr,"%s: Integer too long in config file\n",progname);
exit(1);
}
static char *get_string(char **pp)
{
int length;
char *string;
char *p = *pp, *start, *stop;
while ( isspace(*p) )
p++;
if ( *p == '"' ) {
start = p + 1;
stop = index(start,'"');
if ( stop == 0 ) {
fprintf(stderr,"%s: Missing terminating \" in string in config file\n",
progname);
exit(1);
}
*pp = stop + 1;
} else {
start = p;
while ( !isspace(*p) )
p++;
*pp = stop = p;
}
length = stop - start;
string = malloc(length+1);
strncpy(string,start,length);
string[length] = 0;
return string;
}
static void end_line(char **pp)
{
char *p = *pp;
while ( isspace(*p) )
p++;
if ( *p == '#' || *p == 0 )
return;
fprintf(stderr,"%s: Garbage at end of line in config file\n",progname);
exit(1);
}
void read_configuration_file(void)
{
FILE *cfg;
char *p;
char buffer[MAXCFGLINE+4];
if ( (cfg=fopen(config_file,"r")) == 0 ) {
fprintf(stderr,"%s: Unable to read config file '%s'\n",
progname,config_file);
exit(1);
}
for (;;) {
if ( fgets(buffer,MAXCFGLINE,cfg) == 0 )
break;
p = buffer;
while ( isspace(*p) )
p++;
if ( *p == '#' )
continue;
if ( cmd_match("pidfile",&p) ) {
skip_assignment(&p);
pid_file = get_string(&p);
end_line(&p);
continue;
}
if ( cmd_match("isdn-device",&p) ) {
skip_assignment(&p);
isdn_device = get_string(&p);
end_line(&p);
continue;
}
if ( cmd_match("isdn-msn",&p) ) {
skip_assignment(&p);
isdn_msn = get_string(&p);
end_line(&p);
continue;
}
if ( cmd_match("country",&p) ) {
skip_assignment(&p);
home_country = get_string(&p);
end_line(&p);
continue;
}
if ( cmd_match("international-prefix",&p) ) {
skip_assignment(&p);
int_prefix = get_string(&p);
end_line(&p);
continue;
}
if ( cmd_match("watchdog-timer",&p) ) {
skip_assignment(&p);
watchdog_timeout = get_int(&p);
end_line(&p);
if ( watchdog_timeout < 0 ) {
fprintf(stderr,"%s: Watchdog timer must be positive or zero\n",
progname);
exit(1);
}
continue;
}
if ( cmd_match("realtime-priority",&p) ) {
skip_assignment(&p);
realtime_priority = get_int(&p);
end_line(&p);
if ( realtime_priority < 0 || realtime_priority > 99 ) {
fprintf(stderr,"%s: Real-Time priority must be in range 0-99\n",
progname);
exit(1);
}
continue;
}
if ( cmd_match("lock-memory",&p) ) {
skip_assignment(&p);
do_lock_memory = get_int(&p);
end_line(&p);
if ( do_lock_memory < 0 || do_lock_memory > 1 ) {
fprintf(stderr,"%s: 'lock-memory' must be 0 or 1 in config file\n",
progname);
exit(1);
}
continue;
}
}
fclose(cfg);
}

67
misc/watchdog.c Normal file
View File

@ -0,0 +1,67 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Watchdog timer in case of misbehaving real-time process.
Copyright (C) 1999 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
#include <stdio.h>
#include <signum.h>
#include <signal.h>
#include <sys/time.h>
#include <ifax/misc/globals.h>
#include <ifax/misc/readconfig.h>
#include <ifax/misc/watchdog.h>
static struct itimerval timer;
static void watchdog_trigger(int signum)
{
fprintf(stderr,"\n\n%s: Watchdog timer triggered a termination\n",progname);
exit(17);
}
void initialize_watchdog_timer(void)
{
if ( signal(SIGPROF,watchdog_trigger) == SIG_ERR ) {
fprintf(stderr,"%s: Can't install watchdog signal handeler\n",progname);
exit(1);
}
}
void reset_watchdog_timer(void)
{
timer.it_value.tv_sec = watchdog_timeout;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
if ( setitimer(ITIMER_PROF, &timer, (struct itimerval *)0) < 0 ) {
fprintf(stderr,"%s: Can't install watchdog timer\n",progname);
exit(1);
}
}