#include "config.h" #include "download_manager.hpp" #include "xyz/openbmc_project/Common/error.hpp" #include #include #include #include #include #include #include #include #include namespace phosphor { namespace software { namespace manager { using namespace sdbusplus::xyz::openbmc_project::Common::Error; using namespace phosphor::logging; namespace fs = std::experimental::filesystem; void Download::downloadViaTFTP(std::string fileName, std::string serverAddress) { using Argument = xyz::openbmc_project::Common::InvalidArgument; // Sanitize the fileName string if (!fileName.empty()) { fileName.erase(std::remove(fileName.begin(), fileName.end(), '/'), fileName.end()); fileName = fileName.substr(fileName.find_first_not_of('.')); } if (fileName.empty()) { log("Error FileName is empty"); elog(Argument::ARGUMENT_NAME("FileName"), Argument::ARGUMENT_VALUE(fileName.c_str())); return; } if (serverAddress.empty()) { log("Error ServerAddress is empty"); elog(Argument::ARGUMENT_NAME("ServerAddress"), Argument::ARGUMENT_VALUE(serverAddress.c_str())); return; } log("Downloading via TFTP", entry("FILENAME=%s", fileName.c_str()), entry("SERVERADDRESS=%s", serverAddress.c_str())); // Check if IMAGE DIR exists fs::path imgDirPath(IMG_UPLOAD_DIR); if (!fs::is_directory(imgDirPath)) { log("Error Image Dir does not exist"); elog(); return; } pid_t pid = fork(); if (pid == 0) { pid_t nextPid = fork(); if (nextPid == 0) { // child process execl("/usr/bin/tftp", "tftp", "-g", "-r", fileName.c_str(), serverAddress.c_str(), "-l", (std::string{IMG_UPLOAD_DIR} + '/' + fileName).c_str(), (char*)0); // execl only returns on fail log("Error occurred during the TFTP call"); elog(); } else if (nextPid < 0) { log("Error occurred during fork"); elog(); } // do nothing as parent if all is going well // when parent exits, child will be reparented under init // and then be reaped properly exit(0); } else if (pid < 0) { log("Error occurred during fork"); elog(); } else { int status; if (waitpid(pid, &status, 0) < 0) { log("waitpid error"); } else if (WEXITSTATUS(status) != 0) { log("failed to launch tftp"); } } return; } } // namespace manager } // namespace software } // namespace phosphor