• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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