1bae44755Sopenharmony_ci/*
2bae44755Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3bae44755Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4bae44755Sopenharmony_ci * you may not use this file except in compliance with the License.
5bae44755Sopenharmony_ci * You may obtain a copy of the License at
6bae44755Sopenharmony_ci *
7bae44755Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8bae44755Sopenharmony_ci *
9bae44755Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10bae44755Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11bae44755Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bae44755Sopenharmony_ci * See the License for the specific language governing permissions and
13bae44755Sopenharmony_ci * limitations under the License.
14bae44755Sopenharmony_ci */
15bae44755Sopenharmony_ci
16bae44755Sopenharmony_ci#include <getopt.h>
17bae44755Sopenharmony_ci#include <stdint.h>
18bae44755Sopenharmony_ci#include <unistd.h>
19bae44755Sopenharmony_ci#include <stdio.h>
20bae44755Sopenharmony_ci#include <stdlib.h>
21bae44755Sopenharmony_ci#include <limits.h>
22bae44755Sopenharmony_ci#include "securec.h"
23bae44755Sopenharmony_ci#include "syscap_tool.h"
24bae44755Sopenharmony_ci#include "create_pcid.h"
25bae44755Sopenharmony_ci#include "context_tool.h"
26bae44755Sopenharmony_ci
27bae44755Sopenharmony_ci#define SYSCAP_VERSION "2.0.1"
28bae44755Sopenharmony_ci#define OUTPUT_VERSION_LEN 200
29bae44755Sopenharmony_ci#define ENCODE 0
30bae44755Sopenharmony_ci#define DECODE 1
31bae44755Sopenharmony_ci#define STRING_DECODE 2
32bae44755Sopenharmony_ci#define RPCID 3
33bae44755Sopenharmony_ci#define PCID 4
34bae44755Sopenharmony_ci#define PCID_STRING 5
35bae44755Sopenharmony_ci#define RPCID_STRING 6
36bae44755Sopenharmony_ci#define VERSION 7
37bae44755Sopenharmony_ci#define INPUT_FILE 8
38bae44755Sopenharmony_ci#define OUTPUT_FILE 9
39bae44755Sopenharmony_ci#define HELP 10
40bae44755Sopenharmony_ci#define INPUT_FILE_NUM 4
41bae44755Sopenharmony_ci
42bae44755Sopenharmony_cistatic void PrintHelp(void);
43bae44755Sopenharmony_cistatic void PrintVersion(void);
44bae44755Sopenharmony_cistatic void OutputVersion(const char *arg, int opt);
45bae44755Sopenharmony_cistatic void OutputHelp(void);
46bae44755Sopenharmony_ci
47bae44755Sopenharmony_civoid SetBitMap(char *const *argv, int32_t flag, uint16_t *bitMap, char **outputpath);
48bae44755Sopenharmony_ci
49bae44755Sopenharmony_ciint32_t OperateByBitMap(char *const *argv, uint16_t bitMap, char *outputpath);
50bae44755Sopenharmony_ci
51bae44755Sopenharmony_cistatic struct option g_longOptions[] = {
52bae44755Sopenharmony_ci        {"help",           no_argument,       0,  'h' },
53bae44755Sopenharmony_ci        {"version",        no_argument,       0,  'v' },
54bae44755Sopenharmony_ci        {"rpcid",          no_argument,       0,  'R' },
55bae44755Sopenharmony_ci        {"pcid",           no_argument,       0,  'P' },
56bae44755Sopenharmony_ci        {"compare",        required_argument, 0,  'C' },
57bae44755Sopenharmony_ci        {"encode",         no_argument,       0,  'e' },
58bae44755Sopenharmony_ci        {"decode",         no_argument,       0,  'd' },
59bae44755Sopenharmony_ci        {"string",         no_argument,       0,  's' },
60bae44755Sopenharmony_ci        {"input",          required_argument, 0,  'i' },
61bae44755Sopenharmony_ci        {"output",         required_argument, 0,  'o' },
62bae44755Sopenharmony_ci        {0,                0,                 0,  0   }
63bae44755Sopenharmony_ci};
64bae44755Sopenharmony_ci
65bae44755Sopenharmony_cistatic struct {
66bae44755Sopenharmony_ci    char *inputfile;
67bae44755Sopenharmony_ci    char *pcidfile;
68bae44755Sopenharmony_ci    char *rpcidfile;
69bae44755Sopenharmony_ci} g_customerfileinfo;
70bae44755Sopenharmony_ci
71bae44755Sopenharmony_ciint main(int argc, char **argv)
72bae44755Sopenharmony_ci{
73bae44755Sopenharmony_ci    int32_t optIndex;
74bae44755Sopenharmony_ci    int32_t ret;
75bae44755Sopenharmony_ci    uint16_t bitMap = 0x0;
76bae44755Sopenharmony_ci    char curpath[PATH_MAX] = {0};
77bae44755Sopenharmony_ci    g_customerfileinfo.inputfile = NULL;
78bae44755Sopenharmony_ci    g_customerfileinfo.pcidfile = NULL;
79bae44755Sopenharmony_ci    g_customerfileinfo.rpcidfile = NULL;
80bae44755Sopenharmony_ci    char *outputpath = getcwd(curpath, sizeof(curpath));
81bae44755Sopenharmony_ci    if (outputpath == NULL) {
82bae44755Sopenharmony_ci        PRINT_ERR("Get outputpath failed.\n");
83bae44755Sopenharmony_ci        return -1;
84bae44755Sopenharmony_ci    }
85bae44755Sopenharmony_ci
86bae44755Sopenharmony_ci    while (1) {
87bae44755Sopenharmony_ci        int32_t flag = getopt_long(argc, argv, "hvRPC:edsi:o:", g_longOptions, &optIndex);
88bae44755Sopenharmony_ci        if (flag == -1) {
89bae44755Sopenharmony_ci            break;
90bae44755Sopenharmony_ci        }
91bae44755Sopenharmony_ci        if (flag == 'C') {
92bae44755Sopenharmony_ci            if (argc != INPUT_FILE_NUM || optind < 0 || optind >= argc) {  // 4, argc of ./syscap_tool -C f1 f2
93bae44755Sopenharmony_ci                PRINT_ERR("Input file too few or too many.\n");
94bae44755Sopenharmony_ci                return -1;
95bae44755Sopenharmony_ci            }
96bae44755Sopenharmony_ci        }
97bae44755Sopenharmony_ci        SetBitMap(argv, flag, &bitMap, &outputpath);
98bae44755Sopenharmony_ci    }
99bae44755Sopenharmony_ci    ret = OperateByBitMap(argv, bitMap, outputpath);
100bae44755Sopenharmony_ci    if (ret != 0) {
101bae44755Sopenharmony_ci        PRINT_ERR("syscap_tool failed to complete. input: %s\n", g_customerfileinfo.inputfile);
102bae44755Sopenharmony_ci    }
103bae44755Sopenharmony_ci    return ret;
104bae44755Sopenharmony_ci}
105bae44755Sopenharmony_ci
106bae44755Sopenharmony_ciint32_t OperateByBitMap(char *const *argv, uint16_t bitMap, char *outputpath)
107bae44755Sopenharmony_ci{
108bae44755Sopenharmony_ci    int32_t ret = 0;
109bae44755Sopenharmony_ci    switch (bitMap) {
110bae44755Sopenharmony_ci        case 0x109: // 0x109, -Rei inputfile
111bae44755Sopenharmony_ci            ret = RPCIDEncode(g_customerfileinfo.inputfile, outputpath); break;
112bae44755Sopenharmony_ci        case 0x10A: // 0x10A, -Rdi inputfile
113bae44755Sopenharmony_ci            ret = RPCIDDecode(g_customerfileinfo.inputfile, outputpath); break;
114bae44755Sopenharmony_ci        case 0x10D: // 0x10D, -Resi inputfile
115bae44755Sopenharmony_ci            ret = EncodeRpcidscToString(g_customerfileinfo.inputfile, outputpath); break;
116bae44755Sopenharmony_ci        case 0x115: // 0x115, -Pesi inputfile
117bae44755Sopenharmony_ci            ret = EncodePcidscToString(g_customerfileinfo.inputfile, outputpath); break;
118bae44755Sopenharmony_ci        case 0x60:  // 0x60,  -C pcid.txt rpcid.txt
119bae44755Sopenharmony_ci            ret = ComparePcidWithRpcidString(g_customerfileinfo.pcidfile, g_customerfileinfo.rpcidfile, TYPE_FILE);
120bae44755Sopenharmony_ci            break;
121bae44755Sopenharmony_ci        case 0x64:  // 0x64,  -sC "pcidstring" "rpcidstring"
122bae44755Sopenharmony_ci            ret = ComparePcidWithRpcidString(g_customerfileinfo.pcidfile, g_customerfileinfo.rpcidfile, TYPE_STRING);
123bae44755Sopenharmony_ci            break;
124bae44755Sopenharmony_ci        case 0x111: // 0x111, -Pei inputfile
125bae44755Sopenharmony_ci            ret = CreatePCID(g_customerfileinfo.inputfile, outputpath); break;
126bae44755Sopenharmony_ci        case 0x112: // 0x112, -Pdi inputfile
127bae44755Sopenharmony_ci            ret = DecodePCID(g_customerfileinfo.inputfile, outputpath); break;
128bae44755Sopenharmony_ci        case 0x116: // 0x116, -Pdsi inputfile
129bae44755Sopenharmony_ci            ret = DecodeStringPCIDToJson(g_customerfileinfo.inputfile, outputpath); break;
130bae44755Sopenharmony_ci        case 0x10E: // 0x10E, -Rdsi inputfile
131bae44755Sopenharmony_ci            printf("-Rdsi is not support currently.\n"); break;
132bae44755Sopenharmony_ci        case 0x80:  // 0x80,  -v
133bae44755Sopenharmony_ci            if (optind < 0 || optind >= INPUT_FILE_NUM) {
134bae44755Sopenharmony_ci                PRINT_ERR("Input file too few or too many.\n");
135bae44755Sopenharmony_ci                return -1;
136bae44755Sopenharmony_ci            } else {
137bae44755Sopenharmony_ci                (void)OutputVersion(argv[optind], optind);
138bae44755Sopenharmony_ci                break;
139bae44755Sopenharmony_ci            }
140bae44755Sopenharmony_ci        default:
141bae44755Sopenharmony_ci            (void)OutputHelp();
142bae44755Sopenharmony_ci    }
143bae44755Sopenharmony_ci    return ret;
144bae44755Sopenharmony_ci}
145bae44755Sopenharmony_ci
146bae44755Sopenharmony_civoid SetBitMap(char *const *argv, int32_t flag, uint16_t *bitMap, char **outputpath)
147bae44755Sopenharmony_ci{
148bae44755Sopenharmony_ci    switch (flag) {
149bae44755Sopenharmony_ci        case 'e':
150bae44755Sopenharmony_ci            (*bitMap) |= 0x1 << ENCODE;
151bae44755Sopenharmony_ci            break;
152bae44755Sopenharmony_ci        case 'd':
153bae44755Sopenharmony_ci            (*bitMap) |= 0x1 << DECODE;
154bae44755Sopenharmony_ci            break;
155bae44755Sopenharmony_ci        case 's':
156bae44755Sopenharmony_ci            (*bitMap) |= 0x1 << STRING_DECODE;
157bae44755Sopenharmony_ci            break;
158bae44755Sopenharmony_ci        case 'R':
159bae44755Sopenharmony_ci            (*bitMap) |= 0x1 << RPCID;
160bae44755Sopenharmony_ci            break;
161bae44755Sopenharmony_ci        case 'P':
162bae44755Sopenharmony_ci            (*bitMap) |= 0x1 << PCID;
163bae44755Sopenharmony_ci            break;
164bae44755Sopenharmony_ci        case 'C':
165bae44755Sopenharmony_ci            (*bitMap) |= 0x1 << PCID_STRING;
166bae44755Sopenharmony_ci            (*bitMap) |= 0x1 << RPCID_STRING;
167bae44755Sopenharmony_ci            g_customerfileinfo.pcidfile = optarg;
168bae44755Sopenharmony_ci            g_customerfileinfo.rpcidfile = argv[optind];
169bae44755Sopenharmony_ci            break;
170bae44755Sopenharmony_ci        case 'i':
171bae44755Sopenharmony_ci            (*bitMap) |= 0x1 << INPUT_FILE;
172bae44755Sopenharmony_ci            g_customerfileinfo.inputfile = optarg;
173bae44755Sopenharmony_ci            break;
174bae44755Sopenharmony_ci        case 'o':
175bae44755Sopenharmony_ci            (*outputpath) = optarg;
176bae44755Sopenharmony_ci            break;
177bae44755Sopenharmony_ci        case 'v':
178bae44755Sopenharmony_ci            (*bitMap) |= 0x1 << VERSION;
179bae44755Sopenharmony_ci            break;
180bae44755Sopenharmony_ci        case 'h':
181bae44755Sopenharmony_ci        default:
182bae44755Sopenharmony_ci            (*bitMap) |= 0x1 << HELP;
183bae44755Sopenharmony_ci    }
184bae44755Sopenharmony_ci}
185bae44755Sopenharmony_ci
186bae44755Sopenharmony_civoid PrintVersion(void)
187bae44755Sopenharmony_ci{
188bae44755Sopenharmony_ci    char outputVersion[OUTPUT_VERSION_LEN] = {0};
189bae44755Sopenharmony_ci    int ret = sprintf_s(outputVersion, OUTPUT_VERSION_LEN, "syscap_tool v%s", SYSCAP_VERSION);
190bae44755Sopenharmony_ci    if (ret == -1) {
191bae44755Sopenharmony_ci        PRINT_ERR("sprintf_s failed.\n");
192bae44755Sopenharmony_ci        exit(-1);
193bae44755Sopenharmony_ci    }
194bae44755Sopenharmony_ci    printf("%s\n", outputVersion);
195bae44755Sopenharmony_ci}
196bae44755Sopenharmony_ci
197bae44755Sopenharmony_civoid PrintHelp(void)
198bae44755Sopenharmony_ci{
199bae44755Sopenharmony_ci    printf("syscap_tool -R/P -e/d -i filepath [-o outpath]\n");
200bae44755Sopenharmony_ci    printf("-h, --help\t: how to use\n");
201bae44755Sopenharmony_ci    printf("-R, --rpcid\t: encode or decode rpcid\n");
202bae44755Sopenharmony_ci    printf("-P, --pcid\t: encode or decode pcid\n");
203bae44755Sopenharmony_ci    printf("-C, --compare\t: compare pcid with rpcid string format.\n\t"
204bae44755Sopenharmony_ci           "-s, --string : input string.\n");
205bae44755Sopenharmony_ci    printf("-e, --encode\t: encode to sc format.\n\t-s, --string : encode to string format.\n");
206bae44755Sopenharmony_ci    printf("-d, --decode\t: decode to json format.\n\t-s, --string : decode string format.\n");
207bae44755Sopenharmony_ci    printf("-i filepath, --input filepath\t: input file\n");
208bae44755Sopenharmony_ci    printf("-o outpath, --input outpath\t: output path\n");
209bae44755Sopenharmony_ci    printf("-v, --version\t: print syscap_tool version information.\n");
210bae44755Sopenharmony_ci}
211bae44755Sopenharmony_ci
212bae44755Sopenharmony_civoid OutputVersion(const char *arg, int opt)
213bae44755Sopenharmony_ci{
214bae44755Sopenharmony_ci    if (arg != NULL && opt > 1) {
215bae44755Sopenharmony_ci        printf("syscap_tool: extra operand \"%s\"\n", arg);
216bae44755Sopenharmony_ci        printf("Try 'syscap_tool --help' for more information.\n");
217bae44755Sopenharmony_ci    } else {
218bae44755Sopenharmony_ci        (void)PrintVersion();
219bae44755Sopenharmony_ci    }
220bae44755Sopenharmony_ci}
221bae44755Sopenharmony_ci
222bae44755Sopenharmony_civoid OutputHelp(void)
223bae44755Sopenharmony_ci{
224bae44755Sopenharmony_ci    (void)PrintHelp();
225bae44755Sopenharmony_ci    printf("\n");
226bae44755Sopenharmony_ci    (void)PrintVersion();
227bae44755Sopenharmony_ci}