1 /*
2 * Copyright (C) 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
16 #include <getopt.h>
17 #include <stdint.h>
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <limits.h>
22 #include "securec.h"
23 #include "syscap_tool.h"
24 #include "create_pcid.h"
25
26 #define PRINT_ERR(...) \
27 do { \
28 printf("ERROR: [%s: %d] -> ", __FILE__, __LINE__); \
29 printf(__VA_ARGS__); \
30 } while (0)
31 #define SYSCAP_VERSION "2.0.1"
32 #define OUTPUT_VERSION_LEN 200
33 #define ENCODE 0
34 #define DECODE 1
35 #define STRING_DECODE 2
36 #define RPCID 3
37 #define PCID 4
38 #define PCID_STRING 5
39 #define RPCID_STRING 6
40 #define VERSION 7
41 #define INPUT_FILE 8
42 #define OUTPUT_FILE 9
43 #define HELP 10
44
45 static void PrintHelp(void);
46 static void PrintVersion(void);
47 static void OutputVersion(const char *arg, int opt);
48 static void OutputHelp(void);
49
main(int argc,char ** argv)50 int main(int argc, char **argv)
51 {
52 int32_t optIndex;
53 int32_t ret = 0;
54 uint16_t bitMap = 0x0;
55 char curpath[PATH_MAX] = {0};
56 char *inputfile = NULL;
57 char *pcidfile = NULL;
58 char *rpcidfile = NULL;
59 char *outputpath = getcwd(curpath, sizeof(curpath));
60
61 while (1) {
62 static struct option longOptions[] = {
63 {"help", no_argument, 0, 'h' },
64 {"version", no_argument, 0, 'v' },
65 {"RPCID", no_argument, 0, 'R' },
66 {"PCID", no_argument, 0, 'P' },
67 {"compare", required_argument, 0, 'C' },
68 {"encode", no_argument, 0, 'e' },
69 {"decode", no_argument, 0, 'd' },
70 {"string", no_argument, 0, 's' },
71 {"input", required_argument, 0, 'i' },
72 {"output", required_argument, 0, 'o' },
73 {0, 0, 0, 0 }
74 };
75
76 int32_t flag = getopt_long(argc, argv, "hvRPC:edsi:o:", longOptions, &optIndex);
77 if (flag == -1) {
78 break;
79 }
80 switch (flag) {
81 case 'e':
82 bitMap |= 0x1 << ENCODE;
83 break;
84 case 'd':
85 bitMap |= 0x1 << DECODE;
86 break;
87 case 's':
88 bitMap |= 0x1 << STRING_DECODE;
89 break;
90 case 'R':
91 bitMap |= 0x1 << RPCID;
92 break;
93 case 'P':
94 bitMap |= 0x1 << PCID;
95 break;
96 case 'C':
97 bitMap |= 0x1 << PCID_STRING;
98 bitMap |= 0x1 << RPCID_STRING;
99 if (argc != 4 || optind < 0 || optind >= argc) { // 4, argc of ./syscap_tool -C f1 f2
100 PRINT_ERR("Input file too few or too many.\n");
101 return -1;
102 }
103 pcidfile = optarg;
104 rpcidfile = argv[optind];
105 break;
106 case 'i':
107 bitMap |= 0x1 << INPUT_FILE;
108 inputfile = optarg;
109 break;
110 case 'o':
111 outputpath = optarg;
112 break;
113 case 'v':
114 bitMap |= 0x1 << VERSION;
115 break;
116 case 'h':
117 default:
118 bitMap |= 0x1 << HELP;;
119 }
120 }
121
122 switch (bitMap) {
123 case 0x109: // 0x109, -Rei inputfile
124 ret = RPCIDEncode(inputfile, outputpath); break;
125 case 0x10A: // 0x10A, -Rdi inputfile
126 ret = RPCIDDecode(inputfile, outputpath); break;
127 case 0x10D: // 0x10D, -Resi inputfile
128 ret = EncodeRpcidscToString(inputfile, outputpath); break;
129 case 0x115: // 0x115, -Pesi inputfile
130 ret = EncodePcidscToString(inputfile, outputpath); break;
131 case 0x60: // 0x60, -C PCID.txt RPCID.txt
132 ret = ComparePcidWithRpcidString(pcidfile, rpcidfile, TYPE_FILE); break;
133 case 0x64: // 0x64, -sC "pcidstring" "rpcidstring"
134 ret = ComparePcidWithRpcidString(pcidfile, rpcidfile, TYPE_STRING); break;
135 case 0x111: // 0x111, -Pei inputfile
136 ret = CreatePCID(inputfile, outputpath); break;
137 case 0x112: // 0x112, -Pdi inputfile
138 ret = DecodePCID(inputfile, outputpath); break;
139 case 0x116: // 0x116, -Pdsi inputfile
140 ret = DecodeStringPCIDToJson(inputfile, outputpath); break;
141 case 0x10E: // 0x10E, -Rdsi inputfile
142 printf("-Rdsi is not support currently.\n"); break;
143 case 0x80: // 0x80, -v
144 (void)OutputVersion(argv[optind], optind); break;
145 default:
146 (void)OutputHelp();
147 }
148
149 if (ret != 0) {
150 PRINT_ERR("syscap_tool failed to complete. input: %s\n", inputfile);
151 }
152 return ret;
153 }
154
PrintVersion(void)155 void PrintVersion(void)
156 {
157 char outputVersion[OUTPUT_VERSION_LEN] = {0};
158 int ret = sprintf_s(outputVersion, OUTPUT_VERSION_LEN, "syscap_tool v%s", SYSCAP_VERSION);
159 if (ret == -1) {
160 PRINT_ERR("sprintf_s failed.\n");
161 exit(-1);
162 }
163 printf("%s\n", outputVersion);
164 }
165
PrintHelp(void)166 void PrintHelp(void)
167 {
168 printf("syscap_tool -R/P -e/d -i filepath [-o outpath]\n");
169 printf("-h, --help\t: how to use\n");
170 printf("-R, --RPCID\t: encode or decode RPCID\n");
171 printf("-P, --PCID\t: encode or decode PCID\n");
172 printf("-C, --compare\t: compare pcid with rpcid string format.\n\t"
173 "-s, --string : input string.\n");
174 printf("-e, --encode\t: encode to sc format.\n\t-s, --string : encode to string format.\n");
175 printf("-d, --decode\t: decode to json format.\n\t-s, --string : decode string format.\n");
176 printf("-i filepath, --input filepath\t: input file\n");
177 printf("-o outpath, --input outpath\t: output path\n");
178 printf("-v, --version\t: print syscap_tool version information.\n");
179 }
180
OutputVersion(const char * arg,int opt)181 void OutputVersion(const char *arg, int opt)
182 {
183 if (arg != NULL && opt > 1) {
184 printf("syscap_tool: extra operand \"%s\"\n", arg);
185 printf("Try 'syscap_tool --help' for more information.\n");
186 } else {
187 (void)PrintVersion();
188 }
189 }
190
OutputHelp(void)191 void OutputHelp(void)
192 {
193 (void)PrintHelp();
194 printf("\n");
195 (void)PrintVersion();
196 }