Added next bunch of IBC code
This commit is contained in:
parent
143de27956
commit
a9753fbdb0
316
mbtask/taskibc.c
316
mbtask/taskibc.c
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../lib/mbselib.h"
|
#include "../lib/mbselib.h"
|
||||||
|
#include "taskstat.h"
|
||||||
#include "taskibc.h"
|
#include "taskibc.h"
|
||||||
|
|
||||||
|
|
||||||
@ -38,64 +39,68 @@
|
|||||||
|
|
||||||
int ibc_run = FALSE; /* Thread running */
|
int ibc_run = FALSE; /* Thread running */
|
||||||
extern int T_Shutdown; /* Program shutdown */
|
extern int T_Shutdown; /* Program shutdown */
|
||||||
|
extern int internet; /* Internet status */
|
||||||
|
time_t scfg_time = (time_t)0; /* Servers config time */
|
||||||
|
ncs_list *ncsl = NULL; /* Neighbours list */
|
||||||
|
int ls; /* Listen socket */
|
||||||
|
struct sockaddr_in myaddr_in; /* Listen socket address */
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {NCS_INIT, NCS_CALL, NCS_WAITPWD, NCS_CONNECT, NCS_HANGUP, NCS_FAIL} NCSTYPE;
|
||||||
|
|
||||||
|
|
||||||
|
static char *ncsstate[] = {
|
||||||
|
(char *)"init", (char *)"call", (char *)"waitpwd", (char *)"connect", (char *)"hangup", (char *)"fail"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send a UDP message to one other server.
|
* Add a port to the portlist
|
||||||
*/
|
*/
|
||||||
void send_server(char *name, char *msg)
|
void fill_ncslist(ncs_list **, char *, char *);
|
||||||
|
void fill_ncslist(ncs_list **fdp, char *server, char *passwd)
|
||||||
{
|
{
|
||||||
int a1, a2, a3, a4;
|
ncs_list *tmp, *ta;
|
||||||
int s; /* Socket */
|
|
||||||
struct hostent *he; /* Host info */
|
|
||||||
struct servent *se; /* Service information */
|
|
||||||
struct sockaddr_in server; /* Destination address */
|
|
||||||
char *errmsg;
|
|
||||||
|
|
||||||
/*
|
tmp = (ncs_list *)malloc(sizeof(ncs_list));
|
||||||
* Get IP address for the hostname
|
memset(tmp, 0, sizeof(tmp));
|
||||||
*/
|
tmp->next = NULL;
|
||||||
if (sscanf(name,"%d.%d.%d.%d",&a1,&a2,&a3,&a4) == 4)
|
strncpy(tmp->server, server, 63);
|
||||||
server.sin_addr.s_addr = inet_addr(name);
|
strncpy(tmp->passwd, passwd, 15);
|
||||||
else if ((he = gethostbyname(name)))
|
tmp->state = NCS_INIT;
|
||||||
memcpy(&server.sin_addr,he->h_addr,he->h_length);
|
tmp->action = time(NULL);
|
||||||
else {
|
tmp->last = (time_t)0;
|
||||||
switch (h_errno) {
|
tmp->version = 0;
|
||||||
case HOST_NOT_FOUND: errmsg = (char *)"Authoritative: Host not found"; break;
|
tmp->remove = FALSE;
|
||||||
case TRY_AGAIN: errmsg = (char *)"Non-Authoritive: Host not found"; break;
|
tmp->socket = -1;
|
||||||
case NO_RECOVERY: errmsg = (char *)"Non recoverable errors"; break;
|
tmp->token = 0;
|
||||||
default: errmsg = (char *)"Unknown error"; break;
|
|
||||||
|
if (*fdp == NULL) {
|
||||||
|
*fdp = tmp;
|
||||||
|
} else {
|
||||||
|
for (ta = *fdp; ta; ta = ta->next)
|
||||||
|
if (ta->next == NULL) {
|
||||||
|
ta->next = (ncs_list *)tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Syslog('+', "No IP address for %s: %s", name, errmsg);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
se = getservbyname("fido", "udp");
|
|
||||||
if (se == NULL) {
|
|
||||||
Syslog('n', "Service fido udp not in /etc/services");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
server.sin_family = AF_INET;
|
|
||||||
server.sin_port = se->s_port;
|
|
||||||
|
|
||||||
Syslog('r', "Send to %s, port %d\n", inet_ntoa(server.sin_addr), ntohs(server.sin_port));
|
void dump_ncslist(void);
|
||||||
|
void dump_ncslist(void)
|
||||||
|
{
|
||||||
|
ncs_list *tmp;
|
||||||
|
time_t now;
|
||||||
|
|
||||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
now = time(NULL);
|
||||||
if (s == -1) {
|
Syslog('r', "Server State Del Next action");
|
||||||
Syslog('r', "$Can't create socket");
|
Syslog('r', "--------------------------------------------------------------- ------ --- --------------");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind(s, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1) {
|
for (tmp = ncsl; tmp; tmp = tmp->next) {
|
||||||
Syslog('r', "$Can't bind socket");
|
Syslog('r', "%-63s %-6s %s %d", tmp->server, ncsstate[tmp->state],
|
||||||
return;
|
tmp->remove ? "yes":"no ", (int)tmp->action - (int)now);
|
||||||
}
|
|
||||||
|
|
||||||
if (sendto(s, msg, strlen(msg), 0, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1) {
|
|
||||||
Syslog('r', "$Can't send message");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,29 +111,239 @@ void send_server(char *name, char *msg)
|
|||||||
*/
|
*/
|
||||||
void send_all(char *msg)
|
void send_all(char *msg)
|
||||||
{
|
{
|
||||||
send_server((char *)"router.mbse.ym", msg);
|
}
|
||||||
send_server((char *)"hppa.mbse.ym", msg);
|
|
||||||
|
|
||||||
|
|
||||||
|
void check_servers(void)
|
||||||
|
{
|
||||||
|
char *errmsg, scfgfn[PATH_MAX], buf[512];
|
||||||
|
FILE *fp;
|
||||||
|
ncs_list *tnsl;
|
||||||
|
int inlist, changed = FALSE;
|
||||||
|
time_t now;
|
||||||
|
int a1, a2, a3, a4;
|
||||||
|
struct servent *se;
|
||||||
|
struct hostent *he;
|
||||||
|
|
||||||
|
sprintf(scfgfn, "%s/etc/ibcsrv.data", getenv("MBSE_ROOT"));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if configuration is changed, if so then apply the changes.
|
||||||
|
*/
|
||||||
|
if (file_time(scfgfn) != scfg_time) {
|
||||||
|
Syslog('r', "%s filetime changed, rereading");
|
||||||
|
|
||||||
|
if ((fp = fopen(scfgfn, "r"))) {
|
||||||
|
fread(&ibcsrvhdr, sizeof(ibcsrvhdr), 1, fp);
|
||||||
|
|
||||||
|
while (fread(&ibcsrv, ibcsrvhdr.recsize, 1, fp)) {
|
||||||
|
Syslog('r', "IBC server \"%s\", Active %s", ibcsrv.server, ibcsrv.Active ?"Yes":"No");
|
||||||
|
if (ibcsrv.Active) {
|
||||||
|
inlist = FALSE;
|
||||||
|
for (tnsl = ncsl; tnsl; tnsl = tnsl->next) {
|
||||||
|
if (strcmp(tnsl->server, ibcsrv.server) == 0) {
|
||||||
|
inlist = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!inlist ) {
|
||||||
|
Syslog('r', " not in neighbour list, add");
|
||||||
|
fill_ncslist(&ncsl, ibcsrv.server, ibcsrv.passwd);
|
||||||
|
changed = TRUE;
|
||||||
|
Syslog('+', "Added Internet BBS Chatserver %s", ibcsrv.server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now check for neighbours to delete
|
||||||
|
*/
|
||||||
|
for (tnsl = ncsl; tnsl; tnsl = tnsl->next) {
|
||||||
|
fseek(fp, ibcsrvhdr.hdrsize, SEEK_SET);
|
||||||
|
inlist = FALSE;
|
||||||
|
Syslog('r', "IBC server \"%s\"", ibcsrv.server);
|
||||||
|
|
||||||
|
while (fread(&ibcsrv, ibcsrvhdr.recsize, 1, fp)) {
|
||||||
|
if ((strcmp(tnsl->server, ibcsrv.server) == 0) && ibcsrv.Active) {
|
||||||
|
inlist = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!inlist) {
|
||||||
|
Syslog('r', " not in configuration, remove");
|
||||||
|
tnsl->remove = TRUE;
|
||||||
|
tnsl->action = time(NULL);
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
scfg_time = file_time(scfgfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
dump_ncslist();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if we need to make state changes
|
||||||
|
*/
|
||||||
|
changed = FALSE;
|
||||||
|
now = time(NULL);
|
||||||
|
for (tnsl = ncsl; tnsl; tnsl = tnsl->next) {
|
||||||
|
if (((int)tnsl->action - (int)now) <= 0) {
|
||||||
|
switch (tnsl->state) {
|
||||||
|
case NCS_INIT: Syslog('r', "%s init", tnsl->server);
|
||||||
|
changed = TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If Internet is available, setup the connection.
|
||||||
|
*/
|
||||||
|
if (internet) {
|
||||||
|
/*
|
||||||
|
* Get IP address for the hostname, set default next action
|
||||||
|
* to 60 seconds.
|
||||||
|
*/
|
||||||
|
tnsl->action = now + (time_t)60;
|
||||||
|
memset(&tnsl->servaddr_in, 0, sizeof(struct sockaddr_in));
|
||||||
|
se = getservbyname("fido", "udp");
|
||||||
|
tnsl->servaddr_in.sin_family = AF_INET;
|
||||||
|
tnsl->servaddr_in.sin_port = se->s_port;
|
||||||
|
|
||||||
|
if (sscanf(tnsl->server,"%d.%d.%d.%d",&a1,&a2,&a3,&a4) == 4)
|
||||||
|
tnsl->servaddr_in.sin_addr.s_addr = inet_addr(tnsl->server);
|
||||||
|
else if ((he = gethostbyname(tnsl->server)))
|
||||||
|
memcpy(&tnsl->servaddr_in.sin_addr, he->h_addr, he->h_length);
|
||||||
|
else {
|
||||||
|
switch (h_errno) {
|
||||||
|
case HOST_NOT_FOUND: errmsg = (char *)"Authoritative: Host not found"; break;
|
||||||
|
case TRY_AGAIN: errmsg = (char *)"Non-Authoritive: Host not found"; break;
|
||||||
|
case NO_RECOVERY: errmsg = (char *)"Non recoverable errors"; break;
|
||||||
|
default: errmsg = (char *)"Unknown error"; break;
|
||||||
|
}
|
||||||
|
Syslog('+', "No IP address for %s: %s", tnsl->server, errmsg);
|
||||||
|
tnsl->state = NCS_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tnsl->socket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (tnsl->socket == -1) {
|
||||||
|
Syslog('+', "$Can't create socket for %s", tnsl->server);
|
||||||
|
tnsl->state = NCS_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Syslog('r', "socket %d", tnsl->socket);
|
||||||
|
tnsl->token = gettoken();
|
||||||
|
tnsl->state = NCS_CALL;
|
||||||
|
tnsl->action = now + (time_t)1;
|
||||||
|
} else {
|
||||||
|
tnsl->action = now + (time_t)10;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NCS_CALL: Syslog('r', "%s call", tnsl->server);
|
||||||
|
sprintf(buf, "PASS %s 0000 IBC| %s\r", tnsl->passwd, tnsl->compress ? "Z":"");
|
||||||
|
if (sendto(tnsl->socket, buf, strlen(buf), 0,
|
||||||
|
(struct sockaddr *)&tnsl->servaddr_in, sizeof(struct sockaddr_in)) == -1) {
|
||||||
|
Syslog('r', "$Can't send message");
|
||||||
|
}
|
||||||
|
sprintf(buf, "SERVER seaport 0 %ld mbsebbs v%s\r", tnsl->token, VERSION);
|
||||||
|
if (sendto(tnsl->socket, buf, strlen(buf), 0,
|
||||||
|
(struct sockaddr *)&tnsl->servaddr_in, sizeof(struct sockaddr_in)) == -1) {
|
||||||
|
Syslog('r', "$Can't send message");
|
||||||
|
}
|
||||||
|
tnsl->action = now + (time_t)50;
|
||||||
|
tnsl->state = NCS_WAITPWD;
|
||||||
|
changed = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NCS_WAITPWD: /*
|
||||||
|
* This state can be left by before the timeout is reached
|
||||||
|
* by a reply from the remote if the connection is accepted.
|
||||||
|
*/
|
||||||
|
Syslog('r', "%s waitpwd", tnsl->server);
|
||||||
|
tnsl->state = NCS_CALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
dump_ncslist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IRC thread
|
* IBC thread
|
||||||
*/
|
*/
|
||||||
void *ibc_thread(void *dummy)
|
void *ibc_thread(void *dummy)
|
||||||
{
|
{
|
||||||
struct servent *se;
|
struct servent *se;
|
||||||
|
struct pollfd pfd;
|
||||||
|
int rc, len;
|
||||||
|
socklen_t sl;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
Syslog('+', "Starting IBC thread");
|
||||||
|
|
||||||
if ((se = getservbyname("fido", "udp")) == NULL) {
|
if ((se = getservbyname("fido", "udp")) == NULL) {
|
||||||
Syslog('!', "No fido udp entry in /etc/services, cannot start Internet BBS Chat");
|
Syslog('!', "No fido udp entry in /etc/services, cannot start Internet BBS Chat");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Syslog('+', "Starting IBC thread");
|
myaddr_in.sin_family = AF_INET;
|
||||||
|
myaddr_in.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
myaddr_in.sin_port = se->s_port;
|
||||||
|
Syslog('+', "Listen on %s, port %d\n", inet_ntoa(myaddr_in.sin_addr), ntohs(myaddr_in.sin_port));
|
||||||
|
|
||||||
|
ls = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (ls == -1) {
|
||||||
|
Syslog('!', "$Can't create socket");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(ls, (struct sockaddr *)&myaddr_in, sizeof(struct sockaddr_in)) == -1) {
|
||||||
|
Syslog('!', "$Can't bind socket");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
ibc_run = TRUE;
|
ibc_run = TRUE;
|
||||||
|
|
||||||
while (! T_Shutdown) {
|
while (! T_Shutdown) {
|
||||||
sleep(1);
|
|
||||||
|
/*
|
||||||
|
* First check Shutdown requested
|
||||||
|
*/
|
||||||
|
if (T_Shutdown) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check neighbour servers state
|
||||||
|
*/
|
||||||
|
check_servers();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get any incoming messages
|
||||||
|
*/
|
||||||
|
pfd.fd = ls;
|
||||||
|
pfd.events = POLLIN;
|
||||||
|
pfd.revents = 0;
|
||||||
|
|
||||||
|
if ((rc = poll(&pfd, 1, 1000) < 0)) {
|
||||||
|
Syslog('r', "$poll/select failed");
|
||||||
|
} else {
|
||||||
|
Syslog('r', "poll_thread: poll interrupted rc=%d events=%04x", rc, pfd.revents);
|
||||||
|
|
||||||
|
if (pfd.revents & POLLIN || pfd.revents & POLLERR || pfd.revents & POLLHUP || pfd.revents & POLLNVAL) {
|
||||||
|
sl = sizeof(myaddr_in);
|
||||||
|
if ((len = recvfrom(ls, &buf, sizeof(buf)-1, 0,(struct sockaddr *)&myaddr_in, &sl)) != -1) {
|
||||||
|
Syslog('r', "< : \"%s\"", printable(buf, 0));
|
||||||
|
} else {
|
||||||
|
Syslog('r', "recvfrom returned len=%d", len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@ -138,7 +353,4 @@ exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,8 +4,30 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#ifdef USE_EXPERIMENT
|
#ifdef USE_EXPERIMENT
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Linked list of neighbour chatservers
|
||||||
|
*/
|
||||||
|
typedef struct _ncs_list {
|
||||||
|
struct _ncs_list *next;
|
||||||
|
char server[64]; /* Server address */
|
||||||
|
char passwd[16]; /* Server password */
|
||||||
|
int state; /* Connection state */
|
||||||
|
time_t action; /* Time for next action */
|
||||||
|
time_t last; /* Last received message */
|
||||||
|
int version; /* Protocol version of peer */
|
||||||
|
unsigned remove : 1; /* If entry must be removed */
|
||||||
|
unsigned compress : 1; /* User link compression */
|
||||||
|
struct sockaddr_in servaddr_in; /* Peer socketaddress */
|
||||||
|
int socket; /* Peer socket */
|
||||||
|
unsigned long token; /* Server token */
|
||||||
|
} ncs_list;
|
||||||
|
|
||||||
|
|
||||||
void send_all(char *);
|
void send_all(char *);
|
||||||
void *ibc_thread(void *);
|
void *ibc_thread(void *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -349,6 +349,15 @@ char *getseq(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long gettoken(void)
|
||||||
|
{
|
||||||
|
status.sequence++;
|
||||||
|
status_write();
|
||||||
|
return status.sequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int sem_set(char *sem, int value)
|
int sem_set(char *sem, int value)
|
||||||
{
|
{
|
||||||
if (!strcmp(sem, "scanout")) {
|
if (!strcmp(sem, "scanout")) {
|
||||||
|
@ -17,6 +17,7 @@ void stat_inc_cerr(void); /* Increase comms error */
|
|||||||
char *stat_status(void); /* Return status record */
|
char *stat_status(void); /* Return status record */
|
||||||
int stat_bbs_stat(void); /* Get BBS open status */
|
int stat_bbs_stat(void); /* Get BBS open status */
|
||||||
char *getseq(void); /* Get next sequence number */
|
char *getseq(void); /* Get next sequence number */
|
||||||
|
unsigned long gettoken(void); /* Get next sequence number */
|
||||||
int get_zmh(void); /* Check Zone Mail Hour */
|
int get_zmh(void); /* Check Zone Mail Hour */
|
||||||
int sem_set(char *, int); /* Set/Reset semafore */
|
int sem_set(char *, int); /* Set/Reset semafore */
|
||||||
char *sem_status(char *); /* Get semafore status */
|
char *sem_status(char *); /* Get semafore status */
|
||||||
|
Reference in New Issue
Block a user