~ubuntu-branches/ubuntu/quantal/unzip/quantal

« back to all changes in this revision

Viewing changes to atari/atari.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2009-05-08 20:02:40 UTC
  • mfrom: (2.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090508200240-rk23wg0jdoyc6caj
Tags: 6.0-1
* New upstream release. Closes: #496989.
* Enabled new Unicode support. Closes: #197427. This may or may not work
  for your already created zipfiles, but it's not a bug unless they were
  created using the Unicode feature present in zip 3.0.
* Built using DATE_FORMAT=DF_YMD so that unzip -l show dates in ISO format,
  as that's the only available one which makes sense. Closes: #312886.
* Enabled new bzip2 support. Closes: #426798.
* Exit code for zipgrep should now be the right one. Closes: #441997.
* The reason why a file may not be created is now shown. Closes: #478791.
* Summary of changes in this version not being the debian/* files:
- Manpages in section 1, not 1L.
- Branding patch. UnZip by Debian. Original by Info-ZIP.
- Always #include <unistd.h>. Debian GNU/kFreeBSD needs it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
 
2
  Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
3
3
 
4
4
  See the accompanying file LICENSE, version 2000-Apr-09 or later
5
5
  (the contents of which are also included in unzip.h) for terms of use.
172
172
int mapattr(__G)
173
173
    __GDEF
174
174
{
 
175
    int r;
175
176
    ulg tmp = G.crec.external_file_attributes;
176
177
 
 
178
    G.pInfo->file_attr = 0;
 
179
    /* initialized to 0 for check in "default" branch below... */
 
180
 
177
181
    switch (G.pInfo->hostnum) {
178
182
        case AMIGA_:
179
183
            tmp = (unsigned)(tmp>>17 & 7);   /* Amiga RWE bits */
194
198
        case BEOS_:
195
199
        case QDOS_:
196
200
        case TANDEM_:
 
201
            r = FALSE;
197
202
            G.pInfo->file_attr = (unsigned)(tmp >> 16);
198
 
            if (G.pInfo->file_attr != 0 || !G.extra_field) {
199
 
                return 0;
200
 
            } else {
 
203
            if (G.pInfo->file_attr == 0 && G.extra_field) {
201
204
                /* Some (non-Info-ZIP) implementations of Zip for Unix and
202
 
                   VMS (and probably others ??) leave 0 in the upper 16-bit
203
 
                   part of the external_file_attributes field. Instead, they
204
 
                   store file permission attributes in some extra field.
205
 
                   As a work-around, we search for the presence of one of
206
 
                   these extra fields and fall back to the MSDOS compatible
207
 
                   part of external_file_attributes if one of the known
208
 
                   e.f. types has been detected.
209
 
                   Later, we might implement extraction of the permission
210
 
                   bits from the VMS extra field. But for now, the work-around
211
 
                   should be sufficient to provide "readable" extracted files.
212
 
                   (For ASI Unix e.f., an experimental remap of the e.f.
213
 
                   mode value IS already provided!)
 
205
                 * VMS (and probably others ??) leave 0 in the upper 16-bit
 
206
                 * part of the external_file_attributes field. Instead, they
 
207
                 * store file permission attributes in some extra field.
 
208
                 * As a work-around, we search for the presence of one of
 
209
                 * these extra fields and fall back to the MSDOS compatible
 
210
                 * part of external_file_attributes if one of the known
 
211
                 * e.f. types has been detected.
 
212
                 * Later, we might implement extraction of the permission
 
213
                 * bits from the VMS extra field. But for now, the work-around
 
214
                 * should be sufficient to provide "readable" extracted files.
 
215
                 * (For ASI Unix e.f., an experimental remap of the e.f.
 
216
                 * mode value IS already provided!)
214
217
                 */
215
218
                ush ebID;
216
219
                unsigned ebLen;
217
220
                uch *ef = G.extra_field;
218
221
                unsigned ef_len = G.crec.extra_field_length;
219
 
                int r = FALSE;
220
222
 
221
223
                while (!r && ef_len >= EB_HEADSIZE) {
222
224
                    ebID = makeword(ef);
243
245
                    ef_len -= (ebLen + EB_HEADSIZE);
244
246
                    ef += (ebLen + EB_HEADSIZE);
245
247
                }
246
 
                if (!r)
247
 
                    return 0;
 
248
            }
 
249
            if (!r) {
 
250
#ifdef SYMLINKS
 
251
                /* Check if the file is a (POSIX-compatible) symbolic link.
 
252
                 * We restrict symlink support to those "made-by" hosts that
 
253
                 * are known to support symbolic links.
 
254
                 */
 
255
                G.pInfo->symlink = S_ISLNK(G.pInfo->file_attr) &&
 
256
                                   SYMLINK_HOST(G.pInfo->hostnum);
 
257
#endif
 
258
                return 0;
248
259
            }
249
260
            /* fall through! */
250
261
        /* all remaining cases:  expand MSDOS read-only bit into write perms */
273
284
            }
274
285
            /* read-only bit --> write perms; subdir bit --> dir exec bit */
275
286
            tmp = !(tmp & 1) << 1  |  (tmp & 0x10) >> 4;
276
 
            if ((G.pInfo->file_attr & 0700) == (unsigned)(0400 | tmp<<6))
 
287
            if ((G.pInfo->file_attr & 0700) == (unsigned)(0400 | tmp<<6)) {
277
288
                /* keep previous G.pInfo->file_attr setting, when its "owner"
278
289
                 * part appears to be consistent with DOS attribute flags!
279
290
                 */
 
291
#ifdef SYMLINKS
 
292
                /* Entries "made by FS_FAT_" could have been zipped on a
 
293
                 * system that supports POSIX-style symbolic links.
 
294
                 */
 
295
                G.pInfo->symlink = S_ISLNK(G.pInfo->file_attr) &&
 
296
                                   (G.pInfo->hostnum == FS_FAT_);
 
297
#endif
280
298
                return 0;
 
299
            }
281
300
            G.pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);
282
301
            break;
283
302
    } /* end switch (host-OS-created-by) */
