• 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_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