/* Reset.server emulator (c) 1997 Paweî Marciniak <pmarciniak@lodz.home.pl>*/
/* Wersja finaîowa Niedziela 12-Kwi-98    13:11:00 */
/* róûne poprawki Niedziela 20-Wrz-98    19:13:19 */
/* róûne poprawki Niedziela 14-Lut-98    18:14:19 */
      
#include <stdio.h>
#include <string.h>
#include <exec/execbase.h>
#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <devices/serial.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/diskfont.h>
#include <proto/dos.h>
#include <proto/icon.h>
#include <stdlib.h>

#include <proto/image.h>
#include <libraries/image.h>

#include <gadgets/tabs.h>

#include "ResetServer_globals.h"
#include "ResetServer.h"

#include	"ResetServer_rev.h"

#define	LineDraw(x,y,x2,y2)	Move( APP_Window->RPort, x , y); \
		Draw( APP_Window->RPort, x2, y2 )

static	UBYTE	verstr[]={ VERSTAG };

char __stdiowin[]="CON:10/10/600/240/Reset.server emulator/CLOSE/WAIT/AUTO";

extern struct ExecBase *SysBase;

struct MsgPort *serverport;
struct SignalSemaphore sem;

ULONG sig=0L, sigwin=0L, sigmsg=0L;

BYTE path[1024], header[256], prtdev[108];
ULONG prtunit=0;

/* Tytaj zaczynajâ sië wszystkie poûyteczne funkcje */

/* Funkcja dodaje tekst do listy historylist */
int AddHistory( struct List *historylist, STRPTR text )
{
  struct Node *node;
  STRPTR safetext;
  if(!( safetext=AllocVec( (strlen(text)+1), MEMF_PUBLIC )))
  {
    return( FALSE );
  }
  strcpy( safetext, text );
  if(!( node=AllocVec( sizeof(struct Node), MEMF_PUBLIC|MEMF_CLEAR )))
  {
    FreeVec( safetext );
    return( FALSE );
  }
  node->ln_Name = safetext;
  ObtainSemaphore( &sem );
  AddTail( historylist, node );
  ReleaseSemaphore( &sem );
  return( TRUE );
}

/* Funkcja czyôci historylist */
void RemHistory( struct List *historylist )
{
  struct Node *node;

  ObtainSemaphore( &sem );
  for( node=historylist->lh_Head; node->ln_Succ; node=historylist->lh_Head )
  {
    Remove( node );
    FreeVec( node->ln_Name );
    FreeVec( node );
  }
  ReleaseSemaphore( &sem );

}


/* Funkcje Reset.server */
void SendWarning( struct List *portlist )
{
  struct RWNode *node;
  struct RWMessage *WarnMsg;

  ObtainSemaphore( &sem );
  for( node=(struct RWNode *)portlist->lh_Head; node->rwn_Node.ln_Succ; node=(struct RWNode *)node->rwn_Node.ln_Succ )
  {
    if(node->rwn_MsgPort)
    {
		  WarnMsg=(struct RWMessage *)AllocVec( sizeof(struct RWMessage), MEMF_PUBLIC|MEMF_CLEAR );
  		WarnMsg->rwm_Message.mn_ReplyPort=serverport;
  		WarnMsg->rwm_MsgType=RWM_RESETWARNING;
      PutMsg( node->rwn_MsgPort, (struct Message *)WarnMsg);
    }
  }
  ReleaseSemaphore( &sem );
}

/* Funkcja dodaje msgport do listy portlist */
int RW_AddPort( struct List *portlist, struct RWMessage *rwmsg )
{
  struct RWNode *node;

  if( node=(struct RWNode *)AllocVec( sizeof(struct RWNode), MEMF_PUBLIC|MEMF_CLEAR ) )
  {
    node->rwn_MsgPort = rwmsg->rwm_MsgPort;
    node->rwn_ProgName = rwmsg->rwm_ProgName;
    node->rwn_Node.ln_Name = rwmsg->rwm_ProgName;
    ObtainSemaphore( &sem );
    AddTail( portlist, (struct Node *)node );
    ReleaseSemaphore( &sem );
    return( TRUE );
  }
  return( FALSE );
}

/* Funkcja usuwa msgport z listy portlist */
void RW_RemPort( struct List *portlist, struct RWMessage *rwmsg )
{
  struct RWNode *node;

  ObtainSemaphore( &sem );
  for( node=(struct RWNode *)portlist->lh_Head; node->rwn_Node.ln_Succ; node=(struct RWNode *)node->rwn_Node.ln_Succ )
  {
    if(node->rwn_MsgPort==rwmsg->rwm_MsgPort)
    {
      Remove( (struct Node *)node );
      FreeVec( node );
      break;
    }
  }
  ReleaseSemaphore( &sem );
}

/* Busy Win */
BOOL BusyStart( struct Window *win, struct Requester *waitRequest )
{
  InitRequester( waitRequest );
  if( Request( waitRequest, win ))
  {
    SetWindowPointer( win, WA_BusyPointer, TRUE, TAG_DONE );
    return( TRUE );
  }
  else
    return( FALSE );
}

VOID BusyEnd( struct Window *win, struct Requester *waitRequest )
{
  ClearPointer( win );
  EndRequest( waitRequest, win );
}


/* Funkcja zapisuje historylist do pliku */
LONG WriteHistory( STRPTR filename, STRPTR header, struct List *historylist )
{
  BPTR fh;
  struct Node *node;
  struct Requester busyreq;
	BOOL busy=FALSE;

  busy=BusyStart( APP_Window, &busyreq );

  if(!( fh=Open( filename, MODE_READWRITE )))
	{
		if( busy ) BusyEnd( APP_Window, &busyreq );
    return( FALSE );
	}
  Seek( fh, 0, OFFSET_END );

  if((Write( fh, header, strlen( header ))) == -1)
  {
    Close( fh );
  	if( busy ) BusyEnd( APP_Window, &busyreq );
    return( FALSE );
  }

	ObtainSemaphore( &sem );
  for( node=historylist->lh_Head; node->ln_Succ; node=node->ln_Succ )
  {
    if((Write( fh, node->ln_Name, strlen( node->ln_Name ))) == -1)
    {
      Close( fh );
    	if( busy ) BusyEnd( APP_Window, &busyreq );
    	ReleaseSemaphore( &sem );
      return( FALSE );
    }

    if((Write( fh, "\n", 1 )) == -1)
    {
      Close( fh );
    	if( busy ) BusyEnd( APP_Window, &busyreq );
    	ReleaseSemaphore( &sem );
      return( FALSE );
    }
  }
  ReleaseSemaphore( &sem );
  Close( fh );
  if( busy ) BusyEnd( APP_Window, &busyreq );
  return( TRUE );
}

