blob: d600cf48690365f01209fddbd0f981c123703308 [file] [log] [blame]
Gunnar Millsa927de42017-04-06 21:40:50 -05001#include <iostream>
2#include <string>
3#include <unistd.h>
4#include <sys/wait.h>
5#include <phosphor-logging/log.hpp>
Gunnar Mills3a482f62017-04-20 16:07:20 -05006#include <experimental/filesystem>
Gunnar Mills49739432017-04-21 11:03:34 -05007#include <algorithm>
Gunnar Millsa927de42017-04-06 21:40:50 -05008#include "config.h"
Gunnar Millsa733df52017-04-11 13:05:52 -05009#include <phosphor-logging/elog.hpp>
10#include <phosphor-logging/elog-errors.hpp>
11#include "xyz/openbmc_project/Common/error.hpp"
Gunnar Mills701e0212017-04-03 11:21:27 -050012#include "download_manager.hpp"
13
14namespace phosphor
15{
16namespace software
17{
18namespace manager
19{
20
Gunnar Millsa733df52017-04-11 13:05:52 -050021using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Gunnar Millsa927de42017-04-06 21:40:50 -050022using namespace phosphor::logging;
Gunnar Mills3a482f62017-04-20 16:07:20 -050023namespace fs = std::experimental::filesystem;
Gunnar Millsa927de42017-04-06 21:40:50 -050024
Gunnar Mills49739432017-04-21 11:03:34 -050025void Download::downloadViaTFTP(std::string fileName,
26 std::string serverAddress)
Gunnar Mills701e0212017-04-03 11:21:27 -050027{
Gunnar Mills49739432017-04-21 11:03:34 -050028
29 // Sanitize the fileName string
30 fileName.erase(std::remove(fileName.begin(), fileName.end(), '/'),
31 fileName.end());
32 fileName = fileName.substr(fileName.find_first_not_of('.'));
33
Gunnar Millsa927de42017-04-06 21:40:50 -050034 if (fileName.empty())
35 {
36 log<level::ERR>("Error FileName is empty");
Gunnar Millsa733df52017-04-11 13:05:52 -050037 elog<InvalidArgument>(xyz::openbmc_project::Common::InvalidArgument::
38 ARGUMENT_NAME("FileName"),
39 xyz::openbmc_project::Common::InvalidArgument::
40 ARGUMENT_VALUE(fileName.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050041 return;
42 }
43
44 if (serverAddress.empty())
45 {
46 log<level::ERR>("Error ServerAddress is empty");
Gunnar Millsa733df52017-04-11 13:05:52 -050047 elog<InvalidArgument>(xyz::openbmc_project::Common::InvalidArgument::
48 ARGUMENT_NAME("ServerAddress"),
49 xyz::openbmc_project::Common::InvalidArgument::
50 ARGUMENT_VALUE(serverAddress.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050051 return;
52 }
53
54 log<level::INFO>("Downloading via TFTP",
55 entry("FILENAME=%s", fileName),
56 entry("SERVERADDRESS=%s", serverAddress));
57
Gunnar Mills3a482f62017-04-20 16:07:20 -050058 // Check if IMAGE DIR exists and create if necessary.
59 fs::path imgDirPath(IMG_UPLOAD_DIR);
60 if (!fs::is_directory(imgDirPath))
61 {
62 fs::create_directory(imgDirPath);
63 }
64
Gunnar Millsa927de42017-04-06 21:40:50 -050065 pid_t pid = fork();
66
67 if (pid == 0)
68 {
69 // child process
70 execl("/usr/bin/tftp", "tftp", "-g", "-r", fileName.c_str(),
71 serverAddress.c_str(), "-l", (std::string{IMG_UPLOAD_DIR} + '/' +
72 fileName).c_str(), (char*)0);
73 // execl only returns on fail
74 log<level::ERR>("Error occurred during the TFTP call");
Gunnar Millsa733df52017-04-11 13:05:52 -050075 elog<InternalFailure>();
Gunnar Millsa927de42017-04-06 21:40:50 -050076 }
77 else if (pid < 0)
78 {
79 log<level::ERR>("Error occurred during fork");
Gunnar Millsa733df52017-04-11 13:05:52 -050080 elog<InternalFailure>();
Gunnar Millsa927de42017-04-06 21:40:50 -050081 }
82
Gunnar Mills701e0212017-04-03 11:21:27 -050083 return;
84}
85
86} // namespace manager
87} // namespace software
88} // namespace phosphor
89