Subversion Repositories Kolibri OS

Rev

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