

#include <aes.h>
#include <tos.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#include "transprt.h"

#define  UINT8      0
#define  INT8       1
#define  UINT16     2
#define  INT16      3
#define  UINT32     4
#define  INT32      5
#define  STRING     6


DRV_HDR *  cdecl  my_get_dftab (char *drv_name);
char *     cdecl  my_KRmalloc (int32 length);
void       cdecl  my_KRfree (char *mem_block);
int32      cdecl  my_KRgetfree (int16 flag);
char *     cdecl  my_KRrealloc (char *mem_block, int32 length);
int16      cdecl  my_TCP_open (uint32 rem_host, int16 rem_port, int16 tos, uint16 size);
int16      cdecl  my_TCP_close (int16 connec, int16 timeout);
int16      cdecl  my_TCP_send (int16 connec, char *buffer, int16 length);
int16      cdecl  my_TCP_wait_state (int16 connec, int16 state, int16 timeout);
int16      cdecl  my_TCP_ack_wait (int16 connec, int16 timeout);
int16      cdecl  my_UDP_open (uint32 rem_host, int16 rem_port);
int16      cdecl  my_UDP_close (int16 connec);
int16      cdecl  my_UDP_send (int16 connec, char *buffer, int16 length);
int16      cdecl  my_CNkick (int16 connec);
int16      cdecl  my_CNbyte_count (int16 connec);
int16      cdecl  my_CNget_char (int16 connec);
NDB *      cdecl  my_CNget_NDB (int16 connec);
int16      cdecl  my_CNget_block (int16 connec, char *block, int16 length);
CIB *      cdecl  my_CNget_info (int16 connec);
int16      cdecl  my_resolve (char *domain, char **real, uint32 *ip_list, int16 ip_num);
int16      cdecl  my_g_resolve (char *domain, char **real, uint32 *ip_list, int16 ip_num);
int16      cdecl  my_setvstr (char name[], char value[]);
char *     cdecl  my_getvstr (char name[]);
int16      cdecl  my_on_port (char *port);
void       cdecl  my_off_port (char *port);
int16      cdecl  my_query_port (char *port);
void       cdecl  my_ser_disable (void);
void       cdecl  my_ser_enable (void);
int16      cdecl  my_set_flag (int16 flag);
void       cdecl  my_clear_flag (int16 flag);
char *     cdecl  my_get_err_text (int16 error);
int16      cdecl  my_carrier_detect (void);
void       cdecl  my_housekeep (void);

long    get_stik_cookie (void);
void    install (void);
long    deinstall (void);
char *  get_error (int16 error);
void    write_log_text (char *text);
void    write_function (char *name);
void    write_parameter (char *name, int type, void *value, char *supple);
void    write_buffer (char *buffer, int length);


extern  BASPAG  *_BasPag;

DRV_LIST  *stik_drivers;
TPL       *stik_tpl, *tpl, my_tpl;
DRV_HDR   *cdecl  (*old_get_dftab) (char *drv_name);
long      retnd;
int       handle, index, num, count, byte;
char      path[256];
char      line[100], val_str[32], supp[32], hex_line[50], hex[5], ascii[20];

char      type_txt[][9] = { "(uint8)", "(int8)", "(uint16)", "(int16)", "(uint32)",
                            "(int32)", "(string)"   };

char      errors[][16]  = { "E_NORMAL", "E_OBUFFULL", "E_NODATA", "E_EOF", "E_RRESET", 
                 "E_UA", "E_NOMEM", "E_REFUSE", "E_BADSYN", "E_BADHANDLE", "E_LISTEN", 
                 "E_NOCCB", "E_NOCONNECTION", "E_CONNECTFAIL", "E_BADCLOSE", 
                 "E_USERTIMEOUT", "E_CNTIMEOUT", "E_CANTRESOLVE", "E_BADDNAME", 
                 "E_LOSTCARRIER", "E_NOHOSTNAME", "E_DNSWORKLIMIT", "E_NONAMESERVER", 
                 "E_DNSBADFORMAT", "E_UNREACHABLE", "E_DNSNOADDR", "E_NOROUTINE", 
                 "E_LOCKED", "E_FRAGMENT", "E_TTLEXCEED"   };

char  not_there[] = "[1][ |  STiK is not loaded or enabled !   ][ Hmmm ]";
char  corrupted[] = "[1][ |  STiK structures corrupted !   ][ Fuck ]";
char  found_it[]  = "[3][ |  Driver \'%s\',|  by %s, found,   |  version %s.][ Okay ]";
char  no_module[] = "[1][ |  STiK Transport Driver not found !   ][ Grmbl ]";
char  itsthere[]  = "[1][ |  LogSTiK already installed !   ][ Ooops ]";
char  installed[] = "[3][ |  LogSTiK debugging tool    | |    installed ...][ Okay ]";



void  main()

{
   char  alert[256];

   appl_init();

   stik_drivers = (DRV_LIST *) Supexec (get_stik_cookie);

   if (stik_drivers == 0L) {
        form_alert (1, not_there);
        return;
      }
   if (strcmp (stik_drivers->magic, MAGIC) != 0) {
        form_alert (1, corrupted);
        return;
      }

   if ((long) (*stik_drivers->get_dftab) ("LOGSTIK?") == 'Here') {
        form_alert (1, itsthere);
        return;
      }
   stik_tpl = (TPL *) (*stik_drivers->get_dftab) (TRANSPORT_DRIVER);

   if (stik_tpl != (TPL *) NULL) {
        sprintf (alert, found_it, stik_tpl->module, stik_tpl->author, stik_tpl->version);
        form_alert (1, alert);
        install();
        form_alert (1, installed);
        appl_exit();
        Ptermres (_PgmSize, 0);
      }
     else {
        form_alert (1, no_module);
        appl_exit();
      }
 }


