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 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 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 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 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 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 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