AcePerl
view release on metacpan or search on metacpan
acelib/aceclientlib.c view on Meta::CPAN
dirName = strnew (name, 0) ;
for (cp = dirName ; *cp ; ++cp) ;
while (cp > dirName && *cp != '/') --cp ;
*++cp = '.' ;
*++cp = 0 ;
if (!(f = fopen(dirName, "r")))
{ if (accessDebug)
printf ("// directory %s not readable\n", dirName) ;
return 0 ;
}
fclose (f) ;
}
{ int i ;
struct itimerval tval ;
signal (SIGALRM, wakeUp) ;
tval.it_interval.tv_sec = 0 ;
tval.it_interval.tv_usec = 5000 ; /* 5ms reload */
tval.it_value.tv_sec = 0 ;
tval.it_value.tv_usec = 1000 ; /* 1ms initial */
setitimer (ITIMER_REAL, &tval, 0) ;
for (i = 0 ; i < 1000 ; ++i) /* 5 seconds */
{ pause () ; /* wait until SIGALRM handled */
f = fopen (name, "r") ;
if (f)
{ if (accessDebug)
printf ("// found %s after %d msecs\n", name, 5*i+1) ;
tval.it_interval.tv_usec = tval.it_value.tv_usec = 0 ;
setitimer (ITIMER_REAL, &tval, 0) ;
return f ;
}
}
if (accessDebug)
printf ("// failed to find %s after %d msecs\n", name, 5*i+1) ;
tval.it_interval.tv_usec = tval.it_value.tv_usec = 0 ;
setitimer (ITIMER_REAL, &tval, 0) ;
}
return 0 ;
}
static int getMagic (int magic1, char *nm)
{ int magic = 0, magic2 = 0, magic3 = 0 ;
FILE *f ;
int level ;
char *cp ;
if (magic1 < 0) magic1 = -magic1 ; /* old system */
if (!nm || !*nm) return 0 ;
freeinit() ;
level = freesettext(nm,0) ;
if (!freecard(level))
goto fin ;
cp = freeword () ;
if (!cp)
{ messerror ("Can't obtain write pass name from server") ;
goto fin ;
}
if (accessDebug)
printf ("// Write pass file: %s\n", cp) ;
if (strcmp(cp, "NON_WRITABLE"))
{ f = magicFileOpen (cp) ;
if (f)
{ if (fscanf(f, "%d", &magic3) != 1)
messerror ("failed to read file") ;
fclose(f) ;
}
}
if ((cp = freeword ()) &&
!magic3) /* must be able to read if can write */
{ if (accessDebug)
printf ("// Read pass file: %s\n", cp) ;
if (strcmp(cp, "PUBLIC") && strcmp(cp,"RESTRICTED"))
{ f = magicFileOpen (cp) ;
if (!f)
{ messout ("// Access to this database is restricted, sorry (can't open pass file)\n") ;
goto fin ;
}
if (fscanf(f, "%d", &magic2) != 1)
messerror ("failed to read file") ;
fclose(f) ;
}
}
magic = magic1 ;
if (magic2)
magic = magic1 * magic2 % 73256171 ;
if (magic3)
magic = magic1 * magic3 % 43532334 ;
fin:
freeclose(level) ;
#ifdef DEEP_DEBUG
printf ("// magic1=%d, magic2=%d, magic3=%d, magic=%d\n",
magic1, magic2, magic3, magic) ;
#endif
return magic ;
}
/*************************************************************
Open RPC connection to server
INPUT
char *host hostname running server
int timeOut maximum peroid to wait for answer
OUTPUT
return value:
ace_handle * pointer to structure containing open connection
and client identification information
*/
ace_handle *openServer(char *host, u_long rpc_port, int timeOut)
{
struct timeval tv;
char *answer;
int length,
clientId = 0, n,
magic1, magic3 = 0 ;
ace_reponse *reponse = 0;
ace_data question ;
ace_handle *handle;
CLIENT *clnt;
/* open rpc connection */
/* lao: */
clnt = clnt_create (host, RPC_ACE, RPC_ACE_VERS, "tcp");
if (!clnt) return((ace_handle *)NULL);
/* authenticate */
question.clientId = 0;
question.magic = 0;
question.reponse.reponse_len = 0;
question.reponse.reponse_val = "";
question.question = "";
question.aceError = 0;
question.kBytes = 0;
question.encore = 0;
acelib/aceclientlib.c view on Meta::CPAN
handle->clnt = clnt;
return handle ;
}
/*************************************************************
notify server of intent to close connection
close connection
free structures
INPUT
ace_handle * pointer to structure containing open connection
and client identification information
OUTPUT
none
*/
void closeServer(ace_handle *handle) {
ace_data question;
ace_reponse *reponse = 0;
if (handle) {
if ( (int *)handle && (CLIENT *)handle->clnt) {
/* JC not sure whether I should/need check (int *)handle */
question.clientId = handle->clientId ;
question.magic = handle->magic ;
question.reponse.reponse_len = 0;
question.reponse.reponse_val = "";
question.question = "Quit";
question.aceError = 0;
question.kBytes = 0;
question.encore = 0;
reponse = ace_server_1(&question, handle->clnt);
if (reponse)
{ xdr_free((xdrproc_t )xdr_ace_reponse, (char *)reponse);
memset (reponse,0, sizeof(ace_reponse)) ;
}
clnt_destroy((CLIENT *)handle->clnt);
}
free((char *)handle);
}
}
/*************************************************************
transfer request to server, and wait for binary answer
INPUT
char * request string containing request
unsigned char ** answer ptr to char ptr, that has to be filled with answer
ace_handle * pointer to structure containing open connection
and client identification information
int chunkSize desired size (in kBytes) of returned data-block
This is only a hint. The server can return more.
The server splits on ace boundaries
a chunkSize of 0 indicates a request for unbuffered answers
OUTPUT
unsigned char ** answer ptr to char ptr. Pointing to allocated memory containing
answer string. This memory will be filled with the
unmodified data handled as binary bytes.
return value:
int error condition
ESUCCESS (0) no error.
EIO (5) no response received from server.
ENOMEM (12) no memory available to store answer.
or a server generated error
JC if the server can return both an encore and an aceError at the same time
I'm in trouble. I use only one int return value for both
*/
int askServerBinary(ace_handle *handle, char *request, unsigned char **answerPtr,
int *answerLength, int *encorep, int chunkSize)
{
ace_data question ;
ace_reponse *reponse = 0 ;
unsigned char *answer, *loop ;
int aceError, length, i, encore = 0 ;
/* generate question structure */
question.clientId = handle->clientId;
question.magic = handle->magic;
question.reponse.reponse_len = 0;
question.reponse.reponse_val = "";
question.kBytes = chunkSize;
question.aceError = 0;
/* check if request contains a local command */
if (!strncasecmp(request,"encore",6))
{
/* encore request */
question.encore = WANT_ENCORE;
question.question = "";
}
else if (!strncasecmp(request,"noencore",8))
{
/* encore request */
question.encore = DROP_ENCORE;
question.question = "";
}
else if (!strncasecmp(request,"quit",4))
{ /* ignore quit request. Must go through closeServer routine */
*answerLength = 0;
*answerPtr = NULL;
return 0;
}
else
{ question.encore = 0;
question.question = request;
}
if (*encorep == 3)
question.encore = -3 ;
reponse = ace_server_1(&question, handle->clnt);
/* validity checking of reponse */
/* no data was received, return error */
if (!reponse)
return EIO ;
/* store server returned error status. Give this to the client */
/* JC answer could contain more info on error, so
continue normal handling of the answer */
aceError = reponse->ace_reponse_u.res_data.aceError;
/* no answer was received, return NULL answer
leave checking for NULL reponse to upper layer
if (reponse->ace_reponse_u.res_data.reponse.reponse_len == 0) {
xdr_free((xdrproc_t )xdr_ace_reponse, (char *)reponse);
memset (reponse,0, sizeof(ace_reponse)) ;
*answerLength = 0;
*answerPtr = NULL;
return aceError;
}
*/
/* answer received. allocate memory and fill with answer */
length = reponse->ace_reponse_u.res_data.reponse.reponse_len;
loop = (unsigned char *) reponse->ace_reponse_u.res_data.reponse.reponse_val;
encore = reponse->ace_reponse_u.res_data.encore ;
if ((answer = (unsigned char *)malloc(sizeof(unsigned char)*(length+1))) == NULL)
{
/* JC Need to tell the server we have a problem ?
I guess if the server gave an encore, we need to cancel it
*/
xdr_free((xdrproc_t )xdr_ace_reponse, (char *)reponse);
return(ENOMEM);
}
for (i=0;i<length;i++)
answer[i] = loop[i];
answer[i] = 0 ; /* zero terminate */
xdr_free((xdrproc_t )xdr_ace_reponse, (char *)reponse);
*answerPtr = answer;
*answerLength = length;
*encorep = encore ;
return aceError ? aceError : - encore ; /* surcharge pour JD */
}
/***************************************************************
transfer request to server, and wait for binary answer. Convert answer
to ASCII string
INPUT
char * request string containing request
char ** answer ptr to char ptr, that has to be filled with answer
ace_handle * pointer to structure containing open connection
and client identification information
int chunkSize desired size (in kBytes) of returned data-block
This is only a hint. The server can return more.
The server splits on ace boundaries
a chunkSize of 0 indicates a request for unbuffered answers
OUTPUT
char ** answer ptr to char ptr. Pointing to allocated memory containing
answer string.
return value:
int error condition
ESUCCESS (0) no error.
EIO (5) no response received from server.
ENOMEM (12) no memory available to store answer.
or a server generated error
*/
int askServer(ace_handle *handle, char *request, char **answerPtr, int chunkSize)
{ int length, i, encore ;
int returnValue;
unsigned char *binaryAnswer;
char *answer;
char *loop;
returnValue = askServerBinary(handle, request, &binaryAnswer, &length, &encore, chunkSize) ;
if (returnValue <= 0)
{ /* allocate memory for return string */
/* if memory is more important than speed, we could run
through the string first and count the number of '\0''s
and substract this from the memoryblock we allocate */
if (!length ) /* empty string */
{ *answerPtr = 0;
return returnValue;
}
if ((answer = (char *)malloc(length+1)) == NULL)
{ free(binaryAnswer);
return(ENOMEM);
}
/* initial step of the copy process */
loop = (char *)binaryAnswer;
strcpy(answer,loop);
i = *loop ? strlen(loop): 0 ;
loop += i;
for (;(*loop == '\0')&&(i<length) ;loop++,i++);
for (;i<length;)
{ strcat(answer,loop);
i += strlen(loop);
loop += strlen(loop);
for (;(*loop == '\0')&&(i<length) ;loop++,i++);
}
*(answer+i) = '\0'; /* for safety, make sure the string is terminated */
free((char *)binaryAnswer);
*answerPtr = answer;
}
return returnValue;
}
/************** end of file **************/
( run in 0.916 second using v1.01-cache-2.11-cpan-39bf76dae61 )