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