LONG PrintHistory( STRPTR devicename, ULONG deviceunit, struct List *historylist )
{
	struct MsgPort *ioport=NULL;
	struct IOStdReq *ioreq=NULL;
	struct Node *node;

	if (!(ioport=CreatePort( NULL, 0L )))
		return( 1 );	
	if (!(ioreq=CreateIORequest( ioport, sizeof(struct IOStdReq))))
	{
		DeletePort ( ioport );
		return( 2 );
	}
	if (OpenDevice( devicename, deviceunit, (struct IORequest *)ioreq, 0L ))
	{
		DeleteIORequest( ioreq );
		DeletePort ( ioport );
		return( 3 );
	}

	ObtainSemaphore( &sem );
  for( node=historylist->lh_Head; node->ln_Succ; node=node->ln_Succ )
  {
		ioreq->io_Command=CMD_WRITE;
		ioreq->io_Data=(APTR)node->ln_Name;
		ioreq->io_Length=-1;
		if (DoIO ((struct IORequest *)ioreq))
		{
			ReleaseSemaphore( &sem );
			CloseDevice( (struct IORequest *)ioreq );
			DeleteIORequest( ioreq );
			DeletePort ( ioport );
			return( 4 );
		}
    ioreq->io_Command=CMD_WRITE;
		ioreq->io_Data=(APTR)"\n";
		ioreq->io_Length=-1;
		if (DoIO ((struct IORequest *)ioreq))
		{
			ReleaseSemaphore( &sem );
			CloseDevice( (struct IORequest *)ioreq );
			DeleteIORequest( ioreq );
			DeletePort ( ioport );
			return( 4 );
		}
	}
	ReleaseSemaphore( &sem );

	CloseDevice( (struct IORequest *)ioreq );
	DeleteIORequest( ioreq );
	DeletePort ( ioport );
	return( 0 );
}


struct ClassLibrary *openclass (STRPTR name, ULONG version)
{
    struct Library *retval;
    UBYTE buffer[256];

    if ((retval = OpenLibrary (name, version)) == NULL)
    {
	sprintf (buffer, ":classes/%s", name);
	if ((retval = OpenLibrary (buffer, version)) == NULL)
	{
	    sprintf (buffer, "classes/%s", name);
	    retval = OpenLibrary (buffer, version);
	}
    }
    return (struct ClassLibrary *) retval;
}

LONG MakeTab( void )
{
	if(TabBase = openclass ("gadgets/tabs.gadget", 42))
	{
		if(gad_tab = NewObject (NULL, "tabs.gadget",
					GA_Top,		    APP_Window->BorderTop + 2,
					GA_Left,	    APP_Window->BorderLeft,
					GA_Height,	  FontY + 5,
					GA_RelWidth,	-(APP_Window->BorderLeft + APP_Window->BorderRight),
					GA_TextAttr,	&ScreenFont,
					GA_RelVerify,	TRUE,
					GA_Immediate,	TRUE,
					GA_ID,        GD_TAB,
          LAYOUTA_ChildMaxWidth, FALSE,
					TABS_Labels,	labels,
					TABS_Current,	0,
					TAG_DONE))
		{
      return( TRUE );
    }
  }
  return( FALSE );
}


int MakeGadget( struct List *historylist, struct List *portlist )
{
  if ( g = CreateContext( &APP_GList ))
  {
/* ResetWarning */
    ng.ng_TopEdge    =  (ComputeY( 18 ) + OffY );
    ng.ng_LeftEdge  =  ComputeX( 10 ) + OffX;
    ng.ng_Width      =  ComputeX( 150 );
    ng.ng_Height    =  ComputeY( 12 );
    ng.ng_TextAttr    =  &ScreenFont;
    ng.ng_GadgetText=  MSG_GAD_WARNING;
    ng.ng_GadgetID  =  GD_WARNING;
    ng.ng_Flags       =  PLACETEXT_IN;
    ng.ng_VisualInfo  =  VisualInfo;
    ng.ng_UserData    =  NULL;
    if(!(gad_button = g = CreateGadget( BUTTON_KIND, g, &ng, GT_Underscore, '_', GA_Disabled, TRUE, TAG_DONE )))
      return( FALSE );

/* Text komunikaty */
    ng.ng_TopEdge    =  (ComputeY( 18 ) + OffY);
    ng.ng_LeftEdge  =  ComputeX( 170) + OffX;
    ng.ng_Width      =  ComputeX( 320 );
    ng.ng_Height    =  ComputeY( 12 );
    ng.ng_GadgetText=  "";
    ng.ng_GadgetID  =  GD_TEXT;
    if(!(gad_text = g = CreateGadget( TEXT_KIND, g, &ng, GTTX_Text, (ULONG)"",
                                                   GTTX_Justification, GTJ_LEFT,
                                                   GTTX_Border, TRUE,
                                                   TAG_DONE )))
      return( FALSE );

/* nazwy programów */
    ng.ng_TopEdge    =  ComputeY( 41 ) + OffY;
    ng.ng_LeftEdge  =  ComputeX( 10 ) + OffX;
    ng.ng_Width      =  ComputeX( 150 );
    ng.ng_Height    =  ComputeY( 68 );
    ng.ng_Flags       =  PLACETEXT_ABOVE | NG_HIGHLABEL;
    ng.ng_GadgetText=  NULL;
    ng.ng_GadgetID  =  GD_LVIEW;
    if(!(gad_pname = g = CreateGadget( LISTVIEW_KIND, g, &ng, GTLV_Labels, portlist,
                                   GTLV_ReadOnly, TRUE,
                                   TAG_DONE )))
      return( FALSE );

/* Historia */
    ng.ng_TopEdge    =  ComputeY( 41 ) + OffY;
    ng.ng_LeftEdge  =  ComputeX( 175 ) + OffX;
    ng.ng_Width      =  ComputeX( 315 );
    ng.ng_Height    =  ComputeY( 68 );
    ng.ng_GadgetText=  NULL;
    ng.ng_GadgetID  =  GD_HIST;
    if(!(gad_hist = g = CreateGadget( LISTVIEW_KIND, g, &ng, GTLV_Labels, historylist,
                                   GTLV_ReadOnly, TRUE,
                                   TAG_DONE )))
      return( FALSE );
    return( TRUE );
  }
return( FALSE );
}

