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:
parent
18dd32f03e
commit
d9da365a39
|
@ -1,3 +1,4 @@
|
|||
v21_softmodem
|
||||
test
|
||||
amodemd
|
||||
*.o
|
||||
|
|
12
Makefile
12
Makefile
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
|
@ -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 */
|
|
@ -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);
|
|
@ -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);
|
|
@ -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 *~
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue