Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6725 siemargl 1
/*
2
  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
3
 
4
  See the accompanying file LICENSE, version 2000-Apr-09 or later
5
  (the contents of which are also included in unzip.h) for terms of use.
6
  If, for some reason, all these files are missing, the Info-ZIP license
7
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
8
*/
9
/*---------------------------------------------------------------------------
10
 
11
  macos.c
12
 
13
  Macintosh-specific routines for use with Info-ZIP's UnZip 5.4 and later.
14
 
15
  Contains:
16
                    do_wild ()
17
                    mapattr ()
18
                    checkdir ()
19
                    version ()
20
                    macmkdir ()
21
                    macopen ()
22
                    maccreat ()
23
                    macread ()
24
                    macwrite ()
25
                    macclose ()
26
                    maclseek ()
27
                    BuildMacFilename()
28
                    SetFinderInfo ()
29
                    isMacOSexfield ()
30
                    makePPClong ()
31
                    makePPCword ()
32
                    PrintMacExtraInfo ()
33
                    GetExtraFieldData ()
34
                    DecodeMac3ExtraField ()
35
                    DecodeJLEEextraField ()
36
                    PrintTextEncoding ()
37
                    MacGlobalsInit ()
38
 
39
  ---------------------------------------------------------------------------*/
40
 
41
 
42
/*****************************************************************************/
43
/*  Includes                                                                 */
44
/*****************************************************************************/
45
 
46
#define UNZIP_INTERNAL
47
#include "unzip.h"
48
 
49
#include 
50
#include 
51
 
52
#include "pathname.h"
53
#include "helpers.h"
54
#include "macstuff.h"
55
#include "mactime.h"
56
#include "macbin3.h"
57
 
58
/*****************************************************************************/
59
/*  Macros, typedefs                                                         */
60
/*****************************************************************************/
61
 
62
/* disable ZipIt support
63
#define SwitchZIPITefSupportOff */
64
 
65
#define read_only   file_attr       /* for readability only */
66
#define EB_MAX_OF_VARDATA   1300    /* max possible datasize of extra-field */
67
 
68
#ifdef WILD_STOP_AT_DIR
69
#  define WESEP     , (oU.W_flag ? ':' : '\0')
70
#else
71
#  define WESEP
72
#endif
73
 
74
 
75
/*****************************************************************************/
76
/*  Global Vars                                                              */
77
/*****************************************************************************/
78
 
79
/*  Note: sizeof() returns the size of this allusion
80
          13 is current length of "XtraStuf.mac:"      */
81
extern const char ResourceMark[13]; /* var is initialized in file pathname.c */
82
 
83
Boolean MacUnzip_Noisy;            /* MacUnzip_Noisy is also used by console */
84
 
85
MACINFO newExtraField;  /* contains all extra-field data */
86
short MacZipMode;
87
 
88
 
89
/*****************************************************************************/
90
/*  Module level Vars                                                        */
91
/*****************************************************************************/
92
 
93
static const char MacPathEnd = ':';   /* the Macintosh dir separator */
94
 
95
static int created_dir;        /* used in mapname(), checkdir() */
96
static int renamed_fullpath;   /* ditto */
97
static FSSpec CurrentFile;
98
 
99
static Boolean OpenZipFile = true;
100
static Boolean UseUT_ExtraField     = false;
101
static Boolean IgnoreEF_Macfilename = false;
102
static short fileSystemID;
103
 
104
static uch *attrbuff = NULL;
105
static uch *malloced_attrbuff = NULL;
106
 
107
const short HFS_fileSystem = 0;
108
 
109
/*****************************************************************************/
110
/*  Prototypes                                                               */
111
/*****************************************************************************/
112
 
113
extern char *GetUnZipInfoVersions(void);
114
 
115
static OSErr SetFinderInfo(__GPRO__ int SetTime, FSSpec *spec, MACINFO *mi);
116
static Boolean GetExtraFieldData(short *MacZipMode, MACINFO *mi);
117
static uch *scanMacOSexfield(uch *ef_ptr, unsigned ef_len,
118
                             short *MacZipMode);
119
static Boolean isMacOSexfield(unsigned id, unsigned size, short *MacZipMode);
120
static void PrintMacExtraInfo(MACINFO *mi);
121
static OSErr SetFileTime(__GPRO);
122
static void DecodeMac3ExtraField(ZCONST uch *buff, MACINFO *mi);
123
static void DecodeJLEEextraField(ZCONST uch *buff, MACINFO *mi);
124
static void DecodeZPITextraField(ZCONST uch *buff, MACINFO *mi);
125
static char *PrintTextEncoding(short script);
126
static void BuildMacFilename(void);
127
 
128
/*****************************************************************************/
129
/*  Constants (strings, etc.)                                                */
130
/*****************************************************************************/
131
 
132
static ZCONST char Far CannotCreateFile[] = "error:  cannot create %s\n";
133
 
134
static ZCONST char Far OutOfMemEF[] = "Can't allocate memory to uncompress"\
135
                                      " file attributes.\n";
136
 
137
static ZCONST char Far ErrUncmpEF[] = "Error uncompressing file attributes.\n";
138
 
139
static ZCONST char Far No64Time[]   = "Don't support 64 bit Timevalues; get "\
140
                                      " a newer version of MacZip \n";
141
 
142
static ZCONST char Far NoUniCode[]  = "Don't support Unicoded Filenames; get"\
143
                                      " a newer version of MacZip\n";
144
 
145
static ZCONST char Far ZitIt_EF[]   = "warning: found ZipIt extra field  "\
146
                                      " -> file is probably not "\
147
                                      "usable!!\n";
148
 
149
static ZCONST char Far CantAllocateWildcard[] =
150
    "warning:  cannot allocate wildcard buffers\n";
151
 
152
static ZCONST char Far ErrNoTimeSet[] = "error (%d): cannot set the time for"\
153
                                        " %s\n";
154
 
155
static ZCONST char Far MacBinaryMsg[] = "\n   ... decoding MacBinary ";
156
 
157
static ZCONST char Far WarnDirTraversSkip[] =
158
  "warning:  skipped \"../\" path component(s) in %s\n";
159
 
160
static ZCONST char Far Creating[] = "   creating: %s\n";
161
 
162
static ZCONST char Far ConversionFailed[] =
163
  "mapname:  conversion of %s failed\n";
164
 
165
static ZCONST char Far PathTooLong[] = "checkdir error:  path too long: %s\n";
166
 
167
static ZCONST char Far CantCreateDir[] = "checkdir error:  cannot create %s\n\
168
                 unable to process %s.\n";
169
 
170
static ZCONST char Far DirIsntDirectory[] =
171
  "checkdir error:  %s exists but is not directory\n\
172
                 unable to process %s.\n";
173
 
174
static ZCONST char Far PathTooLongTrunc[] =
175
  "checkdir warning:  path too long; truncating\n                   %s\n\
176
                -> %s\n";
177
 
178
static ZCONST char Far CantCreateExtractDir[] =
179
  "checkdir:  cannot create extraction directory: %s\n";
180
 
181
static ZCONST char Far FilenameToLong[] =
182
  "Filename is to long; truncated: %s\n";
183
 
184
/*****************************************************************************/
185
/*  Functions                                                                */
186
/*****************************************************************************/
187
 
188
#ifndef SFX
189
 
190
/**********************/
191
/* Function do_wild() */   /* for porting: dir separator; match(ignore_case) */
192
/**********************/
193
 
194
char *do_wild(__G__ wildspec)
195
    __GDEF
196
    ZCONST char *wildspec;  /* only used first time on a given dir */
197
{
198
    static DIR *wild_dir = (DIR *)NULL;
199
    static ZCONST char *wildname;
200
    static char *dirname, matchname[FILNAMSIZ];
201
    static int notfirstcall=FALSE, have_dirname;
202
    static unsigned long dirnamelen;
203
    struct dirent *file;
204
 
205
    /* Even when we're just returning wildspec, we *always* do so in
206
     * matchname[]--calling routine is allowed to append four characters
207
     * to the returned string, and wildspec may be a pointer to argv[].
208
     */
209
    if (!notfirstcall) {    /* first call:  must initialize everything */
210
        notfirstcall = TRUE;
211
 
212
        /* Folder names must always end with a colon */
213
        if (uO.exdir[strlen(uO.exdir)-1] != ':') {
214
            strcat(uO.exdir, ":");
215
        }
216
 
217
        MacUnzip_Noisy = !uO.qflag;
218
 
219
        if (MacUnzip_Noisy) printf("%s \n\n", GetUnZipInfoVersions());
220
 
221
        /* break the wildspec into a directory part and a wildcard filename */
222
        if ((wildname = (ZCONST char *)strrchr(wildspec, ':')) ==
223
            (ZCONST char *)NULL) {
224
            dirname = ":";
225
            dirnamelen = 1;
226
            have_dirname = FALSE;
227
            wildname = wildspec;
228
        } else {
229
            ++wildname;     /* point at character after ':' */
230
            dirnamelen = wildname - wildspec;
231
            if ((dirname = (char *)malloc(dirnamelen+1)) == (char *)NULL) {
232
                Info(slide, 0x201, ((char *)slide,
233
                  LoadFarString(CantAllocateWildcard)));
234
                strncpy(matchname, wildspec, FILNAMSIZ);
235
                matchname[FILNAMSIZ-1] = '\0';
236
                return matchname;   /* but maybe filespec was not a wildcard */
237
            }
238
            strncpy(dirname, wildspec, dirnamelen);
239
            dirname[dirnamelen] = '\0';   /* terminate for strcpy below */
240
            have_dirname = TRUE;
241
        }
242
 
243
        if ((wild_dir = opendir(dirname)) != (DIR *)NULL) {
244
            while ((file = readdir(wild_dir)) != (struct dirent *)NULL) {
245
                if (match(file->d_name, wildname, 0 WESEP)) { /* 0=case sens.*/
246
                    if (have_dirname) {
247
                        strcpy(matchname, dirname);
248
                        strcpy(matchname+dirnamelen, file->d_name);
249
                    } else
250
                        strcpy(matchname, file->d_name);
251
                    return matchname;
252
                }
253
            }
254
            /* if we get to here directory is exhausted, so close it */
255
            closedir(wild_dir);
256
            wild_dir = (DIR *)NULL;
257
        }
258
 
259
        /* return the raw wildspec in case that works (e.g., directory not
260
         * searchable, but filespec was not wild and file is readable) */
261
        strncpy(matchname, wildspec, FILNAMSIZ);
262
        matchname[FILNAMSIZ-1] = '\0';
263
        return matchname;
264
    }
265
 
266
    /* last time through, might have failed opendir but returned raw wildspec */
267
    if (wild_dir == (DIR *)NULL) {
268
        notfirstcall = FALSE; /* nothing left to try--reset for new wildspec */
269
        if (have_dirname)
270
            free(dirname);
271
        return (char *)NULL;
272
    }
273
 
274
    /* If we've gotten this far, we've read and matched at least one entry
275
     * successfully (in a previous call), so dirname has been copied into
276
     * matchname already.
277
     */
278
    while ((file = readdir(wild_dir)) != (struct dirent *)NULL)
279
        if (match(file->d_name, wildname, 0 WESEP)) {   /* 0 == case sens. */
280
            if (have_dirname) {
281
                /* strcpy(matchname, dirname); */
282
                strcpy(matchname+dirnamelen, file->d_name);
283
            } else
284
                strcpy(matchname, file->d_name);
285
            return matchname;
286
        }
287
 
288
    closedir(wild_dir);     /* have read at least one entry; nothing left */
289
    wild_dir = (DIR *)NULL;
290
    notfirstcall = FALSE;   /* reset for new wildspec */
291
    if (have_dirname)
292
        free(dirname);
293
    return (char *)NULL;
294
 
295
} /* end function do_wild() */
296
 
