Subversion Repositories Kolibri OS

Rev

Rev 5728 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "7z.h"
  4. #include "7zAlloc.h"
  5. #include "7zBuf.h"
  6. #include "7zCrc.h"
  7. #include "7zFile.h"
  8. #include "7zVersion.h"
  9. #include "package.h"
  10.  
  11. #define PERIOD_4 (4 * 365 + 1)
  12. #define PERIOD_100 (PERIOD_4 * 25 - 1)
  13. #define PERIOD_400 (PERIOD_100 * 4 + 1)
  14.  
  15. #define _UTF8_START(n) (0x100 - (1 << (7 - (n))))
  16.  
  17. #define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6))
  18.  
  19. #define _UTF8_HEAD(n, val) ((Byte)(_UTF8_START(n) + (val >> (6 * (n)))))
  20. #define _UTF8_CHAR(n, val) ((Byte)(0x80 + (((val) >> (6 * (n))) & 0x3F)))
  21.  
  22. #define MY_FILE_CODE_PAGE_PARAM
  23.  
  24. static ISzAlloc g_Alloc = { SzAlloc, SzFree };
  25.  
  26. static int Buf_EnsureSize(CBuf *dest, size_t size)
  27. {
  28.     if (dest->size >= size)
  29.         return 1;
  30.     Buf_Free(dest, &g_Alloc);
  31.     return Buf_Create(dest, size, &g_Alloc);
  32. }
  33.  
  34.  
  35. int test_archive(const char *path)
  36. {
  37.     CFileInStream archiveStream;
  38.     CLookToRead lookStream;
  39.     CSzArEx db;
  40.     SRes res;
  41.     ISzAlloc allocImp;
  42.     ISzAlloc allocTempImp;
  43.     UInt16 *temp = NULL;
  44.  
  45.     allocImp.Alloc = SzAlloc;
  46.     allocImp.Free = SzFree;
  47.  
  48.     allocTempImp.Alloc = SzAllocTemp;
  49.     allocTempImp.Free = SzFreeTemp;
  50.  
  51.     if (InFile_Open(&archiveStream.file, path))
  52.     {
  53.         printf("can not open input file");
  54.         return -1;
  55.     }
  56.  
  57.     FileInStream_CreateVTable(&archiveStream);
  58.     LookToRead_CreateVTable(&lookStream, False);
  59.  
  60.     lookStream.realStream = &archiveStream.s;
  61.     LookToRead_Init(&lookStream);
  62.  
  63.     CrcGenerateTable();
  64.  
  65.     SzArEx_Init(&db);
  66.  
  67.     res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
  68.  
  69.     SzArEx_Free(&db, &allocImp);
  70.     SzFree(NULL, temp);
  71.  
  72.     File_Close(&archiveStream.file);
  73.  
  74.     if (res == SZ_OK)
  75.         return 0;
  76.     else return -1;
  77. };
  78.  
  79. static size_t Utf16_To_Utf8_Calc(const UInt16 *src, const UInt16 *srcLim)
  80. {
  81.     size_t size = 0;
  82.     for (;;)
  83.     {
  84.         UInt32 val;
  85.         if (src == srcLim)
  86.             return size;
  87.  
  88.         size++;
  89.         val = *src++;
  90.  
  91.         if (val < 0x80)
  92.             continue;
  93.  
  94.         if (val < _UTF8_RANGE(1))
  95.         {
  96.             size++;
  97.             continue;
  98.         }
  99.  
  100.         if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
  101.         {
  102.             UInt32 c2 = *src;
  103.             if (c2 >= 0xDC00 && c2 < 0xE000)
  104.             {
  105.                 src++;
  106.                 size += 3;
  107.                 continue;
  108.             }
  109.         }
  110.  
  111.         size += 2;
  112.     }
  113. }
  114.  
  115. static Byte *Utf16_To_Utf8(Byte *dest, const UInt16 *src, const UInt16 *srcLim)
  116. {
  117.     for (;;)
  118.     {
  119.         UInt32 val;
  120.         if (src == srcLim)
  121.             return dest;
  122.  
  123.         val = *src++;
  124.  
  125.         if (val < 0x80)
  126.         {
  127.             *dest++ = (char)val;
  128.             continue;
  129.         }
  130.  
  131.         if (val < _UTF8_RANGE(1))
  132.         {
  133.             dest[0] = _UTF8_HEAD(1, val);
  134.             dest[1] = _UTF8_CHAR(0, val);
  135.             dest += 2;
  136.             continue;
  137.         }
  138.  
  139.         if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
  140.         {
  141.             UInt32 c2 = *src;
  142.             if (c2 >= 0xDC00 && c2 < 0xE000)
  143.             {
  144.                 src++;
  145.                 val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
  146.                 dest[0] = _UTF8_HEAD(3, val);
  147.                 dest[1] = _UTF8_CHAR(2, val);
  148.                 dest[2] = _UTF8_CHAR(1, val);
  149.                 dest[3] = _UTF8_CHAR(0, val);
  150.                 dest += 4;
  151.                 continue;
  152.             }
  153.         }
  154.  
  155.         dest[0] = _UTF8_HEAD(2, val);
  156.         dest[1] = _UTF8_CHAR(1, val);
  157.         dest[2] = _UTF8_CHAR(0, val);
  158.         dest += 3;
  159.     }
  160. }
  161.  
  162. static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
  163. {
  164.     size_t destLen = Utf16_To_Utf8_Calc(src, src + srcLen);
  165.     destLen += 1;
  166.     if (!Buf_EnsureSize(dest, destLen))
  167.         return SZ_ERROR_MEM;
  168.     *Utf16_To_Utf8(dest->data, src, src + srcLen) = 0;
  169.     return SZ_OK;
  170. }
  171.  
  172. static void GetAttribString(UInt32 wa, Bool isDir, char *s)
  173. {
  174.     s[0] = (char)(((wa & (1 << 4)) != 0 || isDir) ? 'D' : '.');
  175.     s[1] = 0;
  176. }
  177.  
  178. static void UInt64ToStr(UInt64 value, char *s)
  179. {
  180.     char temp[32];
  181.     int pos = 0;
  182.     do
  183.     {
  184.         temp[pos++] = (char)('0' + (unsigned)(value % 10));
  185.         value /= 10;
  186.     }
  187.     while (value != 0);
  188.     do
  189.         *s++ = temp[--pos];
  190.     while (pos);
  191.     *s = '\0';
  192. }
  193.  
  194. static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s)
  195. {
  196.     unsigned len = 0;
  197.     for (len = 0; s[len] != 0; len++);
  198.  
  199.     return Utf16_To_Utf8Buf(buf, s, len);
  200. }
  201.  
  202. static char *UIntToStr(char *s, unsigned value, int numDigits)
  203. {
  204.     char temp[16];
  205.     int pos = 0;
  206.     do
  207.         temp[pos++] = (char)('0' + (value % 10));
  208.     while (value /= 10);
  209.     for (numDigits -= pos; numDigits > 0; numDigits--)
  210.         *s++ = '0';
  211.     do
  212.         *s++ = temp[--pos];
  213.     while (pos);
  214.     *s = '\0';
  215.     return s;
  216. }
  217.  
  218. static void UIntToStr_2(char *s, unsigned value)
  219. {
  220.     s[0] = (char)('0' + (value / 10));
  221.     s[1] = (char)('0' + (value % 10));
  222. }
  223.  
  224. static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
  225. {
  226.   CBuf buf;
  227.   WRes res;
  228.   Buf_Init(&buf);
  229.   RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM));
  230.   printf("open file %s\n", (const char *)buf.data);
  231.   res = OutFile_Open(p, (const char *)buf.data);
  232.   Buf_Free(&buf, &g_Alloc);
  233.   return res;
  234. }
  235.  
  236. int create_dir(const char *path)
  237. {
  238.      int retval;
  239.      __asm__ __volatile__ (
  240.      "pushl $0 \n\t"
  241.      "pushl $0 \n\t"
  242.      "movl %1, 1(%%esp) \n\t"
  243.      "pushl $0 \n\t"
  244.      "pushl $0 \n\t"
  245.      "pushl $0 \n\t"
  246.      "pushl $0 \n\t"
  247.      "pushl $9 \n\t"
  248.      "movl %%esp, %%ebx \n\t"
  249.      "movl $70, %%eax \n\t"
  250.      "int $0x40 \n\t"
  251.      "addl $28, %%esp \n\t"
  252.      :"=a" (retval)
  253.      :"r" (path)
  254.      :"ebx");
  255.   return retval;
  256. };
  257.  
  258. static WRes MyCreateDir(const UInt16 *name)
  259. {
  260.   CBuf buf;
  261.   WRes res;
  262.   Buf_Init(&buf);
  263.   RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM));
  264.  
  265.   res = create_dir((const char *)buf.data) == 0 ? 0 : -1;
  266.   Buf_Free(&buf, &g_Alloc);
  267.   return res;
  268. }
  269.  
  270. static SRes PrintString(const UInt16 *s)
  271. {
  272.     CBuf buf;
  273.     SRes res;
  274.     Buf_Init(&buf);
  275.     res = Utf16_To_Char(&buf, s);
  276.     if (res == SZ_OK)
  277.         fputs((const char *)buf.data, stdout);
  278.     Buf_Free(&buf, &g_Alloc);
  279.     return res;
  280. }
  281.  
  282. void PrintError(char *sz)
  283. {
  284.     printf("\nERROR: %s\n", sz);
  285. }
  286.  
  287. static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
  288. {
  289.     unsigned year, mon, hour, min, sec;
  290.     Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  291.     unsigned t;
  292.     UInt32 v;
  293.     UInt64 v64 = nt->Low | ((UInt64)nt->High << 32);
  294.     v64 /= 10000000;
  295.     sec = (unsigned)(v64 % 60); v64 /= 60;
  296.     min = (unsigned)(v64 % 60); v64 /= 60;
  297.     hour = (unsigned)(v64 % 24); v64 /= 24;
  298.  
  299.     v = (UInt32)v64;
  300.  
  301.     year = (unsigned)(1601 + v / PERIOD_400 * 400);
  302.     v %= PERIOD_400;
  303.  
  304.     t = v / PERIOD_100; if (t ==  4) t =  3; year += t * 100; v -= t * PERIOD_100;
  305.     t = v / PERIOD_4;   if (t == 25) t = 24; year += t * 4;   v -= t * PERIOD_4;
  306.     t = v / 365;        if (t ==  4) t =  3; year += t;       v -= t * 365;
  307.  
  308.     if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
  309.         ms[1] = 29;
  310.     for (mon = 0;; mon++)
  311.     {
  312.         unsigned s = ms[mon];
  313.         if (v < s)
  314.             break;
  315.         v -= s;
  316.     }
  317.     s = UIntToStr(s, year, 4); *s++ = '-';
  318.     UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3;
  319.     UIntToStr_2(s, (unsigned)v + 1); s[2] = ' '; s += 3;
  320.     UIntToStr_2(s, hour); s[2] = ':'; s += 3;
  321.     UIntToStr_2(s, min); s[2] = ':'; s += 3;
  322.     UIntToStr_2(s, sec); s[2] = 0;
  323. }
  324.  
  325.  
  326.  
  327. void do_install(list_t *install)
  328. {
  329.     CFileInStream archiveStream;
  330.     CLookToRead lookStream;
  331.     CSzArEx db;
  332.     SRes res;
  333.     ISzAlloc allocImp;
  334.     ISzAlloc allocTempImp;
  335.     UInt16 *temp = NULL;
  336.     size_t tempSize = 0;
  337.  
  338.     package_t   *pkg, *tmp;
  339.     char        *cache_path;
  340.  
  341.     allocImp.Alloc = SzAlloc;
  342.     allocImp.Free = SzFree;
  343.  
  344.     allocTempImp.Alloc = SzAllocTemp;
  345.     allocTempImp.Free = SzFreeTemp;
  346.  
  347.     list_for_each_entry_safe(pkg, tmp, install, list)
  348.     {
  349.         cache_path = make_cache_path(pkg->filename);
  350.  
  351.         if (InFile_Open(&archiveStream.file, cache_path))
  352.             continue;
  353.  
  354.         FileInStream_CreateVTable(&archiveStream);
  355.         LookToRead_CreateVTable(&lookStream, False);
  356.  
  357.         lookStream.realStream = &archiveStream.s;
  358.         LookToRead_Init(&lookStream);
  359.  
  360.         SzArEx_Init(&db);
  361.  
  362.         res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
  363.  
  364.         if (res == SZ_OK)
  365.         {
  366.             UInt32 i;
  367.             UInt32 blockIndex    = 0xFFFFFFFF;  /* it can have any value before first call (if outBuffer = 0) */
  368.             Byte *outBuffer      = 0;           /* it must be 0 before first call for each new archive. */
  369.             size_t outBufferSize = 0;           /* it can have any value before first call (if outBuffer = 0) */
  370.  
  371.             for (i = 0; i < db.NumFiles; i++)
  372.             {
  373.                 size_t offset = 0;
  374.                 size_t outSizeProcessed = 0;
  375.                 size_t len;
  376.                 unsigned isDir = SzArEx_IsDir(&db, i);
  377.  
  378.                 if ( isDir )
  379.                     continue;
  380.  
  381.                 len = SzArEx_GetFileNameUtf16(&db, i, NULL);
  382.  
  383.                 if (len > tempSize)
  384.                 {
  385.                     SzFree(NULL, temp);
  386.                     tempSize = len;
  387.                     temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
  388.                     if (!temp)
  389.                     {
  390.                         res = SZ_ERROR_MEM;
  391.                         break;
  392.                     }
  393.                 }
  394.  
  395.                 SzArEx_GetFileNameUtf16(&db, i, temp);
  396.                 res = PrintString(temp);
  397.                 if (res != SZ_OK)
  398.                     break;
  399.                 printf("\n");
  400.  
  401.                 if (isDir)
  402.                     printf("/");
  403.                 else
  404.                 {
  405.                     res = SzArEx_Extract(&db, &lookStream.s, i,
  406.                           &blockIndex, &outBuffer, &outBufferSize,
  407.                           &offset, &outSizeProcessed,
  408.                            &allocImp, &allocTempImp);
  409.                     if (res != SZ_OK)
  410.                         break;
  411.                 }
  412.  
  413.                 if (1)
  414.                 {
  415.                     CSzFile outFile;
  416.                     size_t processedSize;
  417.                     size_t j;
  418.                     UInt16 *name = (UInt16 *)temp;
  419.                     const UInt16 *destPath = (const UInt16 *)name;
  420.  
  421.                     for (j = 0; name[j] != 0; j++)
  422.                         if (name[j] == '/')
  423.                     {
  424.                         if (1)
  425.                         {
  426.                             name[j] = 0;
  427.                             MyCreateDir(name);
  428.                             name[j] = CHAR_PATH_SEPARATOR;
  429.                         }
  430.                         else
  431.                             destPath = name + j + 1;
  432.                     }
  433.  
  434.                     if (isDir)
  435.                     {
  436.                         MyCreateDir(destPath);
  437.                         printf("\n");
  438.                         continue;
  439.                     }
  440.                     else if (OutFile_OpenUtf16(&outFile, destPath))
  441.                     {
  442.                         PrintError("can not open output file");
  443.                         res = SZ_ERROR_FAIL;
  444.                         break;
  445.                     }
  446.  
  447.                     processedSize = outSizeProcessed;
  448.  
  449.                     if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
  450.                     {
  451.                         PrintError("can not write output file");
  452.                         res = SZ_ERROR_FAIL;
  453.                         break;
  454.                     }
  455.  
  456.                     if (File_Close(&outFile))
  457.                     {
  458.                         PrintError("can not close output file");
  459.                         res = SZ_ERROR_FAIL;
  460.                         break;
  461.                     }
  462.                 };
  463.                 continue;
  464.             };
  465.         };
  466.     };
  467.  
  468. };
  469.  
  470.