blob: a3811dd8b5f720f0f53da5feaea1c22399337850 [file] [log] [blame]
Gunnar Millsa927de42017-04-06 21:40:50 -05001#include "config.h"
Gunnar Millsb0ce9962018-09-07 13:39:10 -05002
Gunnar Mills701e0212017-04-03 11:21:27 -05003#include "download_manager.hpp"
4
Gunnar Millsb0ce9962018-09-07 13:39:10 -05005#include "xyz/openbmc_project/Common/error.hpp"
6
7#include <sys/wait.h>
8#include <unistd.h>
9
10#include <algorithm>
Adriana Kobylakc98d9122020-05-05 10:36:01 -050011#include <filesystem>
Gunnar Millsb0ce9962018-09-07 13:39:10 -050012#include <iostream>
13#include <phosphor-logging/elog-errors.hpp>
14#include <phosphor-logging/elog.hpp>
15#include <phosphor-logging/log.hpp>
16#include <string>
17
Gunnar Mills701e0212017-04-03 11:21:27 -050018namespace phosphor
19{
20namespace software
21{
22namespace manager
23{
24
Gunnar Millsa733df52017-04-11 13:05:52 -050025using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Gunnar Millsa927de42017-04-06 21:40:50 -050026using namespace phosphor::logging;
Adriana Kobylakc98d9122020-05-05 10:36:01 -050027namespace fs = std::filesystem;
Gunnar Millsa927de42017-04-06 21:40:50 -050028
Adriana Kobylak2285fe02018-02-27 15:36:59 -060029void Download::downloadViaTFTP(std::string fileName, std::string serverAddress)
Gunnar Mills701e0212017-04-03 11:21:27 -050030{
Gunnar Millsc7e2d242017-08-31 14:50:17 -050031 using Argument = xyz::openbmc_project::Common::InvalidArgument;
Gunnar Mills49739432017-04-21 11:03:34 -050032
33 // Sanitize the fileName string
Brad Bishop8a24dda2017-08-31 11:25:20 -040034 if (!fileName.empty())
35 {
36 fileName.erase(std::remove(fileName.begin(), fileName.end(), '/'),
37 fileName.end());
38 fileName = fileName.substr(fileName.find_first_not_of('.'));
39 }
Gunnar Mills49739432017-04-21 11:03:34 -050040
Gunnar Millsa927de42017-04-06 21:40:50 -050041 if (fileName.empty())
42 {
43 log<level::ERR>("Error FileName is empty");
Gunnar Millsc7e2d242017-08-31 14:50:17 -050044 elog<InvalidArgument>(Argument::ARGUMENT_NAME("FileName"),
45 Argument::ARGUMENT_VALUE(fileName.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050046 return;
47 }
48
49 if (serverAddress.empty())
50 {
51 log<level::ERR>("Error ServerAddress is empty");
Gunnar Millsc7e2d242017-08-31 14:50:17 -050052 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ServerAddress"),
53 Argument::ARGUMENT_VALUE(serverAddress.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050054 return;
55 }
56
57 log<level::INFO>("Downloading via TFTP",
Adriana Kobylak596466b2018-02-13 14:48:53 -060058 entry("FILENAME=%s", fileName.c_str()),
59 entry("SERVERADDRESS=%s", serverAddress.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050060
Gunnar Mills7e1abfc2017-11-09 15:43:50 -060061 // Check if IMAGE DIR exists
Gunnar Mills3a482f62017-04-20 16:07:20 -050062 fs::path imgDirPath(IMG_UPLOAD_DIR);
63 if (!fs::is_directory(imgDirPath))
64 {
Gunnar Mills7e1abfc2017-11-09 15:43:50 -060065 log<level::ERR>("Error Image Dir does not exist");
66 elog<InternalFailure>();
67 return;
Gunnar Mills3a482f62017-04-20 16:07:20 -050068 }
69
Gunnar Millsa927de42017-04-06 21:40:50 -050070 pid_t pid = fork();
71
72 if (pid == 0)
73 {
Vernon Maueryb891eb32018-05-10 16:06:23 -070074 pid_t nextPid = fork();
75 if (nextPid == 0)
76 {
77 // child process
78 execl("/usr/bin/tftp", "tftp", "-g", "-r", fileName.c_str(),
79 serverAddress.c_str(), "-l",
80 (std::string{IMG_UPLOAD_DIR} + '/' + fileName).c_str(),
81 (char*)0);
82 // execl only returns on fail
83 log<level::ERR>("Error occurred during the TFTP call");
84 elog<InternalFailure>();
85 }
86 else if (nextPid < 0)
87 {
88 log<level::ERR>("Error occurred during fork");
89 elog<InternalFailure>();
90 }
91 // do nothing as parent if all is going well
92 // when parent exits, child will be reparented under init
93 // and then be reaped properly
94 exit(0);
Gunnar Millsa927de42017-04-06 21:40:50 -050095 }
96 else if (pid < 0)
97 {
98 log<level::ERR>("Error occurred during fork");
Gunnar Millsa733df52017-04-11 13:05:52 -050099 elog<InternalFailure>();
Gunnar Millsa927de42017-04-06 21:40:50 -0500100 }
Vernon Maueryb891eb32018-05-10 16:06:23 -0700101 else
102 {
103 int status;
104 if (waitpid(pid, &status, 0) < 0)
105 {
106 log<level::ERR>("waitpid error");
107 }
108 else if (WEXITSTATUS(status) != 0)
109 {
110 log<level::ERR>("failed to launch tftp");
111 }
112 }
Gunnar Millsa927de42017-04-06 21:40:50 -0500113
Gunnar Mills701e0212017-04-03 11:21:27 -0500114 return;
115}
116
117} // namespace manager
118} // namespace software
119} // namespace phosphor