297
#endif /* !SFX */
298
 
299
 
300
 
301
 
302
 
303
/***************************/
304
/* Function open_outfile() */
305
/***************************/
306
 
307
int open_outfile(__G)         /* return 1 if fail */
308
    __GDEF
309
{
310
    short outfd, fDataFork = true;
311
 
312
#ifdef DLL
313
    if (G.redirect_data)
314
        return (redirect_outfile(__G) == FALSE);
315
#endif
316
    Trace((stderr, "open_outfile:  trying to open (%s) for writing\n",
317
      FnFilter1(G.filename)));
318
 
319
    if (!uO.aflag) {
320
         /* unknown type documents */
321
         /* all files are considered to be of type 'TEXT' and creator 'hscd' */
322
         /* this is the default type for CDROM ISO-9660 without Apple extensions */
323
        newExtraField.fpb.hFileInfo.ioFlFndrInfo.fdType    =  'TEXT';
324
        newExtraField.fpb.hFileInfo.ioFlFndrInfo.fdCreator =  'hscd';
325
    } else {
326
     /* unknown text-files defaults to 'TEXT' */
327
        newExtraField.fpb.hFileInfo.ioFlFndrInfo.fdType    =  'TEXT';
328
     /* Bare Bones BBEdit */
329
        newExtraField.fpb.hFileInfo.ioFlFndrInfo.fdCreator =  'R*ch';
330
    }
331
 
332
    BuildMacFilename();
333
 
334
    if  (MacZipMode <= TomBrownZipIt2_EF)
335
        {
336
        fDataFork = true;
337
        }
338
    else
339
        {
340
        fDataFork = (newExtraField.flags & EB_M3_FL_DATFRK) ? TRUE : FALSE;
341
        }
342
 
343
 
344
    if ((outfd = maccreat(G.filename)) != -1) {
345
        outfd = macopen(G.filename, (fDataFork) ? 1 : 2);
346
    }
347
 
348
    if (outfd == -1) {
349
        G.outfile = (FILE *)NULL;
350
        Info(slide, 0x401, ((char *)slide, LoadFarString(CannotCreateFile),
351
          FnFilter1(G.filename)));
352
        return 1;
353
    }
354
    G.outfile = (FILE *)outfd;
355
    Trace((stderr, "open_outfile:  successfully opened (%s) for writing\n",
356
      FnFilter1(G.filename)));
357
 
358
    return 0;
359
 
360
} /* end function open_outfile() */
361
 
362
 
363
 
364
 
365
 
366
/**********************/
367
/* Function mapattr() */
368
/**********************/
369
 
370
int mapattr(__G)
371
    __GDEF
372
{
373
    /* only care about read-only bit, so just look at MS-DOS side of attrs */
374
    G.pInfo->read_only = (unsigned)(G.crec.external_file_attributes & 1);
375
    return 0;
376
 
377
} /* end function mapattr() */
378
 
379
 
380
 
381
 
382
 
383
/************************/
384
/*  Function mapname()  */
385
/************************/
386
 
387
int mapname(__G__ renamed)
388
    __GDEF
389
    int renamed;
390
/*
391
 * returns:
392
 *  MPN_OK          - no problem detected
393
 *  MPN_INF_TRUNC   - caution (truncated filename)
394
 *  MPN_INF_SKIP    - info "skip entry" (dir doesn't exist)
395
 *  MPN_ERR_SKIP    - error -> skip entry
396
 *  MPN_ERR_TOOLONG - error -> path is too long
397
 *  MPN_NOMEM       - error (memory allocation failed) -> skip entry
398
 *  [also MPN_VOL_LABEL, MPN_CREATED_DIR]
399
 */
400
{
401
    char pathcomp[FILNAMSIZ];      /* path-component buffer */
402
    char *pp, *cp=(char *)NULL;    /* character pointers */
403
    char *lastsemi=(char *)NULL;   /* pointer to last semi-colon in pathcomp */
404
    int killed_ddot = FALSE;       /* is set when skipping "../" pathcomp */
405
    int error = MPN_OK;
406
    register unsigned workch;      /* hold the character being tested */
407
 
408
 
409
/*---------------------------------------------------------------------------
410
    Initialize various pointers and counters and stuff.
411
  ---------------------------------------------------------------------------*/
412
 
413
    if (G.pInfo->vollabel)
414
        return MPN_VOL_LABEL;   /* can't set disk volume labels on Macintosh */
415
 
416
    /* can create path as long as not just freshening, or if user told us */
417
    G.create_dirs = (!uO.fflag || renamed);
418
 
419
    created_dir = FALSE;        /* not yet */
420
 
421
    /* user gave full pathname:  don't prepend rootpath */
422
    renamed_fullpath = (renamed && (*G.filename == '/'));
423
 
424
    if (checkdir(__G__ (char *)NULL, INIT) == MPN_NOMEM)
425
        return MPN_NOMEM;       /* initialize path buffer, unless no memory */
426
 
427
    *pathcomp = '\0';           /* initialize translation buffer */
428
    pp = pathcomp;              /* point to translation buffer */
429
 
430
    if (uO.jflag)               /* junking directories */
431
        cp = (char *)strrchr(G.filename, '/');
432
    if (cp == (char *)NULL) {   /* no '/' or not junking dirs */
433
        cp = G.filename;        /* point to internal zipfile-member pathname */
434
        if (renamed_fullpath)
435
            ++cp;               /* skip over leading '/' */
436
    } else
437
        ++cp;                   /* point to start of last component of path */
438
 
439
/*---------------------------------------------------------------------------
440
    Begin main loop through characters in filename.
441
  ---------------------------------------------------------------------------*/
442
 
443
    while ((workch = (uch)*cp++) != 0) {
444
 
445
        switch (workch) {
446
            case '/':             /* can assume -j flag not given */
447
                *pp = '\0';
448
                if (strcmp(pathcomp, ".") == 0) {
449
                    /* don't bother appending "./" to the path */
450
                    *pathcomp = '\0';
451
                } else if (!uO.ddotflag && strcmp(pathcomp, "..") == 0) {
452
                    /* "../" dir traversal detected, skip over it */
453
                    *pathcomp = '\0';
454
                    killed_ddot = TRUE;     /* set "show message" flag */
455
                }
456
                /* when path component is not empty, append it now */
457
                if (*pathcomp != '\0' &&
458
                    ((error = checkdir(__G__ pathcomp, APPEND_DIR))
459
                     & MPN_MASK) > MPN_INF_TRUNC)
460
                    return error;
461
                pp = pathcomp;    /* reset conversion buffer for next piece */
462
                lastsemi = (char *)NULL; /* leave direct. semi-colons alone */
463
                break;
464
 
465
            case ':':
466
                *pp++ = '/';      /* ':' is a pathseperator for HFS  */
467
                break;
468
 
469
            case ';':             /* VMS version (or DEC-20 attrib?) */
470
                lastsemi = pp;         /* keep for now; remove VMS ";##" */
471
                *pp++ = (char)workch;  /*  later, if requested */
472
                break;
473
 
474
            default:
475
                /* allow European characters in filenames: */
476
                if (isprint(workch) || (128 <= workch && workch <= 254))
477
                    *pp++ = (char)workch;
478
        } /* end switch */
479
 
480
    } /* end while loop */
481
 
482
    /* Show warning when stripping insecure "parent dir" path components */
483
    if (killed_ddot && QCOND2) {
484
        Info(slide, 0, ((char *)slide, LoadFarString(WarnDirTraversSkip),
485
          FnFilter1(G.filename)));
486
        if (!(error & ~MPN_MASK))
487
            error = (error & MPN_MASK) | PK_WARN;
488
    }
489
 
490
/*---------------------------------------------------------------------------
491
    Report if directory was created (and no file to create:  filename ended
492
    in '/'), check name to be sure it exists, and combine path and name be-
493
    fore exiting.
494
  ---------------------------------------------------------------------------*/
495
 
496
    if (G.filename[strlen(G.filename) - 1] == '/') {
497
        checkdir(__G__ G.filename, GETPATH);
498
        if (created_dir) {
499
            if (QCOND2) {
500
                Info(slide, 0, ((char *)slide, LoadFarString(Creating),
501
                  FnFilter1(G.filename)));
502
            }
503
            /* set dir time (note trailing '/') */
504
            return (error & ~MPN_MASK) | MPN_CREATED_DIR;
505
        }
506
        /* dir existed already; don't look for data to extract */
507
        return (error & ~MPN_MASK) | MPN_INF_SKIP;
508
    }
509
 
510
    *pp = '\0';                   /* done with pathcomp:  terminate it */
511
 
512
    /* if not saving them, remove VMS version numbers (appended ";###") */
513
    if (!uO.V_flag && lastsemi) {
514
        pp = lastsemi + 1;
515
        while (isdigit((uch)(*pp)))
516
            ++pp;
517
        if (*pp == '\0')          /* only digits between ';' and end:  nuke */
518
            *lastsemi = '\0';
519
    }
520
 
521
    if (*pathcomp == '\0') {
522
        Info(slide, 1, ((char *)slide, LoadFarString(ConversionFailed),
523
          FnFilter1(G.filename)));
524
        return (error & ~MPN_MASK) | MPN_ERR_SKIP;
525
    }
526
 
527
    checkdir(__G__ pathcomp, APPEND_NAME);  /* returns 1 if truncated: care? */
528
    checkdir(__G__ G.filename, GETPATH);
529
 
530
    return error;
531
 
532
} /* end function mapname() */
533
 
