blob: 92f6b10099e7784c493b8cf2172bc49db2330562 [file] [log] [blame]
bigbiff1f9e4842020-10-31 11:33:15 -04001#include "twinstall/get_args.h"
bigbiffdf8436b2020-08-30 16:22:34 -04002
3std::string stage;
bigbiffdf8436b2020-08-30 16:22:34 -04004
5// command line args come from, in decreasing precedence:
6// - the actual command line
7// - the bootloader control block (one per line, after "recovery")
8// - the contents of COMMAND_FILE (one per line)
9std::vector<std::string> args::get_args(const int *argc, char*** const argv) {
10 CHECK_GT(*argc, 0);
11
12 bootloader_message boot = {};
bigbiffaed1bdf2021-08-03 18:21:39 -040013
bigbiffdf8436b2020-08-30 16:22:34 -040014 std::string err;
15 if (!read_bootloader_message(&boot, &err)) {
16 LOG(ERROR) << err;
17 // If fails, leave a zeroed bootloader_message.
18 boot = {};
19 }
20 stage = std::string(boot.stage);
21
22 std::string boot_command;
23 if (boot.command[0] != 0) {
24 if (memchr(boot.command, '\0', sizeof(boot.command))) {
25 boot_command = std::string(boot.command);
26 } else {
27 boot_command = std::string(boot.command, sizeof(boot.command));
28 }
29 LOG(INFO) << "Boot command: " << boot_command;
30 printf("boot command: %s\n", boot_command.c_str());
31 }
32
33 if (boot.status[0] != 0) {
34 std::string boot_status = std::string(boot.status, sizeof(boot.status));
35 LOG(INFO) << "Boot status: " << boot_status;
36 }
37
38 std::vector<std::string> args(*argv, *argv + *argc);
39
40 // --- if arguments weren't supplied, look in the bootloader control block
41 if (args.size() == 1) {
42 boot.recovery[sizeof(boot.recovery) - 1] = '\0'; // Ensure termination
43 std::string boot_recovery(boot.recovery);
44 std::vector<std::string> tokens = android::base::Split(boot_recovery, "\n");
45 if (!tokens.empty() && tokens[0] == "recovery") {
46 for (auto it = tokens.begin() + 1; it != tokens.end(); it++) {
47 // Skip empty and '\0'-filled tokens.
48 if (!it->empty() && (*it)[0] != '\0') args.push_back(std::move(*it));
49 }
50 LOG(INFO) << "Got " << args.size() << " arguments from boot message";
51 } else if (boot.recovery[0] != 0) {
52 LOG(ERROR) << "Bad boot message: \"" << boot_recovery << "\"";
53 }
54 }
55
bigbiffdf8436b2020-08-30 16:22:34 -040056 // Write the arguments (excluding the filename in args[0]) back into the
57 // bootloader control block. So the device will always boot into recovery to
58 // finish the pending work, until finish_recovery() is called.
59 std::vector<std::string> options(args.cbegin() + 1, args.cend());
60 if (!update_bootloader_message(options, &err)) {
61 LOG(ERROR) << "Failed to set BCB message: " << err;
62 }
63
64 // Finally, if no arguments were specified, check whether we should boot
65 // into fastboot or rescue mode.
66 if (args.size() == 1 && boot_command == "boot-fastboot") {
67 printf("fastbootd needed\n");
68 args.emplace_back("--fastboot");
69 } else if (args.size() == 1 && boot_command == "boot-rescue") {
70 args.emplace_back("--rescue");
71 }
72
73 return args;
74}