P8000/WEGA/contrib/K5JB/main.c

1122 lines
26 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Main metwork program - provides both client and server functions
* See readme.src for modification notes - K5JB
* #define CPUSTAT to measure loop performance - adds 768 bytes
*/
#define HOSTNAMELEN 64
#include <stdio.h>
#include <string.h>
#include "options.h"
#include "config.h"
#include "sokname.h"
#include "global.h"
#include "mbuf.h"
#include "netuser.h"
#include "timer.h"
#include "icmp.h"
#include "iface.h"
#include "ip.h"
#include "tcp.h"
#ifdef AX25
#include "ax25.h"
#include "lapb.h"
#endif
#ifdef NETROM
#include "netrom.h"
#include "nr4.h"
#endif
#include "ftp.h"
#include "telnet.h"
#include "remote.h"
#ifdef _FINGER
#include "finger.h"
#endif
#include "session.h"
#include "cmdparse.h"
#if defined(MSDOS) || defined(ASY)
#include "asy.h"
#endif
#ifdef ASY
#include "slip.h"
#endif
#ifdef NRS
#include "nrs.h"
#endif
#ifdef UNIX /* BSD or SYS5 */
#include "unix.h"
#include "unixopt.h"
#endif
#ifdef TRACE
#include "trace.h"
/* Dummy structure for loopback tracing */
extern struct interface loopback;
extern char howtotrace[];
#endif
#if defined(MSDOS) && defined(CUTE_VIDEO)
unsigned int saved_attrib;
unsigned int ourcute = OUR_CUTE; /* we select default from options.h */
int doattrib();
unsigned int get_attr();
void putca(),putsa();
#endif
#ifdef AX25
extern int16 paclen;
#endif
extern struct interface *ifaces;
extern void version(),fileinit();
extern struct mbuf *loopq;
extern FILE *trfp;
extern char trname[];
int mode,atoi(),exitval; /* used by doexit() */
extern char *homedir,*mailspool,*startup;
char badhost[] = "Unknown host %s\n";
char hostname[HOSTNAMELEN];
unsigned nsessions = NSESSIONS;
int32 resolve();
char *strncpy(),*make_path();
int16 lport = 1024;
char prompt[] = "NET> ";
char nospace[] = "No space!!\n"; /* Generic malloc fail message */
#ifdef SYS5
#include <signal.h>
#ifdef USE_QUIT
int backgrd = 0; /* backgrd is controlled by SIGQUIT */
#endif
#ifdef FORKSHELL
extern int shellpid;
#endif
int background = 0; /* background is detected on startup */
int io_active = 0;
#endif
/* PC uses F-10 key always */
#if !defined(MSDOS)
char escape = 0x1d; /* default escape character is ^] */
#endif
/* Enter command mode */
int
cmdmode()
{
void cooked();
extern void echo();
#if defined(SYS5) && defined(FORKSHELL)
if(shellpid)
return 0;
#endif
if(mode != CMD_MODE){
mode = CMD_MODE;
cooked();
#ifdef CUTE_FTP
echo(); /* one in a million chance... */
#endif
}
printf(prompt); /* note change to always print a prompt */
fflush(stdout);
return 0;
}
int /* removed static to make this the only sane exit from program */
doexit() /* left declaration as int to match cmd list */
{
void iostop(),exit();
#ifdef TRACE
if (trfp != stdout)
fclose(trfp);
#endif
#ifdef SYS5
if (!background)
iostop(); /* this function will exit() */
#else /* it is also a signal handler */
iostop();
#endif
exit(exitval); /* only rational exit in NET */
}
static
dohostname(argc,argv)
int argc;
char *argv[];
{
if(argc < 2)
printf("%s\n",hostname);
else
strncpy(hostname,argv[1],HOSTNAMELEN);
return 0;
}
static
int
dohelp()
{
extern struct cmds cmds[];
register struct cmds *cmdp;
int i;
printf("Main commands:"); /* first command is "" and will do \n */
for(i=0,cmdp = cmds;cmdp->name != NULLCHAR;cmdp++,i++){
printf("%-15s",cmdp->name);
if(!(i % 5))
printf("\n");
}
printf("\n");
return 0;
}
int subcmd();
/* Attach an interface
* Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize>
<speed>
*/
doattach(argc,argv)
int argc;
char *argv[];
{
extern struct cmds attab[];
return subcmd(attab,argc,argv);
}
#ifdef MSDOS
unsigned heapsize; /* used only on pc with grabcore (see pc.c) */
#endif
#ifdef CPUSTAT
/* cpu performance statistics - This was added to instrument code that
* is either on a busy or slow machine, or using a processor intensive
* driver like the DRSI thing. It will show if the program is running
* fast enough to service interface chains effectively.
* syntax: cpu [time], where time, in seconds, would change from the
* default of 600 second intervals for cycle accumulation.
* This will not be documented in the user documentation. Joe, K5JB
*/
time_t cycles[7]; /* cycle accumulators, ten minutes each */
time_t next_update;
int last_cycle;
time_t update_interval = 600L;
void
cycle(first)
int first;
{
int i;
time_t curr_time;
/* first count will be short on account of time() granularity */
if(first){
for(i=0;i<7;i++)
cycles[i] = 0L;
time(&next_update);
next_update += update_interval;
return;
}
/* every 16th time through, check time */
if((cycles[0]++ & 0x0F) == 0x0F){
time(&curr_time);
if(curr_time < next_update)
return;
} else
return;
/* Do it this way, rather than absolute time, to detect dormant periods */
next_update += update_interval;
for(i=6;i>0;i--)
cycles[i] = cycles[i-1] == 16 ? 0 : cycles[i-1]; /* "16" when dormant */
cycles[0] = 0L;
}
int
report_cycles(argc,argv)
int argc;
char **argv;
{
time_t now;
int i;
extern time_t next_update, update_interval;
extern time_t cycles[];
#ifdef COMBIOS /* this is temporary */
extern long combios_stat[];
#endif
if(argc == 2 && (i = atoi(argv[1])) != 0){
update_interval = (time_t)i;
cycle(1);
#ifdef COMBIOS /* this is temporary */
combios_stat[0] = combios_stat[1] = 0;
#endif
printf("Update interval changed to %ld sec.\n",update_interval);
return 0;
}
now = update_interval/60L; /* use this temporarily */
printf("Cycles per %ld %s. through main loop, least to most recent:\n",
now > 0 ? now : update_interval, now > 0 ? "min" : "sec");
for(i=6;i>=1;i--) /* don't report current accumulater */
printf("%8ld\n",cycles[i]);
time(&now);
if(next_update > now) /* prevent showing when late */
printf("%d seconds before next update\n",(int)(next_update - now));
#ifdef COMBIOS /* more temporary */
printf("Combios 1 = %lu, Combios 2 - %lu\n",combios_stat[0],combios_stat[1]);
#endif
return 0; /* to be consistent with other commands */
}
#endif /* CPUSTAT */
#define PARAM_MTU
/* Manipulate I/O device parameters */
doparam(argc,argv)
int argc;
char *argv[];
{
register struct interface *ifp;
for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
if(strcmp(argv[1],ifp->name) == 0)
break;
}
if(ifp == NULLIF){
printf("Interface \"%s\" unknown\n",argv[1]);
return 1;
}
#if defined(AX25) && defined(PARAM_MTU)
/* note that there is no error msg if you use a letter other than "m" */
/* and ioctl will get some astonishing, but benign, numbers k33 */
if(argv[2][0] == 'm'){ /* "mtu" (or "mut", heh!) */
if(argc == 4){
ifp->mtu = (int16)atoi(argv[3]);
if(!ifp->mtu) /* bad argument, we'll do it for him */
ifp->mtu = paclen;
}
printf("%s mtu is %d\n",argv[1],ifp->mtu);
return 0;
}
#endif
if(ifp->ioctl == NULLFP){ /* e.g. netrom interface */
printf("No ioctl\n");
return 1;
}
/* Pass rest of args to device-specific code */
return (*ifp->ioctl)(ifp,argc-2,argv+2);
}
/* Command lookup and branch table */
int go(),doax25(),doconnect(),dotelnet(),doclose(),doreset(),dotcp(),
dotrace(),doescape(),doroute(),doip(),doarp(),dosession(),doftp(),
dostart(),dostop(),dosmtp(),doudp(),dodump(),dorecord(),doupload(),
dokick(),domode(),doshell(),dodir(),dohelp1(),dolog(),domail(),
#ifdef AXMBX
dombox(),
#endif
#ifdef FORWARD
doforward(),
#endif
#ifdef MULPORT
mulport(),
#endif
#if defined(REWRITE) && defined(REWRITECMD)
dorewrite(),
#endif
docd(),doatstat(),doping(),doremote();
#ifdef NETROM
int donetrom();
#ifdef NRS
int donrstat();
#endif
#endif
#ifndef UNIX
int memstat();
#endif
#ifdef ETHER
int doetherstat();
#endif
#ifdef DRSI
int dodrstat();
#endif
#ifdef _FINGER
int dofinger();
#endif
#ifdef _TELNET
int doecho();
int doeol();
#endif
#ifdef SOKNAME
int issok = 1;
/* reverse state of socket switch, this command is an exception in always
* being verbose.
*/
int
flipsok() /* int to be consistent with rest of commands */
{
issok = !issok;
printf("Socket names are %s\n",issok ? "on" : "off");
return(0);
}
#endif
#if defined(TN_MOTD) || defined(AX_MOTD)
int motd();
#endif
#ifdef AX25
extern char badcall[];
#endif
struct cmds cmds[] = {
/* The "go" command must be first */
"", go, 0, NULLCHAR, NULLCHAR,
#ifdef SHELL
"!", doshell, 0, NULLCHAR, NULLCHAR,
#endif
#if (defined(AX25) || defined(ETHER)) /* K5JB */
"arp", doarp, 0, NULLCHAR, NULLCHAR,
#endif
#ifdef AX25
"ax25", doax25, 0, NULLCHAR, NULLCHAR,
#endif
#ifdef AX_MOTD
"axmotd", motd, 0, NULLCHAR, NULLCHAR,
#endif
"attach", doattach, 2,
"attach <hardware> <hw specific options>", NULLCHAR,
/* This one is out of alpabetical order to allow abbreviation to "c" */
#ifdef AX25
"connect", doconnect, 3,"connect <interface> <callsign> [digipeaters]",
badcall,
#endif
"cd", docd, 0, NULLCHAR, NULLCHAR,
"close", doclose, 0, NULLCHAR, NULLCHAR,
#ifdef CPUSTAT
"cpustat", report_cycles, 0, NULLCHAR, NULLCHAR,
#endif
#ifdef AX25
"disconnect", doclose, 0, NULLCHAR, NULLCHAR,
#endif
"dir", dodir, 0, NULLCHAR, NULLCHAR,
#ifdef DRSI
"drsistat", dodrstat, 0, NULLCHAR, NULLCHAR,
#endif
#ifdef _TELNET
"echo", doecho, 0, NULLCHAR, "echo [refuse|accept]",
"eol", doeol, 0, NULLCHAR,
"eol options: unix, standard",
#endif
#if !defined(MSDOS)
"escape", doescape, 0, NULLCHAR, NULLCHAR,
#endif
#ifdef PC_EC
"etherstat", doetherstat, 0, NULLCHAR, NULLCHAR,
#endif /* PC_EC */
"exit", doexit, 2, "exit please", NULLCHAR,
#ifdef _FINGER
"finger", dofinger, 0, NULLCHAR, NULLCHAR,
#endif
#ifdef FORWARD
"forward", doforward, 0, NULLCHAR, NULLCHAR,
#endif
"ftp", doftp, 2, "ftp <address>", NULLCHAR,
"help", dohelp1, 0, NULLCHAR, NULLCHAR,
"hostname", dohostname, 0, NULLCHAR, NULLCHAR,
"ip", doip, 0, NULLCHAR, NULLCHAR,
"kick", dokick, 0, NULLCHAR, NULLCHAR,
"log", dolog, 0, NULLCHAR, NULLCHAR,
#ifndef UNIX
"memstat", memstat, 0, NULLCHAR, NULLCHAR,
#endif
"mailscan", domail, 0, NULLCHAR, "Usage: mailscan [<mailfile>] [<skip pages>]",
#ifdef AX25
#ifdef AXMBX
"mbox", dombox, 0, NULLCHAR, NULLCHAR,
#endif
"mode", domode, 2, "mode <interface>", NULLCHAR,
#ifdef TN_MOTD
"motd", motd, 0, NULLCHAR, NULLCHAR,
#endif
#ifdef MULPORT
"mulport", mulport, 2, "mulport <on|off>", NULLCHAR,
#endif
#ifdef NETROM
"netrom", donetrom, 0, NULLCHAR, NULLCHAR,
#ifdef NRS
"nrstat", donrstat, 0, NULLCHAR, NULLCHAR,
#endif
#endif /* NETROM */
#endif /* AX25 */
#ifdef PARAM_MTU
"param", doparam, 2, "param <interface> mtu | <kiss data>", NULLCHAR,
#else
"param", doparam, 2, "param <interface> mtu", NULLCHAR,
#endif
"ping", doping, 0, NULLCHAR, NULLCHAR,
#ifdef UNIX /* BSD or SYS5 */
"pwd", docd, 0, NULLCHAR, NULLCHAR,
#endif
"record", dorecord, 0, NULLCHAR, NULLCHAR,
"remote", doremote, 4, "remote <address> <port> <command>",
NULLCHAR,
"reset", doreset, 0, NULLCHAR, NULLCHAR,
"route", doroute, 0, NULLCHAR, NULLCHAR,
#if defined(REWRITE) && defined(REWRITECMD)
"rewrite", dorewrite, 2, "rewrite <to>", NULLCHAR,
#endif
"session", dosession, 0, NULLCHAR, NULLCHAR,
#ifdef SHELL
"shell", doshell, 0, NULLCHAR, NULLCHAR,
#endif
"smtp", dosmtp, 0, NULLCHAR, NULLCHAR,
#ifdef SOKNAME
"sokname", flipsok, 0, NULLCHAR, NULLCHAR,
#endif
#ifdef SERVERS
"start", dostart, 2, "start <servername>",NULLCHAR,
"stop", dostop, 2, "stop <servername>", NULLCHAR,
#endif
"tcp", dotcp, 0, NULLCHAR, NULLCHAR,
#ifdef _TELNET
"telnet", dotelnet, 2, "telnet <address>", NULLCHAR,
#endif
#ifdef TRACE
"trace", dotrace, 0, NULLCHAR, howtotrace,
#endif
"udp", doudp, 0, NULLCHAR, NULLCHAR,
#if defined(_TELNET) || defined(AX25)
"upload", doupload, 0, NULLCHAR, NULLCHAR,
#endif
#if defined(MSDOS) && defined(CUTE_VIDEO)
"vattrib", doattrib, 0, NULLCHAR, NULLCHAR,
#endif
"?", dohelp, 0, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0,
"Unknown command; type \"?\" for list", NULLCHAR
};
#ifdef SERVERS
/* "start" and "stop" subcommands */
int dis1(),echo1(),ftp1(),smtp1(),tn1(),rem1();
#if defined(UNIX) && defined(TELUNIX)
int tnix0(),tnix1();
#endif
#if defined(UNIX) && defined(TELSERV)
int tserv0(),tserv1();
#endif
#ifdef _FINGER
int finger1();
#endif
static struct cmds startcmds[] = {
"discard", dis1, 0, NULLCHAR, NULLCHAR,
"echo", echo1, 0, NULLCHAR, NULLCHAR,
#ifdef _FINGER
"finger", finger1, 0, NULLCHAR, NULLCHAR,
#endif
"ftp", ftp1, 0, NULLCHAR, NULLCHAR,
"smtp", smtp1, 0, NULLCHAR, NULLCHAR,
#ifdef _TELNET
"telnet", tn1, 0, NULLCHAR, NULLCHAR,
#endif
#if defined(UNIX) && defined(TELUNIX)
"telunix", tnix1, 0, NULLCHAR,
"Could not start telunix - no pty?",
#endif
#if defined(UNIX) && defined(TELSERV)
"telserv", tserv1, 0, NULLCHAR,
"Could not start telserv - no server?",
#endif
"remote", rem1, 0, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0,
STARTOPT, NULLCHAR /* macro defined in config.h */
};
int ftp_stop(),smtp_stop(),echo_stop(),dis_stop(),tn_stop();
int dis0(),echo0(),ftp0(),smtp0(),tn0(),rem0();
#ifdef _FINGER
int finger0();
#endif
static struct cmds stopcmds[] = {
"discard", dis0, 0, NULLCHAR, NULLCHAR,
"echo", echo0, 0, NULLCHAR, NULLCHAR,
#ifdef _FINGER
"finger", finger0, 0, NULLCHAR, NULLCHAR,
#endif
"ftp", ftp0, 0, NULLCHAR, NULLCHAR,
"smtp", smtp0, 0, NULLCHAR, NULLCHAR,
#ifdef _TELNET
"telnet", tn0, 0, NULLCHAR, NULLCHAR,
#endif
#if defined(UNIX) && defined(TELUNIX)
"telunix", tnix0, 0, NULLCHAR,
"Stop telunix failed, no server running",
#endif
#if defined(UNIX) && defined(TELSERV)
"telserv", tserv0, 0, NULLCHAR,
"Stop telserv failed, no server running",
#endif
"remote", rem0, 0, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0,
STOPOPT, NULLCHAR /* macro in config.h */
};
#endif /* SERVERS */
/* Standard commands called from main */
/* Configuration-dependent code */
/* List of supported hardware devices */
int asy_attach(),pc_attach();
#ifdef NETROM
int nr_attach();
#endif
#ifdef MSDOS
#ifdef DRSI
int dr_attach();
#endif
#ifdef PC_EC
int ec_attach();
#endif
#ifdef COMBIOS
int combios_attach();
#endif
#endif /* MSDOS */
#ifdef MDKISSPORT
int mdasy_attach();
#endif
#ifdef PACKET
int pk_attach();
#endif
struct cmds attab[] = {
#if defined(PC_EC) && defined(MSDOS)
/* 3-Com Ethernet interface */
"3c500", ec_attach, 7,
"attach 3c500 <address> <vector> arpa <label> <buffers> <mtu>",
"Could not attach 3c500",
#endif
#ifdef ASY
/* Ordinary (or extended) PC asynchronous adaptor */
"asy", asy_attach, 8,
ATTACHOPT, /* defined in options.h */
"Could not attach asy",
#endif /* ASY */
#if defined(DRSI) && defined(MSDOS)
"drsi", dr_attach, 8,
"attach drsi <address> <vector> ax25 dr0|dr1 <buffers> <mtu> <speed>",
"Could not attach DRSI",
#endif
#if defined(COMBIOS) && defined(MSDOS)
"combios", combios_attach, 7,
"attach combios <com#> ax25 <label> <buffers> <mtu> <speed>",
"Couldn't attach combios",
#endif
#ifdef NETROM
/* fake netrom interface */
"netrom", nr_attach, 1,
"attach netrom",
"Could not attach netrom",
#endif
#ifdef PACKET
/* FTP Software's packet driver spec */
"packet", pk_attach, 4,
#ifdef PACKET_POLL
"attach packet <int#> <label> <buffers> <mtu> [-p]",
#else
"attach packet <int#> <label> <buffers> <mtu>",
#endif
"Could not attach packet driver",
#endif
NULLCHAR, NULLFP, 0, "Unknown device", NULLCHAR
};
#ifdef ASY
/* Attach a serial interface to the system
* argv[0]: hardware type, must be "asy"
* argv[1]: I/O address, e.g., "0x3f8"
* argv[2]: vector, e.g., "4"
* argv[3]: mode, may be:
* "slip" (point-to-point SLIP)
* "ax25" (AX.25 frame format in SLIP for raw TNC)
* "nrs" (NET/ROM format serial protocol)
* argv[4]: interface label, e.g., "sl0"
* argv[5]: receiver ring buffer size in bytes
* argv[6]: maximum transmission unit, bytes
* argv[7]: interface speed, e.g, "9600"
* argv[8]: optional ax.25 callsign (NRS only)
*/
int
asy_attach(argc,argv)
int argc;
char *argv[];
{
register struct interface *if_asy;
extern struct interface *ifaces;
int16 dev;
int mode,asy_init(),asy_send(),asy_ioctl(),asy_stop(),ax_send(),ax_output();
int kiss_raw(),kiss_ioctl(),slip_send(),slip_raw(),atoi();
void kiss_recv(),doslip(),slip_recv(),asy_speed(),free();
#ifdef AX25
extern int16 tcp_mss;
#ifdef NRS
struct ax25_addr addr ;
#endif
void axarp();
#endif
int ax_send(),ax_output(),nrs_raw(),asy_ioctl();
void nrs_recv();
if(nasy >= ASY_MAX){
printf("Too many asynch controllers\n");
return -1;
}
if(strcmp(argv[3],"slip") == 0)
mode = SLIP_MODE;
#ifdef AX25
else if(strcmp(argv[3],"ax25") == 0)
#ifdef MDKISSPORT
return mdasy_attach(argc,argv); /* See mdkiss.c - we're done */
#else
mode = AX25_MODE;
#endif
#endif
#ifdef NRS
else if(strcmp(argv[3],"nrs") == 0)
mode = NRS_MODE;
#endif
else{
printf("Mode %s unknown for interface %s\n",argv[3],argv[4]);
return(-1);
}
dev = nasy++;
/* Create interface structure and fill in details */
if_asy = (struct interface *)calloc(1,sizeof(struct interface));
if_asy->name = malloc((unsigned)strlen(argv[4])+1);
strcpy(if_asy->name,argv[4]);
if_asy->mtu = (int16)atoi(argv[6]);
#if defined(AX25) && !defined(SEGMENT)
/* If we aren't going to do segmentation, enforce mtu size - K5JB k33 */
if(mode == AX25_MODE && if_asy->mtu > paclen)
if_asy->mtu = paclen;
#endif
if_asy->dev = dev;
if_asy->recv = doslip;
if_asy->stop = asy_stop;
switch(mode){
#ifdef SLIP
case SLIP_MODE:
if_asy->ioctl = asy_ioctl;
if_asy->send = slip_send;
if_asy->output = NULLFP; /* ARP isn't used */
if_asy->raw = slip_raw;
if_asy->flags = 0;
slip[dev].recv = slip_recv;
break;
#endif
#if defined(AX25) && !defined(MDKISSPORT)
case AX25_MODE: /* Set up a SLIP link to use AX.25 */
axarp();
if(mycall.call[0] == '\0'){
printf("set mycall first\n");
free(if_asy->name);
free((char *)if_asy);
nasy--;
return -1;
}
if_asy->ioctl = kiss_ioctl;
if_asy->send = ax_send;
if_asy->output = ax_output;
if_asy->raw = kiss_raw;
if(if_asy->hwaddr == NULLCHAR)
if_asy->hwaddr = malloc(sizeof(mycall));
memcpy(if_asy->hwaddr,(char *)&mycall,sizeof(mycall));
slip[dev].recv = kiss_recv;
if(tcp_mss == DEF_MSS) /* here we change a default - K5JB k34 */
tcp_mss = 216;
break;
#endif /* AX25 && MDKISSPORT */
#ifdef NRS
case NRS_MODE: /* Set up a net/rom serial interface */
if(argc < 9){
/* no call supplied? */
if(mycall.call[0] == '\0'){
/* try to use default */
printf("set mycall first or specify in attach statement\n");
return -1;
} else
addr = mycall;
} else {
/* callsign supplied on attach line */
if(setcall(&addr,argv[8]) == -1){
printf ("bad callsign on attach line\n");
free(if_asy->name);
free((char *)if_asy);
nasy--;
return -1;
}
}
if_asy->recv = nrs_recv;
if_asy->ioctl = asy_ioctl;
if_asy->send = ax_send;
if_asy->output = ax_output;
if_asy->raw = nrs_raw;
if(if_asy->hwaddr == NULLCHAR)
if_asy->hwaddr = malloc(sizeof(addr));
memcpy(if_asy->hwaddr,(char *)&addr,sizeof(addr));
nrs[dev].iface = if_asy;
if_asy->mtu -= 20; /* k33 */
if(if_asy->mtu > 236 || if_asy->mtu < 44)
if_asy->mtu = 236; /* Stomp! */
break;
#endif /* NRS */
} /* switch */
if_asy->next = ifaces;
ifaces = if_asy;
asy_init(dev,argv[1],argv[2],(unsigned)atoi(argv[5]));
asy_speed(dev,atoi(argv[7]));
return 0;
}
#endif /* ASY */
#ifdef NOTUSED
#ifndef NETROM
#ifdef AX25
struct ax25_addr nr_nodebc;
#endif
nr_route(bp)
struct mbuf *bp;
{
free_p(bp);
}
nr_nodercv(bp)
{
free_p(bp);
}
#endif /* NETROM */
#endif /* NOTUSED */
/* Display or set IP interface control flags */
domode(argc,argv)
int argc;
char *argv[];
{
register struct interface *ifp;
for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
if(strcmp(argv[1],ifp->name) == 0)
break;
}
if(ifp == NULLIF){
printf("Interface \"%s\" unknown\n",argv[1]);
return 1;
}
if(argc < 3){
printf("%s: %s\n",ifp->name,
(ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
return 0;
}
switch(argv[2][0]){
case 'v':
case 'c':
case 'V':
case 'C':
ifp->flags = CONNECT_MODE;
break;
case 'd':
case 'D':
ifp->flags = DATAGRAM_MODE;
break;
default:
printf("Usage: %s [vc | datagram]\n",argv[0]);
return 1;
}
return 0;
}
#ifdef SERVERS
dostart(argc,argv)
int argc;
char *argv[];
{
return subcmd(startcmds,argc,argv);
}
dostop(argc,argv)
int argc;
char *argv[];
{
return subcmd(stopcmds,argc,argv);
}
#endif /* SERVERS */
#ifndef MSDOS
static
int
doescape(argc,argv)
int argc;
char *argv[];
{
if(argc < 2)
printf("0x%x\n",escape);
else
escape = *argv[1];
return 0;
}
#endif /* MSDOS */
static
doremote(argc,argv)
int argc;
char *argv[];
{
struct socket fsock,lsock;
struct mbuf *bp;
void send_udp();
lsock.address = ip_addr;
fsock.address = resolve(argv[1]);
lsock.port = fsock.port = (int16)atoi(argv[2]);
bp = alloc_mbuf(1);
if(strcmp(argv[3],"reset") == 0)
*bp->data = SYS_RESET; /* only if enabled in pc.c */
/* in Unix, this will exit(2) */
#ifdef NOTUSED /* crap, cost 88 bytes to do this */
else if(strcmp(argv[3],"restart") == 0)
*bp->data = SYS_RESTART; /* will exit(1) */
#endif
else if(strcmp(argv[3],"exit") == 0)
*bp->data = SYS_EXIT; /* will exit(1) which will distinguish */
else { /* from a normal exit */
printf("Unknown command %s\n",argv[3]);
return 1;
}
bp->cnt = 1;
send_udp(&lsock,&fsock,0,0,bp,0,0,0);
return 0;
}
void
keep_things_going()
{
void check_time(), ip_recv(),ntohip();
struct interface *ifp;
struct mbuf *bp;
#if defined(MSDOS)
void giveup();
#endif
#if defined(UNIX) && defined(TELUNIX)
void tnix_scan();
#endif
#if defined(UNIX) && defined(TELSERV)
void tserv_scan();
#endif
#ifdef TRACE
void dump();
#endif
/* Service the loopback queue */
if((bp = dequeue(&loopq)) != NULLBUF){
struct ip ip;
#ifdef TRACE
dump(&loopback,IF_TRACE_IN,TRACE_IP,bp);
#endif
/* Extract IP header */
ntohip(&ip,&bp);
ip_recv(&ip,bp,0);
}
/* Service the interfaces */
#ifdef SYS5
do {
io_active = 0;
#endif
for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next){
if(ifp->recv != NULLVFP)
(*ifp->recv)(ifp);
}
#ifdef SYS5
} while(io_active);
#endif
/* Service the clock if it has ticked */
check_time();
#if defined(MSDOS)
/* Tell DoubleDos or Desqview to let the other task run for awhile.
* If if neither are active, this is a no-op
*/
giveup();
#endif /* MSDOS */
#if defined(UNIX) && defined(TELUNIX)
tnix_scan(); /* this is what eihalt() calls */
#endif
#if defined(UNIX) && defined(TELSERV)
tserv_scan(); /* check on the telnet server(s) */
#endif
}
main(argc,argv)
int argc;
char *argv[];
{
char *indent = " ";
static char inbuf[BUFSIZ]; /* keep it off the stack */
char *fgets();
int cmdparse();
void check_time(),ip_recv(),ioinit(),check_kbd();
FILE *fp;
#ifdef UNIX
char *getenv();
#endif
#ifdef MSDOS
void chktasker();
#endif
#ifdef CPUSTAT
void cycle();
#endif
#ifndef NOCOOKIE
extern char CMARK[];
char *vp = CMARK;
static char *cookie = "!_ (DY]";
while(*cookie){
if(!*vp)
exit(1);
*vp++ = *cookie++ ^ 'j';
}
if(*vp)
*vp = '\0';
#endif
#ifdef CUTE_VIDEO
#ifdef UNIX /* Unix or others with curses */
/* BKW -- W5GFE - this to let reverse video option work */
setupterm((char *) 0,1,(int *) 0);
#else
saved_attrib = get_attr(); /* MSDOS */
#endif
#endif
#ifdef SYS5
if (signal(SIGINT, SIG_IGN) == SIG_IGN) {
background++;
/* daemon(); interferes with nohup.out K5JB */
} else
ioinit();
#else
ioinit();
#endif
#if defined(MSDOS)
chktasker();
#endif
#ifdef SYS5
if (!background) {
#endif
printf("%s%sInternet Protocol Package, (C) 1988 by Phil Karn, KA9Q\n",
indent,indent);
#ifdef NETROM
printf("%s%s%sNET/ROM Support (C) 1989 by Dan Frank, W9NK\n\n",
indent,indent,indent) ;
#endif
#ifndef AX25
printf("%s%s%sNote: This version lacks AX.25 functions!\n\n",
indent,indent,indent);
#endif
#if defined(MSDOS) && defined(CUTE_VIDEO)
printf("%s%s%s%s",indent,indent,indent,indent);
fflush(stdout);
putsa(" This puppy was housebroken by \n",ourcute);
printf("%s%s ",indent,indent);
fflush(stdout);
putsa(" Joe Buswell, K5JB, 44.78.0.2, Midwest City OK \n\n",ourcute);
#else
printf("%s%s%s%s This puppy was housebroken by\n",
indent,indent,indent,indent);
printf("%s%s%sJoe Buswell, K5JB, 44.78.0.2, Midwest City OK\n\n",
indent,indent,indent);
#endif
#ifdef MSDOS
printf("%s%s%sDESQview or Windows users: Heap = %u\n",indent,indent,
indent,heapsize);
#endif /* MSDOS */
#ifdef _OSK
printf("%sOS9-68k Port, Robert E. Brose II, N0QBJ, 44.94.249.29, St. Paul, MN\n\n",
indent);
#endif
version(); /* do formatting in version.c */
/* version will include options like Unix, DRSI, MULPORT, etc. */
#ifdef SYS5
}
#endif
fflush(stdout);
sessions = (struct session *)calloc(nsessions,sizeof(struct session));
fileinit(argv[1]); /* added to permit environmental control K5JB */
/* if SKIP_FSCHECK not defined we could skip this */
fp = fopen(startup,"r"); /* and permit alternative startup files */
if(fp != NULLFILE){
while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
#ifdef MSDOS
if(inbuf[0] == 0x1a) /* Ctrl-Z - prevent error message */
break;
#endif
cmdparse(cmds,inbuf);
}
fclose(fp);
}
cmdmode(1);
#ifdef CPUSTAT
cycle(1); /* initialize cycle counter */
#endif
/* Main commutator loop */
for(;;){
#ifdef CPUSTAT
cycle(0);
#endif
check_kbd();
keep_things_going();
}
}