534
 
535
 
536
 
537
 
538
/***********************/
539
/* Function checkdir() */
540
/***********************/
541
 
542
int checkdir(__G__ pathcomp, flag)
543
    __GDEF
544
    char *pathcomp;
545
    int flag;
546
/*
547
 * returns:
548
 *  MPN_OK          - no problem detected
549
 *  MPN_INF_TRUNC   - (on APPEND_NAME) truncated filename
550
 *  MPN_INF_SKIP    - path doesn't exist, not allowed to create
551
 *  MPN_ERR_SKIP    - path doesn't exist, tried to create and failed; or path
552
 *                    exists and is not a directory, but is supposed to be
553
 *  MPN_ERR_TOOLONG - path is too long
554
 *  MPN_NOMEM       - can't allocate memory for filename buffers
555
 */
556
{
557
    static int rootlen = 0;   /* length of rootpath */
558
    static char *rootpath;    /* user's "extract-to" directory */
559
    static char *buildpath;   /* full path (so far) to extracted file */
560
    static char *end;         /* pointer to end of buildpath ('\0') */
561
 
562
#   define FN_MASK   7
563
#   define FUNCTION  (flag & FN_MASK)
564
 
565
 
566
/*---------------------------------------------------------------------------
567
    APPEND_DIR:  append the path component to the path being built and check
568
    for its existence.  If doesn't exist and we are creating directories, do
569
    so for this one; else signal success or error as appropriate.
570
  ---------------------------------------------------------------------------*/
571
 
572
    if (FUNCTION == APPEND_DIR) {
573
        int too_long = FALSE;
574
#ifdef SHORT_NAMES
575
        char *old_end = end;
576
#endif
577
 
578
        Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp)));
579
        while ((*end = *pathcomp++) != '\0')
580
            ++end;
581
#ifdef SHORT_NAMES   /* path components restricted to 14 chars, typically */
582
        if ((end-old_end) > NAME_MAX)
583
            *(end = old_end + NAME_MAX) = '\0';
584
#endif
585
 
586
        /* GRR:  could do better check, see if overrunning buffer as we go:
587
         * check end-buildpath after each append, set warning variable if
588
         * within 20 of FILNAMSIZ; then if var set, do careful check when
589
         * appending.  Clear variable when begin new path. */
590
 
591
        if ((end-buildpath) > NAME_MAX-3)   /* need ':', one-char name, '\0' */
592
            too_long = TRUE;                /* check if extracting directory? */
593
        if (stat(buildpath, &G.statbuf)) {  /* path doesn't exist */
594
            if (!G.create_dirs) { /* told not to create (freshening) */
595
                free(buildpath);
596
                return MPN_INF_SKIP;    /* path doesn't exist: nothing to do */
597
            }
598
            if (too_long) {
599
                Info(slide, 1, ((char *)slide, LoadFarString(PathTooLong),
600
                  FnFilter1(buildpath)));
601
                free(buildpath);
602
                /* no room for filenames:  fatal */
603
                return MPN_ERR_TOOLONG;
604
            }
605
            if (macmkdir(buildpath) == -1) {   /* create the directory */
606
                Info(slide, 1, ((char *)slide, LoadFarString(CantCreateDir),
607
                  FnFilter2(buildpath), FnFilter1(G.filename)));
608
                free(buildpath);
609
                /* path didn't exist, tried to create, failed */
610
                return MPN_ERR_SKIP;
611
            }
612
            created_dir = TRUE;
613
        } else if (!S_ISDIR(G.statbuf.st_mode)) {
614
            Info(slide, 1, ((char *)slide, LoadFarString(DirIsntDirectory),
615
              FnFilter2(buildpath), FnFilter1(G.filename)));
616
            free(buildpath);
617
            /* path existed but wasn't dir */
618
            return MPN_ERR_SKIP;
619
        }
620
        if (too_long) {
621
            Info(slide, 1, ((char *)slide, LoadFarString(PathTooLong),
622
              FnFilter1(buildpath)));
623
            free(buildpath);
624
            /* no room for filenames:  fatal */
625
            return MPN_ERR_TOOLONG;
626
        }
627
        *end++ = ':';
628
        *end = '\0';
629
        Trace((stderr, "buildpath now = [%s]\n", FnFilter1(buildpath)));
630
        return MPN_OK;
631
 
632
    } /* end if (FUNCTION == APPEND_DIR) */
633
 
634
/*---------------------------------------------------------------------------
635
    GETPATH:  copy full path to the string pointed at by pathcomp, and free
636
    buildpath.
637
  ---------------------------------------------------------------------------*/
638
 
639
    if (FUNCTION == GETPATH) {
640
        strcpy(pathcomp, buildpath);
641
        Trace((stderr, "getting and freeing path [%s]\n",
642
          FnFilter1(pathcomp)));
643
        free(buildpath);
644
        buildpath = end = (char *)NULL;
645
        return MPN_OK;
646
    }
647
 
648
/*---------------------------------------------------------------------------
649
    APPEND_NAME:  assume the path component is the filename; append it and
650
    return without checking for existence.
651
  ---------------------------------------------------------------------------*/
652
 
653
    if (FUNCTION == APPEND_NAME) {
654
#ifdef SHORT_NAMES
655
        char *old_end = end;
656
#endif
657
 
658
        Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));
659
        while ((*end = *pathcomp++) != '\0') {
660
            ++end;
661
#ifdef SHORT_NAMES  /* truncate name at 14 characters, typically */
662
            if ((end-old_end) > NAME_MAX)
663
                *(end = old_end + NAME_MAX) = '\0';
664
#endif
665
            if ((end-buildpath) >= NAME_MAX) {
666
                *--end = '\0';
667
                Info(slide, 0x201, ((char *)slide,
668
                  LoadFarString(PathTooLongTrunc),
669
                  FnFilter1(G.filename), FnFilter2(buildpath)));
670
                return MPN_INF_TRUNC;   /* filename truncated */
671
            }
672
        }
673
        Trace((stderr, "buildpath now = [%s]\n", FnFilter1(buildpath)));
674
        /* could check for existence here, prompt for new name... */
675
        return MPN_OK;
676
    }
677
 
678
/*---------------------------------------------------------------------------
679
    INIT:  allocate and initialize buffer space for the file currently being
680
    extracted.  If file was renamed with an absolute path, don't prepend the
681
    extract-to path.
682
  ---------------------------------------------------------------------------*/
683
 
684
    if (FUNCTION == INIT) {
685
        Trace((stderr, "initializing buildpath to "));
686
        if ((buildpath = (char *)malloc(strlen(G.filename)+rootlen+2))
687
            == (char *)NULL)
688
            return MPN_NOMEM;
689
        if ((rootlen > 0) && !renamed_fullpath) {
690
            strcpy(buildpath, rootpath);
691
            end = buildpath + rootlen;
692
        } else {
693
            end = buildpath;
694
            if (!renamed_fullpath && !uO.jflag) {
695
                *end++ = ':';           /* indicate relative path */
696
            }
697
            *end = '\0';
698
        }
699
        Trace((stderr, "[%s]\n", FnFilter1(buildpath)));
700
        return MPN_OK;
701
    }
702
 
703
/*---------------------------------------------------------------------------
704
    ROOT:  if appropriate, store the path in rootpath and create it if
705
    necessary; else assume it's a zipfile member and return.  This path
706
    segment gets used in extracting all members from every zipfile specified
707
    on the command line.
708
  ---------------------------------------------------------------------------*/
709
 
710
#if (!defined(SFX) || defined(SFX_EXDIR))
711
    if (FUNCTION == ROOT) {
712
        Trace((stderr, "initializing root path to [%s]\n",
713
          FnFilter1pathcomp)));
714
        if (pathcomp == (char *)NULL) {
715
            rootlen = 0;
716
            return MPN_OK;
717
        }
718
        if (rootlen > 0)        /* rootpath was already set, nothing to do */
719
            return MPN_OK;
720
        if ((rootlen = strlen(pathcomp)) > 0) {
721
            char *tmproot;
722
 
723
            if ((tmproot = (char *)malloc(rootlen+2)) == (char *)NULL) {
724
                rootlen = 0;
725
                return MPN_NOMEM;
726
            }
727
            strcpy(tmproot, pathcomp);
728
            if (tmproot[rootlen-1] == ':') {
729
                tmproot[--rootlen] = '\0';     /* strip trailing delimiter */
730
            }
731
            if (rootlen > 0 && (stat(tmproot, &G.statbuf) ||
732
                !S_ISDIR(G.statbuf.st_mode)))
733
            {   /* path does not exist */
734
                if (!G.create_dirs /* || iswild(tmproot) */ ) {
735
                    free(tmproot);
736
                    rootlen = 0;
737
                    /* skip (or treat as stored file) */
738
                    return MPN_INF_SKIP;
739
                }
740
                /* create the directory (could add loop here scanning tmproot
741
                 * to create more than one level, but why really necessary?) */
742
                if (macmkdir(tmproot) == -1) {
743
                    Info(slide, 1, ((char *)slide,
744
                      LoadFarString(CantCreateExtractDir),
745
                      FnFilter1(tmproot)));
746
                    free(tmproot);
747
                    rootlen = 0;
748
                    /* path didn't exist, tried to create, and failed: */
749
                    /* file exists, or 2+ subdir levels required */
750
                    return MPN_ERR_SKIP;
751
                }
752
            }
753
            tmproot[rootlen++] = ':';
754
            tmproot[rootlen] = '\0';
755
            if ((rootpath = (char *)realloc(tmproot, rootlen+1)) == NULL) {
756
                free(tmproot);
757
                rootlen = 0;
758
                return MPN_NOMEM;
759
            }
760
            Trace((stderr, "rootpath now = [%s]\n", FnFilter1(rootpath)));
761
        }
762
        return MPN_OK;
