Subversion Repositories Kolibri OS

Rev

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