home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / comm / mdt100.lzh / mdt.c < prev    next >
C/C++ Source or Header  |  1991-07-22  |  37KB  |  1,389 lines

  1. /* #define XPRDEBUG 1 */
  2. #include <terminal/terminal.h>
  3.  
  4. void main()
  5. {
  6.     OpenAll();
  7.     LoopEm();
  8.     CleanExit();
  9. }
  10.  
  11. void go_away(UWORD return_code)
  12. {
  13.     if(ReqBase)
  14.         CloseLibrary((struct Library *)ReqBase);
  15.     if(timermsg)
  16.         DeleteExtIO((struct IORequest *)timermsg);
  17.     if(TimerPort)
  18.         DeletePort(TimerPort);
  19.     if(ConsoleIn)
  20.         DeleteExtIO(ConsoleIn);
  21.     if(ConsoleReadPort)
  22.         DeletePort(ConsoleReadPort);
  23.     if(ConsoleWritePort)
  24.         DeletePort(ConsoleWritePort);
  25.     if(SerialReadPort)
  26.         DeletePort(SerialReadPort);
  27.     if(SerialWritePort)
  28.         DeletePort(SerialWritePort);
  29.     if(BackWindow)
  30.         CloseWindow(BackWindow);
  31.     if(Scr)
  32.         CloseScreen(Scr);
  33.     exit(FALSE);
  34. }
  35.  
  36. void PrefIt()
  37. {
  38.     struct Preferences prefs;
  39.     char read, write, stop, parity, hs;
  40.  
  41.     GetPrefs(&prefs,sizeof(struct Preferences));
  42.     
  43.     read = (char)(prefs.SerRWBits)&SREAD_BITS;
  44.     read = 8-(read >> 4);
  45.     write = (char)(prefs.SerRWBits)&SWRITE_BITS;
  46.     write = 8-write;
  47.     SerialIn->io_ReadLen = read;
  48.     SerialOut->io_WriteLen = write;
  49.     stop = (char)(prefs.SerStopBuf)&SSTOP_BITS;
  50.     stop = (stop >> 4)+1;
  51.     SerialIn->io_StopBits = stop;
  52.     SerialOut->io_StopBits = stop;
  53.     parity = (char)SPARNUM(prefs.SerParShk);
  54.     hs = (char)SHAKNUM(prefs.SerParShk);
  55.     switch(parity)
  56.     {
  57.         case SPARITY_NONE:    SerialIn->io_SerFlags &= ~SERF_PARTY_ON;
  58.                                     SerialOut->io_SerFlags &= ~SERF_PARTY_ON;
  59.                                     break;
  60.         case SPARITY_EVEN:    SerialIn->io_SerFlags |= SERF_PARTY_ON;
  61.                                     SerialOut->io_SerFlags |= SERF_PARTY_ON;
  62.                                     SerialIn->io_SerFlags &= ~SERF_PARTY_ODD;
  63.                                     SerialOut->io_SerFlags &= ~SERF_PARTY_ODD;
  64.                                     break;
  65.         case SPARITY_ODD:        SerialIn->io_SerFlags |= SERF_PARTY_ON;
  66.                                     SerialOut->io_SerFlags |= SERF_PARTY_ON;
  67.                                     SerialIn->io_SerFlags |= SERF_PARTY_ODD;
  68.                                     SerialOut->io_SerFlags |= SERF_PARTY_ODD;
  69.                                     break;
  70.         case 3:                    SerialIn->io_SerFlags |= SERF_PARTY_ON;
  71.                                     SerialOut->io_SerFlags |= SERF_PARTY_ON;
  72.                                     SerialIn->io_ExtFlags |= SEXTF_MSPON;
  73.                                     SerialOut->io_ExtFlags |= SEXTF_MSPON;
  74.                                     SerialIn->io_ExtFlags |= SEXTF_MARK;
  75.                                     SerialOut->io_ExtFlags |= SEXTF_MARK;
  76.                                     break;
  77.         case 4:                    SerialIn->io_SerFlags |= SERF_PARTY_ON;
  78.                                     SerialOut->io_SerFlags |= SERF_PARTY_ON;
  79.                                     SerialIn->io_ExtFlags |= SEXTF_MSPON;
  80.                                     SerialOut->io_ExtFlags |= SEXTF_MSPON;
  81.                                     SerialIn->io_ExtFlags &= ~SEXTF_MARK;
  82.                                     SerialOut->io_ExtFlags &= ~SEXTF_MARK;
  83.                                     break;
  84.     }
  85.     SerialIn->IOSer.io_Command = SDCMD_SETPARAMS;
  86.     SerialOut->IOSer.io_Command = SDCMD_SETPARAMS;
  87.     DoIO((struct IORequest *)SerialOut);
  88.     DoIO((struct IORequest *)SerialIn);
  89. }
  90.  
  91. void OpenAll()
  92. {
  93.     int error;
  94.     struct Preferences prefs;
  95.     char version[81];
  96.  
  97.     strcpy(version,"$VER: My_Dumb_Terminal 1.00 (22.7.91)");
  98.     ReqBase = (struct ReqLib *)OpenLibrary("req.library",0);
  99.     if(!ReqBase)
  100.     {
  101.         printf("req.library wouldn't open.\n");
  102.         go_away(20);
  103.     }
  104.     // This part causes AmigaDOS (and Intuition) to open all requestors
  105.     // on our screen (window) while we're open.  MUST MUST be restored
  106.     // before shutting down.  See CleanExit().  BTW, req.library observes
  107.     // the windowptr field when opening up requestors.
  108.     IntuitionBase = ReqBase->IntuiLib;
  109.     GfxBase = ReqBase->GfxLib;
  110.     MyProcess = (struct Process *)FindTask(NULL);
  111.     Scr = OpenScreen(&NewScr);
  112.     if (!Scr)
  113.     {
  114.         printf("Couldn't open screen.  Not enough memory?\n");
  115.         go_away(20);
  116.     }
  117.  
  118.     NewWin.Screen = Scr;
  119.     BackWindow = OpenWindow(&NewWin);
  120.     if (!BackWindow)
  121.     {
  122.         printf("Couldn't open Window!  Not enough memory?\n");
  123.         go_away(20);
  124.     }
  125.  
  126.     // Cache the original window pointer to restore later
  127.     OldWindowPointer = (struct Window *)MyProcess->pr_WindowPtr;
  128.     MyProcess->pr_WindowPtr = (APTR)BackWindow;
  129.  
  130.     SerialReadPort = CreatePort(0,0);
  131.     if(!SerialReadPort)
  132.     {
  133.         printf("Error opening MsgPort\n");
  134.         go_away(20);
  135.     }
  136.     SerialWritePort = CreatePort(0,0);
  137.     if(!SerialWritePort)
  138.     {
  139.         printf("Error opening MsgPort\n");
  140.         go_away(20);
  141.     }
  142.     ConsoleReadPort = CreatePort(0,0);
  143.     if(!ConsoleReadPort)
  144.     {
  145.         printf("Error opening MsgPort\n");
  146.         go_away(20);
  147.     }
  148.     ConsoleWritePort = CreatePort(0,0);
  149.     if(!ConsoleWritePort)
  150.     {
  151.         printf("Error opening MsgPort\n");
  152.         go_away(20);
  153.     }
  154.     TimerPort = CreatePort(0,0);
  155.     if(!TimerPort)
  156.     {
  157.         printf("Error opening MsgPort\n");
  158.         go_away(20);
  159.     }
  160.     ConsoleIn = (struct IOStdReq *)CreateExtIO(ConsoleReadPort,sizeof(struct IOStdReq));
  161.     if(!ConsoleIn)
  162.     {
  163.         printf("Error creating StdIO\n");
  164.         go_away(20);
  165.     }
  166.     ConsoleOut = (struct IOStdReq *)CreateExtIO(ConsoleWritePort,sizeof(struct IOStdReq));
  167.     if(!ConsoleOut)
  168.     {
  169.         printf("Error creating StdIO\n");
  170.         go_away(20);
  171.     }
  172.     ConsoleIn->io_Data = (APTR)BackWindow;
  173.     ConsoleIn->io_Length = sizeof(struct Window);
  174.     error = OpenDevice("console.device",0,ConsoleIn,0);
  175.     if(error)
  176.     {
  177.         printf("Error opening console.device");
  178.         go_away(20);
  179.     }
  180.     ConsoleOut->io_Device = ConsoleIn->io_Device;
  181.     ConsoleOut->io_Unit = ConsoleIn->io_Unit;
  182.  
  183.     SerialIn = (struct IOExtSer *)CreateExtIO(SerialReadPort,sizeof(struct IOExtSer));
  184.     if(!SerialIn)
  185.     {
  186.         printf("Unable to allocate enough memory.\n");
  187.         go_away(20);
  188.     }
  189.     SerialOut = (struct IOExtSer *)CreateExtIO(SerialWritePort,sizeof(struct IOExtSer));
  190.     if(!SerialOut)
  191.     {
  192.         printf("Unable to allocate enough memory.\n");
  193.         go_away(20);
  194.     }
  195.     error = OpenDevice("serial.device",0,(struct IOStdReq *)SerialIn,0);
  196.     if(error)
  197.     {
  198.         printf("Error opening serial.device\n");
  199.         go_away(20);
  200.     }
  201.     SerialOut->IOSer.io_Device = SerialIn->IOSer.io_Device;
  202.     SerialOut->IOSer.io_Unit = SerialIn->IOSer.io_Unit;
  203.     xpr_setserial(xpr_setserial(-1)); // copy all the serial port settings into SerialOut
  204.     PrefIt();
  205.     GetPrefs(&prefs,sizeof(struct Preferences));
  206.     switch(prefs.BaudRate)
  207.     {
  208.         case BAUD_110:        SerialOut->io_Baud = 110;
  209.                                 SerialIn->io_Baud = 110;
  210.                                 break;
  211.         case BAUD_300:        SerialOut->io_Baud = 300;
  212.                                 SerialIn->io_Baud = 300;
  213.                                 break;
  214.         case BAUD_1200:    SerialOut->io_Baud = 1200;
  215.                                 SerialIn->io_Baud = 1200;
  216.                                 break;
  217.         case BAUD_2400:    SerialOut->io_Baud = 2400;
  218.                                 SerialIn->io_Baud = 2400;
  219.                                 break;
  220.         case BAUD_4800:    SerialOut->io_Baud = 4800;
  221.                                 SerialIn->io_Baud = 4800;
  222.                                 break;
  223.         case BAUD_9600:    SerialOut->io_Baud = 9600;
  224.                                 SerialIn->io_Baud = 9600;
  225.                                 break;
  226.         case BAUD_19200:    SerialOut->io_Baud = 19200;
  227.                                 SerialIn->io_Baud = 19200;
  228.                                 break;
  229.     }
  230.     SerialIn->IOSer.io_Command = SDCMD_SETPARAMS;
  231.     SerialOut->IOSer.io_Command = SDCMD_SETPARAMS;
  232.     DoIO((struct IORequest *)SerialOut);
  233.     DoIO((struct IORequest *)SerialIn);
  234.  
  235.     SetRGB4(&Scr->ViewPort,0,0,0,0);        /* BLACK */
  236.     SetRGB4(&Scr->ViewPort,1,15,0,0);        /* RED */
  237.     SetRGB4(&Scr->ViewPort,2,0,15,0);        /* GREEN */
  238.     SetRGB4(&Scr->ViewPort,3,15,15,0);        /* YELLOW */
  239.     SetRGB4(&Scr->ViewPort,4,0,0,15);        /* BLUE */
  240.     SetRGB4(&Scr->ViewPort,5,15,0,15);        /* PURPLE */
  241.     SetRGB4(&Scr->ViewPort,6,0,15,15);        /* CYAN */
  242.     SetRGB4(&Scr->ViewPort,7,15,15,15);        /* WHITE */
  243.  
  244.     SetMenuStrip(BackWindow,&Menu1);
  245.  
  246.     timermsg = (struct timerequest *)CreateExtIO(TimerPort,sizeof(struct timerequest));
  247.     if(!timermsg)
  248.     {
  249.         printf("Out of memory.\n");
  250.         go_away(20);
  251.     }
  252.     timermsg->tr_node.io_Message.mn_ReplyPort = TimerPort;
  253.     timermsg->tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  254.     error = OpenDevice("timer.device",UNIT_VBLANK,(struct IORequest *)timermsg,0);
  255.     if(error)
  256.     {
  257.         printf("Error opening timer.device.\n");
  258.         go_away(20);
  259.     }
  260. }
  261.  
  262. void CleanExit()
  263. {
  264.     ClearMenuStrip(BackWindow);
  265.     CloseDevice((struct IORequest *)SerialIn);
  266.     DeleteExtIO((struct IORequest *)SerialIn);
  267.     DeleteExtIO((struct IORequest *)SerialOut);
  268.     while(GetMsg(SerialReadPort));
  269.     DeletePort(SerialReadPort);
  270.     while(GetMsg(SerialWritePort));
  271.     DeletePort(SerialWritePort);
  272.     CloseDevice(ConsoleIn);
  273.     DeleteExtIO(ConsoleIn);
  274.     DeleteExtIO(ConsoleOut);
  275.     while(GetMsg(ConsoleReadPort));
  276.     DeletePort(ConsoleReadPort);
  277.     while(GetMsg(ConsoleWritePort));
  278.     DeletePort(ConsoleWritePort);
  279.     CloseWindow(BackWindow);
  280.     CloseScreen(Scr);
  281.     CloseLibrary((struct Library *)ReqBase);
  282.     // restore the original window pointer for requestors
  283.     MyProcess->pr_WindowPtr = (APTR)OldWindowPointer;
  284.     CloseDevice((struct IORequest *)timermsg);
  285.     DeleteExtIO((struct IORequest *)timermsg);
  286.     while(GetMsg(TimerPort));
  287.     DeletePort(TimerPort);
  288. }
  289.  
  290. void QueueSerial(char *buffer, long size)
  291. {
  292.     SerialIn->IOSer.io_Command = CMD_READ;
  293.     SerialIn->IOSer.io_Data = (APTR)buffer;
  294.     SerialIn->IOSer.io_Length = size;
  295.     SendIO((struct IORequest *)SerialIn);
  296. }
  297.  
  298. void QueueConsole(char *buffer, long size)
  299. {
  300.     ConsoleIn->io_Command = CMD_READ;
  301.     ConsoleIn->io_Data = (APTR)buffer;
  302.     ConsoleIn->io_Length = size;
  303.     SendIO(ConsoleIn);
  304. }
  305.  
  306. void ModemOut(char *buffer, int length)
  307. {
  308.     SerialOut->IOSer.io_Length = length;
  309.     SerialOut->IOSer.io_Data = (APTR)buffer;
  310.     SerialOut->IOSer.io_Command = CMD_WRITE;
  311.     DoIO((struct IORequest *)SerialOut);
  312. }
  313.  
  314. void ScreenOut(char *buffer, int length)
  315. {
  316.     ConsoleOut->io_Length = length;
  317.     ConsoleOut->io_Data = (APTR)buffer;
  318.     ConsoleOut->io_Command = CMD_WRITE;
  319.     DoIO(ConsoleOut);
  320. }
  321.  
  322. void LoopEm()
  323. {
  324.     struct GetLongStruct gls;
  325.     long signals, mask;
  326.     long CharsAvail;
  327.     char SerInBuf[81];
  328.     char ConInBuf[81];
  329.     long code, class;
  330.  
  331.     mask = (1L << ConsoleReadPort->mp_SigBit)|
  332.         (1L << BackWindow->UserPort->mp_SigBit)|
  333.         (1L << SerialReadPort->mp_SigBit);
  334.  
  335.     while(1) // forever
  336.     {
  337.         QueueSerial(SerInBuf,1);
  338.         QueueConsole(ConInBuf,1);
  339.         signals = Wait(mask);
  340.         if(signals & (1L << ConsoleReadPort->mp_SigBit))
  341.             ModemOut(ConInBuf,1);
  342.         else
  343.         {
  344.             AbortIO(ConsoleIn);
  345.             Wait(1L << ConsoleReadPort->mp_SigBit);
  346.         }
  347.         GetMsg(ConsoleReadPort);
  348.         if(signals & (1L << SerialReadPort->mp_SigBit))
  349.         {
  350.             GetMsg(SerialReadPort);
  351.             ScreenOut(SerInBuf,1);
  352.             SerialIn->IOSer.io_Command = SDCMD_QUERY;
  353.             DoIO((struct IORequest *)SerialIn);
  354.             CharsAvail = SerialIn->IOSer.io_Actual;
  355.             if(CharsAvail)
  356.             {
  357.                 if(CharsAvail > 80)
  358.                     CharsAvail = 80;
  359.                 SerialIn->IOSer.io_Data = (APTR)SerInBuf;
  360.                 SerialIn->IOSer.io_Command = CMD_READ;
  361.                 SerialIn->IOSer.io_Length = CharsAvail;
  362.                 DoIO((struct IORequest *)SerialIn);
  363.                 ScreenOut(SerInBuf,CharsAvail);
  364.             }
  365.         }
  366.         else
  367.         {
  368.             AbortIO((struct IORequest *)SerialIn);
  369.             Wait(1L << SerialReadPort->mp_SigBit);
  370.             GetMsg(SerialReadPort);
  371.         }
  372.         if(signals & (1L << BackWindow->UserPort->mp_SigBit))
  373.         {
  374.             IntuiMsg = (struct IntuiMessage *)GetMsg(BackWindow->UserPort);
  375.             class = IntuiMsg->Class;
  376.             code = IntuiMsg->Code;
  377.             ReplyMsg((struct Message *)IntuiMsg);
  378.             if(class == NEWPREFS)
  379.                 PrefIt();
  380.             if(class != MENUPICK)
  381.                 continue;
  382.             if(MENUNUM(code) != 0)
  383.                 continue;
  384.             switch(ITEMNUM(code))
  385.             {
  386.                 case 0:    SimpleRequest("     My Dumb Terminal v1.00 by Ken Schenke\n\n   Donated to Public Domain on "__DATE__".\n\n May only be distributed in unmodified form in\n original archive.  Please see documentation\n for more information.\n\n(C) 1991 ParaLogic Software International, Inc.");
  387.                             break;
  388.                 case 1:    SerialIn->IOSer.io_Command = SDCMD_SETPARAMS;
  389.                             DoIO((struct IORequest *)SerialIn);
  390.                             gls.titlebar = "New Baud Rate";
  391.                             gls.defaultval = (long)SerialIn->io_Baud;
  392.                             gls.minlimit = 0L;
  393.                             gls.maxlimit = 115200L; // seems high enough for now
  394.                             gls.versionnumber = 0L;
  395.                             gls.rfu2 = 0L;
  396.                             gls.window = NULL;
  397.                             if(GetLong(&gls))
  398.                             {
  399.                                 SerialIn->io_Baud = gls.result;
  400.                                 SerialIn->IOSer.io_Command = SDCMD_SETPARAMS;
  401.                                 DoIO((struct IORequest *)SerialIn);
  402.                                 SerialOut->io_Baud = gls.result;
  403.                                 SerialOut->IOSer.io_Command = SDCMD_SETPARAMS;
  404.                                 DoIO((struct IORequest *)SerialOut);
  405.                             }
  406.                             break;
  407.                 case 2:    Upload();
  408.                             break;
  409.                 case 3:    Download();
  410.                             break;
  411.                 case 4:    return;
  412.             }
  413.         }
  414.     }
  415. }
  416.  
  417. BOOL GetProtocol(char *name)
  418. {
  419.     struct FileRequester *MyFileReq;
  420.     char DirStr[FCHARS+1];
  421.     BOOL result = FALSE;
  422.  
  423.     name[0] = '\0';
  424.     MyFileReq = (struct FileRequester *)AllocMem(sizeof(struct FileRequester),MEMF_PUBLIC|MEMF_CLEAR);
  425.     if(!MyFileReq)
  426.         return FALSE;
  427.     strcpy(DirStr,"LIBS:");
  428.     strcpy(MyFileReq->Show,"xpr*");
  429.     MyFileReq->VersionNumber = 0;
  430.     MyFileReq->Title = "Select a Protocol";
  431.     MyFileReq->Dir = DirStr;
  432.     MyFileReq->File = name;
  433.     MyFileReq->PathName = NULL;
  434.     MyFileReq->Window = NULL;
  435.     MyFileReq->numlines = 20;
  436.     MyFileReq->numcolumns = 40;
  437.     MyFileReq->devcolumns = 10;
  438.     MyFileReq->Flags = NULL;
  439.     MyFileReq->MaxExtendedSelect = 0;
  440.     MyFileReq->detailcolor = 4;
  441.     MyFileReq->blockcolor = 7;
  442.     MyFileReq->dirnamescolor = 3;
  443.     MyFileReq->filenamescolor = 7;
  444.     MyFileReq->devicenamescolor = 6;
  445.     MyFileReq->gadgettextcolor = 7;
  446.     MyFileReq->textmessagecolor = 7;
  447.     MyFileReq->stringnamecolor = 7;
  448.     MyFileReq->stringgadgetcolor = 3;
  449.     MyFileReq->boxbordercolor = 3;
  450.     MyFileReq->gadgetboxcolor = 3;
  451.     if(FileRequester(MyFileReq))
  452.         result = TRUE;
  453.     FreeMem(MyFileReq,sizeof(struct FileRequester));
  454. }
  455.  
  456. void Upload()
  457. {
  458.     char DirStr[DSIZE+1], temp[81], node[81], name[81], path[DSIZE+FCHARS+2],
  459.         file[FCHARS+1];
  460.  
  461.     xpr_setup(&io);
  462.     if(!GetProtocol(name))
  463.         return;
  464.     XProtocolBase = OpenLibrary(name,0L);
  465.     if(!XProtocolBase)
  466.     {
  467.         SimpleRequest("Error opening protocol: \"%s\"",name);
  468.         return;
  469.     }
  470.     strsfn(name,temp,temp,node,temp);
  471.     io.xpr_filename = getenv(node);
  472.     xpr_savea4();
  473.     SetupReturn = XProtocolSetup(&io);
  474.     if(!TestBit(SetupReturn,1))
  475.     {
  476.         SimpleRequest("Protocol Intialization failed.");
  477.         return;
  478.     }
  479.     MyFileReq = (struct FileRequester *)AllocMem(sizeof(struct FileRequester),MEMF_PUBLIC|MEMF_CLEAR);
  480.     if(!MyFileReq)
  481.     {
  482.         xpr_savea4();
  483.         XProtocolCleanup(&io);
  484.         CloseLibrary(XProtocolBase);
  485.         return;
  486.     }
  487.     if(!TestBit(SetupReturn,3)) // Protocol requires no file requester
  488.     {
  489.         MyFileReq->VersionNumber = 0;
  490.         MyFileReq->File = file;
  491.         MyFileReq->PathName = path;
  492.         MyFileReq->Dir = DirStr;
  493.         MyFileReq->Window = NULL;
  494.         MyFileReq->numlines = 20;
  495.         MyFileReq->numcolumns = 40;
  496.         MyFileReq->devcolumns = 10;
  497.         MyFileReq->Flags = FRQEXTSELECTM;
  498.         MyFileReq->MaxExtendedSelect = 5;
  499.         DirStr[0] = '\0';
  500.         MyFileReq->Title = "File(s) to Upload";
  501.         MyFileReq->Show[0] = '\0';
  502.         MyFileReq->detailcolor = 4;
  503.         MyFileReq->blockcolor = 7;
  504.         MyFileReq->dirnamescolor = 3;
  505.         MyFileReq->filenamescolor = 7;
  506.         MyFileReq->devicenamescolor = 6;
  507.         MyFileReq->gadgettextcolor = 7;
  508.         MyFileReq->textmessagecolor = 7;
  509.         MyFileReq->stringnamecolor = 7;
  510.         MyFileReq->stringgadgetcolor = 3;
  511.         MyFileReq->boxbordercolor = 3;
  512.         MyFileReq->gadgetboxcolor = 3;
  513.         if(!FileRequester(MyFileReq))
  514.         {
  515.             FreeMem(MyFileReq,sizeof(struct FileRequester));
  516.             xpr_savea4();
  517.             XProtocolCleanup(&io);
  518.             CloseLibrary(XProtocolBase);
  519.             return;
  520.         }
  521.         io.xpr_filename = path;
  522.     }
  523.     else
  524.         io.xpr_filename = NULL;
  525.     NewXferWindow.Screen = Scr;
  526.     NewXferWindow.Title = "Protocol Send Status";
  527.     XferWindow = OpenWindow(&NewXferWindow);
  528.     if(!XferWindow)
  529.     {
  530.         SimpleRequest("Unable to open transfer window.\n     Not enough memory?");
  531.         FreeMem(MyFileReq,sizeof(struct FileRequester));
  532.         xpr_savea4();
  533.         XProtocolCleanup(&io);
  534.         CloseLibrary(XProtocolBase);
  535.         return;
  536.     }
  537.     PrintIText(XferWindow->RPort,&XferTextList,0,0); // Print the fields
  538.     xpr_savea4();
  539.     XProtocolSend(&io);
  540.     Delay(100L);
  541.     CloseWindow(XferWindow);
  542.     XferWindow = NULL;
  543.     xpr_savea4();
  544.     XProtocolCleanup(&io);
  545.     CloseLibrary((struct Library *)XProtocolBase);
  546.     PurgeFiles(MyFileReq);
  547.     FreeMem(MyFileReq,sizeof(struct FileRequester));
  548. }
  549.  
  550. void Download()
  551. {
  552.     char DirStr[DSIZE+1], temp[81], node[81], name[81];
  553.  
  554.     xpr_setup(&io);
  555.     if(!GetProtocol(name))
  556.         return;
  557.     XProtocolBase = OpenLibrary(name,0);
  558.     if(!XProtocolBase)
  559.     {
  560.         SimpleRequest("Error opening protocol: \"%s\"",name);
  561.         return;
  562.     }
  563.     strsfn(name,temp,temp,node,temp);
  564.     io.xpr_filename = getenv(node);
  565.     xpr_savea4();
  566.     SetupReturn = XProtocolSetup(&io);
  567.     if(!TestBit(SetupReturn,1))
  568.     {
  569.         SimpleRequest("Protocol initialization failed");
  570.         CloseLibrary(XProtocolBase);
  571.         return;
  572.     }
  573.     MyFileReq = (struct FileRequester *)AllocMem(sizeof(struct FileRequester),MEMF_PUBLIC|MEMF_CLEAR);
  574.     if(!MyFileReq)
  575.     {
  576.         xpr_savea4();
  577.         XProtocolCleanup(&io);
  578.         CloseLibrary(XProtocolBase);
  579.         return;
  580.     }
  581.     if(!TestBit(SetupReturn,2)) // Protocol requires no file requester
  582.     {
  583.         MyFileReq->VersionNumber = 0;
  584.         MyFileReq->File = temp;
  585.         MyFileReq->PathName = NULL;
  586.         MyFileReq->Window = NULL;
  587.         MyFileReq->numlines = 20;
  588.         MyFileReq->numcolumns = 40;
  589.         MyFileReq->devcolumns = 10;
  590.         MyFileReq->Flags = NULL;
  591.         MyFileReq->MaxExtendedSelect = 0;
  592.         DirStr[0] = '\0';
  593.         MyFileReq->Title = "File(s) to Download";
  594.         MyFileReq->Show[0] = '\0';
  595.         MyFileReq->detailcolor = 4;
  596.         MyFileReq->blockcolor = 7;
  597.         MyFileReq->dirnamescolor = 3;
  598.         MyFileReq->filenamescolor = 7;
  599.         MyFileReq->devicenamescolor = 6;
  600.         MyFileReq->gadgettextcolor = 7;
  601.         MyFileReq->textmessagecolor = 7;
  602.         MyFileReq->stringnamecolor = 7;
  603.         MyFileReq->stringgadgetcolor = 3;
  604.         MyFileReq->boxbordercolor = 3;
  605.         MyFileReq->gadgetboxcolor = 3;
  606.         if(!FileRequester(MyFileReq))
  607.         {
  608.             FreeMem(MyFileReq,sizeof(struct FileRequester));
  609.             xpr_savea4();
  610.             XProtocolCleanup(&io);
  611.             CloseLibrary(XProtocolBase);
  612.             return;
  613.         }
  614.         io.xpr_filename = temp;
  615.     }
  616.     else
  617.         io.xpr_filename = NULL;
  618.     NewXferWindow.Screen = Scr;
  619.     NewXferWindow.Title = "Protocol Receive Status";
  620.     XferWindow = OpenWindow(&NewXferWindow);
  621.     if(!XferWindow)
  622.     {
  623.         SimpleRequest("Unable to open transfer window.\n     Not enough memory?");
  624.         FreeMem(MyFileReq,sizeof(struct FileRequester));
  625.         xpr_savea4();
  626.         XProtocolCleanup(&io);
  627.         CloseLibrary(XProtocolBase);
  628.         return;
  629.     }
  630.     PrintIText(XferWindow->RPort,&XferTextList,0,0);
  631.     xpr_savea4();
  632.     XProtocolReceive(&io);
  633.     Delay(100L); // ~1 second
  634.     CloseWindow(XferWindow);
  635.     XferWindow = NULL;
  636.     xpr_savea4();
  637.     XProtocolCleanup(&io);
  638.     CloseLibrary((struct Library *)XProtocolBase);
  639.     FreeMem(MyFileReq,sizeof(struct FileRequester));
  640. }
  641.  
  642. void *xpr_fopen(char *filename, char *accessmode)
  643. {
  644.     void *fp;
  645.     #if XPRDEBUG
  646.     ScreenOut("Entering xpr_fopen ",-1);
  647.     #endif
  648.     fp = (void *)(fopen(filename,accessmode));
  649.     #if XPRDEBUG
  650.     ScreenOut("Exiting xpr_fopen ",-1);
  651.     #endif
  652.     return fp;
  653. }
  654.  
  655. void xpr_fclose(void *filepointer)
  656. {
  657.     #if XPRDEBUG
  658.     ScreenOut("Entering xpr_fclose ",-1);
  659.     #endif
  660.     fclose((FILE *)filepointer);
  661.     #if XPRDEBUG
  662.     ScreenOut("Exiting xpr_fclose ",-1);
  663.     #endif
  664. }
  665.  
  666. long xpr_fread(char *buffer, long size, long count, void *fileptr)
  667. {
  668.     long actual;
  669.     #if XPRDEBUG
  670.     ScreenOut("Entering xpr_fread ",-1);
  671.     #endif
  672.     actual = fread(buffer,(int)size,(int)count,(FILE *)fileptr);
  673.     #if XPRDEBUG
  674.     ScreenOut("Exiting xpr_fread ",-1);
  675.     #endif
  676.     return actual;
  677. }
  678.  
  679. long xpr_fwrite(char *buffer, long size, long count, void *fileptr)
  680. {
  681.     long actual;
  682.     #if XPRDEBUG
  683.     ScreenOut("Entering xpr_fwrite ",-1);
  684.     #endif
  685.     actual = fwrite(buffer,(int)size,(int)count,(FILE *)fileptr);
  686.     #if XPRDEBUG
  687.     ScreenOut("Exiting xpr_fwrite ",-1);
  688.     #endif
  689.     return actual;
  690. }
  691.  
  692. BOOL CheckTimer()
  693. {
  694.     BOOL test;
  695.     #if XPRDEBUG
  696.     ScreenOut("Entering CheckTimer\n",-1);
  697.     #endif
  698.     if(CheckIO((struct IORequest *)timermsg))
  699.         test =  FALSE;
  700.     else
  701.         test = TRUE;
  702.     #if XPRDEBUG
  703.     ScreenOut("Exiting CheckTimer\n",-1);
  704.     #endif
  705.     return test;
  706. }
  707.  
  708. void SetTimer(long seconds, long micros)
  709. {
  710.     #if XPRDEBUG
  711.     ScreenOut("Entering SetTimer\n",-1);
  712.     #endif
  713.     while(GetMsg(TimerPort)); // Clear the timerport of crud
  714.     if(micros)
  715.     {
  716.         seconds = micros/1000000L;
  717.         micros %= 1000000L;
  718.     }
  719.     timermsg->tr_node.io_Command = TR_ADDREQUEST;
  720.     timermsg->tr_time.tv_secs = seconds;
  721.     timermsg->tr_time.tv_micro = micros;
  722.     SendIO((struct IORequest *)timermsg);
  723.     #if XPRDEBUG
  724.     ScreenOut("Exiting SetTimer\n",-1);
  725.     #endif
  726. }
  727.  
  728. void AbortTimer()
  729. {
  730.     #if XPRDEBUG
  731.     ScreenOut("Entering AbortTimer\n",-1);
  732.     #endif
  733.     AbortIO((struct IORequest *)timermsg);
  734.     Wait(1L << TimerPort->mp_SigBit);
  735.     (void)GetMsg(TimerPort);
  736.     #if XPRDEBUG
  737.     ScreenOut("Exiting AbortTimer\n",-1);
  738.     #endif
  739. }
  740.  
  741. long xpr_sread(char *buffer, long size, long timeout)
  742. {
  743.     long signals, actual = 0L;
  744.  
  745.     #if XPRDEBUG
  746.     ScreenOut("Entering xpr_sread ",-1);
  747.     #endif
  748.     /* Test for carrier before anything else
  749.     SerialIn->IOSer.io_Command = SDCMD_QUERY;
  750.     DoIO((struct IORequest *)SerialIn);
  751.     if(TestBit(SerialIn->io_Status,6))
  752.         return -1L; no carrier, exit */
  753.     if(timeout)
  754.     {
  755.         QueueSerial(buffer,size);
  756.         SetTimer(0, timeout);
  757.         signals = Wait((1L << SerialReadPort->mp_SigBit)|(1L << TimerPort->mp_SigBit));
  758.         if(signals & (1L << SerialReadPort->mp_SigBit))
  759.         {
  760.             (void)GetMsg(SerialReadPort);
  761.             AbortTimer();
  762.         }
  763.         if(signals & (1L << TimerPort->mp_SigBit))
  764.         {
  765.             (void)GetMsg(TimerPort);
  766.             AbortIO((struct IORequest *)SerialIn);
  767.             Wait(1L << SerialReadPort->mp_SigBit);
  768.             (void)GetMsg(SerialReadPort);
  769.         }
  770.         actual = (long)SerialIn->IOSer.io_Actual;
  771.         if(SerialIn->IOSer.io_Error)
  772.             actual = -1L;
  773.     }
  774.     else
  775.     {
  776.         SerialIn->IOSer.io_Command = SDCMD_QUERY;
  777.         DoIO((struct IORequest *)SerialIn);
  778.         if(SerialIn->IOSer.io_Actual > size)
  779.             SerialIn->IOSer.io_Length = size;
  780.         else
  781.             SerialIn->IOSer.io_Length = SerialIn->IOSer.io_Actual;
  782.         SerialIn->IOSer.io_Command = CMD_READ;
  783.         SerialIn->IOSer.io_Data = (APTR)buffer;
  784.         SerialIn->IOSer.io_Error = 0;
  785.         DoIO((struct IORequest *)SerialIn);
  786.         actual = (long)SerialIn->IOSer.io_Actual;
  787.         if(SerialIn->IOSer.io_Error)
  788.             actual = -1L;
  789.     }
  790.     #if XPRDEBUG
  791.     ScreenOut("Exiting xpr_sread ",-1);
  792.     #endif
  793.     return actual;
  794. }
  795.  
  796. long xpr_swrite(char *buffer, long size)
  797. {
  798.     #if XPRNODEBUG
  799.     ScreenOut("Entering xpr_swrite ",-1);
  800.     #endif
  801.     /* check for carrier real quick
  802.     SerialOut->IOSer.io_Command = SDCMD_QUERY;
  803.     DoIO((struct IORequest *)SerialOut);
  804.     if(TestBit(SerialOut->io_Status,6))
  805.         return 1L; no carrier, exit */
  806.     ModemOut(buffer,size);
  807.     #if XPRNODEBUG
  808.     ScreenOut("Exiting xpr_swrite ",-1);
  809.     #endif
  810.     return (long)SerialOut->IOSer.io_Error;
  811. }
  812.  
  813. long xpr_sflush()
  814. {
  815.     #if XPRDEBUG
  816.     ScreenOut("Entering xpr_sflush ",-1);
  817.     #endif
  818.     SerialOut->IOSer.io_Command = CMD_FLUSH;
  819.     DoIO((struct IORequest *)SerialOut);
  820.     #if XPRDEBUG
  821.     ScreenOut("Exiting xpr_sflush ",-1);
  822.     #endif
  823.     return (long)SerialOut->IOSer.io_Error;
  824. }
  825.  
  826. long xpr_update(struct XPR_UPDATE *updatestruct)
  827. {
  828.     struct IntuiText CurrentText;
  829.     char temp[81], temp2[81];
  830.     long percent;
  831.     double tempnum;
  832.  
  833.     #if XPRDEBUG
  834.     ScreenOut("Entering xpr_update ",-1);
  835.     #endif
  836.     CurrentText.DrawMode = JAM2;
  837.     CurrentText.FrontPen = 7;
  838.     CurrentText.BackPen = 0;
  839.     CurrentText.NextText = NULL;
  840.     CurrentText.ITextFont = NULL;
  841.  
  842.     if((updatestruct->xpru_updatemask)&XPRU_PROTOCOL)
  843.     {
  844.         sprintf(temp,"%-16s",updatestruct->xpru_protocol);
  845.         CurrentText.TopEdge = XferText1.TopEdge;
  846.         CurrentText.LeftEdge = XferText1.LeftEdge+IntuiTextLength(&XferText1)+8;
  847.         CurrentText.IText = temp;
  848.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  849.     }
  850.     if(updatestruct->xpru_updatemask&XPRU_FILENAME)
  851.     {
  852.         sprintf(temp,"%-36s",updatestruct->xpru_filename);
  853.         CurrentText.TopEdge = XferText2.TopEdge;
  854.         CurrentText.LeftEdge = XferText2.LeftEdge+IntuiTextLength(&XferText2)+8;
  855.         CurrentText.IText = temp;
  856.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  857.     }
  858.     if(updatestruct->xpru_updatemask&XPRU_BYTES)
  859.     {
  860.         sprintf(temp,"%-10ld",updatestruct->xpru_bytes);
  861.         CurrentText.TopEdge = XferText3.TopEdge;
  862.         CurrentText.LeftEdge = XferText3.LeftEdge+IntuiTextLength(&XferText3)+8;
  863.         CurrentText.IText = temp;
  864.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  865.  
  866.         CurrentText.TopEdge = XferText13.TopEdge;
  867.         CurrentText.LeftEdge = XferText13.LeftEdge+IntuiTextLength(&XferText13)+8;
  868.         if(filesize == 0L) // better safe than sorry
  869.             percent = 0L;
  870.         else
  871.         {
  872.             tempnum = (double)(updatestruct->xpru_bytes)/filesize;
  873.             tempnum = (double)tempnum*100.0;
  874.             percent = (long)tempnum;
  875.         }
  876.         sprintf(temp,"%ld%%",percent);
  877.         sprintf(temp2,"%-5s",temp);
  878.         CurrentText.IText = temp2;
  879.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  880.     }
  881.     if(updatestruct->xpru_updatemask&XPRU_FILESIZE)
  882.     {
  883.         sprintf(temp,"%-12ld",updatestruct->xpru_filesize);
  884.         CurrentText.TopEdge = XferText4.TopEdge;
  885.         CurrentText.LeftEdge = XferText4.LeftEdge+IntuiTextLength(&XferText4)+8;
  886.         CurrentText.IText = temp;
  887.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  888.         filesize = updatestruct->xpru_filesize;
  889.     }
  890.     if(updatestruct->xpru_updatemask&XPRU_BLOCKSIZE)
  891.     {
  892.         sprintf(temp,"%-12ld",updatestruct->xpru_blocksize);
  893.         CurrentText.TopEdge = XferText5.TopEdge;
  894.         CurrentText.LeftEdge = XferText5.LeftEdge+IntuiTextLength(&XferText5)+8;
  895.         CurrentText.IText = temp;
  896.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  897.     }
  898.     if(updatestruct->xpru_updatemask&XPRU_ERRORS)
  899.     {
  900.         sprintf(temp,"%-12ld",updatestruct->xpru_errors);
  901.         CurrentText.TopEdge = XferText6.TopEdge;
  902.         CurrentText.LeftEdge = XferText6.LeftEdge+IntuiTextLength(&XferText6)+8;
  903.         CurrentText.IText = temp;
  904.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  905.     }
  906.     if(updatestruct->xpru_updatemask&XPRU_MSG)
  907.     {
  908.         sprintf(temp,"%-36s",updatestruct->xpru_msg);
  909.         CurrentText.TopEdge = XferText7.TopEdge;
  910.         CurrentText.LeftEdge = XferText7.LeftEdge+IntuiTextLength(&XferText7)+8;
  911.         CurrentText.IText = temp;
  912.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  913.     }
  914.     if(updatestruct->xpru_updatemask&XPRU_ERRORMSG)
  915.     {
  916.         sprintf(temp,"%-32s",updatestruct->xpru_errormsg);
  917.         CurrentText.TopEdge = XferText8.TopEdge;
  918.         CurrentText.LeftEdge = XferText8.LeftEdge+IntuiTextLength(&XferText8)+8;
  919.         CurrentText.IText = temp;
  920.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  921.     }
  922.     if(updatestruct->xpru_updatemask&XPRU_DATARATE)
  923.     {
  924.         sprintf(temp,"%-11ld",updatestruct->xpru_datarate);
  925.         CurrentText.TopEdge = XferText9.TopEdge;
  926.         CurrentText.LeftEdge = XferText9.LeftEdge+IntuiTextLength(&XferText9)+8;
  927.         CurrentText.IText = temp;
  928.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  929.     }
  930.     if(updatestruct->xpru_updatemask&XPRU_BLOCKCHECK)
  931.     {
  932.         sprintf(temp,"%-11s",updatestruct->xpru_blockcheck);
  933.         CurrentText.TopEdge = XferText10.TopEdge;
  934.         CurrentText.LeftEdge = XferText10.LeftEdge+IntuiTextLength(&XferText10)+8;
  935.         CurrentText.IText = temp;
  936.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  937.     }
  938.     if(updatestruct->xpru_updatemask&XPRU_EXPECTTIME)
  939.     {
  940.         sprintf(temp,"%-12s",updatestruct->xpru_expecttime);
  941.         CurrentText.TopEdge = XferText11.TopEdge;
  942.         CurrentText.LeftEdge = XferText11.LeftEdge+IntuiTextLength(&XferText11)+8;
  943.         CurrentText.IText = temp;
  944.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  945.     }
  946.     if(updatestruct->xpru_updatemask&XPRU_ELAPSEDTIME)
  947.     {
  948.         sprintf(temp,"%-12s",updatestruct->xpru_elapsedtime);
  949.         CurrentText.TopEdge = XferText12.TopEdge;
  950.         CurrentText.LeftEdge = XferText12.LeftEdge+IntuiTextLength(&XferText12)+8;
  951.         CurrentText.IText = temp;
  952.         PrintIText(XferWindow->RPort,&CurrentText,0,0);
  953.     }
  954.     {
  955.     }
  956.     #if XPRDEBUG
  957.     ScreenOut("Exiting xpr_update ",-1);
  958.     #endif
  959.     return 0L;
  960. }
  961.  
  962. long xpr_gets(char *prompt, char *buffer)
  963. {
  964.     #if XPRDEBUG
  965.     ScreenOut("Entering xpr_gets ",-1);
  966.     #endif
  967.     GetString(buffer,prompt,NULL,78,255);
  968.     #if XPRDEBUG
  969.     ScreenOut("Exiting xpr_gets ",-1);
  970.     #endif
  971.     return 0L;
  972. }
  973.  
  974. long SetBit(long number, int BitNum)
  975. {
  976.     long power = 1L;
  977.     int i = 1;
  978.     while(i<BitNum)
  979.     {
  980.         power *= 2L;
  981.         i++;
  982.     }
  983.     number |= power;
  984.     return number;
  985. }
  986.  
  987. BOOL TestBit(long number, int BitNum)
  988. {
  989.     int i = 1;
  990.     long power = 1L;
  991.     while(i<BitNum)
  992.     {
  993.         power *= 2L;
  994.         i++;
  995.     }
  996.     if((power&number) == power)
  997.         return TRUE;
  998.     else
  999.         return FALSE;
  1000. }
  1001.  
  1002. long xpr_setserial(long newstatus)
  1003. {
  1004.     int i;
  1005.     short bite = 0; // not to be confused with bit or byte!
  1006.     long number = 0L;
  1007.  
  1008.     #if XPRDEBUG
  1009.     ScreenOut("Entering xpr_setserial ",-1);
  1010.     #endif
  1011.     if(newstatus == -1) // Don't set anything, just return SP status
  1012.     {
  1013.         if(SerialIn->io_SerFlags&SERF_PARTY_ON)
  1014.             SetBit(number,1); // Parity on, set the bit
  1015.         if(SerialIn->io_SerFlags&SERF_PARTY_ODD)
  1016.             SetBit(number,2);    // Parity odd, set the bit
  1017.         if(SerialIn->io_SerFlags&SERF_7WIRE)
  1018.             SetBit(number,3);    // 7 wire handshake on, set the bit
  1019.         if(SerialIn->io_SerFlags&SERF_QUEUEDBRK)
  1020.             SetBit(number,4); // break commands queued, set the bit
  1021.         if(SerialIn->io_SerFlags&SERF_RAD_BOOGIE)
  1022.             SetBit(number,5); // rad boogie high speed, set the bit
  1023.         if(SerialIn->io_SerFlags&SERF_SHARED)
  1024.             SetBit(number,6); // SP shared, set the bit
  1025.         if(SerialIn->io_SerFlags&SERF_EOFMODE)
  1026.             SetBit(number,7); // EOF mode being used, set the bit
  1027.         if(SerialIn->io_SerFlags&SERF_XDISABLED)
  1028.             SetBit(number,8); // Xon/Xoff handshake disabled, set the bit
  1029.         if(SerialIn->io_ExtFlags&SEXTF_MSPON)
  1030.             SetBit(number,9); // Mark/Space parity being used, set the bit
  1031.         if(SerialIn->io_ExtFlags&SEXTF_MARK)
  1032.             SetBit(number,10); // Mark parity used, set the bit
  1033.         if(SerialIn->io_StopBits == 2)
  1034.             SetBit(number,11); // 2 stop bits, set the bit
  1035.         if(SerialIn->io_ReadLen == 7)
  1036.             SetBit(number,12); // 7 bit read length, set the bit
  1037.         if(SerialIn->io_WriteLen == 7)
  1038.             SetBit(number,13); // 7 bit write length, set the bit
  1039.         switch(SerialIn->io_Baud)
  1040.         {
  1041.             case 300:    SetBit(number,17); // 300 bps
  1042.                             break;
  1043.             case 1200:    SetBit(number,18); // 1200 bps
  1044.                             break;
  1045.             case 2400:    SetBit(number,17);
  1046.                             SetBit(number,18); // 2400 bps
  1047.                             break;
  1048.             case 4800:    SetBit(number,19); // 4800 bps
  1049.                             break;
  1050.             case 9600:    SetBit(number,19);
  1051.                             SetBit(number,17); // 9600 bps
  1052.                             break;
  1053.             case 19200:    SetBit(number,19);
  1054.                             SetBit(number,18); // 19200 bps
  1055.                             break;
  1056.             case 38400:    SetBit(number,20); // 38400 bps
  1057.                             break;
  1058.             case 57600:    SetBit(number,20);
  1059.                             SetBit(number,17); // 57600 bps
  1060.                             break;
  1061.             case 76800:    SetBit(number,20);
  1062.                             SetBit(number,18); // 76800 bps
  1063.                             break;
  1064.             case 115200:SetBit(number,20);
  1065.                             SetBit(number,18);
  1066.                             SetBit(number,19); // 115200 bps
  1067.                             break;
  1068.         }
  1069.     }
  1070.     else
  1071.     {
  1072.         number = newstatus;
  1073.         if(TestBit(number,1))
  1074.             SerialIn->io_SerFlags |= SERF_PARTY_ON;
  1075.         if(TestBit(number,2))
  1076.             SerialIn->io_SerFlags |= SERF_PARTY_ODD;
  1077.         if(TestBit(number,3))
  1078.             SerialIn->io_SerFlags |= SERF_7WIRE;
  1079.         if(TestBit(number,4))
  1080.             SerialIn->io_SerFlags |= SERF_QUEUEDBRK;
  1081.         if(TestBit(number,5))
  1082.             SerialIn->io_SerFlags |= SERF_RAD_BOOGIE;
  1083.         if(TestBit(number,6))
  1084.             SerialIn->io_SerFlags |= SERF_SHARED;
  1085.         if(TestBit(number,7))
  1086.             SerialIn->io_SerFlags |= SERF_EOFMODE;
  1087.         if(TestBit(number,8))
  1088.             SerialIn->io_SerFlags |= SERF_XDISABLED;
  1089.         if(TestBit(number,9))
  1090.             SerialIn->io_ExtFlags |= SEXTF_MSPON;
  1091.         if(TestBit(number,10))
  1092.             SerialIn->io_ExtFlags |= SEXTF_MARK;
  1093.         SerialOut->io_ExtFlags = SerialIn->io_ExtFlags;
  1094.         if(TestBit(number,11))
  1095.             SerialIn->io_StopBits = 2;
  1096.         else
  1097.             SerialIn->io_StopBits = 1;
  1098.         SerialOut->io_StopBits = SerialIn->io_StopBits;
  1099.         if(TestBit(number,12))
  1100.             SerialIn->io_ReadLen = 7;
  1101.         else
  1102.             SerialIn->io_ReadLen = 8;
  1103.         SerialOut->io_ReadLen = SerialIn->io_ReadLen;
  1104.         if(TestBit(number,13))
  1105.             SerialIn->io_WriteLen = 7;
  1106.         else
  1107.             SerialIn->io_WriteLen = 8;
  1108.         SerialOut->io_WriteLen = SerialIn->io_WriteLen;
  1109.         // Extract byte 3 to determine baud rate (easier than other way)
  1110.         for(i=1;i<=8;i++)
  1111.             if(TestBit(number,i+16))
  1112.                 SetBit(bite,i);
  1113.         switch(bite)
  1114.         {
  1115.             case 0:    SerialIn->io_Baud = 110;
  1116.                         break;
  1117.             case 1:    SerialIn->io_Baud = 300;
  1118.                         break;
  1119.             case 2:    SerialIn->io_Baud = 1200;
  1120.                         break;
  1121.             case 3:    SerialIn->io_Baud = 2400;
  1122.                         break;
  1123.             case 4:    SerialIn->io_Baud = 4800;
  1124.                         break;
  1125.             case 5:    SerialIn->io_Baud = 9600;
  1126.                         break;
  1127.             case 6:    SerialIn->io_Baud = 19200;
  1128.                         break;
  1129.             case 8:    SerialIn->io_Baud = 38400;
  1130.                         break;
  1131.             case 9:    SerialIn->io_Baud = 57600;
  1132.                         break;
  1133.             case 10:    SerialIn->io_Baud = 76800;
  1134.                         break;
  1135.             case 11:    SerialIn->io_Baud = 115200;
  1136.         }
  1137.         SerialOut->io_Baud = SerialIn->io_Baud;
  1138.         SerialIn->IOSer.io_Command = SDCMD_SETPARAMS;
  1139.         DoIO((struct IORequest *)SerialIn);
  1140.         if(SerialIn->IOSer.io_Error)
  1141.             number = -1L;
  1142.         else
  1143.         {
  1144.             SerialOut->IOSer.io_Command = SDCMD_SETPARAMS;
  1145.             DoIO((struct IORequest *)SerialOut);
  1146.         }
  1147.     }
  1148.     #if XPRDEBUG
  1149.     ScreenOut("Exiting xpr_setserial ",-1);
  1150.     #endif
  1151.     return number;
  1152. }
  1153.  
  1154. long xpr_fseek(void *fp, long offset, long origin)
  1155. {
  1156.     long number;
  1157.     #if XPRDEBUG
  1158.     ScreenOut("Entering xpr_fseek ",-1);
  1159.     #endif
  1160.     number =  fseek((FILE *)fp,offset,origin);
  1161.     #if XPRDEBUG
  1162.     ScreenOut("Exiting xpr_fseek ",-1);
  1163.     #endif
  1164.     return number;
  1165. }
  1166.  
  1167. long xpr_chkabort()
  1168. {
  1169.     struct IntuiMessage *IntuiMsg = NULL;
  1170.     long number = 0L;
  1171.  
  1172.     #if XPRDEBUG
  1173.     ScreenOut("Entering xpr_chkabort ",-1);
  1174.     #endif
  1175.     while(IntuiMsg = (struct IntuiMessage *)GetMsg(XferWindow->UserPort))
  1176.     {
  1177.         if(!IntuiMsg)
  1178.             number = 0L;
  1179.         else
  1180.         {
  1181.             if(IntuiMsg->Class == CLOSEWINDOW)
  1182.                 number = -1L; // Abort this transfer
  1183.             ReplyMsg((struct Message *)IntuiMsg);
  1184.         }
  1185.     }
  1186.     #if XPRDEBUG
  1187.     ScreenOut("Exiting xpr_chkabort ",-1);
  1188.     #endif
  1189.     /* check for loss of carrier too
  1190.     SerialIn->IOSer.io_Command = SDCMD_QUERY;
  1191.     DoIO((struct IORequest *)SerialIn);
  1192.     if(TestBit(SerialIn->io_Status,6))
  1193.         number = -1; */
  1194.     return number;
  1195. }
  1196.  
  1197. long xpr_chkmisc()
  1198. {
  1199.     #if XPRDEBUG
  1200.     ScreenOut("Entering xpr_chkmisc ",-1);
  1201.     #endif
  1202.     #if XPRDEBUG
  1203.     ScreenOut("Exiting xpr_chkmisc ",-1);
  1204.     #endif
  1205.     return 0L;
  1206. }
  1207.  
  1208. long xpr_options(long n, struct xpr_option *opt[])
  1209. {
  1210.     int i;
  1211.     long def;
  1212.     struct GetLongStruct LongStruct;
  1213.  
  1214.     #if XPRDEBUG
  1215.     ScreenOut("Entering xpr_options ",-1);
  1216.     #endif
  1217.     for(i=0;i<=n;i++)
  1218.     {
  1219.         switch(opt[i]->xpro_type)
  1220.         {
  1221.             case XPRO_HEADER:        SimpleRequest(opt[i]->xpro_description);
  1222.                                         break;
  1223.             case XPRO_BOOLEAN:    if(TwoGadRequest(opt[i]->xpro_description))
  1224.                                             strcpy(opt[i]->xpro_value,"yes");
  1225.                                         else
  1226.                                             strcpy(opt[i]->xpro_value,"no");
  1227.                                         break;
  1228.             case XPRO_LONG:        LongStruct.titlebar = opt[i]->xpro_description;
  1229.                                         sscanf(opt[i]->xpro_value,"%ld",&def);
  1230.                                         LongStruct.defaultval = def;
  1231.                                         LongStruct.minlimit = 0L;
  1232.                                         LongStruct.maxlimit = 65535L;
  1233.                                         LongStruct.window = NULL;
  1234.                                         LongStruct.versionnumber = 0;
  1235.                                         LongStruct.flags = NULL;
  1236.                                         LongStruct.rfu2 = 0;
  1237.                                         LongStruct.result = 0;
  1238.                                         GetLong(&LongStruct);
  1239.                                         sprintf(opt[i]->xpro_value,"%ld",LongStruct.result);
  1240.                                         break;
  1241.             case XPRO_STRING:        GetString(opt[i]->xpro_value,opt[i]->xpro_description,NULL,78,opt[i]->xpro_length);
  1242.                                         break;
  1243.             case XPRO_COMMAND:    if(TwoGadRequest(opt[i]->xpro_description))
  1244.                                             strcpy(opt[i]->xpro_value,"yes");
  1245.                                         else
  1246.                                             strcpy(opt[i]->xpro_value,"no");
  1247.                                         return 0L;
  1248.                                         break;
  1249.             case XPRO_COMMPAR:    GetString(opt[i]->xpro_value,opt[i]->xpro_description,NULL,78,opt[i]->xpro_length);
  1250.                                         return 0L;
  1251.                                         break;
  1252.         }
  1253.     }
  1254.     #if XPRDEBUG
  1255.     ScreenOut("Exiting xpr_options ",-1);
  1256.     #endif
  1257. }
  1258.  
  1259. long xpr_unlink(char *filename)
  1260. {
  1261.     long number;
  1262.     #if XPRDEBUG
  1263.     ScreenOut("Entering xpr_unlink ",-1);
  1264.     #endif
  1265.     number = unlink(filename);
  1266.     #if XPRDEBUG
  1267.     ScreenOut("Exiting xpr_unlink ",-1);
  1268.     #endif
  1269.     return number;
  1270. }
  1271.  
  1272. long xpr_squery()
  1273. {
  1274.     #if XPRDEBUG
  1275.     ScreenOut("Entering xpr_squery ",-1);
  1276.     #endif
  1277.     SerialIn->IOSer.io_Command = SDCMD_QUERY;
  1278.     DoIO((struct IORequest *)SerialIn);
  1279.     #if XPRDEBUG
  1280.     ScreenOut("Exiting xpr_squery ",-1);
  1281.     #endif
  1282.     return (long)SerialIn->IOSer.io_Actual;
  1283. }
  1284.  
  1285. long xpr_getptr(long type)
  1286. {
  1287.     long number = 0L;
  1288.     #if XPRDEBUG
  1289.     ScreenOut("Entering xpr_getptr ",-1);
  1290.     #endif
  1291.     if(type == 1L)
  1292.         number = (long)Scr;
  1293.     #if XPRDEBUG
  1294.     ScreenOut("Exiting xpr_getptr ",-1);
  1295.     #endif
  1296.     return number;
  1297. }
  1298.  
  1299. long xpr_finfo(char *filename, long typeofinfo)
  1300. {
  1301.     struct FileInfoBlock *Info;
  1302.     BPTR mylock;
  1303.     long success;
  1304.     long number;
  1305.  
  1306.     #if XPRDEBUG
  1307.     ScreenOut("Entering xpr_finfo ",-1);
  1308.     #endif
  1309.     if(typeofinfo == 1L)
  1310.     {
  1311.         Info = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR);
  1312.         if(!Info)
  1313.             return 0L;
  1314.         mylock = Lock(filename,ACCESS_READ);
  1315.         if(!mylock)
  1316.         {
  1317.             FreeMem(Info,sizeof(struct FileInfoBlock));
  1318.             return 0L;
  1319.         }
  1320.         success = Examine(mylock,Info);
  1321.         UnLock(mylock);
  1322.         if(!success)
  1323.         {
  1324.             FreeMem(Info,sizeof(struct FileInfoBlock));
  1325.             return 0L;
  1326.         }
  1327.         number = Info->fib_Size;
  1328.         FreeMem(Info,sizeof(struct FileInfoBlock));
  1329.     }
  1330.     if(typeofinfo == 2L)
  1331.         number = 1L; // For now, everything is binary :)
  1332.     #if XPRDEBUG
  1333.     ScreenOut("Exiting xpr_finfo ",-1);
  1334.     #endif
  1335.     return number;
  1336. }
  1337.  
  1338. void xpr_setup(struct XPR_IO *XprIO)
  1339. {
  1340.     XprIO->xpr_filename = NULL;
  1341.     XprIO->xpr_fopen    = axpr_fopen;
  1342.     XprIO->xpr_fclose   = axpr_fclose;
  1343.     XprIO->xpr_fread    = axpr_fread;
  1344.     XprIO->xpr_fwrite   = axpr_fwrite;
  1345.     XprIO->xpr_sread    = axpr_sread;
  1346.     XprIO->xpr_swrite   = axpr_swrite;
  1347.     XprIO->xpr_sflush   = axpr_sflush;
  1348.     XprIO->xpr_update   = axpr_update;
  1349.     XprIO->xpr_chkabort = axpr_chkabort;
  1350.     XprIO->xpr_chkmisc  = axpr_chkmisc;
  1351.     XprIO->xpr_gets     = axpr_gets;
  1352.     XprIO->xpr_setserial = axpr_setserial;
  1353.     XprIO->xpr_ffirst    = NULL;  // axpr_ffirst;
  1354.     XprIO->xpr_fnext     = NULL;  // axpr_fnext;
  1355.     XprIO->xpr_finfo     = axpr_finfo;
  1356.     XprIO->xpr_fseek     = axpr_fseek;
  1357.     XprIO->xpr_extension = 4;
  1358.     XprIO->xpr_data      = NULL;
  1359.     XprIO->xpr_options   = axpr_options;
  1360.     XprIO->xpr_unlink    = axpr_unlink;
  1361.     XprIO->xpr_squery    = axpr_squery;
  1362.     XprIO->xpr_getptr    = axpr_getptr;
  1363. }
  1364.  
  1365. long xpr_ffirst(char *buffer, char *pattern)
  1366. {
  1367.     if(!MyFileReq->ExtendedSelect)
  1368.         return 0L;
  1369.     strncpy(buffer,MyFileReq->ExtendedSelect->thefilename,MyFileReq->ExtendedSelect->NameLength);
  1370.     if(MyFileReq->ExtendedSelect->NextFile)
  1371.         return (long)MyFileReq->ExtendedSelect->NextFile;
  1372.     else
  1373.         return 1L;   // we'll look for this value in xpr_fnext()
  1374. }
  1375.  
  1376. long xpr_fnext(long oldstate, char *buffer, char *pattern)
  1377. {
  1378.     struct ESStructure *ptr;
  1379.  
  1380.     if(oldstate == 1L)
  1381.         return 0L;   // there was NO next file, ignore it all
  1382.     ptr = (struct ESStructure *)oldstate;
  1383.     strncpy(buffer,ptr->thefilename,ptr->NameLength);
  1384.     if(ptr->NextFile)
  1385.         return (long)ptr->NextFile;
  1386.     else
  1387.         return 1L;
  1388. }
  1389.