#include "tpt.h"

///   Variables
long                tptflags = 0;
long                myportsig = 0;
long                readsersig = 0;
long                timersig = 0;
long                controlsig = 0;
long                consolesig = 0;

SHORT               aux_avail = 0;
SHORT               in_len = 0;
SHORT               num_times = 0;
SHORT               num_kills = 0;
SHORT               time_delay = 0;
SHORT               TScrDepth = 0;

UBYTE               in_c;
UBYTE               cin_c;
UBYTE               localflag = FALSE;
UBYTE               inline = FALSE;
UBYTE               BadFlag = FALSE;

struct IOExtSer    *ReadSER = NULL;
struct MsgPort     *RSPort = NULL;
struct IOExtSer    *WriteSER = NULL;
struct MsgPort     *WSPort = NULL;

struct IOStdReq    *consoleWriteMsg = NULL;
struct MsgPort     *consoleWritePort = NULL;
struct IOStdReq    *consoleReadMsg = NULL;
struct MsgPort     *consoleReadPort = NULL;
struct Screen      *TScrn = NULL;
struct Window      *TWind = NULL;
struct TextFont    *tf = NULL;
struct TextAttr     ta;

struct timerequest *Timer = NULL;
struct MsgPort     *Timer_Port = NULL;

struct MsgPort     *ctrl_port = NULL;
struct MsgPort     *drport = NULL;
struct MsgPort     *dport = NULL;
struct ctrl_mess   *ctlmsg = NULL;


UWORD               colortable[8] =
{
   0x000, 0xf00, 0x0f0, 0xff0, 0x00f, 0xf0f, 0x0ff, 0xfff}
;


struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase     *GfxBase = NULL;

UBYTE               conwrname[14];
UBYTE               conrdname[13];
UBYTE               dname[10];
UBYTE               fontname[41];
UBYTE               tdevname[4];

UBYTE               intrans[256];
UBYTE               outtrans[256];
char                hackstring[8] = "[3xm";

UBYTE               whichbuf = 0;
UBYTE               cursoron = 1;
UBYTE               mybuf[3][AUXBUFSIZE];

static ULONG        dummy1 = 0xebadc0de;
//-

///   Protection Variables
static char         DLGCookie[4] = ":-)";

// LICENSE SEEKS TO RIGHT HERE, AFTER THE COOKIE, THEN MOVES 131 BYTES
static ULONG        dummy2 = 0xebadc0de;
static char         DLGShortName[26] = DLGSHORTNAME;  // 26 bytes
static char         DLGLongName[80] = DLGLONGNAME;    // 80 bytes,106
static char         DLGCompileDate[20] = "###################";   // 20 bytes,126

static UBYTE        version[21] = "$$$$$$$$$$$$$$$$$$$$";
static char         z = 'Z';
static char         zz[4] = "   ";
static UBYTE        NEW_SN[4] = "\002--";
static UBYTE        XOR_NEW_SN[4] = "\003--";
static UBYTE        DLGOwner[80] = "###############################################################";
static UBYTE        DLGPirate[80] = "###############################################################";
static char         zzz[4] = "   ";
//-

///   More variables
short               DLGVersion = 1;    // 2 bytes
short               DLGRevision = 16;   // 2 bytes,4

UBYTE               crc;
UBYTE               crcsub;
UBYTE               mysub;
UBYTE               crcofs;
ULONG               SERIALNUMBER = 0xeeeeeeee;
ULONG               XORSERIALNUMBER = 0xffffffff;

BOOL                SERGOOD = TRUE;
//-

///   Protos
#undef            _main

void                InitTrans(void);
int                 CarrierDetect(void);
void                Version(int);
int                 Decrypt(char *, char *);
void                Bury(char *);
void                SendBreak(void);
struct DosPacket   *taskwait(struct Process *);
void                InitList(struct List *);
//-


