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(" receive file from medialibrary to path\n");
60 str.append(" command: recv uri path | recv all path\n");
61 str.append(" list file in medialibrary\n");
62 str.append(" command: list uri | list all\n");
63 str.append(" delete database and files in medialibrary\n");
64 str.append(" command: delete all\n");
65 }
66 str.append(" query displayname in medialibrary\n");
67 str.append(" command: query display_name\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 if (env.optArgs.displayName.empty()) {
243 printf("%s input displayName incorrect.\n", STR_FAIL.c_str());
244 return false;
245 }
246 env.queryParam.displayName = env.optArgs.displayName;
247 return true;
248 }
249
Check(ExecEnv & env)250 static bool Check(ExecEnv &env)
251 {
252 if (env.optArgs.cmdType == OptCmdType::TYPE_SEND) {
253 return CheckSend(env);
254 }
255 if (env.optArgs.cmdType == OptCmdType::TYPE_RECV) {
256 return CheckRecv(env);
257 }
258 if (env.optArgs.cmdType == OptCmdType::TYPE_LIST) {
259 return CheckList(env);
260 }
261 if (env.optArgs.cmdType == OptCmdType::TYPE_DELETE) {
262 return CheckDelete(env);
263 }
264 if (env.optArgs.cmdType == OptCmdType::TYPE_QUERY) {
265 return CheckQuery(env);
266 }
267 return false;
268 }
269
PutExtraString(ExecEnv & env,size_t start,size_t end=0)270 static void PutExtraString(ExecEnv &env, size_t start, size_t end = 0)
271 {
272 if (end == 0) {
273 for (size_t i = start; i < env.args.size(); i++) {
274 env.optArgs.extraArgs.push_back(env.args[i]);
275 }
276 } else {
277 for (size_t i = start; i <= std::min(env.args.size(), end); i++) {
278 env.optArgs.extraArgs.push_back(env.args[i]);
279 }
280 }
281 }
282
Parser(ExecEnv & env)283 int32_t CommandLine::Parser(ExecEnv &env)
284 {
285 if (env.args.size() < MEDIATOOL_ARG_MIN) {
286 ShowUsage(env.isRoot);
287 return Media::E_ERR;
288 }
289 std::string cmd = env.args[MEDIATOOL_ARG_CMD];
290 std::string optFirst = (env.args.size() > MEDIATOOL_ARG_FIRST) ? env.args[MEDIATOOL_ARG_FIRST] : "";
291 std::string optSecond = (env.args.size() > MEDIATOOL_ARG_SECOND) ? env.args[MEDIATOOL_ARG_SECOND] : "";
292 if (cmd == OPT_STR_SEND) {
293 env.optArgs.cmdType = OptCmdType::TYPE_SEND;
294 env.optArgs.path = optFirst;
295 if (env.args.size() > MEDIATOOL_ARG_SECOND) {
296 PutExtraString(env, MEDIATOOL_ARG_SECOND);
297 }
298 } else if (cmd == OPT_STR_RECV) {
299 env.optArgs.cmdType = OptCmdType::TYPE_RECV;
300 env.optArgs.uri = optFirst;
301 env.optArgs.recvPath = optSecond;
302 } else if (cmd == OPT_STR_LIST) {
303 env.optArgs.cmdType = OptCmdType::TYPE_LIST;
304 env.optArgs.uri = optFirst;
305 } else if (cmd == OPT_STR_DELETE) {
306 env.optArgs.uri = optFirst;
307 env.optArgs.cmdType = OptCmdType::TYPE_DELETE;
308 PutExtraString(env, MEDIATOOL_ARG_SECOND);
309 } else if (cmd == OPT_STR_QUERY) {
310 env.optArgs.displayName = optFirst;
311 env.optArgs.cmdType = OptCmdType::TYPE_QUERY;
312 } else {
313 ShowUsage(env.isRoot);
314 return Media::E_ERR;
315 }
316 if (!Check(env)) {
317 return Media::E_ERR;
318 }
319 return Media::E_OK;
320 }
321 } // namespace MediaTool
322 } // namespace Media
323 } // namespace OHOS
324