763
    }
764
#endif /* !SFX || SFX_EXDIR */
765
 
766
/*---------------------------------------------------------------------------
767
    END:  free rootpath, immediately prior to program exit.
768
  ---------------------------------------------------------------------------*/
769
 
770
    if (FUNCTION == END) {
771
        Trace((stderr, "freeing rootpath\n"));
772
        if (rootlen > 0) {
773
            free(rootpath);
774
            rootlen = 0;
775
        }
776
        return MPN_OK;
777
    }
778
 
779
    return MPN_INVALID; /* should never reach */
780
 
781
} /* end function checkdir() */
782
 
783
 
784
 
785
 
786
 
787
/****************************/
788
/* Function close_outfile() */
789
/****************************/
790
 
791
void close_outfile(__G)
792
    __GDEF
793
{
794
    OSErr err;
795
 
796
    if (fileno(G.outfile) == 1)
797
        return;         /* don't attempt to close or set time on stdout */
798
 
799
    err = (OSErr)fclose(G.outfile);
800
 
801
    /* finally set FinderInfo */
802
    if  (MacZipMode >= JohnnyLee_EF)
803
        {
804
        /* skip restoring time stamps on user's request */
805
        err = SetFinderInfo(__G__ (uO.D_flag <= 1),
806
                            &CurrentFile, &newExtraField);
807
        printerr("close_outfile SetFinderInfo ", err, err,
808
                 __LINE__, __FILE__, G.filename);
809
        }
810
    else  /* unknown extra field, set at least file time/dates */
811
        {
812
        /* skip restoring time stamps on user's request */
813
        if (uO.D_flag <= 1)
814
            err = SetFileTime(__G);
815
        }
816
 
817
#ifndef SwitchZIPITefSupportOff
818
    if ((MacZipMode == TomBrownZipIt1_EF) ||
819
        (MacZipMode == TomBrownZipIt2_EF))
820
        {
821
        if(FSpIsMacBinary(&CurrentFile))
822
            {
823
            Info(slide, 0, ((char *)slide, LoadFarString(MacBinaryMsg)));
824
                err = DecodeMacBinaryFile(&CurrentFile);
825
                printerr("close_outfile DecodeMacBinaryFile ", err, err,
826
                  __LINE__, __FILE__, G.filename);
827
            }
828
        }
829
#endif
830
 
831
        /* set read-only perms if needed */
832
    if ((err == noErr) && G.pInfo->read_only)
833
        {
834
        err = FSpSetFLock(&CurrentFile);
835
        printerr("FSpSetFLock",err,err,__LINE__,__FILE__,G.filename);
836
        }
837
 
838
    if (malloced_attrbuff != NULL)
839
        {
840
        attrbuff = malloced_attrbuff;
841
        }
842
 
843
} /* end function close_outfile() */
844
 
845
 
846
 
847
 
848
/****************************/
849
/* Function SetFileTime() */
850
/****************************/
851
 
852
static OSErr SetFileTime(__G)
853
    __GDEF
854
{
855
#ifdef USE_EF_UT_TIME
856
    iztimes z_utime;
857
    unsigned eb_izux_flg;
858
#endif
859
    OSErr err;
860
    CInfoPBRec      fpb;
861
 
862
    fpb.hFileInfo.ioNamePtr    = CurrentFile.name;
863
    fpb.hFileInfo.ioVRefNum    = CurrentFile.vRefNum;
864
    fpb.hFileInfo.ioDirID      = CurrentFile.parID;
865
    fpb.hFileInfo.ioFDirIndex  = 0;
866
 
867
    err = PBGetCatInfoSync((CInfoPBPtr)&fpb);
868
    printerr("PBGetCatInfoSync", err, err, __LINE__, __FILE__, G.filename);
869
 
870
    if ((MacZipMode == UnKnown_EF) || UseUT_ExtraField ) {
871
 
872
#ifdef USE_EF_UT_TIME
873
        eb_izux_flg = ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0,
874
                                       G.lrec.last_mod_dos_datetime, &z_utime, NULL);
875
 
876
        if (G.extra_field && (eb_izux_flg & EB_UT_FL_MTIME))
877
            {
878
            fpb.hFileInfo.ioFlMdDat = UnixFtime2MacFtime(z_utime.mtime);
879
            fpb.hFileInfo.ioFlCrDat = UnixFtime2MacFtime(z_utime.ctime);
880
            }
881
 
882
#ifdef DEBUG_TIME
883
            {
884
            struct tm *tp = gmtime(&z_utime.ctime);
885
            printf(
886
              "SetFileTime:  Unix e.f. creat. time = %d/%2d/%2d  %2d:%2d:%2d -> %lu UTC\n",
887
              tp->tm_year, tp->tm_mon+1, tp->tm_mday,
888
              tp->tm_hour, tp->tm_min, tp->tm_sec, z_utime.ctime);
889
            tp = gmtime(&z_utime.mtime);
890
            printf(
891
              "SetFileTime:  Unix e.f. modif. time = %d/%2d/%2d  %2d:%2d:%2d -> %lu UTC\n",
892
              tp->tm_year, tp->tm_mon+1, tp->tm_mday,
893
              tp->tm_hour, tp->tm_min, tp->tm_sec, z_utime.mtime);
894
            }
895
#endif /* DEBUG_TIME */
896
 
897
 
898
        else /* no Unix time field found - use dostime  */
899
#endif /* !USE_EF_UT_TIME */
900
            {
901
            TTrace((stderr, "SetFileTime:  using DOS-Datetime ! \n",
902
                    z_utime.mtime));
903
            fpb.hFileInfo.ioFlMdDat = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
904
            UNIX_TO_MACOS(fpb.hFileInfo.ioFlMdDat);
905
            fpb.hFileInfo.ioFlCrDat = fpb.hFileInfo.ioFlMdDat;
906
            }
907
 
908
     /* Restore ioDirID field in pb which was changed by PBGetCatInfoSync */
909
        fpb.hFileInfo.ioDirID = CurrentFile.parID;
910
 
911
        if (err == noErr)
912
            {
913
            err = PBSetCatInfoSync((CInfoPBPtr)&fpb);
914
            printerr("PBSetCatInfoSync",err,err,__LINE__,__FILE__,G.filename);
915
            }
916
        if (err != noErr)
917
            Info(slide, 0x201, ((char *)slide, LoadFarString(ErrNoTimeSet),
918
              FnFilter1(G.filename)));
919
    }
920
 
921
return err;
922
} /* end function SetFileTime() */
923
 
924
 
925
 
926
 
927
#ifndef SFX
928
 
929
/************************/
930
/*  Function version()  */
931
/************************/
932
 
933
void version(__G)
934
    __GDEF
935
{
936
/*
937
ZCONST char Far CompiledWith[] =
938
               "Compiled with %s%s for %s%s%s%s.\n\n"; */
939
 
940
char DateTime[50];
941
 
942
#ifdef __MWERKS__
943
char CompVer[10];
944
sprintf(CompVer, "%x", __MWERKS__);
945
#endif
946
 
947
    sprintf(DateTime,"%s  %s",__DATE__, __TIME__);
948
 
949
    sprintf((char *)slide, LoadFarString(CompiledWith),
950
 
951
#ifdef __MWERKS__
952
 
953
      " Metrowerks CodeWarrior version ",CompVer,
954
#else
955
      " ", " ",
956
#endif
957
 
958
#ifdef __MC68K__
959
      " MC68K Processor",
960
#else
961
      " PowerPC Processor",
962
#endif
963
 
964
#ifdef __DATE__
965
 
966
      "\n compile time: ", DateTime, ""
967
#else
968
      "", "", ""
969
#endif
970
    );
971
 
972
    (*G.message)((zvoid *)&G, slide, (ulg)strlen((char *)slide), 0);
973
 
974
} /* end function version() */
975
 
976
#endif /* !SFX */
977
 
978
 
979
 
980
 
981
 
982
/***********************/
983
/* Function macmkdir() */
984
/***********************/
985
 
986
int macmkdir(char *path)
987
{
988
    OSErr err = -1;
989
    OSErr err_rc;
990
    char CompletePath[NAME_MAX], CompletePath2[NAME_MAX];
991
    Boolean isDirectory = false;
992
    short CurrentFork;
993
    unsigned pathlen;
994
    long dirID;
995
 
996
    AssertStr(path, path)
997
 
998
    GetExtraFieldData(&MacZipMode, &newExtraField);
999
 
1000
    if (MacZipMode >= JohnnyLee_EF) {
1001
        RfDfFilen2Real(CompletePath, G.filename, MacZipMode,
1002
                       (newExtraField.flags & EB_M3_FL_NOCHANGE), &CurrentFork);
1003
        if (CurrentFork == ResourceFork)
1004
            /* don't build a 'XtraStuf.mac:' dir  */
1005
            return 0;
1006
    }
1007
 
1008
    if (!IgnoreEF_Macfilename)
1009
        {
1010
        pathlen = strlen(path);
1011
        strcpy(CompletePath, uO.exdir);
1012
        strcat(CompletePath, newExtraField.FullPath);
1013
        CompletePath[pathlen] = 0x00;
1014
        }
1015
    else
1016
        {
1017
        strcpy(CompletePath, path);
1018
        }
1019
 
1020
    GetCompletePath(CompletePath2, CompletePath, &CurrentFile, &err);
1021
    printerr("GetCompletePath", (err != -43) && (err != -120) && (err != 0),
1022
              err, __LINE__, __FILE__, CompletePath2);
1023
 
1024
 
1025
    err = FSpGetDirectoryID(&CurrentFile, &dirID, &isDirectory);
1026
    printerr("macmkdir FSpGetDirectoryID ", (err != -43) && (err != 0),
1027
             err, __LINE__, __FILE__, CompletePath2);
1028
 
1029
    if (err != -43)     /* -43 = file/directory not found  */
1030
        return 0;
1031
    else {
1032
        HParamBlockRec    hpbr;
1033
 
1034
        hpbr.fileParam.ioCompletion = NULL;
1035
        hpbr.fileParam.ioNamePtr    = CurrentFile.name;
1036
        hpbr.fileParam.ioVRefNum    = CurrentFile.vRefNum;
1037
        hpbr.fileParam.ioDirID      = CurrentFile.parID;
1038
        err = PBDirCreateSync(&hpbr);
1039
        printerr("macmkdir PBDirCreateSync ", err,
1040
                 err, __LINE__, __FILE__, CompletePath2);
1041
 
1042
        /* finally set FinderInfo */
1043
        if  (MacZipMode >= JohnnyLee_EF)
1044
            {
1045
            err_rc = SetFinderInfo(__G__ (uO.D_flag <= 0),
1046
                                   &CurrentFile, &newExtraField);
1047
            printerr("macmkdir SetFinderInfo ", err_rc, err_rc,
1048
                      __LINE__, __FILE__, CompletePath2);
1049
            }
1050
    }
1051
 
1052
    return (int)err;
1053
} /* macmkdir */
1054
 
