Added outbound experimental calling to mbtask
This commit is contained in:
parent
86a46d24fd
commit
423e1b3022
@ -4394,6 +4394,8 @@ v0.33.19 26-Oct-2001
|
||||
Implemented Txx nodelist flags, FSC-0062.
|
||||
Added code to see which nodes could be called depending on
|
||||
outbound status, nodelist flags etc. Experimental.
|
||||
Added code to do outbound calling, experimental. Calling
|
||||
systems in parallel is now possible.
|
||||
|
||||
mbmon:
|
||||
Changed the lastcaller screen to display the External Door
|
||||
|
@ -77,13 +77,13 @@ depend:
|
||||
callstat.o: libs.h ../lib/structs.h taskutil.h callstat.h
|
||||
nodelist.o: libs.h ../lib/structs.h taskutil.h nodelist.h
|
||||
scanout.o: libs.h ../lib/structs.h taskutil.h scanout.h
|
||||
taskcomm.o: libs.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
|
||||
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
|
||||
outstat.o: libs.h ../lib/structs.h taskutil.h taskstat.h scanout.h nodelist.h callstat.h outstat.h
|
||||
signame.o: signame.h
|
||||
taskdisk.o: libs.h taskdisk.h taskutil.h
|
||||
taskregs.o: libs.h taskstat.h taskregs.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
|
||||
taskutil.o: libs.h ../lib/structs.h signame.h scanout.h taskutil.h
|
||||
# End of generated dependencies
|
||||
|
193
mbtask/mbtask.c
193
mbtask/mbtask.c
@ -63,6 +63,7 @@ typedef enum {P_INIT, P_SENT, P_FAIL, P_OK, P_ERROR, P_NONE} PINGSTATE;
|
||||
* Global variables
|
||||
*/
|
||||
static onetask task[MAXTASKS]; /* Array with tasks */
|
||||
static tocall calllist[MAXTASKS]; /* Array with calllist */
|
||||
reg_info reginfo[MAXCLIENT]; /* Array with clients */
|
||||
static pid_t pgrp; /* Pids group */
|
||||
static char lockfile[PATH_MAX]; /* Lockfile */
|
||||
@ -108,6 +109,10 @@ int ptimer = PAUSETIME; /* Pause timer */
|
||||
int tflags = FALSE; /* if nodes with Txx */
|
||||
extern int nxt_hour; /* Next event hour */
|
||||
extern int nxt_min; /* Next event minute */
|
||||
extern _alist_l *alist; /* Nodes to call list */
|
||||
extern int pots_calls;
|
||||
extern int isdn_calls;
|
||||
extern int inet_calls;
|
||||
|
||||
|
||||
|
||||
@ -459,6 +464,84 @@ 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)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tasklog('o', "%d systems to call", call_work);
|
||||
} else {
|
||||
if (s_scanout)
|
||||
sem_set((char *)"scanout", FALSE);
|
||||
}
|
||||
|
||||
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 Address");
|
||||
tasklog('c', "---- ----- ----- --- ------- ------- ----------------");
|
||||
}
|
||||
call_work++;
|
||||
tasklog('c', "%4d %s %5d %3d %s %s %s", i, calllist[i].calling?"true ":"false", calllist[i].taskpid,
|
||||
calllist[i].cst.tryno, callstatus(calllist[i].cst.trystat), callmode(calllist[i].callmode),
|
||||
ascfnode(calllist[i].addr, 0x1f));
|
||||
}
|
||||
}
|
||||
|
||||
return call_work;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Launch an external program in the background.
|
||||
* On success add it to the tasklist and return
|
||||
@ -590,19 +673,19 @@ int checktasks(int onsig)
|
||||
task[i].rc = wait4(task[i].pid, &status, WNOHANG | WUNTRACED, NULL);
|
||||
if (task[i].rc) {
|
||||
task[i].running = FALSE;
|
||||
if (task[i].tasktype == CALL_POTS || task[i].tasktype == CALL_ISDN || task[i].tasktype == CALL_IP)
|
||||
if (task[i].tasktype == CM_POTS || task[i].tasktype == CM_ISDN || task[i].tasktype == CM_INET)
|
||||
do_outstat = TRUE;
|
||||
ptimer = PAUSETIME;
|
||||
}
|
||||
|
||||
if (first && task[i].rc) {
|
||||
first = FALSE;
|
||||
tasklog('t', "Task T pid stat status rc status");
|
||||
tasklog('t', "---------------- - ----- ---- ----------- ----- --------");
|
||||
tasklog('t', "Task Type pid stat status rc status");
|
||||
tasklog('t', "---------------- ------- ----- ---- ----------- ----- --------");
|
||||
for (j = 0; j < MAXTASKS; j++)
|
||||
if (strlen(task[j].name))
|
||||
tasklog('t', "%-16s %d %5d %s %-11d %5d %08x", task[j].name,
|
||||
task[j].tasktype, task[j].pid, task[j].running?"runs":"stop",
|
||||
tasklog('t', "%-16s %s %5d %s %-11d %5d %08x", task[j].name,
|
||||
callmode(task[j].tasktype), task[j].pid, task[j].running?"runs":"stop",
|
||||
task[j].status, task[j].rc, task[j].status);
|
||||
}
|
||||
|
||||
@ -643,13 +726,22 @@ int checktasks(int onsig)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!task[i].running)
|
||||
if (!task[i].running) {
|
||||
for (j = 0; j < MAXTASKS; j++) {
|
||||
if (calllist[j].taskpid == task[i].pid) {
|
||||
calllist[j].calling = FALSE;
|
||||
calllist[j].taskpid = 0;
|
||||
}
|
||||
}
|
||||
memset(&task[i], 0, sizeof(onetask));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (do_outstat)
|
||||
if (do_outstat) {
|
||||
outstat();
|
||||
check_calllist();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -1049,9 +1141,9 @@ void check_sema(void)
|
||||
void scheduler(void)
|
||||
{
|
||||
struct passwd *pw;
|
||||
int running = 0, rc, rlen;
|
||||
int running = 0, rc, i, rlen, found;
|
||||
static int LOADhi = FALSE, oldmin = 70, olddo = 70, oldsec = 70;
|
||||
char *cmd = NULL;
|
||||
char *cmd = NULL, opts[41];
|
||||
static char doing[32], buf[2048];
|
||||
time_t now;
|
||||
struct tm *tm, *utm;
|
||||
@ -1059,6 +1151,8 @@ void scheduler(void)
|
||||
float lavg1, lavg2, lavg3;
|
||||
struct pollfd pfd;
|
||||
struct in_addr paddr;
|
||||
int call_work;
|
||||
static int call_entry = MAXTASKS;
|
||||
|
||||
InitFidonet();
|
||||
|
||||
@ -1366,19 +1460,83 @@ void scheduler(void)
|
||||
icmp_errs = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update outbound status if needed.
|
||||
*/
|
||||
if (s_scanout) {
|
||||
outstat();
|
||||
}
|
||||
call_work = check_calllist();
|
||||
|
||||
/*
|
||||
* Launch the systems to call, start one system each time.
|
||||
* Set the safety counter to MAXTASKS + 1, this forces that
|
||||
* the counter really will advance to the next node in case
|
||||
* of failing sessions.
|
||||
*/
|
||||
i = MAXTASKS + 1;
|
||||
found = FALSE;
|
||||
if (call_work) {
|
||||
while (TRUE) {
|
||||
/*
|
||||
* Rotate the call entries
|
||||
*/
|
||||
if (call_entry == MAXTASKS)
|
||||
call_entry = 0;
|
||||
else
|
||||
call_entry++;
|
||||
tasklog('c', "Call entry rotaded to %d", call_entry);
|
||||
if (calllist[call_entry].addr.zone && !calllist[call_entry].calling) {
|
||||
if ((calllist[call_entry].callmode == CM_INET) && (runtasktype(CM_INET) < TCFG.max_tcp)) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
if ((calllist[call_entry].callmode == CM_ISDN) && (runtasktype(CM_ISDN) < TCFG.max_isdn)) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
if ((calllist[call_entry].callmode == CM_POTS) && (runtasktype(CM_POTS) < TCFG.max_pots)) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Safety counter, if all systems are already calling, we should
|
||||
* never break out of this loop anymore.
|
||||
*/
|
||||
i--;
|
||||
if (!i)
|
||||
break;
|
||||
}
|
||||
if (found) {
|
||||
tasklog('c', "Should launch slot %d node %s", call_entry, ascfnode(calllist[call_entry].addr, 0x1f));
|
||||
cmd = xstrcpy(pw->pw_dir);
|
||||
cmd = xstrcat(cmd, (char *)"/bin/mbcico");
|
||||
sprintf(opts, "f%u.n%u.z%u", calllist[call_entry].addr.node, calllist[call_entry].addr.net,
|
||||
calllist[call_entry].addr.zone);
|
||||
calllist[call_entry].taskpid = launch(cmd, opts, (char *)"mbcico", calllist[call_entry].callmode);
|
||||
if (calllist[call_entry].taskpid)
|
||||
calllist[call_entry].calling = TRUE;
|
||||
running = checktasks(0);
|
||||
check_calllist();
|
||||
free(cmd);
|
||||
cmd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the mailer if something to do. For now we run just
|
||||
* one task and lock it with CALL_POTS.
|
||||
* Later tasks for different calltypes should run parallel.
|
||||
*/
|
||||
if (s_scanout && !runtasktype(CALL_POTS)) {
|
||||
cmd = xstrcpy(pw->pw_dir);
|
||||
cmd = xstrcat(cmd, (char *)"/bin/mbcico");
|
||||
launch(cmd, (char *)"-r1", (char *)"mbcico", CALL_POTS);
|
||||
running = checktasks(0);
|
||||
free(cmd);
|
||||
cmd = NULL;
|
||||
}
|
||||
// if (s_scanout && !runtasktype(CALL_POTS)) {
|
||||
// cmd = xstrcpy(pw->pw_dir);
|
||||
// cmd = xstrcat(cmd, (char *)"/bin/mbcico");
|
||||
// launch(cmd, (char *)"-r1", (char *)"mbcico", CALL_POTS);
|
||||
// running = checktasks(0);
|
||||
// free(cmd);
|
||||
// cmd = NULL;
|
||||
// }
|
||||
}
|
||||
|
||||
switch (pingstate) {
|
||||
@ -1475,6 +1633,7 @@ int main(int argc, char **argv)
|
||||
|
||||
memset(&task, 0, sizeof(task));
|
||||
memset(®info, 0, sizeof(reginfo));
|
||||
memset(&calllist, 0, sizeof(calllist));
|
||||
sprintf(spath, "%s/tmp/mbtask", getenv("MBSE_ROOT"));
|
||||
|
||||
sprintf(ttyfn, "%s/etc/ttyinfo.data", getenv("MBSE_ROOT"));
|
||||
|
@ -2,8 +2,6 @@
|
||||
#define _MBTASK_H
|
||||
|
||||
|
||||
typedef enum {CALL_POTS, CALL_ISDN, CALL_IP, MBFIDO, MBINDEX, MBFILE, MBINIT} TASKTYPE;
|
||||
|
||||
|
||||
/*
|
||||
* Running tasks information
|
||||
@ -21,6 +19,19 @@ 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 */
|
||||
} tocall;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Logging flagbits, ' ' ? ! + -
|
||||
*/
|
||||
|
@ -91,7 +91,6 @@ void set_next(int hour, int min)
|
||||
|
||||
|
||||
|
||||
char *callstatus(int);
|
||||
char *callstatus(int status)
|
||||
{
|
||||
switch (status) {
|
||||
@ -116,11 +115,15 @@ char *callstatus(int status)
|
||||
char *callmode(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case CM_NONE: return (char *)"None";
|
||||
case CM_INET: return (char *)"Inet";
|
||||
case CM_ISDN: return (char *)"ISDN";
|
||||
case CM_POTS: return (char *)"POTS";
|
||||
default: return (char *)"None";
|
||||
case CM_NONE: return (char *)"None ";
|
||||
case CM_INET: return (char *)"Inet ";
|
||||
case CM_ISDN: return (char *)"ISDN ";
|
||||
case CM_POTS: return (char *)"POTS ";
|
||||
case MBFIDO: return (char *)"mbfido ";
|
||||
case MBINDEX: return (char *)"mbindex";
|
||||
case MBFILE: return (char *)"mbfile ";
|
||||
case MBINIT: return (char *)"mbinit ";
|
||||
default: return (char *)"None ";
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +156,6 @@ int outstat()
|
||||
*/
|
||||
for (tmp = alist; tmp; tmp = old) {
|
||||
old = tmp->next;
|
||||
free(tmp->addr.domain);
|
||||
free(tmp);
|
||||
}
|
||||
alist = NULL;
|
||||
@ -351,7 +353,7 @@ int outstat()
|
||||
sprintf(temp, "%s %8lu %08x %08x %08x %08x %5d %s %s %s", flstr, (long)tmp->size,
|
||||
(unsigned int)tmp->olflags, (unsigned int)tmp->moflags,
|
||||
(unsigned int)tmp->diflags, (unsigned int)tmp->ipflags,
|
||||
tmp->cst.tryno, callstatus(tmp->cst.trystat), callmode(tmp->callmode), ascfnode(&(tmp->addr), 0x0f));
|
||||
tmp->cst.tryno, callstatus(tmp->cst.trystat), callmode(tmp->callmode), ascfnode(tmp->addr, 0x0f));
|
||||
tasklog('+', "%s", temp);
|
||||
}
|
||||
|
||||
@ -392,12 +394,11 @@ int each(faddr *addr, char flavor, int isflo, char *fname)
|
||||
nlent = getnlent(addr);
|
||||
*tmp = (struct _alist *)malloc(sizeof(struct _alist));
|
||||
(*tmp)->next = NULL;
|
||||
(*tmp)->addr.name = NULL;
|
||||
(*tmp)->addr.zone = addr->zone;
|
||||
(*tmp)->addr.net = addr->net;
|
||||
(*tmp)->addr.node = addr->node;
|
||||
(*tmp)->addr.point = addr->point;
|
||||
(*tmp)->addr.domain = xstrcpy(addr->domain);
|
||||
sprintf((*tmp)->addr.domain, "%s", addr->domain);
|
||||
if (nlent->addr.domain)
|
||||
free(nlent->addr.domain);
|
||||
(*tmp)->flavors = 0;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#ifndef _OUTSTAT_H
|
||||
#define _OUTSTAT_H
|
||||
|
||||
typedef enum {CM_NONE, CM_INET, CM_ISDN, CM_POTS} CMODE;
|
||||
typedef enum {CM_NONE, CM_INET, CM_ISDN, CM_POTS, MBFIDO, MBINDEX, MBFILE, MBINIT} CMODE;
|
||||
|
||||
|
||||
/*
|
||||
@ -13,7 +13,7 @@ typedef enum {CM_NONE, CM_INET, CM_ISDN, CM_POTS} CMODE;
|
||||
typedef struct _alist
|
||||
{
|
||||
struct _alist *next; /* Next entry */
|
||||
faddr addr; /* Node address */
|
||||
fidoaddr addr; /* Node address */
|
||||
int flavors; /* ORed flavors of mail/files */
|
||||
time_t time; /* Date/time of mail/files */
|
||||
off_t size; /* Total size of mail/files */
|
||||
@ -45,6 +45,7 @@ struct _ttyinfo ttyinfo;
|
||||
|
||||
|
||||
int each(faddr *, char, int, char *);
|
||||
char *callstatus(int);
|
||||
char *callmode(int);
|
||||
int outstat(void);
|
||||
void load_ports(void);
|
||||
|
@ -1,8 +1,7 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbtask/taskcomm.c
|
||||
* $Id$
|
||||
* Purpose ...............: MBSE BBS Daemon
|
||||
* Last modification date : 01-Nov-2001
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2001
|
||||
@ -30,6 +29,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "libs.h"
|
||||
#include "../lib/structs.h"
|
||||
#include "taskstat.h"
|
||||
#include "taskregs.h"
|
||||
#include "taskdisk.h"
|
||||
|
@ -1,8 +1,7 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbtask/statdisk.c
|
||||
* $Id$
|
||||
* Purpose ...............: Give status of all filesystems
|
||||
* Last modification date : 29-Oct-2001
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2001
|
||||
@ -30,6 +29,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "libs.h"
|
||||
#include "../lib/structs.h"
|
||||
#include "taskdisk.h"
|
||||
#include "taskutil.h"
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbtask/taskregs.c
|
||||
* $Id$
|
||||
* Purpose ...............: Buffers for registration information.
|
||||
* Last modification date : 07-Jun-2001
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2001
|
||||
@ -30,6 +29,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "libs.h"
|
||||
#include "../lib/structs.h"
|
||||
#include "taskstat.h"
|
||||
#include "taskregs.h"
|
||||
#include "taskutil.h"
|
||||
|
@ -327,28 +327,21 @@ time_t file_time(char *path)
|
||||
* Return ASCII string for node, the bits in 'fl' set the
|
||||
* output format.
|
||||
*/
|
||||
char *ascfnode(faddr *a, int fl)
|
||||
char *ascfnode(fidoaddr a, int fl)
|
||||
{
|
||||
static char buf[128];
|
||||
|
||||
if (a == NULL) {
|
||||
strcpy(buf, "<none>");
|
||||
return buf;
|
||||
}
|
||||
|
||||
buf[0] = '\0';
|
||||
if ((fl & 0x40) && (a->name))
|
||||
sprintf(buf+strlen(buf),"%s of ",a->name);
|
||||
if ((fl & 0x08) && (a->zone))
|
||||
sprintf(buf+strlen(buf),"%u:",a->zone);
|
||||
if ((fl & 0x08) && (a.zone))
|
||||
sprintf(buf+strlen(buf),"%u:",a.zone);
|
||||
if (fl & 0x04)
|
||||
sprintf(buf+strlen(buf),"%u/",a->net);
|
||||
sprintf(buf+strlen(buf),"%u/",a.net);
|
||||
if (fl & 0x02)
|
||||
sprintf(buf+strlen(buf),"%u",a->node);
|
||||
if ((fl & 0x01) && (a->point))
|
||||
sprintf(buf+strlen(buf),".%u",a->point);
|
||||
if ((fl & 0x10) && (a->domain))
|
||||
sprintf(buf+strlen(buf),"@%s",a->domain);
|
||||
sprintf(buf+strlen(buf),"%u",a.node);
|
||||
if ((fl & 0x01) && (a.point))
|
||||
sprintf(buf+strlen(buf),".%u",a.point);
|
||||
if ((fl & 0x10) && (strlen(a.domain)))
|
||||
sprintf(buf+strlen(buf),"@%s",a.domain);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _TASKUTIL_H
|
||||
#define _TASKUTIL_H
|
||||
|
||||
@ -31,7 +33,7 @@ int file_exist(char *, int);
|
||||
int mkdirs(char *);
|
||||
long file_size(char *);
|
||||
time_t file_time(char *);
|
||||
char *ascfnode(faddr *, int);
|
||||
char *ascfnode(fidoaddr, int);
|
||||
char *Dos2Unix(char *);
|
||||
char *dayname(void);
|
||||
void InitFidonet(void);
|
||||
|
Reference in New Issue
Block a user