443
462
            *lastsemi = '\0';
444
463
    }
445
464
 
 
465
    /* On UNIX (and compatible systems), "." and ".." are reserved for
 
466
     * directory navigation and cannot be used as regular file names.
 
467
     * These reserved one-dot and two-dot names are mapped to "_" and "__".
 
468
     */
 
469
    if (strcmp(pathcomp, ".") == 0)
 
470
        *pathcomp = '_';
 
471
    else if (strcmp(pathcomp, "..") == 0)
 
472
        strcpy(pathcomp, "__");
 
473
 
446
474
#ifdef ACORN_FTYPE_NFS
447
475
    /* translate Acorn filetype information if asked to do so */
448
476
    if (uO.acorn_nfs_ext &&
775
803
#endif
776
804
    ztimbuf tp;
777
805
 
778
 
    fclose(G.outfile);
779
 
 
780
806
/*---------------------------------------------------------------------------
781
807
    If symbolic links are supported, allocate storage for a symlink control
782
808
    structure, put the uncompressed "data" and other required info in it, and
793
819
     *      link fails?
794
820
     */
795
821
    if (G.symlnk) {
796
 
        unsigned ucsize = (unsigned)G.lrec.ucsize;
797
 
        extent slnk_entrysize = sizeof(slinkentry) + ucsize +
798
 
                                strlen(G.filename);
 
822
        extent ucsize = (extent)G.lrec.ucsize;
 
823
        /* size of the symlink entry is the sum of
 
824
         *  (struct size (includes 1st '\0') + 1 additional trailing '\0'),
 
825
         *  system specific attribute data size (might be 0),
 
826
         *  and the lengths of name and link target.
 
827
         */
 
828
        extent slnk_entrysize = (sizeof(slinkentry) + 1) +
 
829
                                ucsize + strlen(G.filename);
799
830
        slinkentry *slnk_entry;
800
831
 
801
 
        if ((unsigned)slnk_entrysize < ucsize) {
 
832
        if (slnk_entrysize < ucsize) {
802
833
            Info(slide, 0x201, ((char *)slide,
803
834
              "warning:  symbolic link (%s) failed: mem alloc overflow\n",
804
835
              FnFilter1(G.filename)));
 
836
            fclose(G.outfile);
805
837
            return;
806
838
        }
807
839
 
809
841
            Info(slide, 0x201, ((char *)slide,
810
842
              "warning:  symbolic link (%s) failed: no mem\n",
811
843
              FnFilter1(G.filename)));
 
844
            fclose(G.outfile);
812
845
            return;
813
846
        }
814
847
        slnk_entry->next = NULL;
818
851
        slnk_entry->fname = slnk_entry->target + ucsize + 1;
819
852
        strcpy(slnk_entry->fname, G.filename);
820
853
 
821
 
        /* reopen the "link data" file for reading */
822
 
        G.outfile = fopen(G.filename, FOPR);
 
854
        /* move back to the start of the file to re-read the "link data" */
 
855
        rewind(G.outfile);
823
856
 
824
 
        if (!G.outfile ||
825
 
            fread(slnk_entry->target, 1, ucsize, G.outfile) != (int)ucsize)
 
857
        if (fread(slnk_entry->target, 1, ucsize, G.outfile) != ucsize)
826
858
        {
827
859
            Info(slide, 0x201, ((char *)slide,
828
860
              "warning:  symbolic link (%s) failed\n",
845
877
        return;
846
878
    }
847
879
 
 
880
    fclose(G.outfile);
 
881
 
848
882
/*---------------------------------------------------------------------------
849
883
    Convert from MSDOS-format local time and date to Unix-format 32-bit GMT
850
884
    time:  adjust base year from 1980 to 1970, do usual conversions from
852
886
    light savings time differences.
853
887
  ---------------------------------------------------------------------------*/
854
888
 
 
889
    /* skip restoring time stamps on user's request */
 
890
    if (uO.D_flag <= 1) {
855
891
#ifdef USE_EF_UT_TIME
856
 
    eb_izux_flg = (G.extra_field
 
892
        eb_izux_flg = (G.extra_field
857
893
#ifdef IZ_CHECK_TZ
858
 
                   && G.tz_is_valid
 
894
                       && G.tz_is_valid
859
895
#endif
860
 
                   ? ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length,
861
 
                       0, G.lrec.last_mod_dos_datetime, &zt, NULL)
862
 
                   : 0);
863
 
    if (eb_izux_flg & EB_UT_FL_MTIME) {
864
 
        tp.modtime = zt.mtime;
865
 
        TTrace((stderr, "\nclose_outfile:  Unix e.f. modif. time = %ld\n",
866
 
          tp.modtime));
867
 
    } else {
868
 
        tp.modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
869
 
    }
870
 
    if (eb_izux_flg & EB_UT_FL_ATIME) {
871
 
        tp.actime = zt.atime;
872
 
        TTrace((stderr, "close_outfile:  Unix e.f. access time = %ld\n",
873
 
          tp.actime));
874
 
    } else {
875
 
        tp.actime = tp.modtime;
 
896
                       ? ef_scan_for_izux(G.extra_field,
 
897
                           G.lrec.extra_field_length, 0,
 
898
                           G.lrec.last_mod_dos_datetime, &zt, NULL)
 
899
                       : 0);
 
900
        if (eb_izux_flg & EB_UT_FL_MTIME) {
 
901
            tp.modtime = zt.mtime;
 
902
            TTrace((stderr,
 
903
              "\nclose_outfile:  Unix e.f. modif. time = %ld\n",
 
904
              tp.modtime));
 
905
        } else {
 
906
            tp.modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
 
907
        }
 
908
        if (eb_izux_flg & EB_UT_FL_ATIME) {
 
909
            tp.actime = zt.atime;
 
910
            TTrace((stderr,
 
911
              "close_outfile:  Unix e.f. access time = %ld\n",
 
912
              tp.actime));
 
913
        } else {
 
914
            tp.actime = tp.modtime;
 
915
            TTrace((stderr,
 
916
              "\nclose_outfile:  modification/access times = %ld\n",
 
917
              tp.modtime));
 
918
        }
 
919
#else /* !USE_EF_UT_TIME */
 
920
        tp.actime = tp.modtime
 
921
          = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
 
922
 
876
923
        TTrace((stderr, "\nclose_outfile:  modification/access times = %ld\n",
877
924
          tp.modtime));
878
 
    }
879
 
#else /* !USE_EF_UT_TIME */
880
 
    tp.actime = tp.modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
881
 
 
882
 
    TTrace((stderr, "\nclose_outfile:  modification/access times = %ld\n",
883
 
      tp.modtime));
884
925
#endif /* ?USE_EF_UT_TIME */
885
926
 
886
 
    /* set the file's access and modification times */
887
 
    if (utime(G.filename, &tp))
888
 
        Info(slide, 0x201, ((char *)slide,
889
 
          "warning:  cannot set the time for %s\n", FnFilter1(G.filename)));
 
927
        /* set the file's access and modification times */
 
928
        if (utime(G.filename, &tp))
 
929
            Info(slide, 0x201, ((char *)slide,
 
930
              "warning:  cannot set the time for %s\n",
 
931
              FnFilter1(G.filename)));
 
932
    }
890
933
 
891
934
/*---------------------------------------------------------------------------
892
935
    Change the file permissions from default ones to those stored in the
895
938
 
896
939
#ifndef NO_CHMOD
897
940
    if (chmod(G.filename, 0xffff & G.pInfo->file_attr))
898
 
            perror("chmod (file attributes) error");
 
941
        perror("chmod (file attributes) error");
899
942
#endif
900
943
 
901
944
} /* end function close_outfile() */