Home | History | Annotate | Download | only in Split
      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