home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tel2305s.zip / NET14 / RUN14.C < prev    next >
C/C++ Source or Header  |  1991-10-25  |  25KB  |  864 lines

  1. #ifdef __TURBOC__
  2. #include "turboc.h"
  3. #endif
  4. #include <stdio.h>
  5. #include <conio.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <malloc.h>
  9. #include <dos.h>
  10. #include <ctype.h>
  11. #include <process.h>
  12. #include <errno.h>
  13. #ifdef MSC
  14. #include <direct.h>
  15. #include <signal.h>
  16. #include <time.h>
  17. #endif
  18.  
  19.  
  20. #ifdef MEMORY_DEBUG
  21. #include "memdebug.h"
  22. #endif
  23. #include "netevent.h"
  24. #include "hostform.h"
  25. #include "whatami.h"
  26. #include "netutils.h"
  27. #include "externs.h"
  28.  
  29. /* #define DEBUG */
  30.  
  31. /*
  32. *    Global variables
  33. */
  34. struct machinfo *mp;
  35. unsigned char parsedat[32];      /* character buffer to store network writes */
  36. extern unsigned char connected_flags;   /* flags indicating whether a port is connected yet */
  37.  
  38. extern unsigned char buf[256];
  39. #ifdef CHECKNULL
  40. extern unsigned char nullbuf[1024];     /* buffer for checking the NULL area */
  41. #endif
  42.  
  43. #define SERIAL  0x14
  44. #define NUM_COMM_PORTS  4   /* the number of comm. ports supported, remember to change this variable in int14.asm also */
  45.  
  46. /* Definitions for telnet protocol */
  47.  
  48. #define STNORM      0
  49.  
  50. #define SE            240
  51. #define NOP            241
  52. #define DM            242
  53. #define BREAK        243
  54. #define IP            244
  55. #define AO            245
  56. #define AYT            246
  57. #define EC            247
  58. #define EL            248
  59. #define GOAHEAD     249
  60. #define SB            250
  61. #define WILLTEL     251
  62. #define WONTTEL     252
  63. #define DOTEL         253
  64. #define DONTTEL     254
  65. #define IAC             255
  66.  
  67.  
  68. /* Assigned Telnet Options */
  69. #define BINARY                 0
  70. #define ECHO                1
  71. #define RECONNECT            2
  72. #define SGA                 3
  73. #define AMSN                4
  74. #define STATUS                5
  75. #define TIMING                6
  76. #define RCTAN                7
  77. #define OLW                    8
  78. #define OPS                    9
  79. #define OCRD                10
  80. #define OHTS                11
  81. #define OHTD                12
  82. #define OFFD                13
  83. #define OVTS                14
  84. #define OVTD                15
  85. #define OLFD                16
  86. #define XASCII                17
  87. #define LOGOUT                18
  88. #define BYTEM                19
  89. #define DET                    20
  90. #define SUPDUP                21
  91. #define SUPDUPOUT            22
  92. #define SENDLOC                23
  93. #define TERMTYPE             24
  94. #define EOR                    25
  95. #define TACACSUID            26
  96. #define OUTPUTMARK            27
  97. #define TERMLOCNUM            28
  98. #define REGIME3270            29
  99. #define X3PAD                30
  100. #define NAWS                31
  101. #define TERMSPEED            32
  102. #define TFLOWCNTRL            33
  103. #define LINEMODE             34
  104.     #define MODE 1
  105.         #define EDIT     1
  106.         #define TRAPSIG  2
  107.         #define MODE_ACK 4
  108.  
  109.     #define FORWARDMASK 2
  110.  
  111.     #define SLC 3 
  112.         #define NO_SUPPORT        0
  113.         #define CANTCHANGE        1
  114.         #define SLC_VALUE        2
  115.         #define SLC_DEFAULT        3
  116.         #define SLC_LEVELBITS    3
  117.         #define SLC_AWK            128
  118.  
  119.         #define SLC_SYNCH        1
  120.         #define SLC_BRK            2
  121.         #define SLC_IP            3
  122.         #define SLC_AO            4
  123.         #define SLC_AYT            5
  124.         #define SLC_EOR            6
  125.         #define SLC_ABORT        7
  126.         #define SLC_EOF            8
  127.         #define SLC_SUSP        9
  128.         #define SLC_EC            10
  129.         #define SLC_EL           11
  130.         #define SLC_EW           12
  131.         #define SLC_RP            13
  132.         #define SLC_LNEXT        14
  133.         #define SLC_XON            15
  134.         #define SLC_XOFF        16
  135.         #define SLC_FORW1        17
  136.         #define SLC_FORW2        18
  137. #define XDISPLOC            35
  138. #define XOPTIONS            255
  139.  
  140.     
  141. #define ESCFOUND 5
  142. #define IACFOUND 6
  143. #define NEGOTIATE 1
  144.  
  145. #ifdef DEBUG
  146. char *telstates[]={
  147.     "Subnegotiation End",
  148.     "NOP",
  149.     "Data Mark",
  150.     "Break",
  151.     "Interrupt Process",
  152.     "Abort Output",
  153.     "Are You There",
  154.     "Erase Character",
  155.     "Erase Line",
  156.     "Go Ahead",
  157.     "Subnegotiate",
  158.     "Will",
  159.     "Won't",
  160.     "Do",
  161.     "Don't"
  162. };
  163.  
  164. char *teloptions[256]={
  165.     "Binary",                /* 0 */
  166.     "Echo",
  167.     "Reconnection",
  168.     "Supress Go Ahead",
  169.     "Message Size Negotiation",
  170.     "Status",                /* 5 */
  171.     "Timing Mark",
  172.     "Remote Controlled Trans and Echo",
  173.     "Output Line Width",
  174.     "Output Page Size",
  175.     "Output Carriage-Return Disposition",    /* 10 */
  176.     "Output Horizontal Tab Stops",
  177.     "Output Horizontal Tab Disposition",
  178.     "Output Formfeed Disposition",
  179.     "Output Vertical Tabstops",
  180.     "Output Vertical Tab Disposition",        /* 15 */
  181.     "Output Linefeed Disposition",
  182.     "Extended ASCII",
  183.     "Logout",
  184.     "Byte Macro",
  185.     "Data Entry Terminal",                    /* 20 */
  186.     "SUPDUP",
  187.     "SUPDUP Output",
  188.     "Send Location",
  189.     "Terminal Type",
  190.     "End of Record",                        /* 25 */
  191.     "TACACS User Identification",
  192.     "Output Marking",
  193.     "Terminal Location Number",
  194.     "3270 Regime",
  195.     "X.3 PAD",                                /* 30 */
  196.     "Negotiate About Window Size",
  197.     "Terminal Speed",
  198.     "Toggle Flow Control",
  199.     "Linemode",
  200.     "X Display Location",                    /* 35 */
  201.     "36","37","38","39",
  202.     "40","41","42","43","44","45","46","47","48","49",
  203.     "50","51","52","53","54","55","56","57","58","59",
  204.     "60","61","62","63","64","65","66","67","68","69",
  205.     "70","71","72","73","74","75","76","77","78","79",
  206.     "80","81","82","83","84","85","86","87","88","89",
  207.     "90","91","92","93","94","95","96","97","98","99",
  208.     "100","101","102","103","104","105","106","107","108","109",
  209.     "110","111","112","113","114","115","116","117","118","119",
  210.     "120","121","122","123","124","125","126","127","128","129",
  211.     "130","131","132","133","134","135","136","137","138","139",
  212.     "140","141","142","143","144","145","146","147","148","149",
  213.     "150","151","152","153","154","155","156","157","158","159",
  214.     "160","161","162","163","164","165","166","167","168","169",
  215.     "170","171","172","173","174","175","176","177","178","179",
  216.     "180","181","182","183","184","185","186","187","188","189",
  217.     "190","191","192","193","194","195","196","197","198","199",
  218.     "200","201","202","203","204","205","206","207","208","209",
  219.     "210","211","212","213","214","215","216","217","218","219",
  220.     "220","221","222","223","224","225","226","227","228","229",
  221.     "230","231","232","233","234","235","236","237","238","239",
  222.     "240","241","242","243","244","245","246","247","248","249",
  223.     "250","251","252","253","254",
  224.     "Extended Options List"        /* 255 */
  225. };
  226.  
  227. char *LMoptions[]={
  228.     "None",
  229.     "SYNCH",
  230.     "BREAK",
  231.     "IP",
  232.     "ABORT OUTPUT",
  233.     "AYT",
  234.     "EOR",
  235.     "ABORT",
  236.     "EOF",
  237.     "SUSP",
  238.     "EC",
  239.     "EL",
  240.     "EW",
  241.     "RP",
  242.     "LNEXT",
  243.     "XON",
  244.     "XOFF",
  245.     "FORW1",
  246.     "FORW2"
  247. };
  248.  
  249. char *LMflags[]={
  250.     "NOSUPPORT",
  251.     "CANTCHANGE",
  252.     "VALUE",
  253.     "DEFAULT"
  254. };
  255. #endif
  256.  
  257.  
  258. static void int14parse(int comm_port,unsigned char *st,int cnt);
  259. static void int14parsewrite(int comm_port,char *dat,int len);
  260.  
  261. extern unsigned char port_buffer[NUM_COMM_PORTS][64];    /* four buffers to store the machine name to connect to */
  262. extern unsigned char buffer_offset[NUM_COMM_PORTS];      /* the offset into the buffer currently */
  263. extern int pnum[NUM_COMM_PORTS];                         /* the port number we are connected to */
  264.  
  265. extern volatile unsigned char *data_begin[NUM_COMM_PORTS];   /* pointers to the beginning of the data buffer for the comm.ports */
  266. extern unsigned char *data_max[NUM_COMM_PORTS];     /* pointers to the maximum value for the data_end pointers */
  267. extern volatile unsigned char *data_end[NUM_COMM_PORTS];     /* pointers to the end of the data buffer for the comm. ports */
  268. extern unsigned char *data_start[NUM_COMM_PORTS];   /* pointers to the start of the data buffer for the comm. ports */
  269.  
  270. extern int comm_port_index[NPORTS];     /* lookup table from a network port number to a comm port number */
  271. int telstate[NUM_COMM_PORTS];    /* the telnet state for each comm. port */
  272. int substate[NUM_COMM_PORTS];    /* the telnet substate for each comm. port */
  273. int igoahead[NUM_COMM_PORTS];
  274. int ugoahead[NUM_COMM_PORTS];
  275. int echo[NUM_COMM_PORTS];
  276. int timing[NUM_COMM_PORTS];
  277. static char c;
  278.  
  279. #ifndef DEBUG
  280. #ifdef __WATCOMC__
  281. void cdecl print_int(int num)
  282. #else
  283. void print_int(int num)
  284. #endif
  285. {
  286. #ifdef QAK
  287.     printf("number: %d:%x\n",num,num);
  288. #else
  289.     printf("number: %d:%x\t",num,num);
  290. #endif
  291. }   /* end print_int() */
  292.  
  293. #ifdef __WATCOMC__
  294. void cdecl print_int2(int num)
  295. #else
  296. void print_int2(int num)
  297. #endif
  298. {
  299.     printf("number2: %d:%x\n",num,num);
  300. }   /* end print_int2() */
  301. #endif
  302.  
  303. /*
  304. *   int14open
  305. *
  306. *   Entry :
  307. *       int comm_port - which comm port this connection is attached to
  308. *
  309. */
  310. #ifdef __WATCOMC__
  311. int cdecl int14open(int comm_port)
  312. #else
  313. int int14open(int comm_port)
  314. #endif
  315. {
  316.     int ev,what,dat;
  317.     char *errmsg;
  318.  
  319. #ifdef QAK
  320. printf("opening connection to: %s:%d\n",port_buffer[comm_port],comm_port);
  321. #endif
  322.     mp=gethostinfo(port_buffer[comm_port]);    /* look up in hosts cache, also checks for domain lookup */
  323. #ifdef QAK
  324. puts("after opening connection to the machine\n");
  325. #endif
  326.     if(!mp) {
  327.         puts("need to domain lookup!?!?\n");
  328.         return(0);          /* error return */
  329.       } /* end if */
  330.     else {
  331.         while((ev=Sgetevent(ERRCLASS,&what,&dat))!=0) { /* sift through the error events potentially generated by a domain lookup */
  332. #ifdef OLD_WAY
  333.             if(dat!=801 && dat!=805) {  /* filter out reports of using domain lookup */
  334.                 errmsg=neterrstring(dat);
  335.                 puts(errmsg);
  336.               } /* end if */
  337. #endif
  338.           } /* end while */
  339.         if(0>(pnum[comm_port]=Snetopen(mp,23))) {
  340. #ifdef QAK
  341.             errhandle();
  342. #else
  343.             puts("Network open failed");
  344. #endif
  345.             netshut();
  346.             return(0);
  347.           } /* end if */
  348.         comm_port_index[pnum[comm_port]]=comm_port;     /* assign the comm port to the TCP port number */
  349.       }
  350.     return(1);      /* indicate sucessful session opening */
  351. }   /* end int14open() */
  352.  
  353.  
  354. /*********************************************************************/
  355. /* int14process
  356. *  take incoming data and process it.  Close the connection if it
  357. *  is the end of the connection.
  358. */
  359. int int14process(int comm_port)
  360. {
  361.     int cnt;
  362.  
  363.     cnt=netread(pnum[comm_port],buf,64); /* get some from incoming queue */
  364.     if(cnt<0) {                    /* close this session, if over */
  365.         netclose(pnum[comm_port]);
  366.         return(0);
  367.       }
  368.  
  369.     if(cnt) 
  370.         int14parse(comm_port,buf,cnt);            /* display on screen, etc.*/
  371. #ifdef QAK
  372. puts("leaving int14process()");
  373. #endif
  374.     return(0);
  375. }
  376.  
  377. /*********************************************************************/
  378. /*  int14parse
  379. *   Do the telnet negotiation parsing.
  380. *
  381. *   look at the string which has just come in from outside and
  382. *   check for special sequences that we are interested in.
  383. *
  384. *   Tries to pass through routine strings immediately, waiting for special
  385. *   characters ESC and IAC to change modes.
  386. */
  387. void int14parse(int comm_port,unsigned char *st,int cnt)
  388. {
  389.     int i;
  390.     unsigned char *mark,*orig;
  391.  
  392.     orig=st;                /* remember beginning point */
  393.     mark=st+cnt;            /* set to end of input string */
  394.     netpush(pnum[comm_port]);
  395.  
  396. /*
  397. *  traverse string, looking for any special characters which indicate that
  398. *  we need to change modes.
  399. */
  400.     while(st<mark) {
  401.         switch(telstate[comm_port]) {
  402.             case ESCFOUND:
  403.                 int14parsewrite(comm_port,"\033",1);        /* send the missing ESC */
  404.                 telstate[comm_port]=STNORM;
  405.                 break;
  406.  
  407.             case IACFOUND:                 /* telnet option negotiation */
  408.                 if(*st==IAC) {            /* real data=255 */
  409.                     st++;                /* real 255 will get sent */
  410.                     telstate[comm_port]=STNORM;
  411.                     break;
  412.                   }
  413.  
  414.                 if(*st>239) {
  415.                     telstate[comm_port]=*st++; /* by what the option is */
  416.                     break;
  417.                   }
  418.  
  419. #ifdef DEBUG
  420.                 printf("strange telnet option %s\n",itoa(*st,parsedat,10));
  421. #endif
  422.                 orig=st;
  423.                 telstate[comm_port]=STNORM;
  424.                 break;
  425.  
  426.             case EL:        /* received a telnet erase line command */
  427.             case EC:        /* received a telnet erase character command */
  428.             case AYT:       /* received a telnet Are-You-There command */
  429.             case AO:        /* received a telnet Abort Output command */
  430.             case IP:        /* received a telnet Interrupt Process command */
  431.             case BREAK:     /* received a telnet Break command */
  432.             case DM:        /* received a telnet Data Mark command */
  433.             case NOP:       /* received a telnet No Operation command */
  434.             case SE:        /* received a telnet Subnegotiation End command */
  435. #ifdef DEBUG
  436.                 printf("RECV: %s\n",telstates[telstate[comm_port]-SE]);
  437. #endif
  438.                 telstate[comm_port]=STNORM;
  439.                 orig=st;
  440.                 break;
  441.  
  442.             case GOAHEAD:       /* telnet go ahead option*/
  443.                 telstate[comm_port]=STNORM;
  444.                 orig=st;
  445.                 break;
  446.  
  447.             case DOTEL:        /* received a telnet DO negotiation */
  448. #ifdef DEBUG
  449.                 printf("RECV: %s %s\n",telstates[telstate[comm_port]-SE],teloptions[*st]);
  450. #endif
  451.                 switch(*st) {
  452.                     case SGA:        /* Suppress go-ahead */
  453.                         if(igoahead[comm_port]) { /* suppress go-ahead */
  454. #ifdef DEBUG
  455.                             printf("SEND: %s %s\n",telstates[WILLTEL-SE],teloptions[*st]);
  456. #endif
  457.                             sprintf(parsedat,"%c%c%c",IAC,WILLTEL,*st);
  458.                             netwrite(pnum[comm_port],parsedat,3);  /* take it */
  459.                             igoahead[comm_port]=1;
  460.                           }
  461. #ifdef DEBUG
  462.                         else
  463.                             printf("NO REPLY NEEDED: %s %s\n",telstates[WILLTEL-SE],teloptions[SGA]);
  464. #endif
  465.                         telstate[comm_port]=STNORM;
  466.                         orig=++st;
  467.                         break;
  468.  
  469.                     default:
  470. #ifdef DEBUG
  471.                         printf("SEND: %s %s\n",telstates[WONTTEL-SE],teloptions[*st]);
  472. #endif
  473.                         sprintf(parsedat,"%c%c%c",IAC,WONTTEL,*st++);
  474.                         netwrite(pnum[comm_port],parsedat,3);  /* refuse it */
  475.                         telstate[comm_port]=STNORM;
  476.                         orig=st;
  477.                           break;
  478.  
  479.                 }
  480.                 break;
  481.  
  482.             case DONTTEL:        /* Received a telnet DONT option */
  483. #ifdef DEBUG
  484.                 printf("RECV: %s %s\n",telstates[telstate[comm_port]-SE],teloptions[*st]);
  485. #endif
  486.                 telstate[comm_port]=STNORM;
  487.                 orig=++st;
  488.                 break;
  489.  
  490.             case WILLTEL:        /* received a telnet WILL option */
  491. #ifdef DEBUG
  492.                 printf("RECV: %s %s\n",telstates[telstate[comm_port]-SE],teloptions[*st]);
  493. #endif
  494.                 telstate[comm_port]=STNORM;
  495.                 switch(*st++) {
  496.                     case SGA:                    /* suppress go-ahead */
  497.                         if(ugoahead[comm_port])
  498.                             break;
  499.  
  500.                         ugoahead[comm_port]=1;
  501. #ifdef DEBUG
  502.                         printf("SEND: %s %s\n",telstates[DOTEL-SE],teloptions[*st]);
  503. #endif
  504.                         sprintf(parsedat,"%c%c%c",IAC,DOTEL,3);    /* ack */
  505.                         netwrite(pnum[comm_port],parsedat,3);
  506.                         break;
  507.  
  508.                     case ECHO:                        /* echo */
  509.                         if(echo[comm_port])
  510.                             break;
  511.  
  512.                         echo[comm_port]=1;
  513. #ifdef DEBUG
  514.                         printf("SEND: %s %s\n",telstates[DOTEL-SE],teloptions[*st]);
  515. #endif
  516.                         sprintf(parsedat,"%c%c%c",IAC,DOTEL,1);    /* ack */
  517.                         netwrite(pnum[comm_port],parsedat,3);
  518.                         break;
  519.  
  520.                     case TIMING:        /* Timing mark */
  521.                         timing[comm_port]=0;
  522.                         break;
  523.  
  524.                     default:
  525. #ifdef DEBUG
  526.                         printf("SEND: %s %s\n",telstates[DONTTEL-SE],teloptions[*st]);
  527. #endif
  528.                         sprintf(parsedat,"%c%c%c",IAC,DONTTEL,*(st-1));
  529.                         netwrite(pnum[comm_port],parsedat,3);  /* refuse it */
  530.                         break;
  531.                   } /* end switch */
  532.                 orig=st;
  533.                 break;
  534.                             
  535.             case WONTTEL:        /* Received a telnet WONT option */
  536. #ifdef DEBUG
  537.                 printf("RECV: %s %s\n",telstates[telstate[comm_port]-SE],teloptions[*st]);
  538. #endif
  539.                 telstate[comm_port]=STNORM;
  540.                 switch(*st++) {            /* which option? */
  541.                     case ECHO:                /* echo */
  542.                         if(echo[comm_port])
  543.                             break;
  544.  
  545.                         echo[comm_port]=0;
  546.                         sprintf(parsedat,"%c%c%c",IAC,DONTTEL,ECHO);
  547.                         netwrite(pnum[comm_port],parsedat,3);  /* OK with us */
  548.                         break;
  549.  
  550.                     case TIMING:    /* Telnet timing mark option */
  551.                         timing[comm_port]=0;
  552.                         break;
  553.  
  554.                     default:
  555.                         break;
  556.                   }
  557.                 orig=st;
  558.                 break;
  559.  
  560.             case SB:        /* telnet sub-options negotiation */
  561.                 telstate[comm_port]=NEGOTIATE;
  562.                 orig=st;
  563.                 i=substate[comm_port]=0;               /* Defined for each */
  564.                 break;
  565.  
  566.             case NEGOTIATE:
  567.                 if(substate[comm_port]<200) {
  568.                     switch(*st) {
  569.                         case IAC:
  570.                             if(*(st+1)==IAC) {    /* skip over double IAC's */
  571.                                 parsedat[i++]=*st++;
  572.                                 parsedat[i++]=*st++;
  573.                               } /* end if */
  574.                             else {
  575.                                 parsedat[i]='\0';
  576.                                 substate[comm_port]=*st++;
  577.                               } /* end else */
  578.                             break;
  579.  
  580.                         default:
  581.                             parsedat[i++]=*st++;
  582.                             break;
  583.                       }    /* end switch */
  584.                   }    /* end if */
  585.                 else {
  586.                     switch(substate[comm_port]) {
  587.                         case IAC:
  588.                             substate[comm_port]=*st++;
  589.                             orig=st;
  590.                             telstate[comm_port]=STNORM;
  591.                             break;
  592.  
  593.                         default:
  594.                             orig=st;
  595.                             telstate[comm_port]=STNORM;
  596.                             break;
  597.                       }    /* end switch */
  598.                   }    /* end else */
  599.                 break;
  600.  
  601.             default:
  602.                 telstate[comm_port]=STNORM;
  603.                 break;
  604.         }
  605.  
  606. /*
  607. * quick scan of the remaining string, skip chars while they are
  608. * uninteresting
  609. */
  610.         if(telstate[comm_port]==STNORM) {
  611. /*
  612. *  skip along as fast as possible until an interesting character is found
  613. */
  614.             while(st<mark && *st!=27 && *st<IAC) {
  615. /* #ifdef EIGHT_BIT_CLEAN */
  616. /*                if(!tw->binary) */
  617.                     *st &= 127;                    /* mask off high bit */
  618. /* #endif */
  619.                 st++;
  620.               }
  621.             if(!timing[comm_port] && st>orig)
  622.                 int14parsewrite(comm_port,orig,st-orig);
  623.             orig=st;                /* forget what we have sent already */
  624.             if(st<mark)
  625.                 switch (*st) {
  626.                     case IAC:            /* telnet IAC */
  627.                         telstate[comm_port]=IACFOUND;
  628.                         st++;
  629.                         break;
  630.  
  631.                     case 27:            /* ESCape code */
  632.                         if(st==mark-1 || *(st+1)==12 || *(st+1)=='^')
  633.                             telstate[comm_port]=ESCFOUND;
  634.                         st++;            /* strip or accept ESC char */
  635.                         break;
  636.  
  637. #ifdef DEBUG
  638.                     default:
  639. #ifdef QAK
  640.                         vprint(cv," strange char>128\r\n");
  641. #else
  642.                         puts("strange char>128\n");
  643. #endif
  644.                         st++;
  645.                         break;
  646. #endif
  647.                   }    /* end switch */
  648.           }    /* end if */
  649.     }  /* end while */
  650. #ifdef QAK
  651. puts("leaving int14parse()");
  652. #endif
  653. }
  654.  
  655. /*********************************************************************/
  656. /*  int14parsewrite
  657. *   write out some chars from parse
  658. *   Has a choice of where to send the stuff
  659. */
  660. void int14parsewrite(int comm_port,char *dat,int len)
  661. {
  662.     int i;      /* local counting variable */
  663.  
  664.     for(i=0; i<len; i++) {
  665. #ifdef QAK
  666. buffer_stat++;
  667. if(buffer_stat>max_buffer_stat)
  668.     max_buffer_stat=buffer_stat;
  669. printf("buffer_stat=%d, max_buffer_stat=%d\n",buffer_stat,max_buffer_stat);
  670. #endif
  671. #ifdef DEBUG
  672. printf("data_end[%d]=%p, data_begin[%d]=%p\n",comm_port,data_end[comm_port],comm_port,data_begin[comm_port]);
  673. #endif
  674.         *data_end[comm_port]++=dat[i];    /* store the character in the appropriate character buffer */
  675.         if(data_end[comm_port]>=data_max[comm_port])    /* check if we went off the end of the buffer */
  676.             data_end[comm_port]=data_start[comm_port];  /* wrap back to the beginning */
  677.         if(data_end[comm_port]==data_begin[comm_port]) {    /* check if we are going to wrap around */
  678. #ifdef DEBUG
  679. printf("data_end[%d] pushed data_begin[%d]\n",comm_port,comm_port);
  680. #endif
  681.             data_begin[comm_port]++;    /* lose data at the beginning of the buffer */
  682.             if(data_begin[comm_port]>=data_max[comm_port])    /* check if we went off the end of the buffer */
  683.                 data_begin[comm_port]=data_start[comm_port];   /* wrap back to the beginning */
  684.           } /* end if */
  685.       } /* end for */
  686. #ifdef DEBUG
  687. printf("b:data_end[%d]=%p, data_begin[%d]=%p\n",comm_port,data_end[comm_port],comm_port,data_begin[comm_port]);
  688. #endif
  689. }
  690.  
  691. /*********************************************************************/
  692. /*  get_comm_char
  693. *   used by the interrupt service routine to get characters from the
  694. *       comm. buffers
  695. */
  696. #ifdef __WATCOMC__
  697. int cdecl get_comm_char(int comm_port)
  698. #else
  699. int get_comm_char(int comm_port)
  700. #endif
  701. {
  702.     int i;      /* local counting variable */
  703.  
  704.     while(data_end[comm_port]==data_begin[comm_port]);  /* wait for a character */
  705. #ifdef QAK
  706. buffer_stat--;
  707. #endif
  708.     i=*data_begin[comm_port]++;
  709.     if(data_begin[comm_port]>=data_max[comm_port])
  710.         data_begin[comm_port]=data_start[comm_port];
  711.     return(i);
  712. }
  713.  
  714. /*********************************************************************/
  715. /*  int14netsleep
  716. *   manage the network in the background, grabs packets from the network
  717. *   Has a choice of where to send the stuff
  718. */
  719. #ifdef __WATCOMC__
  720. void cdecl int14netsleep(void)
  721. #else
  722. void int14netsleep(void)
  723. #endif
  724. {
  725.     int ev,what,dat;
  726.     char *errmsg;
  727.  
  728. #ifdef DEBUG
  729. printf("int14netsleep().a: stackavail=%u\n",stackavail());
  730. #endif
  731. #ifdef CHECKNULL
  732. /* If we are running in NULL debugging mode, check that */
  733.     if(memcmp(nullbuf,MK_FP(0x0,0x0),1024)) {
  734.         unsigned u;
  735.         unsigned char *s;
  736.  
  737.         s=MK_FP(0x0,136);
  738.         if(*s!=nullbuf[136]) {
  739.             nullbuf[136]=*s++;
  740.             nullbuf[137]=*s++;
  741.             nullbuf[138]=*s++;
  742.             nullbuf[139]=*s;
  743.           } /* end if */
  744.         else {
  745.             puts("NULL overwritten!");
  746.             s=MK_FP(0x0,0x0);
  747.             for(u=0; u<1024; u++,s++)
  748.                 if(*s!=nullbuf[u])
  749.                     printf("s=%p, u=%u, val=%u\n",s,u,(unsigned int)*s);
  750.             getch();
  751.           } /* end else */
  752.       } /* end if */
  753. #endif
  754.  
  755. /* check to make certain we are actually connected to the network before
  756. *   dealing with network events
  757. */
  758.     if(!connected_flags)    /* if any ports are connected, we have to parse data */
  759.         return;
  760.                
  761. /*
  762. *  get event from network, these two classes return all of the events
  763. *  of user interest.
  764. */
  765. #ifdef QAK
  766.     ev=Sgetevent(USERCLASS | CONCLASS | ERRCLASS,&what,&dat);
  767. #else
  768.     ev=Sgetevent(CONCLASS | ERRCLASS,&what,&dat);
  769. #endif
  770.     if(!ev) {
  771. #ifdef DEBUG
  772. printf("int14netsleep().b: stackavail=%u\n",stackavail());
  773. #endif
  774.         return;
  775.       } /* end if */
  776.     if(what==ERRCLASS) {                /* error event */
  777. #ifdef OLD_WAY
  778.         errmsg=neterrstring(dat);
  779.         puts(errmsg);       /* ifdef'ed out because of messing up DOS */
  780. #endif
  781.       }
  782.     else
  783.         if(what==CONCLASS) {        /* event of user interest */
  784.             switch (ev) {
  785.                 case CONOPEN:               /* connection opened or closed */
  786. #ifdef DEBUG
  787. puts("CONOPEN received");
  788. #endif
  789.                     netpush(dat);           /* negotiation */
  790.                     netwrite(dat,"\377\375\001\377\375\003\377\374\030",9);
  791.                     break;
  792.  
  793.                 default:
  794.                     break;
  795.  
  796.                 case CONDATA:               /* data arrived for me */
  797. #ifdef OLD_WAY
  798.                     cnt=netread(dat,buf,80);
  799.                     for(i=0; i<cnt; i++)
  800.                         if(buf[i]<128)
  801.                             putchar(buf[i]);
  802. #else
  803. #ifdef QAK
  804. puts("int14netsleep: data received\n");
  805. #endif
  806.                     if(int14process(comm_port_index[dat]))
  807.                         c=16;       /* break out of the loop */
  808. #endif
  809.                     break;
  810.  
  811.                 case CONFAIL:
  812. #ifdef DEBUG
  813. puts("CONFAIL received");
  814. #endif
  815. #ifdef DEBUG
  816.                     puts("Connection attempt failed");
  817. #endif
  818.                                         /* drop through to exit */
  819.  
  820.                 case CONCLOSE:
  821. #ifdef DEBUG
  822. puts("CONCLOSE received");
  823. #endif
  824. #ifdef QAK
  825.                     netshut();
  826.                     exit(1);
  827. #else
  828.                     c=16;
  829. #endif
  830.                 }
  831.             }
  832. #ifdef QAK
  833.         else
  834.             if(what==USERCLASS) {
  835.                 switch (ev) {
  836.                     case DOMOK:                         /* domain worked */
  837. #ifdef DEBUG
  838. puts("DOMOK received");
  839. #endif
  840.                         mp=Slooknum(dat);               /* get machine info */
  841.                         pnum[PORT]=Snetopen(mp,23);           /* open to host name */
  842.                         break;
  843.  
  844.                     case DOMFAIL:   /* domain failed */
  845. #ifdef DEBUG
  846.                         n_puts("domain failed");
  847. #endif
  848. #ifdef QAK
  849.                         netshut();
  850.                         exit(1);
  851. #else
  852.                         c=16;
  853. #endif
  854.                     default:
  855.                         break;
  856.                   }
  857.               }
  858. #endif
  859. #ifdef DEBUG
  860. printf("int14netsleep().c: stackavail=%u\n",stackavail());
  861. #endif
  862. }
  863.  
  864.