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 + -
显示快捷键?