1 /** @file
2
3 Split a file into two pieces at the request offset.
4
5 Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are licensed and made available
7 under the terms and conditions of the BSD License which accompanies this
8 distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 // GC_TODO: fix comment to start with /*++
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #ifdef __GNUC__
21 #include <unistd.h>
22 #else
23 #include <direct.h>
24 #endif
25 #include <ctype.h>
26 #include "ParseInf.h"
27 #include "CommonLib.h"
28 #include "EfiUtilityMsgs.h"
29 //
30 // Utility Name
31 //
32 #define UTILITY_NAME "Split"
33
34 //
35 // Utility version information
36 //
37 #define UTILITY_MAJOR_VERSION 1
38 #define UTILITY_MINOR_VERSION 0
39
40 void
Version(void)41 Version (
42 void
43 )
44 /*++
45
46 Routine Description:
47
48 Displays the standard utility information to SDTOUT
49
50 Arguments:
51
52 None
53
54 Returns:
55
56 None
57
58 --*/
59 {
60 printf ("%s Version %d.%d Build %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
61 }
62
63 void
Usage(void)64 Usage (
65 void
66 )
67 /*++
68
69 Routine Description:
70
71 GC_TODO: Add function description
72
73 Arguments:
74
75
76 Returns:
77
78 GC_TODO: add return values
79
80 --*/
81 {
82 Version();
83 printf ("Copyright (c) 1999-2016 Intel Corporation. All rights reserved.\n");
84 printf ("\n SplitFile creates two Binary files either in the same directory as the current working\n");
85 printf (" directory or in the specified directory.\n");
86 printf ("\nUsage: \n\
87 Split\n\
88 -f, --filename inputFile to split\n\
89 -s, --split VALUE the number of bytes in the first file\n\
90 [-p, --prefix OutputDir]\n\
91 [-o, --firstfile Filename1]\n\
92 [-t, --secondfile Filename2]\n\
93 [-v, --verbose]\n\
94 [--version]\n\
95 [-q, --quiet disable all messages except fatal errors]\n\
96 [-d, --debug[#]\n\
97 [-h, --help]\n");
98 }
99
100 EFI_STATUS
GetSplitValue(IN CONST CHAR8 * SplitValueString,OUT UINT64 * ReturnValue)101 GetSplitValue (
102 IN CONST CHAR8* SplitValueString,
103 OUT UINT64 *ReturnValue
104 )
105 {
106 UINT64 len = strlen(SplitValueString);
107 UINT64 base = 1;
108 UINT64 index = 0;
109 UINT64 number = 0;
110 CHAR8 lastCHAR = 0;
111 EFI_STATUS Status = EFI_SUCCESS;
112
113 if (len == 0) {
114 return EFI_ABORTED;
115 }
116
117 Status = AsciiStringToUint64 (SplitValueString, FALSE, ReturnValue);
118 if (!EFI_ERROR (Status)) {
119 return Status;
120 }
121
122 if (SplitValueString[0] == '0' && (SplitValueString[1] == 'x' || SplitValueString[1] == 'X')) {
123 Status = AsciiStringToUint64 (SplitValueString, TRUE, ReturnValue);
124 if (!EFI_ERROR (Status)) {
125 return Status;
126 }
127 }
128
129 lastCHAR = (CHAR8)toupper((int)SplitValueString[len - 1]);
130
131 if (lastCHAR != 'K' && lastCHAR != 'M' && lastCHAR != 'G') {
132 return STATUS_ERROR;
133 }
134
135 for (;index < len - 1; ++index) {
136 if (!isdigit((int)SplitValueString[index])) {
137 return EFI_ABORTED;
138 }
139 }
140
141 number = atol (SplitValueString);
142 if (lastCHAR == 'K')
143 base = 1024;
144 else if (lastCHAR == 'M')
145 base = 1024*1024;
146 else
147 base = 1024*1024*1024;
148
149 *ReturnValue = number*base;
150
151 return EFI_SUCCESS;
152 }
153
154 EFI_STATUS
CountVerboseLevel(IN CONST CHAR8 * VerboseLevelString,IN CONST UINT64 Length,OUT UINT64 * ReturnValue)155 CountVerboseLevel (
156 IN CONST CHAR8* VerboseLevelString,
157 IN CONST UINT64 Length,
158 OUT UINT64 *ReturnValue
159 )
160 {
161 UINT64 i = 0;
162 for (;i < Length; ++i) {
163 if (VerboseLevelString[i] != 'v' && VerboseLevelString[i] != 'V') {
164 return EFI_ABORTED;
165 }
166 ++(*ReturnValue);
167 }
168
169 return EFI_SUCCESS;
170 }
171
172 EFI_STATUS
CreateDir(IN OUT CHAR8 ** FullFileName)173 CreateDir (
174 IN OUT CHAR8** FullFileName
175 )
176 {
177 CHAR8* temp = *FullFileName;
178 CHAR8* start = temp;
179 CHAR8 tempchar;
180 UINT64 index = 0;
181
182 for (;index < strlen(temp); ++index) {
183 if (temp[index] == '\\' || temp[index] == '/') {
184 if (temp[index + 1] != '\0') {
185 tempchar = temp[index + 1];
186 temp[index + 1] = 0;
187 if (chdir(start)) {
188 if (mkdir(start, S_IRWXU | S_IRWXG | S_IRWXO) != 0) {
189 return EFI_ABORTED;
190 }
191 chdir(start);
192 }
193 start = temp + index + 1;
194 temp[index] = '/';
195 temp[index + 1] = tempchar;
196 }
197 }
198 }
199
200 return EFI_SUCCESS;
201 }
202
203 int
main(int argc,char * argv[])204 main (
205 int argc,
206 char*argv[]
207 )
208 /*++
209
210 Routine Description:
211
212 GC_TODO: Add function description
213
214 Arguments:
215
216 argc - GC_TODO: add argument description
217 ] - GC_TODO: add argument description
218
219 Returns:
220
221 GC_TODO: add return values
222
223 --*/
224 {
225 EFI_STATUS Status = EFI_SUCCESS;
226 INTN ReturnStatus = STATUS_SUCCESS;
227 FILE *In;
228 CHAR8 *InputFileName = NULL;
229 CHAR8 *OutputDir = NULL;
230 CHAR8 *OutFileName1 = NULL;
231 CHAR8 *OutFileName2 = NULL;
232 UINT64 SplitValue = (UINT64) -1;
233 FILE *Out1 = NULL;
234 FILE *Out2 = NULL;
235 CHAR8 *OutName1 = NULL;
236 CHAR8 *OutName2 = NULL;
237 CHAR8 *CurrentDir = NULL;
238 UINT64 Index;
239 CHAR8 CharC;
240 UINT64 DebugLevel = 0;
241 UINT64 VerboseLevel = 0;
242
243 SetUtilityName(UTILITY_NAME);
244 if (argc == 1) {
245 Usage();
246 return STATUS_ERROR;
247 }
248
249 argc --;
250 argv ++;
251
252 if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
253 Usage();
254 return STATUS_SUCCESS;
255 }
256
257 if (stricmp (argv[0], "--version") == 0) {
258 Version();
259 return STATUS_SUCCESS;
260 }
261
262 while (argc > 0) {
263 if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--prefix") == 0)) {
264 OutputDir = argv[1];
265 if (OutputDir == NULL) {
266 Warning (NULL, 0, 0, "NO output directory specified.", NULL);
267 return STATUS_ERROR;
268 }
269 argc -= 2;
270 argv += 2;
271 continue;
272 }
273
274 if ((stricmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--filename") == 0)) {
275 InputFileName = argv[1];
276 if (InputFileName == NULL) {
277 Error (NULL, 0, 0x1001, "NO Input file specified.", NULL);
278 return STATUS_ERROR;
279 }
280 argc -= 2;
281 argv += 2;
282 continue;
283 }
284
285 if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--split") == 0)) {
286 Status = GetSplitValue(argv[1], &SplitValue);
287 if (EFI_ERROR (Status)) {
288 Error (NULL, 0, 0x1003, "Input split value is not one valid integer.", NULL);
289 return STATUS_ERROR;
290 }
291 argc -= 2;
292 argv += 2;
293 continue;
294 }
295
296 if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--firstfile") == 0)) {
297 OutFileName1 = argv[1];
298 if (OutFileName1 == NULL) {
299 Warning (NULL, 0, 0, NULL, "No output file1 specified.");
300 }
301 argc -= 2;
302 argv += 2;
303 continue;
304 }
305
306 if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--secondfile") == 0)) {
307 OutFileName2 = argv[1];
308 if (OutFileName2 == NULL) {
309 Warning (NULL, 0, 0, NULL, "No output file2 specified.");
310 }
311 argc -= 2;
312 argv += 2;
313 continue;
314 }
315
316 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
317 argc --;
318 argv ++;
319 continue;
320 }
321
322 if ((strlen(argv[0]) >= 2 && argv[0][0] == '-' && (argv[0][1] == 'v' || argv[0][1] == 'V')) || (stricmp (argv[0], "--verbose") == 0)) {
323 VerboseLevel = 1;
324 if (strlen(argv[0]) > 2) {
325 Status = CountVerboseLevel (&argv[0][2], strlen(argv[0]) - 2, &VerboseLevel);
326 if (EFI_ERROR (Status)) {
327 Error (NULL, 0, 0x1003, NULL, "%s is invaild parameter!", argv[0]);
328 return STATUS_ERROR;
329 }
330 }
331
332 argc --;
333 argv ++;
334 continue;
335 }
336
337 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
338 Status = AsciiStringToUint64 (argv[1], FALSE, &DebugLevel);
339 if (EFI_ERROR (Status)) {
340 Error (NULL, 0, 0x1003, "Input debug level is not one valid integrator.", NULL);
341 return STATUS_ERROR;
342 }
343 argc -= 2;
344 argv += 2;
345 continue;
346 }
347 //
348 // Don't recognize the parameter.
349 //
350 Error (NULL, 0, 0x1003, NULL, "%s is invaild parameter!", argv[0]);
351 return STATUS_ERROR;
352 }
353
354 if (InputFileName == NULL) {
355 Error (NULL, 0, 0x1001, "NO Input file specified.", NULL);
356 return STATUS_ERROR;
357 }
358
359 In = fopen (LongFilePath (InputFileName), "rb");
360 if (In == NULL) {
361 // ("Unable to open file \"%s\"\n", InputFileName);
362 Error (InputFileName, 0, 1, "File open failure", NULL);
363 return STATUS_ERROR;
364 }
365
366 if (OutFileName1 == NULL) {
367 OutName1 = (CHAR8*)malloc(strlen(InputFileName) + 16);
368 if (OutName1 == NULL) {
369 Warning (NULL, 0, 0, NULL, "Memory Allocation Fail.");
370 ReturnStatus = STATUS_ERROR;
371 goto Finish;
372 }
373 strcpy (OutName1, InputFileName);
374 strcat (OutName1, "1");
375 OutFileName1 = OutName1;
376
377 }
378 if (OutFileName2 == NULL) {
379 OutName2 = (CHAR8*)malloc(strlen(InputFileName) + 16);
380 if (OutName2 == NULL) {
381 Warning (NULL, 0, 0, NULL, "Memory Allocation Fail.");
382 ReturnStatus = STATUS_ERROR;
383 goto Finish;
384 }
385 strcpy (OutName2, InputFileName);
386 strcat (OutName2, "2");
387 OutFileName2 = OutName2;
388
389 }
390
391 if (OutputDir != NULL) {
392 //OutputDirSpecified = TRUE;
393 if (chdir(OutputDir) != 0) {
394 Warning (NULL, 0, 0, NULL, "Change dir to OutputDir Fail.");
395 ReturnStatus = STATUS_ERROR;
396 goto Finish;
397 }
398 }
399
400 CurrentDir = (CHAR8*)getcwd((CHAR8*)0, 0);
401 if (EFI_ERROR(CreateDir(&OutFileName1))) {
402 Error (OutFileName1, 0, 5, "Create Dir for File1 Fail.", NULL);
403 ReturnStatus = STATUS_ERROR;
404 goto Finish;
405 }
406 chdir(CurrentDir);
407
408 if (EFI_ERROR(CreateDir(&OutFileName2))) {
409 Error (OutFileName2, 0, 5, "Create Dir for File2 Fail.", NULL);
410 ReturnStatus = STATUS_ERROR;
411 goto Finish;
412 }
413 chdir(CurrentDir);
414 free(CurrentDir);
415
416 Out1 = fopen (LongFilePath (OutFileName1), "wb");
417 if (Out1 == NULL) {
418 // ("Unable to open file \"%s\"\n", OutFileName1);
419 Error (OutFileName1, 0, 1, "File open failure", NULL);
420 ReturnStatus = STATUS_ERROR;
421 goto Finish;
422 }
423
424 Out2 = fopen (LongFilePath (OutFileName2), "wb");
425 if (Out2 == NULL) {
426 // ("Unable to open file \"%s\"\n", OutFileName2);
427 Error (OutFileName2, 0, 1, "File open failure", NULL);
428 ReturnStatus = STATUS_ERROR;
429 goto Finish;
430 }
431
432 for (Index = 0; Index < SplitValue; Index++) {
433 CharC = (CHAR8) fgetc (In);
434 if (feof (In)) {
435 break;
436 }
437
438 fputc (CharC, Out1);
439 }
440
441 for (;;) {
442 CharC = (CHAR8) fgetc (In);
443 if (feof (In)) {
444 break;
445 }
446
447 fputc (CharC, Out2);
448 }
449
450 Finish:
451 if (OutName1 != NULL) {
452 free(OutName1);
453 }
454 if (OutName2 != NULL) {
455 free(OutName2);
456 }
457 if (In != NULL) {
458 fclose (In);
459 }
460 if (Out1 != NULL) {
461 fclose (Out1);
462 }
463 if (Out2 != NULL) {
464 fclose (Out2);
465 }
466
467 return ReturnStatus;
468 }
469