libcom_tcp.c

来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 2,071 行 · 第 1/5 页

C
2,071
字号
  printf("If you want me to listen on a different port, enter \"n\", which will\n");
  printf("cause me to terminate.  Then change your port specification (it's\n");
  printf("either in a setup file or an environment variable).  Then restart me.\n");

#endif
}

int
com_ask_about_tcp_exception(int Port, char *Host) {

  char response[100];

  do {
    printf("Currently unable to access %s port %d.\n Try again? [y)es, n)o, h(elp] ", Host, Port);

    scanf("%s\n", (char *)(&response));

    if (strcmp(response,"y") == 0)
      return 1;
    else

      if (strcmp(response, "n") == 0)
        return 0;
      else

        if (strcmp(response, "h") == 0)
          com_print_tcp_exception_help();
  } while (TRUE);
}

/**
 * Looks up the local connections database to extract a socket id.
 * @return the socket id as int, or -1 if fails
 */
int com_get_socket_from_connection_id(char* ConnectionId) {
  ICLTerm *info = NULL;
  int socketNumber = -1;

  /* DEBUG */
  /*
    if (commdb)
    db_PrintDB(commdb);
  */

  ICLTerm* requestTerm = icl_NewStruct("connection", 1, icl_NewVar("_"));
  if (ConnectionId && *ConnectionId && commdb &&
      com_GetInfo(ConnectionId, requestTerm, &info)) {
    icl_NthTermAsInt(info, 1, &socketNumber);
    icl_Free(info);
  }
  icl_Free(requestTerm);

  return socketNumber;
}

/**
 * Sends data to the specified connection ID.
 * For compatibility between Windows and UNIX.
 */
int basic_send(SOCKET inSocket, char *Data, int Size)
{
  int res = FALSE;

  /* send data */
  if (inSocket>0) {
#ifdef _WINDOWS  /* ---------------------------------------------------- */
    if (send(inSocket, Data, Size,0) == SOCKET_ERROR)
      res = -1;
#else
    res = (write(inSocket, Data, Size) == Size);
#endif  /* --------------------------------------------------------------- */
  }
  return res;
}

/**
 * Sends data to the specified connection ID.
 * @return TRUE if success
 */
EXPORT_MSCPP
int EXPORT_BORLAND
com_SendData(char *ConnectionId, char *Data, int Size)
{
  int res = FALSE;
  int socketNumber = com_get_socket_from_connection_id(ConnectionId);

  /* send data */
  if (socketNumber>0) {
    char *buffer = (char*)malloc(Size+8);    /* count \0 too */
    sprintf(buffer,"term(%s).", Data);

    /* DEBUG */
    /*
      printDebug(5, "Sending %s\n", buffer);
    */

    basic_send(socketNumber, buffer, strlen(buffer));
    buffer[0] = 10;
    basic_send(socketNumber, buffer, 1);

    free(buffer);
  }
  return res;
}

EXPORT_MSCPP
int EXPORT_BORLAND
com_SendTerm(char* connectionId, ICLTerm* term)
{
  ICLTerm* result;
  ICLTerm* query = icl_NewTermFromData("sender(_)",9);
  char* pointerStr;
  TermSender* ts;
  if(!com_GetInfo(connectionId, query, &result)) {
    icl_Free(query);
    return FALSE;
  }

  pointerStr = icl_Str(icl_NthTerm(result, 1));
  pointerStr = strdup(pointerStr);
  icl_stRemoveQuotes(pointerStr);
  ts = (TermSender*)stringToPointer(pointerStr);
  free(pointerStr);
  /*
  {
    char* ds = icl_NewStringFromTerm(term);
    fprintf(stderr, "com_SendData(char*, ICLTerm*) sending term [%s]\n", ds);
    icl_stFree(ds);
  }
  */
  termSender_sendTerm(ts, term);
  if(termSender_getError(ts) != TERMSENDER_OKAY) {
    fprintf(stderr, "com_SendData(char*, ICLTerm*) did not send term\n");
    icl_Free(query);
    icl_Free(result);
    return FALSE;
  }
  icl_Free(query);
  icl_Free(result);
  return TRUE;
}

/**
 * Sends data to the specified connection ID.
 * Info may be status(S), type(T), protocol(P) or any element (or list
 * of elements) to be stored in InfoList.
 * @return TRUE if success
 */
