1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "command_line.h"
16
17 #include <cstddef>
18 #include <string>
19
20 #include "constant.h"
21 #include "directory_ex.h"
22 #include "exec_env.h"
23 #include "file_ex.h"
24 #include "media_column.h"
25 #include "media_file_utils.h"
26 #include "medialibrary_errno.h"
27 #include "option_args.h"
28 #include "userfile_client_ex.h"
29
30 namespace OHOS {
31 namespace Media {
32 namespace MediaTool {
33 constexpr char CHAR_PATH_DELIMITER = '/';
34 constexpr int MEDIATOOL_ARG_MIN = 3;
35 constexpr int MEDIATOOL_ARG_CMD = 1;
36 constexpr int MEDIATOOL_ARG_FIRST = 2;
37 constexpr int MEDIATOOL_ARG_SECOND = 3;
38 const std::string OPT_STR_SEND = "send";
39 const std::string OPT_STR_RECV = "recv";
40 const std::string OPT_STR_LIST = "list";
41 const std::string OPT_STR_DELETE = "delete";
42 const std::string OPT_STR_QUERY = "query";
43 const std::string OPT_STR_ALL = "all";
44
45 const std::string SEND_CREATE_THUMBNAIL_SYNC = "-ts";
46 const std::string SEND_CREATE_THUMBNAIL_ASYNC = "-tas";
47 const std::string SEND_CREATE_REMOVE_ORIGIN_FILE = "-rf";
48 const std::string SEND_CREATE_UNREMOVE_ORIGIN_FILE = "-urf";
49
50 const std::string DELETE_ONLY_DATABASE = "-db";
51
ShowUsage(bool isRoot)52 static void ShowUsage(bool isRoot)
53 {
54 std::string str;
55 str.append("usage:\n");
56 if (isRoot) {
57 str.append(" send file from path to medialibrary\n");
58 str.append(" command: send path (file path or dir path)\n");
59 str.append(" list file in medialibrary\n");
60 str.append(" command: list uri | list all\n");
61 }
62 str.append(" receive file from medialibrary to path\n");
63 str.append(" command: recv uri path | recv all path\n");
64 str.append(" delete database and files in medialibrary\n");
65 str.append(" command: delete all\n");
66 str.append(" query path or uri by displayname in medialibrary\n");
67 str.append(" command: query display_name -p | query display_name -u\n");
68 printf("%s", str.c_str());
69 }
70
IsDirPath(const std::string path)71 static inline bool IsDirPath(const std::string path)
72 {
73 if (path.empty()) {
74 return false;
75 }
76 string subName;
77 string::size_type delimiterPos = path.rfind(CHAR_PATH_DELIMITER);
78 if (delimiterPos == std::string::npos) {
79 subName = path;
80 } else {
81 subName = path.substr(delimiterPos + 1);
82 }
83 if (subName.find('.') == std::string::npos || subName == "." || subName == "..") {
84 return true;
85 } else {
86 return false;
87 }
88 }
89
CheckRecvPath(ExecEnv & env)90 static bool CheckRecvPath(ExecEnv &env)
91 {
92 std::string path;
93 if (IsDirPath(env.recvParam.recvPath)) {
94 env.recvParam.isRecvPathDir = true;
95 path = env.recvParam.recvPath;
96 } else {
97 env.recvParam.isRecvPathDir = false;
98 path = ExtractFilePath(env.recvParam.recvPath);
99 }
100
101 if (!MediaFileUtils::IsDirectory(path)) {
102 ForceCreateDirectory(path);
103 }
104 if (!MediaFileUtils::IsDirectory(path)) {
105 printf("%s path issue. path:%s\n", STR_FAIL.c_str(), path.c_str());
106 return false;
107 }
108 if (!env.recvParam.isRecvPathDir) {
109 if (FileExists(env.recvParam.recvPath)) {
110 printf("%s file has exist. file:%s\n", STR_FAIL.c_str(), env.recvParam.recvPath.c_str());
111 return false;
112 }
113 } else {
114 env.recvParam.recvPath = IncludeTrailingPathDelimiter(env.recvParam.recvPath);
115 }
116 return true;
117 }
118
CheckList(ExecEnv & env)119 static bool CheckList(ExecEnv &env)
120 {
121 if (env.optArgs.uri == OPT_STR_ALL) {
122 env.listParam.isListAll = true;
123 env.listParam.listUri.clear();
124 } else if (!env.optArgs.uri.empty()) {
125 std::string tableName = UserFileClientEx::GetTableNameByUri(env.optArgs.uri);
126 if (tableName.empty()) {
127 printf("%s uri invalid. uri:%s\n", STR_FAIL.c_str(), env.optArgs.uri.c_str());
128 return false;
129 }
130 env.listParam.listUri = env.optArgs.uri;
131 } else {
132 printf("%s input uri incorrect.\n", STR_FAIL.c_str());
133 return false;
134 }
135 return true;
136 }
137
CheckRecv(ExecEnv & env)138 static bool CheckRecv(ExecEnv &env)
139 {
140 if (env.optArgs.uri == OPT_STR_ALL) {
141 env.recvParam.recvUri.clear();
142 env.recvParam.isRecvAll = true;
143 } else if (!env.optArgs.uri.empty()) {
144 std::string tableName = UserFileClientEx::GetTableNameByUri(env.optArgs.uri);
145 if (tableName.empty()) {
146 printf("%s uri issue. uri:%s\n", STR_FAIL.c_str(), env.optArgs.uri.c_str());
147 return false;
148 }
149 env.recvParam.recvUri = env.optArgs.uri;
150 env.recvParam.isRecvAll = false;
151 } else {
152 printf("%s input uri incorrect.\n", STR_FAIL.c_str());
153 return false;
154 }
155 if (env.optArgs.recvPath.empty()) {
156 printf("%s recv path empty.\n", STR_FAIL.c_str());
157 return false;
158 }
159 if (env.optArgs.recvPath.find(CHAR_PATH_DELIMITER) == 0) {
160 env.recvParam.recvPath = env.optArgs.recvPath;
161 } else {
162 env.recvParam.recvPath = env.workPath + env.optArgs.recvPath;
163 }
164 if (!CheckRecvPath(env)) {
165 return false;
166 }
167 return true;
168 }
169
CheckExtraArgsInSend(ExecEnv & env)170 static void CheckExtraArgsInSend(ExecEnv &env)
171 {
172 for (size_t i = 0; i < env.optArgs.extraArgs.size(); i++) {
173 string param = env.optArgs.extraArgs[i];
174 if (param == SEND_CREATE_THUMBNAIL_SYNC) {
175 env.sendParam.isCreateThumbSyncInSend = true;
176 }
177 if (param == SEND_CREATE_THUMBNAIL_ASYNC) {
178 env.sendParam.isCreateThumbSyncInSend = false;
179 }
180 if (param == SEND_CREATE_REMOVE_ORIGIN_FILE) {
181 env.sendParam.isRemoveOriginFileInSend = true;
182 }
183 if (param == SEND_CREATE_UNREMOVE_ORIGIN_FILE) {
184 env.sendParam.isRemoveOriginFileInSend = false;
185 }
186 }
187 }
188
CheckSend(ExecEnv & env)189 static bool CheckSend(ExecEnv &env)
190 {
191 if (env.optArgs.path.empty()) {
192 printf("%s path empty.\n", STR_FAIL.c_str());
193 return false;
194 }
195 if (!PathToRealPath(env.optArgs.path, env.sendParam.sendPath)) {
196 printf("%s path issue. errno:%d, path:%s.\n", STR_FAIL.c_str(), errno, env.optArgs.path.c_str());
197 return false;
198 }
199 if (!MediaFileUtils::IsDirectory(env.sendParam.sendPath)) {
200 env.sendParam.isFile = true;
201 } else if (MediaFileUtils::IsDirectory(env.sendParam.sendPath)) {
202 env.sendParam.sendPath = IncludeTrailingPathDelimiter(env.sendParam.sendPath);
203 env.sendParam.isFile = false;
204 } else {
205 printf("%s path issue. not file and not directory. path:%s.\n", STR_FAIL.c_str(),
206 env.sendParam.sendPath.c_str());
207 return false;
208 }
209 CheckExtraArgsInSend(env);
210 return true;
211 }
212
CheckDelete(ExecEnv & env)213 static bool CheckDelete(ExecEnv &env)
214 {
215 if (env.optArgs.uri == OPT_STR_ALL) {
216 env.deleteParam.deleteUri.clear();
217 env.deleteParam.isDeleteAll = true;
218 for (size_t i = 0; i < env.optArgs.extraArgs.size(); i++) {
219 string param = env.optArgs.extraArgs[i];
220 if (param == DELETE_ONLY_DATABASE) {
221 env.deleteParam.isOnlyDeleteDb = true;
222 }
223 }
224 } else if (!env.optArgs.uri.empty()) {
225 std::string tableName = UserFileClientEx::GetTableNameByUri(env.optArgs.uri);
226 if (tableName.empty()) {
227 printf("%s uri invalid. uri:%s\n", STR_FAIL.c_str(), env.optArgs.uri.c_str());
228 return false;
229 }
230 env.deleteParam.isDeleteAll = false;
231 env.deleteParam.deleteUri = env.optArgs.uri;
232 } else {
233 printf("%s input uri incorrect.\n", STR_FAIL.c_str());
234 return false;
235 }
236
237 return true;
238 }
239
CheckQuery(ExecEnv & env)240 static bool CheckQuery(ExecEnv &env)
241 {
242 for (size_t i = 0; i < env.optArgs.extraArgs.size(); i++) {
243 string param = env.optArgs.extraArgs[i];
244 if (param == "-p") {
245 env.queryParam.pathFlag = true;
246 } else if (param == "-u") {
247 env.queryParam.uriFlag = true;
248 } else if (env.queryParam.displayName.empty()) {
249 env.queryParam.displayName = param;
250 }
251 }
252
253 if ((env.queryParam.pathFlag && env.queryParam.uriFlag) || env.queryParam.displayName.empty()) {
254 printf("The command is not a valid query command. See 'mediatool -h'\n");
255 ShowUsage(env.isRoot);
256 return false;
257 }
258 if (!env.queryParam.pathFlag && !env.queryParam.uriFlag) {
259 env.queryParam.pathFlag = true;
260 }
261
262 return true;
263 }
264
Check(ExecEnv & env)265 static bool Check(ExecEnv &env)
266 {
267 if (env.optArgs.cmdType == OptCmdType::TYPE_SEND) {
268 return CheckSend(env);
269 }
270 if (env.optArgs.cmdType == OptCmdType::TYPE_RECV) {
271 return CheckRecv(env);
272 }
273 if (env.optArgs.cmdType == OptCmdType::TYPE_LIST) {
274 return CheckList(env);
275 }
276 if (env.optArgs.cmdType == OptCmdType::TYPE_DELETE) {
277 return CheckDelete(env);
278 }
279 if (env.optArgs.cmdType == OptCmdType::TYPE_QUERY) {
280 return CheckQuery(env);
281 }
282 return false;
283 }
284
PutExtraString(ExecEnv & env,size_t start,size_t end=0)285 static void PutExtraString(ExecEnv &env, size_t start, size_t end = 0)
286 {
287 if (end == 0) {
288 for (size_t i = start; i < env.args.size(); i++) {
289 env.optArgs.extraArgs.push_back(env.args[i]);
290 }
291 } else {
292 for (size_t i = start; i <= std::min(env.args.size(), end); i++) {
293 env.optArgs.extraArgs.push_back(env.args[i]);
294 }
295 }
296 }
297
Parser(ExecEnv & env)298 int32_t CommandLine::Parser(ExecEnv &env)
299 {
300 if (env.args.size() < MEDIATOOL_ARG_MIN) {
301 ShowUsage(env.isRoot);
302 return Media::E_ERR;
303 }
304 std::string cmd = env.args[MEDIATOOL_ARG_CMD];
305 std::string optFirst = (env.args.size() > MEDIATOOL_ARG_FIRST) ? env.args[MEDIATOOL_ARG_FIRST] : "";
306 std::string optSecond = (env.args.size() > MEDIATOOL_ARG_SECOND) ? env.args[MEDIATOOL_ARG_SECOND] : "";
307 if (cmd == OPT_STR_SEND) {
308 env.optArgs.cmdType = OptCmdType::TYPE_SEND;
309 env.optArgs.path = optFirst;
310 if (env.args.size() > MEDIATOOL_ARG_SECOND) {
311 PutExtraString(env, MEDIATOOL_ARG_SECOND);
312 }
313 } else if (cmd == OPT_STR_RECV) {
314 env.optArgs.cmdType = OptCmdType::TYPE_RECV;
315 env.optArgs.uri = optFirst;
316 env.optArgs.recvPath = optSecond;
317 } else if (cmd == OPT_STR_LIST) {
318 env.optArgs.cmdType = OptCmdType::TYPE_LIST;
319 env.optArgs.uri = optFirst;
320 } else if (cmd == OPT_STR_DELETE) {
321 env.optArgs.uri = optFirst;
322 env.optArgs.cmdType = OptCmdType::TYPE_DELETE;
323 PutExtraString(env, MEDIATOOL_ARG_SECOND);
324 } else if (cmd == OPT_STR_QUERY) {
325 env.optArgs.cmdType = OptCmdType::TYPE_QUERY;
326 PutExtraString(env, MEDIATOOL_ARG_FIRST);
327 } else {
328 ShowUsage(env.isRoot);
329 return Media::E_ERR;
330 }
331 if (!Check(env)) {
332 return Media::E_ERR;
333 }
334 return Media::E_OK;
335 }
336 } // namespace MediaTool
337 } // namespace Media
338 } // namespace OHOS
339