Rev 6764 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6764 | Rev 6775 | ||
---|---|---|---|
Line 14... | Line 14... | ||
14 | mapname() |
14 | mapname() |
15 | checkdir() |
15 | checkdir() |
16 | close_outfile() |
16 | close_outfile() |
17 | get_extattribs() |
17 | get_extattribs() |
18 | do_wild() |
18 | do_wild() |
- | 19 | set_direc_attribs() |
|
- | 20 | defer_dir_attribs() |
|
Line 19... | Line 21... | ||
19 | 21 | ||
20 | todo |
22 | todo |
21 | russian filenames in arh |
23 | datetime restore for dirs. buf in unzip - crash when SET_DIR_ATTRIB |
22 | datetime restore |
- | |
23 | overwrite request not in stderr |
- | |
24 | - | ||
25 | too many open files error EMFILE when DEBUG - error in newlib open. fixed |
24 | fixed partial |
26 | -d dir error. Use -ddir or -d dir/ |
- | |
27 | 25 | -d dir error (only in unicode). Use -ddir or -d dir/ |
|
28 | release, sizing removing old compression methods or zlib |
26 | russian filenames in arhives. Now works cp866 version, unicode need to fix @kos32.c:470 (GETPATH) |
Line 29... | Line 27... | ||
29 | */ |
27 | */ |
Line 36... | Line 34... | ||
36 | #include "unzip.h" |
34 | #include "unzip.h" |
Line 37... | Line 35... | ||
37 | 35 | ||
38 | // Siemargl fork of Kolibri system API |
36 | // Siemargl fork of Kolibri system API |
Line -... | Line 37... | ||
- | 37 | #include "kos32sys1.h" |
|
- | 38 | ||
- | 39 | static ZCONST char CannotSetItemTimestamps[] = |
|
- | 40 | "warning: cannot set modif./access times for %s\n %s\n"; |
|
- | 41 | static ZCONST char CannotGetTimestamps[] = |
|
- | 42 | " (warning) cannot get fileinfo for %s\n"; |
|
39 | #include "kos32sys1.h" |
43 | |
40 | 44 | ||
41 | /********************************************************************************************************************/ |
45 | /********************************************************************************************************************/ |
Line 42... | Line 46... | ||
42 | /*** Function version() */ |
46 | /*** Function version() */ |
Line 152... | Line 156... | ||
152 | if (cp == (char *)NULL) /* no '/' or not junking dirs */ |
156 | if (cp == (char *)NULL) /* no '/' or not junking dirs */ |
153 | cp = G.filename; /* point to internal zipfile-member pathname */ |
157 | cp = G.filename; /* point to internal zipfile-member pathname */ |
154 | else |
158 | else |
155 | ++cp; /* point to start of last component of path */ |
159 | ++cp; /* point to start of last component of path */ |
Line 156... | Line 160... | ||
156 | 160 | ||
Line 157... | Line 161... | ||
157 | fprintf(stderr, "mapname start[%s]\n", cp); |
161 | Trace((stderr, "mapname start[%s]\n", cp)); |
158 | 162 | ||
159 | /*--------------------------------------------------------------------------- |
163 | /*--------------------------------------------------------------------------- |
Line 321... | Line 325... | ||
321 | } |
325 | } |
Line 322... | Line 326... | ||
322 | 326 | ||
323 | checkdir(__G__ pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */ |
327 | checkdir(__G__ pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */ |
Line 324... | Line 328... | ||
324 | checkdir(__G__ G.filename, GETPATH); |
328 | checkdir(__G__ G.filename, GETPATH); |
Line 325... | Line 329... | ||
325 | 329 | ||
Line 326... | Line 330... | ||
326 | fprintf(stderr, "mapname end[%s]\n", pathcomp); |
330 | Trace((stderr, "mapname end[%s]\n", pathcomp)); |
Line 463... | Line 467... | ||
463 | 467 | ||
464 | /*--------------------------------------------------------------------------- |
468 | /*--------------------------------------------------------------------------- |
465 | GETPATH: copy full path to the string pointed at by pathcomp, and free |
469 | GETPATH: copy full path to the string pointed at by pathcomp, and free |
466 | G.buildpath. |
470 | G.buildpath. |
467 | ---------------------------------------------------------------------------*/ |
- | |
468 | 471 | ---------------------------------------------------------------------------*/ |
|
- | 472 | if (FUNCTION == GETPATH) { |
|
- | 473 | // kolibri UTf8 support |
|
469 | if (FUNCTION == GETPATH) { |
474 | #ifdef UNICODE_SUPPORT |
470 | if(G.native_is_utf8) |
475 | if(G.native_is_utf8) |
- | 476 | { |
|
- | 477 | if (G.buildpath[0] == '/') |
|
- | 478 | { |
|
- | 479 | pathcomp[0] = '/'; // kolibri utf8 flag |
|
- | 480 | pathcomp[1] = 3; // kolibri utf8 flag |
|
- | 481 | strcpy(pathcomp + 2, G.buildpath); |
|
- | 482 | } else |
|
471 | { |
483 | { |
472 | pathcomp[0] = 3; // kolibri utf8 flag |
484 | pathcomp[0] = 3; // kolibri utf8 flag |
473 | strcpy(pathcomp + 1, G.buildpath); |
485 | strcpy(pathcomp + 1, G.buildpath); |
- | 486 | } |
|
474 | } |
487 | } |
- | 488 | else |
|
475 | else |
489 | #endif // UNICODE_SUPPORT |
476 | strcpy(pathcomp, G.buildpath); |
490 | strcpy(pathcomp, G.buildpath); |
477 | Trace((stderr, "getting and freeing path [%s]\n", |
491 | Trace((stderr, "getting and freeing path [%s]\n", |
478 | FnFilter1(pathcomp))); |
492 | FnFilter1(pathcomp))); |
479 | free(G.buildpath); |
493 | free(G.buildpath); |
Line 620... | Line 634... | ||
620 | 634 | ||
Line 621... | Line 635... | ||
621 | return MPN_INVALID; /* should never reach */ |
635 | return MPN_INVALID; /* should never reach */ |
Line 622... | Line -... | ||
622 | - | ||
Line 623... | Line 636... | ||
623 | } /* end function checkdir() */ |
636 | |
624 | 637 | } /* end function checkdir() */ |
|
625 | static int get_extattribs OF((__GPRO__ iztimes *pzt, ulg z_uidgid[2])); |
638 | |
626 | 639 | ||
627 | static int get_extattribs(__G__ pzt, z_uidgid) |
640 | /****************************/ |
628 | __GDEF |
641 | /* Function dos_to_kolibri_time() */ |
629 | iztimes *pzt; |
642 | /****************************/ |
630 | ulg z_uidgid[2]; |
643 | void dos_to_kolibri_time(unsigned dos_datetime, unsigned *fdat, unsigned *ftim) |
631 | { |
644 | { |
632 | /*--------------------------------------------------------------------------- |
645 | char* pc = (char*)fdat; |
- | 646 | *pc++ = (dos_datetime >> 16) & 0x1F; // day |
|
633 | Convert from MSDOS-format local time and date to Unix-format 32-bit GMT |
647 | *pc++ = (dos_datetime >> 21) & 0xF; // month |
634 | time: adjust base year from 1980 to 1970, do usual conversions from |
648 | short *ps = (short*)pc; |
635 | yy/mm/dd hh:mm:ss to elapsed seconds, and account for timezone and day- |
649 | *ps = (dos_datetime >> 25) + 1980; // year |
636 | light savings time differences. If we have a Unix extra field, however, |
650 | *ftim = 0; |
637 | we're laughing: both mtime and atime are ours. On the other hand, we |
651 | pc = (char*)ftim; |
Line 638... | Line -... | ||
638 | then have to check for restoration of UID/GID. |
- | |
639 | ---------------------------------------------------------------------------*/ |
- | |
640 | int have_uidgid_flg; |
- | |
641 | unsigned eb_izux_flg; |
- | |
642 | - | ||
643 | eb_izux_flg = 0; // kos32 |
- | |
644 | /* |
- | |
645 | (G.extra_field ? ef_scan_for_izux(G.extra_field, |
- | |
646 | G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime, |
- | |
647 | #ifdef IZ_CHECK_TZ |
- | |
648 | (G.tz_is_valid ? pzt : NULL), |
- | |
649 | #else |
- | |
650 | pzt, |
- | |
651 | #endif |
- | |
652 | z_uidgid) : 0); |
- | |
653 | */ |
- | |
654 | if (eb_izux_flg & EB_UT_FL_MTIME) { |
- | |
655 | TTrace((stderr, "\nget_extattribs: Unix e.f. modif. time = %ld\n", |
- | |
656 | pzt->mtime)); |
- | |
657 | } else { |
- | |
658 | pzt->mtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime); |
- | |
659 | } |
- | |
660 | if (eb_izux_flg & EB_UT_FL_ATIME) { |
- | |
661 | TTrace((stderr, "get_extattribs: Unix e.f. access time = %ld\n", |
- | |
662 | pzt->atime)); |
- | |
663 | } else { |
- | |
664 | pzt->atime = pzt->mtime; |
- | |
665 | TTrace((stderr, "\nget_extattribs: modification/access times = %ld\n", |
- | |
666 | pzt->mtime)); |
- | |
667 | } |
- | |
668 | - | ||
669 | /* if -X option was specified and we have UID/GID info, restore it */ |
- | |
670 | have_uidgid_flg = |
- | |
671 | #ifdef RESTORE_UIDGID |
- | |
672 | (uO.X_flag && (eb_izux_flg & EB_UX2_VALID)); |
- | |
Line 673... | Line 652... | ||
673 | #else |
652 | *pc++ = (dos_datetime & 0x1F) << 1; // sec |
674 | 0; |
653 | *pc++ = (dos_datetime >> 5) & 0x3F; // min |
675 | #endif |
654 | *pc = (dos_datetime >> 11) & 0x1F; // hour |
Line 676... | Line 655... | ||
676 | return have_uidgid_flg; |
655 | } /* end function dos_to_kolibri_time() */ |
677 | } |
656 | |
678 | 657 | ||
679 | /****************************/ |
- | |
680 | /* Function close_outfile() */ |
- | |
681 | /****************************/ |
- | |
682 | - | ||
683 | void close_outfile(__G) /* GRR: change to return PK-style warning level */ |
- | |
684 | __GDEF |
- | |
685 | { |
- | |
686 | union { |
- | |
Line 687... | Line -... | ||
687 | iztimes t3; /* mtime, atime, ctime */ |
- | |
688 | ztimbuf t2; /* modtime, actime */ |
- | |
689 | } zt; |
- | |
690 | ulg z_uidgid[2]; |
- | |
691 | int have_uidgid_flg; |
- | |
692 | - | ||
693 | have_uidgid_flg = get_extattribs(__G__ &(zt.t3), z_uidgid); |
- | |
694 | - | ||
695 | /*--------------------------------------------------------------------------- |
658 | /****************************/ |
696 | If symbolic links are supported, allocate storage for a symlink control |
- | |
697 | structure, put the uncompressed "data" and other required info in it, and |
- | |
698 | add the structure to the "deferred symlinks" chain. Since we know it's a |
- | |
699 | symbolic link to start with, we shouldn't have to worry about overflowing |
- | |
700 | unsigned ints with unsigned longs. |
- | |
701 | ---------------------------------------------------------------------------*/ |
- | |
702 | - | ||
703 | #ifdef SYMLINKS |
- | |
704 | if (G.symlnk) { |
- | |
705 | extent ucsize = (extent)G.lrec.ucsize; |
- | |
706 | # ifdef SET_SYMLINK_ATTRIBS |
- | |
707 | extent attribsize = sizeof(unsigned) + |
- | |
708 | (have_uidgid_flg ? sizeof(z_uidgid) : 0); |
- | |
709 | # else |
- | |
710 | extent attribsize = 0; |
- | |
711 | # endif |
- | |
712 | /* size of the symlink entry is the sum of |
- | |
713 | * (struct size (includes 1st '\0') + 1 additional trailing '\0'), |
- | |
714 | * system specific attribute data size (might be 0), |
- | |
715 | * and the lengths of name and link target. |
- | |
716 | */ |
- | |
717 | extent slnk_entrysize = (sizeof(slinkentry) + 1) + attribsize + |
- | |
718 | ucsize + strlen(G.filename); |
- | |
719 | slinkentry *slnk_entry; |
- | |
720 | - | ||
721 | if (slnk_entrysize < ucsize) { |
- | |
722 | Info(slide, 0x201, ((char *)slide, |
- | |
723 | "warning: symbolic link (%s) failed: mem alloc overflow\n", |
- | |
724 | FnFilter1(G.filename))); |
- | |
725 | fclose(G.outfile); |
659 | /* Function close_outfile() */ |
726 | return; |
- | |
727 | } |
- | |
728 | - | ||
729 | if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) { |
- | |
730 | Info(slide, 0x201, ((char *)slide, |
- | |
731 | "warning: symbolic link (%s) failed: no mem\n", |
- | |
732 | FnFilter1(G.filename))); |
- | |
733 | fclose(G.outfile); |
- | |
734 | return; |
- | |
735 | } |
660 | /****************************/ |
736 | slnk_entry->next = NULL; |
661 | |
737 | slnk_entry->targetlen = ucsize; |
- | |
738 | slnk_entry->attriblen = attribsize; |
- | |
739 | # ifdef SET_SYMLINK_ATTRIBS |
- | |
Line -... | Line 662... | ||
- | 662 | void close_outfile(__G) /* GRR: change to return PK-style warning level */ |
|
- | 663 | __GDEF |
|
740 | memcpy(slnk_entry->buf, &(G.pInfo->file_attr), |
664 | { |
- | 665 | ||
741 | sizeof(unsigned)); |
666 | #if (defined(NO_FCHOWN)) |
- | 667 | fclose(G.outfile); |
|
Line -... | Line 668... | ||
- | 668 | Trace((stdout, "File (%s) closed\n", FnFilter1(G.filename))); |
|
742 | if (have_uidgid_flg) |
669 | #endif |
743 | memcpy(slnk_entry->buf + 4, z_uidgid, sizeof(z_uidgid)); |
670 | |
744 | # endif |
671 | /* skip restoring time stamps on user's request */ |
745 | slnk_entry->target = slnk_entry->buf + slnk_entry->attriblen; |
- | |
746 | slnk_entry->fname = slnk_entry->target + ucsize + 1; |
672 | if (uO.D_flag <= 1) { |
747 | strcpy(slnk_entry->fname, G.filename); |
- | |
748 | - | ||
749 | /* move back to the start of the file to re-read the "link data" */ |
673 | /* set the file's access and modification times */ |
750 | rewind(G.outfile); |
674 | /* siemargl: dont using extra fields */ |
751 | - | ||
752 | if (fread(slnk_entry->target, 1, ucsize, G.outfile) != ucsize) |
- | |
753 | { |
- | |
754 | Info(slide, 0x201, ((char *)slide, |
- | |
755 | "warning: symbolic link (%s) failed\n", |
- | |
756 | FnFilter1(G.filename))); |
- | |
757 | free(slnk_entry); |
- | |
758 | fclose(G.outfile); |
675 | unsigned ftim, fdat; |
759 | return; |
- | |
760 | } |
- | |
761 | fclose(G.outfile); /* close "link" file for good... */ |
- | |
762 | slnk_entry->target[ucsize] = '\0'; |
- | |
763 | if (QCOND2) |
- | |
764 | Info(slide, 0, ((char *)slide, "-> %s ", |
- | |
765 | FnFilter1(slnk_entry->target))); |
- | |
766 | /* add this symlink record to the list of deferred symlinks */ |
- | |
767 | if (G.slink_last != NULL) |
- | |
768 | G.slink_last->next = slnk_entry; |
676 | dos_to_kolibri_time(G.lrec.last_mod_dos_datetime, &fdat, &ftim); |
769 | else |
- | |
770 | G.slink_head = slnk_entry; |
677 | |
771 | G.slink_last = slnk_entry; |
- | |
772 | return; |
- | |
773 | } |
- | |
774 | #endif /* SYMLINKS */ |
- | |
775 | - | ||
776 | #ifdef QLZIP |
678 | fileinfo_t finfo; |
777 | if (G.extra_field) { |
- | |
Line 778... | Line -... | ||
778 | static void qlfix OF((__GPRO__ uch *ef_ptr, unsigned ef_len)); |
- | |
779 | - | ||
780 | qlfix(__G__ G.extra_field, G.lrec.extra_field_length); |
- | |
781 | } |
- | |
782 | #endif |
- | |
783 | 679 | if (get_fileinfo(G.filename, &finfo)) |
|
784 | #if (defined(NO_FCHOWN)) |
- | |
785 | fclose(G.outfile); |
- | |
786 | Trace((stdout, "File (%s) closed\n", FnFilter1(G.filename))); |
- | |
787 | #endif |
- | |
788 | - | ||
789 | // kos. add set file datetime ? |
- | |
790 | #ifndef KOS32 |
- | |
791 | /* if -X option was specified and we have UID/GID info, restore it */ |
680 | { |
792 | if (have_uidgid_flg |
- | |
793 | /* check that both uid and gid values fit into their data sizes */ |
- | |
794 | && ((ulg)(uid_t)(z_uidgid[0]) == z_uidgid[0]) |
- | |
795 | && ((ulg)(gid_t)(z_uidgid[1]) == z_uidgid[1])) { |
- | |
796 | TTrace((stderr, "close_outfile: restoring Unix UID/GID info\n")); |
- | |
797 | #if (defined(NO_FCHOWN)) |
- | |
798 | if (chown(G.filename, (uid_t)z_uidgid[0], (gid_t)z_uidgid[1])) |
- | |
799 | #else |
- | |
800 | if (fchown(fileno(G.outfile), (uid_t)z_uidgid[0], (gid_t)z_uidgid[1])) |
- | |
801 | #endif |
- | |
802 | { |
- | |
803 | if (uO.qflag) |
- | |
804 | Info(slide, 0x201, ((char *)slide, CannotSetItemUidGid, |
- | |
805 | z_uidgid[0], z_uidgid[1], FnFilter1(G.filename), |
- | |
806 | strerror(errno))); |
- | |
807 | else |
- | |
808 | Info(slide, 0x201, ((char *)slide, CannotSetUidGid, |
- | |
809 | z_uidgid[0], z_uidgid[1], strerror(errno))); |
- | |
810 | } |
- | |
811 | } |
- | |
812 | - | ||
813 | #if (!defined(NO_FCHOWN) && defined(NO_FCHMOD)) |
- | |
814 | fclose(G.outfile); |
- | |
815 | #endif |
- | |
816 | - | ||
817 | #if (!defined(NO_FCHOWN) && !defined(NO_FCHMOD)) |
- | |
818 | /*--------------------------------------------------------------------------- |
- | |
819 | Change the file permissions from default ones to those stored in the |
- | |
820 | zipfile. |
- | |
821 | ---------------------------------------------------------------------------*/ |
- | |
822 | - | ||
823 | if (fchmod(fileno(G.outfile), filtattr(__G__ G.pInfo->file_attr))) |
681 | Info(slide, 1, ((char *)slide, CannotGetTimestamps, |
824 | perror("fchmod (file attributes) error"); |
682 | FnFilter1(G.filename))); |
825 | 683 | return; |
|
826 | fclose(G.outfile); |
- | |
827 | #endif /* !NO_FCHOWN && !NO_FCHMOD */ |
- | |
828 | 684 | } |
|
829 | /* skip restoring time stamps on user's request */ |
685 | finfo.flags = G.pInfo->file_attr; |
Line 830... | Line 686... | ||
830 | if (uO.D_flag <= 1) { |
686 | finfo.cr_time = finfo.acc_time = finfo.mod_time = ftim; |
831 | /* set the file's access and modification times */ |
687 | finfo.cr_date = finfo.acc_date = finfo.mod_date = fdat; |
Line 849... | Line 705... | ||
849 | if (chmod(G.filename, filtattr(__G__ G.pInfo->file_attr))) |
705 | if (chmod(G.filename, filtattr(__G__ G.pInfo->file_attr))) |
850 | perror("chmod (file attributes) error"); |
706 | perror("chmod (file attributes) error"); |
851 | #endif |
707 | #endif |
852 | #endif /* NO_FCHOWN || NO_FCHMOD */ |
708 | #endif /* NO_FCHOWN || NO_FCHMOD */ |
Line 853... | Line -... | ||
853 | - | ||
Line 854... | Line 709... | ||
854 | #endif // 0 |
709 | |
Line 855... | Line 710... | ||
855 | 710 | ||
Line 976... | Line 831... | ||
976 | free(G.dirname); |
831 | free(G.dirname); |
977 | return (char *)NULL; |
832 | return (char *)NULL; |
Line 978... | Line 833... | ||
978 | 833 | ||
Line -... | Line 834... | ||
- | 834 | } /* end function do_wild() */ |
|
- | 835 | ||
- | 836 | #ifdef SET_DIR_ATTRIB |
|
- | 837 | int defer_dir_attribs(__G__ pd) |
|
- | 838 | __GDEF |
|
- | 839 | direntry **pd; |
|
- | 840 | { |
|
- | 841 | // do nothing |
|
- | 842 | return PK_OK; |
|
- | 843 | } |
|
- | 844 | ||
- | 845 | int set_direc_attribs(__G__ d) |
|
- | 846 | __GDEF |
|
- | 847 | direntry *d; |
|
- | 848 | { |
|
- | 849 | /* skip restoring time stamps on user's request */ |
|
- | 850 | if (uO.D_flag <= 0) { |
|
- | 851 | /* set the file's access and modification times */ |
|
- | 852 | /* siemargl: dont using extra fields */ |
|
- | 853 | unsigned ftim, fdat; |
|
- | 854 | dos_to_kolibri_time(G.lrec.last_mod_dos_datetime, &fdat, &ftim); |
|
- | 855 | ||
- | 856 | fileinfo_t finfo; |
|
- | 857 | if (get_fileinfo(G.filename, &finfo)) |
|
- | 858 | { |
|
- | 859 | Info(slide, 1, ((char *)slide, CannotGetTimestamps, |
|
- | 860 | FnFilter1(G.filename))); |
|
- | 861 | return PK_WARN; |
|
- | 862 | } |
|
- | 863 | finfo.flags = G.pInfo->file_attr; |
|
- | 864 | finfo.cr_time = finfo.acc_time = finfo.mod_time = ftim; |
|
- | 865 | finfo.cr_date = finfo.acc_date = finfo.mod_date = fdat; |
|
- | 866 | Trace((stderr, "Trying to set dirinfo[%s] date %X, time %X, attr %X\n", FnFilter1(G.filename), fdat, ftim, finfo.flags)); |
|
- | 867 | ||
- | 868 | if (set_fileinfo(G.filename, &finfo)) |
|
- | 869 | { |
|
- | 870 | Info(slide, 1, ((char *)slide, CannotSetItemTimestamps, |
|
- | 871 | FnFilter1(G.filename), strerror(errno))); |
|
- | 872 | return PK_WARN; |
|
- | 873 | } |
|
- | 874 | } |
|
- | 875 | ||
- | 876 | return PK_OK; |
|
- | 877 | } /* end function set_direc_attribs() */ |
|
- | 878 |