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 )