EXPORT_MSCPP
int EXPORT_BORLAND
com_AddInfo(char *ConnectionId, ICLTerm *NewInfo)
{
  ICLTerm *info = NULL, *result = NULL;
  char cmd[200];
  int changed = FALSE;
  int res = FALSE;

  /* Make sure there's a valid connection id */
  if (!ConnectionId || !*ConnectionId || !commdb)
    return FALSE;

  sprintf(cmd, "com_connection_info('%s', Protocol, Type,InfoList,Status)",
          ConnectionId);
  info = icl_NewTermFromString(cmd);

  if (db_Solve(commdb, info, ICL_EMPTY, &result)) {
    ICLTerm *ninfo = NULL, *item;
    ICLTerm *protocol, *type, *infolist, *status;
    ICLTerm* templateProtocol =  icl_NewStruct("protocol", 1, icl_NewVar("_"));
    ICLTerm* templateStatus =  icl_NewStruct("status", 1, icl_NewVar("_"));
    ICLTerm* templateType =  icl_NewStruct("type", 1, icl_NewVar("_"));

    db_Retract(commdb, info, ICL_EMPTY);
    item = icl_NthTerm(result, 1);

    if (icl_Unify(templateProtocol, NewInfo, NULL)) {
      protocol = icl_NthTerm(NewInfo, 1);
      changed = TRUE;
    }
    else protocol = icl_NthTerm(item, 2);

    if (icl_Unify(templateType, NewInfo, NULL)) {
      type = icl_NthTerm(NewInfo, 1);
      changed = TRUE;
    }
    else type = icl_NthTerm(item, 3);

    if (icl_Unify(templateStatus, NewInfo, NULL)) {
      status = icl_NthTerm(NewInfo, 1);
      changed = TRUE;
    }
    else status = icl_NthTerm(item, 5);

    if (!changed) {
      if (icl_IsList(NewInfo)) {
        ICLListType *p = icl_List(NewInfo);
        while (p) {
          icl_AddToList(icl_NthTerm(item, 4), icl_CopyTerm(p->elt), TRUE);
          p = p->next;
        }
      }
      else
        icl_AddToList(icl_NthTerm(item, 4), icl_CopyTerm(NewInfo), TRUE);
    }
    infolist = icl_NthTerm(item, 4);

    ninfo = icl_NewStruct("com_connection_info", 5, icl_NewStr(ConnectionId),
                          icl_CopyTerm(protocol), icl_CopyTerm(type),
                          icl_CopyTerm(infolist), icl_CopyTerm(status));

    db_Assert(commdb, ninfo, ICL_EMPTY);

    icl_Free(ninfo);
    icl_Free(result);
    icl_Free(templateProtocol);
    icl_Free(templateStatus);
    icl_Free(templateType);
    res = TRUE;
  }
  else {
    res = FALSE;
  }
  icl_Free(info);
  return res;
}

/**
 * Looks up info based on the connection id.
 * @return TRUE if success
 */
EXPORT_MSCPP
int EXPORT_BORLAND
com_GetInfo(char *ConnectionId, ICLTerm *GInfo, ICLTerm **Result)
{
  ICLTerm *info = NULL, *result = NULL;
  char cmd[200];
  int res = FALSE;

  /* DEBUG */
  /* printf("Comm get info for %s\n", icl_NewStringFromTerm(GInfo));*/


  /* Make sure there's a valid connection id */
  if (!ConnectionId || !*ConnectionId || !commdb)
    return FALSE;

  sprintf(cmd, "com_connection_info(%s, Protocol, Type,InfoList,Status)",
          ConnectionId);
  info = icl_NewTermFromString(cmd);

  if (db_Solve(commdb, info, ICL_EMPTY, &result)) {

    ICLTerm *item = NULL;
    ICLTerm* templateProtocol =  icl_NewStruct("protocol", 1, icl_NewVar("_"));
    ICLTerm* templateStatus =  icl_NewStruct("status", 1, icl_NewVar("_"));
    ICLTerm* templateType =  icl_NewStruct("type", 1, icl_NewVar("_"));

    /* DEBUG */
    /* printf("Result from solve %s\n", icl_NewStringFromTerm(result));*/

    res = TRUE;
    item = icl_NthTerm(result, 1);

    if (icl_Unify(templateProtocol, GInfo, NULL)) {
      if (Result!=NULL) {
        *Result = icl_CopyTerm(icl_NthTerm(item, 2));
      }
      res = TRUE;
    }
    else if (icl_Unify(templateStatus, GInfo, NULL)){
      if (Result!=NULL) {
	*Result = icl_CopyTerm(icl_NthTerm(item, 5));
      }
      res = TRUE;
    }
    else if (icl_Unify(templateType, GInfo, NULL)){
      if (Result!=NULL) {
	*Result = icl_CopyTerm(icl_NthTerm(item, 3));
      }
      res = TRUE;
    }
    else if (Result!=NULL) {
      ICLTerm* tempList = icl_NthTerm(item, 4);
      /* printf("List %s\n", icl_NewStringFromTerm(tempList)); */
      res = icl_Member(GInfo, tempList, Result);
    }

    icl_Free(templateProtocol);
    icl_Free(templateStatus);
    icl_Free(templateType);
    icl_Free(result);
  }
  else {
    res = FALSE;
  }
  icl_Free(info);

  return res;
}


