• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "media_log.h"
27 #include "medialibrary_errno.h"
28 #include "option_args.h"
29 #include "userfile_client_ex.h"
30 
31 namespace OHOS {
32 namespace Media {
33 namespace MediaTool {
34 constexpr char CHAR_PATH_DELIMITER = '/';
35 constexpr int MEDIATOOL_ARG_MIN = 3;
36 constexpr int MEDIATOOL_ARG_CMD = 1;
37 constexpr int MEDIATOOL_ARG_FIRST = 2;
38 constexpr int MEDIATOOL_ARG_SECOND = 3;
39 const std::string OPT_STR_SEND = "send";
40 const std::string OPT_STR_RECV = "recv";
41 const std::string OPT_STR_LIST = "list";
42 const std::string OPT_STR_DELETE = "delete";
43 const std::string OPT_STR_QUERY = "query";
44 const std::string OPT_STR_LS = "ls";
45 const std::string OPT_STR_ALL = "all";
46 
47 const std::string SEND_CREATE_THUMBNAIL_SYNC = "-ts";
48 const std::string SEND_CREATE_THUMBNAIL_ASYNC = "-tas";
49 const std::string SEND_CREATE_REMOVE_ORIGIN_FILE = "-rf";
50 const std::string SEND_CREATE_UNREMOVE_ORIGIN_FILE = "-urf";
51 
52 const std::string DELETE_ONLY_DATABASE = "-db";
53 
ShowUsage(bool isRoot)54 static void ShowUsage(bool isRoot)
55 {
56     std::string str;
57     str.append("usage:\n");
58     if (isRoot) {
59         str.append("  send file from path to medialibrary\n");
60         str.append("    command: mediatool send <file-or-dir-path> [-ts] [-tas] [-rf] [-urf]\n");
61         str.append("  list media assets in medialibrary\n");
62         str.append("    command: mediatool list <media-uri>\n");
63     }
64     str.append("  receive file from medialibrary to path\n");
65     str.append("    command: mediatool recv <src-media> <dest-path>\n");
66     str.append("  delete media assets in medialibrary\n");
67     str.append("    command: mediatool delete <media-uri>\n");
68     str.append("  query path or uri by displayname in medialibrary\n");
69     str.append("    command: mediatool query <display-name> [-p] [-u]\n");
70     str.append("  execute ls -l in system media directory\n");
71     str.append("    command: mediatool ls -l <media-directory>\n");
72 
73     printf("%s", str.c_str());
74 }
75 
IsDirPath(const std::string path)76 static inline bool IsDirPath(const std::string path)
77 {
78     if (path.empty()) {
79         return false;
80     }
81     string subName;
82     string::size_type delimiterPos = path.rfind(CHAR_PATH_DELIMITER);
83     if (delimiterPos == std::string::npos) {
84         subName = path;
85     } else {
86         subName = path.substr(delimiterPos + 1);
87     }
88     if (subName.find('.') == std::string::npos || subName == "." || subName == "..") {
89         return true;
90     } else {
91         return false;
92     }
93 }
94 
CheckRecvPath(ExecEnv & env)95 static bool CheckRecvPath(ExecEnv &env)
96 {
97     std::string path;
98     if (IsDirPath(env.recvParam.recvPath)) {
99         env.recvParam.isRecvPathDir = true;
100         path = env.recvParam.recvPath;
101     } else {
102         env.recvParam.isRecvPathDir = false;
103         path = ExtractFilePath(env.recvParam.recvPath);
104     }
105 
106     if (!MediaFileUtils::IsDirectory(path)) {
107         ForceCreateDirectory(path);
108     }
109     if (!MediaFileUtils::IsDirectory(path)) {
110         MEDIA_ERR_LOG("recv path issue. path: %{public}s", path.c_str());
111         printf("%s path issue. path:%s\n", STR_FAIL.c_str(), path.c_str());
112         return false;
113     }
114     if (!env.recvParam.isRecvPathDir) {
115         if (FileExists(env.recvParam.recvPath)) {
116             MEDIA_ERR_LOG("recv file has exist. file: %{public}s", env.recvParam.recvPath.c_str());
117             printf("%s file has exist. file:%s\n", STR_FAIL.c_str(), env.recvParam.recvPath.c_str());
118             return false;
119         }
120     } else {
121         env.recvParam.recvPath = IncludeTrailingPathDelimiter(env.recvParam.recvPath);
122     }
123     return true;
124 }
125 
CheckList(ExecEnv & env)126 static bool CheckList(ExecEnv &env)
127 {
128     if (env.optArgs.uri == OPT_STR_ALL) {
129         env.listParam.isListAll = true;
130         env.listParam.listUri.clear();
131     } else if (!env.optArgs.uri.empty()) {
132         std::string tableName = UserFileClientEx::GetTableNameByUri(env.optArgs.uri);
133         if (tableName.empty()) {
134             printf("%s uri invalid. uri:%s\n", STR_FAIL.c_str(), env.optArgs.uri.c_str());
135             return false;
136         }
137         env.listParam.listUri = env.optArgs.uri;
138     } else {
139         printf("%s input uri incorrect.\n", STR_FAIL.c_str());
140         return false;
141     }
142     return true;
143 }
144 
CheckRecv(ExecEnv & env)145 static bool CheckRecv(ExecEnv &env)
146 {
147     if (env.optArgs.uri == OPT_STR_ALL) {
148         env.recvParam.recvTarget.clear();
149         env.recvParam.isRecvAll = true;
150     } else if (!env.optArgs.uri.empty()) {
151         env.recvParam.recvTarget = env.optArgs.uri;
152         env.recvParam.isRecvAll = false;
153     } else {
154         MEDIA_ERR_LOG("recv target is empty");
155         printf("%s recv target is empty.\n", STR_FAIL.c_str());
156         return false;
157     }
158     if (env.optArgs.recvPath.empty()) {
159         MEDIA_ERR_LOG("recv path empty");
160         printf("%s recv path empty.\n", STR_FAIL.c_str());
161         return false;
162     }
163     if (env.optArgs.recvPath.find(CHAR_PATH_DELIMITER) == 0) {
164         env.recvParam.recvPath = env.optArgs.recvPath;
165     } else {
166         env.recvParam.recvPath = env.workPath + env.optArgs.recvPath;
167     }
168     if (!CheckRecvPath(env)) {
169         return false;
170     }
171     return true;
172 }
173 
CheckExtraArgsInSend(ExecEnv & env)174 static void CheckExtraArgsInSend(ExecEnv &env)
175 {
176     for (size_t i = 0; i < env.optArgs.extraArgs.size(); i++) {
177         string param = env.optArgs.extraArgs[i];
178         if (param == SEND_CREATE_THUMBNAIL_SYNC) {
179             env.sendParam.isCreateThumbSyncInSend = true;
180         }
181         if (param == SEND_CREATE_THUMBNAIL_ASYNC) {
182             env.sendParam.isCreateThumbSyncInSend = false;
183         }
184         if (param == SEND_CREATE_REMOVE_ORIGIN_FILE) {
185             env.sendParam.isRemoveOriginFileInSend = true;
186         }
187         if (param == SEND_CREATE_UNREMOVE_ORIGIN_FILE) {
188             env.sendParam.isRemoveOriginFileInSend = false;
189         }
190     }
191 }
192 
CheckSend(ExecEnv & env)193 static bool CheckSend(ExecEnv &env)
194 {
195     if (env.optArgs.path.empty()) {
196         printf("%s path empty.\n", STR_FAIL.c_str());
197         return false;
198     }
199     if (!PathToRealPath(env.optArgs.path, env.sendParam.sendPath)) {
200         printf("%s path issue. errno:%d, path:%s.\n", STR_FAIL.c_str(), errno, env.optArgs.path.c_str());
201         return false;
202     }
203     if (!MediaFileUtils::IsDirectory(env.sendParam.sendPath)) {
204         env.sendParam.isFile = true;
205     } else if (MediaFileUtils::IsDirectory(env.sendParam.sendPath)) {
206         env.sendParam.sendPath = IncludeTrailingPathDelimiter(env.sendParam.sendPath);
207         env.sendParam.isFile = false;
208     } else {
209         printf("%s path issue. not file and not directory. path:%s.\n", STR_FAIL.c_str(),
210             env.sendParam.sendPath.c_str());
211         return false;
212     }
213     CheckExtraArgsInSend(env);
214     return true;
215 }
216 
CheckDelete(ExecEnv & env)217 static bool CheckDelete(ExecEnv &env)
218 {
219     if (env.optArgs.uri == OPT_STR_ALL) {
220         env.deleteParam.deleteUri.clear();
221         env.deleteParam.isDeleteAll = true;
222         for (size_t i = 0; i < env.optArgs.extraArgs.size(); i++) {
223             string param = env.optArgs.extraArgs[i];
224             if (param == DELETE_ONLY_DATABASE) {
225                 env.deleteParam.isOnlyDeleteDb = true;
226             }
227         }
228     } else if (!env.optArgs.uri.empty()) {
229         std::string tableName = UserFileClientEx::GetTableNameByUri(env.optArgs.uri);
230         if (tableName.empty()) {
231             printf("%s uri invalid. uri:%s\n", STR_FAIL.c_str(), env.optArgs.uri.c_str());
232             return false;
233         }
234         env.deleteParam.isDeleteAll = false;
235         env.deleteParam.deleteUri = env.optArgs.uri;
236     } else {
237         printf("%s input uri incorrect.\n", STR_FAIL.c_str());
238         return false;
239     }
240 
241     return true;
242 }
243 
CheckQuery(ExecEnv & env)244 static bool CheckQuery(ExecEnv &env)
245 {
246     for (size_t i = 0; i < env.optArgs.extraArgs.size(); i++) {
247         string param = env.optArgs.extraArgs[i];
248         if (param == "-p") {
249             env.queryParam.pathFlag = true;
250         } else if (param == "-u") {
251             env.queryParam.uriFlag = true;
252         } else if (env.queryParam.displayName.empty()) {
253             env.queryParam.displayName = param;
254         }
255     }
256 
257     if ((env.queryParam.pathFlag && env.queryParam.uriFlag) || env.queryParam.displayName.empty()) {
258         printf("The command is not a valid query command. See 'mediatool -h'\n");
259         ShowUsage(env.isRoot);
260         return false;
261     }
262     if (!env.queryParam.pathFlag && !env.queryParam.uriFlag) {
263         env.queryParam.pathFlag = true;
264     }
265 
266     return true;
267 }
268 
Check(ExecEnv & env)269 static bool Check(ExecEnv &env)
270 {
271     if (env.optArgs.cmdType == OptCmdType::TYPE_SEND) {
272         return CheckSend(env);
273     }
274     if (env.optArgs.cmdType == OptCmdType::TYPE_RECV) {
275         return CheckRecv(env);
276     }
277     if (env.optArgs.cmdType == OptCmdType::TYPE_LIST) {
278         return CheckList(env);
279     }
280     if (env.optArgs.cmdType == OptCmdType::TYPE_DELETE) {
281         return CheckDelete(env);
282     }
283     if (env.optArgs.cmdType == OptCmdType::TYPE_QUERY) {
284         return CheckQuery(env);
285     }
286     if (env.optArgs.cmdType == OptCmdType::TYPE_LS) {
287         // ls command performs check later
288         return true;
289     }
290     return false;
291 }
292 
PutExtraString(ExecEnv & env,size_t start,size_t end=0)293 static void PutExtraString(ExecEnv &env, size_t start, size_t end = 0)
294 {
295     if (end == 0) {
296         for (size_t i = start; i < env.args.size(); i++) {
297             env.optArgs.extraArgs.push_back(env.args[i]);
298         }
299     } else {
300         for (size_t i = start; i <= std::min(env.args.size(), end); i++) {
301             env.optArgs.extraArgs.push_back(env.args[i]);
302         }
303     }
304 }
305 
Parser(ExecEnv & env)306 int32_t CommandLine::Parser(ExecEnv &env)
307 {
308     if (env.args.size() < MEDIATOOL_ARG_MIN) {
309         ShowUsage(env.isRoot);
310         return Media::E_ERR;
311     }
312     env.commandArgs = std::vector<std::string>(env.args.begin() + MEDIATOOL_ARG_MIN - 1, env.args.end());
313     std::string cmd = env.args[MEDIATOOL_ARG_CMD];
314     std::string optFirst = (env.args.size() > MEDIATOOL_ARG_FIRST) ? env.args[MEDIATOOL_ARG_FIRST] : "";
315     std::string optSecond = (env.args.size() > MEDIATOOL_ARG_SECOND) ? env.args[MEDIATOOL_ARG_SECOND] : "";
316     if (cmd == OPT_STR_SEND) {
317         env.optArgs.cmdType = OptCmdType::TYPE_SEND;
318         env.optArgs.path = optFirst;
319         if (env.args.size() > MEDIATOOL_ARG_SECOND) {
320             PutExtraString(env, MEDIATOOL_ARG_SECOND);
321         }
322     } else if (cmd == OPT_STR_RECV) {
323         env.optArgs.cmdType = OptCmdType::TYPE_RECV;
324         env.optArgs.uri = optFirst;
325         env.optArgs.recvPath = optSecond;
326     } else if (cmd == OPT_STR_LIST) {
327         env.optArgs.cmdType = OptCmdType::TYPE_LIST;
328         env.optArgs.uri = optFirst;
329     } else if (cmd == OPT_STR_DELETE) {
330         env.optArgs.uri = optFirst;
331         env.optArgs.cmdType = OptCmdType::TYPE_DELETE;
332         PutExtraString(env, MEDIATOOL_ARG_SECOND);
333     } else if (cmd == OPT_STR_QUERY) {
334         env.optArgs.cmdType = OptCmdType::TYPE_QUERY;
335         PutExtraString(env, MEDIATOOL_ARG_FIRST);
336     } else if (cmd == OPT_STR_LS) {
337         env.optArgs.cmdType = OptCmdType::TYPE_LS;
338     } else {
339         ShowUsage(env.isRoot);
340         return Media::E_ERR;
341     }
342     if (!Check(env)) {
343         return Media::E_ERR;
344     }
345     return Media::E_OK;
346 }
347 
348 } // namespace MediaTool
349 } // namespace Media
350 } // namespace OHOS
351