1
2 /*
3 * Copyright (C) 2024 Huawei Device Co., Ltd.
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
17 #include "command/ls_command.h"
18
19 #include <sstream>
20 #include <string>
21 #include <vector>
22
23 #include "constant.h"
24 #include "medialibrary_errno.h"
25 #include "utils/mediatool_command_utils.h"
26 #include "media_file_utils.h"
27 #include "media_log.h"
28 #include "mediatool_uri.h"
29 #include "userfile_client.h"
30
31 namespace OHOS {
32 namespace Media {
33 namespace MediaTool {
34
35 using namespace std;
36
37 const int LSCommand::LS_POS_ARG_MIN = 1;
38 const int LSCommand::LS_POS_ARG_MAX = 1;
39
ParsePositionalArgs(const std::vector<std::string> & positionalArgs)40 bool LSCommand::ParsePositionalArgs(const std::vector<std::string>& positionalArgs)
41 {
42 if (positionalArgs.size() < LS_POS_ARG_MIN || positionalArgs.size() > LS_POS_ARG_MAX) {
43 MEDIA_ERR_LOG("ls command positional args size is invalid. size:%{public}zu", positionalArgs.size());
44 printf("%s invalid arguments.\n", STR_FAIL.c_str());
45 return false;
46 }
47
48 inputPath_ = positionalArgs[0];
49 return true;
50 }
51
ParseFlagsArgs(const std::vector<std::string> & flags)52 bool LSCommand::ParseFlagsArgs(const std::vector<std::string>& flags)
53 {
54 for (const auto& flag : flags) {
55 if (flag == "-l") {
56 longFormat_ = true;
57 } else {
58 MEDIA_ERR_LOG("ls command flags args is invalid. flag:%{public}s", flag.c_str());
59 printf("%s invalid option: %s.\n", STR_FAIL.c_str(), flag.c_str());
60 return false;
61 }
62 }
63
64 return true;
65 }
66
ParseArgs(const std::vector<std::string> & commandArgs)67 bool LSCommand::ParseArgs(const std::vector<std::string>& commandArgs)
68 {
69 vector<string> positionalArgs;
70 vector<string> flags;
71 for (size_t i = 0; i < commandArgs.size(); ++i) {
72 if (MediaFileUtils::StartsWith(commandArgs[i], "-")) {
73 flags.push_back(commandArgs[i]);
74 } else {
75 positionalArgs.push_back(commandArgs[i]);
76 }
77 }
78
79 CHECK_AND_RETURN_RET_LOG(ParsePositionalArgs(positionalArgs), false, "Parse positional args failed");
80 CHECK_AND_RETURN_RET_LOG(ParseFlagsArgs(flags), false, "Parse flags args failed");
81
82 return true;
83 }
84
CheckArgs()85 bool LSCommand::CheckArgs()
86 {
87 if (!longFormat_) {
88 MEDIA_ERR_LOG("ls failed: ls command long format is not enabled.");
89 printf("%s -l option is required for ls command.\n", STR_FAIL.c_str());
90 return false;
91 }
92
93 string reformattedPath;
94 if (!MediatoolCommandUtils::CheckAndReformatPathParam(inputPath_, reformattedPath)) {
95 MEDIA_ERR_LOG("ls failed: path is invalid. path: %{public}s", inputPath_.c_str());
96 printf("%s path invalid: %s.\n", STR_FAIL.c_str(), inputPath_.c_str());
97 return false;
98 }
99
100 lsPath_ = reformattedPath;
101
102 return true;
103 }
104
ToString()105 string LSCommand::ToString()
106 {
107 string result = "ls command, long format: ";
108 result += longFormat_ ? "true" : "false";
109 result += ", path: ";
110 result += lsPath_;
111 return result;
112 }
113
ErrorCodeToMsg(int32_t errorCode)114 string LSCommand::ErrorCodeToMsg(int32_t errorCode)
115 {
116 switch (errorCode) {
117 case E_INVALID_PATH: {
118 std::ostringstream errMsgOss;
119 errMsgOss << "Path error: " << inputPath_;
120 return errMsgOss.str();
121 }
122 default:
123 return "Unknown error";
124 }
125 }
126
PrintEachFile(const nlohmann::json & file)127 static void PrintEachFile(const nlohmann::json& file)
128 {
129 string permissions = (file.contains("permissions") && file["permissions"].is_string()) ?
130 file["permissions"].get<std::string>() : "unknown";
131 std::cout << permissions << " ";
132 nlink_t links = (file.contains("links") && file["links"].is_number()) ? file["links"].get<nlink_t>() : 0;
133 std::cout << links << " ";
134 string owner = (file.contains("owner") && file["owner"].is_string()) ? file["owner"].get<std::string>() : "unknown";
135 std::cout << owner << " ";
136 string group = (file.contains("group") && file["group"].is_string()) ? file["group"].get<std::string>() : "unknown";
137 std::cout << group << " ";
138 long size = (file.contains("size") && file["size"].is_number()) ? file["size"].get<long>() : 0;
139 std::cout << size << " ";
140 string modTime = (file.contains("modTime") && file["modTime"].is_string()) ?
141 file["modTime"].get<std::string>() : "unknown";
142 std::cout << modTime << " ";
143 string fileName = (file.contains("fileName") && file["fileName"].is_string()) ?
144 file["fileName"].get<std::string>() : "unknown";
145 std::cout << fileName << "\n";
146 }
147
PrintFileInfo(const string & fileInfoJSONString)148 int32_t LSCommand::PrintFileInfo(const string& fileInfoJSONString)
149 {
150 if (fileInfoJSONString.empty() || !nlohmann::json::accept(fileInfoJSONString)) {
151 MEDIA_ERR_LOG("File Info JSON invalid");
152 return E_FAIL;
153 }
154
155 nlohmann::json jsonObj = nlohmann::json::parse(fileInfoJSONString);
156 if (!jsonObj.contains("files")) {
157 return E_OK;
158 }
159
160 for (const auto& file : jsonObj["files"]) {
161 PrintEachFile(file);
162 }
163 return E_OK;
164 }
165
Execute()166 int32_t LSCommand::Execute()
167 {
168 std::string lsUriStr = TOOL_LS_PHOTO;
169 Uri lsUri(lsUriStr);
170 DataShare::DataShareValuesBucket values;
171 values.Put(MediaColumn::MEDIA_FILE_PATH, lsPath_);
172 MEDIA_INFO_LOG("mediatool ls execute, %{public}s", this->ToString().c_str());
173 string outString;
174 auto ret = UserFileClient::InsertExt(lsUri, values, outString);
175 if (ret != E_OK) {
176 MEDIA_ERR_LOG("mediatool ls execute failed. ret:%{public}d", ret);
177 return ret;
178 }
179 ret = PrintFileInfo(outString);
180 if (ret != E_OK) {
181 MEDIA_ERR_LOG("print ls info failed. ret:%{public}d", ret);
182 return ret;
183 }
184 return E_OK;
185 }
186
Start(const ExecEnv & env)187 int32_t LSCommand::Start(const ExecEnv &env)
188 {
189 CHECK_AND_RETURN_RET_LOG(ParseArgs(env.commandArgs), Media::E_ERR, "Parse args failed");
190 CHECK_AND_RETURN_RET_LOG(CheckArgs(), Media::E_ERR, "Check args failed");
191 int32_t ret = Execute();
192 if (ret != E_OK) {
193 printf("%s %s\n", STR_FAIL.c_str(), ErrorCodeToMsg(ret).c_str());
194 }
195 return ret;
196 }
197
198 }
199 }
200 }