1055
 
1056
 
1057
 
1058
/**********************/
1059
/* Function macopen() */
1060
/**********************/
1061
 
1062
short macopen(char *sz, short nFlags)
1063
{
1064
    OSErr   err;
1065
    char    chPerms = (!nFlags) ? fsRdPerm : fsRdWrPerm;
1066
    short   nFRefNum;
1067
 
1068
    AssertStr(sz, sz)
1069
 
1070
    /* we only need the filespec of the zipfile;
1071
       filespec of the other files (to be extracted) will be
1072
       determined by open_outfile() */
1073
    if (OpenZipFile)
1074
        {
1075
        char CompletePath[NAME_MAX];
1076
        FSSpec zipfile;
1077
        GetCompletePath(CompletePath, sz, &zipfile, &err);
1078
        printerr("GetCompletePath", (err != -43) && (err != 0),
1079
                  err, __LINE__, __FILE__, sz);
1080
        if (CheckMountedVolumes(CompletePath) > 1)
1081
            DoWarnUserDupVol(CompletePath);
1082
        err = HOpen(zipfile.vRefNum, zipfile.parID, zipfile.name,
1083
                    chPerms, &nFRefNum);
1084
        printerr("Zipfile HOpen", err, err, __LINE__, __FILE__, sz);
1085
        OpenZipFile = false;
1086
        }
1087
    else   /* open zipfile entries  */
1088
        {
1089
        if (nFlags > 1)
1090
            {
1091
            err = HOpenRF(CurrentFile.vRefNum, CurrentFile.parID, CurrentFile.name,
1092
                      chPerms, &nFRefNum);
1093
            printerr("HOpenRF", (err != -43) && (err != 0) && (err != -54),
1094
                 err, __LINE__, __FILE__, sz);
1095
            }
1096
        else
1097
            {
1098
            err = HOpen(CurrentFile.vRefNum, CurrentFile.parID, CurrentFile.name,
1099
                    chPerms, &nFRefNum);
1100
            printerr("HOpen", (err != -43) && (err != 0),
1101
                 err, __LINE__, __FILE__, sz);
1102
            }
1103
        }
1104
 
1105
    if ( err || (nFRefNum == 1) )
1106
        {
1107
        printerr("macopen", err, err, __LINE__, __FILE__,
1108
                 (char *) CurrentFile.name);
1109
        return -1;
1110
        }
1111
    else
1112
        {
1113
        if ( nFlags )
1114
            SetEOF( nFRefNum, 0 );
1115
        return nFRefNum;
1116
        }
1117
}
1118
 
1119
 
1120
 
1121
 
1122
 
1123
/***********************/
1124
/* Function maccreat() */
1125
/***********************/
1126
 
1127
short maccreat(char *sz)
1128
{
1129
    OSErr   err;
1130
    char scriptTag = newExtraField.fpb.hFileInfo.ioFlXFndrInfo.fdScript;
1131
    static char Num = 0;
1132
 
1133
    sz = sz;
1134
 
1135
    /* Set fdScript in FXInfo
1136
     * The negative script constants (smSystemScript, smCurrentScript,
1137
     * and smAllScripts) don't make sense on disk.  So only use scriptTag
1138
     * if scriptTag >= smRoman (smRoman is 0).
1139
     * fdScript is valid if high bit is set (see IM-6, page 9-38)
1140
     */
1141
    scriptTag = (scriptTag >= smRoman) ?
1142
                ((char)scriptTag | (char)0x80) : (smRoman);
1143
    newExtraField.fpb.hFileInfo.ioFlXFndrInfo.fdScript = scriptTag;
1144
 
1145
    err = FSpCreate(&CurrentFile,
1146
                    newExtraField.fpb.hFileInfo.ioFlFndrInfo.fdCreator,
1147
                    newExtraField.fpb.hFileInfo.ioFlFndrInfo.fdType,
1148
                    newExtraField.fpb.hFileInfo.ioFlXFndrInfo.fdScript);
1149
 
1150
    /* -37 = bad filename; make the filename shorter and try again  */
1151
    /* filename must not be longer than 32 chars */
1152
    if (err == -37)
1153
        {
1154
        strcpy((char *)CurrentFile.name,
1155
                MakeFilenameShorter(P2CStr(CurrentFile.name)));
1156
        Info(slide, 0x401, ((char *)slide, LoadFarString(FilenameToLong),
1157
          FnFilter1((char *)CurrentFile.name)));
1158
        C2PStr((char *)CurrentFile.name);
1159
        err = FSpCreate(&CurrentFile,
1160
                    newExtraField.fpb.hFileInfo.ioFlFndrInfo.fdCreator,
1161
                    newExtraField.fpb.hFileInfo.ioFlFndrInfo.fdType,
1162
                    newExtraField.fpb.hFileInfo.ioFlXFndrInfo.fdScript);
1163
        }
1164
 
1165
    err = printerr("FSpCreate maccreat ", (err != -48) && (err != 0),
1166
                   err, __LINE__, __FILE__, G.filename);
1167
 
1168
    if (err == noErr)
1169
        return noErr;
1170
    else
1171
        return -1;
1172
}
1173
 
1174
 
1175
 
1176
 
1177
 
1178
/**********************/
1179
/* Function macread() */
1180
/**********************/
1181
 
1182
short macread(short nFRefNum, char *pb, unsigned cb)
1183
{
1184
    long    lcb = cb;
1185
 
1186
    (void)FSRead( nFRefNum, &lcb, pb );
1187
    return (short)lcb;
1188
}
1189
 
1190
 
1191
 
1192
 
1193
/***********************/
1194
/* Function macwrite() */
1195
/***********************/
1196
 
1197
long macwrite(short nFRefNum, char *pb, unsigned cb)
1198
{
1199
    long    lcb = cb;
1200
    OSErr   err = 0;
1201
    FILE    *stream;
1202
 
1203
    if ( (nFRefNum == 1) || (nFRefNum == 2) )
1204
        {
1205
        stream = (nFRefNum == 1 ? stdout : stderr);
1206
        pb[cb] = '\0';           /* terminate C-string */
1207
                                 /* assumes writable buffer (e.g., slide[]) */
1208
                                 /* with room for one more char at end of buf */
1209
        lcb = fprintf(stream, "%s", pb);
1210
        }
1211
    else
1212
        err = FSWrite( nFRefNum, &lcb, pb );
1213
 
1214
    if (err != 0)
1215
        {
1216
        errno = ERANGE;
1217
        return -1;
1218
        }
1219
 
1220
    return (long)lcb;
1221
}
1222
 
1223
 
1224
 
1225
 
1226
 
1227
/***********************/
1228
/* Function macclose() */
1229
/***********************/
1230
 
1231
short macclose(short nFRefNum)
1232
{
1233
OSErr err;
1234
 
1235
err = FSClose( nFRefNum );
1236
printerr("macclose FSClose ",err,err, __LINE__,__FILE__,G.filename);
1237
 
1238
 
1239
return err;
1240
}
1241
 
1242
 
1243
 
1244
 
1245
 
1246
/***********************/
1247
/* Function maclseek() */
1248
/***********************/
1249
 
1250
long maclseek(short nFRefNum, long lib, short nMode)
1251
{
1252
    ParamBlockRec   pbr;
1253
 
1254
    if (nMode == SEEK_SET)
1255
        nMode = fsFromStart;
1256
    else if (nMode == SEEK_CUR)
1257
        nMode = fsFromMark;
1258
    else if (nMode == SEEK_END)
1259
        nMode = fsFromLEOF;
1260
    pbr.ioParam.ioRefNum = nFRefNum;
1261
    pbr.ioParam.ioPosMode = nMode;
1262
    pbr.ioParam.ioPosOffset = lib;
1263
    (void)PBSetFPosSync(&pbr);
1264
    return pbr.ioParam.ioPosOffset;
1265
}
1266
 
1267
 
1268
 
1269
static void BuildMacFilename(void)
1270
{
1271
char CompletePath[NAME_MAX];
1272
char ArchiveDir[NAME_MAX];
1273
unsigned exdirlen = strlen(uO.exdir);
1274
short CurrentFork;
1275
OSErr err;
1276
 
1277
GetExtraFieldData(&MacZipMode, &newExtraField);
1278
 
1279
if (MacZipMode >= JohnnyLee_EF)
1280
    {
1281
    if (IgnoreEF_Macfilename)
1282
        {
1283
        strcpy(ArchiveDir, &G.filename[exdirlen+1]);
1284
        G.filename[exdirlen+1] = '\0';
1285
        RfDfFilen2Real(ArchiveDir, ArchiveDir, MacZipMode,
1286
                      (newExtraField.flags & EB_M3_FL_DATFRK), &CurrentFork);
1287
        strcat(G.filename, ArchiveDir);
1288
        }
1289
    else
1290
        {        /* use the filename of mac extra-field */
1291
        G.filename[exdirlen] = '\0';  /* cut resource-path */
1292
        strcat(G.filename,newExtraField.FullPath);
1293
        }
1294
    }
1295
 
1296
GetCompletePath(CompletePath, G.filename, &CurrentFile, &err);
1297
printerr("GetCompletePath BuildMacFilename ", (err != -43) && (err != 0),
1298
             err, __LINE__, __FILE__, CompletePath);
1299
 
1300
err = GetVolFileSystemID(C2PStr(CompletePath), CurrentFile.vRefNum,
1301
                         &fileSystemID);
1302
printerr("GetVolFileSystemID BuildMacFilename ", err, err, __LINE__, __FILE__,
1303
          CompletePath);
1304
 
1305
if (MacZipMode == TomBrownZipIt1_EF)
1306
    {
1307
    memcpy(CurrentFile.name, newExtraField.filename, newExtraField.filename[0]+1);
1308
    CurrentFile.name[0] = CurrentFile.name[0] - 1;
1309
    }
1310
 
1311
}
1312
 