/**
 * Looks up connection id based on oaa_name, oaa_id, or fac_id,
 * @returns TRUE if success
 */
EXPORT_MSCPP
int EXPORT_BORLAND
com_GetConnectionId(char **ConnectionId, ICLTerm *GInfo)
{
  static ICLTerm *info = NULL;
  ICLTerm *result = NULL;
  int res = FALSE;

  if (!icl_IsValid(info)) {
    info = icl_NewTermFromData("com_connection_info(ConnectionId,Protocol,Type,InfoList,Status)",63);
  }

  /*
   * Retrieve all connection_info terms from the db
   */
  if (db_Solve(commdb, info, ICL_EMPTY, &result)) {

    ICLListType *reslist = icl_List(result);

    while(reslist != NULL) {
      ICLTerm *current = reslist->elt;
      ICLTerm *infolist = icl_NthTerm(current, 4);
      reslist = reslist->next;

      /*
       * check for the various types of info to match against
       */
      if(icl_ParamValue(icl_Functor(GInfo), icl_NthTerm(GInfo, 1),
                        infolist, NULL)) {
        *ConnectionId = strdup(icl_Str(icl_NthTerm(current, 1)));
        res = TRUE;
        break;
      }
    }
    icl_Free(result);
    /* Free reslist */
  }
  return res;
} // end of com_GetConnectionId

/*
 * name:    com_SelectEvent
 * purpose:
 * remarks:
 * returns: True if success
 */
EXPORT_MSCPP
int EXPORT_BORLAND
com_SelectEvent(char* inConnectionId, double timeout, ICLTerm **event){
  ICLTerm* readerTerm;
  ICLTerm* query;
  TermReader* reader;
  char* readerString;

  query = icl_NewTermFromData("reader(_)",9);
  if(!com_GetInfo(inConnectionId, query, &readerTerm)) {
    icl_Free(query);
    fprintf(stderr, "com_SelectEvent could not find reader\n");
    return FALSE;
  }
  readerString = icl_Str(icl_NthTerm(readerTerm, 1));
  readerString = strdup(readerString);
  icl_stRemoveQuotes(readerString);
  reader = (TermReader*)stringToPointer(readerString);
  free(readerString);
  *event = termReader_getNextTerm(reader, timeout);
  icl_Free(query);
  icl_Free(readerTerm);
  if(*event == NULL) {
    int te = termReader_getError(reader);
    fprintf(stderr, "com_SelectEvent error in reading term: %i\n", te);
    return FALSE;
  }
  else {
    return TRUE;
  }
}

/**
 * Prints out tcpError messages.
 */
EXTERN void comPrintError(char *str, ...) {
  char buf[512];
  va_list ptr;
  va_start(ptr,str);
  vsprintf(buf,str,ptr);
  printf("COM ERROR : %s\n",  buf);
  va_end(ptr);
}

/****************************************************************************
 * Definitions for MICROSOFT WINDOWS Specific functions
 ****************************************************************************/

#ifdef _WINDOWS   /*---------------------------------------------------*/

int EXPORT_MSCPP tcpStartup()
{
  WORD wVersionRequested;
  WSADATA wsaData;

  /* Asking for version 1.1 */
  wVersionRequested=MAKEWORD(1,1);

  if (WSAStartup(wVersionRequested,&wsaData)!=0)
    return (0);

  if (LOBYTE(wsaData.wVersion)!=1 ||
      HIBYTE(wsaData.wVersion)!=1) {
    WSACleanup();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?