1 /*
2  * Copyright (c) 2022-2024 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 
16 #ifndef BACKUP_TOOL_ENABLE
main()17 int main()
18 {
19     return 0;
20 }
21 #else
22 
23 #include "errors.h"
24 #include "tools_op.h"
25 #include "tools_op_backup.h"
26 #include "tools_op_check_sa.h"
27 #include "tools_op_help.h"
28 #include "tools_op_restore.h"
29 #include "tools_op_restore_async.h"
30 #include "tools_op_incremental_backup.h"
31 #include "tools_op_incremental_restore.h"
32 #include "tools_op_incremental_restore_async.h"
33 
34 #include <algorithm>
35 #include <cstddef>
36 #include <cstdio>
37 #include <getopt.h>
38 #include <iostream>
39 #include <optional>
40 #include <sstream>
41 
42 namespace OHOS::FileManagement::Backup {
43 using namespace std;
44 
GetArgsMap(int argc,char * const argv[],const vector<ToolsOp::CmdInfo> & argList)45 optional<map<string, vector<string>>> GetArgsMap(int argc, char *const argv[], const vector<ToolsOp::CmdInfo> &argList)
46 {
47     int i = 0;
48     map<int, string> mapOptToName;
49     vector<struct option> vecLongOptions;
50     for (auto &&arg : argList) {
51         mapOptToName[i] = arg.paramName;
52         vecLongOptions.emplace_back(option {
53             .name = arg.paramName.c_str(),
54             .has_arg = required_argument,
55             .flag = nullptr,
56             .val = i++,
57         });
58     }
59     vecLongOptions.emplace_back(option {nullptr, 0, nullptr, 0});
60 
61     int opt = 0;
62     int options_index = 0;
63     map<string, vector<string>> mapArgToVals;
64     while ((opt = getopt_long(argc, argv, "", vecLongOptions.data(), &options_index)) != -1) {
65         if (opt == '?') {
66             // "我们匹配到了一个奇怪的命令 返回 nullopt,getopt_long 在opterr 未被赋值0时 会自动打印未被定义参数到终端"
67             return nullopt;
68         }
69         string argName = mapOptToName[opt];
70         if (mapArgToVals.find(argName) != mapArgToVals.end() && argList[opt].repeatable == true) {
71             mapArgToVals[argName].emplace_back(optarg);
72         } else if (mapArgToVals.find(argName) != mapArgToVals.end()) {
73             fprintf(stderr, "%s can only be entered once, but you repeat it.\n", argName.c_str());
74             return nullopt;
75         } else {
76             mapArgToVals.emplace(argName, vector<string> {optarg});
77         }
78     }
79     return mapArgToVals;
80 }
81 
ToolRegister()82 void ToolRegister()
83 {
84     OHOS::FileManagement::Backup::BackUpRegister();
85     OHOS::FileManagement::Backup::HelpRegister();
86     OHOS::FileManagement::Backup::CheckSaRegister();
87     OHOS::FileManagement::Backup::RestoreRegister();
88     OHOS::FileManagement::Backup::RestoreAsyncRegister();
89     OHOS::FileManagement::Backup::IncrementalBackUpRegister();
90     OHOS::FileManagement::Backup::IncrementalRestoreRegister();
91     OHOS::FileManagement::Backup::IncrementalRestoreAsyncRegister();
92 }
93 
ParseOpAndExecute(const int argc,char * const argv[])94 int ParseOpAndExecute(const int argc, char *const argv[])
95 {
96     // 注册下命令
97     ToolRegister();
98     int flag = -1;
99     for (int i = 1; i < argc; i++) {
100         // 暂存 {argv[1]...argv[i]};
101         vector<string_view> curOp;
102         for (int j = 1; j <= i; ++j) {
103             curOp.emplace_back(argv[j]);
104         }
105 
106         // 尝试匹配当前命令,成功后执行
107         auto tryOpSucceed = [&curOp](const ToolsOp &op) { return op.TryMatch(curOp); };
108         auto &&opeartions = ToolsOp::GetAllOperations();
109         auto matchedOp = find_if(opeartions.begin(), opeartions.end(), tryOpSucceed);
110         if (matchedOp != opeartions.end()) {
111             vector<ToolsOp::CmdInfo> argList = matchedOp->GetParams();
112             optional<map<string, vector<string>>> mapNameToArgs = GetArgsMap(argc, argv, argList);
113             if (mapNameToArgs.has_value()) {
114                 flag = matchedOp->Execute(mapNameToArgs.value());
115             }
116         }
117     }
118     if (flag != 0) {
119         printf("backup_tool: missing operand\nTry 'backup_tool help' for more information.\n");
120     }
121     return flag;
122 }
123 } // namespace OHOS::FileManagement::Backup
124 
main(int argc,char * const argv[])125 int main(int argc, char *const argv[])
126 {
127     return OHOS::FileManagement::Backup::ParseOpAndExecute(argc, argv);
128 }
129 
130 #endif