blob: 06f4c7860caa7f611203c27316a4d8dba7a8f320 [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
Gunnar Millsb0ce9962018-09-07 13:39:10 -050010#include <phosphor-logging/elog-errors.hpp>
11#include <phosphor-logging/elog.hpp>
12#include <phosphor-logging/log.hpp>
Adriana Kobylak58aa7502020-06-08 11:12:11 -050013
14#include <algorithm>
15#include <filesystem>
16#include <iostream>
Gunnar Millsb0ce9962018-09-07 13:39:10 -050017#include <string>
18
Gunnar Mills701e0212017-04-03 11:21:27 -050019namespace phosphor
20{
21namespace software
22{
23namespace manager
24{
25
Gunnar Millsa733df52017-04-11 13:05:52 -050026using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Gunnar Millsa927de42017-04-06 21:40:50 -050027using namespace phosphor::logging;
Adriana Kobylakc98d9122020-05-05 10:36:01 -050028namespace fs = std::filesystem;
Gunnar Millsa927de42017-04-06 21:40:50 -050029
Adriana Kobylak2285fe02018-02-27 15:36:59 -060030void Download::downloadViaTFTP(std::string fileName, std::string serverAddress)
Gunnar Mills701e0212017-04-03 11:21:27 -050031{
Gunnar Millsc7e2d242017-08-31 14:50:17 -050032 using Argument = xyz::openbmc_project::Common::InvalidArgument;
Gunnar Mills49739432017-04-21 11:03:34 -050033
34 // Sanitize the fileName string
Brad Bishop8a24dda2017-08-31 11:25:20 -040035 if (!fileName.empty())
36 {
37 fileName.erase(std::remove(fileName.begin(), fileName.end(), '/'),
38 fileName.end());
39 fileName = fileName.substr(fileName.find_first_not_of('.'));
40 }
Gunnar Mills49739432017-04-21 11:03:34 -050041
Gunnar Millsa927de42017-04-06 21:40:50 -050042 if (fileName.empty())
43 {
44 log<level::ERR>("Error FileName is empty");
Gunnar Millsc7e2d242017-08-31 14:50:17 -050045 elog<InvalidArgument>(Argument::ARGUMENT_NAME("FileName"),
46 Argument::ARGUMENT_VALUE(fileName.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050047 return;
48 }
49
50 if (serverAddress.empty())
51 {
52 log<level::ERR>("Error ServerAddress is empty");
Gunnar Millsc7e2d242017-08-31 14:50:17 -050053 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ServerAddress"),
54 Argument::ARGUMENT_VALUE(serverAddress.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050055 return;
56 }
57
58 log<level::INFO>("Downloading via TFTP",
Adriana Kobylak596466b2018-02-13 14:48:53 -060059 entry("FILENAME=%s", fileName.c_str()),
60 entry("SERVERADDRESS=%s", serverAddress.c_str()));
Gunnar Millsa927de42017-04-06 21:40:50 -050061
Gunnar Mills7e1abfc2017-11-09 15:43:50 -060062 // Check if IMAGE DIR exists
Gunnar Mills3a482f62017-04-20 16:07:20 -050063 fs::path imgDirPath(IMG_UPLOAD_DIR);
64 if (!fs::is_directory(imgDirPath))
65 {
Gunnar Mills7e1abfc2017-11-09 15:43:50 -060066 log<level::ERR>("Error Image Dir does not exist");
67 elog<InternalFailure>();
68 return;
Gunnar Mills3a482f62017-04-20 16:07:20 -050069 }
70
Gunnar Millsa927de42017-04-06 21:40:50 -050071 pid_t pid = fork();
72
73 if (pid == 0)
74 {
Vernon Maueryb891eb32018-05-10 16:06:23 -070075 pid_t nextPid = fork();
76 if (nextPid == 0)
77 {
78 // child process
79 execl("/usr/bin/tftp", "tftp", "-g", "-r", fileName.c_str(),
80 serverAddress.c_str(), "-l",
81 (std::string{IMG_UPLOAD_DIR} + '/' + fileName).c_str(),
82 (char*)0);
83 // execl only returns on fail
84 log<level::ERR>("Error occurred during the TFTP call");
85 elog<InternalFailure>();
86 }
87 else if (nextPid < 0)
88 {
89 log<level::ERR>("Error occurred during fork");
90 elog<InternalFailure>();
91 }
92 // do nothing as parent if all is going well
93 // when parent exits, child will be reparented under init
94 // and then be reaped properly
95 exit(0);
Gunnar Millsa927de42017-04-06 21:40:50 -050096 }
97 else if (pid < 0)
98 {
99 log<level::ERR>("Error occurred during fork");
Gunnar Millsa733df52017-04-11 13:05:52 -0500100 elog<InternalFailure>();
Gunnar Millsa927de42017-04-06 21:40:50 -0500101 }
Vernon Maueryb891eb32018-05-10 16:06:23 -0700102 else
103 {
104 int status;
105 if (waitpid(pid, &status, 0) < 0)
106 {
107 log<level::ERR>("waitpid error");
108 }
109 else if (WEXITSTATUS(status) != 0)
110 {
111 log<level::ERR>("failed to launch tftp");
112 }
113 }
Gunnar Millsa927de42017-04-06 21:40:50 -0500114
Gunnar Mills701e0212017-04-03 11:21:27 -0500115 return;
116}
117
118} // namespace manager
119} // namespace software
120} // namespace phosphor