int MakeGadget2( STRPTR path, STRPTR header, int wborcli )
{
  if ( g = CreateContext( &APP_GList2 ))
  {
/* Path */
    ng.ng_TopEdge    =  (ComputeY( 25 ) + OffY );
    ng.ng_LeftEdge  =  ComputeX( 155 ) + OffX;
    ng.ng_Width      =  ComputeX( 330 );
    ng.ng_Height    =  ComputeY( 12 );
    ng.ng_TextAttr    =  &ScreenFont;
    ng.ng_GadgetText=  MSG_GAD_PATH;
    ng.ng_GadgetID  =  GD_PATH;
    ng.ng_Flags       =  PLACETEXT_LEFT;
    ng.ng_VisualInfo  =  VisualInfo;
    ng.ng_UserData    =  NULL;
    if(!(gad_path = g = CreateGadget( STRING_KIND, g, &ng, GT_Underscore, '_', GTST_String, path, GTST_MaxChars, 256, TAG_DONE )))
      return( FALSE );

/* Header */
    ng.ng_TopEdge    =  (ComputeY( 40 ) + OffY );
    ng.ng_LeftEdge  =  ComputeX( 155 ) + OffX;
    ng.ng_Width      =  ComputeX( 330 );
    ng.ng_Height    =  ComputeY( 12 );
    ng.ng_GadgetText=  MSG_GAD_HEADER;
    ng.ng_GadgetID  =  GD_HEADER;
    ng.ng_Flags       =  PLACETEXT_LEFT;
    ng.ng_UserData    =  NULL;
    if(!(gad_header = g = CreateGadget( STRING_KIND, g, &ng, GT_Underscore, '_', GTST_String, header, GTST_MaxChars, 256, TAG_DONE )))
      return( FALSE );

/* prtdev */
    ng.ng_TopEdge    =  (ComputeY( 70 ) + OffY );
    ng.ng_LeftEdge  =  ComputeX( 155 ) + OffX;
    ng.ng_Width      =  ComputeX( 195 );
    ng.ng_Height    =  ComputeY( 12 );
    ng.ng_GadgetText=  MSG_GAD_PRTDEV;
    ng.ng_GadgetID  =  GD_PRTDEV;
    ng.ng_Flags       =  PLACETEXT_LEFT;
    ng.ng_UserData    =  NULL;
    if(!(gad_prtdev = g = CreateGadget( STRING_KIND, g, &ng, GT_Underscore, '_', GTST_String, prtdev, GTST_MaxChars, 108, TAG_DONE )))
      return( FALSE );

/* prtunit */
    ng.ng_TopEdge    =  (ComputeY( 70 ) + OffY );
    ng.ng_LeftEdge  =  ComputeX( 450 ) + OffX;
    ng.ng_Width      =  ComputeX( 35 );
    ng.ng_Height    =  ComputeY( 12 );
    ng.ng_GadgetText=  MSG_GAD_PRTUNIT;
    ng.ng_GadgetID  =  GD_PRTUNIT;
    ng.ng_Flags       =  PLACETEXT_LEFT;
    ng.ng_UserData    =  NULL;
    if(!(gad_prtunit = g = CreateGadget( INTEGER_KIND, g, &ng, GT_Underscore, '_', GTIN_Number, prtunit, TAG_DONE )))
      return( FALSE );

/* Save  */
    ng.ng_TopEdge    =  (ComputeY( 96 ) + OffY );
    ng.ng_LeftEdge  =  ComputeX( 10 ) + OffX;
    ng.ng_Width      =  ComputeX( 120 );
    ng.ng_Height    =  ComputeY( 12 );
    ng.ng_GadgetText=  MSG_GAD_SAVE;
    ng.ng_GadgetID  =  GD_SAVE;
    ng.ng_Flags       =  PLACETEXT_IN;
    ng.ng_UserData    =  NULL;
    if(!(gad_save = g = CreateGadget( BUTTON_KIND, g, &ng, GT_Underscore, '_', GA_Disabled, wborcli ? TRUE : FALSE, TAG_DONE )))
      return( FALSE );

/* Use  */
    ng.ng_TopEdge    =  (ComputeY( 96 ) + OffY );
    ng.ng_LeftEdge  =  ComputeX( 190 ) + OffX;
    ng.ng_Width      =  ComputeX( 120 );
    ng.ng_Height    =  ComputeY( 12 );
    ng.ng_GadgetText=  MSG_GAD_USE;
    ng.ng_GadgetID  =  GD_USE;
    ng.ng_Flags       =  PLACETEXT_IN;
    ng.ng_UserData    =  NULL;
    if(!(gad_use = g = CreateGadget( BUTTON_KIND, g, &ng, GT_Underscore, '_', TAG_DONE )))
      return( FALSE );

/* UnDo  */
    ng.ng_TopEdge    =  (ComputeY( 96 ) + OffY );
    ng.ng_LeftEdge  =  ComputeX( 365 ) + OffX;
    ng.ng_Width      =  ComputeX( 120 );
    ng.ng_Height    =  ComputeY( 12 );
    ng.ng_GadgetText=  MSG_GAD_UNDO;
    ng.ng_GadgetID  =  GD_UNDO;
    ng.ng_Flags       =  PLACETEXT_IN;
    ng.ng_UserData    =  NULL;
    if(!(gad_undo = g = CreateGadget( BUTTON_KIND, g, &ng, GT_Underscore, '_', TAG_DONE )))
      return( FALSE );
    return( TRUE );
  }
return( FALSE );
}

