home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / OSKBox.lzh / MAILBOX / CC / host.c < prev    next >
C/C++ Source or Header  |  1991-10-20  |  17KB  |  719 lines

  1. #include <stdio.h>
  2. #include <sgstat.h>
  3. #include <signal.h>
  4. #include <setjmp.h>
  5. #include <errno.h>
  6.  
  7. #define ESC 27
  8. #define MAX_CHANNEL 12
  9. #define MAXPAC 236        /* anything bigger and NET/ROM will split it */
  10.  
  11. /* channel status values */
  12. #define DISCONNECTED 0
  13. #define DISCONNECTING 1
  14. #define TERMINATE 2
  15. #define CONNECTED 3
  16. #define MANUAL 4
  17.  
  18. /* responses from G command */
  19. #define OK 0
  20. #define OK_MSG 1
  21. #define BAD_MSG 2
  22. #define STATUS 3
  23. #define MON_HDR1 4
  24. #define MON_HDR2 5
  25. #define MON_INFO 6
  26. #define CON_INFO 7
  27.  
  28. int modem;
  29. struct sgbuf modem_opt, oldm_opt;
  30. unsigned char outbuff[300], inbuff[300];
  31. int signalman(), quit = 0;
  32. int monitor, beacon, command;
  33. struct {
  34.     int status;
  35.     int process;
  36.     int path_in, path_out;
  37.     int cpath_in, cpath_out;
  38.     int o_buffsize;
  39.     unsigned char o_linebuff[MAXPAC];
  40.     int i_buffsize;
  41.     unsigned char i_linebuff[MAXPAC];
  42.     } tasks[MAX_CHANNEL + 1];
  43. int channelnum;
  44. jmp_buf resync;
  45. char portstr[33];
  46.  
  47. main (argc, argv)
  48. char *argv[];
  49. {
  50.     int i, cnum, type, len, active;
  51.     unsigned char *p;
  52.     int status_disp, data_disp, data_send, data_ack, tries, state;
  53.     char str[40];
  54.     int foo;
  55.     
  56.     if (argc < 2) {
  57.         printf ("No modem specified\n");
  58.         exit (0);
  59.         }
  60.     if ((modem = open (argv[1], 3)) <= 0) exit (errno);
  61.     _gs_opt (modem, &oldm_opt);
  62.     if (oldm_opt.sg_class != 0) {
  63.         printf ("%s not an SCF-type device\n", argv[1]);
  64.         exit (0);
  65.         }
  66.     close (0);  dup (modem);    /* redirect standard I/O to TNC */
  67.     close (1);  dup (modem);    /* allows procs to show proc's port */
  68.     close (2);  dup (modem);
  69.     modem_opt.sg_parity = oldm_opt.sg_parity;
  70.     modem_opt.sg_baud = oldm_opt.sg_baud;
  71.     modem_opt.sg_tbl = oldm_opt.sg_tbl;
  72.     _ss_opt (modem, &modem_opt);
  73.     _ss_enrts (modem);
  74.     intercept (signalman);
  75.     strcpy (portstr, argv[1]+1);
  76.     strcpy (str, "/pipe/monitor.");
  77.     strcat (str, portstr);
  78.     if ((monitor = create (str, 043, 013, 512)) == -1)
  79.         monitor = open (str, 3);
  80.     _ss_size (monitor, 0);
  81.     strcpy (str, "/pipe/beacon.");
  82.     strcat (str, portstr);
  83.     if ((beacon = create (str, 043, 013, 512)) == -1)
  84.         beacon = open (str, 3);
  85.     _ss_size (beacon, 0);
  86.     strcpy (str, "/pipe/command.");
  87.     strcat (str, portstr);
  88.     if ((command = create (str, 043, 013, 512)) == -1)
  89.         command = open (str, 3);
  90.     _ss_size (command, 0);
  91.     setpr (getpid (), 100);
  92.     setjmp (resync);
  93.     sync ();
  94.     put_command (0, "MN");
  95.     put_command (0, "Y3");
  96.     for (channelnum = 1; put_command (channelnum, "L") < 2; channelnum++)
  97.         ;
  98.     channelnum--;
  99. log ("initialization complete, %d channels", channelnum);
  100.     while (!quit) {
  101.         /* check for monitored packets */
  102.         active = 0;
  103.         while ((type = put_command (0, "G")) != OK) {
  104.             active = 1;
  105.             if (type == MON_HDR1 || type == MON_HDR2)
  106.                 writemon (monitor, inbuff + 2, strlen (inbuff + 2));
  107.             else
  108.                 writemon (monitor, inbuff + 3, inbuff[2] + 1);
  109.             }
  110.         if ((len = _gs_rdy (beacon)) > 0) {
  111.             /* assemble and send UI beacon packet */
  112.             active = 1;
  113.             len = min (len, 255);
  114.             outbuff[0] = 0;
  115.             outbuff[1] = 0;
  116.             outbuff[2] = len - 1;
  117.             read (beacon, outbuff + 3, len);
  118.             write (modem, outbuff, outbuff[2] + 4);
  119.             gethost (inbuff);
  120.             }
  121.         if (_gs_rdy (command) > 0)
  122.             check_command ();
  123.  
  124.         for (cnum = channelnum; cnum > 0; cnum--)
  125.             if (tasks[cnum].process) break;
  126.         for (i = 1; i <= min (channelnum, cnum+1); i++) {
  127.             foo = 0;
  128.             /* check for packets on other channels */
  129.             while (1) {
  130.                 if (foo++ > 99) {
  131.                     log ("Too long in loop, type=%d, status=%d, proc=%d, paths=%d %d, ibsize=%d",
  132.                         type, tasks[i].status, tasks[i].process,
  133.                         tasks[i].path_in, tasks[i].path_out, tasks[i].i_buffsize);
  134.                     tasks[i].i_buffsize = 0;
  135.                     break;
  136.                     }
  137.                 if (tasks[i].i_buffsize && tasks[i].process)
  138.                     type = CON_INFO;    /* try to write previously received data */
  139.                 else {
  140.                     type = put_command (i, "G");
  141.                     if (type == OK) break;
  142.                     if (type == CON_INFO) {
  143.                         /* put incomming data in buffer (may not fit yet) */
  144.                         tasks[i].i_buffsize = inbuff[2] + 1;
  145.                         movmem (inbuff+3, tasks[i].i_linebuff,
  146.                                           tasks[i].i_buffsize);
  147.                         }
  148.                     }
  149.                 active = 1;
  150.                 if (tasks[i].status == MANUAL) {
  151.                     if (type == CON_INFO) {
  152.                         if (_gs_size (tasks[i].path_in) -
  153.                             _gs_rdy  (tasks[i].path_in) < tasks[i].i_buffsize)
  154.                             break;    /* not enough space yet */
  155.                         write (tasks[i].path_in, tasks[i].i_linebuff,
  156.                                                  tasks[i].i_buffsize);
  157.                         tasks[i].i_buffsize = 0;
  158.                         }
  159.                     else {
  160.                         write (tasks[i].cpath_in, inbuff + 2,
  161.                                 strlen (inbuff + 2));
  162.                         write (tasks[i].cpath_in, "\n", 1);
  163.                         }
  164.                     }
  165.                 else if (tasks[i].status != DISCONNECTED) {
  166.                     if (type == STATUS)
  167.                         check_status (i);
  168.                     else if (type == CON_INFO && tasks[i].process != 0) {
  169.                         if (_gs_size (tasks[i].path_in) -
  170.                             _gs_rdy  (tasks[i].path_in) < tasks[i].i_buffsize)
  171.                             break;    /* not enough space yet */
  172.                         write (tasks[i].path_in, tasks[i].i_linebuff,
  173.                                                  tasks[i].i_buffsize);
  174.                         for (p = tasks[i].i_linebuff;
  175.                              p - tasks[i].i_linebuff < tasks[i].i_buffsize; p++)
  176.                             if (*p == '\003')
  177.                                 kill (tasks[i].process, SIGINT);
  178.                         tasks[i].i_buffsize = 0;
  179.                         }
  180.                     }
  181.                 else
  182.                     check_connect (i);
  183.                 }
  184.  
  185.             if (tasks[i].status > DISCONNECTING) {
  186.                 put_command (i, "L");
  187.                 scan_status (&status_disp, &data_disp, &data_send, 
  188.                                 &data_ack, &tries, &state);
  189.                 }
  190.             if (tasks[i].status == TERMINATE && data_ack == 0) {
  191. log ("%d empty, disconnecting", i);
  192.                 put_command (i, "D");
  193.                 tasks[i].status = DISCONNECTING;
  194.                 }
  195.             
  196.             /* check for data from processes */
  197.             if (tasks[i].process != 0 && 
  198.                ((len = _gs_rdy (tasks[i].path_out)) > 0 || tasks[i].o_buffsize) &&
  199.                data_send <= 8) {
  200.  
  201.                 int tlen;
  202.  
  203.                 if (len == -1) len = 0;
  204.                 len = min (len, MAXPAC-tasks[i].o_buffsize);
  205.                 tlen = len + tasks[i].o_buffsize;
  206.                 outbuff[0] = i;
  207.                 outbuff[1] = 0;
  208.                 outbuff[2] = tlen - 1;
  209.                 movmem (tasks[i].o_linebuff, outbuff + 3, tasks[i].o_buffsize);
  210.                 if (len)
  211.                     read (tasks[i].path_out, outbuff + 3 + tasks[i].o_buffsize, len);
  212.                 for (p = outbuff + 3 + tlen - 1; p > outbuff + 3; p--)
  213.                     if (*p == '\n') break;
  214.                 if (*p == '\n') {
  215.                     /* Send up to newline, save the rest for later */
  216.                     tasks[i].o_buffsize = tlen - ((p - (outbuff + 3)) + 1);
  217.                     movmem (p+1, tasks[i].o_linebuff, tasks[i].o_buffsize);
  218.                     outbuff[2] -= tasks[i].o_buffsize;
  219.                     write (modem, outbuff, outbuff[2] + 4);
  220.                     if (gethost (inbuff) == 2) {
  221.                         log ("%d: %s", inbuff[0], inbuff + 2);
  222.                         goto full;
  223.                         }
  224.                     active = 1;
  225.                     }
  226.                 else if (tasks[i].o_buffsize > 0 && len == 0) {
  227.                     /* No newline, no new data, send saved data */
  228.                     write (modem, outbuff, outbuff[2] + 4);
  229.                     if (gethost (inbuff) == 2) {
  230.                         log ("%d: %s", inbuff[0], inbuff + 2);
  231.                         goto full;
  232.                         }
  233.                     tasks[i].o_buffsize = 0;
  234.                     active = 1;
  235.                     }
  236.                 else {
  237.                     /* No newline, save the data for next time */
  238. full:                tasks[i].o_buffsize = tlen;
  239.                     movmem (outbuff + 3, tasks[i].o_linebuff, tlen);
  240.                     }
  241.                 }
  242.             if (tasks[i].process != 0 && tasks[i].status == MANUAL &&
  243.                (len = _gs_rdy (tasks[i].cpath_out)) > 0) {
  244.                 char str[80];
  245.  
  246.                 readln (tasks[i].cpath_out, str, 80);
  247.                 str[len - 1] = '\0';
  248.                 if (put_command (i, str) != 0) {
  249.                     write (tasks[i].cpath_in, inbuff + 2,
  250.                             strlen (inbuff + 2));
  251.                     write (tasks[i].cpath_in, "\n", 1);
  252.                     }
  253.                 }
  254.             }
  255.         check_children ();
  256.         if (!active)
  257.             sleep (1);
  258.         }
  259. log ("terminating host mode");
  260.     put_command (0, "MN");
  261.     put_command (0, "Y0");
  262.     put_command (0, "JHOST0");
  263.     _ss_size (monitor, 0);
  264.     close (monitor);
  265.     _ss_size (beacon, 0);
  266.     close (beacon);
  267.     _ss_opt (modem, &modem_opt);
  268.     _ss_dsrts (modem);
  269.     exit (0);
  270.     }
  271.  
  272. check_connect (channel)
  273. {
  274.     char *p;
  275.     char w[20];
  276.     char sta[10];
  277.     char digi[8][10];
  278.     char *argv[10];
  279.     int i, d = 0;
  280.     int std_in, std_out, std_err;
  281.     extern int os9fork();
  282.     extern char **environ;
  283.  
  284.     if (inbuff[1] != 3) return;
  285.     p = (char *)inbuff + 2;
  286.     p += scanword (p, w);
  287.     p += scanword (p, w);
  288.     if (strcmp (w, "CONNECTED") != 0) return;
  289.     p += scanword (p, w);
  290.     if (strcmp (w, "to") != 0) return;
  291.     p += scanword (p, sta);
  292.     if (*p) {
  293.         p += scanword (p, w);
  294.         if (strcmp (w, "via") != 0) return;
  295.         for (d = 0; *p; d++)
  296.             p += scanword (p, digi[d]);
  297.         }
  298. log ("%s on channel %d", sta, channel);
  299.     argv[0] = "mailbox";    /* APPLICATION SPECIFIC:  Substitute appropriate program */
  300.     argv[1] = sta;
  301.     argv[2] = portstr;
  302.     for (i = 0; i < d; i++)
  303.         argv[i+3] = digi[i];
  304.     argv[i+3] = NULL;
  305.     std_in = dup (0);
  306.     close (0);
  307.     if (create ("/pipe", 043, 013, 2048) == -1) {
  308.         tasks[channel].status = TERMINATE;
  309. log ("error %d creating pipe (1)", errno);
  310.         return;
  311.         }
  312.     std_out = dup (1);
  313.     close (1);
  314.     if (create ("/pipe", 043, 013, 2048) == -1) {
  315.         tasks[channel].status = TERMINATE;
  316. log ("error %d creating pipe (2)", errno);
  317.         return;
  318.         }
  319.     std_err = dup (2);
  320.     close (2);
  321.     dup (1);
  322.     tasks[channel].process = 
  323.             os9exec (os9fork, argv[0], argv, environ, 0, 128, 3);
  324.     tasks[channel].path_in  = dup (0);
  325.     tasks[channel].path_out = dup (1);
  326.     tasks[channel].status = CONNECTED;
  327.     tasks[channel].cpath_in = tasks[channel].cpath_out = 0;
  328.     close (0); dup (std_in);  close (std_in);
  329.     close (1); dup (std_out); close (std_out);
  330.     close (2); dup (std_err); close (std_err);
  331.     if (tasks[channel].process <= 0) {
  332.         /* fork didn't succeed */
  333. log ("fork failed");
  334.         closepaths (channel);
  335.         tasks[channel].process = 0;
  336.         tasks[channel].status = TERMINATE;
  337.         }
  338.     if (strncmp (sta, "KB6GOZ", 6) == 0) {        /* FOO */
  339.         put_command (channel, "W64");
  340.         }
  341.     }
  342.  
  343. check_status (channel)
  344. {
  345.     char *p, w[20];
  346.  
  347.     p = (char *)inbuff + 2;
  348.     p += scanword (p, w);
  349.     p += scanword (p, w);
  350.     if (strcmp (w, "LINK") == 0) {
  351.         p += scanword (p, w);
  352.         if (strcmp (w, "FAILURE") != 0)
  353.             return;
  354.         }
  355.     else if (strcmp (w, "DISCONNECTED") != 0)
  356.         return;
  357. log ("disconnect %d", channel);
  358.     tasks[channel].status = DISCONNECTED;
  359.     if (tasks[channel].process != 0) {
  360.         if (tasks[channel].path_in) {
  361.             close (tasks[channel].path_in);
  362.             tasks[channel].path_in = 0;
  363.             }
  364.         tasks[channel].i_buffsize = 0;
  365.         tasks[channel].o_buffsize = 0;
  366.         }
  367.     }
  368.  
  369. scan_status (a, b, c, d, x, f)
  370. int *a, *b, *c, *d, *x, *f;
  371. {
  372.     char *p, w[20];
  373.  
  374.     p = (char *)inbuff + 2;
  375.     p += scanword (p, w);
  376.     *a = atoi (w);
  377.     p += scanword (p, w);
  378.     *b = atoi (w);
  379.     p += scanword (p, w);
  380.     *c = atoi (w);
  381.     p += scanword (p, w);
  382.     *d = atoi (w);
  383.     p += scanword (p, w);
  384.     *x = atoi (w);
  385.     p += scanword (p, w);
  386.     *f = atoi (w);
  387.     }
  388.  
  389. check_children ()
  390. {
  391.     int i, j, k;
  392.  
  393. start:
  394.     for (i = 1; i <= channelnum; i++)
  395.         if (tasks[i].process != 0 && _gs_eof (tasks[i].path_out) == 1 &&
  396.                 tasks[i].status != MANUAL) {
  397. log ("process %d eof", tasks[i].process);
  398.             j = wait (0);
  399.             if (j == -1) return;
  400.             for (k = 0; k < channelnum; k++)
  401.                 if (tasks[k].process == j) {
  402.                     tasks[k].process = 0;
  403.                     if (tasks[k].status > TERMINATE)
  404.                         tasks[k].status = TERMINATE;
  405.                     closepaths (k);
  406.                     }
  407.             goto start;
  408.             }
  409.     }
  410.  
  411. check_command ()
  412. {
  413.     char str[40], *p;
  414.     int len, pid, channel;
  415.  
  416.     len = readln (command, str, 40);
  417.     str[len - 1] = '\0';
  418.     pid = atoi (str + 1);
  419.     if (*str == 'o') {
  420.         /* open a manual control channel for this process */
  421.         for (channel = channelnum; channel > 0; channel--)
  422.             if (tasks[channel].process == 0) break;
  423.         if (channel == 0) return;
  424.         sprintf (str, "/pipe/data_in.%d", pid);
  425.         if ((tasks[channel].path_in = create (str, 043, 013, 2048)) == -1)
  426.             goto error;
  427.         sprintf (str, "/pipe/data_out.%d", pid);
  428.         if ((tasks[channel].path_out = create (str, 043, 013, 2048)) == -1)
  429.             goto error;
  430.         sprintf (str, "/pipe/ctl_in.%d", pid);
  431.         if ((tasks[channel].cpath_in = create (str, 043, 013, 2048)) == -1)
  432.             goto error;
  433.         sprintf (str, "/pipe/ctl_out.%d", pid);
  434.         if ((tasks[channel].cpath_out = create (str, 043, 013, 2048)) == -1)
  435.             goto error;
  436.         tasks[channel].process = pid;
  437.         tasks[channel].status = MANUAL;
  438.         return;
  439.         }
  440.     else if (*str == 'c') {
  441.         /* close a previously opened control channel */
  442.         for (channel = 1; channel <= channelnum; channel++)
  443.             if (tasks[channel].process == pid) break;
  444.         if (channel > channelnum) return;
  445.         if (tasks[channel].status != MANUAL) return;
  446.         closepaths (channel);
  447.         tasks[channel].status = DISCONNECTED;
  448.         tasks[channel].process = 0;
  449.         return;
  450.         }
  451.     else if (*str == 'm') {
  452.         put_command (0, str);
  453.         return;
  454.         }
  455.     else if (*str == 'u') {
  456.         *str = 'c';
  457.         put_command (0, str);
  458.         return;
  459.         }
  460.     else
  461.         return;
  462. error:
  463.     closepaths (channel);
  464.     log ("error %d creating pipe (3)", errno);
  465.     return;
  466.     }
  467.  
  468. closepaths (channel)
  469. {
  470.     if (tasks[channel].path_in) {
  471.         close (tasks[channel].path_in);
  472.         tasks[channel].path_in = 0;
  473.         }
  474.     if (tasks[channel].path_out) {
  475.         close (tasks[channel].path_out);
  476.         tasks[channel].path_out = 0;
  477.         }
  478.     if (tasks[channel].cpath_in) {
  479.         close (tasks[channel].cpath_in);
  480.         tasks[channel].cpath_in = 0;
  481.         }
  482.     if (tasks[channel].cpath_out) {
  483.         close (tasks[channel].cpath_out);
  484.         tasks[channel].cpath_out = 0;
  485.         }
  486.     tasks[channel].i_buffsize = 0;
  487.     tasks[channel].o_buffsize = 0;
  488.     }
  489.  
  490. scanword (s, d)
  491. char *s, *d;
  492. {
  493.     int num = 0;
  494.  
  495.     while (*s && *s == ' ') {
  496.         s++;
  497.         num++;
  498.         }
  499.     while (*s && *s != ' ') {
  500.         *d++ = *s++;
  501.         num++;
  502.         }
  503.     *d = '\0';
  504.     return (num);
  505.     }
  506.  
  507. writemon (path, str, len)
  508. char *str;
  509. {
  510.     if (_gs_size (path) - _gs_rdy (path) > len) {
  511.         write (path, str, len);
  512.         write (path, "\n", 1);
  513.         }
  514.     }
  515.  
  516. put_command (channel, cmd)
  517. char *cmd;
  518. {
  519.     outbuff[0] = channel;
  520.     outbuff[1] = 1;
  521.     outbuff[2] = strlen (cmd) - 1;
  522.     strcpy (outbuff+3, cmd);
  523.     write (modem, outbuff, outbuff[2] + 4);
  524.     return (gethost (inbuff));
  525.     }
  526.  
  527.  
  528. int syncing = 0;
  529.  
  530. sync ()
  531. {
  532.     int i;
  533.     char *syncstr = "INVALID COMMAND";
  534.  
  535.     syncing = 1;
  536.     if (write (modem, "\021\030\033", 3) == -1) exit (errno);
  537.     tsleep ((1<<31) | (3*25));
  538.     while (1) {
  539.         tsleep ((1<<31) | (25*2));
  540.         if ((i = _gs_rdy (modem)) == -1) break;
  541.         if (read (modem, inbuff, i) == -1) exit (errno);
  542.         }
  543.     if (write (modem, "JHOST 1\r", 8) == -1) exit (errno);
  544.     while (1) {
  545.         tsleep ((1<<31) | (25*2));
  546.         if ((i = _gs_rdy (modem)) == -1) break;
  547.         if (read (modem, inbuff, i) == -1) exit (errno);
  548.         }
  549.     while (1) {
  550.         while (_gs_rdy (modem) == -1) {
  551.             if (write (modem, "\001", 1) == -1) exit (errno);
  552.             tsleep ((1<<31) | (25*2));
  553.             }
  554.         gethost (inbuff);
  555.         if (*inbuff == 1 && *(inbuff+1) == 2 && 
  556.                 strncmp (inbuff+2, syncstr, strlen (syncstr)) == 0)
  557.             break;
  558.         }
  559.     syncing = 0;
  560.     }
  561.  
  562. gethost (buff)
  563. unsigned char *buff;
  564. {
  565.     unsigned char *p;
  566.     int i;
  567.     struct sgbuf errbuf;
  568.  
  569. /*    while (_gs_rdy (modem) < 2)
  570.         ; */
  571.     i = read (modem, buff, 2);
  572.     if (!syncing && *buff > MAX_CHANNEL || *(buff+1) > 7) {
  573.         log ("resync %d %d", *buff, *(buff+1));
  574.         longjmp (resync, 1);
  575.         }
  576. if (i != 2) 
  577.  if (i < 0) {
  578.   _gs_opt (modem, &errbuf);
  579.   log ("error %d %d", errno, errbuf.sg_err);
  580.   }
  581.  else log ("%d read %d", 1, i);
  582.      if (errno == 2) {
  583.          quit = 1;
  584.          return 0;
  585.          }
  586.     if (buff[1] == 0)
  587.         return (0);
  588.     else if (buff[1] < 6) {
  589.         p = buff+2;
  590.         while (1) {
  591.             i = read (modem, p, 1);
  592. if (i != 1)
  593.  if (i < 0) {
  594.   _gs_opt (modem, &errbuf);
  595.   log ("error %d %d", errno, errbuf.sg_err);
  596.   }
  597.  else log ("%d read %d", 2, i);
  598.              if (i != 1) break;
  599.             if (*p == '\0') break;
  600.             p++;
  601.             }
  602.         }
  603.     else {
  604.         i = read (modem, buff+2, 1);
  605. if (i != 1) 
  606.  if (i < 0) {
  607.   _gs_opt (modem, &errbuf);
  608.   log ("error %d %d", errno, errbuf.sg_err);
  609.   }
  610.  else log ("%d read %d", 3, i);
  611.         if (i == 1) i = read (modem, buff+3, buff[2]+1);
  612. if (i != buff[2]+1) 
  613.  if (i < 0) {
  614.   _gs_opt (modem, &errbuf);
  615.   log ("error %d %d", errno, errbuf.sg_err);
  616.   }
  617.  else log ("%d read %d", buff[2]+1, i);
  618.         }
  619.      if (errno == 2) {
  620.          quit = 1;
  621.          return 0;
  622.          }
  623.     return (buff[1]);
  624.     }
  625.     
  626.  
  627. /* Debugging code.  Not used in normal operation.
  628. host ()
  629. {
  630.     char line[100], *p;
  631.  
  632.     while (1) {
  633.         printf ("> ");
  634.         if (!gets (line)) return (0);
  635.         p = line;
  636.         if (*p == '*') {
  637.             outbuff[1] = 1;
  638.             p++;
  639.             }
  640.         else
  641.             outbuff[1] = 0;
  642.         if (*p <'0' || *p > '4') {
  643.             printf ("Illegal channel number\n");
  644.             continue;
  645.             }
  646.         outbuff[0] = *p - '0';
  647.         p++;
  648.         outbuff[2] = strlen (p) - 1;
  649.         strcpy (outbuff+3, p);
  650.         write (modem, outbuff, outbuff[2] + 4);
  651.         gethost (inbuff);
  652.         dump (inbuff);
  653.         }
  654.     }
  655.  
  656. dump (buff)
  657. char *buff;
  658. {
  659.     if (buff[1] == 0)
  660.         printf ("%d: <null>\n", buff[0]);
  661.     else if (buff[1] < 6)
  662.         printf ("%d: <%d> %s\n", buff[0], buff[1], buff+2);
  663.     else
  664.         printf ("%d: <%d> '%s'\n", buff[0], buff[1], buff+3);
  665.     }
  666. */
  667.  
  668. signalman (signal)
  669. {
  670.     switch (signal) {
  671. case SIGQUIT:
  672.         quit = 1;
  673.         break;
  674. default:
  675.         break;
  676.         
  677.         }
  678.     }
  679.  
  680. min (a, b)
  681. {
  682.     return ((a < b) ? a : b);
  683.     }
  684.  
  685. log (s, a, b, c, d, e, f, g, h)
  686. char *s;
  687. {
  688.     static int f = 0;
  689.     char *name = "/pipe/hostlog.";
  690.     char line[80];
  691.  
  692.     strcpy (line, name);
  693.     strcat (line, portstr);
  694.     if (f == 0) {
  695.         if ((f = create (line, 043, 013, 512)) == -1)
  696.             f = open (line, 3);
  697.         _ss_size (f, 0);
  698.         }
  699.     sprintf (line, s, a, b, c, d, e, f, g, h);
  700.     writemon (f, line, strlen (line));
  701.     }
  702.  
  703. movmem (from, to, count)
  704. register char *from, *to;
  705. register int count;
  706. {
  707.     if (from > to)
  708.         while (count--)
  709.             *to++ = *from++;
  710.     else {
  711.         from += count;
  712.         to += count;
  713.         while (count--)
  714.             *--to = *--from;
  715.         }
  716.     }
  717.  
  718.  
  719.