Advertisement
aeee98

Untitled

Mar 18th, 2016
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* 7zMain.c - Test application for 7z Decoder
  2. 2010-10-28 : Igor Pavlov : Public domain */
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6.  
  7. #include "7z.h"
  8. #include "7zAlloc.h"
  9. #include "7zCrc.h"
  10. #include "7zFile.h"
  11. #include "7zVersion.h"
  12.  
  13. #ifndef USE_WINDOWS_FILE
  14. /* for mkdir */
  15. #ifdef _WIN32
  16. #include <direct.h>
  17. #else
  18. #include <sys/stat.h>
  19. #include <errno.h>
  20. #endif
  21. #endif
  22.  
  23. static ISzAlloc g_Alloc = { SzAlloc, SzFree };
  24.  
  25. static int Buf_EnsureSize(CBuf *dest, size_t size)
  26. {
  27.   if (dest->size >= size)
  28.     return 1;
  29.   Buf_Free(dest, &g_Alloc);
  30.   return Buf_Create(dest, size, &g_Alloc);
  31. }
  32.  
  33. #ifndef _WIN32
  34.  
  35. static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
  36.  
  37. static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen)
  38. {
  39.   size_t destPos = 0, srcPos = 0;
  40.   for (;;)
  41.   {
  42.     unsigned numAdds;
  43.     UInt32 value;
  44.     if (srcPos == srcLen)
  45.     {
  46.       *destLen = destPos;
  47.       return True;
  48.     }
  49.     value = src[srcPos++];
  50.     if (value < 0x80)
  51.     {
  52.       if (dest)
  53.         dest[destPos] = (char)value;
  54.       destPos++;
  55.       continue;
  56.     }
  57.     if (value >= 0xD800 && value < 0xE000)
  58.     {
  59.       UInt32 c2;
  60.       if (value >= 0xDC00 || srcPos == srcLen)
  61.         break;
  62.       c2 = src[srcPos++];
  63.       if (c2 < 0xDC00 || c2 >= 0xE000)
  64.         break;
  65.       value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
  66.     }
  67.     for (numAdds = 1; numAdds < 5; numAdds++)
  68.       if (value < (((UInt32)1) << (numAdds * 5 + 6)))
  69.         break;
  70.     if (dest)
  71.       dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
  72.     destPos++;
  73.     do
  74.     {
  75.       numAdds--;
  76.       if (dest)
  77.         dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
  78.       destPos++;
  79.     }
  80.     while (numAdds != 0);
  81.   }
  82.   *destLen = destPos;
  83.   return False;
  84. }
  85.  
  86. static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
  87. {
  88.   size_t destLen = 0;
  89.   Bool res;
  90.   Utf16_To_Utf8(NULL, &destLen, src, srcLen);
  91.   destLen += 1;
  92.   if (!Buf_EnsureSize(dest, destLen))
  93.     return SZ_ERROR_MEM;
  94.   res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen);
  95.   dest->data[destLen] = 0;
  96.   return res ? SZ_OK : SZ_ERROR_FAIL;
  97. }
  98. #endif
  99.  
  100. static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
  101. {
  102.   int len = 0;
  103.   for (len = 0; s[len] != '\0'; len++);
  104.  
  105.   #ifdef _WIN32
  106.   {
  107.     int size = len * 3 + 100;
  108.     if (!Buf_EnsureSize(buf, size))
  109.       return SZ_ERROR_MEM;
  110.     {
  111.       char defaultChar = '_';
  112.       BOOL defUsed;
  113.       int numChars = WideCharToMultiByte(fileMode ?
  114.           (
  115.           #ifdef UNDER_CE
  116.           CP_ACP
  117.           #else
  118.           AreFileApisANSI() ? CP_ACP : CP_OEMCP
  119.           #endif
  120.           ) : CP_OEMCP,
  121.           0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
  122.       if (numChars == 0 || numChars >= size)
  123.         return SZ_ERROR_FAIL;
  124.       buf->data[numChars] = 0;
  125.       return SZ_OK;
  126.     }
  127.   }
  128.   #else
  129.   fileMode = fileMode;
  130.   return Utf16_To_Utf8Buf(buf, s, len);
  131.   #endif
  132. }
  133.  
  134. static WRes MyCreateDir(const UInt16 *name)
  135. {
  136.   #ifdef USE_WINDOWS_FILE
  137.  
  138.   return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
  139.  
  140.   #else
  141.  
  142.   CBuf buf;
  143.   WRes res;
  144.   Buf_Init(&buf);
  145.   RINOK(Utf16_To_Char(&buf, name, 1));
  146.  
  147.   res =
  148.   #ifdef _WIN32
  149.   _mkdir((const char *)buf.data)
  150.   #else
  151.   mkdir((const char *)buf.data, 0777)
  152.   #endif
  153.   == 0 ? 0 : errno;
  154.   Buf_Free(&buf, &g_Alloc);
  155.   return res;
  156.  
  157.   #endif
  158. }
  159.  
  160. static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
  161. {
  162.   #ifdef USE_WINDOWS_FILE
  163.   return OutFile_OpenW(p, name);
  164.   #else
  165.   CBuf buf;
  166.   WRes res;
  167.   Buf_Init(&buf);
  168.   RINOK(Utf16_To_Char(&buf, name, 1));
  169.   res = OutFile_Open(p, (const char *)buf.data);
  170.   Buf_Free(&buf, &g_Alloc);
  171.   return res;
  172.   #endif
  173. }
  174.  
  175. static SRes PrintString(const UInt16 *s)
  176. {
  177.   CBuf buf;
  178.   SRes res;
  179.   Buf_Init(&buf);
  180.   res = Utf16_To_Char(&buf, s, 0);
  181.   if (res == SZ_OK)
  182.     fputs((const char *)buf.data, stdout);
  183.   Buf_Free(&buf, &g_Alloc);
  184.   return res;
  185. }
  186.  
  187. static void UInt64ToStr(UInt64 value, char *s)
  188. {
  189.   char temp[32];
  190.   int pos = 0;
  191.   do
  192.   {
  193.     temp[pos++] = (char)('0' + (unsigned)(value % 10));
  194.     value /= 10;
  195.   }
  196.   while (value != 0);
  197.   do
  198.     *s++ = temp[--pos];
  199.   while (pos);
  200.   *s = '\0';
  201. }
  202.  
  203. static char *UIntToStr(char *s, unsigned value, int numDigits)
  204. {
  205.   char temp[16];
  206.   int pos = 0;
  207.   do
  208.     temp[pos++] = (char)('0' + (value % 10));
  209.   while (value /= 10);
  210.   for (numDigits -= pos; numDigits > 0; numDigits--)
  211.     *s++ = '0';
  212.   do
  213.     *s++ = temp[--pos];
  214.   while (pos);
  215.   *s = '\0';
  216.   return s;
  217. }
  218.  
  219. #define PERIOD_4 (4 * 365 + 1)
  220. #define PERIOD_100 (PERIOD_4 * 25 - 1)
  221. #define PERIOD_400 (PERIOD_100 * 4 + 1)
  222.  
  223. static void ConvertFileTimeToString(const CNtfsFileTime *ft, char *s)
  224. {
  225.   unsigned year, mon, day, hour, min, sec;
  226.   UInt64 v64 = (ft->Low | ((UInt64)ft->High << 32)) / 10000000;
  227.   Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  228.   unsigned t;
  229.   UInt32 v;
  230.   sec = (unsigned)(v64 % 60); v64 /= 60;
  231.   min = (unsigned)(v64 % 60); v64 /= 60;
  232.   hour = (unsigned)(v64 % 24); v64 /= 24;
  233.  
  234.   v = (UInt32)v64;
  235.  
  236.   year = (unsigned)(1601 + v / PERIOD_400 * 400);
  237.   v %= PERIOD_400;
  238.  
  239.   t = v / PERIOD_100; if (t ==  4) t =  3; year += t * 100; v -= t * PERIOD_100;
  240.   t = v / PERIOD_4;   if (t == 25) t = 24; year += t * 4;   v -= t * PERIOD_4;
  241.   t = v / 365;        if (t ==  4) t =  3; year += t;       v -= t * 365;
  242.  
  243.   if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
  244.     ms[1] = 29;
  245.   for (mon = 1; mon <= 12; mon++)
  246.   {
  247.     unsigned s = ms[mon - 1];
  248.     if (v < s)
  249.       break;
  250.     v -= s;
  251.   }
  252.   day = (unsigned)v + 1;
  253.   s = UIntToStr(s, year, 4); *s++ = '-';
  254.   s = UIntToStr(s, mon, 2);  *s++ = '-';
  255.   s = UIntToStr(s, day, 2);  *s++ = ' ';
  256.   s = UIntToStr(s, hour, 2); *s++ = ':';
  257.   s = UIntToStr(s, min, 2);  *s++ = ':';
  258.   s = UIntToStr(s, sec, 2);
  259. }
  260.  
  261. void PrintError(char *sz)
  262. {
  263.   printf("\nERROR: %s\n", sz);
  264. }
  265.  
  266. #ifdef USE_WINDOWS_FILE
  267. #define kEmptyAttribChar '.'
  268. static void GetAttribString(UInt32 wa, Bool isDir, char *s)
  269. {
  270.   s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar);
  271.   s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar);
  272.   s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar);
  273.   s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar);
  274.   s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar);
  275.   s[5] = '\0';
  276. }
  277. #else
  278. static void GetAttribString(UInt32, Bool, char *s)
  279. {
  280.   s[0] = '\0';
  281. }
  282. #endif
  283.  
  284. int MY_CDECL main(int numargs, char *args[])
  285. {
  286.   CFileInStream archiveStream;
  287.   CLookToRead lookStream;
  288.   CSzArEx db;
  289.   SRes res;
  290.   ISzAlloc allocImp;
  291.   ISzAlloc allocTempImp;
  292.   UInt16 *temp = NULL;
  293.   size_t tempSize = 0;
  294.   char *testchar;
  295.   if (numargs < 3)
  296.   {
  297.     PrintError("incorrect command");
  298.     return 1;
  299.   }
  300.  
  301.   allocImp.Alloc = SzAlloc;
  302.   allocImp.Free = SzFree;
  303.  
  304.   allocTempImp.Alloc = SzAllocTemp;
  305.   allocTempImp.Free = SzFreeTemp;
  306.  
  307.   if (InFile_Open(&archiveStream.file, args[2]))
  308.   {
  309.     PrintError("can not open input file");
  310.     return 1;
  311.   }
  312.  
  313.   FileInStream_CreateVTable(&archiveStream);
  314.   LookToRead_CreateVTable(&lookStream, False);
  315.  
  316.   lookStream.realStream = &archiveStream.s;
  317.   LookToRead_Init(&lookStream);
  318.  
  319.   CrcGenerateTable();
  320.  
  321.   SzArEx_Init(&db);
  322.   res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
  323.   if (res == SZ_OK)
  324.   {
  325.     char *command = args[1];
  326.     int listCommand = 0, testCommand = 0, extractCommand = 0, fullPaths = 0;
  327.     if (strcmp(command, "l") == 0) listCommand = 1;
  328.     else if (strcmp(command, "t") == 0) testCommand = 1;
  329.     else if (strcmp(command, "e") == 0) extractCommand = 1;
  330.     else if (strcmp(command, "x") == 0) { extractCommand = 1; fullPaths = 1; }
  331.     else
  332.     {
  333.       PrintError("incorrect command");
  334.       res = SZ_ERROR_FAIL;
  335.     }
  336.  
  337.     if (res == SZ_OK)
  338.     {
  339.       UInt32 i;
  340.  
  341.       /*
  342.       if you need cache, use these 3 variables.
  343.       if you use external function, you can make these variable as static.
  344.       */
  345.       UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
  346.       Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
  347.       size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */
  348.  
  349.       for (i = 0; i < db.db.NumFiles; i++)
  350.       {
  351.         size_t offset = 0;
  352.         size_t outSizeProcessed = 0;
  353.         const CSzFileItem *f = db.db.Files + i;
  354.         size_t len;
  355.         if (listCommand == 0 && f->IsDir && !fullPaths)
  356.           continue;
  357.         len = SzArEx_GetFileNameUtf16(&db, i, NULL);
  358.  
  359.         if (len > tempSize)
  360.         {
  361.           SzFree(NULL, temp);
  362.           tempSize = len;
  363.           temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
  364.           if (temp == 0)
  365.           {
  366.             res = SZ_ERROR_MEM;
  367.             break;
  368.           }
  369.         }
  370.  
  371.         SzArEx_GetFileNameUtf16(&db, i, temp);
  372.         WideCharToMultiByte(CP_UTF8,NULL,temp,sizeof(temp),testchar, 0, NULL, NULL);
  373.         }
  374.   return 0;
  375. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement