Rev 6764 | Show entire file | Ignore 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 35... | Line 33... | ||
35 | #define UNZIP_INTERNAL |
33 | #define UNZIP_INTERNAL |
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 |
- | 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"; |
|
Line 39... | Line 43... | ||
39 | #include "kos32sys1.h" |
43 | |
40 | 44 | ||
41 | /********************************************************************************************************************/ |
45 | /********************************************************************************************************************/ |
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 |
- | 485 | strcpy(pathcomp + 1, G.buildpath); |
|
473 | 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 | - | ||
623 | } /* end function checkdir() */ |
636 | |
624 | 637 | } /* end function checkdir() */ |
|
625 | static int get_extattribs OF((__GPRO__ iztimes *pzt, ulg z_uidgid[2])); |
- | |
626 | 638 | ||
627 | static int get_extattribs(__G__ pzt, z_uidgid) |
639 | |
628 | __GDEF |
- | |
629 | iztimes *pzt; |
- | |
630 | ulg z_uidgid[2]; |
- | |
631 | { |
- | |
632 | /*--------------------------------------------------------------------------- |
- | |
633 | Convert from MSDOS-format local time and date to Unix-format 32-bit GMT |
640 | /****************************/ |
634 | time: adjust base year from 1980 to 1970, do usual conversions from |
- | |
635 | yy/mm/dd hh:mm:ss to elapsed seconds, and account for timezone and day- |
- | |
636 | light savings time differences. If we have a Unix extra field, however, |
- | |
637 | we're laughing: both mtime and atime are ours. On the other hand, we |
- | |
638 | then have to check for restoration of UID/GID. |
- | |
639 | ---------------------------------------------------------------------------*/ |
641 | /* Function dos_to_kolibri_time() */ |
640 | int have_uidgid_flg; |
642 | /****************************/ |
641 | unsigned eb_izux_flg; |
- | |
642 | 643 | void dos_to_kolibri_time(unsigned dos_datetime, unsigned *fdat, unsigned *ftim) |
|
643 | eb_izux_flg = 0; // kos32 |
- | |
644 | /* |
- | |
645 | (G.extra_field ? ef_scan_for_izux(G.extra_field, |
644 | { |
646 | G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime, |
- | |
647 | #ifdef IZ_CHECK_TZ |
645 | char* pc = (char*)fdat; |
648 | (G.tz_is_valid ? pzt : NULL), |
- | |
649 | #else |
- | |
650 | pzt, |
- | |
651 | #endif |
646 | *pc++ = (dos_datetime >> 16) & 0x1F; // day |
652 | z_uidgid) : 0); |
- | |
653 | */ |
- | |
654 | if (eb_izux_flg & EB_UT_FL_MTIME) { |
647 | *pc++ = (dos_datetime >> 21) & 0xF; // month |
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 | } |
648 | short *ps = (short*)pc; |
660 | if (eb_izux_flg & EB_UT_FL_ATIME) { |
- | |
661 | TTrace((stderr, "get_extattribs: Unix e.f. access time = %ld\n", |
649 | *ps = (dos_datetime >> 25) + 1980; // year |
662 | pzt->atime)); |
- | |
663 | } else { |
- | |
664 | pzt->atime = pzt->mtime; |
- | |
665 | TTrace((stderr, "\nget_extattribs: modification/access times = %ld\n", |
- | |
666 | pzt->mtime)); |
650 | *ftim = 0; |
667 | } |
- | |
668 | - | ||
669 | /* if -X option was specified and we have UID/GID info, restore it */ |
651 | pc = (char*)ftim; |
670 | have_uidgid_flg = |
- | |
671 | #ifdef RESTORE_UIDGID |
- | |
672 | (uO.X_flag && (eb_izux_flg & EB_UX2_VALID)); |
- | |
673 | #else |
652 | *pc++ = (dos_datetime & 0x1F) << 1; // sec |
674 | 0; |
653 | *pc++ = (dos_datetime >> 5) & 0x3F; // min |
Line 675... | Line 654... | ||
675 | #endif |
654 | *pc = (dos_datetime >> 11) & 0x1F; // hour |
676 | return have_uidgid_flg; |
655 | } /* end function dos_to_kolibri_time() */ |
677 | } |
656 | |
Line 678... | Line 657... | ||
678 | 657 | ||
679 | /****************************/ |
658 | /****************************/ |
680 | /* Function close_outfile() */ |
659 | /* Function close_outfile() */ |
681 | /****************************/ |
- | |
682 | - | ||
683 | void close_outfile(__G) /* GRR: change to return PK-style warning level */ |
- | |
684 | __GDEF |
- | |
685 | { |
- | |
686 | union { |
- | |
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 | /*--------------------------------------------------------------------------- |
- | |
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); |
- | |
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 | } |
- | |
736 | slnk_entry->next = NULL; |
- | |
737 | slnk_entry->targetlen = ucsize; |
- | |
738 | slnk_entry->attriblen = attribsize; |
- | |
739 | # ifdef SET_SYMLINK_ATTRIBS |
- | |
740 | memcpy(slnk_entry->buf, &(G.pInfo->file_attr), |
- | |
741 | sizeof(unsigned)); |
- | |
742 | if (have_uidgid_flg) |
- | |
743 | memcpy(slnk_entry->buf + 4, z_uidgid, sizeof(z_uidgid)); |
- | |
744 | # endif |
- | |
745 | slnk_entry->target = slnk_entry->buf + slnk_entry->attriblen; |
- | |
746 | slnk_entry->fname = slnk_entry->target + ucsize + 1; |
- | |
747 | strcpy(slnk_entry->fname, G.filename); |
- | |
748 | - | ||
749 | /* move back to the start of the file to re-read the "link data" */ |
- | |
750 | rewind(G.outfile); |
- | |
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); |
- | |
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; |
- | |
769 | else |
- | |
770 | G.slink_head = slnk_entry; |
- | |
771 | G.slink_last = slnk_entry; |
- | |
772 | return; |
- | |
773 | } |
- | |
774 | #endif /* SYMLINKS */ |
- | |
775 | - | ||
776 | #ifdef QLZIP |
- | |
777 | if (G.extra_field) { |
- | |
Line 778... | Line 660... | ||
778 | static void qlfix OF((__GPRO__ uch *ef_ptr, unsigned ef_len)); |
660 | /****************************/ |
779 | 661 | ||
780 | qlfix(__G__ G.extra_field, G.lrec.extra_field_length); |
662 | void close_outfile(__G) /* GRR: change to return PK-style warning level */ |
781 | } |
663 | __GDEF |
Line 782... | Line -... | ||
782 | #endif |
- | |
783 | - | ||
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 */ |
- | |
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 | 664 | { |
|
823 | if (fchmod(fileno(G.outfile), filtattr(__G__ G.pInfo->file_attr))) |
665 | |
824 | perror("fchmod (file attributes) error"); |
666 | #if (defined(NO_FCHOWN)) |
- | 667 | fclose(G.outfile); |
|
- | 668 | Trace((stdout, "File (%s) closed\n", FnFilter1(G.filename))); |
|
- | 669 | #endif |
|
- | 670 | ||
- | 671 | /* skip restoring time stamps on user's request */ |
|
825 | 672 | if (uO.D_flag <= 1) { |
|
826 | fclose(G.outfile); |
673 | /* set the file's access and modification times */ |
827 | #endif /* !NO_FCHOWN && !NO_FCHMOD */ |
674 | /* siemargl: dont using extra fields */ |
828 | 675 | unsigned ftim, fdat; |
|
829 | /* skip restoring time stamps on user's request */ |
676 | dos_to_kolibri_time(G.lrec.last_mod_dos_datetime, &fdat, &ftim); |
- | 677 | ||
- | 678 | fileinfo_t finfo; |
|
- | 679 | if (get_fileinfo(G.filename, &finfo)) |
|
- | 680 | { |
|
- | 681 | Info(slide, 1, ((char *)slide, CannotGetTimestamps, |
|
- | 682 | FnFilter1(G.filename))); |
|
- | 683 | return; |
|
- | 684 | } |
|
830 | if (uO.D_flag <= 1) { |
685 | finfo.flags = G.pInfo->file_attr; |
831 | /* set the file's access and modification times */ |
686 | finfo.cr_time = finfo.acc_time = finfo.mod_time = ftim; |
- | 687 | finfo.cr_date = finfo.acc_date = finfo.mod_date = fdat; |
|
832 | if (utime(G.filename, &(zt.t2))) { |
688 | Trace((stderr, "Trying to set fileinfo[%s] date %X, time %X, attr %X\n", FnFilter1(G.filename), fdat, ftim, finfo.flags)); |
833 | if (uO.qflag) |
689 | |
Line 834... | Line 690... | ||
834 | Info(slide, 0x201, ((char *)slide, CannotSetItemTimestamps, |
690 | if (set_fileinfo(G.filename, &finfo)) |
835 | FnFilter1(G.filename), strerror(errno))); |
691 | { |
836 | else |
692 | Info(slide, 1, ((char *)slide, CannotSetItemTimestamps, |
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 975... | Line 830... | ||
975 | if (G.have_dirname) |
830 | if (G.have_dirname) |
976 | free(G.dirname); |
831 | free(G.dirname); |
977 | return (char *)NULL; |
832 | return (char *)NULL; |
Line 978... | Line 833... | ||
978 | 833 | ||
- | 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 |