home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / s920603.zip / MAIN.C < prev    next >
C/C++ Source or Header  |  1992-05-31  |  12KB  |  621 lines

  1. /* Main-level NOS program:
  2.  *  initialization
  3.  *  keyboard processing
  4.  *  generic user commands
  5.  *
  6.  * Copyright 1991 Phil Karn, KA9Q
  7.  */
  8. #include <stdio.h>
  9. #include <time.h>
  10. #if    defined(__TURBOC__) && defined(MSDOS)
  11. #include <io.h>
  12. #include <conio.h>
  13. #endif
  14. #include "global.h"
  15. #ifdef    ANSIPROTO
  16. #include <stdarg.h>
  17. #endif
  18. #include "mbuf.h"
  19. #include "timer.h"
  20. #include "proc.h"
  21. #include "iface.h"
  22. #include "ip.h"
  23. #include "tcp.h"
  24. #include "udp.h"
  25. #include "ax25.h"
  26. #include "kiss.h"
  27. #include "enet.h"
  28. #include "netrom.h"
  29. #include "ftpcli.h"
  30. #include "telnet.h"
  31. #include "tty.h"
  32. #include "session.h"
  33. #include "hardware.h"
  34. #include "usock.h"
  35. #include "socket.h"
  36. #include "cmdparse.h"
  37. #include "commands.h"
  38. #include "daemon.h"
  39. #include "devparam.h"
  40. #include "domain.h"
  41. #include "files.h"
  42. #include "main.h"
  43. #include "remote.h"
  44. #include "trace.h"
  45.  
  46. extern struct cmds Cmds[],Startcmds[],Stopcmds[],Attab[];
  47.  
  48. #ifndef    MSDOS            /* PC uses F-10 key always */
  49. static char Escape = 0x1d;    /* default escape character is ^] */
  50. #endif
  51.  
  52. char Badhost[] = "Unknown host %s\n";
  53. char *Hostname;
  54. char Nospace[] = "No space!!\n";    /* Generic malloc fail message */
  55. struct proc *Cmdpp;
  56. struct proc *Display;
  57. int main_exit = FALSE;            /* from main program (flag) */
  58.  
  59. static char Prompt[] = "net> ";
  60. static FILE *Logfp;
  61. static time_t StartTime;        /* time that NOS was started */
  62. static int Verbose;
  63.  
  64. int
  65. main(argc,argv)
  66. int argc;
  67. char *argv[];
  68. {
  69.     char *intmp;
  70.     FILE *fp;
  71.     struct daemon *tp;
  72.     int c;
  73.     char cmdbuf[256];
  74.  
  75.     StartTime = time(&StartTime);
  76.  
  77.     while((c = getopt(argc,argv,"f:s:d:bv")) != EOF){
  78.         switch(c){
  79.         case 'f':    /* Number of files */
  80.             Nfiles = atoi(optarg);
  81.             break;
  82.         case 's':    /* Number of sockets */
  83.             Nsock = atoi(optarg);
  84.             break;
  85.         case 'd':    /* Root directory for various files */
  86.             initroot(optarg);
  87.             break;
  88. #ifdef    __TURBOC__
  89.         case 'b':    /* Use BIOS for screen output */
  90.             directvideo = 0;
  91.             break;
  92. #endif
  93.         case 'v':
  94.             Verbose = 1;
  95.             break;
  96.         }
  97.     }
  98.     kinit();
  99.     ipinit();
  100.     ioinit();
  101.     sockinit();
  102.     Cmdpp = mainproc("cmdintrp");
  103.  
  104.     Sessions = (struct session **)callocw(Nsessions,sizeof(struct session *));
  105.     Command = Lastcurr = newsession("command interpreter",COMMAND,1);
  106.     Display = newproc("display",250,display,0,NULLCHAR,NULL,0);
  107.     printf("KA9Q NOS version %s\n",Version);
  108.     printf("Copyright 1992 by Phil Karn, KA9Q\n");
  109.     /* Start background Daemons */
  110.     for(tp=Daemons;;tp++){
  111.         if(tp->name == NULLCHAR)
  112.             break;
  113.         newproc(tp->name,tp->stksize,tp->fp,0,NULLCHAR,NULL,0);
  114.     }
  115.     Encap.txproc = newproc("encap tx",512,if_tx,0,&Encap,NULL,0);
  116.     if(optind < argc){
  117.         /* Read startup file named on command line */
  118.         if((fp = fopen(argv[optind],READ_TEXT)) == NULLFILE)
  119.             printf("Can't read config file %s: %s\n",
  120.              argv[optind],sys_errlist[errno]);
  121.     } else {
  122.         fp = fopen(Startup,READ_TEXT);
  123.     }
  124.     if(fp != NULLFILE){
  125.         while(fgets(cmdbuf,sizeof(cmdbuf),fp) != NULLCHAR){
  126.             intmp = strdup(cmdbuf);
  127.             if(Verbose)
  128.                 printf("%s",intmp);
  129.             if(cmdparse(Cmds,cmdbuf,NULL) != 0){
  130.                 printf("input line: %s",intmp);
  131.             }
  132.             free(intmp);
  133.         }
  134.         fclose(fp);
  135.     }
  136.     /* Now loop forever, processing commands */
  137.     for(;;){
  138.         printf(Prompt);
  139.         fflush(stdout);
  140.         if(fgets(cmdbuf,sizeof(cmdbuf),stdin) != NULLCHAR){
  141.             (void)cmdparse(Cmds,cmdbuf,Lastcurr);
  142.         }
  143.     }
  144. }
  145. /* Keyboard input process */
  146. void
  147. keyboard(i,v1,v2)
  148. int i;
  149. void *v1;
  150. void *v2;
  151. {
  152.     int c;
  153.     char *cp;
  154.  
  155.     /* Keyboard process loop */
  156.     for(;;){
  157.         c = kbread();
  158. #ifdef    MSDOS
  159.         switch(c){
  160.         case 256 + 68:    /* F-10 */
  161.             c = -2;
  162.             break;
  163.         }
  164. #else
  165.         if(c == Escape && Escape != 0)
  166.             c = -2;
  167. #endif
  168.         if(c == -2 && Current != Command){
  169.             /* Save current tty mode and set cooked */
  170.             Lastcurr = Current;
  171.             Current = Command;
  172.             alert(Display,1);
  173.         } else if(c >= 0 && c < 256){
  174.             /* Ordinary ASCII character, hand to tty editor */
  175.             if((cp = ttydriv(Current,(char)c)) != NULLCHAR){
  176.                 /* Input ready to hand to process */
  177.                 fputs(cp,Current->input);
  178.                 fflush(Current->input);
  179.                 free(cp);
  180.             }
  181.         } else if(Current->ctlproc != NULLFP)
  182.             (*Current->ctlproc)(c);
  183.     }
  184. }
  185. /* Standard commands called from main */
  186. int
  187. dodelete(argc,argv,p)
  188. int argc;
  189. char *argv[];
  190. void *p;
  191. {
  192.     int i;
  193.  
  194.     for(i=1;i < argc; i++){
  195.         if(unlink(argv[i]) == -1){
  196.             printf("Can't delete %s: %s\n",
  197.              argv[i],sys_errlist[errno]);
  198.         }
  199.     }
  200.     return 0;
  201. }
  202. int
  203. dorename(argc,argv,p)
  204. int argc;
  205. char *argv[];
  206. void *p;
  207. {
  208.     if(rename(argv[1],argv[2]) == -1)
  209.         printf("Can't rename: %s\n",sys_errlist[errno]);
  210.     return 0;
  211. }
  212. int
  213. doexit(argc,argv,p)
  214. int argc;
  215. char *argv[];
  216. void *p;
  217. {
  218.     int i;
  219.     time_t StopTime;
  220.  
  221.     StopTime = time(&StopTime);
  222.     main_exit = TRUE;    /* let everyone know we're out of here */
  223.     reset_all();
  224.     if(Dfile_updater != NULLPROC)
  225.         alert(Dfile_updater,0);    /* don't wait for timeout */
  226.     for(i=0;i<100;i++)
  227.         pwait(NULL);    /* Allow tasks to complete */
  228.     shuttrace();
  229.     log(-1,"NOS was stopped at %s", ctime(&StopTime));
  230.     if(Logfp){
  231.         fclose(Logfp);
  232.         Logfp = NULLFILE;
  233.     }
  234.     iostop();
  235.     exit(0);
  236.     return 0;    /* To satisfy lint */
  237. }
  238. int
  239. dohostname(argc,argv,p)
  240. int argc;
  241. char *argv[];
  242. void *p;
  243. {
  244.     if(argc < 2)
  245.         printf("%s\n",Hostname);
  246.     else {
  247.         struct iface *ifp;
  248.         char *name;
  249.  
  250.         if((ifp = if_lookup(argv[1])) != NULLIF){
  251.             if((name = resolve_a(ifp->addr, FALSE)) == NULLCHAR){
  252.                 printf("Interface address not resolved\n");
  253.                 return 1;
  254.             } else {
  255.                 if(Hostname != NULLCHAR)
  256.                     free(Hostname);
  257.                 Hostname = name;
  258.  
  259.                 /* remove trailing dot */
  260.                 if ( Hostname[strlen(Hostname)] == '.' ) {
  261.                     Hostname[strlen(Hostname)] = '\0';
  262.                 }
  263.                 printf("Hostname set to %s\n", name );
  264.             }
  265.         } else {
  266.             if(Hostname != NULLCHAR)
  267.                 free(Hostname);
  268.             Hostname = strdup(argv[1]);
  269.         }
  270.     }
  271.     return 0;
  272. }
  273. int
  274. dolog(argc,argv,p)
  275. int argc;
  276. char *argv[];
  277. void *p;
  278. {
  279.     static char *logname;
  280.  
  281.     if(argc < 2){
  282.         if(Logfp)
  283.             printf("Logging to %s\n",logname);
  284.         else
  285.             printf("Logging off\n");
  286.         return 0;
  287.     }
  288.     if(Logfp){
  289.         log(-1,"NOS log closed");
  290.         fclose(Logfp);
  291.         Logfp = NULLFILE;
  292.         free(logname);
  293.         logname = NULLCHAR;
  294.     }
  295.     if(strcmp(argv[1],"stop") != 0){
  296.         logname = strdup(argv[1]);
  297.         Logfp = fopen(logname,APPEND_TEXT);
  298.         log(-1,"NOS was started at %s", ctime(&StartTime));
  299. #ifdef MSDOS
  300.         log(-1,"NOS load information: CS=0x%04x DS=0x%04x", _CS, _DS);
  301. #endif
  302.     }
  303.     return 0;
  304. }
  305. int
  306. dohelp(argc,argv,p)
  307. int argc;
  308. char *argv[];
  309. void *p;
  310. {
  311.     register struct cmds *cmdp;
  312.     int i;
  313.     char buf[66];
  314.  
  315.     printf("Main commands:\n");
  316.     memset(buf,' ',sizeof(buf));
  317.     buf[64] = '\n';
  318.     buf[65] = '\0';
  319.     for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i = (i+1)%4){
  320.         strncpy(&buf[i*16],cmdp->name,strlen(cmdp->name));
  321.         if(i == 3){
  322.             printf(buf);
  323.             memset(buf,' ',sizeof(buf));
  324.             buf[64] = '\n';
  325.             buf[65] = '\0';
  326.         }
  327.     }
  328.     if(i != 0)
  329.         printf(buf);
  330.     return 0;
  331. }
  332. /* Attach an interface
  333.  * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
  334.  */
  335. int
  336. doattach(argc,argv,p)
  337. int argc;
  338. char *argv[];
  339. void *p;
  340. {
  341.     return subcmd(Attab,argc,argv,p);
  342. }
  343. /* Manipulate I/O device parameters */
  344. int
  345. doparam(argc,argv,p)
  346. int argc;
  347. char *argv[];
  348. void *p;
  349. {
  350.     register struct iface *ifp;
  351.     int param;
  352.     int32 val;
  353.  
  354.     if((ifp = if_lookup(argv[1])) == NULLIF){
  355.         printf("Interface \"%s\" unknown\n",argv[1]);
  356.         return 1;
  357.     }
  358.     if(ifp->ioctl == NULL){
  359.         printf("Not supported\n");
  360.         return 1;
  361.     }
  362.     if(argc < 3){
  363.         for(param=1;param<=16;param++){
  364.             val = (*ifp->ioctl)(ifp,param,FALSE,0L);
  365.             if(val != -1)
  366.                 printf("%s: %ld\n",parmname(param),val);
  367.         }
  368.         return 0;
  369.     }
  370.     if((param = devparam(argv[2])) == -1){
  371.         printf("Unknown parameter %s\n",argv[2]);
  372.         return 1;
  373.     }
  374.     if(argc < 4){
  375.         /* Read specific parameter */
  376.         val = (*ifp->ioctl)(ifp,param,FALSE,0L);
  377.         if(val == -1){
  378.             printf("Parameter %s not supported\n",argv[2]);
  379.         } else {
  380.             printf("%s: %ld\n",parmname(param),val);
  381.         }
  382.         return 0;
  383.     }
  384.     /* Set parameter */
  385.     (*ifp->ioctl)(ifp,param,TRUE,atol(argv[3]));
  386.     return 0;
  387. }
  388.  
  389. /* Display or set IP interface control flags */
  390. int
  391. domode(argc,argv,p)
  392. int argc;
  393. char *argv[];
  394. void *p;
  395. {
  396.     register struct iface *ifp;
  397.  
  398.     if((ifp = if_lookup(argv[1])) == NULLIF){
  399.         printf("Interface \"%s\" unknown\n",argv[1]);
  400.         return 1;
  401.     }
  402.     if(argc < 3){
  403.         printf("%s: %s\n",ifp->name,
  404.          (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  405.         return 0;
  406.     }
  407.     switch(argv[2][0]){
  408.     case 'v':
  409.     case 'c':
  410.     case 'V':
  411.     case 'C':
  412.         ifp->flags = CONNECT_MODE;
  413.         break;
  414.     case 'd':
  415.     case 'D':
  416.         ifp->flags = DATAGRAM_MODE;
  417.         break;
  418.     default:
  419.         printf("Usage: %s [vc | datagram]\n",argv[0]);
  420.         return 1;
  421.     }
  422.     return 0;
  423. }
  424.  
  425. #ifndef    MSDOS
  426. int
  427. doescape(argc,argv,p)
  428. int argc;
  429. char *argv[];
  430. void *p;
  431. {
  432.     if(argc < 2)
  433.         printf("0x%x\n",Escape);
  434.     else
  435.         Escape = *argv[1];
  436.     return 0;
  437. }
  438. #endif    MSDOS
  439. /* Generate system command packet. Synopsis:
  440.  * remote [-p port#] [-k key] [-a hostname] <hostname> reset|exit|kickme
  441.  */
  442. int
  443. doremote(argc,argv,p)
  444. int argc;
  445. char *argv[];
  446. void *p;
  447. {
  448.     struct sockaddr_in fsock;
  449.     int s,c;
  450.     char *data,x;
  451.     int16 port,len;
  452.     char *key = NULLCHAR;
  453.     int klen;
  454.     int32 addr = 0;
  455.     char *cmd,*host;
  456.  
  457.     port = IPPORT_REMOTE;    /* Set default */
  458.     optind = 1;        /* reinit getopt() */
  459.     while((c = getopt(argc,argv,"a:p:k:s:")) != EOF){
  460.         switch(c){
  461.         case 'a':
  462.             addr = resolve(optarg);
  463.             break;
  464.         case 'p':
  465.             port = atoi(optarg);
  466.             break;
  467.         case 'k':
  468.             key = optarg;
  469.             klen = strlen(key);
  470.             break;
  471.         case 's':
  472.             Rempass = strdup(optarg);
  473.             return 0;    /* Only set local password */
  474.         }
  475.     }
  476.     if(optind > argc - 2){
  477.         printf("Insufficient args\n");
  478.         return -1;
  479.     }
  480.     host = argv[optind++];
  481.     cmd = argv[optind];
  482.     if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
  483.         perror("socket failed");
  484.         return 1;
  485.     }
  486.     len = 1;
  487.     /* Did the user include a password or kickme target? */
  488.     if(addr != 0)
  489.         len += sizeof(int32);
  490.  
  491.     if(key != NULLCHAR)
  492.         len += klen;
  493.  
  494.     if(len == 1)
  495.         data = &x;
  496.     else
  497.         data = mallocw(len);
  498.  
  499.     fsock.sin_family = AF_INET;
  500.     fsock.sin_addr.s_addr = resolve(host);
  501.     fsock.sin_port = port;
  502.  
  503.     switch(cmd[0]){
  504.     case 'r':
  505.         data[0] = SYS_RESET;
  506.         if(key != NULLCHAR)
  507.             strncpy(&data[1],key,klen);
  508.         break;
  509.     case 'e':
  510.         data[0] = SYS_EXIT;
  511.         if(key != NULLCHAR)
  512.             strncpy(&data[1],key,klen);
  513.         break;
  514.     case 'k':
  515.         data[0] = KICK_ME;
  516.         if(addr != 0)
  517.             put32(&data[1],addr);
  518.         break;
  519.     default:
  520.         printf("Unknown command %s\n",cmd);
  521.         goto cleanup;
  522.     }
  523.     /* Form the command packet and send it */
  524.     if(sendto(s,data,len,0,(char *)&fsock,sizeof(fsock)) == -1){
  525.         perror("sendto failed");
  526.         goto cleanup;
  527.     }
  528. cleanup:
  529.     if(data != &x)
  530.         free(data);
  531.     close_s(s);
  532.     return 0;
  533. }
  534.  
  535. /* No-op command */
  536. int
  537. donothing(argc,argv,p)
  538. int argc;
  539. char *argv[];
  540. void *p;
  541. {
  542.     return 0;
  543. }
  544.  
  545. /* Log messages of the form
  546.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  547.  */
  548. #if    defined(ANSIPROTO)
  549. void
  550. log(int s,char *fmt, ...)
  551. {
  552.     va_list ap;
  553.     char *cp;
  554.     long t;
  555.     int i;
  556.     struct sockaddr fsocket;
  557. #ifdef    MSDOS
  558.     int fd;
  559. #endif
  560.  
  561.     if(Logfp == NULLFILE)
  562.         return;
  563.  
  564.     time(&t);
  565.     cp = ctime(&t);
  566.     rip(cp);
  567.     i = SOCKSIZE;
  568.     fprintf(Logfp,"%s",cp);
  569.     if(getpeername(s,(char *)&fsocket,&i) != -1)
  570.         fprintf(Logfp," %s",psocket(&fsocket));
  571.  
  572.     fprintf(Logfp," - ");
  573.     va_start(ap,fmt);
  574.     vfprintf(Logfp,fmt,ap);
  575.     va_end(ap);
  576.     fprintf(Logfp,"\n");
  577.     fflush(Logfp);
  578. #ifdef    MSDOS
  579.     /* MS-DOS doesn't really flush files until they're closed */
  580.     fd = fileno(Logfp);
  581.     if((fd = dup(fd)) != -1)
  582.         close(fd);
  583. #endif
  584. }
  585. #else
  586. /*VARARGS2*/
  587. void
  588. log(s,fmt,arg1,arg2,arg3,arg4,arg5)
  589. int s;
  590. char *fmt;
  591. int arg1,arg2,arg3,arg4,arg5;
  592. {
  593.     char *cp;
  594.     long t;
  595.     int fd,i;
  596.     struct sockaddr fsocket;
  597.  
  598.     if(Logfp == NULLFILE)
  599.         return;
  600.     time(&t);
  601.     cp = ctime(&t);
  602.     rip(cp);
  603.     i = SOCKSIZE;
  604.     fprintf(Logfp,"%s",cp);
  605.     if(getpeername(s,(char *)&fsocket,&i) != -1)
  606.         fprintf(Logfp," %s",psocket(&fsocket));
  607.  
  608.     fprintf(Logfp," - ");
  609.     fprintf(Logfp,fmt,arg1,arg2,arg3,arg4,arg5);
  610.     fprintf(Logfp,"\n");
  611.     fflush(Logfp);
  612. #ifdef    MSDOS
  613.     /* MS-DOS doesn't really flush files until they're closed */
  614.     fd = fileno(Logfp);
  615.     if((fd = dup(fd)) != -1)
  616.         close(fd);
  617. #endif
  618. }
  619. #endif
  620.  
  621.