1 /*
2 * Copyright (c) 2021-2022 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 <getopt.h>
17 #include "account_log_wrapper.h"
18 #include "singleton.h"
19
20 using namespace OHOS::AAFwk;
21
22 namespace OHOS {
23 namespace AccountSA {
24 namespace {
25 const std::string SHORT_OPTIONS = "hn:t:i:c:ea";
26 const struct option LONG_OPTIONS[] = {
27 {"help", no_argument, nullptr, 'h'},
28 {"name", required_argument, nullptr, 'n'},
29 {"type", required_argument, nullptr, 't'},
30 {"id", required_argument, nullptr, 'i'},
31 {"constraint", required_argument, nullptr, 'c'},
32 {"enable", no_argument, nullptr, 'e'},
33 {"all", no_argument, nullptr, 'a'},
34 };
35 } // namespace
36
AccountCommand(int argc,char * argv[])37 AccountCommand::AccountCommand(int argc, char *argv[]) : ShellCommand(argc, argv, TOOL_NAME)
38 {
39 ACCOUNT_LOGD("enter");
40
41 for (int i = 0; i < argc_; i++) {
42 ACCOUNT_LOGD("argv_[%{public}d]: %{public}s", i, argv_[i]);
43 }
44 }
45
CreateCommandMap()46 ErrCode AccountCommand::CreateCommandMap()
47 {
48 ACCOUNT_LOGD("enter");
49
50 commandMap_ = {
51 {"help", std::bind(&AccountCommand::RunAsHelpCommand, this)},
52 {"create", std::bind(&AccountCommand::RunAsCreateCommand, this)},
53 {"delete", std::bind(&AccountCommand::RunAsDeleteCommand, this)},
54 {"dump", std::bind(&AccountCommand::RunAsDumpCommand, this)},
55 {"set", std::bind(&AccountCommand::RunAsSetCommand, this)},
56 {"switch", std::bind(&AccountCommand::RunAsSwitchCommand, this)},
57 #ifdef ENABLE_MULTIPLE_ACTIVE_ACCOUNTS
58 {"stop", std::bind(&AccountCommand::RunAsStopCommand, this)},
59 #endif // ENABLE_MULTIPLE_ACTIVE_ACCOUNTS
60 };
61
62 return ERR_OK;
63 }
64
CreateMessageMap()65 ErrCode AccountCommand::CreateMessageMap()
66 {
67 ACCOUNT_LOGD("enter");
68
69 return ERR_OK;
70 }
71
init()72 ErrCode AccountCommand::init()
73 {
74 ACCOUNT_LOGD("enter");
75
76 return ERR_OK;
77 }
78
RunAsHelpCommand(void)79 ErrCode AccountCommand::RunAsHelpCommand(void)
80 {
81 ACCOUNT_LOGD("enter");
82
83 resultReceiver_.append(HELP_MSG);
84
85 return ERR_OK;
86 }
87
RunAsCreateCommand(void)88 ErrCode AccountCommand::RunAsCreateCommand(void)
89 {
90 ACCOUNT_LOGD("enter");
91
92 ErrCode result = ERR_OK;
93
94 int counter = 0;
95
96 std::string name = "";
97 OsAccountType osAccountType = static_cast<OsAccountType>(-1);
98
99 while (true) {
100 counter++;
101
102 int option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
103 ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
104
105 if (option == -1) {
106 if (counter == 1) {
107 result = RunAsCreateCommandError();
108 }
109 break;
110 }
111
112 if (option == '?') {
113 result = RunAsCreateCommandMissingOptionArgument();
114 break;
115 }
116
117 result = RunAsCreateCommandExistentOptionArgument(option, name, osAccountType);
118 }
119
120 if (result == ERR_OK) {
121 if (name.size() == 0 || osAccountType == static_cast<OsAccountType>(-1)) {
122 ACCOUNT_LOGD("'acm create' without enough options");
123
124 if (name.size() == 0) {
125 resultReceiver_.append(HELP_MSG_NO_NAME_OPTION + "\n");
126 }
127
128 if (osAccountType == static_cast<OsAccountType>(-1)) {
129 resultReceiver_.append(HELP_MSG_NO_TYPE_OPTION + "\n");
130 }
131
132 result = ERR_INVALID_VALUE;
133 }
134 }
135
136 if (result != ERR_OK) {
137 resultReceiver_.append(HELP_MSG_CREATE);
138 } else {
139 /* create */
140
141 // make os account info
142 OsAccountInfo osAccountInfo;
143
144 // create an os account
145 result = OsAccount::GetInstance().CreateOsAccount(name, osAccountType, osAccountInfo);
146 if (result == ERR_OK) {
147 resultReceiver_ = STRING_CREATE_OS_ACCOUNT_OK + "\n";
148 } else {
149 resultReceiver_ = STRING_CREATE_OS_ACCOUNT_NG + "\n";
150 }
151 }
152
153 ACCOUNT_LOGD("result = %{public}d, name = %{public}s, type = %{public}d", result, name.c_str(), osAccountType);
154
155 return result;
156 }
157
RunAsDeleteCommand(void)158 ErrCode AccountCommand::RunAsDeleteCommand(void)
159 {
160 ACCOUNT_LOGD("enter");
161
162 ErrCode result = ERR_OK;
163
164 int counter = 0;
165
166 int id = -1;
167
168 while (true) {
169 counter++;
170
171 int option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
172 ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
173
174 if (option == -1) {
175 if (counter == 1) {
176 result = RunAsDeleteCommandError();
177 }
178 break;
179 }
180
181 if (option == '?') {
182 result = RunAsDeleteCommandMissingOptionArgument();
183 break;
184 }
185
186 result = RunAsDeleteCommandExistentOptionArgument(option, id);
187 }
188
189 if (result != ERR_OK) {
190 resultReceiver_.append(HELP_MSG_DELETE);
191 } else {
192 /* delete */
193
194 // delete an os account
195 result = OsAccount::GetInstance().RemoveOsAccount(id);
196 if (result == ERR_OK) {
197 resultReceiver_ = STRING_DELETE_OS_ACCOUNT_OK + "\n";
198 } else {
199 resultReceiver_ = STRING_DELETE_OS_ACCOUNT_NG + "\n";
200 }
201 }
202
203 ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
204
205 return result;
206 }
207
RunAsDumpCommand(void)208 ErrCode AccountCommand::RunAsDumpCommand(void)
209 {
210 ACCOUNT_LOGD("enter");
211
212 ErrCode result = ERR_OK;
213
214 int counter = 0;
215
216 int id = -1;
217
218 while (true) {
219 counter++;
220
221 int option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
222 ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
223
224 if (option == -1) {
225 if (counter == 1) {
226 result = RunAsDumpCommandError();
227 }
228 break;
229 }
230
231 if (option == '?') {
232 result = RunAsDumpCommandMissingOptionArgument();
233 break;
234 }
235
236 result = RunAsDumpCommandExistentOptionArgument(option, id);
237 }
238
239 if (result != ERR_OK) {
240 resultReceiver_.append(HELP_MSG_DUMP);
241 } else {
242 /* dump */
243
244 // dump state
245 std::vector<std::string> state;
246 result = OsAccount::GetInstance().DumpState(id, state);
247 if (result == ERR_OK) {
248 for (auto info : state) {
249 resultReceiver_ += info + "\n";
250 }
251 } else {
252 resultReceiver_ = STRING_DUMP_OS_ACCOUNT_NG + "\n";
253 }
254 }
255
256 ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
257
258 return result;
259 }
260
RunAsSetCommand(void)261 ErrCode AccountCommand::RunAsSetCommand(void)
262 {
263 ACCOUNT_LOGD("enter");
264
265 ErrCode result = ERR_OK;
266
267 int counter = 0;
268
269 int id = -1;
270 std::vector<std::string> constraints;
271 bool enable = false;
272
273 while (true) {
274 counter++;
275
276 int option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
277 ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
278
279 if (option == -1) {
280 if (counter == 1) {
281 result = RunAsSetCommandError();
282 }
283 break;
284 }
285
286 if (option == '?') {
287 result = RunAsSetCommandMissingOptionArgument();
288 break;
289 }
290
291 result = RunAsSetCommandExistentOptionArgument(option, id, constraints, enable);
292 }
293
294 if (result == ERR_OK) {
295 if (id == -1 || constraints.size() == 0) {
296 ACCOUNT_LOGD("'acm set' without enough options");
297
298 if (id == -1) {
299 resultReceiver_.append(HELP_MSG_NO_ID_OPTION + "\n");
300 }
301
302 if (constraints.size() == 0) {
303 resultReceiver_.append(HELP_MSG_NO_CONSTRAINTS_OPTION + "\n");
304 }
305
306 result = ERR_INVALID_VALUE;
307 }
308 }
309
310 if (result != ERR_OK) {
311 resultReceiver_.append(HELP_MSG_SET);
312 } else {
313 /* set */
314
315 // set os account constraints
316 result = OsAccount::GetInstance().SetOsAccountConstraints(id, constraints, enable);
317 if (result == ERR_OK) {
318 resultReceiver_ = STRING_SET_OS_ACCOUNT_CONSTRAINTS_OK + "\n";
319 } else {
320 resultReceiver_ = STRING_SET_OS_ACCOUNT_CONSTRAINTS_NG + "\n";
321 }
322 }
323
324 ACCOUNT_LOGD("result = %{public}d, id = %{public}d, enable = %{public}d", result, id, enable);
325 for (auto constraint : constraints) {
326 ACCOUNT_LOGD("constraint = %{public}s", constraint.c_str());
327 }
328
329 return result;
330 }
331
RunAsSwitchCommand(void)332 ErrCode AccountCommand::RunAsSwitchCommand(void)
333 {
334 ACCOUNT_LOGD("enter");
335
336 ErrCode result = ERR_OK;
337
338 int counter = 0;
339
340 int id = -1;
341
342 while (true) {
343 counter++;
344
345 int option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
346 ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
347
348 if (option == -1) {
349 if (counter == 1) {
350 result = RunAsSwitchCommandError();
351 }
352 break;
353 }
354
355 if (option == '?') {
356 result = RunAsSwitchCommandMissingOptionArgument();
357 break;
358 }
359
360 result = RunAsSwitchCommandExistentOptionArgument(option, id);
361 }
362
363 if (result != ERR_OK) {
364 resultReceiver_.append(HELP_MSG_SWITCH);
365 } else {
366 /* switch */
367
368 // switch an os account
369 result = OsAccount::GetInstance().ActivateOsAccount(id);
370 if (result == ERR_OK) {
371 resultReceiver_ = STRING_SWITCH_OS_ACCOUNT_OK + "\n";
372 } else {
373 resultReceiver_ = STRING_SWITCH_OS_ACCOUNT_NG + "\n";
374 }
375 }
376
377 ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
378
379 return result;
380 }
381
RunAsStopCommand(void)382 ErrCode AccountCommand::RunAsStopCommand(void)
383 {
384 ACCOUNT_LOGD("enter");
385
386 ErrCode result = ERR_OK;
387
388 int counter = 0;
389
390 int id = -1;
391
392 while (true) {
393 counter++;
394
395 int option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
396 ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
397
398 if (option == -1) {
399 if (counter == 1) {
400 result = RunAsStopCommandError();
401 }
402 break;
403 }
404
405 if (option == '?') {
406 result = RunAsStopCommandMissingOptionArgument();
407 break;
408 }
409
410 result = RunAsStopCommandExistentOptionArgument(option, id);
411 }
412
413 if (result != ERR_OK) {
414 resultReceiver_.append(HELP_MSG_STOP);
415 } else {
416 /* stop */
417
418 // stop an os account
419 result = OsAccount::GetInstance().StopOsAccount(id);
420 if (result == ERR_OK) {
421 resultReceiver_ = STRING_STOP_OS_ACCOUNT_OK + "\n";
422 } else {
423 resultReceiver_ = STRING_STOP_OS_ACCOUNT_NG + "\n";
424 }
425 }
426
427 ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
428
429 return result;
430 }
431
RunAsCreateCommandError(void)432 ErrCode AccountCommand::RunAsCreateCommandError(void)
433 {
434 ACCOUNT_LOGD("enter");
435
436 ErrCode result = ERR_OK;
437
438 if (optind < 0 || optind >= argc_) {
439 return ERR_INVALID_VALUE;
440 }
441
442 // When scanning the first argument
443 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
444 // 'acm create' with no option: acm create
445 // 'acm create' with a wrong argument: acm create xxx
446 ACCOUNT_LOGD("'acm create' with no option.");
447
448 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
449 result = ERR_INVALID_VALUE;
450 }
451
452 ACCOUNT_LOGD("end, result = %{public}d", result);
453
454 return result;
455 }
456
RunAsCreateCommandMissingOptionArgument(void)457 ErrCode AccountCommand::RunAsCreateCommandMissingOptionArgument(void)
458 {
459 ACCOUNT_LOGD("enter");
460
461 ErrCode result = ERR_OK;
462
463 switch (optopt) {
464 case 'n': {
465 // 'acm create -n <name>' with no argument: acm create -n
466 // 'acm create --name <name>' with no argument: acm create --name
467 ACCOUNT_LOGD("'acm create -n' with no argument.");
468
469 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
470 result = ERR_INVALID_VALUE;
471 break;
472 }
473 case 't': {
474 // 'acm create -t <type>' with no argument: acm create -t
475 // 'acm create --type <type>' with no argument: acm create --type
476 ACCOUNT_LOGD("'acm create -t' with no argument.");
477
478 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
479
480 result = ERR_INVALID_VALUE;
481 break;
482 }
483 default: {
484 // 'acm create' with an unknown option: acm create -x
485 // 'acm create' with an unknown option: acm create -xxx
486 std::string unknownOption = "";
487 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
488
489 ACCOUNT_LOGD("'acm create' with an unknown option.");
490
491 resultReceiver_.append(unknownOptionMsg);
492 result = ERR_INVALID_VALUE;
493 break;
494 }
495 }
496
497 ACCOUNT_LOGD("end, result = %{public}d", result);
498
499 return result;
500 }
501
RunAsCreateCommandExistentOptionArgument(const int & option,std::string & name,OsAccountType & type)502 ErrCode AccountCommand::RunAsCreateCommandExistentOptionArgument(
503 const int &option, std::string &name, OsAccountType &type)
504 {
505 ACCOUNT_LOGD("enter");
506
507 ErrCode result = ERR_OK;
508
509 switch (option) {
510 case 'h': {
511 // 'acm create -h'
512 // 'acm create --help'
513 result = ERR_INVALID_VALUE;
514 break;
515 }
516 case 'n': {
517 // 'acm create -n <name>'
518 // 'acm create --name <name>'
519 name = optarg;
520 break;
521 }
522 case 't': {
523 // 'acm create -t <type>'
524 // 'acm create --type <type>'
525 result = AnalyzeTypeArgument(type);
526 break;
527 }
528 default: {
529 break;
530 }
531 }
532
533 ACCOUNT_LOGD("end, result = %{public}d", result);
534
535 return result;
536 }
537
RunAsDeleteCommandError(void)538 ErrCode AccountCommand::RunAsDeleteCommandError(void)
539 {
540 ACCOUNT_LOGD("enter");
541
542 ErrCode result = ERR_OK;
543
544 if (optind < 0 || optind >= argc_) {
545 return ERR_INVALID_VALUE;
546 }
547
548 // When scanning the first argument
549 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
550 // 'acm delete' with no option: acm delete
551 // 'acm delete' with a wrong argument: acm delete xxx
552 ACCOUNT_LOGD("'acm delete' with no option.");
553
554 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
555 result = ERR_INVALID_VALUE;
556 }
557
558 ACCOUNT_LOGD("end, result = %{public}d", result);
559
560 return result;
561 }
562
RunAsDeleteCommandMissingOptionArgument(void)563 ErrCode AccountCommand::RunAsDeleteCommandMissingOptionArgument(void)
564 {
565 ACCOUNT_LOGD("enter");
566
567 ErrCode result = ERR_OK;
568
569 switch (optopt) {
570 case 'i': {
571 // 'acm delete -i <id>' with no argument: acm delete -i
572 // 'acm delete --id <id>' with no argument: acm delete --id
573 ACCOUNT_LOGD("'acm delete -i' with no argument.");
574
575 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
576 result = ERR_INVALID_VALUE;
577 break;
578 }
579 default: {
580 // 'acm delete' with an unknown option: acm delete -x
581 // 'acm delete' with an unknown option: acm delete -xxx
582 std::string unknownOption = "";
583 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
584
585 ACCOUNT_LOGD("'acm delete' with an unknown option.");
586
587 resultReceiver_.append(unknownOptionMsg);
588 result = ERR_INVALID_VALUE;
589 break;
590 }
591 }
592
593 return result;
594 }
595
RunAsDeleteCommandExistentOptionArgument(const int & option,int & id)596 ErrCode AccountCommand::RunAsDeleteCommandExistentOptionArgument(const int &option, int &id)
597 {
598 ACCOUNT_LOGD("enter");
599
600 ErrCode result = ERR_OK;
601
602 switch (option) {
603 case 'h': {
604 // 'acm delete -h'
605 // 'acm delete --help'
606 result = ERR_INVALID_VALUE;
607 break;
608 }
609 case 'i': {
610 // 'acm delete -i <id>'
611 // 'acm delete --id <id>'
612 result = AnalyzeLocalIdArgument(id);
613 break;
614 }
615 default: {
616 break;
617 }
618 }
619
620 return result;
621 }
622
RunAsDumpCommandError(void)623 ErrCode AccountCommand::RunAsDumpCommandError(void)
624 {
625 ACCOUNT_LOGD("enter");
626
627 ErrCode result = ERR_OK;
628
629 if (optind < 0 || optind >= argc_) {
630 return ERR_INVALID_VALUE;
631 }
632
633 // When scanning the first argument
634 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
635 // 'acm dump' with no option: acm dump
636 // 'acm dump' with a wrong argument: acm dump xxx
637 ACCOUNT_LOGD("'acm dump' with no option.");
638
639 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
640 result = ERR_INVALID_VALUE;
641 }
642
643 ACCOUNT_LOGD("end, result = %{public}d", result);
644
645 return result;
646 }
647
RunAsDumpCommandMissingOptionArgument(void)648 ErrCode AccountCommand::RunAsDumpCommandMissingOptionArgument(void)
649 {
650 ACCOUNT_LOGD("enter");
651
652 ErrCode result = ERR_OK;
653
654 switch (optopt) {
655 case 'i': {
656 // 'acm dump -i <id>' with no argument: acm dump -i
657 // 'acm dump --id <id>' with no argument: acm dump --id
658 ACCOUNT_LOGD("'acm dump -i' with no argument.");
659
660 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
661 result = ERR_INVALID_VALUE;
662 break;
663 }
664 default: {
665 // 'acm dump' with an unknown option: acm dump -x
666 // 'acm dump' with an unknown option: acm dump -xxx
667 std::string unknownOption = "";
668 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
669
670 ACCOUNT_LOGD("'acm dump' with an unknown option.");
671
672 resultReceiver_.append(unknownOptionMsg);
673 result = ERR_INVALID_VALUE;
674 break;
675 }
676 }
677
678 return result;
679 }
680
RunAsDumpCommandExistentOptionArgument(const int & option,int & id)681 ErrCode AccountCommand::RunAsDumpCommandExistentOptionArgument(const int &option, int &id)
682 {
683 ACCOUNT_LOGD("enter");
684
685 ErrCode result = ERR_OK;
686
687 switch (option) {
688 case 'h': {
689 // 'acm dump -h'
690 // 'acm dump --help'
691 result = ERR_INVALID_VALUE;
692 break;
693 }
694 case 'a': {
695 // 'acm dump -a'
696 // 'acm dump --all'
697 break;
698 }
699 case 'i': {
700 // 'acm dump -i <id>'
701 // 'acm dump --id <id>'
702 result = AnalyzeLocalIdArgument(id);
703 break;
704 }
705 default: {
706 break;
707 }
708 }
709
710 ACCOUNT_LOGD("end, result = %{public}d, id = %{public}d", result, id);
711
712 return result;
713 }
714
RunAsSetCommandError(void)715 ErrCode AccountCommand::RunAsSetCommandError(void)
716 {
717 ACCOUNT_LOGD("enter");
718
719 ErrCode result = ERR_OK;
720
721 if (optind < 0 || optind >= argc_) {
722 return ERR_INVALID_VALUE;
723 }
724
725 // When scanning the first argument
726 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
727 // 'acm set' with no option: acm set
728 // 'acm set' with a wrong argument: acm set xxx
729 ACCOUNT_LOGD("'acm set' with no option.");
730
731 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
732 result = ERR_INVALID_VALUE;
733 }
734
735 ACCOUNT_LOGD("end, result = %{public}d", result);
736
737 return result;
738 }
739
RunAsSetCommandMissingOptionArgument(void)740 ErrCode AccountCommand::RunAsSetCommandMissingOptionArgument(void)
741 {
742 ACCOUNT_LOGD("enter");
743
744 ErrCode result = ERR_OK;
745
746 switch (optopt) {
747 case 'i': {
748 // 'acm set -i <id>' with no argument: acm set -i
749 // 'acm set --id <id>' with no argument: acm set --id
750 ACCOUNT_LOGD("'acm set -i' with no argument.");
751
752 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
753 result = ERR_INVALID_VALUE;
754 break;
755 }
756 case 'c': {
757 // 'acm set -c <constraints>' with no argument: acm set -c
758 // 'acm set --constraint <constraints>' with no argument: acm set --constraint
759 ACCOUNT_LOGD("'acm set -c' with no argument.");
760
761 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
762 result = ERR_INVALID_VALUE;
763 break;
764 }
765 default: {
766 // 'acm set' with an unknown option: acm set -x
767 // 'acm set' with an unknown option: acm set -xxx
768 std::string unknownOption = "";
769 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
770
771 ACCOUNT_LOGD("'set dump' with an unknown option.");
772
773 resultReceiver_.append(unknownOptionMsg);
774 result = ERR_INVALID_VALUE;
775 break;
776 }
777 }
778
779 return result;
780 }
781
RunAsSetCommandExistentOptionArgument(const int & option,int & id,std::vector<std::string> & constraints,bool & enable)782 ErrCode AccountCommand::RunAsSetCommandExistentOptionArgument(
783 const int &option, int &id, std::vector<std::string> &constraints, bool &enable)
784 {
785 ACCOUNT_LOGD("enter");
786
787 ErrCode result = ERR_OK;
788
789 switch (option) {
790 case 'h': {
791 // 'acm set -h'
792 // 'acm set --help'
793 result = ERR_INVALID_VALUE;
794 break;
795 }
796 case 'i': {
797 // 'acm set -i <id>'
798 // 'acm set --id <id>'
799 result = AnalyzeLocalIdArgument(id);
800 break;
801 }
802 case 'c': {
803 // 'acm set -c <constraints>'
804 // 'acm set --constraint <constraints>'
805 result = AnalyzeConstraintArgument(constraints);
806 break;
807 }
808 case 'e': {
809 // 'acm set -e'
810 // 'acm set --enable'
811 enable = true;
812 break;
813 }
814 default: {
815 break;
816 }
817 }
818
819 ACCOUNT_LOGD("end, result = %{public}d, id = %{public}d", result, id);
820
821 return result;
822 }
823
RunAsSwitchCommandError(void)824 ErrCode AccountCommand::RunAsSwitchCommandError(void)
825 {
826 ACCOUNT_LOGD("enter");
827
828 ErrCode result = ERR_OK;
829
830 if (optind < 0 || optind >= argc_) {
831 return ERR_INVALID_VALUE;
832 }
833
834 // When scanning the first argument
835 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
836 // 'acm switch' with no option: acm switch
837 // 'acm switch' with a wrong argument: acm switch xxx
838 ACCOUNT_LOGD("'acm switch' with no option.");
839
840 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
841 result = ERR_INVALID_VALUE;
842 }
843
844 ACCOUNT_LOGD("end, result = %{public}d", result);
845
846 return result;
847 }
848
RunAsStopCommandError(void)849 ErrCode AccountCommand::RunAsStopCommandError(void)
850 {
851 ACCOUNT_LOGD("enter");
852
853 ErrCode result = ERR_OK;
854
855 if (optind < 0 || optind >= argc_) {
856 return ERR_INVALID_VALUE;
857 }
858
859 // When scanning the first argument
860 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
861 // 'acm stop' with no option: acm stop
862 // 'acm stop' with a wrong argument: acm stop xxx
863 ACCOUNT_LOGD("'acm stop' with no option.");
864
865 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
866 result = ERR_INVALID_VALUE;
867 }
868
869 ACCOUNT_LOGD("end, result = %{public}d", result);
870
871 return result;
872 }
873
RunAsSwitchCommandMissingOptionArgument(void)874 ErrCode AccountCommand::RunAsSwitchCommandMissingOptionArgument(void)
875 {
876 ACCOUNT_LOGD("enter");
877
878 ErrCode result = ERR_OK;
879
880 switch (optopt) {
881 case 'i': {
882 // 'acm switch -i <id>' with no argument: acm switch -i
883 // 'acm switch --id <id>' with no argument: acm switch --id
884 ACCOUNT_LOGD("'acm switch -i' with no argument.");
885
886 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
887 result = ERR_INVALID_VALUE;
888 break;
889 }
890 default: {
891 // 'acm switch' with an unknown option: acm switch -x
892 // 'acm switch' with an unknown option: acm switch -xxx
893 std::string unknownOption = "";
894 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
895
896 ACCOUNT_LOGD("'acm switch' with an unknown option.");
897
898 resultReceiver_.append(unknownOptionMsg);
899 result = ERR_INVALID_VALUE;
900 break;
901 }
902 }
903
904 return result;
905 }
906
RunAsStopCommandMissingOptionArgument(void)907 ErrCode AccountCommand::RunAsStopCommandMissingOptionArgument(void)
908 {
909 ACCOUNT_LOGD("enter");
910
911 ErrCode result = ERR_OK;
912
913 switch (optopt) {
914 case 'i': {
915 // 'acm stop -i <id>' with no argument: acm stop -i
916 // 'acm stop --id <id>' with no argument: acm stop --id
917 ACCOUNT_LOGD("'acm stop -i' with no argument.");
918
919 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
920 result = ERR_INVALID_VALUE;
921 break;
922 }
923 default: {
924 // 'acm stop' with an unknown option: acm stop -x
925 // 'acm stop' with an unknown option: acm stop -xxx
926 std::string unknownOption = "";
927 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
928
929 ACCOUNT_LOGD("'acm stop' with an unknown option.");
930
931 resultReceiver_.append(unknownOptionMsg);
932 result = ERR_INVALID_VALUE;
933 break;
934 }
935 }
936
937 return result;
938 }
939
RunAsSwitchCommandExistentOptionArgument(const int & option,int & id)940 ErrCode AccountCommand::RunAsSwitchCommandExistentOptionArgument(const int &option, int &id)
941 {
942 ACCOUNT_LOGD("enter");
943
944 ErrCode result = ERR_OK;
945
946 switch (option) {
947 case 'h': {
948 // 'acm switch -h'
949 // 'acm switch --help'
950 result = ERR_INVALID_VALUE;
951 break;
952 }
953 case 'i': {
954 // 'acm switch -i <id>'
955 // 'acm switch --id <id>'
956 result = AnalyzeLocalIdArgument(id);
957 break;
958 }
959 default: {
960 break;
961 }
962 }
963
964 return result;
965 }
966
RunAsStopCommandExistentOptionArgument(const int & option,int & id)967 ErrCode AccountCommand::RunAsStopCommandExistentOptionArgument(const int &option, int &id)
968 {
969 ACCOUNT_LOGD("enter");
970
971 ErrCode result = ERR_OK;
972
973 switch (option) {
974 case 'h': {
975 // 'acm stop -h'
976 // 'acm stop --help'
977 result = ERR_INVALID_VALUE;
978 break;
979 }
980 case 'i': {
981 // 'acm stop -i <id>'
982 // 'acm stop --id <id>'
983 result = AnalyzeLocalIdArgument(id);
984 break;
985 }
986 default: {
987 break;
988 }
989 }
990
991 return result;
992 }
993
AnalyzeTypeArgument(OsAccountType & type)994 ErrCode AccountCommand::AnalyzeTypeArgument(OsAccountType &type)
995 {
996 ErrCode result = ERR_OK;
997
998 std::string typeByUser = optarg;
999
1000 if (typeByUser == "admin") {
1001 type = OsAccountType::ADMIN;
1002 } else if (typeByUser == "normal") {
1003 type = OsAccountType::NORMAL;
1004 } else if (typeByUser == "guest") {
1005 type = OsAccountType::GUEST;
1006 } else {
1007 resultReceiver_.append(HELP_MSG_INVALID_TYPE_ARGUMENT + "\n");
1008 result = ERR_INVALID_VALUE;
1009 }
1010
1011 return result;
1012 }
1013
AnalyzeLocalIdArgument(int & id)1014 ErrCode AccountCommand::AnalyzeLocalIdArgument(int &id)
1015 {
1016 std::string idByUser = optarg;
1017 if (idByUser == "0") {
1018 id = 0;
1019 return ERR_OK;
1020 }
1021
1022 if (atoi(optarg) == 0) {
1023 resultReceiver_.append(HELP_MSG_INVALID_ID_ARGUMENT + "\n");
1024 return ERR_INVALID_VALUE;
1025 }
1026
1027 id = atoi(optarg);
1028
1029 return ERR_OK;
1030 }
1031
AnalyzeConstraintArgument(std::vector<std::string> & constraints)1032 ErrCode AccountCommand::AnalyzeConstraintArgument(std::vector<std::string> &constraints)
1033 {
1034 ACCOUNT_LOGD("enter");
1035
1036 std::string constraintsByUser = optarg;
1037 ACCOUNT_LOGD("constraintsByUser = %{public}s", constraintsByUser.c_str());
1038
1039 constraints.clear();
1040 std::string constraint = "";
1041 std::string delimiter = ",";
1042
1043 size_t last = 0;
1044 size_t next = 0;
1045 while ((next = constraintsByUser.find(delimiter, last)) != std::string::npos) {
1046 constraint = constraintsByUser.substr(last, next - last);
1047 ACCOUNT_LOGD("constraint = %{public}s", constraint.c_str());
1048
1049 constraints.emplace_back(constraint);
1050 last = next + 1;
1051 }
1052 constraint = constraintsByUser.substr(last);
1053 ACCOUNT_LOGD("constraint = %{public}s", constraint.c_str());
1054 constraints.emplace_back(constraint);
1055
1056 return ERR_OK;
1057 }
1058 } // namespace AccountSA
1059 } // namespace OHOS
1060