long  get_stik_cookie()

{
   long  *work;

   for (work = * (long **) 0x5a0L; *work != 0L; work += 2)
        if (*work == 'STiK')
             return (*++work);

   return (0L);
 }


void  install()

{
   path[0] = 'A' + Dgetdrv();
   path[1] = ':';
   Dgetpath (& path[2], 0);
   strcat (path, "\\STIK.LOG");

   tpl = & my_tpl;

   memcpy (tpl, stik_tpl, sizeof (TPL));

   stik_tpl->KRmalloc       = my_KRmalloc;
   stik_tpl->KRfree         = my_KRfree;
   stik_tpl->KRgetfree      = my_KRgetfree;
   stik_tpl->KRrealloc      = my_KRrealloc;
   stik_tpl->TCP_open       = my_TCP_open;
   stik_tpl->TCP_close      = my_TCP_close;
   stik_tpl->TCP_send       = my_TCP_send;
   stik_tpl->TCP_wait_state = my_TCP_wait_state;
   stik_tpl->TCP_ack_wait   = my_TCP_ack_wait;
   stik_tpl->UDP_open       = my_UDP_open;
   stik_tpl->UDP_close      = my_UDP_close;
   stik_tpl->UDP_send       = my_UDP_send;
   stik_tpl->CNkick         = my_CNkick;
   stik_tpl->CNbyte_count   = my_CNbyte_count;
   stik_tpl->CNget_char     = my_CNget_char;
   stik_tpl->CNget_NDB      = my_CNget_NDB;
   stik_tpl->CNget_block    = my_CNget_block;
   stik_tpl->CNgetinfo      = my_CNget_info;
   stik_tpl->resolve        = my_resolve;
   stik_tpl->g_resolve      = my_g_resolve;
   stik_tpl->setvstr        = my_setvstr;
   stik_tpl->getvstr        = my_getvstr;
   stik_tpl->on_port        = my_on_port;
   stik_tpl->off_port       = my_off_port;
   stik_tpl->query_port     = my_query_port;
   stik_tpl->ser_disable    = my_ser_disable;
   stik_tpl->ser_enable     = my_ser_enable;
   stik_tpl->set_flag       = my_set_flag;
   stik_tpl->clear_flag     = my_clear_flag;
   stik_tpl->get_err_text   = my_get_err_text;
   stik_tpl->carrier_detect = my_carrier_detect;
   stik_tpl->housekeep      = my_housekeep;

   old_get_dftab = stik_drivers->get_dftab;
   stik_drivers->get_dftab = my_get_dftab;
 }


long  deinstall()

{
   stik_drivers->get_dftab = old_get_dftab;

   memcpy (stik_tpl, tpl, sizeof (TPL));

   Mfree (_BasPag->p_env);
   Mfree (_BasPag);

   return (0L);
 }


char *  get_error (error)

int16  error;

{
   error *= -1;

   if (error <= 0 || E_LASTERROR < error)
        return ("");

   return (errors[error]);
 }


void  write_log_text (text)

char  *text;

{
   if ((retnd = Fopen (path, FO_RW)) < 0)
        if ((retnd = Fcreate (path, 0)) < 0)   return;

   handle = (int) retnd;

   Fseek (0, handle, 2);
   Fwrite (handle, strlen (text), text);
   Fwrite (handle, 2L, "\r\n");
   Fclose (handle);
 }


void  write_function (name)

char  *name;

{
   sprintf (line, "\r\nCall to \'%s\'. Parameter :", name);

   write_log_text (line);
 }


void  write_parameter (name, type, value, supple)

char  *name, *supple;
int   type;
void  *value;

{
   uint32  number;

   switch (type) {
      case UINT8 :
        number = * ((uint8 *) value);
        sprintf (val_str, "%u ($%x)", (uint16) number, (uint16) number);
        break;
      case INT8 :
        sprintf (val_str, "%d", (int16) * ((int8 *) value));
        break;
      case UINT16 :
        number = * ((uint16 *) value);
        sprintf (val_str, "%u ($%x)", (uint16) number, (uint16) number);
        break;
      case INT16 :
        sprintf (val_str, "%d",  * ((int16 *) value));
        break;
      case UINT32 :
        number = * ((uint32 *) value);
        sprintf (val_str, "%lu ($%lx)", number, number);
        break;
      case INT32 :
        sprintf (val_str, "%ld", * ((int32 *) value));
        break;
      case STRING :
        strcpy (val_str, (char *) value);
        break;
      }

   if (*supple) {
        supp[0] = '(';   strcpy (& supp[1], supple);   strcat (supp, ")");
      }
     else   supp[0] = '\0';

   sprintf (line, "   %-16s %10s  :  %s  %s", name, type_txt[type], val_str, supp);

   write_log_text (line);
 }


void  write_buffer (buffer, length)

char  *buffer;
int   length;

{
   if (buffer == NULL)   return;

   for (index = 0; index < length; index += 16) {
        num = length - index;
        if (num > 16)   num = 16;
        hex_line[0] = '\0';
        for (count = 0; count < num; count++) {
             byte = (int) *((unsigned char *) buffer + index + count);
             sprintf (hex, " %02x", byte);
             strcat (hex_line, hex);
             if (byte < 32 || 127 < byte)   byte = '.';
             ascii[count] = byte;
           }
        ascii[count] = '\0';
        sprintf (line, "     $%04x : %-48s \'%s", index, hex_line, ascii);
        write_log_text (line);
      }
 }