///   _main()
void __saveds       _main(void)
{
   struct TPTPort      ps;      /* All the port stuff */
   struct TPTSess      sess;
   struct DeviceNode  *mynode;  /* our device node (parmpkt Arg3) */

   UBYTE               ttitle[71];

   /* Initializing the Handler */

   InitTrans();

   ps.sess = &sess;
   ps.sess->port = &ps;
   ps.sess->run = TRUE;
   ps.sess->aux_open = 0;
   InitList(&(ps.sess->readerlist));
   ps.sess->creader = NULL;
   InitList(&(ps.sess->readmsg));
   InitList(&(ps.sess->othermsg));

   ps.unit = 0;
   ps.serflags = SERF_SHARED | SERF_XDISABLED | SERF_RAD_BOOGIE;
   ps.myproc = (struct Process *) FindTask(0);
   ps.myport = &ps.myproc->pr_MsgPort;
   myportsig = MYPORT_SIG;

   /* Wait for my startup message */
   ps.sess->mypkt = taskwait(ps.myproc);

   /* Process StartUp Message */

   {
      UBYTE              *ptr;  /* ptr for name translation */
      UBYTE              *s;

      long                counter;
      long                len;
      UBYTE               name[256];

      ptr = BADDR(ps.sess->mypkt->dp_Arg1);
      len = *ptr;

      movmem(ptr + 1, name, len);
      name[len] = '\0';

      strncpy(tdevname, name, 3);
      tdevname[3] = '\0';
      
      for (s = (char *) tdevname; *s; ++s)
      {
         *s = toupper(*s);
      }

      if (!strncmp(tdevname, "TL", 2))
      {
         strcpy(ps.tserdev, "console.device");
         localflag = TRUE;
      }
      else
      {
         strcpy(ps.tserdev, SERIALNAME);

         if (len > 4)
         {
            ptr = &name[4];
            for (s = ptr; *s; s++)
            if (*s == '/')
            break;

            counter = s - ptr;

            // Changed 9/3/96 -- this ties to the length of tserdev in the handler includes.

            if (counter > 35)
            {
               counter = 35;
            }
            
            strncpy(ps.tserdev, ptr, counter);
            ps.tserdev[counter] = '\0';

            if (*s)
            {
               s++;
               ptr = s;

               while (*s)
               {
                  if (*s == '/')
                  {
                     break;
                  }
                  
                  s++;
               }

               if (*s)
               {
                  *s = '\0';
                  ps.unit = atoi(ptr);

                  if (*(s + 1) == '7')
                  {
                     ps.serflags =  SERF_SHARED    |
                     SERF_XDISABLED |
                     SERF_7WIRE     |
                     SERF_RAD_BOOGIE;
                  }
               }
               else
               {
                  ps.unit = atoi(ptr);
               }
            }
         }
      }  // end else
   }

   mynode = BADDR(ps.sess->mypkt->dp_Arg3);
   mynode->dn_Task = &ps.myproc->pr_MsgPort;
   mynode->dn_Type = DLT_DEVICE;
   mynode->dn_Lock = NULL;

   /* Return StartUp Message */

   returnpkt(ps.sess->mypkt, ps.myproc, DOS_TRUE, ps.sess->mypkt->dp_Res2);

   /* Create Handler Message Ports */

   strncpy(ps.tctl, tdevname, 4);
   strcat(ps.tctl, "control");
   ps.tctl[10] = '\0';

   strncpy(conwrname, tdevname, 4);
   strcat(conwrname, ".con.write");
   conwrname[13] = '\0';

   strncpy(conrdname, tdevname, 4);
   strcat(conrdname, ".con.read");
   conrdname[12] = '\0';

   #ifdef DO_DEBUG
   if (dport = (struct MsgPort *) FindPort(DEBUG))
   {
      strcpy(dname, tdevname);
      strcat(dname, "Debug");

      drport = (struct MsgPort *) CreateMsgPort();
      drport->mp_Node.ln_Name = dname;
      AddPort(drport);

      TDebug(0, "Started up Handler debug port");
   }
   #endif

TDebug(1,"Setting up title");

   /* SetUp Title */
   strcpy(ttitle, tdevname);

///   Process Requests till Done
   while (ps.sess->run)
   {
      long                signals;
      long                waitsignals;

      if (ps.sess->aux_open)
      {
         waitsignals = myportsig | controlsig | timersig;

         if ((!localflag) && ps.sess->aux_open)
         {
            waitsignals |= readsersig;
         }
         
         if (tptflags & T_WINDOW)
         {
            waitsignals |= consolesig;
         }

///      Do if killed or frozen
         if ((tptflags & T_KILLED) || (tptflags & T_FROZEN))
         {
            waitsignals &= ~(timersig);
            
            if (tptflags & T_WINDOW)
            {
               waitsignals &= ~(consolesig);
            }
            
            if ((!localflag) && ps.sess->aux_open)
            {
               waitsignals &= ~(readsersig);
            }
         }
//-

      }
      else
      {
         waitsignals = myportsig;
      }

///   Do if not paused AND (raw OR (line freezed AND inline)) AND not frozen
      if (!(tptflags & T_PAUSED) &&
         ((tptflags & T_RAW) || !((tptflags & T_LINEFREEZE) && inline)) &&
         !(tptflags & T_FROZEN))
      {
         while (ps.mymess = (struct Message *) RemHead(&(ps.sess->othermsg)))
         {
            DoPacket(&ps);
         }
         
         if (!(tptflags & T_RPEND) && !(tptflags & T_WAIT_FOR))
         {
            while (ps.mymess = (struct Message *) RemHead(&(ps.sess->readmsg)))
            {
               DoPacket(&ps);
            }
         }
      }
//-

      signals = Wait(waitsignals);

///   Process signal from timer
      if (signals & timersig)
      {
         WaitIO((struct IORequest *) Timer);

///      Do if port is frozen or killed
         if (!((tptflags & T_FROZEN) || (tptflags & T_KILLED)))
         {

///         Do if read pending, wait for, or paused
            if (((tptflags & T_RPEND) || (tptflags & T_WAIT_FOR) || (tptflags & T_PAUSED)))
            {

///            Do if wait for
               if (tptflags & T_WAIT_FOR)
               {
                  tptflags &= ~T_WAIT_FOR;
                  ps.sess->creader->rdpkt->dp_Res1 = DOS_FALSE;
                  returnpktplain(ps.sess->creader->rdpkt, ps.myproc);
               }
               else
               {
                  num_times++;

///               Timeout warning
                  if ((tptflags & T_DO_TIMEOUT) && (time_delay > 11) && (num_times == time_delay - 4))
                  {
#ifdef DO_DEBUG
                     TDebug(0,"Timing port out in 20 seconds");
#endif
                     WriteSer("\n\007Inactivity TIME OUT in 20 seconds...\n", 38);
                  }
//-

///               Time out port
                  if ((num_times >= time_delay) && (tptflags & T_DO_TIMEOUT))
                  {
                     if ((num_times >= time_delay) && !(tptflags & T_KILL_PEND))
                     {
#ifdef DO_DEBUG
                        TDebug(0,"Timing out port");
#endif
                        WriteSer("\nInactivity TIME OUT...", 22);
                     }
                     
                     Die(ps.sess);
                  }
//-
               }
//-

            }
//-

            if (!CarrierDetect())
            {
#ifdef DO_DEBUG
               TDebug(0,"Carrier apparently lost.");
#endif
               Die(ps.sess);
            }
         }
//-

         Timer->tr_time.tv_secs = 5;
         Timer->tr_time.tv_micro = 0;
         SendIO((struct IORequest *) Timer);
      }
//-

///   ReadSerial signal
      if (signals & readsersig)
      {
         if (CheckIO((struct IORequest *) ReadSER))
         {
            if (CarrierDetect())
            {
               ReadSer(ps.sess, SERCHAR);
               CheckPending(ps.sess);
            }
            else if (!Die(ps.sess))
            {
               ReadSer(ps.sess, SERCHAR);
               CheckPending(ps.sess);
            }
         }
      }
//-

///   Console signal
      if (signals & consolesig)
      {
         if (CheckIO((struct IORequest *) consoleReadMsg))
         {
            ReadSer(ps.sess, CONCHAR);
            CheckPending(ps.sess);
         }
      }
//-

///   Port signal
      if (signals & myportsig)
      {
         while (ps.mymess = (struct Message *) GetMsg(ps.myport))
         {
            DoPacket(&ps);
         }
      }
//-

///   Control signal
      if (signals & controlsig)
      {
         while ((ctlmsg = (struct ctrl_mess *) GetMsg(ctrl_port)) != NULL)
         {
            // main program loop here
            
///         Switch on ctlmsg->mod_type
            switch(ctlmsg->mod_type)
            {

///            TADDSTAT
               case TADDSTAT:
               {
                  tptflags |= ctlmsg->astat;
                  ctlmsg->astat = tptflags;

                  if (tptflags & T_KILL_ENABLE)
                  {
                     if (tptflags & T_KILL_PEND)
                     {
                        tptflags &= ~T_KILL_PEND;
                        Die(ps.sess);
                     }
                  }
                  break;
               }
//-

///            TDELSTAT
               case TDELSTAT:
               {
                  tptflags &= ~ctlmsg->astat;
                  ctlmsg->astat = tptflags;
                  break;
               }
//-

///            TBAUD
               case TBAUD:
               {
                  if (localflag)
                  {
                     ctlmsg->astat = GENERALERR;
                  }
                  else if (tptflags & T_FROZEN)
                  {
                     ctlmsg->astat = FROZENERR;
                  }
                  else
                  {
                     if (!(tptflags & T_TYPEAHEAD_FULL))
                     {
                        NiceAbort((struct IORequest *) ReadSER);
                     }

                     if (!localflag && (tptflags & T_WRITE_PEND))
                     {
                        WaitIO((struct IORequest *) WriteSER);
                        tptflags &= ~T_WRITE_PEND;
                     }

                     ReadSER->io_Baud = ctlmsg->astat;
                     ReadSER->IOSer.io_Command = SDCMD_SETPARAMS;
                     ctlmsg->astat = DoIO((struct IORequest *) ReadSER);
                     
                     if (!(tptflags & T_TYPEAHEAD_FULL))
                     {
                        set_read();
                     }
                  }
                  break;
               }
//-

///            TPOPSCREEN
               case TPOPSCREEN:
               {
                  if (!(tptflags & T_WINDOW))
                  {
                     struct ScrStruct   *scrstruct;
                     ULONG               flags;

                     scrstruct = (struct ScrStruct *) ctlmsg->astat;

                     if (OpenScrStuff(ttitle, scrstruct))
                     {
                        if (localflag || !(scrstruct->flags & DISP_BKGRND))
                        {
                           flags = SIMPLE_REFRESH | BACKDROP |
                           BORDERLESS | ACTIVATE;
                        }
                        else
                        {
                           flags = SIMPLE_REFRESH | BACKDROP | BORDERLESS;
                        }

                        strcpy(fontname, scrstruct->fontname);
                        
                        if (OpenWinStuff(0, 12, scrstruct->width, (scrstruct->height) - 12, flags, (UBYTE *) NULL, TScrn, 0, 0, 0, 0, (USHORT) CUSTOMSCREEN, fontname, scrstruct->fontsize))
                        {
                           ctlmsg->astat = tptflags;
                        }
                        else
                        {
                           CloseScrStuff();
                           ctlmsg->astat = GENERALERR;
                        }
                     }
                     else
                     {
                        ctlmsg->astat = GENERALERR;
                     }
                  }
                  else if (tptflags & T_SCREEN)
                  {
                     ctlmsg->astat = SCROPENERR;
                  }
                  else
                  {
                     ctlmsg->astat = WINOPENERR;
                  }
                  
                  break;
               }
//-

///            TCLOSESCREEN
               case TCLOSESCREEN:
               {
                  if (tptflags & T_SCREEN)
                  {
                     CloseWinStuff();
                     CloseScrStuff();
                     ctlmsg->astat = tptflags;
                  }
                  else
                  {
                     ctlmsg->astat = SCRCLOSEDERR;
                  }
                  
                  break;
               }
//-

///            TPOPWIND
               case TPOPWIND:
               {
                  if (!(tptflags & T_WINDOW))
                  {
                     struct WinStruct   *winstruct;
                     ULONG               flags;

                     winstruct = (struct WinStruct *) ctlmsg->astat;
                  
                     if (localflag || !(winstruct->flags & DISP_BKGRND))
                     {
                        flags = WINDOWDEPTH | WINDOWSIZING |
                        WINDOWDRAG | SIMPLE_REFRESH |
                        ACTIVATE;
                     }
                     else
                     {
                        flags = WINDOWDEPTH | WINDOWSIZING |
                        WINDOWDRAG | SIMPLE_REFRESH;
                     }

                     strcpy(fontname, winstruct->fontname);
                     
                     if (OpenWinStuff(winstruct->x, winstruct->y, winstruct->width, winstruct->height, flags, (UBYTE *) ttitle, NULL, 85, 21, -1, -1, (USHORT) WBENCHSCREEN, fontname, winstruct->fontsize))
                     {
                        ctlmsg->astat = tptflags;
                     }
                     else
                     {
                        ctlmsg->astat = GENERALERR;
                     }
                  }
                  else
                  {
                     ctlmsg->astat = WINOPENERR;
                  }
                  break;
               }  // end TPOPWIND
//-

///            TCLOSEWIND
               case TCLOSEWIND:
               {
                  if (!(tptflags & T_SCREEN))
                  {
                     if (tptflags & T_WINDOW)
                     {
                        CloseWinStuff();
                        ctlmsg->astat = tptflags;
                     }
                     else
                     {
                        ctlmsg->astat = WINCLOSEDERR;
                     }
                  }
                  else
                  {
                     ctlmsg->astat = SCROPENERR;
                  }
                  
                  break;
               }
//-

///            TTITLE
               case TTITLE:
               {
                  strncpy(ttitle, (UBYTE *) ctlmsg->astat, 70);
                  ttitle[70] = '\0';
                  ctlmsg->astat = NOERR;

                  if (tptflags & T_SCREEN)
                  {
                     SetWindowTitles(TWind, NULL, (UBYTE *) ttitle);
                     ShowTitle(TScrn, TRUE);
                  }
                  else if (tptflags & T_WINDOW)
                  {
                     SetWindowTitles(TWind, (UBYTE *) ttitle, NULL);
                  }
                  break;
               }
//-

///            TGETTITLE
               case TGETTITLE:
               {
                  strcpy((char *) ctlmsg->astat, ttitle);
                  ctlmsg->astat = NOERR;
                  break;
               }
//-

///            TWINHEIGHT
               case TWINHEIGHT:
               {
                  if (tptflags & T_SCREEN)
                  {
                     WriteCon("\x9b", 1);
                     WriteCon((char *) ctlmsg->astat, strlen((char *) ctlmsg->astat));
                     WriteCon("\x74", 1);
                     ctlmsg->astat = NOERR;
                  }
                  else
                  {
                     ctlmsg->astat = SCRCLOSEDERR;
                  }
                  break;
               }
//-

///            TCOLORS
               case TCOLORS:
               {
                  movmem((void *) ctlmsg->astat, colortable, 16);
                  
                  if (TScrn)
                  {
                     LoadRGB4(&(TScrn->ViewPort), colortable, (1 << TScrDepth));
                  }
                  ctlmsg->astat = NOERR;
                  break;
               }
//-

///            TDEVQUERY
               case TDEVQUERY:
               {
                  struct tdev_info   *mydevinfo;

                  mydevinfo = (struct tdev_info *) ctlmsg->astat;
                  strcpy(mydevinfo->devname, ps.tserdev);
                  mydevinfo->unit = (UBYTE) ps.unit;
                  mydevinfo->serflags = ps.serflags;
                  ctlmsg->astat = NOERR;
                  break;
               }
//-

///            TGETSER
               case TGETSER:
               {
                  struct TPTSerStuff *ss;

                  ss = (struct TPTSerStuff *) ctlmsg->astat;
                  ss->read = ReadSER;
                  ss->write = WriteSER;
                  ctlmsg->astat = NOERR;
                  break;
               }
//-

///            TTIMEOUTDELAY
               case TTIMEOUTDELAY:
               {
                  time_delay = (int) ctlmsg->astat;
                  ctlmsg->astat = NULL;
                  break;
               }
//-

///            TKILL
               case TKILL:
               {
                  #ifdef DO_DEBUG
                  TDebug(0, "Killing Port");
                  #endif
                  Die(ps.sess);
                  break;
               }
//-

///            TFREEZE
               case TFREEZE:
               {
                  if (tptflags & T_FROZEN)
                  {
                     ctlmsg->astat = FROZENERR;
                  }
                  else
                  {
                     #ifdef DO_DEBUG
                     TDebug(1, "Freezing Port");
                     #endif
                     tptflags |= T_FROZEN;
                   
                     if (!localflag && !(tptflags & T_TYPEAHEAD_FULL))
                     {
                        NiceAbort((struct IORequest *) ReadSER);
                     }

                     if (consoleReadMsg && !(tptflags & T_TYPEAHEAD_FULL))
                     {
                        NiceAbort((struct IORequest *) consoleReadMsg);
                     }

                     if (tptflags & T_WRITE_PEND)
                     {
                        WaitIO((struct IORequest *) WriteSER);
                        tptflags &= ~T_WRITE_PEND;
                     }

                     if (tptflags & T_WAIT_FOR)
                     {
                        tptflags &= ~T_WAIT_FOR;
                        ps.sess->creader->rdpkt->dp_Res1 = DOS_FALSE;
                        returnpktplain(ps.sess->creader->rdpkt, ps.myproc);
                     }

                     if (tptflags & T_SER_TIMEOUT)
                     {
                        NiceAbort((struct IORequest *) Timer);
                        Wait(1L << Timer_Port->mp_SigBit);
                     }

                     ctlmsg->astat = NOERR;
                  }
                  break;
               }
//-

///            TCONT
               case TCONT:
               {
                  if (tptflags & T_FROZEN)
                  {
                     tptflags &= ~T_FROZEN;

                     #ifdef DO_DEBUG
                     TDebug(1, "Port Unfrozen");
                     #endif
                     if (!(tptflags & T_TYPEAHEAD_FULL))
                     {
                        if (!localflag)
                        {
                           set_read();
                        }
                        
                        if (tptflags & T_WINDOW)
                        {
                           set_con_read();
                        }
                     }

                     if (tptflags & T_SER_TIMEOUT)
                     {
                        num_times = 0;
                        Timer->tr_time.tv_secs = 5;
                        Timer->tr_time.tv_micro = 0;
                        SendIO((struct IORequest *) Timer);
                     }

                     if ((tptflags & T_KILLED) || !CarrierDetect())
                     {
                        Die(ps.sess);
                     }
                  }

                  ctlmsg->astat = NOERR;
                  break;
               }
//-

///            TRECOVER
               case TRECOVER:
               {
                  tptflags &= ~T_KILLED;
                  num_kills = 0;
                  ctlmsg->astat = tptflags;
                  break;
               }
//-

  // this triggers the decryption and display of licensor and
  // serial number strings

///            TVERSION
               case TVERSION:
               {
                  if (ctlmsg->astat > 0)
                  {
                     crcofs = ctlmsg->astat;
                     Version(0);
                  }
                  else
                  {
                     Version(ctlmsg->astat);
                  }

                  ctlmsg->astat = NOERR;
                  break;
               }
//-

///            TSTRING
               case TSTRING:
               {
                  FakeSerString(ps.sess, (UBYTE *) ctlmsg->astat, strlen((char *) ctlmsg->astat));
                  CheckPending(ps.sess);
                  ctlmsg->astat = NOERR;
                  break;
               }
//-

///            TINTRANS
               case TINTRANS:
               {
                  movmem((void *) ctlmsg->astat, intrans, 256);
                  ctlmsg->astat = NOERR;
                  break;
               }
//-

///            TOUTTRANS
               case TOUTTRANS:
               {
                  movmem((void *) ctlmsg->astat, outtrans, 256);
                  ctlmsg->astat = NOERR;
                  break;
               }
//-

///            TCHECKCARRIER
               case TCHECKCARRIER:
               {
                  if (!CarrierDetect())
                  {
                     ctlmsg->astat = FALSE;
                     #ifdef DO_DEBUG
                     TDebug(1, "No Carrier");
                     #endif
                     Die(ps.sess);
                  }
                  else
                  {
                     ctlmsg->astat = TRUE;
                     #ifdef DO_DEBUG
                     TDebug(1, "Carrier Detected");
                     #endif
                  }
                  break;
               }
//-

///            TSENDBREAK
               case TSENDBREAK:
               {
                  SendBreak();
                  ctlmsg->astat = NOERR;
                  break;
               }
//-

///            Decrypt Owner
               // new stuff 6/28/95 by Steve -- not #defined anywhere for security
               case 98:
               {
                  ctlmsg->astat = (long) &DLGOwner;
                  break;
               }
//-

///            Get Serial Number + Version
               case 99:
               {
                  ctlmsg->astat = (long) &version;
                  break;
               }
//-

///            Default
               default:
                  ctlmsg->astat = GENERALERR;
                  break;
//-
            }
//-


            if (crcsub < crc)
            {
               ctlmsg->mod_type = crcsub + 256 - crc;
            }
            else
            {
               ctlmsg->mod_type = crcsub - crc;
            }

            ReplyMsg((struct Message *) ctlmsg);
         }
      }
//-
   }
//-


#ifdef DO_DEBUG
   if (crcsub < crc)
   {
      mysub = crcsub + 256 - crc;
   }
   else
   {
      mysub = crcsub - crc;
   }
   
   TDebug(mysub, "Stopping Handler");
#endif

   CloseTimer();
// TDebug(4,"Timer Closed");

   CloseSer();

   if (TWind)
      CloseWinStuff();

   if (TScrn)
      CloseScrStuff();

   Forbid();
   while ((ctlmsg = (struct ctrl_mess *) GetMsg(ctrl_port)) != NULL)
   {
      ctlmsg->astat = ACTIVERR;
      ReplyMsg((struct Message *) ctlmsg);
   }

   while (ps.mymess = (struct Message *) RemHead(&(ps.sess->othermsg)))
   {
      ps.sess->mypkt = (struct DosPacket *) ps.mymess->mn_Node.ln_Name;
      returnpkt(ps.sess->mypkt, ps.myproc, DOS_FALSE, 0L);
   }

   while (ps.mymess = (struct Message *) GetMsg(ps.myport))
   {
      ps.sess->mypkt = (struct DosPacket *) ps.mymess->mn_Node.ln_Name;
      returnpkt(ps.sess->mypkt, ps.myproc, DOS_FALSE, 0L);
   }
   Permit();

   ClosePorts();
   mynode->dn_Task = FALSE;

   #ifdef DO_DEBUG
   if (drport)
   {
      RemPort(drport);
      DeleteMsgPort(drport);
   }
   #endif

   CloseLibs();
}
//-