void DrawGadsBox( void )
{
	Draw3DBox( APP_Window->RPort, APP_Font,
						DBA_PosX,		ComputeX( 5 ) + OffX,
						DBA_PosY,		ComputeY( 36 ) + OffY,
						DBA_Width,	ComputeX( 160 ),
						DBA_Height,	ComputeY( 75 ),
						DBA_Text,		MSG_GAD_PNAME,
            DBA_Align,  ALIGN_CENTER,
						TAG_DONE );

	Draw3DBox( APP_Window->RPort, APP_Font,
						DBA_PosX,		ComputeX( 170 ) + OffX,
						DBA_PosY,		ComputeY( 36 ) + OffY,
						DBA_Width,	ComputeX( 325 ),
						DBA_Height,	ComputeY( 75 ),
						DBA_Text,		MSG_GAD_HIST,
            DBA_Align,  ALIGN_CENTER,
						TAG_DONE );
  SetAPen( APP_Window->RPort, 0 );
}

void DrawGadsBox2( void )
{
	Draw3DBox( APP_Window->RPort, APP_Font,
						DBA_PosX,		ComputeX( 5 ) + OffX,
						DBA_PosY,		ComputeY( 20 ) + OffY,
						DBA_Width,	ComputeX( 490 ),
						DBA_Height,	ComputeY( 35 ),
						DBA_Text,		MSG_TXT_FILEPREF,
            DBA_Align,  ALIGN_LEFT,
						TAG_DONE );

	Draw3DBox( APP_Window->RPort, APP_Font,
						DBA_PosX,		ComputeX( 5 ) + OffX,
						DBA_PosY,		ComputeY( 65 ) + OffY,
						DBA_Width,	ComputeX( 490 ),
						DBA_Height,	ComputeY( 20 ),
						DBA_Text,		MSG_TXT_PRTPREF,
            DBA_Align,  ALIGN_LEFT,
						TAG_DONE );
  SetAPen( APP_Window->RPort, 0 );
}

int OpenFonts( void )
{
  if (!(APP_Font=OpenDiskFont( &ScreenFont )))
    return( FALSE );
  return( TRUE );
}


/* Funkcja zamyka otwarty font */

void CloseFonts( void )
{
  if ( APP_Font )  
  {
    CloseFont( APP_Font );
    APP_Font=NULL;
  }
}


UWORD ComputeX( UWORD value )
{
  return(( UWORD )((( FontX * value ) + 4 ) / 8 ));
}


UWORD ComputeY( UWORD value )
{
  return(( UWORD )((( FontY * value ) + 4 ) / 8 ));
}


void ComputeFont( void )
{
  Font = &ScreenFont;
  Font->ta_Name = (STRPTR)Screen->RastPort.Font->tf_Message.mn_Node.ln_Name;
  Font->ta_YSize = FontY = Screen->RastPort.Font->tf_YSize;
  FontX = Screen->RastPort.Font->tf_XSize;
  OffX = Screen->WBorLeft;
  OffY = Screen->RastPort.TxHeight + Screen->WBorTop + 1;
  return;
}


/* Funkcja otwiera okno */

int OpenAPP_Display( WORD Left, WORD Top )
{
  WORD Width=500;
  WORD Height=114;

  if(!(APP_Window=OpenWindowTags( 0,
    WA_Left,        Left,
    WA_Top,          Top,
    WA_Width,        ComputeX(Width) + OffX + Screen->WBorRight,
    WA_Height,      ComputeY(Height) + OffY + Screen->WBorBottom,
    WA_Activate,    TRUE,
    WA_NewLookMenus,TRUE,
    WA_Title,        APP_TitleWindow,
    WA_Flags,        WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH,
    WA_IDCMP,        IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_REFRESHWINDOW | IDCMP_GADGETUP | LISTVIEWIDCMP | IDCMP_VANILLAKEY,
    WA_Gadgets,      NULL,
    WA_AutoAdjust,  FALSE,
    WA_PubScreen,    (struct Screen *)Screen,
    TAG_DONE)))
      return( FALSE );
  GT_RefreshWindow( APP_Window, NULL );
  sigwin=( 1L << APP_Window->UserPort->mp_SigBit );
  return( TRUE );
}


/* Funkcja odczytuje komunikat Intuition */

LONG ReadIMsg( struct Window *iwnd )
{
  struct IntuiMessage *imsg;
  
  if ( imsg = GT_GetIMsg( iwnd->UserPort ))
  {
    IClass    =  imsg->Class;
    Qualifier  =  imsg->Qualifier;
    Code      =  imsg->Code;
    IObject    =  imsg->IAddress;

    GT_ReplyIMsg( imsg );
    return( TRUE );
  }
  return( FALSE );
}


/* Funkcja zamyka otwarte okno */

void CloseAPP_Display(void)
{
  if(APP_Window) 
  {
    Forbid();
    while ( ReadIMsg( APP_Window ))
    ;
    CloseWindow((struct Window *)APP_Window);
    APP_Window=NULL;
    Permit();
  }
}


/* Funkcja alokuje ekran */

int SetupScreen( void )
{
  if (!(Screen = LockPubScreen( PubScreenName )))
    return( FALSE );

  ComputeFont();

  if(!(OpenFonts()))
    return( FALSE );


  if (!( VisualInfo = GetVisualInfo( Screen, TAG_DONE )))
    return( FALSE );

  return( TRUE );
}


/* Funkcja dealokuje ekran */

void CloseDownScreen( void )
{
  if ( VisualInfo )
  {
    FreeVisualInfo( VisualInfo );
    VisualInfo = NULL;
  }

  CloseFonts();

  if ( Screen )
  {
    UnlockPubScreen( NULL, Screen );
    Screen = NULL;
  }
}

BOOL OpenMenu( void )
{
  if(!(MenuStrip=CreateMenus( mbld,TAG_DONE )))
    return( FALSE );
  LayoutMenus( MenuStrip, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE );
  SetMenuStrip( APP_Window, MenuStrip );
  return( TRUE );
}

void CloseMenu( void )
{
  ClearMenuStrip( APP_Window );
  if( MenuStrip )
  {
    FreeMenus( MenuStrip );
    MenuStrip=NULL;
  }
}


/* Funkcja otwiera wszystkie biblioteki */