1313
 
1314
 
1315
 
1316
/* The following functions are dealing with the extra-field handling, only. */
1317
 
1318
/****************************/
1319
/* Function SetFinderInfo() */
1320
/****************************/
1321
 
1322
static OSErr SetFinderInfo(__GPRO__ int SetTime, FSSpec *spec, MACINFO *mi)
1323
{
1324
    OSErr err;
1325
    CInfoPBRec      fpb;
1326
 
1327
    fpb.hFileInfo.ioNamePtr   = (StringPtr) &(spec->name);
1328
    fpb.hFileInfo.ioVRefNum   = spec->vRefNum;
1329
    fpb.hFileInfo.ioDirID     = spec->parID;
1330
    fpb.hFileInfo.ioFDirIndex = 0;
1331
 
1332
    err = PBGetCatInfoSync(&fpb);
1333
    printerr("PBGetCatInfo SetFinderInfo ", err, err,
1334
             __LINE__, __FILE__, G.filename);
1335
 
1336
    if  ((MacZipMode == JohnnyLee_EF) || (MacZipMode == NewZipMode_EF))
1337
    {
1338
        /* skip restoring time stamps on user's request */
1339
        if (SetTime && !UseUT_ExtraField) {
1340
            fpb.hFileInfo.ioFlCrDat = mi->fpb.hFileInfo.ioFlCrDat;
1341
            fpb.hFileInfo.ioFlMdDat = mi->fpb.hFileInfo.ioFlMdDat;
1342
        }
1343
 
1344
        fpb.hFileInfo.ioFlFndrInfo   = mi->fpb.hFileInfo.ioFlFndrInfo;
1345
    }
1346
 
1347
    if (MacZipMode == NewZipMode_EF)
1348
    {
1349
        if (uO.E_flag) PrintMacExtraInfo(mi);
1350
        fpb.hFileInfo.ioFlXFndrInfo  = mi->fpb.hFileInfo.ioFlXFndrInfo;
1351
 
1352
        fpb.hFileInfo.ioFVersNum  = mi->fpb.hFileInfo.ioFVersNum;
1353
        fpb.hFileInfo.ioACUser    = mi->fpb.hFileInfo.ioACUser;
1354
 
1355
        /* skip restoring time stamps on user's request */
1356
        if (SetTime && !UseUT_ExtraField) {
1357
            fpb.hFileInfo.ioFlBkDat = mi->fpb.hFileInfo.ioFlBkDat;
1358
#ifdef USE_EF_UT_TIME
1359
            if (!(mi->flags & EB_M3_FL_NOUTC))
1360
                {
1361
#ifdef DEBUG_TIME
1362
            {
1363
            printf("\nSetFinderInfo:  Mac modif: %lu local -> UTOffset: "\
1364
                   "%d before AdjustForTZmoveMac\n",
1365
              fpb.hFileInfo.ioFlCrDat, mi->Cr_UTCoffs);
1366
            }
1367
#endif /* DEBUG_TIME */
1368
                fpb.hFileInfo.ioFlCrDat =
1369
                  AdjustForTZmoveMac(fpb.hFileInfo.ioFlCrDat, mi->Cr_UTCoffs);
1370
                fpb.hFileInfo.ioFlMdDat =
1371
                  AdjustForTZmoveMac(fpb.hFileInfo.ioFlMdDat, mi->Md_UTCoffs);
1372
                fpb.hFileInfo.ioFlBkDat =
1373
                  AdjustForTZmoveMac(fpb.hFileInfo.ioFlBkDat, mi->Bk_UTCoffs);
1374
#ifdef DEBUG_TIME
1375
            {
1376
            printf("SetFinderInfo:  Mac modif: %lu local -> UTOffset: "\
1377
                   "%d after AdjustForTZmoveMac\n",
1378
              fpb.hFileInfo.ioFlCrDat, mi->Cr_UTCoffs);
1379
            }
1380
#endif /* DEBUG_TIME */
1381
 
1382
                }
1383
#endif /* USE_EF_UT_TIME */
1384
        }
1385
 
1386
        if ((mi->FinderComment) &&
1387
           (fileSystemID == HFS_fileSystem)) {
1388
            C2PStr(mi->FinderComment);
1389
            err = FSpDTSetComment(spec, (unsigned char *) mi->FinderComment);
1390
            printerr("FSpDTSetComment:",err , err,
1391
                     __LINE__, __FILE__, mi->FullPath);
1392
        }
1393
    }
1394
 
1395
    /* Restore ioDirID field in pb which was changed by PBGetCatInfo */
1396
    fpb.hFileInfo.ioDirID = spec->parID;
1397
    err = PBSetCatInfoSync(&fpb);
1398
 
1399
    return err;
1400
} /* SetFinderInfo() */
1401
 
1402
 
1403
 
1404
 
1405
/*
1406
** Scan the extra fields in extra_field, and look for a MacOS EF; return a
1407
** pointer to that EF, or NULL if it's not there.
1408
*/
1409
static uch *scanMacOSexfield(uch *ef_ptr, unsigned ef_len,
1410
                             short *MacZipMode)
1411
{
1412
    while (ef_ptr != NULL && ef_len >= EB_HEADSIZE) {
1413
        unsigned eb_id  = makeword(EB_ID  + ef_ptr);
1414
        unsigned eb_len = makeword(EB_LEN + ef_ptr);
1415
 
1416
        if (eb_len > (ef_len - EB_HEADSIZE)) {
1417
            Trace((stderr,
1418
              "scanMacOSexfield: block length %u > rest ef_size %u\n", eb_len,
1419
              ef_len - EB_HEADSIZE));
1420
            break;
1421
        }
1422
 
1423
        if (isMacOSexfield(eb_id, eb_len, MacZipMode)) {
1424
            return ef_ptr;
1425
        }
1426
 
1427
        ef_ptr += (eb_len + EB_HEADSIZE);
1428
        ef_len -= (eb_len + EB_HEADSIZE);
1429
    }
1430
 
1431
    return NULL;
1432
}
1433
 
1434
 
1435
 
1436
 
1437
static Boolean isMacOSexfield(unsigned id, unsigned size, short *MacZipMode)
1438
{
1439
size = size;
1440
 
1441
    switch (id)
1442
        {
1443
        case EF_ZIPIT:
1444
            {           /* we do not (yet) support ZipIt's format completely */
1445
            *MacZipMode = TomBrownZipIt1_EF;
1446
            IgnoreEF_Macfilename = true;
1447
            return true;
1448
            }
1449
 
1450
        case EF_ZIPIT2:
1451
            {           /* we do not (yet) support ZipIt's format completely */
1452
            *MacZipMode = TomBrownZipIt2_EF;
1453
            IgnoreEF_Macfilename = true;
1454
            return true;
1455
            }
1456
 
1457
        case EF_MAC3:
1458
            {           /* the new maczip format */
1459
            *MacZipMode = NewZipMode_EF;
1460
            IgnoreEF_Macfilename = false;
1461
            return true;
1462
            }
1463
 
1464
        case EF_JLMAC:
1465
            {           /* Johnny Lee's old maczip format */
1466
            *MacZipMode = JohnnyLee_EF;
1467
            IgnoreEF_Macfilename = true;
1468
            return true;
1469
            }
1470
 
1471
        default:
1472
            {           /* any other format */
1473
            *MacZipMode = UnKnown_EF;
1474
            IgnoreEF_Macfilename = true;
1475
            return false;
1476
            }
1477
        }
1478
 
1479
    return false;
1480
}
1481
 
1482
 
1483
 
1484
 
1485
/*
1486
** Return a unsigned long from a four-byte sequence
1487
** in big endian format
1488
*/
1489
 
1490
ulg makePPClong(ZCONST uch *sig)
1491
{
1492
    return (((ulg)sig[0]) << 24)
1493
         + (((ulg)sig[1]) << 16)
1494
         + (((ulg)sig[2]) << 8)
1495
         +  ((ulg)sig[3]);
1496
}
1497
 
1498
 
1499
 
1500
 
1501
/*
1502
** Return a unsigned short from a two-byte sequence
1503
** in big endian format
1504
*/
1505
 
1506
ush makePPCword(ZCONST uch *b)
1507
{
1508
    return (ush)((b[0] << 8) | b[1]);
1509
}
1510
 
1511
 
1512
 
1513
 
1514
/*
1515
** Print mac extra-field
1516
**
1517
*/
1518
 
