home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #3
/
amigamamagazinepolishissue1998.iso
/
bazy
/
kingfisher-distribution
/
developer
/
client.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-02
|
15KB
|
509 lines
/****************************************************************************
* KingFisher Release 2 CLI client: "CLIent"
* Copyright © 1994 by Udo Schuermann
* All rights reserved
* ------------------------------------------------------------------------
* Demonstration of a KingFisher Release 2 message-based interface without the
* use of the kf-api. In other words, we do everything the "hard" way here.
* ------------------------------------------------------------------------
* This program is available only to registered users of KingFisher.
* PLEASE DO NOT REDISTRIBUTE!
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include "kf.h"
#include "kf-err.c" /* defines KFError[] array */
#define VERSION "1.4"
/* prototypes */
BOOL TellKF( struct KFMsg *myMsg );
#ifndef __MYDATE__
#define __MYDATE__ __AMIGADATE__
#endif
char Version[] = "$VER: CLIent "VERSION" for KingFisher Release 2 "__MYDATE__;
void UpgradeBuffer( struct KFMsg *myMsg ) {
char *p;
/* Is the maximum required/requested buffer size (myMsg->BParam) larger than what
* we have currently allocated (myMsg->BufferSize)? */
if( myMsg->BParam > myMsg->BufferSize ) {
/* then try reallocating the memory to which we are pointing... */
if( p = realloc(myMsg->Buffer,myMsg->BParam) ) {
printf("NOTE: Upgraded our buffer from %d to %d bytes in size\n",
myMsg->BufferSize,myMsg->BParam);
myMsg->BufferSize = myMsg->BParam;
myMsg->Buffer = p;
} else
printf("Could not upgrade our buffer from %d to %d bytes\n",
myMsg->BufferSize,myMsg->BParam);
}
} /* UpgradeBuffer() */
void main() {
struct MsgPort *myPort=NULL;
struct KFMsg *myMsg,*reply;
BOOL happy = TRUE,connected=FALSE;
char cmd[80];
char *p,*q;
LONG n,i;
printf("CLIent "VERSION" for KingFisher Release 2\n"
"Copyright \© 1994 by Udo Schuermann\n"
"All rights reserved\n\n");
if( FindPort( KFPortName ) ) {
/*****************************************************************
* Initialize our message; we use this one to communicate with the
* KFServer's message port. If something fails, we'll just set
* the variable 'happy' to FALSE to avoid running through the main
* while() loop below.
*****************************************************************
*/
if( myMsg = AllocMem( sizeof(struct KFMsg), MEMF_PUBLIC|MEMF_CLEAR ) ) {
myMsg->AmigaMsg.mn_Node.ln_Type = NT_MESSAGE;
myMsg->AmigaMsg.mn_Length = sizeof(struct KFMsg);
if( myMsg->AmigaMsg.mn_ReplyPort = myPort = CreateMsgPort() ) {
if( myMsg->Buffer = malloc( 256 ) )
myMsg->BufferSize = 256;
else {
printf("Cannot allocate 256 bytes for buffer space!\n");
happy = FALSE;
}
} else {
printf("Cannot create a private message port!\n");
happy = FALSE;
}
} else {
printf("Cannot allocate memory for message interface!\n");
happy = FALSE;
} /* if */
/*****************************************************************
* Now loop until we're no longer "happy," i.e. made to shut down
* or the user decided to shut us down.
*****************************************************************
*/
while( happy ) {
/*****************************************************************
* Prompt the user for input and process it
*****************************************************************
*/
printf("\nKF Ready: ");
fflush(stdout);
if( p = fgets(cmd,sizeof(cmd),stdin) ) {
/* convert string "foo bar fun" to "foo\0bar fun" where p points to "bar fun" */
while( *p > ' ' )
p++;
if( *p )
*p++ = '\0';
while( *p == ' ' )
p++;
/* kill the terminating newline, too */
q = p;
while( *q )
if( *q == '\n' )
*q = '\0';
else
q++;
/*****************************************************************
* we now have converted a line such as
* get=4289\n\0
* ^cmd
* to this:
* get\04289\0
* ^cmd ^p
*****************************************************************
*/
/*****************************************************************
* HELP
*****************************************************************
*/
if( (stricmp(cmd,"?") == 0) || (stricmp(cmd,"help") == 0) )
printf("The CLIent understands the following commands:\n"
" ? or HELP This display\n"
" HELLO [name] Announce yourself to the server (optional name)\n"
" BYE Say good-bye to the server\n"
" STATUS Get status information\n"
" GET [n] Get fish n (n is optional fish number)\n"
" POS Get current position in database\n"
" TEST n Retrieve n successive fish\n"
" LIST List all databases available for use\n"
" USE database Select a new database for use\n"
" BUILD file Add all fish from given file, unconditionally\n"
" PARSE file Add fish from given file with prompts for each\n"
" REINDEX Reindexes the current database\n"
" QUIT Quit the CLIent\n");
else
/*****************************************************************
* HELLO
*****************************************************************
*/
if( stricmp(cmd,"HELLO") == 0 ) {
if( !connected ) {
myMsg->Command = kfcHELLO;
myMsg->BParam = (ULONG)FindTask(NULL);
myMsg->RESERVED = NULL;
if( myMsg->Buffer ) {
if( *p == '\0' )
p = "CLIent "VERSION" for KingFisher Release 2";
printf("We call ourselves \"%s\"\n",p);
strncpy(myMsg->Buffer,p,myMsg->BufferSize);
}
if( TellKF(myMsg) ) {
if( myMsg->Error == kfeOK ) {
printf("You are now connected to the KFServer.\n");
connected = TRUE;
UpgradeBuffer( myMsg );
}
} if( myMsg->Error != kfeREFUSED )
connected = TRUE;
} else
printf("Use BYE before saying HELLO again.\n");
} else
/*****************************************************************
* BYE
*****************************************************************
*/
if( stricmp(cmd,"BYE") == 0 ) {
myMsg->Command = kfcBYE;
if( TellKF(myMsg) ) {
if( myMsg->Error == kfeOK ) {
printf("KFServer has said good bye.\n"
"Use the HELLO command to reconnect to the KFServer.\n");
connected = FALSE;
}
}
} else
/*****************************************************************
* STATUS
*****************************************************************
*/
if( stricmp(cmd,"STATUS") == 0 ) {
myMsg->Command = kfcSTATUS;
if( TellKF(myMsg) ) {
if( myMsg->Error == kfeOK )
printf(myMsg->Buffer);
}
} else
/*****************************************************************
* GET
*****************************************************************
*/
if( stricmp(cmd,"GET") == 0 ) {
myMsg->BParam = atol( p ); /* if 0 then KFServer gets current fish */
myMsg->Command = kfcGETFISH;
if( TellKF(myMsg) ) {
if( myMsg->Error == kfeOK )
printf("Flags = %04X, Name = ",myMsg->FParam);
printf(myMsg->Buffer);
}
} else
/*****************************************************************
* POS
*****************************************************************
*/
if( stricmp(cmd,"POS") == 0 ) {
myMsg->Command = kfcGETPOS;
if( TellKF(myMsg) )
if( myMsg->Error == kfeOK )
printf("Current position in database: %d\n",myMsg->BParam);
} else
/*****************************************************************
* TEST
*****************************************************************
*/
if( stricmp(cmd,"TEST") == 0 ) {
n = atol(p);
printf("Retrieving %d successive fish for TEST ...",n);
myMsg->Command = kfcGETPOS;
if( TellKF(myMsg) )
i = myMsg->BParam;
else
n = 0;
while( n > 0 ) {
myMsg->BParam = i;
myMsg->Command = kfcGETFISH;
if( TellKF(myMsg) ) {
i++;
n--;
} else {
printf(" (test loop terminated by GETFISH %d error)",i);
n = 0;
}
} /* while */
printf(" done!\n");
} else
/*****************************************************************
* LIST
*/
if( stricmp(cmd,"LIST") == 0 ) {
myMsg->Command = kfcLISTDBASES;
if( TellKF(myMsg) )
printf("---Databases Available---\n%s"
"-------------------------",myMsg->Buffer);
} else
/*****************************************************************
* USE database
*/
if( stricmp(cmd,"USE") == 0 ) {
if( *p ) {
myMsg->Command = kfcSELECTDBASE;
myMsg->BParam = (ULONG)p;
if( TellKF(myMsg) ) {
printf("Database \"%s\" is now in use!",p);
UpgradeBuffer( myMsg );
}
} else
printf("You should also give the name of a database to use!\n");
} else
/*****************************************************************
* PARSE file
*/
if( stricmp(cmd,"PARSE") == 0 ) {
if( *p ) {
myMsg->Command = kfcPARSEFILE;
myMsg->BParam = (ULONG)p;
while( TellKF(myMsg) ) {
if( myMsg->Error == kfeOK ) {
printf("Disk %d, Flags %04d\n"
"--------------------NEW FISH--------------------\n%s"
"------------------------------------------------\n"
"Add this to the database? (y/N/q) ",1,0,myMsg->Buffer);
fflush(stdout);
if( p = fgets(cmd,sizeof(cmd),stdin) ) {
if( (*p == 'y') || (*p == 'Y') ) {
myMsg->Command = kfcADDFISH;
myMsg->BParam = 1;
myMsg->FParam = 0x0000;
if( TellKF(myMsg) )
printf("Fish has been added as number %d\n\n",myMsg->BParam);
} else
if( (cmd[0] == 'q') || (cmd[0] == 'Q') )
break;
} else
break;
myMsg->Command = kfcPARSEFILE; /* prepare for next swing through loop */
} else
break;
} /* while */
if( myMsg->Error != kfeNOMORE ) {
myMsg->Command = kfcSTOPPARSE;
if( TellKF(myMsg) )
printf("Database has been made sharable again.\n");
} else
printf("Parsing completed. Database is sharable again.\n");
} else
printf("Please also give the name of a file!\n");
} else
/*****************************************************************
* BUILD file
*/
if( stricmp(cmd,"BUILD") == 0 ) {
if( *p ) {
myMsg->Command = kfcPARSEFILE;
myMsg->BParam = (ULONG)p;
while( TellKF(myMsg) ) {
if( myMsg->Error == kfeOK ) {
myMsg->Command = kfcADDFISH;
myMsg->BParam = 1;
myMsg->FParam = 0x0000;
if( TellKF(myMsg) )
myMsg->Command = kfcPARSEFILE; /* prepare for next swing through loop */
else
break;
} else
break;
} /* while */
if( myMsg->Error != kfeNOMORE ) {
myMsg->Command = kfcSTOPPARSE;
if( TellKF(myMsg) )
printf("Database has been made sharable again.\n");
} else
printf("Parsing completed. Database is sharable again.\n");
} else
printf("Please also give the name of a file!\n");
} else
/*****************************************************************
* REINDEX
*****************************************************************
*/
if( stricmp(cmd,"REINDEX") == 0 ) {
printf("Reindexing ");
/* we need to loop repeatedly until KFServer tells us it's done
*/
for(;;) {
printf(".");
fflush(stdout);
myMsg->Command = kfcREINDEX;
if( !TellKF(myMsg) )
break;
} /* for */
printf("\n");
} else
/*****************************************************************
* QUIT (implies a BYE if connected)
*****************************************************************
*/
if( stricmp(cmd,"QUIT") == 0 ) {
if( connected ) {
myMsg->Command = kfcBYE;
if( TellKF(myMsg) ) {
if( myMsg->Error == kfeOK ) {
printf("KFServer has said good bye.\n");
connected = FALSE;
}
}
}
happy = FALSE;
} else
/*****************************************************************
* Command not recognized ...
*****************************************************************
*/
if( cmd[0] )
printf("No such command: \"%s\"\n",cmd);
} else {
if( connected ) {
myMsg->Command = kfcBYE;
if( TellKF(myMsg) ) {
if( myMsg->Error == kfeOK ) {
printf("KFServer has said good bye.\n");
connected = FALSE;
}
}
}
happy = FALSE; /* EOF received */
}
while( reply = (struct KFMsg *)GetMsg( myPort ) ) {
if( reply->Command == kfcEXIT ) {
printf("Received EXIT request from server!\n");
connected = FALSE;
}
if( reply != myMsg )
ReplyMsg( (struct Message *)reply );
}
} /* while */
if( myPort )
DeleteMsgPort( myPort );
if( myMsg ) {
if( myMsg->Buffer )
free( myMsg->Buffer );
FreeMem( myMsg, sizeof(struct KFMsg) );
}
printf("Bye-bye!\n");
} else
printf("KFServer is not running!\n"
"Please start the server first!\n");
} /* main */
/* sends message to KFServer and waits for a reply; waits until our
* message is returned from server; processes all intermittend
* stuff from the server (i.e. kfcEXIT requests);
* returns FALSE if any problem occurred, or if the server asked us
* to exit; TRUE means "all is well, let's keep on dancing!"
*/
BOOL TellKF( struct KFMsg *myMsg ) {
struct MsgPort *PrimaryPort,*myPort=myMsg->AmigaMsg.mn_ReplyPort;
struct KFMsg *reply;
BOOL result=TRUE,showError=TRUE,done=FALSE;
ULONG sigs;
Forbid();
if( PrimaryPort = FindPort( KFPortName ) )
PutMsg( PrimaryPort, (struct Message *)myMsg );
Permit();
if( PrimaryPort ) {
while( !done ) {
sigs = Wait( (1L << myPort->mp_SigBit) | SIGBREAKF_CTRL_C );
if( sigs & (1L << myPort->mp_SigBit) )
while( reply = (struct KFMsg *)GetMsg( myPort ) ) {
if( reply == myMsg ) {
done = TRUE;
if( showError && (myMsg->Error != kfeOK) ) {
printf("ERROR: %s\n",KFError[myMsg->Error]);
if( myMsg->Error == kfeTRUNC )
UpgradeBuffer(myMsg);
if( myMsg->Buffer )
printf(myMsg->Buffer);
printf("\n");
result = FALSE;
}
} else {
if( reply->Command == kfcEXIT ) {
printf("Received EXIT request from server!\n");
result = FALSE;
} else {
if( myMsg->Error != kfeOK ) {
printf("ERROR: %s\n",KFError[myMsg->Error]);
if( myMsg->Buffer )
printf(myMsg->Buffer);
printf("\n");
showError = FALSE;
result = FALSE;
}
}
printf("Replying to %08x\n",reply->AmigaMsg.mn_ReplyPort);
ReplyMsg( (struct Message *)reply );
}
} /* while */
if( sigs & SIGBREAKF_CTRL_C ) {
SetSignal(0L,SIGBREAKF_CTRL_C);
printf("Wait for reply from server interrupted.\n"
"The client is now in a precarious state and should NOT quit!\n");
done = TRUE;
result = FALSE;
}
} /* while */
} else {
printf("The KFServer (%s) has shutdown!\n"
"Please QUIT the CLIent, too.\n",KFPortName);
myMsg->Error = 0xffff;
result = FALSE;
}
return result;
} /* Tell */