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