1519
static void PrintMacExtraInfo(MACINFO *mi)
1520
{
1521
#define MY_FNDRINFO fpb.hFileInfo.ioFlFndrInfo
1522
    DateTimeRec  MacTime;
1523
    static ZCONST char space[] = "                                    ";
1524
    static ZCONST char line[]  = "------------------------------------"\
1525
                                 "------------------------------";
1526
 
1527
    printf("\n\n%s", line);
1528
 
1529
    printf("\nFullPath      = [%s]", mi->FullPath);
1530
    printf("\nFinderComment = [%s]", mi->FinderComment);
1531
    printf("\nText Encoding Base (Filename)       \"%s\" \n",
1532
        PrintTextEncoding(mi->fpb.hFileInfo.ioFlXFndrInfo.fdScript));
1533
 
1534
    printf("\nExtraField Flags :                  %s  0x%x  %4d",
1535
             sBit2Str(mi->flags), mi->flags, mi->flags);
1536
 
1537
    printf("\n%sExtra Field is %s", space,
1538
           (mi->flags & EB_M3_FL_UNCMPR ?
1539
            "Uncompressed" : "Compressed"));
1540
    printf("\n%sFile Dates are in %u Bit", space,
1541
           (mi->flags & EB_M3_FL_TIME64 ? 64 : 32));
1542
    printf("\n%sFile UTC time adjustments are %ssupported", space,
1543
           (mi->flags & EB_M3_FL_NOUTC ? "not " : ""));
1544
    printf("\n%sFile Name is %schanged", space,
1545
           (mi->flags & EB_M3_FL_NOCHANGE ? "not " : ""));
1546
    printf("\n%sFile is a %s\n", space,
1547
           (mi->flags & EB_M3_FL_DATFRK ?
1548
            "Datafork" : "Resourcefork"));
1549
 
1550
    /* not all type / creator codes are printable */
1551
    if (isprint((char)(mi->MY_FNDRINFO.fdType >> 24)) &&
1552
        isprint((char)(mi->MY_FNDRINFO.fdType >> 16)) &&
1553
        isprint((char)(mi->MY_FNDRINFO.fdType >> 8)) &&
1554
        isprint((char)mi->MY_FNDRINFO.fdType))
1555
    {
1556
        printf("\nFile Type =                         [%c%c%c%c]  0x%lx",
1557
            (char)(mi->MY_FNDRINFO.fdType >> 24),
1558
            (char)(mi->MY_FNDRINFO.fdType >> 16),
1559
            (char)(mi->MY_FNDRINFO.fdType >> 8),
1560
            (char)(mi->MY_FNDRINFO.fdType),
1561
            mi->MY_FNDRINFO.fdType);
1562
    }
1563
    else
1564
    {
1565
        printf("\nFile Type =                                     0x%lx",
1566
            mi->MY_FNDRINFO.fdType);
1567
    }
1568
 
1569
    if (isprint((char)(mi->MY_FNDRINFO.fdCreator >> 24)) &&
1570
        isprint((char)(mi->MY_FNDRINFO.fdCreator >> 16)) &&
1571
        isprint((char)(mi->MY_FNDRINFO.fdCreator >> 8)) &&
1572
        isprint((char)mi->MY_FNDRINFO.fdCreator))
1573
    {
1574
        printf("\nFile Creator =                      [%c%c%c%c]  0x%lx",
1575
            (char)(mi->MY_FNDRINFO.fdCreator >> 24),
1576
            (char)(mi->MY_FNDRINFO.fdCreator >> 16),
1577
            (char)(mi->MY_FNDRINFO.fdCreator >> 8),
1578
            (char)(mi->MY_FNDRINFO.fdCreator),
1579
            mi->MY_FNDRINFO.fdCreator);
1580
    }
1581
    else
1582
    {
1583
        printf("\nFile Creator =                                  0x%lx",
1584
            mi->MY_FNDRINFO.fdCreator);
1585
    }
1586
 
1587
    printf("\n\nDates (local time of archiving location):");
1588
    SecondsToDate(mi->fpb.hFileInfo.ioFlCrDat, &MacTime);
1589
    printf("\n    Created  =                      %4d/%2d/%2d %2d:%2d:%2d  ",
1590
           MacTime.year, MacTime.month, MacTime.day,
1591
           MacTime.hour, MacTime.minute, MacTime.second);
1592
    SecondsToDate(mi->fpb.hFileInfo.ioFlMdDat, &MacTime);
1593
    printf("\n    Modified =                      %4d/%2d/%2d %2d:%2d:%2d  ",
1594
           MacTime.year, MacTime.month, MacTime.day,
1595
           MacTime.hour, MacTime.minute, MacTime.second);
1596
    SecondsToDate(mi->fpb.hFileInfo.ioFlBkDat, &MacTime);
1597
    printf("\n    Backup   =                      %4d/%2d/%2d %2d:%2d:%2d  ",
1598
        MacTime.year, MacTime.month, MacTime.day,
1599
        MacTime.hour, MacTime.minute, MacTime.second);
1600
 
1601
    if (!(mi->flags & EB_M3_FL_NOUTC)) {
1602
        printf("\nGMT Offset of Creation time  =      %4ld sec  %2d h",
1603
          mi->Cr_UTCoffs, (int)mi->Cr_UTCoffs / (60 * 60));
1604
        printf("\nGMT Offset of Modification time  =  %4ld sec  %2d h",
1605
          mi->Md_UTCoffs, (int)mi->Md_UTCoffs / (60 * 60));
1606
        printf("\nGMT Offset of Backup time  =        %4ld sec  %2d h",
1607
          mi->Bk_UTCoffs, (int)mi->Bk_UTCoffs / (60 * 60));
1608
    }
1609
 
1610
    printf("\n\nFinder Flags :                      %s  0x%x  %4d",
1611
        sBit2Str(mi->MY_FNDRINFO.fdFlags),
1612
        mi->MY_FNDRINFO.fdFlags,
1613
        mi->MY_FNDRINFO.fdFlags);
1614
 
1615
    printf("\nFinder Icon Position =              X: %4d",
1616
        mi->MY_FNDRINFO.fdLocation.h);
1617
 
1618
    printf("\n                                    Y: %4d",
1619
        mi->MY_FNDRINFO.fdLocation.v);
1620
 
1621
    printf("\n\nText Encoding Base (System/MacZip)  \"%s\"",
1622
        PrintTextEncoding(mi->TextEncodingBase));
1623
 
1624
    printf("\n%s\n", line);
1625
#undef MY_FNDRINFO
1626
}
1627
 
1628
 
1629
 
1630
 
1631
/*
1632
** Decode mac extra-field and assign the data to the structure
1633
**
1634
*/
1635
 
1636
static Boolean GetExtraFieldData(short *MacZipMode, MACINFO *mi)
1637
{
1638
uch *ptr;
1639
int  retval = PK_OK;
1640
 
1641
ptr = scanMacOSexfield(G.extra_field, G.lrec.extra_field_length, MacZipMode);
1642
 
1643
/* MacOS is no preemptive OS therefore do some (small) event-handling */
1644
UserStop();
1645
 
1646
if (uO.J_flag)
1647
    {
1648
    *MacZipMode = UnKnown_EF;
1649
    IgnoreEF_Macfilename = true;
1650
    return false;
1651
    }
1652
 
1653
if (ptr != NULL)
1654
{   /*   Collect the data from the extra field buffer. */
1655
    mi->header    = makeword(ptr);    ptr += 2;
1656
    mi->data      = makeword(ptr);    ptr += 2;
1657
 
1658
    switch (*MacZipMode)
1659
        {
1660
        case NewZipMode_EF:
1661
           {
1662
            mi->size      =  makelong(ptr); ptr += 4;
1663
            mi->flags     =  makeword(ptr); ptr += 2;
1664
                             /* Type/Creator are always uncompressed */
1665
            mi->fpb.hFileInfo.ioFlFndrInfo.fdType    = makePPClong(ptr);
1666
            ptr += 4;
1667
            mi->fpb.hFileInfo.ioFlFndrInfo.fdCreator = makePPClong(ptr);
1668
            ptr += 4;
1669
 
1670
            if (!(mi->flags & EB_M3_FL_UNCMPR))
1671
                {
1672
 
1673
                retval = memextract(__G__ attrbuff, mi->size, ptr,
1674
                                    mi->data - EB_MAC3_HLEN);
1675
 
1676
                if (retval != PK_OK)  /* error uncompressing attributes */
1677
                    {
1678
                    Info(slide, 0x201, ((char *)slide,
1679
                         LoadFarString(ErrUncmpEF)));
1680
                    *MacZipMode = UnKnown_EF;
1681
                    return false;     /* EF-Block unusable, ignore it */
1682
                    }
1683
 
1684
                }
1685
             else
1686
                {   /* file attributes are uncompressed */
1687
                attrbuff = ptr;
1688
                }
1689
 
1690
            DecodeMac3ExtraField(attrbuff, mi);
1691
 
1692
            return true;
1693
            break;
1694
            }
1695
 
1696
        case JohnnyLee_EF:
1697
            {
1698
            if (strncmp((char *)ptr, "JLEE", 4) == 0)
1699
                {   /* Johnny Lee's old MacZip e.f. was found */
1700
                attrbuff  = ptr + 4;
1701
                DecodeJLEEextraField(attrbuff, mi);
1702
                return true;
1703
                }
1704
            else
1705
                {   /* second signature did not match, ignore EF block */
1706
                *MacZipMode = UnKnown_EF;
1707
                return false;
1708
                }
1709
            break;
1710
            }
1711
 
1712
 
1713
        case TomBrownZipIt1_EF:
1714
        case TomBrownZipIt2_EF:
1715
            {
1716
            if (strncmp((char *)ptr, "ZPIT", 4) == 0)
1717
                {   /* Johnny Lee's old MacZip e.f. was found */
1718
                attrbuff  = ptr + 4;
1719
                DecodeZPITextraField(attrbuff, mi);
1720
                return true;
1721
                }
1722
            else
1723
                {   /* second signature did not match, ignore EF block */
1724
                *MacZipMode = UnKnown_EF;
1725
                return false;
1726
                }
1727
            break;
1728
            }
1729
 
1730
 
1731
        default:
1732
            {  /* just to make sure */
1733
            *MacZipMode = UnKnown_EF;
1734
            IgnoreEF_Macfilename = true;
1735
            return false;
1736
            break;
1737
            }
1738
        }
1739
}  /* if (ptr != NULL)  */
1740
 
1741
/* no Mac extra field was found */
1742
return false;
1743
}
1744
 
1745
 
1746
 
1747
 
1748
/*
1749
** Assign the new Mac3 Extra-Field to the structure
1750
**
1751
*/
1752
 