///   InitTrans()
/*
** Initiate translation table
** Currently doesn't do anything.
*/

void InitTrans(void)
{
   SHORT c;

   for (c = 0; c < 256; c++)
   {
      outtrans[c] = c;              /* & ~128; */
      intrans[c] = c;               /* & ~128; */
   }
}
//-

///   CarrierDetect()
int                 CarrierDetect(void)
{
   UWORD               cd;
   UBYTE               i;

   if (localflag || !((tptflags & T_KILL_ENABLE) || (tptflags & T_DO_PEND)))
   return (1);

   if (tptflags & T_WRITE_PEND)
   {
      WaitIO((struct IORequest *) WriteSER);
      tptflags &= ~T_WRITE_PEND;
   }

   WriteSER->IOSer.io_Command = SDCMD_QUERY;

   for (i = 0; i < 5; i++)
   {
      DoIO((struct IORequest *) WriteSER);
      cd = WriteSER->io_Status;
      cd = !(cd & (UWORD) 1 << (UWORD) 5);
      if (cd)
      break;
   }

   WriteSER->IOSer.io_Command = CMD_WRITE;
   return ((int) cd);
}
//-

///   Version()
void                Version(int printit)
{
   char                buf[32];
   char                name[128];

   ULONG               serial;
   ULONG               xorserial;

   long                numchars;
   long                numname;

   BadFlag = FALSE;
   numchars = Decrypt(version, buf);
   serial = atoi(buf + 10);
   numname = Decrypt(DLGOwner, name);

   // new stuff
   Bury(version);
   xorserial = XORSERIALNUMBER;
   xorserial ^= 0xffffffff;
   // end new

   if ((!serial && strnicmp(buf + 8, "DEMO", 4)) ||
   serial != SERIALNUMBER ||
   serial != xorserial ||
   (strnicmp(buf + 8, "DV", 2) &&
   strnicmp(buf + 8, "BT", 2) &&
   strnicmp(buf + 8, "PR", 2) &&
   strnicmp(buf + 8, "RE", 2) &&
   strnicmp(buf + 8, "DEMO", 4)) ||
   #include <dialog/dead.h>
   )
   {
      BadFlag = TRUE;
      numname = Decrypt(DLGPirate, name);
   }

   if (printit)
   {
      WriteSer("\n\n", 2);
      WriteSer(DLGLongName, strlen(DLGLongName));
      WriteSer("\n", 1);
      WriteSer(buf, numchars);

      if (BadFlag || !serial || printit == -2)
      {
         WriteSer("  ", 2);
         WriteSer(name, numname);
      }

      WriteSer("\n\n", 2);
   }

   /* if (printit < 0) {WriteSer("\n\n",      2);
 * WriteSer(DLGLongName, strlen(DLGLongName));
 * WriteSer("\n",        1); WriteSer(buf,
 * numchars); WriteSer("  ",        2); WriteSer(name,
 *   numname); WriteSer("\n\n",      2); } */
   crcsub = version[20];
}
//-

