197
202
G.pInfo->file_attr = (unsigned)(tmp >> 16);
198
if (G.pInfo->file_attr != 0 || !G.extra_field) {
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!)
217
220
uch *ef = G.extra_field;
218
221
unsigned ef_len = G.crec.extra_field_length;
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);
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.
255
G.pInfo->symlink = S_ISLNK(G.pInfo->file_attr) &&
256
SYMLINK_HOST(G.pInfo->hostnum);
249
260
/* fall through! */
250
261
/* all remaining cases: expand MSDOS read-only bit into write perms */
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!
292
/* Entries "made by FS_FAT_" could have been zipped on a
293
* system that supports POSIX-style symbolic links.
295
G.pInfo->symlink = S_ISLNK(G.pInfo->file_attr) &&
296
(G.pInfo->hostnum == FS_FAT_);
281
300
G.pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);
283
302
} /* end switch (host-OS-created-by) */
443
462
*lastsemi = '\0';
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 "__".
469
if (strcmp(pathcomp, ".") == 0)
471
else if (strcmp(pathcomp, "..") == 0)
472
strcpy(pathcomp, "__");
446
474
#ifdef ACORN_FTYPE_NFS
447
475
/* translate Acorn filetype information if asked to do so */
448
476
if (uO.acorn_nfs_ext &&
796
unsigned ucsize = (unsigned)G.lrec.ucsize;
797
extent slnk_entrysize = sizeof(slinkentry) + ucsize +
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.
828
extent slnk_entrysize = (sizeof(slinkentry) + 1) +
829
ucsize + strlen(G.filename);
799
830
slinkentry *slnk_entry;
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)));
818
851
slnk_entry->fname = slnk_entry->target + ucsize + 1;
819
852
strcpy(slnk_entry->fname, G.filename);
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" */
825
fread(slnk_entry->target, 1, ucsize, G.outfile) != (int)ucsize)
857
if (fread(slnk_entry->target, 1, ucsize, G.outfile) != ucsize)
827
859
Info(slide, 0x201, ((char *)slide,
828
860
"warning: symbolic link (%s) failed\n",
852
886
light savings time differences.
853
887
---------------------------------------------------------------------------*/
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
860
? ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length,
861
0, G.lrec.last_mod_dos_datetime, &zt, NULL)
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",
868
tp.modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
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",
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)
900
if (eb_izux_flg & EB_UT_FL_MTIME) {
901
tp.modtime = zt.mtime;
903
"\nclose_outfile: Unix e.f. modif. time = %ld\n",
906
tp.modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
908
if (eb_izux_flg & EB_UT_FL_ATIME) {
909
tp.actime = zt.atime;
911
"close_outfile: Unix e.f. access time = %ld\n",
914
tp.actime = tp.modtime;
916
"\nclose_outfile: modification/access times = %ld\n",
919
#else /* !USE_EF_UT_TIME */
920
tp.actime = tp.modtime
921
= dos_to_unix_time(G.lrec.last_mod_dos_datetime);
876
923
TTrace((stderr, "\nclose_outfile: modification/access times = %ld\n",
879
#else /* !USE_EF_UT_TIME */
880
tp.actime = tp.modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
882
TTrace((stderr, "\nclose_outfile: modification/access times = %ld\n",
884
925
#endif /* ?USE_EF_UT_TIME */
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)));
891
934
/*---------------------------------------------------------------------------
892
935
Change the file permissions from default ones to those stored in the