LONG OpenLibraries( void )
{
  if ( !(DosBase = (struct DosLibrary *) OpenLibrary((UBYTE *) "dos.library", 37 )))
    return( FALSE );
  if ( !(IntuitionBase = (struct IntuitionBase *) OpenLibrary((UBYTE *) "intuition.library", 37 )))
    return( FALSE );
  if ( !(GadToolsBase = (struct Library *) OpenLibrary((UBYTE *) "gadtools.library", 39 )))
    return( FALSE );
  if ( !(GfxBase = (struct GfxBase *) OpenLibrary((UBYTE *) "graphics.library" , 37 )))
    return( FALSE );
  if ( !(DiskFontBase = (struct Library *) OpenLibrary((UBYTE *) "diskfont.library" , 37 )))
    return( FALSE );
  if ( !(IconBase = (struct Library *) OpenLibrary((UBYTE *) "icon.library" , 37 )))
    return( FALSE );
	if ( !(ImageBase = (struct Library *) OpenLibrary((UBYTE *) "image.library" , 36 )))
	{
		printf("Couldn't open image.library\n");
		return( FALSE );
	}

  return( TRUE );
}


/* Funkcja zamyka wszystkie biblioteki */

void CloseLibraries( void )
{
	if (ImageBase)			CloseLibrary( (struct Library *) ImageBase );
  if (DiskFontBase)   CloseLibrary( (struct Library *) DiskFontBase );
  if (IconBase)    		CloseLibrary( (struct Library *) IconBase );
  if (GfxBase)        CloseLibrary( (struct Library *) GfxBase );
  if (GadToolsBase)   CloseLibrary( (struct Library *) GadToolsBase );
  if (IntuitionBase)  CloseLibrary( (struct Library *) IntuitionBase );
  if (DosBase)        CloseLibrary( (struct Library *) DOSBase );
}


void ShutDown( void )
{
  if (serverport)
    DeletePort (serverport);
  if(gad_tab)
  {
  	RemoveGadget( APP_Window, gad_tab );
    DisposeObject (gad_tab);
    gad_tab=NULL;
  }
  if(TabBase)
  {
    CloseLibrary ((struct Library *) TabBase);
    TabBase=NULL;
  }
  CloseMenu();
  CloseAPP_Display();
  FreeGadgets( APP_GList2 );
  APP_GList2 = NULL;
  FreeGadgets( APP_GList );
  APP_GList = NULL;
  CloseDownScreen();
  CloseLibraries();
}

/* Funkcja obsîuguje rwmessage */
void MessageFunc( STRPTR tab, STRPTR text, ULONG cases, struct RWMessage *msg, struct List *portlist, struct List *historylist, ULONG gad )
{
if(!gad)
{
	GT_SetGadgetAttrs( gad_hist, APP_Window, 0, GTLV_Labels, -1, TAG_DONE);
	sprintf( tab, text, msg->rwm_ProgName, msg->rwm_MsgPort );
	AddHistory( historylist, tab );
	GT_SetGadgetAttrs( gad_hist, APP_Window, 0, GTLV_Labels, historylist, TAG_DONE);

	GT_SetGadgetAttrs( gad_pname, APP_Window, 0, GTLV_Labels, -1, TAG_DONE);
	switch( cases )
	{
		case RWM_ADDPORT:
			RW_AddPort( portlist, msg );
		break;
		case RWM_REMPORT:
		case RWM_DONE:
			RW_RemPort( portlist, msg );
		break;
	}
	GT_SetGadgetAttrs( gad_pname, APP_Window, 0, GTLV_Labels, portlist, TAG_DONE);
	GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)"Message RWM_ADDPORT", TAG_DONE);
	switch( cases )
	{
		case RWM_ADDPORT:
		case RWM_REMPORT:
			if( IsListEmpty( portlist ) )
    		GT_SetGadgetAttrs( gad_button, APP_Window, 0, GA_Disabled, TRUE, TAG_DONE);
  		else
    		GT_SetGadgetAttrs( gad_button, APP_Window, 0, GA_Disabled, FALSE, TAG_DONE);
		break;
		case RWM_DONE:
			if( IsListEmpty( portlist ) )
      {
        GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)"All ports done - Reset", TAG_DONE);
        GT_SetGadgetAttrs( gad_button, APP_Window, 0, GA_Disabled, TRUE, TAG_DONE);
      }
		break;
	}
}
else
{
	sprintf( tab, text, msg->rwm_ProgName, msg->rwm_MsgPort );
	AddHistory( historylist, tab );
	switch( cases )
	{
		case RWM_ADDPORT:
			RW_AddPort( portlist, msg );
		break;
		case RWM_REMPORT:
		case RWM_DONE:
			RW_RemPort( portlist, msg );
		break;
	}
	if( IsListEmpty( portlist ) )
    gad_button->Flags|=GFLG_DISABLED;
  else
    gad_button->Flags&=~GFLG_DISABLED;
}

}

/* Funkcja obsîuguje gadget gad_tab */
void GadTabFunc( ULONG cases, ULONG tab )
{
	switch( cases )
	{
		case 0:
			if(tab==1)	RemoveGList( APP_Window, APP_GList2, -1 );
			RectFill( APP_Window->RPort, APP_Window->BorderLeft, APP_Window->BorderTop + FontY + 7,
	  		        APP_Window->Width-(APP_Window->BorderRight)-1, ComputeY( 122 ));
	  	AddGList( APP_Window, APP_GList, -1, -1, 0 );
  		RefreshGadgets( APP_GList, APP_Window, 0 );
  		GT_RefreshWindow( APP_Window, 0 );
			DrawGadsBox();
		break;

		case 1:
			if(tab==0)	RemoveGList( APP_Window, APP_GList, -1 );
			RectFill( APP_Window->RPort, APP_Window->BorderLeft, APP_Window->BorderTop + FontY + 7,
	  		        APP_Window->Width-(APP_Window->BorderRight)-1, ComputeY( 122 ));
	  	AddGList( APP_Window, APP_GList2, -1, -1, 0 );
  		RefreshGadgets( APP_GList2, APP_Window, 0 );
  		GT_RefreshWindow( APP_Window, 0 );
      GT_SetGadgetAttrs( gad_path, APP_Window, 0, GTST_String, path, TAG_DONE);
      GT_SetGadgetAttrs( gad_header, APP_Window, 0, GTST_String, header, TAG_DONE);
      DrawGadsBox2();
		break;

		case 2:
		case 3:
			if(tab==1)	RemoveGList( APP_Window, APP_GList2, -1 );
			if(tab==0)	RemoveGList( APP_Window, APP_GList, -1 );
			RectFill( APP_Window->RPort, APP_Window->BorderLeft, APP_Window->BorderTop + FontY + 7,
	  		        APP_Window->Width-(APP_Window->BorderRight)-1, ComputeY( 122 ));
		break;
	}
}

