View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.commons.compress.archivers.dump;
20  
21  import java.io.IOException;
22  import java.util.Arrays;
23  
24  import org.apache.commons.compress.archivers.zip.ZipEncoding;
25  import org.apache.commons.compress.utils.ByteUtils;
26  
27  /**
28   * Various utilities for dump archives.
29   */
30  final class DumpArchiveUtil {
31  
32      /**
33       * Calculate checksum for buffer.
34       *
35       * @param buffer buffer containing tape segment header
36       * @return checksum
37       */
38      public static int calculateChecksum(final byte[] buffer) {
39          int calc = 0;
40          for (int i = 0; i < 256; i++) {
41              calc += DumpArchiveUtil.convert32(buffer, 4 * i);
42          }
43          return DumpArchiveConstants.CHECKSUM - (calc - DumpArchiveUtil.convert32(buffer, 28));
44      }
45  
46      /**
47       * Reads 2-byte integer from buffer.
48       *
49       * @param buffer The source buffer.
50       * @param offset Where to start reading.
51       * @return the 2-byte entry as an int.
52       */
53      public static int convert16(final byte[] buffer, final int offset) {
54          return (int) ByteUtils.fromLittleEndian(buffer, offset, 2);
55      }
56  
57      /**
58       * Reads 4-byte integer from buffer.
59       *
60       * @param buffer The source buffer.
61       * @param offset Where to start reading.
62       * @return the 4-byte entry as an int.
63       */
64      public static int convert32(final byte[] buffer, final int offset) {
65          return (int) ByteUtils.fromLittleEndian(buffer, offset, 4);
66      }
67  
68      /**
69       * Reads 8-byte integer from buffer.
70       *
71       * @param buffer The source buffer.
72       * @param offset Where to start reading.
73       * @return the 8-byte entry as a long.
74       */
75      public static long convert64(final byte[] buffer, final int offset) {
76          return ByteUtils.fromLittleEndian(buffer, offset, 8);
77      }
78  
79      /**
80       * Decodes a byte array to a string.
81       */
82      static String decode(final ZipEncoding encoding, final byte[] b, final int offset, final int len) throws IOException {
83              if (offset > offset + len) {
84                  throw new IOException("Invalid offset/length combination");
85              }
86              return encoding.decode(Arrays.copyOfRange(b, offset, offset + len));
87      }
88  
89      /**
90       * Gets the ino associated with this buffer.
91       *
92       * @param buffer The source buffer.
93       * @return the ino associated with this buffer.
94       */
95      public static int getIno(final byte[] buffer) {
96          return convert32(buffer, 20);
97      }
98  
99      /**
100      * Verifies that the buffer contains a tape segment header.
101      *
102      * @param buffer The source buffer.
103      * @return Whether the buffer contains a tape segment header.
104      */
105     public static boolean verify(final byte[] buffer) {
106         if (buffer == null) {
107             return false;
108         }
109         // verify magic. for now only accept NFS_MAGIC.
110         final int magic = convert32(buffer, 24);
111         if (magic != DumpArchiveConstants.NFS_MAGIC) {
112             return false;
113         }
114         // verify checksum...
115         final int checksum = convert32(buffer, 28);
116         return checksum == calculateChecksum(buffer);
117     }
118 
119     /**
120      * Private constructor to prevent instantiation.
121      */
122     private DumpArchiveUtil() {
123     }
124 }