1dffd6523SWilliam A. Kennington III // Copyright 2022 Google LLC
2dffd6523SWilliam A. Kennington III //
3dffd6523SWilliam A. Kennington III // Licensed under the Apache License, Version 2.0 (the "License");
4dffd6523SWilliam A. Kennington III // you may not use this file except in compliance with the License.
5dffd6523SWilliam A. Kennington III // You may obtain a copy of the License at
6dffd6523SWilliam A. Kennington III //
7dffd6523SWilliam A. Kennington III //      http://www.apache.org/licenses/LICENSE-2.0
8dffd6523SWilliam A. Kennington III //
9dffd6523SWilliam A. Kennington III // Unless required by applicable law or agreed to in writing, software
10dffd6523SWilliam A. Kennington III // distributed under the License is distributed on an "AS IS" BASIS,
11dffd6523SWilliam A. Kennington III // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12dffd6523SWilliam A. Kennington III // See the License for the specific language governing permissions and
13dffd6523SWilliam A. Kennington III // limitations under the License.
14dffd6523SWilliam A. Kennington III 
151e76060aSYuxiao Zhang #include "file-io.hpp"
161e76060aSYuxiao Zhang 
17dffd6523SWilliam A. Kennington III #include <sdeventplus/event.hpp>
18dffd6523SWilliam A. Kennington III #include <sdeventplus/source/io.hpp>
19dffd6523SWilliam A. Kennington III #include <stdplus/fd/create.hpp>
20dffd6523SWilliam A. Kennington III #include <stdplus/fd/ops.hpp>
21253e6463SWilly Tu #include <stdplus/print.hpp>
22dffd6523SWilliam A. Kennington III 
235ca20ffeSYuxiao Zhang using namespace std::string_view_literals;
245ca20ffeSYuxiao Zhang 
25dffd6523SWilliam A. Kennington III // A privileged port that is reserved for querying BMC DHCP completion.
26dffd6523SWilliam A. Kennington III // This is well known by the clients querying the status.
27dffd6523SWilliam A. Kennington III constexpr uint16_t kListenPort = 23;
28dffd6523SWilliam A. Kennington III 
createListener()29dffd6523SWilliam A. Kennington III stdplus::ManagedFd createListener()
30dffd6523SWilliam A. Kennington III {
31dffd6523SWilliam A. Kennington III     using namespace stdplus::fd;
32*c66ebc35SPatrick Williams     auto sock =
33*c66ebc35SPatrick Williams         socket(SocketDomain::INet6, SocketType::Stream, SocketProto::TCP);
34dffd6523SWilliam A. Kennington III     setFileFlags(sock, getFileFlags(sock).set(stdplus::fd::FileFlag::NonBlock));
35dffd6523SWilliam A. Kennington III     sockaddr_in6 addr = {};
36dffd6523SWilliam A. Kennington III     addr.sin6_family = AF_INET6;
37dffd6523SWilliam A. Kennington III     addr.sin6_port = htons(kListenPort);
38dffd6523SWilliam A. Kennington III     bind(sock, addr);
39dffd6523SWilliam A. Kennington III     listen(sock, 10);
40dffd6523SWilliam A. Kennington III     return sock;
41dffd6523SWilliam A. Kennington III }
42dffd6523SWilliam A. Kennington III 
main()431e76060aSYuxiao Zhang int main()
44dffd6523SWilliam A. Kennington III {
45dffd6523SWilliam A. Kennington III     try
46dffd6523SWilliam A. Kennington III     {
47dffd6523SWilliam A. Kennington III         auto listener = createListener();
48dffd6523SWilliam A. Kennington III         auto event = sdeventplus::Event::get_default();
49dffd6523SWilliam A. Kennington III         sdeventplus::source::IO do_accept(
50dffd6523SWilliam A. Kennington III             event, listener.get(), EPOLLIN | EPOLLET,
51dffd6523SWilliam A. Kennington III             [&](sdeventplus::source::IO&, int, uint32_t) {
525ca20ffeSYuxiao Zhang                 while (auto fd = stdplus::fd::accept(listener))
535ca20ffeSYuxiao Zhang                 {
541e76060aSYuxiao Zhang                     std::string data;
551e76060aSYuxiao Zhang                     try
561e76060aSYuxiao Zhang                     {
571e76060aSYuxiao Zhang                         data = fileRead(statusFile);
581e76060aSYuxiao Zhang                     }
591e76060aSYuxiao Zhang                     catch (const std::exception& e)
601e76060aSYuxiao Zhang                     {
61*c66ebc35SPatrick Williams                         // we don't want to fail the upgrade process, set the
62*c66ebc35SPatrick Williams                         // status to ONGOING
631e76060aSYuxiao Zhang                         data.push_back(2);
641e76060aSYuxiao Zhang                         data.append("Failed to read status ");
651e76060aSYuxiao Zhang                         data.append(e.what());
661e76060aSYuxiao Zhang                     }
671e76060aSYuxiao Zhang 
68*c66ebc35SPatrick Williams                     stdplus::fd::sendExact(*fd, data,
69*c66ebc35SPatrick Williams                                            stdplus::fd::SendFlags(0));
705ca20ffeSYuxiao Zhang                 }
71dffd6523SWilliam A. Kennington III             });
72dffd6523SWilliam A. Kennington III         return event.loop();
73dffd6523SWilliam A. Kennington III     }
74dffd6523SWilliam A. Kennington III     catch (const std::exception& e)
75dffd6523SWilliam A. Kennington III     {
76253e6463SWilly Tu         stdplus::println(stderr, "Failed: {}", e.what());
77dffd6523SWilliam A. Kennington III         return 1;
78dffd6523SWilliam A. Kennington III     }
79dffd6523SWilliam A. Kennington III }
80