/* Funkcja wypisuje tekst */
void DrawInfoText( STRPTR wintext )
{
	SetAPen( APP_Window->RPort, 1 );
	DrawText( DT_Texts, wintext,
						DT_FontA, APP_Font,
						DT_FontB, APP_Font,
						DT_RastPort , APP_Window->RPort,
						DT_Top, APP_Window->BorderTop + FontY + 10,
						DT_Left, APP_Window->Width/2,
						TAG_DONE);
	SetAPen( APP_Window->RPort, 0 );
}

LONG EasyDialogBox( struct Window *edb_win, STRPTR edb_title, STRPTR edb_text, STRPTR edb_button, APTR edb_args )
{
	struct EasyStruct easyreq;
	
	easyreq.es_StructSize=sizeof(struct EasyStruct);
	easyreq.es_Title=edb_title;
	easyreq.es_TextFormat=edb_text;
	easyreq.es_GadgetFormat=edb_button;
	return(EasyRequestArgs( edb_win, &easyreq, 0, edb_args ));
}

/* Funkcja odczytuje preferencje z ikony */
LONG ReadPrefs( STRPTR prefs_path, STRPTR prefs_header, STRPTR icon_name )
{
	struct DiskObject *PrefsIcon;
	STRPTR string;

	if(!(PrefsIcon=GetDiskObject( icon_name )))
		return(1000);
	if(string=FindToolType( PrefsIcon->do_ToolTypes, "PATH" ))
		strcpy( prefs_path, string );
	if(string=FindToolType( PrefsIcon->do_ToolTypes, "HEADER" ))
		strcpy( prefs_header, string );
	if(string=FindToolType( PrefsIcon->do_ToolTypes, "DEVICE" ))
		strcpy( prtdev, string );
	if(string=FindToolType( PrefsIcon->do_ToolTypes, "UNIT" ))
		prtunit=atol( string );
	FreeDiskObject( PrefsIcon );
	return( 0 );
}

/* This function write tooltype to icon */
/* WriteToolType() (c) 1998 Paweî Marciniak <pmarciniak@lodz.home.pl>
  Modify date  |  Version  |  Comment
---------------+-----------+------------------------------
20-10-98 8:19  |  1.0      |
*/
LONG WriteToolType( STRPTR ToolTypeName, STRPTR ToolTypeArg, STRPTR IconName )
{
	struct DiskObject *Icon;
	LONG i, j;
	UBYTE **newtooltypes, **oldtooltypes;
	UWORD sizettname, sizettarg, stringsize;
	STRPTR ttstring, oldstring;

	if(!(Icon=GetDiskObjectNew( IconName )))
		return(1000);

	sizettname=strlen(ToolTypeName);
	sizettarg=strlen(ToolTypeArg);
	stringsize=sizettname+sizettarg+2;

	if(!(ttstring=AllocVec( stringsize, MEMF_CLEAR )))
	{
		FreeDiskObject( Icon );
		return(1001);
	}
	strcpy(ttstring, ToolTypeName );
	strcat(ttstring, "=" );
	strcat(ttstring, ToolTypeArg );

	for( i=0; Icon->do_ToolTypes[i]!=NULL; i++);

	for( j=0; j<i; j++ )
	{
		if(!strncmp( Icon->do_ToolTypes[j], ttstring, sizettname+1 ))
		{
			oldstring=Icon->do_ToolTypes[j];
			Icon->do_ToolTypes[j]=ttstring;
			PutDiskObject( IconName, Icon );
			Icon->do_ToolTypes[j]=oldstring;
			FreeVec( ttstring );
			FreeDiskObject( Icon );
			return( 0 );
		}
	}
	if(!(newtooltypes=AllocVec( sizeof(newtooltypes)*(i+2), MEMF_CLEAR )))
	{
		FreeVec( ttstring );
		FreeDiskObject( Icon );
		return(1001);
	}

	for( j=0; j<i; j++ )
		newtooltypes[j]=Icon->do_ToolTypes[j];
	newtooltypes[j]=ttstring;
	oldtooltypes=Icon->do_ToolTypes;
	Icon->do_ToolTypes=newtooltypes;
	PutDiskObject( IconName, Icon );
	Icon->do_ToolTypes=oldtooltypes;
	FreeVec( ttstring );
	FreeVec( newtooltypes );
	FreeDiskObject( Icon );
	return( 0 );
}

/* Gîówna funkcja */

