jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipInfo.java
changeset 24414 2061862eb57c
parent 24413 1d117d2dfe92
parent 24077 0809c9a4d36e
child 24415 43aa54df554d
equal deleted inserted replaced
24413:1d117d2dfe92 24414:2061862eb57c
     1 /*
       
     2  * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  *
       
     8  *   - Redistributions of source code must retain the above copyright
       
     9  *     notice, this list of conditions and the following disclaimer.
       
    10  *
       
    11  *   - Redistributions in binary form must reproduce the above copyright
       
    12  *     notice, this list of conditions and the following disclaimer in the
       
    13  *     documentation and/or other materials provided with the distribution.
       
    14  *
       
    15  *   - Neither the name of Oracle nor the names of its
       
    16  *     contributors may be used to endorse or promote products derived
       
    17  *     from this software without specific prior written permission.
       
    18  *
       
    19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
       
    20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
       
    21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
       
    23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
       
    27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
       
    28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       
    29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    30  */
       
    31 
       
    32 /*
       
    33  * This source code is provided to illustrate the usage of a given feature
       
    34  * or technique and has been deliberately simplified. Additional steps
       
    35  * required for a production-quality application, such as security checks,
       
    36  * input validation and proper error handling, might not be present in
       
    37  * this sample code.
       
    38  */
       
    39 
       
    40 
       
    41 package com.sun.nio.zipfs;
       
    42 
       
    43 import java.nio.file.Paths;
       
    44 import java.util.Collections;
       
    45 import java.util.Map;
       
    46 import static com.sun.nio.zipfs.ZipConstants.*;
       
    47 import static com.sun.nio.zipfs.ZipUtils.*;
       
    48 
       
    49 /**
       
    50  * Print all loc and cen headers of the ZIP file
       
    51  *
       
    52  * @author  Xueming Shen
       
    53  */
       
    54 
       
    55 public class ZipInfo {
       
    56 
       
    57     public static void main(String[] args) throws Throwable {
       
    58         if (args.length < 1) {
       
    59             print("Usage: java ZipInfo zfname");
       
    60         } else {
       
    61             Map<String, ?> env = Collections.emptyMap();
       
    62             ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
       
    63                                     .newFileSystem(Paths.get(args[0]), env));
       
    64             byte[] cen = zfs.cen;
       
    65             if (cen == null) {
       
    66                 print("zip file is empty%n");
       
    67                 return;
       
    68             }
       
    69             int    pos = 0;
       
    70             byte[] buf = new byte[1024];
       
    71             int    no = 1;
       
    72             while (pos + CENHDR < cen.length) {
       
    73                 print("----------------#%d--------------------%n", no++);
       
    74                 printCEN(cen, pos);
       
    75 
       
    76                 // use size CENHDR as the extra bytes to read, just in case the
       
    77                 // loc.extra is bigger than the cen.extra, try to avoid to read
       
    78                 // twice
       
    79                 long len = LOCHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENHDR;
       
    80                 if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
       
    81                     ZipFileSystem.zerror("read loc header failed");
       
    82                 if (LOCEXT(buf) > CENEXT(cen, pos) + CENHDR) {
       
    83                     // have to read the second time;
       
    84                     len = LOCHDR + LOCNAM(buf) + LOCEXT(buf);
       
    85                     if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
       
    86                         ZipFileSystem.zerror("read loc header failed");
       
    87                 }
       
    88                 printLOC(buf);
       
    89                 pos += CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos);
       
    90             }
       
    91             zfs.close();
       
    92         }
       
    93     }
       
    94 
       
    95     static void print(String fmt, Object... objs) {
       
    96         System.out.printf(fmt, objs);
       
    97     }
       
    98 
       
    99     static void printLOC(byte[] loc) {
       
   100         print("%n");
       
   101         print("[Local File Header]%n");
       
   102         print("    Signature   :   %#010x%n", LOCSIG(loc));
       
   103         if (LOCSIG(loc) != LOCSIG) {
       
   104            print("    Wrong signature!");
       
   105            return;
       
   106         }
       
   107         print("    Version     :       %#6x    [%d.%d]%n",
       
   108                   LOCVER(loc), LOCVER(loc) / 10, LOCVER(loc) % 10);
       
   109         print("    Flag        :       %#6x%n", LOCFLG(loc));
       
   110         print("    Method      :       %#6x%n", LOCHOW(loc));
       
   111         print("    LastMTime   :   %#10x    [%tc]%n",
       
   112               LOCTIM(loc), dosToJavaTime(LOCTIM(loc)));
       
   113         print("    CRC         :   %#10x%n", LOCCRC(loc));
       
   114         print("    CSize       :   %#10x%n", LOCSIZ(loc));
       
   115         print("    Size        :   %#10x%n", LOCLEN(loc));
       
   116         print("    NameLength  :       %#6x    [%s]%n",
       
   117                   LOCNAM(loc), new String(loc, LOCHDR, LOCNAM(loc)));
       
   118         print("    ExtraLength :       %#6x%n", LOCEXT(loc));
       
   119         if (LOCEXT(loc) != 0)
       
   120             printExtra(loc, LOCHDR + LOCNAM(loc), LOCEXT(loc));
       
   121     }
       
   122 
       
   123     static void printCEN(byte[] cen, int off) {
       
   124         print("[Central Directory Header]%n");
       
   125         print("    Signature   :   %#010x%n", CENSIG(cen, off));
       
   126         if (CENSIG(cen, off) != CENSIG) {
       
   127            print("    Wrong signature!");
       
   128            return;
       
   129         }
       
   130         print("    VerMadeby   :       %#6x    [%d, %d.%d]%n",
       
   131               CENVEM(cen, off), (CENVEM(cen, off) >> 8),
       
   132               (CENVEM(cen, off) & 0xff) / 10,
       
   133               (CENVEM(cen, off) & 0xff) % 10);
       
   134         print("    VerExtract  :       %#6x    [%d.%d]%n",
       
   135               CENVER(cen, off), CENVER(cen, off) / 10, CENVER(cen, off) % 10);
       
   136         print("    Flag        :       %#6x%n", CENFLG(cen, off));
       
   137         print("    Method      :       %#6x%n", CENHOW(cen, off));
       
   138         print("    LastMTime   :   %#10x    [%tc]%n",
       
   139               CENTIM(cen, off), dosToJavaTime(CENTIM(cen, off)));
       
   140         print("    CRC         :   %#10x%n", CENCRC(cen, off));
       
   141         print("    CSize       :   %#10x%n", CENSIZ(cen, off));
       
   142         print("    Size        :   %#10x%n", CENLEN(cen, off));
       
   143         print("    NameLen     :       %#6x    [%s]%n",
       
   144               CENNAM(cen, off), new String(cen, off + CENHDR, CENNAM(cen, off)));
       
   145         print("    ExtraLen    :       %#6x%n", CENEXT(cen, off));
       
   146         if (CENEXT(cen, off) != 0)
       
   147             printExtra(cen, off + CENHDR + CENNAM(cen, off), CENEXT(cen, off));
       
   148         print("    CommentLen  :       %#6x%n", CENCOM(cen, off));
       
   149         print("    DiskStart   :       %#6x%n", CENDSK(cen, off));
       
   150         print("    Attrs       :       %#6x%n", CENATT(cen, off));
       
   151         print("    AttrsEx     :   %#10x%n", CENATX(cen, off));
       
   152         print("    LocOff      :   %#10x%n", CENOFF(cen, off));
       
   153 
       
   154     }
       
   155 
       
   156     static long locoff(byte[] cen, int pos) {
       
   157         long locoff = CENOFF(cen, pos);
       
   158         if (locoff == ZIP64_MINVAL) {    //ZIP64
       
   159             int off = pos + CENHDR + CENNAM(cen, pos);
       
   160             int end = off + CENEXT(cen, pos);
       
   161             while (off + 4 < end) {
       
   162                 int tag = SH(cen, off);
       
   163                 int sz = SH(cen, off + 2);
       
   164                 if (tag != EXTID_ZIP64) {
       
   165                     off += 4 + sz;
       
   166                     continue;
       
   167                 }
       
   168                 off += 4;
       
   169                 if (CENLEN(cen, pos) == ZIP64_MINVAL)
       
   170                     off += 8;
       
   171                 if (CENSIZ(cen, pos) == ZIP64_MINVAL)
       
   172                     off += 8;
       
   173                 return LL(cen, off);
       
   174             }
       
   175             // should never be here
       
   176         }
       
   177         return locoff;
       
   178     }
       
   179 
       
   180     static void printExtra(byte[] extra, int off, int len) {
       
   181         int end = off + len;
       
   182         while (off + 4 <= end) {
       
   183             int tag = SH(extra, off);
       
   184             int sz = SH(extra, off + 2);
       
   185             print("        [tag=0x%04x, sz=%d, data= ", tag, sz);
       
   186             if (off + sz > end) {
       
   187                 print("    Error: Invalid extra data, beyond extra length");
       
   188                 break;
       
   189             }
       
   190             off += 4;
       
   191             for (int i = 0; i < sz; i++)
       
   192                 print("%02x ", extra[off + i]);
       
   193             print("]%n");
       
   194             switch (tag) {
       
   195             case EXTID_ZIP64 :
       
   196                 print("         ->ZIP64: ");
       
   197                 int pos = off;
       
   198                 while (pos + 8 <= off + sz) {
       
   199                     print(" *0x%x ", LL(extra, pos));
       
   200                     pos += 8;
       
   201                 }
       
   202                 print("%n");
       
   203                 break;
       
   204             case EXTID_NTFS:
       
   205                 print("         ->PKWare NTFS%n");
       
   206                 // 4 bytes reserved
       
   207                 if (SH(extra, off + 4) !=  0x0001 || SH(extra, off + 6) !=  24)
       
   208                     print("    Error: Invalid NTFS sub-tag or subsz");
       
   209                 print("            mtime:%tc%n",
       
   210                       winToJavaTime(LL(extra, off + 8)));
       
   211                 print("            atime:%tc%n",
       
   212                       winToJavaTime(LL(extra, off + 16)));
       
   213                 print("            ctime:%tc%n",
       
   214                       winToJavaTime(LL(extra, off + 24)));
       
   215                 break;
       
   216             case EXTID_EXTT:
       
   217                 print("         ->Info-ZIP Extended Timestamp: flag=%x%n",extra[off]);
       
   218                 pos = off + 1 ;
       
   219                 while (pos + 4 <= off + sz) {
       
   220                     print("            *%tc%n",
       
   221                           unixToJavaTime(LG(extra, pos)));
       
   222                     pos += 4;
       
   223                 }
       
   224                 break;
       
   225             default:
       
   226                 print("         ->[tag=%x, size=%d]%n", tag, sz);
       
   227             }
       
   228             off += sz;
       
   229         }
       
   230     }
       
   231 }