home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / internet / tcpip / src205 / TCPIP_Src / Main / c / main < prev    next >
Encoding:
Text File  |  1995-03-21  |  26.8 KB  |  1,078 lines

  1. /* Main network program - provides both client and server functions */
  2.  
  3. #define HOSTNAMELEN 64
  4.  
  5. #define ESC 29
  6.  
  7. extern char config[];    /* File to read setup from */
  8. extern char startup[];   /* File to read startup commands from */
  9. extern char alternate[]; /* Directory for alternate startup commands */
  10. extern char scripts[];   /* Directory for command files for source command */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <time.h>
  16. #include <stdarg.h>
  17. #include <ctype.h>
  18.  
  19. #include "wimp.h"
  20. #include "wimpt.h"
  21. #include "visdelay.h"
  22.  
  23. #include "config.h"
  24. #include "global.h"
  25. #include "mbuf.h"
  26. #include "netuser.h"
  27. #include "timer.h"
  28. #include "icmp.h"
  29. #include "iface.h"
  30. #include "ip.h"
  31. #include "tcp.h"
  32. #include "ax25.h"
  33. #include "netrom.h"
  34. #include "remote.h"
  35. #include "ftp.h"
  36. #include "telnet.h"
  37. #include "session.h"
  38. #include "cmdparse.h"
  39. #include "asy.h"
  40. #include "chat.h"
  41. #include "slip.h"
  42. #include "nrs.h"
  43. #include "trace.h"
  44. #include "mem.h"
  45. #include "arp.h"
  46. #include "ax_mbx.h"
  47. #include "finger.h"
  48. #include "ident.h"
  49. #include "dns.h"
  50. #include "internet.h"
  51. #include "kiss.h"
  52. #include "lapb.h"
  53. #include "nr4.h"
  54. #include "ping.h"
  55. #include "pop.h"
  56. #include "nntp.h"
  57. #include "smtp.h"
  58. #include "NetTime.h"
  59. #include "udp.h"
  60. #include "misc.h"
  61. #include "domain.h"
  62. #include "arc.h"
  63. #include "driver.h"
  64. #include "pppdriver.h"
  65. #include "alarm.h"
  66. #include "var.h"
  67.  
  68. extern varlist global_vars;
  69.  
  70. extern int (*driver_load(char*))(int,...);
  71.  
  72. /* Dummy structure for loopback tracing */
  73. struct interface loopback = {
  74.   NULLIF, "loopback" };
  75.  
  76. extern struct interface *ifaces;
  77. extern struct mbuf *loopq;
  78.  
  79. extern Terminal *MWin;
  80.  
  81. int mode;
  82.  
  83. char badhost[] = "Unknown host %s\r\n";
  84. char hostname[HOSTNAMELEN];
  85. unsigned nsessions = NSESSIONS;
  86. int16 lport    = 1024;
  87. char *prompt   = "net> ";
  88. char nospace[] = "No space!!\r\n";        /* Generic malloc fail message */
  89. int attended = 1;
  90. int ttyflow = 1;                        /* tty flow control */
  91. int initialisation_completed = FALSE;
  92.  
  93. static char *ttybuf;
  94. static int quiet = FALSE;  /* Echo startup files */
  95.  
  96. extern int doresolve(int, char **);
  97. extern int dotransfer(int, char **);
  98.  
  99. static int doexit(int, char **);
  100. static int doattach(int, char **);
  101. static int doecho(int, char **);
  102. static int doeol(int, char **);
  103. static int dohostname(int, char **);
  104. static int dolog(int, char **);
  105. static int dohelp(int, char **);
  106. static int domode(int, char **);
  107. static int doparam(int, char **);
  108. static int doremote(int, char **);
  109. static int dostart(int, char **);
  110. static int dostop(int, char **);
  111. static int dotrace(int, char **);
  112. static int dosource(int, char **);
  113. static int dounattend(int, char **);
  114. static int dofiler(int, char **);
  115.  
  116. static int filer_open(int, char **);
  117. static int filer_run(int, char **);
  118.  
  119. extern int docredits(int argc, char **argv);
  120. extern int doterm(int argc, char **argv);
  121.  
  122. extern int doslipstat(int argc, char **argv);
  123.  
  124. extern int dosetvar(int argc, char **argv); /* In command parse */
  125. extern int dosetosvar(int argc, char **argv); /* In command parse */
  126. extern int doshowvar(int argc, char **argv); /* In command parse */
  127.  
  128. extern int doident(int argc, char **argv);
  129. extern int doftpopt(int argc, char **argv);
  130.  
  131. static void showtrace(struct interface *);
  132. static int  asy_attach(int, char **);
  133. extern int ether_attach(int argc, char **argv);
  134. extern int aun_attach(int argc, char **argv);
  135.  
  136. extern int ask_user(char *msg, char *but0, char *but1);
  137.  
  138. struct cmds cmds[] = {
  139.   /* The "go" command must be first */
  140.   "",             go,             0, NULLCHAR,    NULLCHAR,
  141.   "aftp",         doaftp,         2, "aftp <host> [<script file>]",     NULLCHAR,
  142.   "arp",          doarp,          0, NULLCHAR,    NULLCHAR,
  143.   "asystat",      doasystat,      0, NULLCHAR,    NULLCHAR,
  144.   "ax25",         doax25,         0, NULLCHAR,    NULLCHAR,
  145.   "attach",       doattach,       2, "attach <hardware> <hw specific options>", NULLCHAR,
  146.   /* This one is out of alpabetical order to allow abbreviation to "c" */
  147.   "connect",      doconnect,      3,"connect <interface> <callsign> [digipeaters]",
  148.   NULLCHAR,
  149.   "chat",         dochat,         0, "chat <interface> <error-send> [expect-send pairs]",    NULLCHAR,
  150.   "chattrace",    chat_trace,     0, NULLCHAR,    NULLCHAR,
  151.   "close",        doclose,        0, NULLCHAR,    NULLCHAR,
  152.   "credits",      docredits,      0, NULLCHAR,    NULLCHAR,
  153.   "disconnect",   doclose,        0, NULLCHAR,    NULLCHAR,
  154.   "domain",       dodomain,       0, NULLCHAR,    NULLCHAR,
  155.   "echo",         doecho,         0, NULLCHAR,    "echo [refuse|accept]",
  156.   "eol",          doeol,          0, NULLCHAR,    "eol options: unix, standard",
  157.   "exit",         doexit,         0, NULLCHAR,    NULLCHAR,
  158.   "finger",       dofinger,       0, NULLCHAR,    NULLCHAR,
  159.   "filer",        dofiler,        1, "open|run <file>",    NULLCHAR,
  160.   "forward",      doforward,      0, NULLCHAR,    NULLCHAR,
  161.   "ftp",          doftp,          2, "ftp <address> [ \\ <switches>[ \\ <chat strings>]]",     NULLCHAR,
  162.   "ftpopt",       doftpopt,       0, NULLCHAR,    NULLCHAR,
  163.   "help",         dohelp,         0, NULLCHAR,    NULLCHAR,
  164.   "hop",          dohop,      0, NULLCHAR,    NULLCHAR,
  165.   "hostname",     dohostname,     0, NULLCHAR,    NULLCHAR,
  166.   "kick",         dokick,         0, NULLCHAR,    NULLCHAR,
  167.   "log",          dolog,          0, NULLCHAR,    NULLCHAR,
  168.   "ip",           doip,           0, NULLCHAR,    NULLCHAR,
  169.   "ident",        doident,        1, NULLCHAR,    NULLCHAR,
  170.   "mbox",         dombox,         0, NULLCHAR,    NULLCHAR,
  171.   "mem",          domem,          0, NULLCHAR,    NULLCHAR,
  172.   "mode",         domode,         2, "mode <interface>",  NULLCHAR,
  173.   "netrom",       donetrom,       0, NULLCHAR,    NULLCHAR,
  174.   "nntp",         donntp,         0, NULLCHAR,    NULLCHAR,
  175. /*  "nntp2",        donntp2,        0, NULLCHAR,    NULLCHAR, */
  176.   "nrstat",       donrstat,       0, NULLCHAR,    NULLCHAR,
  177.   "nsquery",      dodns,          0, "nsquery <options> [<namesever>] [<name>] [<type>]", NULLCHAR,
  178.   "param",        doparam,        2, "param <interface>", NULLCHAR,
  179.   "ping",         doping,         0, NULLCHAR,    NULLCHAR,
  180.   "pop",          dopop,          0, NULLCHAR,    NULLCHAR,
  181.   "quit",         doexit,         0, NULLCHAR,    NULLCHAR,
  182.   "record",       dorecord,       0, NULLCHAR,    NULLCHAR,
  183.   "remote",       doremote,       4, "remote <address> <port> <command>", NULLCHAR,
  184.   "reset",        doreset,        0, NULLCHAR,    NULLCHAR,
  185.   "resolve",      doresolve,      0, NULLCHAR,    NULLCHAR,
  186.   "route",        doroute,        0, NULLCHAR,    NULLCHAR,
  187.   "session",      dosession,      0, NULLCHAR,    NULLCHAR,
  188.   "setvar",       dosetvar,       3, "setvar <variable> <value_string>", NULLCHAR,
  189.   "setosvar",     dosetosvar,     3, "setvar <variable> <os variable name>", NULLCHAR,
  190.   "showvar",      doshowvar,      0, "showvar [<variable>]", NULLCHAR,
  191.   "smtp",         dosmtp,         0, NULLCHAR,    NULLCHAR,
  192.   "slipstat",     doslipstat,     2, "slipstat <interface>",    NULLCHAR,
  193.   "source",       dosource,       2, "source <filename>", NULLCHAR,
  194.   "start",        dostart,        2, "start <servername>",NULLCHAR,
  195.   "stop",         dostop,         2, "stop <servername>", NULLCHAR,
  196.   "tcp",          dotcp,          0, NULLCHAR,    NULLCHAR,
  197.   "telnet",       dotelnet,       2, "telnet <address> [<port>] [ \\ <switches>[ \\ <chat strings>]]",  NULLCHAR,
  198.   "time",         dotime,         1, NULLCHAR,  NULLCHAR,
  199.   "trace",        dotrace,        0, NULLCHAR,    NULLCHAR,
  200.   "trf",          dotransfer,     4, "trf <site> <port> <command>", NULLCHAR,
  201.   "udp",          doudp,          0, NULLCHAR,    NULLCHAR,
  202.   "unattended",   dounattend,     0, NULLCHAR,    NULLCHAR,
  203.   "upload",       doupload,       0, NULLCHAR,    NULLCHAR,
  204.   "window",       dowin,          0, NULLCHAR,    NULLCHAR,
  205.   "terminal",     doterm,         1, "terminal [*] <switches>[ \\ <chat strings>]",    NULLCHAR,
  206.   "?",            dohelp,         0, NULLCHAR,    NULLCHAR,
  207.   NULLCHAR,       NULLFP,         0,
  208.   "Unknown command; type \"?\" for list",   NULLCHAR,
  209. };
  210.  
  211. /* "start" and "stop" subcommands */
  212.  
  213. static struct cmds startcmds[] = {
  214.   "discard",      dis1,           0, NULLCHAR, NULLCHAR,
  215.   "echo",         echo1,          0, NULLCHAR, NULLCHAR,
  216.   "finger",       finger1,        0, NULLCHAR, NULLCHAR,
  217.   "ftp",          ftp1,           0, NULLCHAR, NULLCHAR,
  218.   "smtp",         smtp1,          0, NULLCHAR, NULLCHAR,
  219.   "telnet",       tn1,            0, NULLCHAR, NULLCHAR,
  220.   "ident",        ident1,         0, NULLCHAR, NULLCHAR,
  221.   NULLCHAR,       NULLFP,         0,
  222.   "start options: discard, echo, finger, ftp, smtp, telnet", NULLCHAR,
  223. };
  224.  
  225. static struct cmds stopcmds[] = {
  226.   "discard",      dis0,           0, NULLCHAR, NULLCHAR,
  227.   "echo",         echo0,          0, NULLCHAR, NULLCHAR,
  228.   "finger",       finger0,        0, NULLCHAR, NULLCHAR,
  229.   "ftp",          ftp0,           0, NULLCHAR, NULLCHAR,
  230.   "smtp",         smtp0,          0, NULLCHAR, NULLCHAR,
  231.   "telnet",       tn0,            0, NULLCHAR, NULLCHAR,
  232.   "ident",        ident0,         0, NULLCHAR, NULLCHAR,
  233.   NULLCHAR,       NULLFP,         0,
  234.   "stop options: discard, echo, finger, ftp, smtp, telnet", NULLCHAR,
  235. };
  236.  
  237. static struct cmds filercmds[] = {
  238.   "open",         filer_open,     0, NULLCHAR, NULLCHAR,
  239.   "run",          filer_run,      1, NULLCHAR, NULLCHAR,
  240.   NULLCHAR,       NULLFP,         0,
  241.   "filer commands: open, run", NULLCHAR,
  242. };
  243.  
  244.  
  245. static void AutoExec(int at, void *handle)
  246. {
  247.   char *args[3], buffer[256];
  248.   char *exec_file = (char *) handle;
  249.  
  250.   if (exec_file == NULL || exec_file[0] == '\0')
  251.     strcpy(buffer, startup);
  252.   else
  253.     sprintf(buffer, "%s%s", alternate, exec_file);
  254.   args[1] = buffer;
  255.   args[2] = "q";
  256.   dosource((quiet)?3:2, args);
  257.   initialisation_completed = TRUE;
  258. }
  259.  
  260. void net_init(int argc, char *argv[])
  261. {
  262.   char *args[3], buffer[256];
  263.   char *config_file = NULL;
  264.   char *exec_file = NULL;
  265.  
  266.   if (argc>=1 && argv[0][0]=='-')
  267.   {
  268.     quiet = (tolower(argv[0][1])=='q');
  269.     --argc;  ++argv;
  270.   }
  271.  
  272.   if (argc>=1)
  273.     config_file = argv[0];
  274.   if (argc>=2)
  275.     exec_file = argv[1];
  276.  
  277.   sessions = (struct session *) calloc(nsessions, sizeof(struct session));
  278.   memset(udps, NUDP * sizeof(struct udp_cb *), '\0');
  279.   ttydriv('\n',&ttybuf); /* Initialise the keyboard buffer */
  280.  
  281.   Read_Domain_File();
  282.  
  283.   docredits(0, NULL);
  284.  
  285.  /* read default start_up file */
  286.   if (config_file == NULL || config_file[0] == '\0')
  287.     strcpy(buffer, config);
  288.   else
  289.     sprintf(buffer, "%s%s", alternate, config_file);
  290.   args[1] = buffer;
  291.   args[2] = "q";
  292.   dosource((quiet)?3:2, args);
  293.   cmdmode();
  294.   alarm_set(alarm_timenow() + 100, AutoExec, (void *) exec_file);
  295. }
  296.  
  297. void net_keyboard(int c)
  298. {
  299.   int16 cnt;
  300.  
  301.   /* c == 0x1CA means the command escape key (F10) */
  302.   if(c == 0x1CA || c == ESC)
  303.   {
  304.     if(mode != CMD_MODE)
  305.     {
  306.       cwprintf(NULL, "\r\n");
  307.       cmdmode();
  308.     }
  309.     return;
  310.   }
  311.   if ((cnt = ttydriv(c,&ttybuf)) == 0)
  312.   {
  313.     ttyflow = 0;    /* stop output to screen */
  314.     return;
  315.   }
  316.   else
  317.       {
  318.     ttyflow = 1;    /* restart output again */
  319.     if(mode != CMD_MODE)
  320.       go(NULL);   /* display pending chars */
  321.   }
  322.  
  323.   switch(mode)
  324.   {
  325.   case CMD_MODE:
  326.     cmdparse(cmds, ttybuf, NULL);
  327.     break;
  328.   case CONV_MODE:
  329.     if(current->parse != NULLVFP)
  330.       (*current->parse)(NULL, ttybuf, cnt);
  331.     break;
  332.   }
  333.   if(mode == CMD_MODE)
  334.   {
  335.     vterm_newline(MWin->vt);
  336.     cwprintf(NULL, prompt);
  337.   }
  338. }
  339.  
  340. void net_poll(void)
  341. {
  342.   struct interface *ifp;
  343.   struct mbuf *bp;
  344.   struct ip ip;
  345.  
  346.   /* Service the loopback queue */
  347.   if((bp = dequeue(&loopq)) != NULLBUF)
  348.   {
  349.     dump(&loopback, IF_TRACE_IN, TRACE_IP, bp);  /* Extract IP header */
  350.     ntohip(&ip,&bp);
  351.     ip_recv(&ip,bp,0);
  352.   }
  353.   /* Service the interfaces */
  354.   for (ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  355.   {
  356.     if (ifp->recv != NULLVFP)
  357.     {
  358.       (*ifp->recv)(ifp);
  359.       if (ifp->driver != NULL)
  360.         (*ifp->driver)(DRIVER_POLL, ifp->subdevice);
  361.     }
  362.   }
  363.  
  364.   /* Service the clock if it has ticked */
  365.   check_time();
  366. }
  367.  
  368. /* Standard commands called from main */
  369.  
  370. /* Enter command mode */
  371. int cmdmode(void)
  372. {
  373.   if (mode != CMD_MODE)
  374.   {
  375.     mode = CMD_MODE;
  376.     cooked();
  377.     vterm_newline(MWin->vt);
  378.     cwprintf(MWin, prompt);
  379.   }
  380.   return 0;
  381. }
  382.  
  383. static int doexit(int argc, char **argv)
  384. {
  385.    if ( (argc>=2 && strcmp(argv[1], "force")) ||
  386.          !tcp_hasactive() ||
  387.          ask_user("The are active connections. Are you sure you want to quit?",
  388.                   "Quit", "Cancel") )
  389.     net_exit();
  390.  
  391.   return(0);
  392. }
  393.  
  394. void net_exit(void)
  395. {
  396.   iostop();
  397.   exit(0);
  398. }
  399.  
  400. static int dohostname(int argc, char **argv)
  401. {
  402.   if(argc < 2)
  403.     cwprintf(NULL, "%s\r\n",hostname);
  404.   else
  405.     strncpy(hostname,argv[1],HOSTNAMELEN);
  406.   return 0;
  407. }
  408.  
  409. static char logname[80];
  410.  
  411. static int dolog(int argc, char **argv)
  412. {
  413.   if(argc < 2)
  414.   {
  415.     if(logname[0])
  416.       cwprintf(NULL, "Logging to %s\r\n", logname);
  417.     else
  418.         cwprintf(NULL, "Logging off\r\n");
  419.     return 0;
  420.   }
  421.   if(strcmp(argv[1], "stop") != 0)
  422.   {
  423.     strcpy(logname, argv[1]);
  424.   }
  425.   else
  426.       {
  427.     logname[0] = '\0';
  428.   }
  429.   return 0;
  430. }
  431.  
  432. static int dohelp(int argc, char **argv)
  433. {
  434.   register struct cmds *cmdp;
  435.   register char *s;
  436.   int i, j;
  437.  
  438.   argc = argc;
  439.   argv = argv;
  440.  
  441.   if ((s = malloc(2000)) == NULL) return 0;
  442.  
  443.   sprintf(s, "Main commands:\r\n");
  444.  
  445.   for (i = 0, cmdp = cmds; cmdp->name != NULL; cmdp++, i++)
  446.   {
  447.     strcat(s, cmdp->name);
  448.  
  449.     if ((i % 4) == 3)
  450.     {
  451.       strcat(s, "\r\n");
  452.     }
  453.     else {
  454.       for (j = strlen(cmdp->name); j < 16; j++)
  455.         strcat(s, " ");
  456.     }
  457.   }
  458.  
  459.   if ((i % 4) != 0) strcat(s, "\r\n");
  460.  
  461.   cwputs(NULL, s);
  462.  
  463.   free(s);
  464.  
  465.   return 0;
  466. }
  467.  
  468. static int doecho(int argc, char **argv)
  469. {
  470.   extern int refuse_echo;
  471.  
  472.   if(argc < 2)
  473.   {
  474.     if(refuse_echo)
  475.       cwprintf(NULL, "Refuse\r\n");
  476.     else
  477.       cwprintf(NULL, "Accept\r\n");
  478.   }
  479.   else
  480.   {
  481.     if(argv[1][0] == 'r')
  482.       refuse_echo = 1;
  483.     else if(argv[1][0] == 'a')
  484.       refuse_echo = 0;
  485.     else
  486.       return -1;
  487.   }
  488.   return 0;
  489. }
  490.  
  491. static int doremote(int argc, char **argv)
  492. {
  493.   struct socket fsock, lsock;
  494.   struct mbuf *bp;
  495.  
  496.   argc = argc;
  497.  
  498.   lsock.address = ip_addr;
  499.   fsock.address = resolve(argv[1]);
  500.   lsock.port    = fsock.port = atoi(argv[2]);
  501.   bp = alloc_mbuf(1);
  502.   if (strcmp(argv[3], "reset") == 0)
  503.   {
  504.     *bp->data = SYS_RESET;
  505.   }
  506.   else if (strcmp(argv[3], "exit") == 0)
  507.   {
  508.     *bp->data = SYS_EXIT;
  509.   }
  510.   else if (strcmp(argv[3], "kick") == 0)
  511.   {
  512.     *bp->data = SYS_KICK;
  513.   }
  514.   else
  515.   {
  516.     cwprintf(NULL, "Unknown command %s\r\n", argv[3]);
  517.     return(1);
  518.   }
  519.   bp->cnt = 1;
  520.   send_udp(&lsock, &fsock, 0, 0, bp, 0, 0, 0);
  521.   return(0);
  522. }
  523.  
  524. /* if unattended mode is set - restrict ax25 and telnet sessions */
  525. static int dounattend(int argc, char **argv)
  526. {
  527.   if(argc < 2)
  528.   {
  529.     if(attended)
  530.       cwprintf(NULL, "System in attended operation.\r\n");
  531.     else
  532.         cwprintf(NULL, "System in unattended operation.\r\n");
  533.   }
  534.   else
  535.       {
  536.     if(argv[1][0] == 'y')
  537.     {
  538.       attended = 0;
  539.       cwprintf(NULL, "System now in unattended operation.\r\n");
  540.     }
  541.     else if(argv[1][0] == 'n')
  542.     {
  543.       attended = 1;
  544.       cwprintf(NULL, "System now in attended operation.\r\n");
  545.     }
  546.     else
  547.     {
  548.       cwprintf(NULL, "Usage : unattended y|n\r\n");
  549.       return -1;
  550.     }
  551.   }
  552.   return 0;
  553. }
  554.  
  555. /* set for unix end of line for remote echo mode telnet */
  556. static int doeol(int argc, char **argv)
  557. {
  558.   extern int unix_line_mode;
  559.  
  560.   if(argc < 2){
  561.     if(unix_line_mode)
  562.       cwprintf(NULL, "Unix\r\n");
  563.     else
  564.         cwprintf(NULL, "Standard\r\n");
  565.   }
  566.   else {
  567.     if(strcmp(argv[1],"unix") == 0)
  568.       unix_line_mode = 1;
  569.     else if(strcmp(argv[1],"standard") == 0)
  570.       unix_line_mode = 0;
  571.     else {
  572.       return -1;
  573.     }
  574.   }
  575.   return 0;
  576. }
  577. /* Attach an interface
  578.  * Syntax: attach <hw type> <hw name> <mode> <label> <bufsize> [<speed>]
  579.  */
  580. static int doattach(int argc, char **argv)
  581. {
  582.   extern struct cmds attab[];
  583.  
  584.   return subcmd(attab,argc,argv);
  585. }
  586. /* Manipulate I/O device parameters */
  587. static int doparam(int argc, char **argv)
  588. {
  589.   register struct interface *ifp;
  590.  
  591.   for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next)
  592.   {
  593.     if(strcmp(argv[1],ifp->name) == 0)
  594.       break;
  595.   }
  596.   if(ifp == NULLIF)
  597.   {
  598.     cwprintf(NULL, "Interface \"%s\" unknown\r\n",argv[1]);
  599.     return 1;
  600.   }
  601.   if(ifp->ioctl == NULLFP)
  602.   {
  603.     cwprintf(NULL, "Not supported\r\n");
  604.     return 1;
  605.   }
  606.   /* Pass rest of args to device-specific code */
  607.   return (*ifp->ioctl)(ifp,argc-2,argv+2);
  608. }
  609.  
  610. void set_server_vars(char *name, struct tcb *tcb)
  611. {
  612.   char ipa[16];
  613.   char buf[32];
  614.  
  615.   sprintf(ipa, "%u.%u.%u.%u",
  616.           hibyte(hiword(tcb->conn.remote.address)),
  617.           lobyte(hiword(tcb->conn.remote.address)),
  618.           hibyte(loword(tcb->conn.remote.address)),
  619.           lobyte(loword(tcb->conn.remote.address)) );
  620.  
  621.   sprintf(buf, "%s_caller", name);
  622.   var_create_string(global_vars, buf, 0, ipa);
  623.   var_create_string(global_vars, "last_caller", 0, ipa);
  624. }
  625.  
  626. /* Log messages of the form
  627.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  628.  */
  629. void log_event(struct tcb *tcb, char *fmt, ...)
  630. {
  631.   va_list argptr;
  632.   char *cp;
  633.   time_t t;
  634.   FILE *logfp;
  635.  
  636.   if (logname[0] == '\0')
  637.     return;
  638.   if (logfp = fopen(logname, "a+"), logfp == NULLFILE)
  639.     return;
  640.   time(&t);
  641.   cp = ctime(&t);
  642.   rip(cp);
  643.   if (tcb)
  644.     fprintf(logfp, "%s %s - ", cp, psocket(&tcb->conn.remote));
  645.   va_start(argptr,fmt);
  646.   vfprintf(logfp,fmt,argptr);
  647.   va_end(argptr);
  648.   fprintf(logfp,"\n");
  649.   fclose(logfp);
  650. }
  651. /* Configuration-dependent code */
  652.  
  653. /* List of supported hardware devices */
  654.  
  655. struct cmds attab[] = {
  656.  
  657.   /* Ordinary asynchronous adaptor */
  658.   "asy", asy_attach, 8,
  659.   "attach asy <driver> <subdevice> slip|ax25|nrs <label> <buffers> <mtu> <speed>\r\n        <nrs call>",
  660.   "Could not attach asy",
  661.  
  662.   /* PPP driver */
  663.   "ppp", ppp_attach, 1,
  664.   "attach ppp",
  665.   "Could not attach ppp",
  666.  
  667.   /* fake netrom interface */
  668.   "netrom", nr_attach, 1,
  669.   "attach netrom",
  670.   "Could not attach netrom",
  671.  
  672.   /* DCI Drivers for Ethernet */
  673.   "ether", ether_attach, 4,
  674.   "attach ether <port> <label> <mtu>",
  675.   "Could not attach ether",
  676.  
  677.   /* DCI Drivers for AUN Link */
  678.   "aun", aun_attach, 2,
  679.   "attach aun <label>",
  680.   "Could not attach aun link",
  681.  
  682.   NULLCHAR, NULLFP, 0,
  683.   "Unknown device",
  684.   NULLCHAR,
  685. };
  686.  
  687. /* Protocol tracing function pointers */
  688. void (*tracef[])() = {
  689.   ax25_dump,
  690.  
  691.   NULLVFP,
  692.   ip_dump,
  693.  
  694.  
  695.   NULLVFP,
  696. };
  697.  
  698.  
  699. /* Attach a serial interface to the system
  700.  * argv[0]: hardware type, must be "asy"
  701.  * argv[1]: async adapter type, e.g. internal
  702.  * argv[2]: async adapter port number
  703.  * argv[3]: mode, may be:
  704.  *          "slip" (point-to-point SLIP)
  705.  *          "ax25" (AX.25 frame format in SLIP for raw TNC)
  706.  *          "nrs" (NET/ROM format serial protocol)
  707.  * argv[4]: interface label, e.g., "sl0"
  708.  * argv[5]: receiver ring buffer size in bytes
  709.  * argv[6]: maximum transmission unit, bytes
  710.  * argv[7]: interface speed, e.g, "9600"
  711.  * argv[8]: optional ax.25 callsign (NRS only)
  712.  */
  713. static int asy_attach(int argc, char **argv)
  714. {
  715.   register struct interface *if_asy;
  716.   extern struct interface *ifaces;
  717.   int dev;
  718.   int mode;
  719.   struct ax25_addr addr ;
  720.  
  721.   if (nasy >= ASY_MAX)
  722.   {
  723.     cwprintf(NULL, "Too many asynch controllers\r\n");
  724.     return -1;
  725.   }
  726.   dev = nasy++;
  727.  
  728.   /* Create interface structure and fill in details */
  729.   if_asy = (struct interface *) malloc(sizeof(struct interface));
  730.   memset(if_asy, '\0', sizeof(struct interface));
  731.   if_asy->name = strdup(argv[4]);
  732.  
  733.   if_asy->mtu  = atoi(argv[6]);
  734.   if_asy->dev  = dev;
  735.   if_asy->recv = doslip;
  736.   if_asy->stop = asy_stop;
  737.  
  738.   /* Get driver */
  739.   if (if_asy->driver = driver_load(argv[1]), if_asy->driver ==NULL)
  740.   {
  741.     cwprintf(NULL, "can't load asy driver \"%s\"\r\n", argv[1]);
  742.     return -1;
  743.   }
  744.   if_asy->subdevice = atoi(argv[2]);
  745.  
  746.   if (!strcmp(argv[3], "slip") || !strcmp(argv[3], "cslip"))
  747.     mode = SLIP_MODE;
  748.   else if (!strcmp(argv[3], "ax25"))
  749.     mode = AX25_MODE;
  750.   else if (!strcmp(argv[3], "nrs"))
  751.     mode = NRS_MODE;
  752.   else
  753.     mode = UNKNOWN;
  754.  
  755.   switch(mode)
  756.   {
  757.   case SLIP_MODE:
  758.     if_asy->ioctl = asy_ioctl;
  759.     if_asy->send = (int(*)())slip_send;
  760.     if_asy->output = NULLFP;        /* ARP isn't used */
  761.     if_asy->raw = slip_raw;
  762.     if_asy->flags = 0;
  763.     slip[dev].recv = slip_recv;
  764.     slip[dev].slcomp = NULL;
  765.     slip[dev].cslip_mode = 0;
  766.     slip[dev].stat_ip_sent = 0;
  767.     slip[dev].stat_tcp_compressed_sent = 0;
  768.     slip[dev].stat_tcp_uncompressed_sent = 0;
  769.     slip[dev].stat_ip_recvd = 0;
  770.     slip[dev].stat_tcp_compressed_recvd = 0;
  771.     slip[dev].stat_tcp_uncompressed_recvd = 0;
  772.     slip[dev].stat_bad_recvd = 0;
  773.  
  774.     if (!strcmp(argv[3], "cslip"))
  775.       sl_compress_init(&slip[dev].slcomp);
  776.     break;
  777.   case AX25_MODE:  /* Set up a SLIP link to use AX.25 */
  778.     axarp();
  779.     if(argc < 9)
  780.     {
  781.       /* no call sign supplied */
  782.       if(mycall.call[0] == '\0')
  783.       {
  784.         cwprintf(NULL, "set mycall first or specify in attach statement\r\n");
  785.         free(if_asy->name);
  786.         free((char *)if_asy);
  787.         nasy--;
  788.         return -1;
  789.       }
  790.       else
  791.           {
  792.         addr = mycall;
  793.       }
  794.     }
  795.     else
  796.     {
  797.       /* callsign supplied on attach line */
  798.       if(setcall(&addr,argv[8]) == -1)
  799.       {
  800.         cwprintf (NULL, "bad callsign on attach line\r\n");
  801.         free(if_asy->name);
  802.         free((char *)if_asy);
  803.         nasy--;
  804.         return -1;
  805.       }
  806.     }
  807.     if_asy->ioctl = kiss_ioctl;
  808.     if_asy->send = (int(*)())ax_send;
  809.     if_asy->output = (int(*)())ax_output;
  810.     if_asy->raw = kiss_raw;
  811.     if(if_asy->hwaddr == NULLCHAR)
  812.       if_asy->hwaddr = malloc(sizeof(addr));
  813.     memcpy(if_asy->hwaddr,(char *)&addr,sizeof(addr));
  814.     slip[dev].recv = kiss_recv;
  815.     break;
  816.   case NRS_MODE: /* Set up a net/rom serial interface */
  817.     if(argc < 9)
  818.     {
  819.       /* no call supplied? */
  820.       if(mycall.call[0] == '\0')
  821.       {
  822.         /* try to use default */
  823.         cwprintf(NULL, "set mycall first or specify in attach statement\r\n");
  824.         return -1;
  825.       }
  826.       else
  827.           addr = mycall;
  828.     }
  829.     else
  830.     {
  831.       /* callsign supplied on attach line */
  832.       if(setcall(&addr,argv[8]) == -1){
  833.         cwprintf (NULL, "bad callsign on attach line\r\n");
  834.         free(if_asy->name);
  835.         free((char *)if_asy);
  836.         nasy--;
  837.         return -1;
  838.       }
  839.     }
  840.     if_asy->recv = nrs_recv;
  841.     if_asy->ioctl = asy_ioctl;
  842.     if_asy->send = (int(*)())ax_send;
  843.     if_asy->output = (int(*)())ax_output;
  844.     if_asy->raw = nrs_raw;
  845.     if(if_asy->hwaddr == NULLCHAR)
  846.       if_asy->hwaddr = malloc(sizeof(addr));
  847.     memcpy(if_asy->hwaddr,(char *)&addr,sizeof(addr));
  848.     nrs[dev].iface = if_asy;
  849.     break;
  850.   default:
  851.     cwprintf(NULL, "Mode %s unknown for interface %s\r\n",
  852.     argv[2],argv[4]);
  853.     free(if_asy->name);
  854.     free((char *)if_asy);
  855.     nasy--;
  856.     return -1;
  857.   }
  858.   if_asy->next = ifaces;
  859.   ifaces = if_asy;
  860.   asy_init(dev, if_asy, (unsigned)atoi(argv[5]));
  861.   if (argc>7)
  862.     asy_speed(dev, atoi(argv[7]));
  863.   if (argc>8)
  864.     asy_flowctrl(dev, atoi(argv[8]));
  865.   return 0;
  866. }
  867.  
  868.  
  869. /* Display or set IP interface control flags */
  870. static int domode(int argc, char **argv)
  871. {
  872.   register struct interface *ifp;
  873.  
  874.   for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  875.     if(strcmp(argv[1],ifp->name) == 0)
  876.       break;
  877.   }
  878.   if(ifp == NULLIF){
  879.     cwprintf(NULL, "Interface \"%s\" unknown\r\n",argv[1]);
  880.     return 1;
  881.   }
  882.   if(argc < 3){
  883.     cwprintf(NULL, "%s: %s\r\n",ifp->name,
  884.     (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  885.     return 0;
  886.   }
  887.   switch(argv[2][0]){
  888.   case 'v':
  889.   case 'c':
  890.   case 'V':
  891.   case 'C':
  892.     ifp->flags = CONNECT_MODE;
  893.     break;
  894.   case 'd':
  895.   case 'D':
  896.     ifp->flags = DATAGRAM_MODE;
  897.     break;
  898.   default:
  899.     cwprintf(NULL, "Usage: %s [vc | datagram]\r\n",argv[0]);
  900.     return 1;
  901.   }
  902.   return 0;
  903. }
  904.  
  905. static int dostart(int argc, char **argv)
  906. {
  907.   return subcmd(startcmds,argc,argv);
  908. }
  909.  
  910. static int dostop(int argc, char **argv)
  911. {
  912.   return subcmd(stopcmds,argc,argv);
  913. }
  914.  
  915. static int dotrace(int argc, char **argv)
  916. {
  917.   struct interface *ifp;
  918.   struct interface *ifpp;
  919.   int tracing = 0;
  920.  
  921.   if(argc < 2){
  922.     showtrace(&loopback);
  923.     for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  924.       showtrace(ifp);
  925.     return 0;
  926.   }
  927.   if(strcmp("loopback",argv[1]) == 0)
  928.     ifp = &loopback;
  929.   else
  930.       for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  931.     if(strcmp(ifp->name,argv[1]) == 0)
  932.       break;
  933.  
  934.   if(ifp == NULLIF){
  935.     cwprintf(NULL, "Interface %s unknown\r\n",argv[1]);
  936.     return 1;
  937.   }
  938.   if(argc >= 3){
  939.     if ((ifp->trace = htoi(argv[2])) > 0)
  940.     {
  941.       twopen();
  942.     }
  943.     else {
  944.       for(ifpp = ifaces; ifpp != NULLIF; ifpp = ifpp->next)
  945.         if (ifpp->trace > 0)
  946.           tracing = 1;
  947.       if (loopback.trace > 0)
  948.         tracing = 1;
  949.       if (!tracing)
  950.         twclose();
  951.     }
  952.   }
  953.   showtrace(ifp);
  954.   return 0;
  955. }
  956. /* Display the trace flags for a particular interface */
  957. static void showtrace(register struct interface *ifp)
  958. {
  959.   if(ifp == NULLIF)
  960.     return;
  961.   cwprintf(NULL, "%s:",ifp->name);
  962.   if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT)){
  963.     if(ifp->trace & IF_TRACE_IN)
  964.       cwprintf(NULL, " input");
  965.     if(ifp->trace & IF_TRACE_OUT)
  966.       cwprintf(NULL, " output");
  967.  
  968.     if(ifp->trace & IF_TRACE_HEX)
  969.       cwprintf(NULL, " (Hex/ASCII dump)");
  970.     else if(ifp->trace & IF_TRACE_ASCII)
  971.       cwprintf(NULL, " (ASCII dump)");
  972.     else
  973.         cwprintf(NULL, " (headers only)");
  974.     cwprintf(NULL, "\r\n");
  975.   }
  976.   else
  977.       cwprintf(NULL, " tracing off\r\n");
  978. }
  979.  
  980. void stoptrace(void)
  981. {
  982.   struct interface *ifp;
  983.  
  984.   loopback.trace = 0;
  985.   for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  986.     ifp->trace = 0;
  987. }
  988.  
  989.  
  990. static int dosource(int argc, char **argv)
  991. {
  992.   char inbuf[500];
  993.   char filename[256];                 /* for error messages */
  994.   int linenum = 0;
  995.   FILE *fp;
  996.   int quiet = FALSE;
  997.  
  998.   if (argc>2 && tolower(*argv[2])=='q')
  999.     quiet = TRUE;
  1000.  
  1001.   argc = argc;
  1002.  
  1003.   if (!strchr(argv[1], '.') && !strchr(argv[1], ':'))
  1004.     sprintf(filename, "%s.%s", scripts, argv[1]);
  1005.   else
  1006.     strcpy(filename, argv[1]);
  1007.  
  1008.   if ((fp = fopen(filename, "r")) == NULLFILE)
  1009.   {
  1010.     cwprintf(NULL, "%s: cannot open\r\n", filename);
  1011.     return 1;
  1012.   }
  1013.  
  1014.   cwprintf(NULL, "Source: %s\r\n", filename);
  1015.  
  1016.   while (fgets(inbuf, sizeof(inbuf),fp) != NULLCHAR)
  1017.   {
  1018.     char * ptr;
  1019.     rip(inbuf);
  1020.     linenum++;
  1021.     /* Do a quick check for comments - no point in calling cmdparse */
  1022.     for (ptr = inbuf; isspace(*ptr); ptr++);
  1023.     if (*ptr == '#' || *ptr == '\0')
  1024.       continue;
  1025.  
  1026.     if (!quiet)
  1027.       cwprintf(NULL, "%s\r\n", inbuf);
  1028.  
  1029.     if (cmdparse(cmds, inbuf, NULL) != 0)
  1030.       cwprintf(NULL, "*** file \"%s\", line %d: %s\r\n", filename, linenum, inbuf);
  1031.   }
  1032.   fclose(fp);
  1033.   return 0;
  1034. }
  1035.  
  1036. static int dofiler(int argc, char **argv)
  1037. {
  1038.   return subcmd(filercmds,argc,argv);
  1039. }
  1040.  
  1041. static int filer_open(int argc, char **argv)
  1042. {
  1043.   os_error *e;
  1044.   char buf[256];
  1045.  
  1046.   if (argc>1)
  1047.   {
  1048.     if (strpbrk(argv[1], "$:<>"))
  1049.       sprintf(buf, "Filer_OpenDir %s", argv[1]);
  1050.     else
  1051.       sprintf(buf, "Filer_OpenDir %s.%s", "<TCPIP$Dir>", argv[1]);
  1052.   }
  1053.   else
  1054.     sprintf(buf, "Filer_OpenDir %s", "<TCPIP$Dir>");
  1055.  
  1056.   visdelay_begin();
  1057.   e = wimp_starttask(buf);
  1058.   visdelay_end();
  1059.   wimpt_complain(e);
  1060.   return 0;
  1061. }
  1062.  
  1063. static int filer_run(int argc, char **argv)
  1064. {
  1065.   os_error *e;
  1066.   char buf[256];
  1067.  
  1068.   if (strpbrk(argv[1], "$:<>"))
  1069.     sprintf(buf, "Filer_Run %s", argv[1]);
  1070.   else
  1071.     sprintf(buf, "Filer_Run %s.%s", "<TCPIP$Dir>", argv[1]);
  1072.   visdelay_begin();
  1073.   e = wimp_starttask(buf);
  1074.   visdelay_end();
  1075.   wimpt_complain(e);
  1076.   return 0;
  1077. }
  1078.