/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int32 CFE_ES_ShellOutputCommand(char * CmdString, char *Filename) { int32 Result; int32 ReturnCode = CFE_SUCCESS; int32 fd; int32 FileSize; int32 CurrFilePtr; uint32 i; /* the extra 1 added for the \0 char */ char CheckCmd [CFE_ES_CHECKSIZE + 1]; char Cmd [CFE_ES_MAX_SHELL_CMD]; char OutputFilename [OS_MAX_PATH_LEN]; /* Use default filename if not provided */ if (Filename[0] == '\0') { strncpy(OutputFilename, CFE_ES_DEFAULT_SHELL_FILENAME, OS_MAX_PATH_LEN); } else { strncpy(OutputFilename, Filename, OS_MAX_PATH_LEN); } /* Make sure string is null terminated */ OutputFilename[OS_MAX_PATH_LEN - 1] = '\0'; /* Remove previous version of output file */ OS_remove(OutputFilename); fd = OS_creat(OutputFilename, OS_READ_WRITE); if (fd < OS_FS_SUCCESS) { Result = OS_FS_ERROR; } else { strncpy(CheckCmd,CmdString,CFE_ES_CHECKSIZE); CheckCmd[CFE_ES_CHECKSIZE] = '\0'; strncpy(Cmd,CmdString, CFE_ES_MAX_SHELL_CMD); /* We need to check if this command is directed at ES, or at the operating system */ if (strncmp(CheckCmd,"ES_",CFE_ES_CHECKSIZE) == 0) { /* This list can be expanded to include other ES functionality */ if ( strncmp(Cmd,CFE_ES_LIST_APPS_CMD,strlen(CFE_ES_LIST_APPS_CMD) )== 0) { Result = CFE_ES_ListApplications(fd); } else if ( strncmp(Cmd,CFE_ES_LIST_TASKS_CMD,strlen(CFE_ES_LIST_TASKS_CMD) )== 0) { Result = CFE_ES_ListTasks(fd); } else if ( strncmp(Cmd,CFE_ES_LIST_RESOURCES_CMD,strlen(CFE_ES_LIST_RESOURCES_CMD) )== 0) { Result = CFE_ES_ListResources(fd); } /* default if there is not an ES command that matches */ else { Result = CFE_ES_ERR_SHELL_CMD; CFE_ES_WriteToSysLog("There is no ES Shell command that matches %s \n",Cmd); } } /* if the command is not directed at ES, pass it through to the * underlying OS */ else { Result = OS_ShellOutputToFile(Cmd,fd); } /* seek to the end of the file to get it's size */ FileSize = OS_lseek(fd,0,OS_SEEK_END); if (FileSize == OS_FS_ERROR) { OS_close(fd); CFE_ES_WriteToSysLog("OS_lseek call failed from CFE_ES_ShellOutputCmd 1\n"); Result = OS_FS_ERROR; } /* We want to add 3 characters at the end of the telemetry,'\n','$','\0'. * To do this we need to make sure there are at least 3 empty characters at * the end of the last CFE_ES_MAX_SHELL_PKT so we don't over write any data. If * the current file has only 0,1, or 2 free spaces at the end, we want to * make the file longer to start a new tlm packet of size CFE_ES_MAX_SHELL_PKT. * This way we will get a 'blank' packet with the correct 3 characters at the end. */ else { /* if we are within 2 bytes of the end of the packet*/ if ( FileSize % CFE_ES_MAX_SHELL_PKT > (CFE_ES_MAX_SHELL_PKT - 3)) { /* add enough bytes to start a new packet */ for (i = 0; i < CFE_ES_MAX_SHELL_PKT - (FileSize % CFE_ES_MAX_SHELL_PKT) + 1 ; i++) { OS_write(fd," ",1); } } else { /* we are exactly at the end */ if( FileSize % CFE_ES_MAX_SHELL_PKT == 0) { OS_write(fd," ",1); } } /* seek to the end of the file again to get it's new size */ FileSize = OS_lseek(fd,0,OS_SEEK_END); if (FileSize == OS_FS_ERROR) { OS_close(fd); CFE_ES_WriteToSysLog("OS_lseek call failed from CFE_ES_ShellOutputCmd 2\n"); Result = OS_FS_ERROR; } else { /* set the file back to the beginning */ OS_lseek(fd,0,OS_SEEK_SET); /* start processing the chunks. We want to have one packet left so we are sure this for loop * won't run over */ for (CurrFilePtr=0; CurrFilePtr < (FileSize - CFE_ES_MAX_SHELL_PKT); CurrFilePtr += CFE_ES_MAX_SHELL_PKT) { OS_read(fd, CFE_ES_TaskData.ShellPacket.ShellOutput, CFE_ES_MAX_SHELL_PKT); /* Send the packet */ CFE_SB_TimeStampMsg((CFE_SB_Msg_t *) &CFE_ES_TaskData.ShellPacket); CFE_SB_SendMsg((CFE_SB_Msg_t *) &CFE_ES_TaskData.ShellPacket); /* delay to not flood the pipe on large messages */ OS_TaskDelay(200); } /* finish off the last portion of the file */ /* over write the last packet with spaces, then it will get filled * in with the correct info below. This assures that the last non full * part of the packet will be spaces */ for (i =0; i < CFE_ES_MAX_SHELL_PKT; i++) { CFE_ES_TaskData.ShellPacket.ShellOutput[i] = ' '; } OS_read(fd, CFE_ES_TaskData.ShellPacket.ShellOutput, ( FileSize - CurrFilePtr)); /* From our check above, we are assured that there are at least 3 free * characters to write our data into at the end of this last packet * * The \n assures we are on a new line, the $ gives us our prompt, and the * \0 assures we are null terminalted. */ CFE_ES_TaskData.ShellPacket.ShellOutput[ CFE_ES_MAX_SHELL_PKT - 3] = '\n'; CFE_ES_TaskData.ShellPacket.ShellOutput[ CFE_ES_MAX_SHELL_PKT - 2] = '$'; CFE_ES_TaskData.ShellPacket.ShellOutput[ CFE_ES_MAX_SHELL_PKT - 1] = '\0'; /* Send the last packet */ CFE_SB_TimeStampMsg((CFE_SB_Msg_t *) &CFE_ES_TaskData.ShellPacket); CFE_SB_SendMsg((CFE_SB_Msg_t *) &CFE_ES_TaskData.ShellPacket); /* Close the file descriptor */ OS_close(fd); } /* if FilseSize == OS_FS_ERROR */ } /* if FileSeize == OS_FS_ERROR */ }/* if fd < OS_FS_SUCCESS */ if (Result != OS_SUCCESS && Result != CFE_SUCCESS ) { ReturnCode = CFE_ES_ERR_SHELL_CMD; CFE_ES_WriteToSysLog("OS_ShellOutputToFile call failed from CFE_ES_ShellOutputCommand\n"); } else { ReturnCode = CFE_SUCCESS; } return ReturnCode; }
/* -------------------------------------------------------------------------------------- Name: OS_ShellOutputToFile Purpose: Takes a shell command in and writes the output of that command to the specified file Returns: OS_FS_ERROR if the command was not executed properly OS_FS_ERR_INVALID_FD if the file descriptor passed in is invalid OS_SUCCESS if success ---------------------------------------------------------------------------------------*/ int32 OS_ShellOutputToFile(char* Cmd, int32 OS_fd) { int32 cmdFd; int32 tmpFd; rtems_status_code rtemsRc;; int32 ReturnCode = OS_SUCCESS; int32 fileStatus; int32 bytesRead; int32 bytesWritten; char readBuffer[256]; char outputFileName[OS_MAX_PATH_LEN + OS_SHELL_TMP_FILE_EXT_LEN]; char localCmd[OS_MAX_CMD_LEN]; /* Make sure the file descriptor is legit before using it */ if (OS_fd < 0 || OS_fd >= OS_MAX_NUM_OPEN_FILES || OS_FDTable[OS_fd].IsValid == FALSE) { ReturnCode = OS_FS_ERR_INVALID_FD; } else { /* ** Create a file to write the command to (or write over the old one) */ cmdFd = OS_creat(OS_SHELL_CMD_INPUT_FILE_NAME,OS_READ_WRITE); if (cmdFd < OS_FS_SUCCESS) { ReturnCode = OS_FS_ERROR; } else { /* ** Write the command to the buffer */ strncpy(localCmd,Cmd,OS_MAX_CMD_LEN); strncat(localCmd,"\n",1); /* ** This function passes in an open file descriptor to write the shell ** command output. The RTEMS shell script API expects a filename, not ** a file descriptor. So in addition to the temporary file for the shell input, ** we need to create a temporary file for the command output, then it has ** to be copied to the open file. */ strncpy(outputFileName,OS_SHELL_CMD_INPUT_FILE_NAME,OS_MAX_PATH_LEN); strncat(outputFileName,OS_SHELL_TMP_FILE_EXT,OS_SHELL_TMP_FILE_EXT_LEN); /* ** copy the shell command buffer to the file */ fileStatus = OS_write(cmdFd, localCmd, strlen(localCmd)); if ( fileStatus == strlen(localCmd) ) { /* ** Close the file */ OS_close(cmdFd); /* ** Spawn a task to execute the shell command */ rtemsRc = rtems_shell_script ( "RSHL", OS_SHELL_CMD_TASK_STACK_SIZE, OS_SHELL_CMD_TASK_PRIORITY, OS_SHELL_CMD_INPUT_FILE_NAME, outputFileName, FALSE, /* Do not append output to file */ TRUE, /* Wait for shell task to complete */ FALSE /* Echo output */ ); /* ** Now we have the temporary file with the output */ if((tmpFd = OS_open(outputFileName, OS_READ_ONLY,0)) == OS_FS_ERROR) { printf("OSAL:Could not open %s for reading\n",outputFileName); ReturnCode = OS_FS_ERROR; } else { while((bytesRead = OS_read(tmpFd, readBuffer, 256)) > 0) { bytesWritten = OS_write(OS_fd, readBuffer, bytesRead); } OS_close(tmpFd); /* ** Remove the temporary output file */ fileStatus = OS_remove(outputFileName); } } else { ReturnCode = OS_FS_ERROR; } } /* ** Remove the temporary shell input file */ fileStatus = OS_remove(OS_SHELL_CMD_INPUT_FILE_NAME); } return ReturnCode; }/* end OS_ShellOutputToFile */
/****************************************************************************** ** ** ParseXmlFile ** ** Parse an XML file */ static boolean ParseXmlFile(const char* FilePathName, XML_StartElementHandler StartElementHandler, XML_EndElementHandler EndElementHandler) { int FileHandle; int32 ReadStatus; boolean Done; boolean ParseErr = FALSE; boolean RetStatus = FALSE; XML_Parser XmlParser = XML_ParserCreate(NULL); if (! XmlParser) { CFE_EVS_SendEvent(TBLMGR_CREATE_ERR_EID, CFE_EVS_ERROR, "Failed to allocate memory for XML parser"); } else { XML_SetElementHandler(XmlParser, StartElementHandler, EndElementHandler); FileHandle = OS_open(FilePathName, OS_READ_ONLY, 0); if (FileHandle >= 0) { Done = FALSE; while (!Done) { ReadStatus = OS_read(FileHandle, TblFileBuff, TBLMGR_BUFFSIZE); if ( ReadStatus == OS_FS_ERROR ) { CFE_EVS_SendEvent(TBLMGR_FILE_READ_ERR_EID, CFE_EVS_ERROR, "File read error, EC = 0x%08X",ReadStatus); Done = TRUE; ParseErr = TRUE; } else if ( ReadStatus == 0 ) /* EOF reached */ { Done = TRUE; } else { /* ReadStatus contains number of bytes read */ if (XML_Parse(XmlParser, TblFileBuff, ReadStatus, Done) == XML_STATUS_ERROR) { CFE_EVS_SendEvent(TBLMGR_PARSE_ERR_EID, CFE_EVS_ERROR, "Parse error at line %l, error code = %s", XML_GetCurrentLineNumber(XmlParser), XML_ErrorString(XML_GetErrorCode(XmlParser))); Done = TRUE; ParseErr = TRUE; } /* End if valid parse */ } /* End if valid fread */ } /* End file read loop */ RetStatus = !ParseErr; OS_close(FileHandle); } /* End if file opened */ else { CFE_EVS_SendEvent(TBLMGR_FILE_OPEN_ERR_EID, CFE_EVS_ERROR, "File open error for %s, Error = %d", FilePathName, FileHandle ); } XML_ParserFree(XmlParser); } /* end if parser allocated */ return RetStatus; } /* End ParseXmlFile() */