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