Subversion Repositories Kolibri OS

Rev

Rev 5728 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5728 Rev 5729
Line 4... Line 4...
4
#include "7zAlloc.h"
4
#include "7zAlloc.h"
5
#include "7zBuf.h"
5
#include "7zBuf.h"
6
#include "7zCrc.h"
6
#include "7zCrc.h"
7
#include "7zFile.h"
7
#include "7zFile.h"
8
#include "7zVersion.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
Line 9... Line 23...
9
 
23
 
Line -... Line 24...
-
 
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
}
10
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
33
 
11
 
34
 
12
int test_archive(const char *path)
35
int test_archive(const char *path)
13
{
36
{
14
    CFileInStream archiveStream;
37
    CFileInStream archiveStream;
Line 50... Line 73...
50
 
73
 
51
    if (res == SZ_OK)
74
    if (res == SZ_OK)
52
        return 0;
75
        return 0;
53
    else return -1;
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
};