int main( int argc, char *argv[] )
{
  BOOL running=TRUE, busy=FALSE;
  UBYTE text[100], undo[256];
	ULONG TabOK=0, undounit;
	STRPTR tempstr;
  struct Requester busyreq;
  struct RWMessage *msg;
  struct List PortList;
  struct List HistoryList;
  struct WBArg *wba;
  struct WBStartup *wbs;

	/* Start */

  NewList( &PortList );
  NewList( &HistoryList );
  InitSemaphore( &sem );
	strcpy( path, MSG_TXT_PATH );
	strcpy( header, MSG_TXT_HEADER );
	strcpy( prtdev, MSG_TXT_PRTDEV );

  Forbid();
  if (FindPort( RESETSERVERNAME ))
  {
    Permit();
    printf("Program jest juû uruchomiony\n");
    return( FALSE );
  }
  if (!(serverport=CreatePort( RESETSERVERNAME, 0L )))
  {
    Permit();
    printf("Brak pamiëci na port\n");
    return( FALSE );
  }
  Permit();
  sigmsg = 1L << serverport->mp_SigBit;

  if(!(OpenLibraries()))
  {
    ShutDown();
    return( FALSE );
  }
  
  if(!(SetupScreen()))
  {
    ShutDown();
    return( FALSE );
  }

	if(!argc)
	{
		wbs=(struct WBStartup *)argv;
		wba=&wbs->sm_ArgList[wbs->sm_NumArgs-1];
		ReadPrefs( path, header, wba->wa_Name );
	}

  if(!(OpenAPP_Display( 20, 20 )))
  {
    ShutDown();
    return( FALSE );
  }

  if(!(OpenMenu()))
  {
    ShutDown();
    return( FALSE );
  }

  if(!MakeGadget( &HistoryList, &PortList ))
  {
    ShutDown();
    return( FALSE );
  }

  if(!MakeGadget2( path, header, argc ))
  {
    ShutDown();
    return( FALSE );
  }

  if(!(MakeTab()))
  {
    ShutDown();
    return( FALSE );
  }

  SetFont( APP_Window->RPort, APP_Font );
  SetAPen( APP_Window->RPort, 0 );
  GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)"Welcom to Reset.server emulator", TAG_DONE);

  AddGadget( APP_Window, gad_tab, -1 );
  AddGList( APP_Window, APP_GList, -1, -1, 0 );
  RefreshGList( gad_tab, APP_Window, 0, -1 );

	DrawGadsBox();

  do
  {
    sig=Wait( sigwin | sigmsg );


    while ( ReadIMsg( APP_Window ))
    {
      switch ( IClass )
      {
        case  IDCMP_REFRESHWINDOW:
          GT_BeginRefresh( APP_Window );
          GT_EndRefresh( APP_Window, TRUE );
        break;

        case  IDCMP_VANILLAKEY:
          switch( Code )
          {
          	case 'u':
          	break;
          }
        break;

        case  IDCMP_CLOSEWINDOW:
        if(EasyDialogBox( APP_Window, MSG_REQ_QUIT_TITLE, MSG_REQ_QUIT_TEXT, MSG_REQ_QUIT_BUTTON, 0 ))
				{
        	if( IsListEmpty( &PortList ) )
          {
            running=FALSE;
          }
          else
            if(TabOK)
            {
            	GadTabFunc( 0, TabOK );
							GT_SetGadgetAttrs( gad_hist, APP_Window, 0, GTLV_Labels, -1, TAG_DONE);
							GT_SetGadgetAttrs( gad_hist, APP_Window, 0, GTLV_Labels, &HistoryList, TAG_DONE);
							GT_SetGadgetAttrs( gad_pname, APP_Window, 0, GTLV_Labels, -1, TAG_DONE);
							GT_SetGadgetAttrs( gad_pname, APP_Window, 0, GTLV_Labels, &PortList, TAG_DONE);
            	SetGadgetAttrs( gad_tab, APP_Window, 0, TABS_Current, 0, TAG_DONE );
              TabOK=0;
            }
						GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)"First remove all ports", TAG_DONE);
				}
        break; /* IDCMP_CLOSEWINDOW */

        case  IDCMP_GADGETUP:
          switch ( IObject->GadgetID )
          {
            case  GD_WARNING:
              SendWarning( &PortList );
              GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)"Sending ResetWarning", TAG_DONE);
            break; /* GD_WARNING */

            case  GD_SAVE:
							if(!argc)
							{
								wbs=(struct WBStartup *)argv;
								wba=&wbs->sm_ArgList[0];
/* PATH */			strcpy( undo, path );
	              GT_GetGadgetAttrs( gad_path, APP_Window, 0, GTST_String, &tempstr, TAG_DONE);
  	            strcpy( path, tempstr );
								if(WriteToolType( "PATH", path, wba->wa_Name ))
								{
									strcpy( path, undo );
								}
/* HEADER */		strcpy( undo, header );
  	            GT_GetGadgetAttrs( gad_header, APP_Window, 0, GTST_String, &tempstr, TAG_DONE);
	              strcpy( header, tempstr );
								if(WriteToolType( "HEADER", header, wba->wa_Name ))
								{
									strcpy( header, undo );
								}
/* DEVICE */		strcpy( undo, prtdev );
  	            GT_GetGadgetAttrs( gad_prtdev, APP_Window, 0, GTST_String, &tempstr, TAG_DONE);
	              strcpy( prtdev, tempstr );
								if(WriteToolType( "DEVICE", prtdev, wba->wa_Name ))
								{
									strcpy( prtdev, undo );
								}
/* UNIT */			undounit=prtunit;
  	            GT_GetGadgetAttrs( gad_prtunit, APP_Window, 0, GTIN_Number, &prtunit, TAG_DONE);
  	            sprintf( undo, "%ld", prtunit );
								if(WriteToolType( "UNIT", undo, wba->wa_Name ))
								{
									prtunit=undounit;
								}
							}
            break; /* GD_SAVE */

            case  GD_USE:
              GT_GetGadgetAttrs( gad_path, APP_Window, 0, GTST_String, &tempstr, TAG_DONE);
              strcpy( path, tempstr );
              GT_GetGadgetAttrs( gad_header, APP_Window, 0, GTST_String, &tempstr, TAG_DONE);
              strcpy( header, tempstr );
              GT_GetGadgetAttrs( gad_prtdev, APP_Window, 0, GTST_String, &tempstr, TAG_DONE);
              strcpy( prtdev, tempstr );
              GT_GetGadgetAttrs( gad_prtunit, APP_Window, 0, GTIN_Number, &prtunit, TAG_DONE);
            break; /* GD_USE */

            case  GD_UNDO:
              GT_SetGadgetAttrs( gad_path, APP_Window, 0, GTST_String, path, TAG_DONE);
              GT_SetGadgetAttrs( gad_header, APP_Window, 0, GTST_String, header, TAG_DONE);
              GT_SetGadgetAttrs( gad_prtdev, APP_Window, 0, GTST_String, prtdev, TAG_DONE);
              GT_SetGadgetAttrs( gad_prtunit, APP_Window, 0, GTIN_Number, prtunit, TAG_DONE);
            break; /* GD_UNDO */

            case GD_TAB:
              switch( Code )
              {
                case 0:
									GadTabFunc( Code, TabOK );
									GT_SetGadgetAttrs( gad_hist, APP_Window, 0, GTLV_Labels, -1, TAG_DONE);
									GT_SetGadgetAttrs( gad_hist, APP_Window, 0, GTLV_Labels, &HistoryList, TAG_DONE);
									GT_SetGadgetAttrs( gad_pname, APP_Window, 0, GTLV_Labels, -1, TAG_DONE);
									GT_SetGadgetAttrs( gad_pname, APP_Window, 0, GTLV_Labels, &PortList, TAG_DONE);
                  TabOK=0;
                break;
                
                case 1:
									GadTabFunc( Code, TabOK );
									SetAPen( APP_Window->RPort, 1 );
									LineDraw(OffX, ComputeY( 90 )+OffY, (APP_Window->Width - (APP_Window->BorderRight)-1), ComputeY( 90 )+OffY );
									SetAPen( APP_Window->RPort, 2 );
									LineDraw(OffX, ComputeY( 90 )+OffY+1, (APP_Window->Width - (APP_Window->BorderRight)-1), ComputeY( 90 )+OffY+1 );
									SetAPen( APP_Window->RPort, 0 );
                  TabOK=1;
                break;

                case 2:
									GadTabFunc( Code, TabOK );
									DrawInfoText( MSG_TXT_AUTOR );
                  TabOK=2;
                break;

                case 3:
									GadTabFunc( Code, TabOK );
									DrawInfoText( MSG_TXT_ABOUT );
                  TabOK=3;
                break;
              }
            break;
          }
        break; /* IDCMP_GADGETUP */

        case  IDCMP_MENUPICK:
          while( Code != MENUNULL )
          {
            switch( MENUNUM( Code ))
            {
              case TITLE_PROJECT:
                switch( ITEMNUM( Code ))
                {
                  case MENU_ABOUT:
                    busy=BusyStart( APP_Window, &busyreq );
                    EasyDialogBox( APP_Window, MSG_REQ_INFO_TITLE, MSG_REQ_INFO_TEXT, MSG_REQ_INFO_BUTTON, 0 );
                    if( busy ) BusyEnd( APP_Window, &busyreq );
                    Code=(ItemAddress( MenuStrip, Code ))->NextSelect;
                  break; /* MENU_ABOUT */

                  case MENU_QUIT:
                  if(EasyDialogBox( APP_Window, MSG_REQ_QUIT_TITLE, MSG_REQ_QUIT_TEXT, MSG_REQ_QUIT_BUTTON, 0 ))
									{
					        	if( IsListEmpty( &PortList ) )
          					{
 					          	running=FALSE;
        					  }
          					else
            				{
											if(TabOK)
            					{
            						GadTabFunc( 0, TabOK );
												GT_SetGadgetAttrs( gad_hist, APP_Window, 0, GTLV_Labels, -1, TAG_DONE);
												GT_SetGadgetAttrs( gad_hist, APP_Window, 0, GTLV_Labels, &HistoryList, TAG_DONE);
												GT_SetGadgetAttrs( gad_pname, APP_Window, 0, GTLV_Labels, -1, TAG_DONE);
												GT_SetGadgetAttrs( gad_pname, APP_Window, 0, GTLV_Labels, &PortList, TAG_DONE);
           						 	SetGadgetAttrs( gad_tab, APP_Window, 0, TABS_Current, 0, TAG_DONE );
           					  	TabOK=0;
            					}
											GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)"First remove all ports", TAG_DONE);
										}
									}
                    Code=(ItemAddress( MenuStrip, Code ))->NextSelect;
                  break;/* MENU_QUIT */
                }
              break;/* TITLE_PROJECT */

              case TITLE_EDIT:
                switch( ITEMNUM( Code ))
                {
                  case MENU_SAVEHIST:
                    if(!(WriteHistory( path, header, &HistoryList )))
                    {
                      busy=BusyStart( APP_Window, &busyreq );
                      EasyDialogBox( APP_Window, MSG_REQ_ERR_TITLE, MSG_REQ_ERR_WRITE, MSG_REQ_ERR_BUTTON, path );
                      if( busy ) BusyEnd( APP_Window, &busyreq );
                    }
                    Code=(ItemAddress( MenuStrip, Code ))->NextSelect;
                  break; /* MENU_SAVEHIS */

                  case MENU_CLEARHIST:
                    if(!TabOK) GT_SetGadgetAttrs( gad_hist, APP_Window, 0, GTLV_Labels, -1, TAG_DONE);
                    RemHistory( &HistoryList );
                    if(!TabOK) GT_SetGadgetAttrs( gad_hist, APP_Window, 0, GTLV_Labels, &HistoryList, TAG_DONE);
                    Code=(ItemAddress( MenuStrip, Code ))->NextSelect;
                  break; /* MENU_CLEARHIS */

                  case MENU_PRINT:
                      busy=BusyStart( APP_Window, &busyreq );
                      if(PrintHistory( prtdev, prtunit, &HistoryList ))
	                      EasyDialogBox( APP_Window, MSG_REQ_ERR_TITLE, MSG_REQ_ERR_PRINT, MSG_REQ_ERR_BUTTON, 0 );
                      if( busy ) BusyEnd( APP_Window, &busyreq );
                  	
                    Code=(ItemAddress( MenuStrip, Code ))->NextSelect;
                  break; /* MENU_PRINT */
                }
              break; /* TITLE_EDIT */
            }
          }
        break; /* IDCMP_MENUPICK */

        default:
        break;
      }
    }

    while( msg=(struct RWMessage *)GetMsg( serverport ))
    {
      switch( msg->rwm_Message.mn_Node.ln_Type )
      {
        case  NT_REPLYMSG:
          switch( msg->rwm_MsgType )
          {
	        	case RWM_RESETWARNING:
              FreeVec( msg );
            break;
          }
        break;

        case  NT_MESSAGE:
          switch( msg->rwm_MsgType )
          {
            case  RWM_ADDPORT:
              MessageFunc( text, MSG_TXT_ADDPORT, RWM_ADDPORT, msg, &PortList, &HistoryList, TabOK );
            break;

            case  RWM_REMPORT:
              MessageFunc( text, MSG_TXT_REMPORT, RWM_REMPORT, msg, &PortList, &HistoryList, TabOK );
            break;

            case  RWM_DONE:
              MessageFunc( text, MSG_TXT_DONE, RWM_DONE, msg, &PortList, &HistoryList, TabOK );
            break;

            default:
            break;
          }
        ReplyMsg((struct Message *)msg);
        break;
        
        default:
        break;

      }
    } /* while reset serverport */
  } while ( running );

  ShutDown();
  RemHistory( &HistoryList );
  return( TRUE );
}
