static void esif_ws_cgi_parse_script ( const char *resourceLoc, int fd, char *full_script_name ) { char abbr_script_name[100]; u32 i = 0; esif_ccb_memcpy(abbr_script_name, resourceLoc, esif_ccb_strlen(resourceLoc, MAX_SIZE)); abbr_script_name[esif_ccb_strlen(resourceLoc, MAX_SIZE)] = 0; printf("cgi script name: %s\n", abbr_script_name); i = i; // to satisfy compiler #ifdef ESIF_ATTR_OS_WINDOWS for (i = 0; i < esif_ccb_strlen(abbr_script_name, MAX_SIZE); i++) if (abbr_script_name[i] == '/') { abbr_script_name[i] = '\\'; } #endif esif_ccb_strcat(full_script_name, abbr_script_name, sizeof(full_script_name)); printf("full_cgi_script_name: %s\n", full_script_name); esif_ws_cgi_redirect_output(full_script_name, fd); }
/* Data For Interface Marshaling */ static AppDomainDataPtr CreateDomainData(const struct esif_fpc_domain *domainPtr) { AppDomainDataPtr dom_data_ptr = (AppDomainDataPtr)esif_ccb_malloc(sizeof(AppDomainData)); ESIF_TRACE_DEBUG("%s\n", domainPtr->descriptor.name); if (NULL == dom_data_ptr) { goto exit; } dom_data_ptr->fName.buf_ptr = (void *)domainPtr->descriptor.name; dom_data_ptr->fName.buf_len = ESIF_NAME_LEN; dom_data_ptr->fName.data_len = (UInt32)esif_ccb_strlen(domainPtr->descriptor.name, ESIF_NAME_LEN); dom_data_ptr->fName.type = ESIF_DATA_STRING; dom_data_ptr->fDescription.buf_ptr = (void *)domainPtr->descriptor.description; dom_data_ptr->fDescription.buf_len = ESIF_DESC_LEN; dom_data_ptr->fDescription.data_len = (UInt32)esif_ccb_strlen(domainPtr->descriptor.description, ESIF_DESC_LEN); dom_data_ptr->fDescription.type = ESIF_DATA_STRING; dom_data_ptr->fGuid.buf_ptr = (void *)domainPtr->descriptor.guid; dom_data_ptr->fGuid.buf_len = ESIF_GUID_LEN; dom_data_ptr->fGuid.data_len = ESIF_GUID_LEN; dom_data_ptr->fGuid.type = ESIF_DATA_GUID; dom_data_ptr->fVersion = APP_DOMAIN_VERSION; dom_data_ptr->fType = (enum esif_domain_type)domainPtr->descriptor.domainType; dom_data_ptr->fCapability = domainPtr->capability_for_domain.capability_flags; esif_ccb_memcpy(dom_data_ptr->fCapabilityBytes, domainPtr->capability_for_domain.capability_mask, 32); exit: return dom_data_ptr; }
// Automatically Load all Static DataVaults and *.dv files in the current folder into the DataBank eEsifError DataBank_LoadDataVaults (DataBankPtr self) { eEsifError rc = ESIF_OK; esif_ccb_file_find_handle find_handle = INVALID_HANDLE_VALUE; char file_path[MAX_PATH] = {0}; char file_pattern[MAX_PATH] = {0}; struct esif_ccb_file *ffd_ptr; UInt32 idx; ASSERT(self); // Import all Static DataVaults into ReadOnly DataVaults for (idx = 0; g_StaticDataVaults[idx].name; idx++) { DataVaultPtr DB = DataBank_OpenNameSpace(self, g_StaticDataVaults[idx].name); if (DB) { IOStream_SetMemory(DB->stream, g_StaticDataVaults[idx].buffer, g_StaticDataVaults[idx].buf_len); DB->flags |= (ESIF_SERVICE_CONFIG_READONLY | ESIF_SERVICE_CONFIG_NOCACHE); DataVault_ReadVault(DB); } } // Create DataVault Directory if it doesn't exit esif_build_path(file_path, sizeof(file_path), ESIF_PATHTYPE_DV, NULL, NULL); esif_ccb_makepath(file_path); // Import all matching *.dv files into ReadWrite DataVaults esif_ccb_sprintf(MAX_PATH, file_pattern, "*%s", ESIFDV_FILEEXT); ffd_ptr = (struct esif_ccb_file*)esif_ccb_malloc(sizeof(*ffd_ptr)); if (NULL == ffd_ptr) { rc = ESIF_E_NO_MEMORY; } if (rc == ESIF_OK) { find_handle = esif_ccb_file_enum_first(file_path, file_pattern, ffd_ptr); } if (INVALID_HANDLE_VALUE != find_handle) { do { struct esif_ccb_file dv_file = {0}; DataVaultPtr DB = 0; // Read DataVault File, unless it's already been loaded as a Static DataVault if (esif_ccb_strlen(ffd_ptr->filename, MAX_PATH) > sizeof(ESIFDV_FILEEXT)) { ffd_ptr->filename[esif_ccb_strlen(ffd_ptr->filename, MAX_PATH) - (sizeof(ESIFDV_FILEEXT) - 1)] = 0; // Truncate ".dv" extension if (DataBank_GetNameSpace(self, ffd_ptr->filename) == NULL) { DB = DataBank_OpenNameSpace(self, ffd_ptr->filename); if (DB) { esif_build_path(dv_file.filename, sizeof(dv_file.filename), ESIF_PATHTYPE_DV, DB->name, ESIFDV_FILEEXT); IOStream_SetFile(DB->stream, dv_file.filename, "rb"); DataVault_ReadVault(DB); } } } } while (esif_ccb_file_enum_next(find_handle, file_pattern, ffd_ptr)); esif_ccb_file_enum_close(find_handle); } esif_ccb_free(ffd_ptr); return rc; }
static void esif_ws_cgi_parse_query ( char *query, const char *beg_parms_loc_in_query, int fd, char *cgi_dir ) { char *cgi_script; char *cgi_script_buf; // char *cgi_dir; char cgiParms[100]; size_t cgi_script_size; #define MAX_SIZE 100 cgi_script_size = query - beg_parms_loc_in_query; cgi_script = (char*)esif_ccb_malloc(cgi_script_size + 1); if (cgi_script == NULL) { exit(1); } // cgi_dir = (char*)esif_ccb_malloc(esif_ccb_strlen(cgi_dir, MAX_SIZE) + cgi_script_size); // if (cgi_dir == NULL) // exit(1); esif_ccb_memcpy(cgi_script, beg_parms_loc_in_query, cgi_script_size); // esif_ccb_memcpy(cgi_dir, DIRECTORY, esif_ccb_strlen(DIRECTORY, MAX_SIZE)); cgi_script[cgi_script_size] = '\0'; // cgi_dir[esif_ccb_strlen(DIRECTORY, MAX_SIZE)]='\0'; printf("cgi_script 1: %s\n", cgi_script); query++; cgi_script_buf = cgi_script; #ifdef ESIF_ATTR_OS_WINDOWS cgi_script_buf = (char*)strrchr(cgi_script_buf, '/'); cgi_script_buf++; cgi_script_buf[esif_ccb_strlen(cgi_script_buf, MAX_SIZE)] = '\0'; #endif esif_ccb_strcpy(cgiParms, query, esif_ccb_strlen(query, MAX_SIZE)); printf("cgi_dir: %s\n", cgi_dir); printf("cgiParms 1: %s\n", cgiParms); esif_ccb_strcat(cgi_dir, cgi_script_buf, sizeof(cgi_dir)); esif_ws_cgi_redirect_output(cgi_dir, fd); if (cgi_script) { esif_ccb_free(cgi_script); } // if (cgi_dir) // esif_ccb_free(cgi_dir); }
// Read a Registry Key Value into a specified memory buffer static eEsifError DataVault_ReadRegistry ( DataVaultPtr self, esif_string keyname, void * *buffer, UInt32 *buf_size ) { eEsifError rc = ESIF_E_UNSPECIFIED; HKEY hKey = 0; DWORD dwFlags = RRF_RT_ANY; DWORD dwError = 0; DWORD dwSize = 0; char *regkey = 0; char *valuename = 0; u32 j; UNREFERENCED_PARAMETER(self); // Format: HKLM\Subkey\Path\ValueName for (j = 0; HKeyList[j].name; j++) { size_t namelen = esif_ccb_strlen(HKeyList[j].name, 30); if (esif_ccb_strnicmp(HKeyList[j].name, keyname, namelen) == 0 && keyname[namelen] == '\\') { hKey = HKeyList[j].hkey; keyname += esif_ccb_strlen(HKeyList[j].name, 30) + 1; break; } } if (!hKey) { return rc; } regkey = esif_ccb_strdup(keyname); if ((valuename = strrchr(regkey, '\\')) == 0) { esif_ccb_free(regkey); return rc; } *valuename++ = 0; // Get Data Size from Registry and copy into buffer if found if ((dwError = RegGetValueA(hKey, regkey, valuename, dwFlags, NULL, 0, &dwSize)) == 0) { void *reg_buf = esif_ccb_malloc(dwSize); dwError = RegGetValueA(hKey, regkey, valuename, dwFlags, NULL, reg_buf, &dwSize); if (dwError == 0) { *buffer = reg_buf; *buf_size = dwSize; rc = ESIF_OK; } else { esif_ccb_free(reg_buf); } } else { rc = ESIF_E_NOT_FOUND; } esif_ccb_free(regkey); return rc; }
// This extracts the Kernel version from the string returned by esif_cmd_info() static void extract_kernel_version(char *str, size_t buf_len) { char *prefix = "Kernel Version = "; size_t len = esif_ccb_strlen(prefix, buf_len); if (str != NULL && esif_ccb_strnicmp(str, "Kernel Version = ", len) == 0) { esif_ccb_strcpy(str, str+len, buf_len); len = esif_ccb_strlen(str, buf_len); if (len > 1 && str[len-1] == '\n') { str[len-1] = 0; } } }
/* WARNING: The allocated strings in replacedStrPtr must be released by the caller */ eEsifError EsifFpcAction_GetParamAsEsifData( EsifFpcActionPtr fpcActionPtr, UInt8 paramNum, EsifDataPtr paramPtr ) { eEsifError rc = ESIF_OK; DataItemPtr dataItemPtr = NULL; EsifString paramStr = NULL; if ((NULL == fpcActionPtr) || (NULL == paramPtr)) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } paramPtr->buf_len = 0; paramPtr->buf_ptr = NULL; paramPtr->type = ESIF_DATA_UINT32; dataItemPtr = EsifFpcAction_GetParam(fpcActionPtr, paramNum); if (NULL == dataItemPtr) { goto exit; } switch (dataItemPtr->data_type) { case DATA_ITEM_TYPE_STRING: { paramStr = (EsifString) &dataItemPtr->data; paramPtr->buf_ptr = paramStr; paramPtr->buf_len = (u32)esif_ccb_strlen(paramStr, MAXPARAMLEN); paramPtr->data_len = (u32)esif_ccb_strlen(paramStr, MAXPARAMLEN); paramPtr->type = ESIF_DATA_STRING; break; } case DATA_ITEM_TYPE_UINT32: paramPtr->buf_ptr = (u32 *)&dataItemPtr->data; paramPtr->buf_len = dataItemPtr->data_length_in_bytes; paramPtr->data_len = dataItemPtr->data_length_in_bytes; paramPtr->type = ESIF_DATA_UINT32; break; default: break; } exit: return rc; }
// Recursively create a path if it does not already exist static int esif_ccb_makepath (char *path) { int rc = -1; struct stat st = {0}; // create path only if it does not already exist if ((rc = esif_ccb_stat(path, &st)) != 0) { size_t len = esif_ccb_strlen(path, MAX_PATH); char dir[MAX_PATH]; char *slash; // trim any trailing slash esif_ccb_strcpy(dir, path, MAX_PATH); if (len > 0 && dir[len - 1] == *ESIF_PATH_SEP) { dir[len - 1] = 0; } // if path doesn't exist and can't be created, recursively create parent folder(s) if ((rc = esif_ccb_stat(dir, &st)) != 0 && (rc = esif_ccb_mkdir(dir)) != 0) { if ((slash = esif_ccb_strrchr(dir, *ESIF_PATH_SEP)) != 0) { *slash = 0; if ((rc = esif_ccb_makepath(dir)) == 0) { *slash = *ESIF_PATH_SEP; rc = esif_ccb_mkdir(dir); } } } } return rc; }
const char *EsifTraceModule_ToString(enum esif_tracemodule val) { const char *str = EsifTraceModule_FullName(val); if (str && esif_ccb_strlen(str, 20) >= 17) str += 17; // Truncate "ESIF_TRACEMODULE_" return str; }
static void esif_ws_http_send_error_code ( ClientRecordPtr connection, int error_code ) { char buffer[MAX_PATH]={0}; char *message = (error_code==404 ? "Not Found" : "Error"); esif_ccb_sprintf(sizeof(buffer), buffer, (char*)"HTTP/1.1 %d %s\r\n\r\n<h1>%d %s</h1>", error_code, message, error_code, message); send(connection->socket, buffer, (int)esif_ccb_strlen(buffer, sizeof(buffer)), ESIF_WS_SEND_FLAGS); esif_ws_client_close_client(connection); }
static void esif_ws_http_send_error_code ( int fd, int error_code ) { char buffer[BUFFER_LENGTH]; error_code = error_code; (void)esif_ccb_sprintf(BUFFER_LENGTH, buffer, (char*)"HTTP/1.1 404 Not Found\r\n\r\n"); (void)send(fd, buffer, (int)esif_ccb_strlen(buffer, MAX_SIZE), 0); esif_uf_ccb_sock_close(fd); }
char *esif_memtrace_strdup( const char *str, const char *func, const char *file, int line ) { size_t len = esif_ccb_strlen(str, 0x7fffffff) + 1; char *mem_ptr = (char *)esif_memtrace_alloc(0, len, func, file, line); if (NULL != mem_ptr) { esif_ccb_strcpy(mem_ptr, str, len); } return mem_ptr; }
// Replacement for strstr() that supports Case-Insensitive searches static const char*strfind ( const char *str, const char *strSearch, int IgnoreCase ) { if (IgnoreCase) { size_t len = esif_ccb_strlen(strSearch, 0x7FFFFFFF); while (*str != 0 && esif_ccb_strnicmp(str, strSearch, len) != 0) str++; return *str != 0 ? str : 0; } return strstr(str, strSearch); }
/* TRUE if item is an exact match or item is a member of "item1|item2|...|itemN" (case-insensitive) */ static Bool minterm_matches( esif_string list, esif_string item ) { size_t len = esif_ccb_strlen(item, MAX_MINTERM_LENGTH); while (list) { if ((esif_ccb_strnicmp(list, item, len) == 0) && (list[len] == 0 || list[len] == '|')) { return ESIF_TRUE; } if ((list = esif_ccb_strchr(list, '|')) != NULL) list++; } return ESIF_FALSE; }
static void esif_ws_http_send_401 (int fd) { char buffer[256]; char tmpbuffer[128]; char *fileType = "text/html"; FILE *file_fp = NULL; int len; struct stat st; int ret; char *fileName = "error.html"; printf("fileName :%s\n", fileName); esif_ccb_fopen(&file_fp, fileName, "r"); if (NULL == file_fp) { printf("failed to open file: \n"); return; } if (esif_ccb_stat(fileName, &st) != 0) { printf("Could not stat file descriptor \n"); return; } len = (long)fseek(file_fp, (off_t)0, SEEK_END); (void)fseek(file_fp, (off_t)0, SEEK_SET); (void)esif_ccb_sprintf(256, buffer, (char*)"HTTP/1.1 401 Unauthorized\n" "Server: server/%d.0\nLast-Modified: %s\nDate: %s\n" "Content-Type: %s\nContent-Length: %ld\nConnection: close\n\n", VERSION, esif_ws_http_time_stamp(st.st_mtime, tmpbuffer), esif_ws_http_time_stamp(time(0), tmpbuffer), fileType, (long)st.st_size); (void)send(fd, buffer, (int)esif_ccb_strlen(buffer), 0); while ((ret = (int)fread(buffer, 1, 256, file_fp)) > 0) (void)send(fd, buffer, ret, 0); fclose(file_fp); }
char *esif_ws_server_get_rest_response(size_t *msgLenPtr) { char *msgPtr = g_rest_out; size_t msgLen = 0; ESIF_TRACE_DEBUG("Message Received: %s \n", msgPtr); if (msgPtr == NULL) { goto exit; } msgLen = esif_ccb_strlen((char *)msgPtr, WS_BUFFER_LENGTH); if (msgLen == 0) { goto exit; } *msgLenPtr = msgLen; exit: return msgPtr; }
static eEsifError ESIF_CALLCONV EsifActWriteLogHandler( const EsifDataPtr message, /* Message For Log */ const eLogType logType /* Log Type e.g. crticial, debug, info,e tc */ ) { eEsifError rc = ESIF_OK; size_t msgLen = 0; if ((NULL == message) || (NULL == message->buf_ptr)) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } msgLen = esif_ccb_strlen(message->buf_ptr, message->buf_len); if (msgLen > 0) { ESIF_TRACE_IFACTIVE(ESIF_TRACE_ID, logType, message->buf_ptr); } exit: return rc; }
static char*esif_ws_http_get_file_type (char *resource) { char *fileType = NULL; char *ext = NULL; int i; ext = strrchr(resource, '.'); if (!ext) { return NULL; } ext++; for (i = 0; g_exts[i].fileExtension != 0; i++) if (!strncmp(ext, g_exts[i].fileExtension, esif_ccb_strlen(ext, MAX_SIZE))) { fileType = g_exts[i].fileType; break; } return fileType; }
/* Data For Interface Marshaling */ static AppDataPtr CreateAppData(esif_string pathBuf) { AppDataPtr app_data_ptr = NULL; char policyPath[ESIF_PATH_LEN] = { 0 }; if (NULL == pathBuf) { ESIF_TRACE_ERROR("Path buffer is NULL\n"); goto exit; } /* Build path(s) for DPTF: "HomeDir" or "HomeDir|[#]PolicyDir" */ esif_build_path(pathBuf, ESIF_PATH_LEN, ESIF_PATHTYPE_DPTF, NULL, NULL); esif_build_path(policyPath, sizeof(policyPath), ESIF_PATHTYPE_DLL, NULL, NULL); if (esif_ccb_strcmp(pathBuf, policyPath) != 0) { char policyDummyPath[ESIF_PATH_LEN] = { 0 }; /* empty if path starts with "#" */ esif_build_path(policyDummyPath, sizeof(policyDummyPath), ESIF_PATHTYPE_DLL, "", NULL); esif_ccb_sprintf_concat(ESIF_PATH_LEN, pathBuf, "|%s%s", (policyDummyPath[0] ? "" : "#"), policyPath); } ESIF_TRACE_DEBUG("pathBuf=%s\n\n", (esif_string)pathBuf); app_data_ptr = (AppDataPtr)esif_ccb_malloc(sizeof(AppData)); if (NULL == app_data_ptr) { ESIF_TRACE_ERROR("Fail to allocate AppData\n"); goto exit; } app_data_ptr->fPathHome.buf_ptr = (void *)pathBuf; app_data_ptr->fPathHome.buf_len = ESIF_PATH_LEN; app_data_ptr->fPathHome.data_len = (UInt32)esif_ccb_strlen(pathBuf, ESIF_PATH_LEN); app_data_ptr->fPathHome.type = ESIF_DATA_STRING; app_data_ptr->fLogLevel = (eLogType) g_traceLevel; exit: return app_data_ptr; }
static int esif_ws_http_server_static_pages ( char *buffer, char *resource, int fd, ssize_t ret, char *fileType ) { struct stat st; char tmpbuffer[128]; char file_to_open[1000]; FILE *file_fp = NULL; #define MAX_SIZE 200 esif_ccb_memcpy(file_to_open, g_server_root, esif_ccb_strlen(g_server_root, MAX_SIZE)); file_to_open[esif_ccb_strlen(g_server_root, MAX_SIZE)] = '\0'; // printf("file to open after esif_ccb_memcpy: %s\n", file_to_open); // printf("resource : %s\n", resource); #ifdef ESIF_ATTR_OS_WINDOWS strcat_s((esif_string)file_to_open, 1000, resource); esif_ccb_fopen(&file_fp, (esif_string)file_to_open, (esif_string)"rb"); #else strcat((esif_string)file_to_open, resource); esif_ccb_fopen(&file_fp, (esif_string)file_to_open, (esif_string)"r"); #endif printf("file to open: %s\n", file_to_open); printf("file type: %s\n", fileType); if (NULL == file_fp) { printf("failed to open file: %s\n", file_to_open); return 404; } if (esif_ccb_stat(file_to_open, &st) != 0) { printf("Could not stat file descriptor \n"); fclose(file_fp); return 404; } (long)fseek(file_fp, (off_t)0, SEEK_END); (void)fseek(file_fp, (off_t)0, SEEK_SET); if (!strcmp(fileType, "text/xml")) { (void)esif_ccb_sprintf(BUFFER_LENGTH, buffer, (char*)"HTTP/1.1 200 OK\n<?xml version==\"1.0\" encoding=\"utf-8\"?>\n" "Server: server/%d.0\n" "Content-Type: %s\nContent-Length: %ld\nConnection: close\n\n", VERSION, fileType, (long)st.st_size); } else { (void)esif_ccb_sprintf(BUFFER_LENGTH, buffer, (char*)"HTTP/1.1 200 OK\n" "Server: server/%d.0\nLast-Modified: %s\nDate: %s\n" "Content-Type: %s\nContent-Length: %ld\nConnection: close\n\n", VERSION, esif_ws_http_time_stamp(st.st_mtime, tmpbuffer), esif_ws_http_time_stamp(time(0), tmpbuffer), fileType, (long)st.st_size); } (void)send(fd, buffer, (int)esif_ccb_strlen(buffer, MAX_SIZE), 0); while ((ret = (int)fread(buffer, 1, BUFFER_LENGTH, file_fp)) > 0) (void)send(fd, buffer, ret, 0); fclose(file_fp); return 0; }
/* ******************************************************************************* ** PUBLIC ******************************************************************************* */ void esif_ws_http_copy_server_root (char *dir) { #define MAX_LENGTH 200 esif_ccb_memcpy(g_server_root, dir, esif_ccb_strlen(dir, MAX_LENGTH)); }
int EsifTraceMessage( esif_tracemask_t module, int level, const char *func, const char *file, int line, const char *msg, ...) { int rc=0; char *appname = ""; char *fmtDetail= "%s%s:[<%s>%s@%s#%d]<%llu ms>: "; char *fmtInfo = "%s%s:[<%s>]<%llu ms>: "; const char *sep=NULL; size_t fmtlen=esif_ccb_strlen(msg, 0x7FFFFFFF); int detailed_message = (level >= DETAILED_TRACELEVEL ? ESIF_TRUE : ESIF_FALSE); va_list args; esif_ccb_time_t msec = 0; enum esif_tracemodule moduleid = ESIF_TRACEMODULE_DEFAULT; const char *module_name = NULL; esif_ccb_system_time(&msec); while (module >>= 1) moduleid++; module_name = EsifTraceModule_ToString(moduleid); level = esif_ccb_min(level, ESIF_TRACELEVEL_MAX); level = esif_ccb_max(level, ESIF_TRACELEVEL_FATAL); if ((sep = strrchr(file, *ESIF_PATH_SEP)) != NULL) file = sep+1; // Do not log function/file/line information for DPTF app interface messages logged from EsifSvcWriteLog if (moduleid == ESIF_TRACEMODULE_DPTF) { detailed_message = ESIF_FALSE; } if (g_traceinfo[level].routes & ESIF_TRACEROUTE_CONSOLE) { if (detailed_message) rc = CMD_CONSOLE(fmtDetail, appname, g_traceinfo[level].label, module_name, func, file, line, msec); else rc = CMD_CONSOLE(fmtInfo, appname, g_traceinfo[level].label, module_name, msec); va_start(args, msg); rc += EsifConsole_WriteConsole(msg, args); va_end(args); if (fmtlen && msg[fmtlen-1]!='\n') CMD_CONSOLE("\n"); } if (g_traceinfo[level].routes & ESIF_TRACEROUTE_LOGFILE && EsifLogFile_IsOpen(ESIF_LOG_TRACE)) { time_t now=0; char timestamp[MAX_CTIME_LEN]={0}; time(&now); esif_ccb_ctime(timestamp, sizeof(timestamp), &now); timestamp[20] = 0; // truncate year if (detailed_message) rc = EsifLogFile_Write(ESIF_LOG_TRACE, fmtDetail, timestamp + 4, g_traceinfo[level].label, module_name, func, file, line, msec); else rc = EsifLogFile_Write(ESIF_LOG_TRACE, fmtInfo, timestamp+4, g_traceinfo[level].label, module_name, msec); va_start(args, msg); rc += EsifLogFile_WriteArgsAppend(ESIF_LOG_TRACE, "\n", msg, args); va_end(args); } #ifdef ESIF_ATTR_OS_WINDOWS if (g_traceinfo[level].routes & (ESIF_TRACEROUTE_DEBUGGER)) { size_t msglen=0; char *buffer=0; int offset=0; va_start(args, msg); msglen = esif_ccb_vscprintf(msg, args) + esif_ccb_strlen(g_traceinfo[level].label, MAX_PATH) + esif_ccb_strlen(appname, MAX_PATH) + esif_ccb_strlen(func, MAX_PATH) + esif_ccb_strlen(file, MAX_PATH) + esif_ccb_strlen(module_name, MAX_PATH) + 22; va_end(args); msglen += (detailed_message ? esif_ccb_strlen(fmtDetail, MAX_PATH) : esif_ccb_strlen(fmtInfo, MAX_PATH)); buffer = (char *)esif_ccb_malloc(msglen); if (NULL != buffer) { if (detailed_message) rc = esif_ccb_sprintf(msglen, buffer, fmtDetail, appname, g_traceinfo[level].label, module_name, func, file, line, msec); else rc = esif_ccb_sprintf(msglen, buffer, fmtInfo, appname, g_traceinfo[level].label, module_name, msec); offset = rc; va_start(args, msg); rc += esif_ccb_vsprintf(msglen-offset, buffer+offset, msg, args); va_end(args); if (rc && buffer[rc-1]!='\n') esif_ccb_strcat(buffer, "\n", msglen); OutputDebugStringA(buffer); esif_ccb_free(buffer); } } if (g_traceinfo[level].routes & (ESIF_TRACEROUTE_EVENTLOG)) { size_t msglen=0; char *buffer=0; char *replaced=0; int offset=0; int backset=0; WORD eventType; appname = ""; fmtInfo = "%sESIF(%s) TYPE: %s MODULE: %s TIME %llu ms\n\n"; fmtDetail= "%sESIF(%s) TYPE: %s MODULE: %s FUNC: %s FILE: %s LINE: %d TIME: %llu ms\n\n"; backset = 0; va_start(args, msg); msglen = esif_ccb_vscprintf(msg,args) + esif_ccb_strlen(g_traceinfo[level].label, MAX_PATH) + esif_ccb_strlen(appname, MAX_PATH) + esif_ccb_strlen(func, MAX_PATH) + esif_ccb_strlen(file, MAX_PATH) + esif_ccb_strlen(module_name, MAX_PATH) + 32; va_end(args); msglen += (detailed_message ? esif_ccb_strlen(fmtDetail, MAX_PATH) : esif_ccb_strlen(fmtInfo, MAX_PATH)); buffer = (char *)esif_ccb_malloc(msglen); if (NULL != buffer) { if (detailed_message) rc = esif_ccb_sprintf(msglen, buffer, fmtDetail, appname, ESIF_UF_VERSION, g_traceinfo[level].label, module_name, func, file, line, msec); else rc = esif_ccb_sprintf(msglen, buffer, fmtInfo, appname, ESIF_UF_VERSION, g_traceinfo[level].label, module_name, msec); if (backset && backset < rc) buffer[rc-backset-1] = 0; offset = rc-backset; va_start(args, msg); rc += esif_ccb_vsprintf(msglen-(offset+backset), buffer+offset+backset, msg, args); va_end(args); if (rc && buffer[rc-1]=='\n') buffer[--rc] = 0; switch (g_traceinfo[level].level) { case ESIF_TRACELEVEL_FATAL: case ESIF_TRACELEVEL_ERROR: eventType = EVENTLOG_ERROR_TYPE; break; case ESIF_TRACELEVEL_WARN: eventType = EVENTLOG_WARNING_TYPE; break; case ESIF_TRACELEVEL_INFO: case ESIF_TRACELEVEL_DEBUG: default: eventType = EVENTLOG_INFORMATION_TYPE; break; } // Escape any "%" in message before writing to EventLog if ((replaced = esif_str_replace(buffer, "%", "%%")) != NULL) { esif_ccb_free(buffer); buffer = replaced; replaced = NULL; } report_event_to_event_log(CATEGORY_GENERAL, eventType, buffer); esif_ccb_free(buffer); } } #endif #ifdef ESIF_ATTR_OS_LINUX if (g_traceinfo[level].routes & (ESIF_TRACEROUTE_EVENTLOG|ESIF_TRACEROUTE_DEBUGGER)) { size_t msglen=0; char *buffer=0; int offset=0; int priority; fmtDetail= "%s:[<%s>%s@%s#%d]<%llu ms>: "; fmtInfo = "%s:[<%s>]<%llu ms>: "; va_start(args, msg); msglen = esif_ccb_vscprintf(msg,args) + esif_ccb_strlen(g_traceinfo[level].label, MAX_PATH) + esif_ccb_strlen(func, MAX_PATH) + esif_ccb_strlen(file, MAX_PATH) + esif_ccb_strlen(module_name, MAX_PATH) + 22; va_end(args); msglen += (detailed_message ? esif_ccb_strlen(fmtDetail, MAX_PATH) : esif_ccb_strlen(fmtInfo, MAX_PATH)); buffer = (char *)esif_ccb_malloc(msglen); if (NULL != buffer) { char *lf; if (detailed_message) rc = esif_ccb_sprintf(msglen, buffer, fmtDetail, g_traceinfo[level].label, module_name, func, file, line, msec); else rc = esif_ccb_sprintf(msglen, buffer, fmtInfo, g_traceinfo[level].label, module_name, msec); offset = rc; va_start(args, msg); rc += esif_ccb_vsprintf(msglen-offset, buffer+offset, msg, args); va_end(args); if (rc && buffer[rc-1]=='\n') buffer[--rc] = 0; while ((lf = esif_ccb_strchr(buffer, '\n')) != NULL) *lf = '\t'; switch (g_traceinfo[level].level) { case ESIF_TRACELEVEL_FATAL: priority = ESIF_PRIORITY_FATAL; break; case ESIF_TRACELEVEL_ERROR: priority = ESIF_PRIORITY_ERROR; break; case ESIF_TRACELEVEL_WARN: priority = ESIF_PRIORITY_WARNING; break; case ESIF_TRACELEVEL_INFO: priority = ESIF_PRIORITY_INFO; break; case ESIF_TRACELEVEL_DEBUG: default: priority = ESIF_PRIORITY_DEBUG; break; } #ifdef ESIF_ATTR_OS_ANDROID __android_log_write(priority, IDENT, buffer); #else openlog(IDENT, OPTION, FACILITY); syslog(priority, "%s", buffer); closelog(); #endif esif_ccb_free(buffer); } } #endif return rc; }
static void esif_ws_cgi_redirect_output ( char *script, int fd ) { int current_out; char buffer[BUFFER_LENGTH]; int ret; FILE *dataFile = NULL; #define MAX_SIZE 100 printf("esif_ws_cgi_redirect_output-> full_script_name: %s\n", script); current_out = esif_ccb_dup(1); if (current_out == -1) { perror("_dup( 1 ) failure"); exit(1); } esif_ccb_fopen(&dataFile, "data", "w"); if (NULL == dataFile) { printf("failed to open file in writing mode \n"); return; } if (-1 == esif_ccb_dup2(dataFile, 1)) { perror("Can't _dup2 stdout"); exit(1); } printf("Execute the script\n"); system(script); fflush(stdout); fclose(dataFile); esif_ccb_dup3(current_out, 1); esif_ccb_flushall(); esif_ccb_fopen(&dataFile, "data", "r"); if (NULL == dataFile) { printf("failed to open file in readig mode: \n"); return; } (long)fseek(dataFile, (off_t)0, SEEK_END); (void)fseek(dataFile, (off_t)0, SEEK_SET); (void)esif_ccb_sprintf(BUFFER_LENGTH, buffer, (char*)"HTTP/1.1 200 OK\n"); (void)send(fd, buffer, (int)esif_ccb_strlen(buffer, MAX_SIZE), 0); while ((ret = (int)fread(buffer, 1, BUFFER_LENGTH, dataFile)) > 0) (void)send(fd, buffer, ret, 0); fclose(dataFile); esif_ws_server_initialize_clients(); esif_ws_http_set_login_requested(1); esif_ws_http_set_authenticated(1); }
static eEsifError EsifDataLogValidateParticipantList(char *inParticipantList) { int i = 0; char *participantList = NULL; char *participantSelect = NULL; char colDelims [] = ","; char *partTok = NULL; UInt8 participantId = 0; int participantCounter = 0; int totalFields = 0; eEsifError rc = ESIF_OK; for (i = 0; i < MAX_PARTICIPANT_ENTRY; i++){ g_dataLogParticipants[i].participantId = 0; g_dataLogParticipants[i].participantNumFields = 0; } if (inParticipantList == NULL) { for (i = 0; i < MAX_PARTICIPANT_ENTRY; i++) { EsifUpPtr upPtr = NULL; participantId = (UInt8) i; upPtr = EsifUpPm_GetAvailableParticipantByInstance(participantId); if (NULL != upPtr) { int j = 0; int fieldCounter = 0; struct esif_fpc_domain *domainPtr = NULL; UInt8 domainCount = (u8)upPtr->fDspPtr->get_domain_count(upPtr->fDspPtr); DataLogParticipant nextParticipant = { 0 }; for (j = 0; j < domainCount; j++) { domainPtr = upPtr->fDspPtr->get_domain(upPtr->fDspPtr, j + 1); if (NULL == domainPtr) { continue; } if (domainPtr->capability_for_domain.capability_flags & ESIF_CAPABILITY_TEMP_STATUS) { fieldCounter += 4; } if (domainPtr->capability_for_domain.capability_flags & ESIF_CAPABILITY_POWER_CONTROL) { fieldCounter += 2; } if (domainPtr->capability_for_domain.capability_flags & ESIF_CAPABILITY_ACTIVE_CONTROL) { fieldCounter += 1; } } nextParticipant.participantId = participantId; nextParticipant.participantNumFields = fieldCounter; g_dataLogParticipants[participantCounter] = nextParticipant; totalFields += fieldCounter; EsifUp_PutRef(upPtr); participantCounter++; } } goto exit; } if (esif_ccb_strlen(inParticipantList, MAX_LOG_LINE) >= 1) { participantList = esif_ccb_strdup(inParticipantList); participantSelect = esif_ccb_strtok(participantList, colDelims, &partTok); while (participantSelect != NULL) { EsifUpPtr upPtr = { 0 }; if (participantCounter >= (sizeof(g_dataLogParticipants)/sizeof(*g_dataLogParticipants))) { rc = ESIF_E_NOT_SUPPORTED; goto exit; } if ((int)esif_atoi(participantSelect) > 0 || esif_ccb_strcmp(participantSelect, "0") == 0) { participantId = (UInt8) esif_atoi(participantSelect); upPtr = EsifUpPm_GetAvailableParticipantByInstance(participantId); } else { upPtr = EsifUpPm_GetAvailableParticipantByName(participantSelect); } if (NULL == upPtr) { rc = ESIF_E_PARTICIPANT_NOT_FOUND; goto exit; } else { int j = 0; int fieldCounter = 0; struct esif_fpc_domain *domainPtr = NULL; UInt8 domainCount = (u8) upPtr->fDspPtr->get_domain_count(upPtr->fDspPtr); DataLogParticipant nextParticipant = { 0 }; participantId = (UInt8) upPtr->fInstance; /* redundant in the case of an id passed in, but needed for name*/ for (j = 0; j < domainCount; j++) { domainPtr = upPtr->fDspPtr->get_domain(upPtr->fDspPtr, j + 1); if (NULL == domainPtr) { continue; } if (domainPtr->capability_for_domain.capability_flags & ESIF_CAPABILITY_TEMP_STATUS) { fieldCounter += 4; } if (domainPtr->capability_for_domain.capability_flags & ESIF_CAPABILITY_POWER_CONTROL) { fieldCounter += 2; } if (domainPtr->capability_for_domain.capability_flags & ESIF_CAPABILITY_ACTIVE_CONTROL) { fieldCounter += 1; } } nextParticipant.participantId = participantId; nextParticipant.participantNumFields = fieldCounter; g_dataLogParticipants[participantCounter] = nextParticipant; totalFields += fieldCounter; EsifUp_PutRef(upPtr); participantCounter++; } participantSelect = esif_ccb_strtok(NULL, colDelims, &partTok); } } else { for (i = 0; i < MAX_PARTICIPANT_ENTRY; i++) { EsifUpPtr upPtr = NULL; participantId = (UInt8) i; upPtr = EsifUpPm_GetAvailableParticipantByInstance(participantId); if (NULL != upPtr) { int j = 0; int fieldCounter = 0; struct esif_fpc_domain *domainPtr = NULL; UInt8 domainCount = (u8)upPtr->fDspPtr->get_domain_count(upPtr->fDspPtr); DataLogParticipant nextParticipant = { 0 }; for (j = 0; j < domainCount; j++) { domainPtr = upPtr->fDspPtr->get_domain(upPtr->fDspPtr, j + 1); if (NULL == domainPtr) { continue; } if (domainPtr->capability_for_domain.capability_flags & ESIF_CAPABILITY_TEMP_STATUS) { fieldCounter += 4; } if (domainPtr->capability_for_domain.capability_flags & ESIF_CAPABILITY_POWER_CONTROL) { fieldCounter += 2; } if (domainPtr->capability_for_domain.capability_flags & ESIF_CAPABILITY_ACTIVE_CONTROL) { fieldCounter += 1; } } nextParticipant.participantId = participantId; nextParticipant.participantNumFields = fieldCounter; g_dataLogParticipants[participantCounter] = nextParticipant; totalFields += fieldCounter; EsifUp_PutRef(upPtr); participantCounter++; } } } exit: esif_ccb_free(participantList); if (totalFields == 0) { rc = ESIF_E_NOT_SUPPORTED; } return rc; }
// Duplicate a ZString into a new Dynamically-Allocated IString IStringPtr IString_Strdup (ZString src) { return IString_StrdupSubstr(src, (u32)esif_ccb_strlen(src, ZSTRING_MAXLEN)); }
// Write a Registry Key Value from an EsifData value static eEsifError DataVault_WriteRegistry ( DataVaultPtr self, esif_string keyname, EsifDataPtr value ) { eEsifError rc = ESIF_E_UNSPECIFIED; HKEY hKey = 0; DWORD dwFlags = RRF_RT_ANY; DWORD dwError = 0; DWORD dwSize = 0; DWORD dwType = REG_NONE; char *regkey = 0; char *valuename = 0; u32 j; UNREFERENCED_PARAMETER(self); // Keyname Format: "HKLM\Subkey\Path\ValueName" for (j = 0; HKeyList[j].name; j++) { size_t namelen = esif_ccb_strlen(HKeyList[j].name, 30); if (esif_ccb_strnicmp(HKeyList[j].name, keyname, namelen) == 0 && keyname[namelen] == '\\') { hKey = HKeyList[j].hkey; keyname += esif_ccb_strlen(HKeyList[j].name, 30) + 1; break; } } if (!hKey) { return rc; } regkey = esif_ccb_strdup(keyname); if ((valuename = strrchr(regkey, '\\')) == 0) { esif_ccb_free(regkey); return rc; } *valuename++ = 0; // Get Data Type from Registry if value already exists, otherwise deduce it from ESIF Data Type if ((dwError = RegGetValueA(hKey, regkey, valuename, dwFlags, &dwType, 0, 0)) != 0) { switch (value->type) { case ESIF_DATA_INT32: case ESIF_DATA_UINT32: case ESIF_DATA_TEMPERATURE: dwType = REG_DWORD; dwSize = value->data_len; break; case ESIF_DATA_INT64: case ESIF_DATA_UINT64: dwType = REG_QWORD; dwSize = value->data_len; break; case ESIF_DATA_STRING: dwType = REG_SZ; dwSize = value->data_len; break; case ESIF_DATA_BINARY: case ESIF_DATA_BLOB: dwType = REG_BINARY; dwSize = value->data_len; break; default: rc = ESIF_E_NOT_SUPPORTED; break; } } // Write Registry Value if (dwType != REG_NONE) { dwError = RegSetKeyValueA(hKey, regkey, valuename, dwType, value->buf_ptr, value->data_len); if (dwError == 0) { rc = ESIF_OK; } } esif_ccb_free(regkey); return rc; }
static int esif_ws_http_process_static_pages ( ClientRecordPtr connection, char *buffer, char *resource, ssize_t ret, char *fileType ) { struct stat st={0}; char tmpbuffer[128]={0}; char file_to_open[MAX_PATH]={0}; char content_disposition[MAX_PATH]={0}; FILE *file_fp = NULL; esif_build_path(file_to_open, sizeof(file_to_open), ESIF_PATHTYPE_UI, resource, NULL); esif_ccb_fopen(&file_fp, (esif_string)file_to_open, (esif_string)"rb"); // Log file workaround: If not found in HTML folder, look in LOG folder if (NULL == file_fp) { char logpath[MAX_PATH]={0}; esif_build_path(logpath, sizeof(logpath), ESIF_PATHTYPE_LOG, resource, NULL); esif_ccb_fopen(&file_fp, (esif_string)logpath, (esif_string)"rb"); if (NULL != file_fp) esif_ccb_strcpy(file_to_open, logpath, sizeof(file_to_open)); } ESIF_TRACE_DEBUG("HTTP: file=%s, type=%s\n", file_to_open, fileType); if (NULL == file_fp) { ESIF_TRACE_DEBUG("failed to open file: %s\n", file_to_open); return 404; } if (esif_ccb_stat(file_to_open, &st) != 0) { ESIF_TRACE_DEBUG("Could not stat file descriptor \n"); fclose(file_fp); return 404; } fseek(file_fp, (off_t)0, SEEK_END); fseek(file_fp, (off_t)0, SEEK_SET); // Add Content-Disposition header to prompt user with Save-As Dialog if unknown file type if (esif_ccb_strcmp(fileType, UNKNOWN_MIME_TYPE) == 0) { esif_ccb_sprintf(sizeof(content_disposition), content_disposition, "Content-Disposition: attachment; filename=\"%s\";\n", resource); } esif_ccb_sprintf(WS_BUFFER_LENGTH, buffer, "HTTP/1.1 200 OK\n" "Server: ESIF_UF/%s\n" "Last-Modified: %s\n" "Date: %s\n" "Content-Type: %s\n" "Content-Length: %ld\n" "%s" "Connection: close\n" "\n", ESIF_UF_VERSION, esif_ws_http_time_stamp(st.st_mtime, tmpbuffer), esif_ws_http_time_stamp(time(0), tmpbuffer), fileType, (long)st.st_size, content_disposition); send(connection->socket, buffer, (int)esif_ccb_strlen(buffer, WS_BUFFER_LENGTH), ESIF_WS_SEND_FLAGS); while ((ret = (int)fread(buffer, 1, WS_BUFFER_LENGTH, file_fp)) > 0) { send(connection->socket, buffer, (int)ret, ESIF_WS_SEND_FLAGS); } fclose(file_fp); return 0; }
void esif_ws_server_execute_rest_cmd( const char *dataPtr, const size_t dataSize ) { char *command_buf = NULL; if (atomic_read(&g_ws_quit)) return; command_buf = strchr(dataPtr, ':'); if (NULL != command_buf) { u32 msg_id = atoi(dataPtr); *command_buf = 0; command_buf++; // Ad-Hoc UI Shell commands begin with "0:", so verify ESIF shell is enabled and command is valid if (msg_id == 0 || g_ws_restricted) { char *response = NULL; if (msg_id == 0 && !g_shell_enabled) { response = "Shell Disabled"; } else { static char *whitelist[] = { "status", "participants", NULL }; static char *blacklist[] = { "shell", "web", "exit", "quit", NULL }; Bool blocked = ESIF_FALSE; int j = 0; if (g_ws_restricted) { for (j = 0; whitelist[j] != NULL; j++) { if (esif_ccb_strnicmp(command_buf, whitelist[j], esif_ccb_strlen(whitelist[j], MAX_PATH)) == 0) { break; } } if (whitelist[j] == NULL) { blocked = ESIF_TRUE; } } else { for (j = 0; blacklist[j] != NULL; j++) { if (esif_ccb_strnicmp(command_buf, blacklist[j], esif_ccb_strlen(blacklist[j], MAX_PATH)) == 0) { blocked = ESIF_TRUE; break; } } } if (blocked) { response = "Unsupported Command"; } } // Exit if shell or command unavailable if (response) { char buffer[MAX_PATH] = { 0 }; esif_ccb_sprintf(sizeof(buffer), buffer, "%d:%s", msg_id, response); esif_ccb_free(g_rest_out); g_rest_out = esif_ccb_strdup(buffer); goto exit; } } // Lock Shell so we can capture output before another thread executes another command #ifdef ESIF_ATTR_SHELL_LOCK esif_ccb_mutex_lock(&g_shellLock); #endif if (!atomic_read(&g_ws_quit)) { EsifString cmd_results = esif_shell_exec_command(command_buf, dataSize, ESIF_TRUE); if (NULL != cmd_results) { size_t out_len = esif_ccb_strlen(cmd_results, OUT_BUF_LEN) + 12; esif_ccb_free(g_rest_out); g_rest_out = (EsifString) esif_ccb_malloc(out_len); if (g_rest_out) { esif_ccb_sprintf(out_len, g_rest_out, "%u:%s", msg_id, cmd_results); } } } #ifdef ESIF_ATTR_SHELL_LOCK esif_ccb_mutex_unlock(&g_shellLock); #endif } exit: return; }
// Automatically Load all Static DataVaults and *.dv files in the current folder into the DataBank eEsifError DataBank_LoadDataVaults (DataBankPtr self) { eEsifError rc = ESIF_OK; esif_ccb_file_find_handle find_handle; esif_string file_path = 0; char file_pattern[MAX_PATH]; char file_path_buf[MAX_PATH] = {0}; struct esif_ccb_file *ffd_ptr; UInt32 idx; ASSERT(self); esif_ccb_lock_init(&self->lock); // TODO: Locking // Import all Static DataVaults into ReadOnly DataVaults for (idx = 0; g_StaticDataVaults[idx].name; idx++) { DataVaultPtr DB = DataBank_OpenNameSpace(self, g_StaticDataVaults[idx].name); if (DB) { IOStream_SetMemory(DB->stream, g_StaticDataVaults[idx].buffer, g_StaticDataVaults[idx].buf_len); DB->flags |= (ESIF_SERVICE_CONFIG_READONLY | ESIF_SERVICE_CONFIG_NOCACHE); DataVault_ReadVault(DB); } } // Create ESIFDV_DIR if it doesn't exit (only 1 level deep for now) esif_ccb_makepath(ESIFDV_DIR); // Import all matching *.dv files into ReadWrite DataVaults esif_ccb_strcpy(file_path_buf, ESIFDV_DIR, sizeof(file_path_buf)); file_path = file_path_buf; esif_ccb_sprintf(MAX_PATH, file_pattern, "*%s", ESIFDV_FILEEXT); ffd_ptr = (struct esif_ccb_file*)esif_ccb_malloc(sizeof(*ffd_ptr)); if (NULL == ffd_ptr) { return ESIF_E_NO_MEMORY; } find_handle = esif_ccb_file_enum_first(file_path, file_pattern, ffd_ptr); if (INVALID_HANDLE_VALUE == find_handle) { rc = ESIF_OK; // No Persisted DataVaults found } else { do { struct esif_ccb_file dv_file = {0}; DataVaultPtr DB = 0; // Read DataVault File, unless it's already been loaded as a Static DataVault if (esif_ccb_strlen(ffd_ptr->filename, MAX_PATH) > sizeof(ESIFDV_FILEEXT)) { ffd_ptr->filename[esif_ccb_strlen(ffd_ptr->filename, MAX_PATH) - (sizeof(ESIFDV_FILEEXT) - 1)] = 0; // Truncate ".dv" extension if (DataBank_GetNameSpace(self, ffd_ptr->filename) == NULL) { DB = DataBank_OpenNameSpace(self, ffd_ptr->filename); if (DB) { esif_ccb_sprintf(MAX_PATH, dv_file.filename, "%s%s%s", file_path, DB->name, ESIFDV_FILEEXT); IOStream_SetFile(DB->stream, dv_file.filename, "rb"); DataVault_ReadVault(DB); } } } } while (esif_ccb_file_enum_next(find_handle, file_pattern, ffd_ptr)); esif_ccb_file_enum_close(find_handle); } esif_ccb_free(ffd_ptr); return rc; }
/* * This function processes requests for clients already opened. */ static eEsifError esif_ws_client_process_active_client( ClientRecordPtr clientPtr, char *bufferPtr, size_t bufferSize, size_t messageLength ) { eEsifError result = ESIF_OK; FrameType frameType; size_t frameSize = 0; char *data = NULL; size_t dataSize = 0; char *restRespPtr = NULL; size_t restRespSize = 0; size_t bytesRemaining = 0; char *bufferRemaining = NULL; char *textStrPtr = NULL; do { /* If more frames remaining, copy them into buffer and reparse */ if (bytesRemaining != 0) { esif_ccb_memcpy(bufferPtr, bufferRemaining, bytesRemaining); messageLength = bytesRemaining; bytesRemaining = 0; } frameType = esif_ws_socket_get_subsequent_frame_type((WsSocketFramePtr)bufferPtr, messageLength, &data, &dataSize, &bytesRemaining); ESIF_TRACE_DEBUG("FrameType: %d\n", frameType); /* Save remaining frames for reparsing if more than one frame received */ if (bytesRemaining > 0) { if (bufferRemaining == NULL) { bufferRemaining = (char *)esif_ccb_malloc(bytesRemaining); if (NULL == bufferRemaining) { result = ESIF_E_NO_MEMORY; goto exit; } } esif_ccb_memcpy(bufferRemaining, data + dataSize, bytesRemaining); } else { esif_ccb_free(bufferRemaining); bufferRemaining = NULL; } /*Now, if the frame type is an incomplete type or if it is an error type of frame */ if ((INCOMPLETE_FRAME == frameType) || (ERROR_FRAME == frameType)) { if (INCOMPLETE_FRAME == frameType) { ESIF_TRACE_DEBUG("Incomplete frame received; closing socket\n"); } else { ESIF_TRACE_DEBUG("Improper format for frame; closing socket\n"); } /* * If the socket is not in its opening state while its frame type is in error or is incomplete * setup to store the payload to send to the client */ esif_ws_socket_build_payload(NULL, 0, (WsSocketFramePtr)bufferPtr, bufferSize, &frameSize, CLOSING_FRAME); esif_ws_client_write_to_socket(clientPtr, bufferPtr, frameSize); /* * Force the socket state into its closing state */ result = ESIF_E_WS_DISC; goto exit; } if (CLOSING_FRAME == frameType) { ESIF_TRACE_DEBUG("Close frame received; closing socket\n"); esif_ws_socket_build_payload(NULL, 0, (WsSocketFramePtr)bufferPtr, bufferSize, &frameSize, CLOSING_FRAME); esif_ws_client_write_to_socket(clientPtr, bufferPtr, frameSize); result = ESIF_E_WS_DISC; goto exit; } if (TEXT_FRAME == frameType) { /* Use a copy of the frame text to send to the rest API */ textStrPtr = (char*)esif_ccb_malloc(dataSize + 1); if (NULL == textStrPtr) { result = ESIF_E_NO_MEMORY; goto exit; } esif_ccb_memcpy(textStrPtr, data, dataSize); textStrPtr[dataSize] = 0; esif_ws_server_execute_rest_cmd((const char*)textStrPtr, esif_ccb_strlen((const char*)textStrPtr, bufferSize)); /* Get message to send*/ restRespPtr = esif_ws_server_get_rest_response(&restRespSize); if (restRespPtr != NULL) { esif_ws_socket_build_payload(restRespPtr, restRespSize, (WsSocketFramePtr)bufferPtr, bufferSize, &frameSize, TEXT_FRAME); if (esif_ws_client_write_to_socket(clientPtr, bufferPtr, frameSize) == EXIT_FAILURE) { result = ESIF_E_WS_DISC; goto exit; } } esif_ccb_free(textStrPtr); textStrPtr = NULL; } /* Handle unsolicited PONG (keepalive) messages from Internet Explorer 10 */ if (PONG_FRAME == frameType) { esif_ws_socket_build_payload("", 0, (WsSocketFramePtr)bufferPtr, bufferSize, &frameSize, TEXT_FRAME); esif_ws_client_write_to_socket(clientPtr, bufferPtr, frameSize); } } while (bytesRemaining != 0); exit: esif_ccb_free(textStrPtr); esif_ccb_free(bufferRemaining); textStrPtr = NULL; bufferRemaining = NULL; return result; }