blob: 8bda6f2155229c10ec14e96ee0e997e38896f3fe [file] [log] [blame]
Felipe Lemebda15a02016-11-16 17:48:25 -08001/*
Felipe Leme6f674ae2016-11-18 17:10:33 -08002 * Copyright (C) 2016 The Android Open Source Project
Felipe Lemebda15a02016-11-16 17:48:25 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef FRAMEWORK_NATIVE_CMD_DUMPSTATE_UTIL_H_
17#define FRAMEWORK_NATIVE_CMD_DUMPSTATE_UTIL_H_
18
Felipe Lemef0292972016-11-22 13:57:05 -080019#include <cstdint>
20#include <string>
21
Felipe Leme6f674ae2016-11-18 17:10:33 -080022// TODO: use android::os::dumpstate (must wait until device code is refactored)
23
Felipe Lemebda15a02016-11-16 17:48:25 -080024/*
Felipe Leme46b85da2016-11-21 17:40:45 -080025 * Defines the Linux account that should be executing a command.
Felipe Lemebda15a02016-11-16 17:48:25 -080026 */
Felipe Leme46b85da2016-11-21 17:40:45 -080027enum PrivilegeMode {
Felipe Lemebda15a02016-11-16 17:48:25 -080028 /* Explicitly change the `uid` and `gid` to be `shell`.*/
29 DROP_ROOT,
30 /* Don't change the `uid` and `gid`. */
31 DONT_DROP_ROOT,
32 /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
33 SU_ROOT
34};
35
36/*
Felipe Leme46b85da2016-11-21 17:40:45 -080037 * Defines what should happen with the main output stream (`stdout` or fd) of a command.
Felipe Lemebda15a02016-11-16 17:48:25 -080038 */
Felipe Leme46b85da2016-11-21 17:40:45 -080039enum OutputMode {
40 /* Don't change main output. */
41 NORMAL_OUTPUT,
42 /* Redirect main output to `stderr`. */
Felipe Lemebda15a02016-11-16 17:48:25 -080043 REDIRECT_TO_STDERR
44};
45
46/*
47 * Value object used to set command options.
48 *
49 * Typically constructed using a builder with chained setters. Examples:
50 *
51 * CommandOptions::WithTimeout(20).AsRoot().Build();
52 * CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
53 *
54 * Although the builder could be used to dynamically set values. Example:
55 *
56 * CommandOptions::CommandOptionsBuilder options =
57 * CommandOptions::WithTimeout(10);
58 * if (!is_user_build()) {
59 * options.AsRoot();
60 * }
61 * RunCommand("command", {"args"}, options.Build());
62 */
63class CommandOptions {
64 private:
65 class CommandOptionsValues {
66 private:
67 CommandOptionsValues(int64_t timeout);
68
69 int64_t timeout_;
70 bool always_;
Felipe Leme46b85da2016-11-21 17:40:45 -080071 PrivilegeMode account_mode_;
72 OutputMode output_mode_;
Felipe Lemebda15a02016-11-16 17:48:25 -080073 std::string logging_message_;
74
75 friend class CommandOptions;
76 friend class CommandOptionsBuilder;
77 };
78
79 CommandOptions(const CommandOptionsValues& values);
80
81 const CommandOptionsValues values;
82
83 public:
84 class CommandOptionsBuilder {
85 public:
86 /* Sets the command to always run, even on `dry-run` mode. */
87 CommandOptionsBuilder& Always();
Felipe Leme46b85da2016-11-21 17:40:45 -080088 /* Sets the command's PrivilegeMode as `SU_ROOT` */
Felipe Lemebda15a02016-11-16 17:48:25 -080089 CommandOptionsBuilder& AsRoot();
Felipe Leme46b85da2016-11-21 17:40:45 -080090 /* Sets the command's PrivilegeMode as `DROP_ROOT` */
Felipe Lemebda15a02016-11-16 17:48:25 -080091 CommandOptionsBuilder& DropRoot();
Felipe Leme46b85da2016-11-21 17:40:45 -080092 /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */
Felipe Lemebda15a02016-11-16 17:48:25 -080093 CommandOptionsBuilder& RedirectStderr();
94 /* When not empty, logs a message before executing the command.
95 * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
96 CommandOptionsBuilder& Log(const std::string& message);
97 /* Builds the command options. */
98 CommandOptions Build();
99
100 private:
101 CommandOptionsBuilder(int64_t timeout);
102 CommandOptionsValues values;
103 friend class CommandOptions;
104 };
105
106 /** Gets the command timeout, in seconds. */
107 int64_t Timeout() const;
108 /* Checks whether the command should always be run, even on dry-run mode. */
109 bool Always() const;
Felipe Leme46b85da2016-11-21 17:40:45 -0800110 /** Gets the PrivilegeMode of the command. */
111 PrivilegeMode PrivilegeMode() const;
112 /** Gets the OutputMode of the command. */
113 OutputMode OutputMode() const;
Felipe Lemebda15a02016-11-16 17:48:25 -0800114 /** Gets the logging message header, it any. */
115 std::string LoggingMessage() const;
116
117 /** Creates a builder with the requied timeout. */
118 static CommandOptionsBuilder WithTimeout(int64_t timeout);
119
120 // Common options.
121 static CommandOptions DEFAULT;
Felipe Lemef0292972016-11-22 13:57:05 -0800122 static CommandOptions AS_ROOT;
123
124 // TODO: temporary, until device implementations use AS_ROOT
Felipe Lemebda15a02016-11-16 17:48:25 -0800125 static CommandOptions AS_ROOT_5;
Felipe Lemef0292972016-11-22 13:57:05 -0800126};
127
128/*
129 * System properties helper.
130 */
131class PropertiesHelper {
132 friend class DumpstateBaseTest;
133
134 public:
135 /*
136 * Gets whether device is running a `user` build.
137 */
138 static bool IsUserBuild();
139
140 /*
141 * When running in dry-run mode, skips the real dumps and just print the section headers.
142 *
143 * Useful when debugging dumpstate or other bugreport-related activities.
144 *
145 * Dry-run mode is enabled by setting the system property `dumpstate.dry_run` to true.
146 */
147 static bool IsDryRun();
148
149 private:
150 static std::string build_type_;
151 static int dry_run_;
Felipe Lemebda15a02016-11-16 17:48:25 -0800152};
153
154/*
155 * Forks a command, waits for it to finish, and returns its status.
156 *
157 * |fd| file descriptor that receives the command's 'stdout'.
Felipe Lemef0292972016-11-22 13:57:05 -0800158 * |title| description of the command printed on `stdout` (or empty to skip
159 * description).
Felipe Lemebda15a02016-11-16 17:48:25 -0800160 * |full_command| array containing the command (first entry) and its arguments.
Felipe Leme46b85da2016-11-21 17:40:45 -0800161 * Must contain at least one element.
Felipe Lemebda15a02016-11-16 17:48:25 -0800162 * |options| optional argument defining the command's behavior.
Felipe Lemebda15a02016-11-16 17:48:25 -0800163 */
Felipe Lemef0292972016-11-22 13:57:05 -0800164int RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -0800165 const CommandOptions& options = CommandOptions::DEFAULT);
Felipe Lemebda15a02016-11-16 17:48:25 -0800166
167/*
168 * Dumps the contents of a file into a file descriptor.
169 *
170 * |fd| file descriptor where the file is dumped into.
Felipe Lemef0292972016-11-22 13:57:05 -0800171 * |title| description of the command printed on `stdout` (or empty to skip
172 * description).
Felipe Lemebda15a02016-11-16 17:48:25 -0800173 * |path| location of the file to be dumped.
174 */
Felipe Lemef0292972016-11-22 13:57:05 -0800175int DumpFileToFd(int fd, const std::string& title, const std::string& path);
Felipe Lemebda15a02016-11-16 17:48:25 -0800176
177#endif // FRAMEWORK_NATIVE_CMD_DUMPSTATE_UTIL_H_