blob: 6bbe6042fbdbd3f5d5326cdb3cd6cf6972a0fd44 [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
Adriana Kobylak2285fe02018-02-27 15:36:59 -060025void Download::downloadViaTFTP(std::string fileName, std::string serverAddress)
Gunnar Mills701e0212017-04-03 11:21:27 -050026{
Gunnar Millsc7e2d242017-08-31 14:50:17 -050027 using Argument = xyz::openbmc_project::Common::InvalidArgument;
Gunnar Mills49739432017-04-21 11:03:34 -050028
29 // Sanitize the fileName string
Brad Bishop8a24dda2017-08-31 11:25:20 -040030 if (!fileName.empty())
31 {
32 fileName.erase(std::remove(fileName.begin(), fileName.end(), '/'),
33 fileName.end());
34 fileName = fileName.substr(fileName.find_first_not_of('.'));
35 }
Gunnar Mills49739432017-04-21 11:03:34 -050036
Gunnar Millsa927de42017-04-06 21:40:50 -050037 if (fileName.empty())
38 {
39 log<level::ERR>("Error FileName is empty");
Gunnar Millsc7e2d242017-08-31 14:50:17 -050040 elog<InvalidArgument>(Argument::ARGUMENT_NAME("FileName"),
41 Argument::ARGUMENT_VALUE(fileName.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050042 return;
43 }
44
45 if (serverAddress.empty())
46 {
47 log<level::ERR>("Error ServerAddress is empty");
Gunnar Millsc7e2d242017-08-31 14:50:17 -050048 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ServerAddress"),
49 Argument::ARGUMENT_VALUE(serverAddress.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050050 return;
51 }
52
53 log<level::INFO>("Downloading via TFTP",
Adriana Kobylak596466b2018-02-13 14:48:53 -060054 entry("FILENAME=%s", fileName.c_str()),
55 entry("SERVERADDRESS=%s", serverAddress.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050056
Gunnar Mills7e1abfc2017-11-09 15:43:50 -060057 // Check if IMAGE DIR exists
Gunnar Mills3a482f62017-04-20 16:07:20 -050058 fs::path imgDirPath(IMG_UPLOAD_DIR);
59 if (!fs::is_directory(imgDirPath))
60 {
Gunnar Mills7e1abfc2017-11-09 15:43:50 -060061 log<level::ERR>("Error Image Dir does not exist");
62 elog<InternalFailure>();
63 return;
Gunnar Mills3a482f62017-04-20 16:07:20 -050064 }
65
Gunnar Millsa927de42017-04-06 21:40:50 -050066 pid_t pid = fork();
67
68 if (pid == 0)
69 {
Vernon Maueryb891eb32018-05-10 16:06:23 -070070 pid_t nextPid = fork();
71 if (nextPid == 0)
72 {
73 // child process
74 execl("/usr/bin/tftp", "tftp", "-g", "-r", fileName.c_str(),
75 serverAddress.c_str(), "-l",
76 (std::string{IMG_UPLOAD_DIR} + '/' + fileName).c_str(),
77 (char*)0);
78 // execl only returns on fail
79 log<level::ERR>("Error occurred during the TFTP call");
80 elog<InternalFailure>();
81 }
82 else if (nextPid < 0)
83 {
84 log<level::ERR>("Error occurred during fork");
85 elog<InternalFailure>();
86 }
87 // do nothing as parent if all is going well
88 // when parent exits, child will be reparented under init
89 // and then be reaped properly
90 exit(0);
Gunnar Millsa927de42017-04-06 21:40:50 -050091 }
92 else if (pid < 0)
93 {
94 log<level::ERR>("Error occurred during fork");
Gunnar Millsa733df52017-04-11 13:05:52 -050095 elog<InternalFailure>();
Gunnar Millsa927de42017-04-06 21:40:50 -050096 }
Vernon Maueryb891eb32018-05-10 16:06:23 -070097 else
98 {
99 int status;
100 if (waitpid(pid, &status, 0) < 0)
101 {
102 log<level::ERR>("waitpid error");
103 }
104 else if (WEXITSTATUS(status) != 0)
105 {
106 log<level::ERR>("failed to launch tftp");
107 }
108 }
Gunnar Millsa927de42017-04-06 21:40:50 -0500109
Gunnar Mills701e0212017-04-03 11:21:27 -0500110 return;
111}
112
113} // namespace manager
114} // namespace software
115} // namespace phosphor