///   Decrypt()
int                 Decrypt(char *inbuf, char *outbuf)
{
   int                 numchars;
   int                 i;

   UBYTE              *in;
   UBYTE               shift;

   Forbid();
   in = inbuf;
   numchars = *inbuf++;
   shift = numchars;
   for (i = 0; i < numchars; i++)
   {
      *outbuf++ = *inbuf - shift;
      shift = *inbuf - (UBYTE) crcofs;
      inbuf++;
   }

   if (in == version)
   crc = shift;
   *outbuf = 0;
   Permit();

   return (numchars);
}
//-

///   Bury()
void                Bury(char *shit)
{
   UBYTE              *r;

   r = shit + 26;
   SERIALNUMBER = ((ULONG) * (r) << 24) + ((ULONG) * (r + 1) << 16) + ((ULONG) * (r + 2) << 8) + ((ULONG) * (r + 3));
   XORSERIALNUMBER = ((ULONG) * (r + 4) << 24) + ((ULONG) * (r + 5) << 16) + ((ULONG) * (r + 6) << 8) + ((ULONG) * (r + 7));
}
//-

///   SendBreak()
/* */
/* Send a break to the serial device */
/* */
void                SendBreak(void)

{
   if (!localflag)
   {
      if (tptflags & T_WRITE_PEND)
      {
         AbortIO((struct IORequest *) WriteSER);
         WaitIO((struct IORequest *) WriteSER);
         tptflags &= ~T_WRITE_PEND;
      }

      WriteSER->IOSer.io_Command = SDCMD_BREAK;
      DoIO((struct IORequest *) WriteSER);

      WriteSER->IOSer.io_Command = CMD_WRITE;
   }
}
//-

///   taskwait()
struct DosPacket *taskwait(struct Process *myproc)
{
   struct MsgPort *myport;
   struct Message *mymess;

   myport = &myproc->pr_MsgPort;
   WaitPort(myport);
   mymess = GetMsg(myport);
   return((struct DosPacket *)mymess->mn_Node.ln_Name);
}
//-

///   InitList()
void                InitList(struct List *list)
{
   list->lh_Head = (struct Node *) &(list->lh_Tail);
   list->lh_TailPred = (struct Node *) &(list->lh_Head);
   list->lh_Tail = NULL;
   list->lh_Type = NT_UNKNOWN;
}
//-
