• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 
16 #include "host_shell_option.h"
17 
18 namespace Hdc {
19 namespace HostShellOption {
FormatParametersToTlv(const string & parameters,const int startPos,string & formatOutput,string & errMsg)20 bool FormatParametersToTlv(const string &parameters, const int startPos, string &formatOutput, string &errMsg)
21 {
22     if (parameters.empty() || startPos >= parameters.size()) {
23         errMsg = "[E003007] Internal error: Invalid option parameters";
24         return false;
25     }
26     int argc = 0;
27     char **argv = Base::SplitCommandToArgs(parameters.c_str() + startPos, &argc);
28     if (argv == nullptr || argc <= 0) {
29         WRITE_LOG(LOG_FATAL, "Failed to split command to args");
30         errMsg = "[E003007] Internal error: Invalid option parameters";
31         return false;
32     }
33     bool ret = false;
34     TlvBuf tb(Base::REGISTERD_TAG_SET);
35     if (!ParameterToTlv(argv, argc, tb, errMsg)) {
36         ret = false;
37     } else if (!CopyToString(tb, formatOutput)) {
38         errMsg = "[E003009] Internal error: Invalid tlv buffer";
39     } else {
40         ret = true;
41     }
42     delete[](reinterpret_cast<char *>(argv));
43     argv = nullptr;
44     return ret;
45 }
46 
CopyToString(const TlvBuf & tlvBuf,string & output)47 bool CopyToString(const TlvBuf &tlvBuf, string &output)
48 {
49     uint32_t bufSize = tlvBuf.GetBufSize();
50     if (bufSize <= 0) {
51         WRITE_LOG(LOG_FATAL, "tlvSize error, size is: %u", bufSize);
52         return false;
53     }
54     uint8_t* tlvs = new uint8_t[bufSize];
55     if (tlvs == nullptr) {
56         WRITE_LOG(LOG_FATAL, "failed to allocate tlvs memory");
57         return false;
58     }
59     bool ret = false;
60     if (tlvBuf.CopyToBuf(tlvs, bufSize)) {
61         output = string(reinterpret_cast<char *>(tlvs), bufSize);
62         ret = true;
63     } else {
64         WRITE_LOG(LOG_FATAL, "tlvs CopyToString failed");
65     }
66     delete[] tlvs;
67     tlvs = nullptr;
68     return ret;
69 }
70 
ParameterToTlv(char ** argv,int argc,TlvBuf & tlvBuf,string & errMsg)71 bool ParameterToTlv(char **argv, int argc, TlvBuf &tlvBuf, string &errMsg)
72 {
73     int skipNext = 0;
74     const string cmdOptionBundle = "-b";
75     string shellCommand = "";
76     bool ret = false;
77     for (int i = 0; i < argc; i++) {
78         if (skipNext > 0) {
79             skipNext--;
80             continue;
81         }
82         if (std::strcmp(argv[i], cmdOptionBundle.c_str()) == 0) {
83             if (i + 1 >= argc) {
84                 WRITE_LOG(LOG_FATAL, "empty bundle name");
85                 errMsg = "[E003005] The parameter is missing, correct your input by referring below:\n"
86                          "Usage: hdc shell [-b bundlename] [COMMAND...]";
87                 break;
88             }
89             string bundlePath = argv[i + 1];
90             if (!TlvAppendParameter(TAG_SHELL_BUNDLE, bundlePath, errMsg, tlvBuf)) {
91                 break;
92             } else {
93                 skipNext++; // skip the next parameter
94             }
95         } else if (strlen(argv[i]) >= 1 && argv[i][0] == '-') {
96             WRITE_LOG(LOG_FATAL, "Unsupport shell option: %s", argv[i]);
97             errMsg = "[E003003] Unsupport shell option: " + std::string(argv[i]);
98             break;
99         } else {
100             shellCommand = ConstructShellCommand(argv, i, argc);
101             if (!TlvAppendParameter(TAG_SHELL_CMD, shellCommand, errMsg, tlvBuf)) {
102                 break;
103             }
104             ret = true;
105             break;
106         }
107     }
108     if (errMsg.empty() && shellCommand.empty()) {
109         errMsg = "[E003002] Unsupport interactive shell command option";
110     }
111     return ret;
112 }
113 
TlvAppendParameter(const uint32_t tag,const string & shellCommand,string & errMsg,TlvBuf & tlvBuf)114 bool TlvAppendParameter(const uint32_t tag, const string &shellCommand, string &errMsg, TlvBuf &tlvBuf)
115 {
116     if (tag == TAG_SHELL_CMD && shellCommand.empty()) {
117         errMsg = "[E003002] Unsupport interactive shell command option";
118         return false;
119     }
120     if (tag == TAG_SHELL_BUNDLE && !Base::CheckBundleName(shellCommand)) {
121         errMsg = "[E003001] Invalid bundle name: " + shellCommand;
122         return false;
123     }
124     if (!tlvBuf.Append(tag, shellCommand.size(),
125         reinterpret_cast<uint8_t *>(const_cast<char *>(shellCommand.c_str())))) {
126         errMsg = "[E003008] Internal error: Failed to add value to TLV buffer";
127         return false;
128     }
129     return true;
130 }
131 
ConstructShellCommand(char ** argv,const int startIndex,const int argc)132 string ConstructShellCommand(char **argv, const int startIndex, const int argc)
133 {
134     if (argv == nullptr || startIndex >= argc) {
135         return "";
136     }
137     string shellCommand;
138     for (int j = startIndex; j < argc; j++) {
139         shellCommand += argv[j];
140         if (j != argc - 1) {
141             shellCommand += " ";
142         }
143     }
144     return shellCommand;
145 }
146 }
147 }
148