1753
static void DecodeMac3ExtraField(ZCONST uch *buff, MACINFO *mi)
1754
{               /* extra-field info of the new MacZip implementation */
1755
                /* compresssed extra-field starts here (if compressed) */
1756
 
1757
Assert_it(buff, "", "");
1758
 
1759
mi->fpb.hFileInfo.ioFlFndrInfo.fdFlags        =  makeword(buff); buff += 2;
1760
mi->fpb.hFileInfo.ioFlFndrInfo.fdLocation.v   =  makeword(buff); buff += 2;
1761
mi->fpb.hFileInfo.ioFlFndrInfo.fdLocation.h   =  makeword(buff); buff += 2;
1762
mi->fpb.hFileInfo.ioFlFndrInfo.fdFldr         =  makeword(buff); buff += 2;
1763
 
1764
mi->fpb.hFileInfo.ioFlXFndrInfo.fdIconID      =  makeword(buff); buff += 2;
1765
mi->fpb.hFileInfo.ioFlXFndrInfo.fdReserved[0] =  makeword(buff); buff += 2;
1766
mi->fpb.hFileInfo.ioFlXFndrInfo.fdReserved[1] =  makeword(buff); buff += 2;
1767
mi->fpb.hFileInfo.ioFlXFndrInfo.fdReserved[2] =  makeword(buff); buff += 2;
1768
mi->fpb.hFileInfo.ioFlXFndrInfo.fdScript      = *buff;           buff += 1;
1769
mi->fpb.hFileInfo.ioFlXFndrInfo.fdXFlags      = *buff;           buff += 1;
1770
mi->fpb.hFileInfo.ioFlXFndrInfo.fdComment     =  makeword(buff); buff += 2;
1771
mi->fpb.hFileInfo.ioFlXFndrInfo.fdPutAway     =  makelong(buff); buff += 4;
1772
 
1773
mi->fpb.hFileInfo.ioFVersNum                  = *buff;           buff += 1;
1774
mi->fpb.hFileInfo.ioACUser                    = *buff;           buff += 1;
1775
 
1776
/*
1777
This implementation does not use the 64 bit time values, therefore
1778
use the UT extra field instead
1779
*/
1780
if (mi->flags & EB_M3_FL_TIME64)
1781
    {
1782
    Info(slide, 0x201, ((char *)slide, LoadFarString(No64Time)));
1783
    UseUT_ExtraField = true;
1784
    buff += 24; /* jump over the date values */
1785
    }
1786
else
1787
    {
1788
    UseUT_ExtraField = false;
1789
    mi->fpb.hFileInfo.ioFlCrDat   =  makelong(buff); buff += 4;
1790
    mi->fpb.hFileInfo.ioFlMdDat   =  makelong(buff); buff += 4;
1791
    mi->fpb.hFileInfo.ioFlBkDat   =  makelong(buff); buff += 4;
1792
    }
1793
 
1794
if (!(mi->flags & EB_M3_FL_NOUTC))
1795
    {
1796
    mi->Cr_UTCoffs =  makelong(buff); buff += 4;
1797
    mi->Md_UTCoffs =  makelong(buff); buff += 4;
1798
    mi->Bk_UTCoffs =  makelong(buff); buff += 4;
1799
    }
1800
 
1801
/* TextEncodingBase type & values */
1802
/* (values 0-32 correspond to the Script Codes defined in "Inside Macintosh",
1803
    Text pages 6-52 and 6-53) */
1804
mi->TextEncodingBase =  makeword(buff); buff += 2;
1805
 
1806
if (mi->TextEncodingBase >= kTextEncodingUnicodeV1_1)
1807
    {
1808
    Info(slide, 0x201, ((char *)slide, LoadFarString(NoUniCode)));
1809
    IgnoreEF_Macfilename = true;
1810
    }
1811
 
1812
mi->FullPath      = (char *)buff; buff += strlen(mi->FullPath) + 1;
1813
mi->FinderComment = (char *)buff; buff += strlen(mi->FinderComment) + 1;
1814
 
1815
if (uO.i_flag) IgnoreEF_Macfilename = true;
1816
 
1817
}
1818
 
1819
 
1820
 
1821
 
1822
/*
1823
** Assign the new JLEE Extra-Field to the structure
1824
**
1825
*/
1826
 
1827
static void DecodeJLEEextraField(ZCONST uch *buff, MACINFO *mi)
1828
{ /*  extra-field info of Johnny Lee's old MacZip  */
1829
 
1830
Assert_it(buff, "", "");
1831
 
1832
mi->fpb.hFileInfo.ioFlFndrInfo.fdType       = makePPClong(buff); buff += 4;
1833
mi->fpb.hFileInfo.ioFlFndrInfo.fdCreator    = makePPClong(buff); buff += 4;
1834
mi->fpb.hFileInfo.ioFlFndrInfo.fdFlags      = makePPCword(buff); buff += 2;
1835
mi->fpb.hFileInfo.ioFlFndrInfo.fdLocation.v = makePPCword(buff); buff += 2;
1836
mi->fpb.hFileInfo.ioFlFndrInfo.fdLocation.h = makePPCword(buff); buff += 2;
1837
mi->fpb.hFileInfo.ioFlFndrInfo.fdFldr       = makePPCword(buff); buff += 2;
1838
 
1839
mi->fpb.hFileInfo.ioFlCrDat                =  makePPClong(buff); buff += 4;
1840
mi->fpb.hFileInfo.ioFlMdDat                =  makePPClong(buff); buff += 4;
1841
mi->flags                                  =  makePPClong(buff); buff += 4;
1842
 
1843
newExtraField.fpb.hFileInfo.ioFlXFndrInfo.fdScript = smSystemScript;
1844
}
1845
 
1846
 
1847
 
1848
 
1849
/*
1850
** Assign the new JLEE Extra-Field to the structure
1851
**
1852
*/
1853
 
1854
static void DecodeZPITextraField(ZCONST uch *buff, MACINFO *mi)
1855
{ /*  extra-field info of Johnny Lee's old MacZip  */
1856
unsigned char filelen;
1857
 
1858
Assert_it(buff, "", "");
1859
 
1860
#ifdef SwitchZIPITefSupportOff
1861
MacZipMode = UnKnown_EF;
1862
Info(slide, 0x221, ((char *)slide,LoadFarString(ZitIt_EF)));
1863
return;
1864
#endif
1865
 
1866
if (MacZipMode == TomBrownZipIt1_EF)
1867
    {
1868
    filelen = *buff;
1869
    newExtraField.filename = buff;
1870
    buff += 1;
1871
    buff += filelen;
1872
    mi->fpb.hFileInfo.ioFlFndrInfo.fdType       = makePPClong(buff);
1873
    buff += 4;
1874
    mi->fpb.hFileInfo.ioFlFndrInfo.fdCreator    = makePPClong(buff);
1875
    buff += 4;
1876
    }
1877
else   /*  if (MacZipMode == TomBrownZipIt2_EF)  */
1878
    {
1879
    mi->fpb.hFileInfo.ioFlFndrInfo.fdType       = makePPClong(buff);
1880
    buff += 4;
1881
    mi->fpb.hFileInfo.ioFlFndrInfo.fdCreator    = makePPClong(buff);
1882
    buff += 4;
1883
    }
1884
 
1885
newExtraField.fpb.hFileInfo.ioFlXFndrInfo.fdScript = smSystemScript;
1886
}
1887
 
1888
 
1889
 
1890
/*
1891
** Return char* to describe the text encoding
1892
**
1893
*/
1894
 
1895
static char *PrintTextEncoding(short script)
1896
{
1897
char *info;
1898
static char buffer[14];
1899
/* TextEncodingBase type & values */
1900
/* (values 0-32 correspond to the Script Codes defined in
1901
   Inside Macintosh: Text pages 6-52 and 6-53 */
1902
 
1903
switch (script) {               /* Mac OS encodings*/
1904
    case kTextEncodingMacRoman:         info = "Roman";             break;
1905
    case kTextEncodingMacJapanese:      info = "Japanese";          break;
1906
    case kTextEncodingMacChineseTrad:   info = "ChineseTrad";       break;
1907
    case kTextEncodingMacKorean:        info = "Korean";            break;
1908
    case kTextEncodingMacArabic:        info = "Arabic";            break;
1909
    case kTextEncodingMacHebrew:        info = "Hebrew";            break;
1910
    case kTextEncodingMacGreek:         info = "Greek";             break;
1911
    case kTextEncodingMacCyrillic:      info = "Cyrillic";          break;
1912
    case kTextEncodingMacDevanagari:    info = "Devanagari";        break;
1913
    case kTextEncodingMacGurmukhi:      info = "Gurmukhi";          break;
1914
    case kTextEncodingMacGujarati:      info = "Gujarati";          break;
1915
    case kTextEncodingMacOriya:         info = "Oriya";             break;
1916
    case kTextEncodingMacBengali:       info = "Bengali";           break;
1917
    case kTextEncodingMacTamil:         info = "Tamil";             break;
1918
    case kTextEncodingMacTelugu:        info = "Telugu";            break;
1919
    case kTextEncodingMacKannada:       info = "Kannada";           break;
1920
    case kTextEncodingMacMalayalam:     info = "Malayalam";         break;
1921
    case kTextEncodingMacSinhalese:     info = "Sinhalese";         break;
1922
    case kTextEncodingMacBurmese:       info = "Burmese";           break;
1923
    case kTextEncodingMacKhmer:         info = "Khmer";             break;
1924
    case kTextEncodingMacThai:          info = "Thai";              break;
1925
    case kTextEncodingMacLaotian:       info = "Laotian";           break;
1926
    case kTextEncodingMacGeorgian:      info = "Georgian";          break;
1927
    case kTextEncodingMacArmenian:      info = "Armenian";          break;
1928
    case kTextEncodingMacChineseSimp:   info = "ChineseSimp";       break;
1929
    case kTextEncodingMacTibetan:       info = "Tibetan";           break;
1930
    case kTextEncodingMacMongolian:     info = "Mongolian";         break;
1931
    case kTextEncodingMacEthiopic:      info = "Ethiopic";          break;
1932
    case kTextEncodingMacCentralEurRoman: info = "CentralEurRoman"; break;
1933
    case kTextEncodingMacVietnamese:    info = "Vietnamese";        break;
1934
    case kTextEncodingMacExtArabic:     info = "ExtArabic";         break;
1935
 
1936
    case kTextEncodingUnicodeV1_1:      info = "Unicode V 1.1";     break;
1937
    case kTextEncodingUnicodeV2_0:      info = "Unicode V 2.0";     break;
1938
 
1939
    default:  {
1940
        sprintf(buffer,"Code: 0x%x",(short) script);
1941
        info = buffer;
1942
        break;
1943
        }
1944
    }
1945
 
1946
return info;
1947
}
1948
 
1949
 
1950
 
1951
/*
1952
** Init Globals
1953
**
1954
*/
1955
 
1956
void   MacGlobalsInit(__GPRO)
1957
{
1958
newExtraField.FullPath      = NULL;
1959
newExtraField.FinderComment = NULL;
1960
 
1961
OpenZipFile = true;
1962
 
1963
MacZipMode = UnKnown_EF;
1964
IgnoreEF_Macfilename = true;
1965
 
1966
if (malloced_attrbuff == NULL)
1967
    {
1968
    /* make room for extra-field */
1969
    attrbuff = (uch *)malloc(EB_MAX_OF_VARDATA);
1970
 
1971
    if (attrbuff == NULL)
1972
        {             /* No memory to uncompress attributes */
1973
        Info(slide, 0x201, ((char *)slide, LoadFarString(OutOfMemEF)));
1974
        exit(PK_MEM);
1975
        }
1976
    else
1977
        {
1978
        malloced_attrbuff = attrbuff;
1979
        }
1980
    }
1981
else
1982
    {
1983
    attrbuff = malloced_attrbuff;
1984
    }
1985
 
1986
}