/* Main-level NOS program: * initialization * keyboard processing * generic user commands * * Copyright 1991 Phil Karn, KA9Q */ #include #include #if defined(__TURBOC__) && defined(MSDOS) #include #include #endif #include "global.h" #ifdef ANSIPROTO #include #endif #include "mbuf.h" #include "timer.h" #include "proc.h" #include "iface.h" #include "ip.h" #include "tcp.h" #include "udp.h" #include "ax25.h" #include "kiss.h" #include "enet.h" #include "netrom.h" #include "ftpcli.h" #include "telnet.h" #include "tty.h" #include "session.h" #include "hardware.h" #include "usock.h" #include "socket.h" #include "cmdparse.h" #include "commands.h" #include "daemon.h" #include "devparam.h" #include "domain.h" #include "files.h" #include "main.h" #include "remote.h" #include "trace.h" extern struct cmds Cmds[],Startcmds[],Stopcmds[],Attab[]; #ifndef MSDOS /* PC uses F-10 key always */ static char Escape = 0x1d; /* default escape character is ^] */ #endif char Badhost[] = "Unknown host %s\n"; char *Hostname; char Nospace[] = "No space!!\n"; /* Generic malloc fail message */ struct proc *Cmdpp; struct proc *Display; int main_exit = FALSE; /* from main program (flag) */ static char Prompt[] = "net> "; static FILE *Logfp; static time_t StartTime; /* time that NOS was started */ static int Verbose; int main(argc,argv) int argc; char *argv[]; { char *inbuf,*intmp; FILE *fp; struct daemon *tp; struct mbuf *bp; int c; StartTime = time(&StartTime); while((c = getopt(argc,argv,"s:d:bv")) != EOF){ switch(c){ case 's': /* Number of sockets */ Nusock = atoi(optarg); break; case 'd': /* Root directory for various files */ initroot(optarg); break; #ifdef __TURBOC__ case 'b': /* Use BIOS for screen output */ directvideo = 0; break; #endif case 'v': Verbose = 1; break; } } kinit(); ipinit(); ioinit(); sockinit(); Cmdpp = mainproc("cmdintrp"); Sessions = (struct session *)callocw(Nsessions,sizeof(struct session)); Command = Lastcurr = newsession("command interpreter",COMMAND,1); Display = newproc("display",250,display,0,NULLCHAR,NULL,0); tprintf("KA9Q NOS version %s\n",Version); tprintf("Copyright 1992 by Phil Karn, KA9Q\n"); rflush(); /* Start background Daemons */ for(tp=Daemons;;tp++){ if(tp->name == NULLCHAR) break; newproc(tp->name,tp->stksize,tp->fp,0,NULLCHAR,NULL,0); } Encap.txproc = newproc("encap tx",512,if_tx,0,&Encap,NULL,0); if(optind < argc){ /* Read startup file named on command line */ if((fp = fopen(argv[optind],READ_TEXT)) == NULLFILE) tprintf("Can't read config file %s: %s\n", argv[optind],sys_errlist[errno]); } else { fp = fopen(Startup,READ_TEXT); } if(fp != NULLFILE){ inbuf = mallocw(BUFSIZ); intmp = mallocw(BUFSIZ); while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){ strcpy(intmp,inbuf); if(Verbose) tprintf("%s",intmp); if(cmdparse(Cmds,inbuf,NULL) != 0){ tprintf("input line: %s",intmp); } } fclose(fp); free(inbuf); free(intmp); } /* Now loop forever, processing commands */ for(;;){ tprintf(Prompt); usflush(Command->output); if(recv_mbuf(Command->input,&bp,0,NULLCHAR,0) != -1){ (void)cmdparse(Cmds,bp->data,Lastcurr); free_p(bp); } } } /* Keyboard input process */ void keyboard(i,v1,v2) int i; void *v1; void *v2; { int c; struct mbuf *bp; /* Keyboard process loop */ for(;;){ c = kbread(); #ifndef MSDOS if(c == Escape && Escape != 0) c = -2; #endif if(c == -2 && Current != Command){ /* Save current tty mode and set cooked */ swapscreen(Current,Command); Lastcurr = Current; Current = Command; } Current->row = MOREROWS; psignal(&Current->row,1); if(c >= 0){ /* If the screen driver was in morewait state, this char * has woken him up. Toss it so it doesn't also get taken * as normal input. If the char was a command escape, * however, it will be accepted; this gives the user * a way out of lengthy output. */ if(!Current->morewait && (bp = ttydriv(Current,(char)c)) != NULLBUF){ send_mbuf(Current->input,bp,0,NULLCHAR,0); } } } } /* Standard commands called from main */ int dodelete(argc,argv,p) int argc; char *argv[]; void *p; { int i; for(i=1;i < argc; i++){ if(unlink(argv[i]) == -1){ tprintf("Can't delete %s: %s\n", argv[i],sys_errlist[errno]); } } return 0; } int dorename(argc,argv,p) int argc; char *argv[]; void *p; { if(rename(argv[1],argv[2]) == -1) tprintf("Can't rename: %s\n",sys_errlist[errno]); return 0; } int doexit(argc,argv,p) int argc; char *argv[]; void *p; { int i; time_t StopTime; StopTime = time(&StopTime); main_exit = TRUE; /* let everyone know we're out of here */ reset_all(); if(Dfile_updater != NULLPROC) alert(Dfile_updater,0); /* don't wait for timeout */ for(i=0;i<100;i++) pwait(NULL); /* Allow tasks to complete */ shuttrace(); log(-1,"NOS was stopped at %s", ctime(&StopTime)); if(Logfp){ fclose(Logfp); Logfp = NULLFILE; } iostop(); exit(0); return 0; /* To satisfy lint */ } int dohostname(argc,argv,p) int argc; char *argv[]; void *p; { if(argc < 2) tprintf("%s\n",Hostname); else { struct iface *ifp; char *name; if((ifp = if_lookup(argv[1])) != NULLIF){ if((name = resolve_a(ifp->addr, FALSE)) == NULLCHAR){ tprintf("Interface address not resolved\n"); return 1; } else { if(Hostname != NULLCHAR) free(Hostname); Hostname = name; /* remove trailing dot */ if ( Hostname[strlen(Hostname)] == '.' ) { Hostname[strlen(Hostname)] = '\0'; } tprintf("Hostname set to %s\n", name ); } } else { if(Hostname != NULLCHAR) free(Hostname); Hostname = strdup(argv[1]); } } return 0; } int dolog(argc,argv,p) int argc; char *argv[]; void *p; { static char *logname; if(argc < 2){ if(Logfp) tprintf("Logging to %s\n",logname); else tprintf("Logging off\n"); return 0; } if(Logfp){ log(-1,"NOS log closed"); fclose(Logfp); Logfp = NULLFILE; free(logname); logname = NULLCHAR; } if(strcmp(argv[1],"stop") != 0){ logname = strdup(argv[1]); Logfp = fopen(logname,APPEND_TEXT); log(-1,"NOS was started at %s", ctime(&StartTime)); #ifdef MSDOS log(-1,"NOS load information: CS=0x%04x DS=0x%04x", _CS, _DS); #endif } return 0; } int dohelp(argc,argv,p) int argc; char *argv[]; void *p; { register struct cmds *cmdp; int i; char buf[66]; tprintf("Main commands:\n"); memset(buf,' ',sizeof(buf)); buf[64] = '\n'; buf[65] = '\0'; for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i = (i+1)%4){ strncpy(&buf[i*16],cmdp->name,strlen(cmdp->name)); if(i == 3){ tprintf(buf); memset(buf,' ',sizeof(buf)); buf[64] = '\n'; buf[65] = '\0'; } } if(i != 0) tprintf(buf); return 0; } /* Attach an interface * Syntax: attach