• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "account_command.h"
16 #include <fstream>
17 #include <getopt.h>
18 #include <sys/stat.h>
19 #include "account_log_wrapper.h"
20 #include "singleton.h"
21 #include "string_ex.h"
22 
23 using namespace OHOS::AAFwk;
24 
25 namespace OHOS {
26 namespace AccountSA {
27 namespace {
28 const char SHORT_OPTIONS[] = "hn:t:i:s:d:p:c:ea";
29 const struct option LONG_OPTIONS[] = {
30     {"help", no_argument, nullptr, 'h'},
31     {"name", required_argument, nullptr, 'n'},
32     {"type", required_argument, nullptr, 't'},
33     {"id", required_argument, nullptr, 'i'},
34     {"shortName", optional_argument, nullptr, 's'},
35     {"disallowedPreinstalledBundles", optional_argument, nullptr, 'd'},
36     {"allowedPreinstalledBundles", optional_argument, nullptr, 'p'},
37     {"constraint", required_argument, nullptr, 'c'},
38     {"enable", no_argument, nullptr, 'e'},
39     {"all", no_argument, nullptr, 'a'},
40     {nullptr, no_argument, nullptr, no_argument}
41 };
42 
43 static const char DEACTIVATE_COMMAND[] = "deactivate";
44 static const char DELETE_COMMAND[] = "delete";
45 static const char SWITCH_COMMAND[] = "switch";
46 static const char DUMP_COMMAND[] = "dump";
47 static const char SET_COMMAND[] = "set";
48 static const char CREATE_COMMAND[] = "create";
49 static constexpr int MIN_ARGUMENT_NUMBER = 2;
50 static constexpr int MAX_ARGUMENT_NUMBER = 4096;
51 }  // namespace
52 
AccountCommand(int argc,char * argv[])53 AccountCommand::AccountCommand(int argc, char *argv[])
54 {
55     ACCOUNT_LOGD("enter");
56     opterr = 0;
57     argc_ = argc;
58     argv_ = argv;
59     name_ = TOOL_NAME;
60 
61     if (argc < MIN_ARGUMENT_NUMBER || argc > MAX_ARGUMENT_NUMBER) {
62         cmd_ = "help";
63         return;
64     }
65     cmd_ = argv[1];
66     for (int i = MIN_ARGUMENT_NUMBER; i < argc; i++) {
67         argList_.push_back(argv[i]);
68     }
69     for (int i = 0; i < argc_; i++) {
70         ACCOUNT_LOGD("argv_[%{public}d]: %{public}s", i, argv_[i]);
71     }
72 }
73 
CreateCommandMap()74 void AccountCommand::CreateCommandMap()
75 {
76     commandMap_ = {
77         {"help", [this] { return this->RunAsHelpCommand(); }},
78         {"create", [this] { return this->RunAsCreateCommand(); }},
79         {"delete", [this] { return this->RunAsDeleteCommand(); }},
80         {"dump", [this] { return this->RunAsDumpCommand(); }},
81         {"set", [this] { return this->RunAsSetCommand(); }},
82         {"switch", [this] { return this->RunAsSwitchCommand(); }},
83         {"deactivate", [this] { return this->RunAsDeactivateCommand(); }},
84     };
85 }
86 
GetCommandErrorMsg() const87 std::string AccountCommand::GetCommandErrorMsg() const
88 {
89     std::string commandErrorMsg =
90         name_ + ": '" + cmd_ + "' is not a valid " + name_ + " command. See '" + name_ + " help'.\n";
91 
92     return commandErrorMsg;
93 }
94 
GetUnknownOptionMsg(std::string & unknownOption) const95 std::string AccountCommand::GetUnknownOptionMsg(std::string& unknownOption) const
96 {
97     std::string result = "";
98 
99     if (optind < 0 || optind > argc_) {
100         return result;
101     }
102 
103     result.append("fail: unknown option");
104     result.append(".\n");
105 
106     return result;
107 }
108 
OnCommand()109 void AccountCommand::OnCommand()
110 {
111     auto respond = commandMap_[cmd_];
112     if (respond == nullptr) {
113         resultReceiver_.append(GetCommandErrorMsg());
114         respond = commandMap_["help"];
115     }
116 
117     respond();
118 }
119 
ExecCommand()120 std::string AccountCommand::ExecCommand()
121 {
122     CreateCommandMap();
123     OnCommand();
124     return resultReceiver_;
125 }
126 
RunAsHelpCommand(void)127 ErrCode AccountCommand::RunAsHelpCommand(void)
128 {
129     ACCOUNT_LOGD("enter");
130     resultReceiver_.append(HELP_MSG);
131     return ERR_OK;
132 }
133 
ParseCreateCommandOpt(std::string & name,std::string & shortName,OsAccountType & osAccountType,CreateOsAccountOptions & options)134 ErrCode AccountCommand::ParseCreateCommandOpt(std::string &name,
135     std::string &shortName, OsAccountType &osAccountType, CreateOsAccountOptions &options)
136 {
137     int counter = 0;
138     ErrCode result = ERR_OK;
139     while (true) {
140         counter++;
141 
142         int option = getopt_long(argc_, argv_, SHORT_OPTIONS, LONG_OPTIONS, nullptr);
143         ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
144 
145         if (option == -1) {
146             if (counter == 1) {
147                 result = RunCommandError(CREATE_COMMAND);
148             }
149             break;
150         }
151 
152         if (option == '?') {
153             result = RunAsCreateCommandMissingOptionArgument();
154             break;
155         }
156 
157         result = RunAsCreateCommandExistentOptionArgument(option, name, shortName, osAccountType, options);
158     }
159     return result;
160 }
161 
RunAsCreateCommand(void)162 ErrCode AccountCommand::RunAsCreateCommand(void)
163 {
164     ACCOUNT_LOGD("enter");
165     ErrCode result = ERR_OK;
166     std::string name = "";
167     std::string shortName = "";
168     OsAccountType osAccountType = END;
169     CreateOsAccountOptions options;
170     result = ParseCreateCommandOpt(name, shortName, osAccountType, options);
171     if (result == ERR_OK) {
172         if (name.size() == 0 || osAccountType == END) {
173             ACCOUNT_LOGD("'acm create' without enough options");
174 
175             if (name.size() == 0) {
176                 resultReceiver_.append(HELP_MSG_NO_NAME_OPTION + "\n");
177             }
178 
179             if (osAccountType == END) {
180                 resultReceiver_.append(HELP_MSG_NO_TYPE_OPTION + "\n");
181             }
182 
183             result = ERR_INVALID_VALUE;
184         }
185     }
186 
187     if (result != ERR_OK && result != ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED) {
188         resultReceiver_.append(HELP_MSG_CREATE);
189     } else {
190         /* create */
191 
192         // make os account info
193         OsAccountInfo osAccountInfo;
194         if (shortName.empty()) {
195             shortName = name;
196         }
197         // create an os account
198         result = OsAccount::GetInstance().CreateOsAccount(name, shortName, osAccountType, osAccountInfo, options);
199         switch (result) {
200             case ERR_OK:
201                 resultReceiver_ = STRING_CREATE_OS_ACCOUNT_OK + "\n";
202                 break;
203             case ERR_OSACCOUNT_SERVICE_MANAGER_NOT_ENABLE_MULTI_ERROR:
204                 resultReceiver_ = "create failed, reason: multiple-os-account feature not enabled\n";
205                 break;
206             default:
207                 resultReceiver_ = STRING_CREATE_OS_ACCOUNT_NG + "\n";
208         }
209     }
210 
211     ACCOUNT_LOGD("result = %{public}d, name = %{public}s, type = %{public}d", result, name.c_str(), osAccountType);
212     return result;
213 }
214 
RunAsDeleteCommand(void)215 ErrCode AccountCommand::RunAsDeleteCommand(void)
216 {
217     ErrCode result = ERR_OK;
218     int id = -1;
219 
220     ParseCommandOpt(DELETE_COMMAND, result, id);
221 
222     if (result != ERR_OK) {
223         resultReceiver_.append(HELP_MSG_DELETE);
224     } else {
225         /* delete */
226 
227         // delete an os account
228         result = OsAccount::GetInstance().RemoveOsAccount(id);
229         if (result == ERR_OK) {
230             resultReceiver_ = STRING_DELETE_OS_ACCOUNT_OK + "\n";
231         } else {
232             resultReceiver_ = STRING_DELETE_OS_ACCOUNT_NG + "\n";
233         }
234     }
235 
236     ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
237     return result;
238 }
239 
RunAsDumpCommand(void)240 ErrCode AccountCommand::RunAsDumpCommand(void)
241 {
242     ErrCode result = ERR_OK;
243     int id = -1;
244 
245     ParseCommandOpt(DUMP_COMMAND, result, id);
246 
247     if (result != ERR_OK) {
248         resultReceiver_.append(HELP_MSG_DUMP);
249     } else {
250         /* dump */
251 
252         // dump state
253         std::vector<std::string> state;
254         result = OsAccount::GetInstance().DumpState(id, state);
255         if (result == ERR_OK) {
256             for (auto info : state) {
257                 resultReceiver_ += info + "\n";
258             }
259         } else {
260             resultReceiver_ = STRING_DUMP_OS_ACCOUNT_NG + "\n";
261         }
262     }
263 
264     ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
265     return result;
266 }
267 
RunCommand(int & counter,ErrCode & result,bool & enable,int & id,std::vector<std::string> & constraints)268 void AccountCommand::RunCommand(
269     int &counter, ErrCode &result, bool &enable, int &id, std::vector<std::string> &constraints)
270 {
271     while (true) {
272         counter++;
273 
274         int option = getopt_long(argc_, argv_, SHORT_OPTIONS, LONG_OPTIONS, nullptr);
275         ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
276 
277         if (option == -1) {
278             if (counter == 1) {
279                 result = RunCommandError(SET_COMMAND);
280             }
281             break;
282         }
283 
284         if (option == '?') {
285             result = RunAsSetCommandMissingOptionArgument();
286             break;
287         }
288 
289         result = RunAsSetCommandExistentOptionArgument(option, id, constraints, enable);
290     }
291 }
292 
RunAsSetCommand(void)293 ErrCode AccountCommand::RunAsSetCommand(void)
294 {
295     ErrCode result = ERR_OK;
296     int counter = 0;
297     int id = -1;
298     std::vector<std::string> constraints;
299     bool enable = false;
300 
301     RunCommand(counter, result, enable, id, constraints);
302 
303     if (result == ERR_OK) {
304         if (id == -1 || constraints.size() == 0) {
305             ACCOUNT_LOGD("'acm set' without enough options");
306 
307             if (id == -1) {
308                 resultReceiver_.append(HELP_MSG_NO_ID_OPTION + "\n");
309             }
310 
311             if (constraints.size() == 0) {
312                 resultReceiver_.append(HELP_MSG_NO_CONSTRAINTS_OPTION + "\n");
313             }
314 
315             result = ERR_INVALID_VALUE;
316         }
317     }
318 
319     if (result != ERR_OK) {
320         resultReceiver_.append(HELP_MSG_SET);
321     } else {
322         /* set */
323 
324         // set os account constraints
325         result = OsAccount::GetInstance().SetOsAccountConstraints(id, constraints, enable);
326         if (result == ERR_OK) {
327             resultReceiver_ = STRING_SET_OS_ACCOUNT_CONSTRAINTS_OK + "\n";
328         } else {
329             resultReceiver_ = STRING_SET_OS_ACCOUNT_CONSTRAINTS_NG + "\n";
330         }
331     }
332 
333     ACCOUNT_LOGD("result = %{public}d, id = %{public}d, enable = %{public}d", result, id, enable);
334     for (auto constraint : constraints) {
335         ACCOUNT_LOGD("constraint = %{public}s", constraint.c_str());
336     }
337 
338     return result;
339 }
340 
ParseCommandOpt(const std::string & command,ErrCode & result,int & id)341 void AccountCommand::ParseCommandOpt(const std::string &command, ErrCode &result, int &id)
342 {
343     int counter = 0;
344     while (true) {
345         counter++;
346 
347         int option = getopt_long(argc_, argv_, SHORT_OPTIONS, LONG_OPTIONS, nullptr);
348         ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
349 
350         if (option == -1) {
351             if (counter == 1) {
352                 result = RunCommandError(command);
353             }
354             break;
355         }
356 
357         if (option == '?') {
358             result = RunAsCommonCommandMissingOptionArgument(command);
359             break;
360         }
361 
362         result = RunAsCommonCommandExistentOptionArgument(option, id);
363     }
364 }
365 
RunAsSwitchCommand(void)366 ErrCode AccountCommand::RunAsSwitchCommand(void)
367 {
368     ErrCode result = ERR_OK;
369     int id = -1;
370     ParseCommandOpt(SWITCH_COMMAND, result, id);
371 
372     if (result != ERR_OK) {
373         resultReceiver_.append(HELP_MSG_SWITCH);
374     } else {
375         /* switch */
376 
377         // switch an os account
378         result = OsAccount::GetInstance().ActivateOsAccount(id);
379         if (result == ERR_OK) {
380             resultReceiver_ = STRING_SWITCH_OS_ACCOUNT_OK + "\n";
381         } else {
382             resultReceiver_ = STRING_SWITCH_OS_ACCOUNT_NG + "\n";
383         }
384     }
385 
386     ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
387     return result;
388 }
389 
RunAsDeactivateCommand(void)390 ErrCode AccountCommand::RunAsDeactivateCommand(void)
391 {
392     ErrCode result = ERR_OK;
393     int id = -1;
394 
395     ParseCommandOpt(DEACTIVATE_COMMAND, result, id);
396 
397     if (result != ERR_OK) {
398         resultReceiver_.append(HELP_MSG_DEACTIVATE);
399     } else if (id != -1) {
400         /* deactivate */
401 
402         // deactivate an os account
403         result = OsAccount::GetInstance().DeactivateOsAccount(id);
404         if (result == ERR_OK) {
405             resultReceiver_ = STRING_DEACTIVATE_OS_ACCOUNT_OK + "\n";
406         } else {
407             resultReceiver_ = STRING_DEACTIVATE_OS_ACCOUNT_NG + "\n";
408         }
409     } else {
410         result = OsAccount::GetInstance().DeactivateAllOsAccounts();
411         if (result == ERR_OK) {
412             resultReceiver_ = STRING_DEACTIVATE_ALL_OS_ACCOUNTS_OK + "\n";
413         } else {
414             resultReceiver_ = STRING_DEACTIVATE_ALL_OS_ACCOUNTS_NG + "\n";
415         }
416     }
417 
418     ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
419 
420     return result;
421 }
422 
RunAsCreateCommandMissingOptionArgument(void)423 ErrCode AccountCommand::RunAsCreateCommandMissingOptionArgument(void)
424 {
425     ErrCode result = ERR_OK;
426 
427     switch (optopt) {
428         case 'n': {
429             // 'acm create -n <name>' with no argument: acm create -n
430             // 'acm create --name <name>' with no argument: acm create --name
431             ACCOUNT_LOGD("'acm create -n' with no argument.");
432 
433             resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
434             result = ERR_INVALID_VALUE;
435             break;
436         }
437         case 't': {
438             // 'acm create -t <type>' with no argument: acm create -t
439             // 'acm create --type <type>' with no argument: acm create --type
440             ACCOUNT_LOGD("'acm create -t' with no argument.");
441 
442             resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
443 
444             result = ERR_INVALID_VALUE;
445             break;
446         }
447         default: {
448             // 'acm create' with an unknown option: acm create -x
449             // 'acm create' with an unknown option: acm create -xxx
450             std::string unknownOption = "";
451             std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
452 
453             ACCOUNT_LOGD("'acm create' with an unknown option.");
454 
455             resultReceiver_.append(unknownOptionMsg);
456             result = ERR_INVALID_VALUE;
457             break;
458         }
459     }
460 
461     ACCOUNT_LOGD("end, result = %{public}d", result);
462     return result;
463 }
464 
RunAsCreateCommandExistentOptionArgument(const int & option,std::string & name,std::string & shortName,OsAccountType & type,CreateOsAccountOptions & options)465 ErrCode AccountCommand::RunAsCreateCommandExistentOptionArgument(const int &option, std::string &name,
466     std::string &shortName, OsAccountType &type, CreateOsAccountOptions &options)
467 {
468     ErrCode result = ERR_OK;
469 
470     switch (option) {
471         case 'h': {
472             // 'acm create -h'
473             // 'acm create --help'
474             result = ERR_INVALID_VALUE;
475             break;
476         }
477         case 'n': {
478             // 'acm create -n <name>'
479             // 'acm create --name <name>'
480             name = optarg;
481             break;
482         }
483         case 't': {
484             // 'acm create -t <type>'
485             // 'acm create --type <type>'
486             result = AnalyzeTypeArgument(type);
487             break;
488         }
489         case 's': {
490             // 'acm create -s <shortName>'
491             // 'acm create --shortName <shortName>'
492             shortName = optarg;
493             break;
494         }
495         case 'd': {
496             // 'acm create -d <disallowedPreinstalledBundles>'
497             // 'acm create --disallowedPreinstalledBundles <disallowedPreinstalledBundles>'
498             result = AnalyzeListArgument(options.disallowedHapList);
499             break;
500         }
501         case 'p': {
502             // 'acm create -p <allowedPreinstalledBundles>'
503             // 'acm create --allowedPreinstalledBundles <allowedPreinstalledBundles>'
504             std::vector<std::string> list = {};
505             result = AnalyzeListArgument(list);
506             options.allowedHapList = std::make_optional<std::vector<std::string>>(list);
507             break;
508         }
509         default: {
510             break;
511         }
512     }
513 
514     ACCOUNT_LOGD("end, result = %{public}d", result);
515     return result;
516 }
517 
RunAsCommonCommandMissingOptionArgument(const std::string & command)518 ErrCode AccountCommand::RunAsCommonCommandMissingOptionArgument(const std::string &command)
519 {
520     ErrCode result = ERR_OK;
521 
522     switch (optopt) {
523         case 'i': {
524             // 'acm command -i <id>' with no argument: acm command -i
525             // 'acm command --id <id>' with no argument: acm command --id
526             ACCOUNT_LOGD("'acm %{public}s -i' with no argument.", command.c_str());
527 
528             resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
529             result = ERR_INVALID_VALUE;
530             break;
531         }
532         default: {
533             // 'acm delete' with an unknown option: acm delete -x
534             // 'acm delete' with an unknown option: acm delete -xxx
535             std::string unknownOption = "";
536             std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
537 
538             ACCOUNT_LOGD("'acm %{public}s' with an unknown option.",  command.c_str());
539 
540             resultReceiver_.append(unknownOptionMsg);
541             result = ERR_INVALID_VALUE;
542             break;
543         }
544     }
545     ACCOUNT_LOGD("end, result = %{public}d", result);
546     return result;
547 }
548 
RunCommandError(const std::string & command)549 ErrCode AccountCommand::RunCommandError(const std::string &command)
550 {
551     ErrCode result = ERR_OK;
552 
553     if (optind < 0 || optind >= argc_) {
554         ACCOUNT_LOGD("optind %{public}d invalid", optind);
555         return ERR_INVALID_VALUE;
556     }
557 
558     // When scanning the first argument
559     if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
560         // 'acm command' with no option: acm command
561         // 'acm command' with a wrong argument: acm command xxx
562         ACCOUNT_LOGD("'acm %{public}s' with no option.", command.c_str());
563 
564         resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
565         result = ERR_INVALID_VALUE;
566     }
567 
568     ACCOUNT_LOGD("end, result = %{public}d", result);
569 
570     return result;
571 }
572 
RunAsSetCommandMissingOptionArgument(void)573 ErrCode AccountCommand::RunAsSetCommandMissingOptionArgument(void)
574 {
575     ErrCode result = ERR_OK;
576 
577     switch (optopt) {
578         case 'i': {
579             // 'acm set -i <id>' with no argument: acm set -i
580             // 'acm set --id <id>' with no argument: acm set --id
581             ACCOUNT_LOGD("'acm set -i' with no argument.");
582 
583             resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
584             result = ERR_INVALID_VALUE;
585             break;
586         }
587         case 'c': {
588             // 'acm set -c <constraints>' with no argument: acm set -c
589             // 'acm set --constraint <constraints>' with no argument: acm set --constraint
590             ACCOUNT_LOGD("'acm set -c' with no argument.");
591 
592             resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
593             result = ERR_INVALID_VALUE;
594             break;
595         }
596         default: {
597             // 'acm set' with an unknown option: acm set -x
598             // 'acm set' with an unknown option: acm set -xxx
599             std::string unknownOption = "";
600             std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
601 
602             ACCOUNT_LOGD("'set dump' with an unknown option.");
603 
604             resultReceiver_.append(unknownOptionMsg);
605             result = ERR_INVALID_VALUE;
606             break;
607         }
608     }
609     ACCOUNT_LOGD("end, result = %{public}d", result);
610     return result;
611 }
612 
RunAsSetCommandExistentOptionArgument(const int & option,int & id,std::vector<std::string> & constraints,bool & enable)613 ErrCode AccountCommand::RunAsSetCommandExistentOptionArgument(
614     const int &option, int &id, std::vector<std::string> &constraints, bool &enable)
615 {
616     ErrCode result = ERR_OK;
617 
618     switch (option) {
619         case 'h': {
620             // 'acm set -h'
621             // 'acm set --help'
622             result = ERR_INVALID_VALUE;
623             break;
624         }
625         case 'i': {
626             // 'acm set -i <id>'
627             // 'acm set --id <id>'
628             result = AnalyzeLocalIdArgument(id);
629             break;
630         }
631         case 'c': {
632             // 'acm set -c <constraints>'
633             // 'acm set --constraint <constraints>'
634             result = AnalyzeConstraintArgument(constraints);
635             break;
636         }
637         case 'e': {
638             // 'acm set -e'
639             // 'acm set --enable'
640             enable = true;
641             break;
642         }
643         default: {
644             break;
645         }
646     }
647 
648     ACCOUNT_LOGD("end, result = %{public}d, id = %{public}d", result, id);
649     return result;
650 }
651 
RunAsCommonCommandExistentOptionArgument(const int & option,int & id)652 ErrCode AccountCommand::RunAsCommonCommandExistentOptionArgument(const int &option, int &id)
653 {
654     ErrCode result = ERR_OK;
655 
656     switch (option) {
657         case 'h': {
658             // 'acm command -h'
659             // 'acm command --help'
660             // command includes stop, switch, deactivate, dump, delete
661             result = ERR_INVALID_VALUE;
662             break;
663         }
664         case 'i': {
665             // 'acm command -i <id>'
666             // 'acm command --id <id>
667             // command includes stop, switch, deactivate, dump, delete
668             result = AnalyzeLocalIdArgument(id);
669             break;
670         }
671         default: {
672             break;
673         }
674     }
675     ACCOUNT_LOGD("end, result = %{public}d, id = %{public}d", result, id);
676     return result;
677 }
678 
AnalyzeTypeArgument(OsAccountType & type)679 ErrCode AccountCommand::AnalyzeTypeArgument(OsAccountType &type)
680 {
681     ErrCode result = ERR_OK;
682     std::string typeByUser = optarg;
683 
684     if (typeByUser == "admin") {
685         type = OsAccountType::ADMIN;
686     } else if (typeByUser == "normal") {
687         type = OsAccountType::NORMAL;
688     } else if (typeByUser == "guest") {
689         type = OsAccountType::GUEST;
690     } else if (typeByUser == "private") {
691         type = OsAccountType::PRIVATE;
692     } else if (typeByUser == "maintenance") {
693         type = OsAccountType::MAINTENANCE;
694     } else {
695         resultReceiver_.append(HELP_MSG_INVALID_TYPE_ARGUMENT + "\n");
696         result = ERR_INVALID_VALUE;
697     }
698 
699     return result;
700 }
701 
IsExistFile(const std::string & path)702 static bool IsExistFile(const std::string &path)
703 {
704     if (path.empty()) {
705         return false;
706     }
707 
708     struct stat buf = {};
709     if (stat(path.c_str(), &buf) != 0) {
710         return false;
711     }
712 
713     return S_ISREG(buf.st_mode);
714 }
715 
GetListByPath(const std::string & path,std::vector<std::string> & list)716 static ErrCode GetListByPath(const std::string &path, std::vector<std::string> &list)
717 {
718     if (!IsExistFile(path)) {
719         ACCOUNT_LOGE("cannot find file, path = %{public}s", path.c_str());
720         return ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED;
721     }
722     std::ifstream readFile;
723     readFile.open(path.c_str(), std::ios::in);
724     if (!readFile.is_open()) {
725         ACCOUNT_LOGE("cannot open file, path = %{public}s", path.c_str());
726         return ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED;
727     }
728     std::string str;
729     while (getline(readFile, str)) {
730         ACCOUNT_LOGI("read file, str = %{public}s", str.c_str());
731         list.emplace_back(str);
732     }
733     readFile.close();
734     return ERR_OK;
735 }
736 
AnalyzeListArgument(std::vector<std::string> & list)737 ErrCode AccountCommand::AnalyzeListArgument(std::vector<std::string> &list)
738 {
739     std::string listPath = optarg;
740     return GetListByPath(listPath, list);
741 }
742 
AnalyzeLocalIdArgument(int & id)743 ErrCode AccountCommand::AnalyzeLocalIdArgument(int &id)
744 {
745     std::string idByUser = optarg;
746     if (!StrToInt(idByUser, id)) {
747         resultReceiver_.append(HELP_MSG_INVALID_ID_ARGUMENT + "\n");
748         return ERR_INVALID_VALUE;
749     }
750 
751     return ERR_OK;
752 }
753 
AnalyzeConstraintArgument(std::vector<std::string> & constraints)754 ErrCode AccountCommand::AnalyzeConstraintArgument(std::vector<std::string> &constraints)
755 {
756     std::string constraintsByUser = optarg;
757     ACCOUNT_LOGD("constraintsByUser = %{public}s", constraintsByUser.c_str());
758 
759     constraints.clear();
760     std::string constraint = "";
761     std::string delimiter = ",";
762     size_t last = 0;
763     size_t next = 0;
764 
765     while ((next = constraintsByUser.find(delimiter, last)) != std::string::npos) {
766         constraint = constraintsByUser.substr(last, next - last);
767         ACCOUNT_LOGD("constraint = %{public}s", constraint.c_str());
768 
769         constraints.emplace_back(constraint);
770         last = next + 1;
771     }
772     constraint = constraintsByUser.substr(last);
773     ACCOUNT_LOGD("constraint = %{public}s", constraint.c_str());
774     constraints.emplace_back(constraint);
775 
776     return ERR_OK;
777 }
778 }  // namespace AccountSA
779 }  // namespace OHOS