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