/*! A helper function that actually writes to stdout. This function is called by QxtBasicSTDLoggerEngine. Reimplement this function when creating a subclass of QxtBasicSTDLoggerEngine. */ void QxtBasicSTDLoggerEngine::writeToStdOut(const QString& level, const QList<QVariant> &msgs) { /* Message format... [time] [error level] First message..... second message third message */ if (msgs.isEmpty()) return; QString header = '[' + QTime::currentTime().toString("hh:mm:ss.zzz") + "] [" + level + "] "; QString padding; QTextStream* outstream = stdOutStream(); Q_ASSERT(outstream); *outstream << header; for (int i = 0; i < header.size(); i++) padding.append(' '); int count = 0; Q_FOREACH(const QVariant& out, msgs) { if (!out.isNull()) { if (count != 0) *outstream << padding; *outstream << out.toString() << '\n'; } count++; } *outstream << endl; }
void TskCarveExtractScalpel::carveFile(const std::string &unallocImgPath, const std::string &outputFolderPath, const std::string &stdOutFilePath, const std::string &stdErrFilePath) const { try { // Find out where Scalpel is installed. std::string scalpelDirPath = GetSystemProperty("SCALPEL_DIR"); if (scalpelDirPath.empty()) { throw TskException("TskCarveExtractScalpel::configure : Scalpel directory not set"); } if (!Poco::File(scalpelDirPath).exists()) { std::stringstream msg; msg << "TskCarveExtractScalpel::configure : specified Scalpel directory '" << scalpelDirPath << "' does not exist"; throw TskException(msg.str()); } // Get the path to the Scalpel executable. std::stringstream pathBuilder; pathBuilder << scalpelDirPath << Poco::Path::separator() << SCALPEL_EXE_FILE_NAME; std::string scalpelExePath = pathBuilder.str(); if (!Poco::File(scalpelExePath).exists()) { std::stringstream msg; msg << "TskCarveExtractScalpel::configure : Scalpel executable '" << scalpelExePath << "' does not exist"; throw TskException(msg.str()); } // Get the path to the Scalpel config file. std::string scalpelConfigFilePath = GetSystemProperty("SCALPEL_CONFIG_FILE"); if (!Poco::File(scalpelConfigFilePath).exists()) { std::stringstream msg; msg << "TskCarveExtractScalpel::TskCarveExtractScalpel : Scalpel config file '" << scalpelConfigFilePath << "' does not exist"; throw TskException(msg.str()); } // Set the Scalpel command line: specify the Scalpel config file. Poco::Process::Args args; args.push_back("-c"); args.push_back(scalpelConfigFilePath); // Set the Scalpel command line: allow for nested headers and footers. args.push_back("-e"); // Set the Scalpel command line: put any carved files directly into the output folder. args.push_back("-o"); args.push_back(outputFolderPath); args.push_back("-O"); // Set the Scalpel command line: specify the file to carve. args.push_back(unallocImgPath); // Launch Scalpel with console output redirects. Poco::Pipe outPipe; Poco::Pipe errPipe; Poco::ProcessHandle handle = Poco::Process::launch(scalpelExePath, args, NULL, &outPipe, &errPipe); // Capture the console output. Note that Scalpel may block at times as it waits for this loop to empty the stream buffers. Poco::PipeInputStream stdOutInputStream(outPipe); Poco::FileOutputStream stdOutOutputStream(stdOutFilePath); Poco::PipeInputStream stdErrInputStream(errPipe); Poco::FileOutputStream stdErrOutputStream(stdErrFilePath); while (stdOutInputStream || stdErrInputStream) { if (stdOutInputStream) { Poco::StreamCopier::copyStream(stdOutInputStream, stdOutOutputStream); } if (stdErrInputStream) { Poco::StreamCopier::copyStream(stdErrInputStream, stdErrOutputStream); } } // Scalpel should be finished since the console output streams are closed. int exitCode = Poco::Process::wait(handle); stdOutOutputStream.flush(); stdErrOutputStream.flush(); // On the first invocation of Scalpel, record its use in the image database. static bool toolInfoRecorded = false; if (!toolInfoRecorded) { std::ifstream stdOutStream(stdOutFilePath.c_str()); if (stdOutStream) { std::string versionString; std::getline(stdOutStream, versionString); Poco::StringTokenizer tokenizer(versionString, "\t ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); if (tokenizer[0] == "Scalpel" && tokenizer[1] == "version") { TskServices::Instance().getImgDB().addToolInfo("Scalpel", tokenizer[2].c_str()); toolInfoRecorded = true; } else { LOGWARN("TskCarveExtractScalpel::carveFile : Scalpel stdout output format changed, cannot record tool info"); } } else { LOGWARN("TskCarveExtractScalpel::carveFile : failed to open stdout stream, cannot record tool info"); } } // Delete input files by default. std::string option = GetSystemProperty("CARVE_EXTRACT_KEEP_INPUT_FILES"); std::transform(option.begin(), option.end(), option.begin(), ::toupper); bool deleteInputFiles = (option != "TRUE"); if (deleteInputFiles) { Poco::File file(unallocImgPath); file.remove(); } if (exitCode != 0) { std::stringstream msg; msg << "TskCarveExtractScalpel::carveFile : Scalpel exited with error exit code " << exitCode << " when carving '" << unallocImgPath.c_str() << "'"; throw TskException(msg.str()); } } catch (Poco::Exception &ex) { std::stringstream msg; msg << "TskCarveExtractScalpel::carveFile : Poco exception: " << ex.displayText(); throw TskException(msg.str()); } }