mbtask added portcheck, code cleanup
This commit is contained in:
parent
9cefcf9b3a
commit
19183e73b6
@ -4637,6 +4637,8 @@ v0.33.20 10-Feb-2002
|
|||||||
Removed some debug logging.
|
Removed some debug logging.
|
||||||
Creates the semafore is_inet when the internet connections is
|
Creates the semafore is_inet when the internet connections is
|
||||||
available, and removes it when it is down.
|
available, and removes it when it is down.
|
||||||
|
Added test for ISDN/modem lines in use.
|
||||||
|
Lost of code cleanup.
|
||||||
|
|
||||||
mbcico:
|
mbcico:
|
||||||
Fixed binkp driver to accept incoming unprotected sessions.
|
Fixed binkp driver to accept incoming unprotected sessions.
|
||||||
|
@ -5,11 +5,14 @@
|
|||||||
include ../Makefile.global
|
include ../Makefile.global
|
||||||
|
|
||||||
SRCS = callstat.c nodelist.c scanout.c taskcomm.c taskinfo.c taskstat.c \
|
SRCS = callstat.c nodelist.c scanout.c taskcomm.c taskinfo.c taskstat.c \
|
||||||
mbtask.c outstat.c signame.c taskdisk.c taskregs.c taskutil.c
|
mbtask.c outstat.c signame.c taskdisk.c taskregs.c taskutil.c \
|
||||||
|
ports.c calllist.c ping.c
|
||||||
HDRS = callstat.h mbtask.h outstat.h signame.h taskdisk.h taskregs.h taskutil.h \
|
HDRS = callstat.h mbtask.h outstat.h signame.h taskdisk.h taskregs.h taskutil.h \
|
||||||
libs.h nodelist.h scanout.h taskcomm.h taskinfo.h taskstat.h
|
libs.h nodelist.h scanout.h taskcomm.h taskinfo.h taskstat.h \
|
||||||
|
ports.h calllist.h ping.h
|
||||||
OBJS = callstat.o nodelist.o scanout.o taskcomm.o taskinfo.o taskstat.o \
|
OBJS = callstat.o nodelist.o scanout.o taskcomm.o taskinfo.o taskstat.o \
|
||||||
mbtask.o outstat.o signame.o taskdisk.o taskregs.o taskutil.o
|
mbtask.o outstat.o signame.o taskdisk.o taskregs.o taskutil.o \
|
||||||
|
ports.o calllist.o ping.o
|
||||||
OTHER = Makefile issue issue.netbsd
|
OTHER = Makefile issue issue.netbsd
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
@ -80,10 +83,13 @@ scanout.o: libs.h ../lib/structs.h taskutil.h scanout.h
|
|||||||
taskcomm.o: libs.h ../lib/structs.h taskstat.h taskregs.h taskdisk.h taskinfo.h taskutil.h taskcomm.h
|
taskcomm.o: libs.h ../lib/structs.h taskstat.h taskregs.h taskdisk.h taskinfo.h taskutil.h taskcomm.h
|
||||||
taskinfo.o: libs.h ../lib/structs.h taskinfo.h
|
taskinfo.o: libs.h ../lib/structs.h taskinfo.h
|
||||||
taskstat.o: libs.h ../lib/structs.h taskstat.h callstat.h outstat.h taskutil.h
|
taskstat.o: libs.h ../lib/structs.h taskstat.h callstat.h outstat.h taskutil.h
|
||||||
mbtask.o: libs.h ../lib/structs.h signame.h taskstat.h taskutil.h taskregs.h taskcomm.h callstat.h outstat.h nodelist.h mbtask.h
|
mbtask.o: libs.h ../lib/structs.h signame.h taskstat.h taskutil.h taskregs.h taskcomm.h callstat.h outstat.h nodelist.h ports.h calllist.h ping.h mbtask.h
|
||||||
outstat.o: libs.h ../lib/structs.h taskutil.h taskstat.h scanout.h nodelist.h callstat.h outstat.h
|
outstat.o: libs.h ../lib/structs.h taskutil.h taskstat.h scanout.h nodelist.h callstat.h ports.h outstat.h
|
||||||
signame.o: signame.h
|
signame.o: signame.h
|
||||||
taskdisk.o: libs.h ../lib/structs.h taskdisk.h taskutil.h
|
taskdisk.o: libs.h ../lib/structs.h taskdisk.h taskutil.h
|
||||||
taskregs.o: libs.h ../lib/structs.h taskstat.h taskregs.h taskutil.h
|
taskregs.o: libs.h ../lib/structs.h taskstat.h taskregs.h taskutil.h
|
||||||
taskutil.o: libs.h ../lib/structs.h signame.h scanout.h taskutil.h
|
taskutil.o: libs.h ../lib/structs.h signame.h scanout.h taskutil.h
|
||||||
|
ports.o: libs.h ../lib/structs.h taskutil.h nodelist.h ports.h
|
||||||
|
calllist.o: libs.h ../lib/structs.h taskstat.h taskutil.h callstat.h outstat.h mbtask.h ports.h calllist.h
|
||||||
|
ping.o: libs.h ../lib/structs.h taskstat.h taskutil.h ping.h
|
||||||
# End of generated dependencies
|
# End of generated dependencies
|
||||||
|
154
mbtask/calllist.c
Normal file
154
mbtask/calllist.c
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
* Purpose ...............: mbtask - calllist
|
||||||
|
*
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 1997-2002
|
||||||
|
*
|
||||||
|
* Michiel Broek FIDO: 2:280/2802
|
||||||
|
* Beekmansbos 10
|
||||||
|
* 1971 BV IJmuiden
|
||||||
|
* the Netherlands
|
||||||
|
*
|
||||||
|
* This file is part of MBSE BBS.
|
||||||
|
*
|
||||||
|
* This BBS 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, or (at your option) any
|
||||||
|
* later version.
|
||||||
|
*
|
||||||
|
* MBSE BBS 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 MBSE BBS; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "libs.h"
|
||||||
|
#include "../lib/structs.h"
|
||||||
|
#include "taskstat.h"
|
||||||
|
#include "taskutil.h"
|
||||||
|
#include "callstat.h"
|
||||||
|
#include "outstat.h"
|
||||||
|
#include "mbtask.h"
|
||||||
|
#include "ports.h"
|
||||||
|
#include "calllist.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Global variables
|
||||||
|
*/
|
||||||
|
tocall calllist[MAXTASKS]; /* Array with calllist */
|
||||||
|
extern int internet; /* Internet is down */
|
||||||
|
extern int s_scanout; /* Scan outbound sema */
|
||||||
|
extern int s_do_inet; /* Internet wanted */
|
||||||
|
extern _alist_l *alist; /* Nodes to call list */
|
||||||
|
extern int pots_calls;
|
||||||
|
extern int isdn_calls;
|
||||||
|
extern int inet_calls;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the actual list of nodes to call.
|
||||||
|
*/
|
||||||
|
int check_calllist(void)
|
||||||
|
{
|
||||||
|
int i, found, call_work;
|
||||||
|
struct _alist *tmp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check callist, remove obsolete entries.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < MAXTASKS; i++) {
|
||||||
|
if (calllist[i].addr.zone) {
|
||||||
|
found = FALSE;
|
||||||
|
for (tmp = alist; tmp; tmp = tmp->next) {
|
||||||
|
if ((calllist[i].addr.zone == tmp->addr.zone) && (calllist[i].addr.net == tmp->addr.net) &&
|
||||||
|
(calllist[i].addr.node == tmp->addr.node) && (calllist[i].addr.point == tmp->addr.point) &&
|
||||||
|
((tmp->flavors) & F_CALL)) {
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
tasklog('c', "Removing slot %d node %s from calllist", i, ascfnode(calllist[i].addr, 0x0f));
|
||||||
|
memset(&calllist[i], 0, sizeof(tocall));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check_ports();
|
||||||
|
|
||||||
|
if (pots_calls || isdn_calls || inet_calls) {
|
||||||
|
call_work = 0;
|
||||||
|
for (tmp = alist; tmp; tmp = tmp->next) {
|
||||||
|
if (tmp->callmode != CM_NONE) {
|
||||||
|
call_work++;
|
||||||
|
found = FALSE;
|
||||||
|
for (i = 0; i < MAXTASKS; i++) {
|
||||||
|
if ((calllist[i].addr.zone == tmp->addr.zone) && (calllist[i].addr.net == tmp->addr.net) &&
|
||||||
|
(calllist[i].addr.node == tmp->addr.node) && (calllist[i].addr.point == tmp->addr.point)) {
|
||||||
|
found = TRUE;
|
||||||
|
/*
|
||||||
|
* Refresh last call status
|
||||||
|
*/
|
||||||
|
calllist[i].cst = tmp->cst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
for (i = 0; i < MAXTASKS; i++) {
|
||||||
|
if (!calllist[i].addr.zone) {
|
||||||
|
tasklog('c', "Adding %s to calllist slot %d", ascfnode(tmp->addr, 0x1f), i);
|
||||||
|
calllist[i].addr = tmp->addr;
|
||||||
|
calllist[i].cst = tmp->cst;
|
||||||
|
calllist[i].callmode = tmp->callmode;
|
||||||
|
calllist[i].moflags = tmp->moflags;
|
||||||
|
calllist[i].diflags = tmp->diflags;
|
||||||
|
calllist[i].ipflags = tmp->ipflags;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tasklog('o', "%d systems to call", call_work);
|
||||||
|
} else {
|
||||||
|
if (s_scanout)
|
||||||
|
sem_set((char *)"scanout", FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if we need to remove the do_inet semafore
|
||||||
|
*/
|
||||||
|
if (!inet_calls && internet && s_do_inet) {
|
||||||
|
tasklog('c', "Removing do_inet semafore");
|
||||||
|
s_do_inet = FALSE;
|
||||||
|
if (IsSema((char *)"do_inet")) {
|
||||||
|
RemoveSema((char *)"do_inet");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
call_work = 0;
|
||||||
|
for (i = 0; i < MAXTASKS; i++) {
|
||||||
|
if (calllist[i].addr.zone) {
|
||||||
|
if (!call_work) {
|
||||||
|
tasklog('c', "Slot Call Pid Try Status Mode Modem ISDN TCP/IP Address");
|
||||||
|
tasklog('c', "---- ----- ----- --- ------- ------- -------- -------- -------- ----------------");
|
||||||
|
}
|
||||||
|
call_work++;
|
||||||
|
tasklog('c', "%4d %s %5d %3d %s %s %08x %08x %08x %s", i, calllist[i].calling?"true ":"false", calllist[i].taskpid,
|
||||||
|
calllist[i].cst.tryno, callstatus(calllist[i].cst.trystat), callmode(calllist[i].callmode),
|
||||||
|
calllist[i].moflags, calllist[i].diflags, calllist[i].ipflags, ascfnode(calllist[i].addr, 0x1f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return call_work;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
26
mbtask/calllist.h
Normal file
26
mbtask/calllist.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#ifndef _CALLLIST_H
|
||||||
|
#define _CALLLIST_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callist
|
||||||
|
*/
|
||||||
|
typedef struct _tocall {
|
||||||
|
fidoaddr addr; /* Address to call */
|
||||||
|
int callmode; /* Method to use */
|
||||||
|
callstat cst; /* Last call status */
|
||||||
|
int calling; /* Is calling */
|
||||||
|
pid_t taskpid; /* Task pid number */
|
||||||
|
unsigned long moflags; /* Modem flags */
|
||||||
|
unsigned long diflags; /* ISDN flags */
|
||||||
|
unsigned long ipflags; /* TCP/IP flags */
|
||||||
|
} tocall;
|
||||||
|
|
||||||
|
|
||||||
|
int check_calllist(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
420
mbtask/mbtask.c
420
mbtask/mbtask.c
@ -38,32 +38,18 @@
|
|||||||
#include "callstat.h"
|
#include "callstat.h"
|
||||||
#include "outstat.h"
|
#include "outstat.h"
|
||||||
#include "nodelist.h"
|
#include "nodelist.h"
|
||||||
|
#include "ports.h"
|
||||||
|
#include "calllist.h"
|
||||||
|
#include "ping.h"
|
||||||
#include "mbtask.h"
|
#include "mbtask.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Defines.
|
|
||||||
* SLOWRUN is number of seconds for scheduling mailer calls. Leave at 20!
|
|
||||||
*/
|
|
||||||
#define MAXTASKS 10
|
|
||||||
#define SLOWRUN 20
|
|
||||||
#define TMPNAME "TMP."
|
|
||||||
#define LCKNAME "LOCKTASK"
|
|
||||||
#define ICMP_BASEHDR_LEN 8
|
|
||||||
#define ICMP_MAX_ERRS 5
|
|
||||||
#define SET_SOCKA_LEN4(socka)
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {P_INIT, P_SENT, P_FAIL, P_OK, P_ERROR, P_NONE} PINGSTATE;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global variables
|
* Global variables
|
||||||
*/
|
*/
|
||||||
static onetask task[MAXTASKS]; /* Array with tasks */
|
static onetask task[MAXTASKS]; /* Array with tasks */
|
||||||
static tocall calllist[MAXTASKS]; /* Array with calllist */
|
extern tocall calllist[MAXTASKS]; /* Array with calllist */
|
||||||
reg_info reginfo[MAXCLIENT]; /* Array with clients */
|
reg_info reginfo[MAXCLIENT]; /* Array with clients */
|
||||||
static pid_t pgrp; /* Pids group */
|
static pid_t pgrp; /* Pids group */
|
||||||
static char lockfile[PATH_MAX]; /* Lockfile */
|
static char lockfile[PATH_MAX]; /* Lockfile */
|
||||||
@ -85,8 +71,7 @@ time_t tty_time; /* TTY config time */
|
|||||||
char tcfgfn[PATH_MAX]; /* Config file name */
|
char tcfgfn[PATH_MAX]; /* Config file name */
|
||||||
char cfgfn[PATH_MAX]; /* Config file name */
|
char cfgfn[PATH_MAX]; /* Config file name */
|
||||||
char ttyfn[PATH_MAX]; /* TTY file name */
|
char ttyfn[PATH_MAX]; /* TTY file name */
|
||||||
int ping_isocket; /* Ping socket */
|
extern int ping_isocket; /* Ping socket */
|
||||||
int icmp_errs = 0; /* ICMP error counter */
|
|
||||||
int internet = FALSE; /* Internet is down */
|
int internet = FALSE; /* Internet is down */
|
||||||
double Load; /* System Load */
|
double Load; /* System Load */
|
||||||
int Processing; /* Is system running */
|
int Processing; /* Is system running */
|
||||||
@ -101,10 +86,7 @@ extern int s_newnews; /* New news semafore */
|
|||||||
extern int s_reqindex; /* Create req index sem */
|
extern int s_reqindex; /* Create req index sem */
|
||||||
extern int s_msglink; /* Messages link sem */
|
extern int s_msglink; /* Messages link sem */
|
||||||
extern int s_do_inet; /* Internet wanted */
|
extern int s_do_inet; /* Internet wanted */
|
||||||
int pingstate = P_INIT; /* Ping state */
|
extern int pingresult[2]; /* Ping results */
|
||||||
int pingnr = 1; /* Ping #, 1 or 2 */
|
|
||||||
int pingresult[2]; /* Ping results */
|
|
||||||
char pingaddress[41]; /* Ping current address */
|
|
||||||
int masterinit = FALSE; /* Master init needed */
|
int masterinit = FALSE; /* Master init needed */
|
||||||
int ptimer = PAUSETIME; /* Pause timer */
|
int ptimer = PAUSETIME; /* Pause timer */
|
||||||
int tflags = FALSE; /* if nodes with Txx */
|
int tflags = FALSE; /* if nodes with Txx */
|
||||||
@ -466,103 +448,6 @@ void load_taskcfg(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check the actual list of nodes to call.
|
|
||||||
*/
|
|
||||||
int check_calllist(void);
|
|
||||||
int check_calllist(void)
|
|
||||||
{
|
|
||||||
int i, found, call_work;
|
|
||||||
struct _alist *tmp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check callist, remove obsolete entries.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < MAXTASKS; i++) {
|
|
||||||
if (calllist[i].addr.zone) {
|
|
||||||
found = FALSE;
|
|
||||||
for (tmp = alist; tmp; tmp = tmp->next) {
|
|
||||||
if ((calllist[i].addr.zone == tmp->addr.zone) && (calllist[i].addr.net == tmp->addr.net) &&
|
|
||||||
(calllist[i].addr.node == tmp->addr.node) && (calllist[i].addr.point == tmp->addr.point) &&
|
|
||||||
((tmp->flavors) & F_CALL)) {
|
|
||||||
found = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
tasklog('c', "Removing slot %d node %s from calllist", i, ascfnode(calllist[i].addr, 0x0f));
|
|
||||||
memset(&calllist[i], 0, sizeof(tocall));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pots_calls || isdn_calls || inet_calls) {
|
|
||||||
call_work = 0;
|
|
||||||
for (tmp = alist; tmp; tmp = tmp->next) {
|
|
||||||
if (tmp->callmode != CM_NONE) {
|
|
||||||
call_work++;
|
|
||||||
found = FALSE;
|
|
||||||
for (i = 0; i < MAXTASKS; i++) {
|
|
||||||
if ((calllist[i].addr.zone == tmp->addr.zone) && (calllist[i].addr.net == tmp->addr.net) &&
|
|
||||||
(calllist[i].addr.node == tmp->addr.node) && (calllist[i].addr.point == tmp->addr.point)) {
|
|
||||||
found = TRUE;
|
|
||||||
/*
|
|
||||||
* Refresh last call status
|
|
||||||
*/
|
|
||||||
calllist[i].cst = tmp->cst;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
for (i = 0; i < MAXTASKS; i++) {
|
|
||||||
if (!calllist[i].addr.zone) {
|
|
||||||
tasklog('c', "Adding %s to calllist slot %d", ascfnode(tmp->addr, 0x1f), i);
|
|
||||||
calllist[i].addr = tmp->addr;
|
|
||||||
calllist[i].cst = tmp->cst;
|
|
||||||
calllist[i].callmode = tmp->callmode;
|
|
||||||
calllist[i].moflags = tmp->moflags;
|
|
||||||
calllist[i].diflags = tmp->diflags;
|
|
||||||
calllist[i].ipflags = tmp->ipflags;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tasklog('o', "%d systems to call", call_work);
|
|
||||||
} else {
|
|
||||||
if (s_scanout)
|
|
||||||
sem_set((char *)"scanout", FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if we need to remove the do_inet semafore
|
|
||||||
*/
|
|
||||||
if (!inet_calls && internet && s_do_inet) {
|
|
||||||
tasklog('c', "Removing do_inet semafore");
|
|
||||||
s_do_inet = FALSE;
|
|
||||||
if (IsSema((char *)"do_inet")) {
|
|
||||||
RemoveSema((char *)"do_inet");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
call_work = 0;
|
|
||||||
for (i = 0; i < MAXTASKS; i++) {
|
|
||||||
if (calllist[i].addr.zone) {
|
|
||||||
if (!call_work) {
|
|
||||||
tasklog('c', "Slot Call Pid Try Status Mode Modem ISDN TCP/IP Address");
|
|
||||||
tasklog('c', "---- ----- ----- --- ------- ------- -------- -------- -------- ----------------");
|
|
||||||
}
|
|
||||||
call_work++;
|
|
||||||
tasklog('c', "%4d %s %5d %3d %s %s %08x %08x %08x %s", i, calllist[i].calling?"true ":"false", calllist[i].taskpid,
|
|
||||||
calllist[i].cst.tryno, callstatus(calllist[i].cst.trystat), callmode(calllist[i].callmode),
|
|
||||||
calllist[i].moflags, calllist[i].diflags, calllist[i].ipflags, ascfnode(calllist[i].addr, 0x1f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return call_work;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Launch an external program in the background.
|
* Launch an external program in the background.
|
||||||
* On success add it to the tasklist and return
|
* On success add it to the tasklist and return
|
||||||
@ -885,216 +770,6 @@ void ulocktask(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* different names, same thing... be careful, as these are macros... */
|
|
||||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
|
||||||
# define icmphdr icmp
|
|
||||||
# define iphdr ip
|
|
||||||
# define ip_saddr ip_src.s_addr
|
|
||||||
# define ip_daddr ip_dst.s_addr
|
|
||||||
#else
|
|
||||||
# define ip_saddr saddr
|
|
||||||
# define ip_daddr daddr
|
|
||||||
# define ip_hl ihl
|
|
||||||
# define ip_p protocol
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
# define icmp_type type
|
|
||||||
# define icmp_code code
|
|
||||||
# define icmp_cksum checksum
|
|
||||||
# ifdef icmp_id
|
|
||||||
# undef icmp_id
|
|
||||||
# endif
|
|
||||||
# define icmp_id un.echo.id
|
|
||||||
# ifdef icmp_seq
|
|
||||||
# undef icmp_seq
|
|
||||||
# endif
|
|
||||||
# define icmp_seq un.echo.sequence
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
|
||||||
# define ICMP_DEST_UNREACH ICMP_UNREACH
|
|
||||||
# define ICMP_TIME_EXCEEDED ICMP_TIMXCEED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ICMP_BASEHDR_LEN 8
|
|
||||||
#define ICMP4_ECHO_LEN ICMP_BASEHDR_LEN
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Takes a packet as send out and a recieved ICMP packet and looks whether the ICMP packet is
|
|
||||||
* an error reply on the sent-out one. packet is only the packet (without IP header).
|
|
||||||
* errmsg includes an IP header.
|
|
||||||
* to is the destination address of the original packet (the only thing that is actually
|
|
||||||
* compared of the IP header). The RFC sais that we get at least 8 bytes of the offending packet.
|
|
||||||
* We do not compare more, as this is all we need.
|
|
||||||
*/
|
|
||||||
static int icmp4_errcmp(char *packet, int plen, struct in_addr *to, char *errmsg, int elen, int errtype)
|
|
||||||
{
|
|
||||||
struct iphdr iph;
|
|
||||||
struct icmphdr icmph;
|
|
||||||
struct iphdr eiph;
|
|
||||||
char *data;
|
|
||||||
|
|
||||||
/* XXX: lots of memcpy to avoid unaligned accesses on alpha */
|
|
||||||
if (elen < sizeof(struct iphdr))
|
|
||||||
return 0;
|
|
||||||
memcpy(&iph, errmsg, sizeof(iph));
|
|
||||||
if (iph.ip_p != IPPROTO_ICMP || elen < iph.ip_hl * 4 + ICMP_BASEHDR_LEN + sizeof(eiph))
|
|
||||||
return 0;
|
|
||||||
memcpy(&icmph, errmsg + iph.ip_hl * 4, ICMP_BASEHDR_LEN);
|
|
||||||
memcpy(&eiph, errmsg + iph.ip_hl * 4 + ICMP_BASEHDR_LEN, sizeof(eiph));
|
|
||||||
if (elen < iph.ip_hl * 4 + ICMP_BASEHDR_LEN + eiph.ip_hl * 4 + 8)
|
|
||||||
return 0;
|
|
||||||
data = errmsg + iph.ip_hl * 4 + ICMP_BASEHDR_LEN + eiph.ip_hl * 4;
|
|
||||||
return icmph.icmp_type == errtype && memcmp(&to->s_addr, &eiph.ip_daddr, sizeof(to->s_addr)) == 0 &&
|
|
||||||
memcmp(data, packet, plen < 8 ?plen:8) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned short get_rand16(void)
|
|
||||||
{
|
|
||||||
return random()&0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
short p_sequence = 0;
|
|
||||||
unsigned short id;
|
|
||||||
struct icmphdr icmpd;
|
|
||||||
struct sockaddr_in to;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IPv4/ICMPv4 ping. Called from ping (see below)
|
|
||||||
*/
|
|
||||||
int ping_send(struct in_addr addr)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
int isock;
|
|
||||||
#ifdef __linux__
|
|
||||||
struct icmp_filter f;
|
|
||||||
#else
|
|
||||||
struct protoent *pe;
|
|
||||||
int SOL_IP;
|
|
||||||
#endif
|
|
||||||
unsigned long sum;
|
|
||||||
unsigned short *ptr;
|
|
||||||
|
|
||||||
#ifndef __linux__
|
|
||||||
if (!(pe = getprotobyname("ip"))) {
|
|
||||||
tasklog('?', "icmp ping: getprotobyname() failed: %s", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
SOL_IP = pe->p_proto;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
isock = ping_isocket;
|
|
||||||
p_sequence = 1;
|
|
||||||
id = (unsigned short)get_rand16(); /* randomize a ping id */
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
/* Fancy ICMP filering -- only on Linux (as far is I know) */
|
|
||||||
|
|
||||||
/* In fact, there should be macros for treating icmp_filter, but I haven't found them in Linux 2.2.15.
|
|
||||||
* So, set it manually and unportable ;-) */
|
|
||||||
/* This filter lets ECHO_REPLY (0), DEST_UNREACH(3) and TIME_EXCEEDED(11) pass. */
|
|
||||||
/* !(0000 1000 0000 1001) = 0xff ff f7 f6 */
|
|
||||||
f.data=0xfffff7f6;
|
|
||||||
if (setsockopt(isock, SOL_RAW, ICMP_FILTER, &f, sizeof(f)) == -1) {
|
|
||||||
if (icmp_errs < ICMP_MAX_ERRS)
|
|
||||||
tasklog('?', "$icmp ping: setsockopt() failed %d", isock);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
icmpd.icmp_type = ICMP_ECHO;
|
|
||||||
icmpd.icmp_code = 0;
|
|
||||||
icmpd.icmp_cksum = 0;
|
|
||||||
icmpd.icmp_id = htons((short)id);
|
|
||||||
icmpd.icmp_seq = htons(p_sequence);
|
|
||||||
|
|
||||||
/* Checksumming - Algorithm taken from nmap. Thanks... */
|
|
||||||
|
|
||||||
ptr = (unsigned short *)&icmpd;
|
|
||||||
sum = 0;
|
|
||||||
|
|
||||||
for (len = 0; len < 4; len++) {
|
|
||||||
sum += *ptr++;
|
|
||||||
}
|
|
||||||
sum = (sum >> 16) + (sum & 0xffff);
|
|
||||||
sum += (sum >> 16);
|
|
||||||
icmpd.icmp_cksum = ~sum;
|
|
||||||
|
|
||||||
memset(&to, 0, sizeof(to));
|
|
||||||
to.sin_family = AF_INET;
|
|
||||||
to.sin_port = 0;
|
|
||||||
to.sin_addr = addr;
|
|
||||||
SET_SOCKA_LEN4(to);
|
|
||||||
if (sendto(isock, &icmpd, ICMP4_ECHO_LEN, 0, (struct sockaddr *)&to, sizeof(to)) == -1) {
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ping_receive(struct in_addr addr)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
int isock;
|
|
||||||
int len;
|
|
||||||
struct sockaddr_in ffrom;
|
|
||||||
struct icmphdr icmpp;
|
|
||||||
struct iphdr iph;
|
|
||||||
socklen_t sl;
|
|
||||||
struct pollfd pfd;
|
|
||||||
|
|
||||||
isock = ping_isocket;
|
|
||||||
|
|
||||||
pfd.fd = isock;
|
|
||||||
pfd.events = POLLIN;
|
|
||||||
/*
|
|
||||||
* 10 mSec is enough, this function is called at regular intervals.
|
|
||||||
*/
|
|
||||||
if (poll(&pfd, 1, 10) < 0) {
|
|
||||||
if (icmp_errs < ICMP_MAX_ERRS)
|
|
||||||
tasklog('?', "$poll/select failed");
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfd.revents & POLLIN || pfd.revents & POLLERR || pfd.revents & POLLHUP || pfd.revents & POLLNVAL) {
|
|
||||||
sl = sizeof(ffrom);
|
|
||||||
if ((len = recvfrom(isock, &buf, sizeof(buf), 0,(struct sockaddr *)&ffrom, &sl)) != -1) {
|
|
||||||
if (len > sizeof(struct iphdr)) {
|
|
||||||
memcpy(&iph, buf, sizeof(iph));
|
|
||||||
if (len - iph.ip_hl * 4 >= ICMP_BASEHDR_LEN) {
|
|
||||||
memcpy(&icmpp, ((unsigned long int *)buf)+iph.ip_hl, sizeof(icmpp));
|
|
||||||
if (iph.ip_saddr == addr.s_addr &&
|
|
||||||
icmpp.icmp_type == ICMP_ECHOREPLY &&
|
|
||||||
ntohs(icmpp.icmp_id) == id &&
|
|
||||||
ntohs(icmpp.icmp_seq) <= p_sequence) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
/* No regular echo reply. Maybe an error? */
|
|
||||||
if (icmp4_errcmp((char *)&icmpd, ICMP4_ECHO_LEN,
|
|
||||||
&to.sin_addr, buf, len, ICMP_DEST_UNREACH) ||
|
|
||||||
icmp4_errcmp((char *)&icmpd, ICMP4_ECHO_LEN,
|
|
||||||
&to.sin_addr, buf, len, ICMP_TIME_EXCEEDED)) {
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return -5; /* error */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -6; /* no answer */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* External Semafore Checks
|
* External Semafore Checks
|
||||||
@ -1169,7 +844,6 @@ void scheduler(void)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
#endif
|
#endif
|
||||||
struct pollfd pfd;
|
struct pollfd pfd;
|
||||||
struct in_addr paddr;
|
|
||||||
int call_work;
|
int call_work;
|
||||||
static int call_entry = MAXTASKS;
|
static int call_entry = MAXTASKS;
|
||||||
double loadavg[3];
|
double loadavg[3];
|
||||||
@ -1271,7 +945,7 @@ void scheduler(void)
|
|||||||
check_sema();
|
check_sema();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the systems load average. FIXME: doesn't work in FreeBSD !!!
|
* Check the systems load average.
|
||||||
*/
|
*/
|
||||||
Load = loadavg[0] = loadavg[1] = loadavg[2] = 0.0;
|
Load = loadavg[0] = loadavg[1] = loadavg[2] = 0.0;
|
||||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
@ -1345,6 +1019,7 @@ void scheduler(void)
|
|||||||
if (file_time(ttyfn) != tty_time) {
|
if (file_time(ttyfn) != tty_time) {
|
||||||
tasklog('+', "Ports configuration changed, reloading");
|
tasklog('+', "Ports configuration changed, reloading");
|
||||||
load_ports();
|
load_ports();
|
||||||
|
check_ports();
|
||||||
sem_set((char *)"scanout", TRUE);
|
sem_set((char *)"scanout", TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1440,69 +1115,7 @@ void scheduler(void)
|
|||||||
*/
|
*/
|
||||||
oldmin = tm->tm_sec / SLOWRUN;
|
oldmin = tm->tm_sec / SLOWRUN;
|
||||||
|
|
||||||
/*
|
check_ping();
|
||||||
* If the previous pingstat is still P_SENT, then we now consider it a timeout.
|
|
||||||
*/
|
|
||||||
if (pingstate == P_SENT) {
|
|
||||||
pingresult[pingnr] = FALSE;
|
|
||||||
icmp_errs++;
|
|
||||||
if (icmp_errs < ICMP_MAX_ERRS)
|
|
||||||
tasklog('p', "ping %s seq=%d timeout", pingaddress, p_sequence);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check internet connection with ICMP ping
|
|
||||||
*/
|
|
||||||
rc = 0;
|
|
||||||
if (pingnr == 1) {
|
|
||||||
pingnr = 2;
|
|
||||||
if (strlen(TCFG.isp_ping2)) {
|
|
||||||
sprintf(pingaddress, "%s", TCFG.isp_ping2);
|
|
||||||
} else {
|
|
||||||
pingstate = P_NONE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pingnr = 1;
|
|
||||||
if (strlen(TCFG.isp_ping1)) {
|
|
||||||
sprintf(pingaddress, "%s", TCFG.isp_ping1);
|
|
||||||
} else {
|
|
||||||
pingstate = P_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inet_aton(pingaddress, &paddr)) {
|
|
||||||
rc = ping_send(paddr);
|
|
||||||
if (rc) {
|
|
||||||
if (icmp_errs++ < ICMP_MAX_ERRS)
|
|
||||||
tasklog('?', "ping send %s rc=%d", pingaddress, rc);
|
|
||||||
pingstate = P_FAIL;
|
|
||||||
pingresult[pingnr] = FALSE;
|
|
||||||
} else {
|
|
||||||
pingstate = P_SENT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (icmp_errs++ < ICMP_MAX_ERRS)
|
|
||||||
tasklog('?', "Ping address %d is invalid \"%s\"", pingnr, pingaddress);
|
|
||||||
pingstate = P_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pingresult[1] == FALSE && pingresult[2] == FALSE) {
|
|
||||||
icmp_errs++;
|
|
||||||
if (internet) {
|
|
||||||
tasklog('!', "Internet connection is down");
|
|
||||||
internet = FALSE;
|
|
||||||
sem_set((char *)"scanout", TRUE);
|
|
||||||
RemoveSema((char *)"is_inet");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!internet) {
|
|
||||||
tasklog('!', "Internet connection is up");
|
|
||||||
internet = TRUE;
|
|
||||||
sem_set((char *)"scanout", TRUE);
|
|
||||||
CreateSema((char *)"is_inet");
|
|
||||||
}
|
|
||||||
icmp_errs = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update outbound status if needed.
|
* Update outbound status if needed.
|
||||||
@ -1580,19 +1193,7 @@ void scheduler(void)
|
|||||||
/*
|
/*
|
||||||
* PING state changes
|
* PING state changes
|
||||||
*/
|
*/
|
||||||
switch (pingstate) {
|
state_ping();
|
||||||
case P_NONE: pingresult[pingnr] = TRUE;
|
|
||||||
break;
|
|
||||||
case P_SENT: rc = ping_receive(paddr);
|
|
||||||
if (!rc) {
|
|
||||||
pingstate = P_OK;
|
|
||||||
pingresult[pingnr] = TRUE;
|
|
||||||
} else {
|
|
||||||
if (rc != -6)
|
|
||||||
tasklog('p', "ping recv %s id=%d rc=%d", pingaddress, id, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (Processing) {
|
if (Processing) {
|
||||||
@ -1679,6 +1280,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
sprintf(ttyfn, "%s/etc/ttyinfo.data", getenv("MBSE_ROOT"));
|
sprintf(ttyfn, "%s/etc/ttyinfo.data", getenv("MBSE_ROOT"));
|
||||||
load_ports();
|
load_ports();
|
||||||
|
check_ports();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that init is complete and this program is locked, it is
|
* Now that init is complete and this program is locked, it is
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
|
/* $Id */
|
||||||
|
|
||||||
#ifndef _MBTASK_H
|
#ifndef _MBTASK_H
|
||||||
#define _MBTASK_H
|
#define _MBTASK_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines.
|
||||||
|
* SLOWRUN is number of seconds for scheduling mailer calls. Leave at 20!
|
||||||
|
*/
|
||||||
|
#define MAXTASKS 10
|
||||||
|
#define SLOWRUN 20
|
||||||
|
#define TMPNAME "TMP."
|
||||||
|
#define LCKNAME "LOCKTASK"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -19,22 +29,6 @@ typedef struct _onetask {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Callist
|
|
||||||
*/
|
|
||||||
typedef struct _tocall {
|
|
||||||
fidoaddr addr; /* Address to call */
|
|
||||||
int callmode; /* Method to use */
|
|
||||||
callstat cst; /* Last call status */
|
|
||||||
int calling; /* Is calling */
|
|
||||||
pid_t taskpid; /* Task pid number */
|
|
||||||
unsigned long moflags; /* Modem flags */
|
|
||||||
unsigned long diflags; /* ISDN flags */
|
|
||||||
unsigned long ipflags; /* TCP/IP flags */
|
|
||||||
} tocall;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Logging flagbits, ' ' ? ! + -
|
* Logging flagbits, ' ' ? ! + -
|
||||||
*/
|
*/
|
||||||
@ -53,10 +47,6 @@ pid_t launch(char *, char *, char *, int);
|
|||||||
int runtasktype(int);
|
int runtasktype(int);
|
||||||
int checktasks(int);
|
int checktasks(int);
|
||||||
void die(int);
|
void die(int);
|
||||||
static int icmp4_errcmp(char *, int, struct in_addr *, char *, int, int);
|
|
||||||
unsigned short get_rand16(void);
|
|
||||||
int ping_send(struct in_addr);
|
|
||||||
int ping_receive(struct in_addr);
|
|
||||||
void scheduler(void);
|
void scheduler(void);
|
||||||
int locktask(char *);
|
int locktask(char *);
|
||||||
void ulocktask(void);
|
void ulocktask(void);
|
||||||
|
106
mbtask/outstat.c
106
mbtask/outstat.c
@ -35,6 +35,7 @@
|
|||||||
#include "scanout.h"
|
#include "scanout.h"
|
||||||
#include "nodelist.h"
|
#include "nodelist.h"
|
||||||
#include "callstat.h"
|
#include "callstat.h"
|
||||||
|
#include "ports.h"
|
||||||
#include "outstat.h"
|
#include "outstat.h"
|
||||||
|
|
||||||
|
|
||||||
@ -42,13 +43,11 @@ extern int do_quiet;
|
|||||||
extern int internet; /* Internet status */
|
extern int internet; /* Internet status */
|
||||||
extern struct sysconfig CFG; /* Main configuration */
|
extern struct sysconfig CFG; /* Main configuration */
|
||||||
extern struct taskrec TCFG; /* Task configuration */
|
extern struct taskrec TCFG; /* Task configuration */
|
||||||
extern char ttyfn[]; /* TTY file name */
|
|
||||||
extern time_t tty_time; /* TTY update time */
|
|
||||||
int nxt_hour, nxt_min; /* Time of next event */
|
int nxt_hour, nxt_min; /* Time of next event */
|
||||||
int inet_calls; /* Internet calls to make */
|
int inet_calls; /* Internet calls to make */
|
||||||
int isdn_calls; /* ISDN calls to make */
|
int isdn_calls; /* ISDN calls to make */
|
||||||
int pots_calls; /* POTS calls to make */
|
int pots_calls; /* POTS calls to make */
|
||||||
pp_list *pl = NULL; /* Portlist */
|
extern pp_list *pl; /* Portlist */
|
||||||
_alist_l *alist = NULL; /* Nodes to call list */
|
_alist_l *alist = NULL; /* Nodes to call list */
|
||||||
extern int s_do_inet; /* Internet wanted */
|
extern int s_do_inet; /* Internet wanted */
|
||||||
|
|
||||||
@ -383,7 +382,7 @@ int outstat()
|
|||||||
*/
|
*/
|
||||||
if ((tmp->callmode == CM_NONE) && TCFG.max_isdn) {
|
if ((tmp->callmode == CM_NONE) && TCFG.max_isdn) {
|
||||||
/*
|
/*
|
||||||
* Dialup node, check available dialout ports
|
* ISDN node, check available dialout ports
|
||||||
*/
|
*/
|
||||||
for (tpl = pl; tpl; tpl = tpl->next) {
|
for (tpl = pl; tpl; tpl = tpl->next) {
|
||||||
if (tpl->dflags & tmp->diflags) {
|
if (tpl->dflags & tmp->diflags) {
|
||||||
@ -394,6 +393,9 @@ int outstat()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((tmp->callmode == CM_NONE) && TCFG.max_pots) {
|
if ((tmp->callmode == CM_NONE) && TCFG.max_pots) {
|
||||||
|
/*
|
||||||
|
* POTS node, check available modems
|
||||||
|
*/
|
||||||
for (tpl = pl; tpl; tpl = tpl->next) {
|
for (tpl = pl; tpl; tpl = tpl->next) {
|
||||||
if (tpl->mflags & tmp->moflags) {
|
if (tpl->mflags & tmp->moflags) {
|
||||||
pots_calls++;
|
pots_calls++;
|
||||||
@ -563,99 +565,3 @@ int each(faddr *addr, char flavor, int isflo, char *fname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tidy the portlist
|
|
||||||
*/
|
|
||||||
void tidy_portlist(pp_list **);
|
|
||||||
void tidy_portlist(pp_list ** fdp)
|
|
||||||
{
|
|
||||||
pp_list *tmp, *old;
|
|
||||||
|
|
||||||
tasklog('p', "tidy_portlist");
|
|
||||||
for (tmp = *fdp; tmp; tmp = old) {
|
|
||||||
old = tmp->next;
|
|
||||||
free(tmp);
|
|
||||||
}
|
|
||||||
*fdp = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add a port to the portlist
|
|
||||||
*/
|
|
||||||
void fill_portlist(pp_list **, pp_list *);
|
|
||||||
void fill_portlist(pp_list **fdp, pp_list *new)
|
|
||||||
{
|
|
||||||
pp_list *tmp, *ta;
|
|
||||||
|
|
||||||
tmp = (pp_list *)malloc(sizeof(pp_list));
|
|
||||||
tmp->next = NULL;
|
|
||||||
strncpy(tmp->tty, new->tty, 6);
|
|
||||||
tmp->mflags = new->mflags;
|
|
||||||
tmp->dflags = new->dflags;
|
|
||||||
|
|
||||||
if (*fdp == NULL) {
|
|
||||||
*fdp = tmp;
|
|
||||||
} else {
|
|
||||||
for (ta = *fdp; ta; ta = ta->next)
|
|
||||||
if (ta->next == NULL) {
|
|
||||||
ta->next = (pp_list *)tmp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Build a list of available dialout ports.
|
|
||||||
*/
|
|
||||||
void load_ports()
|
|
||||||
{
|
|
||||||
FILE *fp;
|
|
||||||
pp_list new;
|
|
||||||
int count = 0, j, stdflag;
|
|
||||||
char *p, *q;
|
|
||||||
|
|
||||||
tidy_portlist(&pl);
|
|
||||||
if ((fp = fopen(ttyfn, "r")) == NULL) {
|
|
||||||
tasklog('?', "$Can't open %s", ttyfn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fread(&ttyinfohdr, sizeof(ttyinfohdr), 1, fp);
|
|
||||||
|
|
||||||
tasklog('p', "Building portlist...");
|
|
||||||
while (fread(&ttyinfo, ttyinfohdr.recsize, 1, fp) == 1) {
|
|
||||||
if (((ttyinfo.type == POTS) || (ttyinfo.type == ISDN)) && (ttyinfo.available) && (ttyinfo.callout)) {
|
|
||||||
memset(&new, 0, sizeof(new));
|
|
||||||
strncpy(new.tty, ttyinfo.tty, 6);
|
|
||||||
|
|
||||||
stdflag = TRUE;
|
|
||||||
q = xstrcpy(ttyinfo.flags);
|
|
||||||
for (p = q; p; p = q) {
|
|
||||||
if ((q = strchr(p, ',')))
|
|
||||||
*q++ = '\0';
|
|
||||||
if ((strncasecmp(p, "U", 1) == 0) && (strlen(p) == 1)) {
|
|
||||||
stdflag = FALSE;
|
|
||||||
} else {
|
|
||||||
for (j = 0; fkey[j].key; j++)
|
|
||||||
if (strcasecmp(p, fkey[j].key) == 0)
|
|
||||||
new.mflags |= fkey[j].flag;
|
|
||||||
for (j = 0; dkey[j].key; j++)
|
|
||||||
if (strcasecmp(p, dkey[j].key) == 0)
|
|
||||||
new.dflags |= dkey[j].flag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tasklog('p', "port %s modem %08lx ISDN %08lx", new.tty, new.mflags, new.dflags);
|
|
||||||
fill_portlist(&pl, &new);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
tty_time = file_time(ttyfn);
|
|
||||||
tasklog('p', "make_portlist %d ports", count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,17 +31,6 @@ typedef struct _alist
|
|||||||
} _alist_l;
|
} _alist_l;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Linked list of available dialout ports.
|
|
||||||
*/
|
|
||||||
typedef struct _pp_list {
|
|
||||||
struct _pp_list *next;
|
|
||||||
char tty[7]; /* tty name of the port */
|
|
||||||
unsigned long mflags; /* Analogue modem flags */
|
|
||||||
unsigned long dflags; /* ISDN flags */
|
|
||||||
int locked; /* If port is locked */
|
|
||||||
} pp_list;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bitmasks for calling status
|
* Bitmasks for calling status
|
||||||
@ -58,15 +47,9 @@ typedef struct _pp_list {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct _ttyinfohdr ttyinfohdr; /* TTY lines */
|
|
||||||
struct _ttyinfo ttyinfo;
|
|
||||||
|
|
||||||
|
|
||||||
int each(faddr *, char, int, char *);
|
int each(faddr *, char, int, char *);
|
||||||
char *callstatus(int);
|
char *callstatus(int);
|
||||||
char *callmode(int);
|
char *callmode(int);
|
||||||
int outstat(void);
|
int outstat(void);
|
||||||
void load_ports(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
370
mbtask/ping.c
Normal file
370
mbtask/ping.c
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
* Purpose ...............: mbtask - ping functions
|
||||||
|
*
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 1997-2002
|
||||||
|
*
|
||||||
|
* Michiel Broek FIDO: 2:280/2802
|
||||||
|
* Beekmansbos 10
|
||||||
|
* 1971 BV IJmuiden
|
||||||
|
* the Netherlands
|
||||||
|
*
|
||||||
|
* This file is part of MBSE BBS.
|
||||||
|
*
|
||||||
|
* This BBS 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, or (at your option) any
|
||||||
|
* later version.
|
||||||
|
*
|
||||||
|
* MBSE BBS 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 MBSE BBS; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "libs.h"
|
||||||
|
#include "../lib/structs.h"
|
||||||
|
#include "taskstat.h"
|
||||||
|
#include "taskutil.h"
|
||||||
|
#include "ping.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Global variables
|
||||||
|
*/
|
||||||
|
extern struct taskrec TCFG; /* Task config record */
|
||||||
|
int ping_isocket; /* Ping socket */
|
||||||
|
int icmp_errs = 0; /* ICMP error counter */
|
||||||
|
extern int internet; /* Internet is down */
|
||||||
|
int pingstate = P_INIT; /* Ping state */
|
||||||
|
int pingnr = 1; /* Ping #, 1 or 2 */
|
||||||
|
int pingresult[2]; /* Ping results */
|
||||||
|
char pingaddress[41]; /* Ping current address */
|
||||||
|
struct in_addr paddr; /* Current ping address */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int icmp4_errcmp(char *, int, struct in_addr *, char *, int, int);
|
||||||
|
unsigned short get_rand16(void);
|
||||||
|
int ping_send(struct in_addr);
|
||||||
|
int ping_receive(struct in_addr);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* different names, same thing... be careful, as these are macros...
|
||||||
|
*/
|
||||||
|
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
|
# define icmphdr icmp
|
||||||
|
# define iphdr ip
|
||||||
|
# define ip_saddr ip_src.s_addr
|
||||||
|
# define ip_daddr ip_dst.s_addr
|
||||||
|
#else
|
||||||
|
# define ip_saddr saddr
|
||||||
|
# define ip_daddr daddr
|
||||||
|
# define ip_hl ihl
|
||||||
|
# define ip_p protocol
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
# define icmp_type type
|
||||||
|
# define icmp_code code
|
||||||
|
# define icmp_cksum checksum
|
||||||
|
# ifdef icmp_id
|
||||||
|
# undef icmp_id
|
||||||
|
# endif
|
||||||
|
# define icmp_id un.echo.id
|
||||||
|
# ifdef icmp_seq
|
||||||
|
# undef icmp_seq
|
||||||
|
# endif
|
||||||
|
# define icmp_seq un.echo.sequence
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
|
# define ICMP_DEST_UNREACH ICMP_UNREACH
|
||||||
|
# define ICMP_TIME_EXCEEDED ICMP_TIMXCEED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ICMP_BASEHDR_LEN 8
|
||||||
|
#define ICMP4_ECHO_LEN ICMP_BASEHDR_LEN
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Takes a packet as send out and a recieved ICMP packet and looks whether the ICMP packet is
|
||||||
|
* an error reply on the sent-out one. packet is only the packet (without IP header).
|
||||||
|
* errmsg includes an IP header.
|
||||||
|
* to is the destination address of the original packet (the only thing that is actually
|
||||||
|
* compared of the IP header). The RFC sais that we get at least 8 bytes of the offending packet.
|
||||||
|
* We do not compare more, as this is all we need.
|
||||||
|
*/
|
||||||
|
static int icmp4_errcmp(char *packet, int plen, struct in_addr *to, char *errmsg, int elen, int errtype)
|
||||||
|
{
|
||||||
|
struct iphdr iph;
|
||||||
|
struct icmphdr icmph;
|
||||||
|
struct iphdr eiph;
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
/* XXX: lots of memcpy to avoid unaligned accesses on alpha */
|
||||||
|
if (elen < sizeof(struct iphdr))
|
||||||
|
return 0;
|
||||||
|
memcpy(&iph, errmsg, sizeof(iph));
|
||||||
|
if (iph.ip_p != IPPROTO_ICMP || elen < iph.ip_hl * 4 + ICMP_BASEHDR_LEN + sizeof(eiph))
|
||||||
|
return 0;
|
||||||
|
memcpy(&icmph, errmsg + iph.ip_hl * 4, ICMP_BASEHDR_LEN);
|
||||||
|
memcpy(&eiph, errmsg + iph.ip_hl * 4 + ICMP_BASEHDR_LEN, sizeof(eiph));
|
||||||
|
if (elen < iph.ip_hl * 4 + ICMP_BASEHDR_LEN + eiph.ip_hl * 4 + 8)
|
||||||
|
return 0;
|
||||||
|
data = errmsg + iph.ip_hl * 4 + ICMP_BASEHDR_LEN + eiph.ip_hl * 4;
|
||||||
|
return icmph.icmp_type == errtype && memcmp(&to->s_addr, &eiph.ip_daddr, sizeof(to->s_addr)) == 0 &&
|
||||||
|
memcmp(data, packet, plen < 8 ?plen:8) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned short get_rand16(void)
|
||||||
|
{
|
||||||
|
return random()&0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
short p_sequence = 0;
|
||||||
|
unsigned short id;
|
||||||
|
struct icmphdr icmpd;
|
||||||
|
struct sockaddr_in to;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IPv4/ICMPv4 ping. Called from ping (see below)
|
||||||
|
*/
|
||||||
|
int ping_send(struct in_addr addr)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
int isock;
|
||||||
|
#ifdef __linux__
|
||||||
|
struct icmp_filter f;
|
||||||
|
#else
|
||||||
|
struct protoent *pe;
|
||||||
|
int SOL_IP;
|
||||||
|
#endif
|
||||||
|
unsigned long sum;
|
||||||
|
unsigned short *ptr;
|
||||||
|
|
||||||
|
#ifndef __linux__
|
||||||
|
if (!(pe = getprotobyname("ip"))) {
|
||||||
|
tasklog('?', "icmp ping: getprotobyname() failed: %s", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SOL_IP = pe->p_proto;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
isock = ping_isocket;
|
||||||
|
p_sequence = 1;
|
||||||
|
id = (unsigned short)get_rand16(); /* randomize a ping id */
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
/* Fancy ICMP filering -- only on Linux (as far is I know) */
|
||||||
|
|
||||||
|
/* In fact, there should be macros for treating icmp_filter, but I haven't found them in Linux 2.2.15.
|
||||||
|
* So, set it manually and unportable ;-) */
|
||||||
|
/* This filter lets ECHO_REPLY (0), DEST_UNREACH(3) and TIME_EXCEEDED(11) pass. */
|
||||||
|
/* !(0000 1000 0000 1001) = 0xff ff f7 f6 */
|
||||||
|
f.data=0xfffff7f6;
|
||||||
|
if (setsockopt(isock, SOL_RAW, ICMP_FILTER, &f, sizeof(f)) == -1) {
|
||||||
|
if (icmp_errs < ICMP_MAX_ERRS)
|
||||||
|
tasklog('?', "$icmp ping: setsockopt() failed %d", isock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
icmpd.icmp_type = ICMP_ECHO;
|
||||||
|
icmpd.icmp_code = 0;
|
||||||
|
icmpd.icmp_cksum = 0;
|
||||||
|
icmpd.icmp_id = htons((short)id);
|
||||||
|
icmpd.icmp_seq = htons(p_sequence);
|
||||||
|
|
||||||
|
/* Checksumming - Algorithm taken from nmap. Thanks... */
|
||||||
|
|
||||||
|
ptr = (unsigned short *)&icmpd;
|
||||||
|
sum = 0;
|
||||||
|
|
||||||
|
for (len = 0; len < 4; len++) {
|
||||||
|
sum += *ptr++;
|
||||||
|
}
|
||||||
|
sum = (sum >> 16) + (sum & 0xffff);
|
||||||
|
sum += (sum >> 16);
|
||||||
|
icmpd.icmp_cksum = ~sum;
|
||||||
|
|
||||||
|
memset(&to, 0, sizeof(to));
|
||||||
|
to.sin_family = AF_INET;
|
||||||
|
to.sin_port = 0;
|
||||||
|
to.sin_addr = addr;
|
||||||
|
SET_SOCKA_LEN4(to);
|
||||||
|
if (sendto(isock, &icmpd, ICMP4_ECHO_LEN, 0, (struct sockaddr *)&to, sizeof(to)) == -1) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int ping_receive(struct in_addr addr)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
int isock;
|
||||||
|
int len;
|
||||||
|
struct sockaddr_in ffrom;
|
||||||
|
struct icmphdr icmpp;
|
||||||
|
struct iphdr iph;
|
||||||
|
socklen_t sl;
|
||||||
|
struct pollfd pfd;
|
||||||
|
|
||||||
|
isock = ping_isocket;
|
||||||
|
|
||||||
|
pfd.fd = isock;
|
||||||
|
pfd.events = POLLIN;
|
||||||
|
/*
|
||||||
|
* 10 mSec is enough, this function is called at regular intervals.
|
||||||
|
*/
|
||||||
|
if (poll(&pfd, 1, 10) < 0) {
|
||||||
|
if (icmp_errs < ICMP_MAX_ERRS)
|
||||||
|
tasklog('?', "$poll/select failed");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pfd.revents & POLLIN || pfd.revents & POLLERR || pfd.revents & POLLHUP || pfd.revents & POLLNVAL) {
|
||||||
|
sl = sizeof(ffrom);
|
||||||
|
if ((len = recvfrom(isock, &buf, sizeof(buf), 0,(struct sockaddr *)&ffrom, &sl)) != -1) {
|
||||||
|
if (len > sizeof(struct iphdr)) {
|
||||||
|
memcpy(&iph, buf, sizeof(iph));
|
||||||
|
if (len - iph.ip_hl * 4 >= ICMP_BASEHDR_LEN) {
|
||||||
|
memcpy(&icmpp, ((unsigned long int *)buf)+iph.ip_hl, sizeof(icmpp));
|
||||||
|
if (iph.ip_saddr == addr.s_addr &&
|
||||||
|
icmpp.icmp_type == ICMP_ECHOREPLY &&
|
||||||
|
ntohs(icmpp.icmp_id) == id &&
|
||||||
|
ntohs(icmpp.icmp_seq) <= p_sequence) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* No regular echo reply. Maybe an error? */
|
||||||
|
if (icmp4_errcmp((char *)&icmpd, ICMP4_ECHO_LEN,
|
||||||
|
&to.sin_addr, buf, len, ICMP_DEST_UNREACH) ||
|
||||||
|
icmp4_errcmp((char *)&icmpd, ICMP4_ECHO_LEN,
|
||||||
|
&to.sin_addr, buf, len, ICMP_TIME_EXCEEDED)) {
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -5; /* error */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -6; /* no answer */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void check_ping(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the previous pingstat is still P_SENT, then we now consider it a timeout.
|
||||||
|
*/
|
||||||
|
if (pingstate == P_SENT) {
|
||||||
|
pingresult[pingnr] = FALSE;
|
||||||
|
icmp_errs++;
|
||||||
|
if (icmp_errs < ICMP_MAX_ERRS)
|
||||||
|
tasklog('p', "ping %s seq=%d timeout", pingaddress, p_sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check internet connection with ICMP ping
|
||||||
|
*/
|
||||||
|
rc = 0;
|
||||||
|
if (pingnr == 1) {
|
||||||
|
pingnr = 2;
|
||||||
|
if (strlen(TCFG.isp_ping2)) {
|
||||||
|
sprintf(pingaddress, "%s", TCFG.isp_ping2);
|
||||||
|
} else {
|
||||||
|
pingstate = P_NONE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pingnr = 1;
|
||||||
|
if (strlen(TCFG.isp_ping1)) {
|
||||||
|
sprintf(pingaddress, "%s", TCFG.isp_ping1);
|
||||||
|
} else {
|
||||||
|
pingstate = P_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inet_aton(pingaddress, &paddr)) {
|
||||||
|
rc = ping_send(paddr);
|
||||||
|
if (rc) {
|
||||||
|
if (icmp_errs++ < ICMP_MAX_ERRS)
|
||||||
|
tasklog('?', "ping send %s rc=%d", pingaddress, rc);
|
||||||
|
pingstate = P_FAIL;
|
||||||
|
pingresult[pingnr] = FALSE;
|
||||||
|
} else {
|
||||||
|
pingstate = P_SENT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (icmp_errs++ < ICMP_MAX_ERRS)
|
||||||
|
tasklog('?', "Ping address %d is invalid \"%s\"", pingnr, pingaddress);
|
||||||
|
pingstate = P_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pingresult[1] == FALSE && pingresult[2] == FALSE) {
|
||||||
|
icmp_errs++;
|
||||||
|
if (internet) {
|
||||||
|
tasklog('!', "Internet connection is down");
|
||||||
|
internet = FALSE;
|
||||||
|
sem_set((char *)"scanout", TRUE);
|
||||||
|
RemoveSema((char *)"is_inet");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!internet) {
|
||||||
|
tasklog('!', "Internet connection is up");
|
||||||
|
internet = TRUE;
|
||||||
|
sem_set((char *)"scanout", TRUE);
|
||||||
|
CreateSema((char *)"is_inet");
|
||||||
|
}
|
||||||
|
icmp_errs = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void state_ping(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PING state changes
|
||||||
|
*/
|
||||||
|
switch (pingstate) {
|
||||||
|
case P_NONE: pingresult[pingnr] = TRUE;
|
||||||
|
break;
|
||||||
|
case P_SENT: rc = ping_receive(paddr);
|
||||||
|
if (!rc) {
|
||||||
|
pingstate = P_OK;
|
||||||
|
pingresult[pingnr] = TRUE;
|
||||||
|
} else {
|
||||||
|
if (rc != -6)
|
||||||
|
tasklog('p', "ping recv %s id=%d rc=%d", pingaddress, id, rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
22
mbtask/ping.h
Normal file
22
mbtask/ping.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* $Id */
|
||||||
|
|
||||||
|
#ifndef _PING_H
|
||||||
|
#define _PING_H
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {P_INIT, P_SENT, P_FAIL, P_OK, P_ERROR, P_NONE} PINGSTATE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines.
|
||||||
|
*/
|
||||||
|
#define ICMP_BASEHDR_LEN 8
|
||||||
|
#define ICMP_MAX_ERRS 5
|
||||||
|
#define SET_SOCKA_LEN4(socka)
|
||||||
|
|
||||||
|
void check_ping(void);
|
||||||
|
void state_ping(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
188
mbtask/ports.c
Normal file
188
mbtask/ports.c
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
* Purpose ...............: mbtask - mode portlists
|
||||||
|
*
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 1997-2002
|
||||||
|
*
|
||||||
|
* Michiel Broek FIDO: 2:280/2802
|
||||||
|
* Beekmansbos 10
|
||||||
|
* 1971 BV IJmuiden
|
||||||
|
* the Netherlands
|
||||||
|
*
|
||||||
|
* This file is part of MBSE BBS.
|
||||||
|
*
|
||||||
|
* This BBS 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, or (at your option) any
|
||||||
|
* later version.
|
||||||
|
*
|
||||||
|
* MBSE BBS 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 MBSE BBS; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "libs.h"
|
||||||
|
#include "../lib/structs.h"
|
||||||
|
#include "taskutil.h"
|
||||||
|
#include "nodelist.h"
|
||||||
|
#include "ports.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LOCKDIR
|
||||||
|
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
|
#define LOCKDIR "/var/spool/lock"
|
||||||
|
#else
|
||||||
|
#define LOCKDIR "/var/lock"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LCKPREFIX LOCKDIR"/LCK.."
|
||||||
|
#define LCKTMP LOCKDIR"/TMP."
|
||||||
|
|
||||||
|
|
||||||
|
extern char ttyfn[]; /* TTY file name */
|
||||||
|
extern time_t tty_time; /* TTY update time */
|
||||||
|
pp_list *pl = NULL; /* Portlist */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tidy the portlist
|
||||||
|
*/
|
||||||
|
void tidy_portlist(pp_list **);
|
||||||
|
void tidy_portlist(pp_list ** fdp)
|
||||||
|
{
|
||||||
|
pp_list *tmp, *old;
|
||||||
|
|
||||||
|
tasklog('p', "tidy_portlist");
|
||||||
|
for (tmp = *fdp; tmp; tmp = old) {
|
||||||
|
old = tmp->next;
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
*fdp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a port to the portlist
|
||||||
|
*/
|
||||||
|
void fill_portlist(pp_list **, pp_list *);
|
||||||
|
void fill_portlist(pp_list **fdp, pp_list *new)
|
||||||
|
{
|
||||||
|
pp_list *tmp, *ta;
|
||||||
|
|
||||||
|
tmp = (pp_list *)malloc(sizeof(pp_list));
|
||||||
|
tmp->next = NULL;
|
||||||
|
strncpy(tmp->tty, new->tty, 6);
|
||||||
|
tmp->mflags = new->mflags;
|
||||||
|
tmp->dflags = new->dflags;
|
||||||
|
|
||||||
|
if (*fdp == NULL) {
|
||||||
|
*fdp = tmp;
|
||||||
|
} else {
|
||||||
|
for (ta = *fdp; ta; ta = ta->next)
|
||||||
|
if (ta->next == NULL) {
|
||||||
|
ta->next = (pp_list *)tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build a list of available dialout ports.
|
||||||
|
*/
|
||||||
|
void load_ports()
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
pp_list new;
|
||||||
|
int count = 0, j, stdflag;
|
||||||
|
char *p, *q;
|
||||||
|
|
||||||
|
tidy_portlist(&pl);
|
||||||
|
if ((fp = fopen(ttyfn, "r")) == NULL) {
|
||||||
|
tasklog('?', "$Can't open %s", ttyfn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fread(&ttyinfohdr, sizeof(ttyinfohdr), 1, fp);
|
||||||
|
|
||||||
|
tasklog('p', "Building portlist...");
|
||||||
|
while (fread(&ttyinfo, ttyinfohdr.recsize, 1, fp) == 1) {
|
||||||
|
if (((ttyinfo.type == POTS) || (ttyinfo.type == ISDN)) && (ttyinfo.available) && (ttyinfo.callout)) {
|
||||||
|
memset(&new, 0, sizeof(new));
|
||||||
|
strncpy(new.tty, ttyinfo.tty, 6);
|
||||||
|
|
||||||
|
stdflag = TRUE;
|
||||||
|
q = xstrcpy(ttyinfo.flags);
|
||||||
|
for (p = q; p; p = q) {
|
||||||
|
if ((q = strchr(p, ',')))
|
||||||
|
*q++ = '\0';
|
||||||
|
if ((strncasecmp(p, "U", 1) == 0) && (strlen(p) == 1)) {
|
||||||
|
stdflag = FALSE;
|
||||||
|
} else {
|
||||||
|
for (j = 0; fkey[j].key; j++)
|
||||||
|
if (strcasecmp(p, fkey[j].key) == 0)
|
||||||
|
new.mflags |= fkey[j].flag;
|
||||||
|
for (j = 0; dkey[j].key; j++)
|
||||||
|
if (strcasecmp(p, dkey[j].key) == 0)
|
||||||
|
new.dflags |= dkey[j].flag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tasklog('p', "port %s modem %08lx ISDN %08lx", new.tty, new.mflags, new.dflags);
|
||||||
|
fill_portlist(&pl, &new);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
tty_time = file_time(ttyfn);
|
||||||
|
tasklog('p', "make_portlist %d ports", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check status of all modem/ISDN ports
|
||||||
|
*/
|
||||||
|
void check_ports(void)
|
||||||
|
{
|
||||||
|
pp_list *tpl;
|
||||||
|
char lckname[256];
|
||||||
|
FILE *lf;
|
||||||
|
int tmppid;
|
||||||
|
pid_t rempid = 0;
|
||||||
|
|
||||||
|
for (tpl = pl; tpl; tpl = tpl->next) {
|
||||||
|
sprintf(lckname, "%s%s", LCKPREFIX, tpl->tty);
|
||||||
|
// tasklog('p', "checking %s", lckname);
|
||||||
|
if ((lf = fopen(lckname, "r")) == NULL) {
|
||||||
|
if (tpl->locked) {
|
||||||
|
tpl->locked = 0;
|
||||||
|
tasklog('+', "Port %s is now free", tpl->tty);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fscanf(lf, "%d", &tmppid);
|
||||||
|
rempid = tmppid;
|
||||||
|
fclose(lf);
|
||||||
|
if (kill(rempid, 0) && (errno == ESRCH)) {
|
||||||
|
tasklog('+', "Stale lockfile for %s, unlink", tpl->tty);
|
||||||
|
unlink(lckname);
|
||||||
|
} else {
|
||||||
|
if (!tpl->locked) {
|
||||||
|
tpl->locked = rempid;
|
||||||
|
tasklog('+', "Port %s locked, pid %d", tpl->tty, rempid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
28
mbtask/ports.h
Normal file
28
mbtask/ports.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#ifndef _PORTS_H
|
||||||
|
#define _PORTS_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Linked list of available dialout ports.
|
||||||
|
*/
|
||||||
|
typedef struct _pp_list {
|
||||||
|
struct _pp_list *next;
|
||||||
|
char tty[7]; /* tty name of the port */
|
||||||
|
unsigned long mflags; /* Analogue modem flags */
|
||||||
|
unsigned long dflags; /* ISDN flags */
|
||||||
|
int locked; /* If port is locked */
|
||||||
|
} pp_list;
|
||||||
|
|
||||||
|
|
||||||
|
struct _ttyinfohdr ttyinfohdr; /* TTY lines */
|
||||||
|
struct _ttyinfo ttyinfo;
|
||||||
|
|
||||||
|
|
||||||
|
void load_ports(void); /* Initialize portlist */
|
||||||
|
void check_ports(void); /* Check status of all ports */
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user