2 * Copyright 2012 Kamran Zafar
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 package org.kamranzafar.jtar;
29 * 108 8 Owner's numeric user ID
30 * 116 8 Group's numeric user ID
31 * 124 12 File size in bytes
32 * 136 12 Last modification time in numeric Unix time format
33 * 148 8 Checksum for header block
34 * 156 1 Link indicator (file type)
35 * 157 100 Name of linked file
44 * (ASCII NUL) Normal file (now obsolete)
47 * '3' Character special
60 * 257 6 UStar indicator "ustar"
61 * 263 2 UStar version "00"
62 * 265 32 Owner user name
63 * 297 32 Owner group name
64 * 329 8 Device major number
65 * 337 8 Device minor number
66 * 345 155 Filename prefix
70 public class TarHeader {
75 public static final int NAMELEN = 100;
76 public static final int MODELEN = 8;
77 public static final int UIDLEN = 8;
78 public static final int GIDLEN = 8;
79 public static final int SIZELEN = 12;
80 public static final int MODTIMELEN = 12;
81 public static final int CHKSUMLEN = 8;
82 public static final byte LF_OLDNORM = 0;
87 public static final byte LF_NORMAL = (byte) '0';
88 public static final byte LF_LINK = (byte) '1';
89 public static final byte LF_SYMLINK = (byte) '2';
90 public static final byte LF_CHR = (byte) '3';
91 public static final byte LF_BLK = (byte) '4';
92 public static final byte LF_DIR = (byte) '5';
93 public static final byte LF_FIFO = (byte) '6';
94 public static final byte LF_CONTIG = (byte) '7';
100 public static final String USTAR_MAGIC = "ustar"; // POSIX
102 public static final int USTAR_MAGICLEN = 8;
103 public static final int USTAR_USER_NAMELEN = 32;
104 public static final int USTAR_GROUP_NAMELEN = 32;
105 public static final int USTAR_DEVLEN = 8;
106 public static final int USTAR_FILENAME_PREFIX = 155;
109 public StringBuffer name;
116 public byte linkFlag;
117 public StringBuffer linkName;
118 public StringBuffer magic; // ustar indicator and version
119 public StringBuffer userName;
120 public StringBuffer groupName;
123 public StringBuffer namePrefix;
126 this.magic = new StringBuffer(TarHeader.USTAR_MAGIC);
128 this.name = new StringBuffer();
129 this.linkName = new StringBuffer();
131 String user = System.getProperty("user.name", "");
133 if (user.length() > 31)
134 user = user.substring(0, 31);
138 this.userName = new StringBuffer(user);
139 this.groupName = new StringBuffer("");
140 this.namePrefix = new StringBuffer();
144 * Parse an entry name from a header buffer.
148 * The header buffer from which to parse.
150 * The offset into the buffer from which to parse.
152 * The number of header bytes to parse.
153 * @return The header's entry name.
155 public static StringBuffer parseName(byte[] header, int offset, int length) {
156 StringBuffer result = new StringBuffer(length);
158 int end = offset + length;
159 for (int i = offset; i < end; ++i) {
162 result.append((char) header[i]);
169 * Determine the number of bytes in an entry name.
173 * The header buffer from which to parse.
175 * The offset into the buffer from which to parse.
177 * The number of header bytes to parse.
178 * @return The number of bytes in a header's entry name.
180 public static int getNameBytes(StringBuffer name, byte[] buf, int offset, int length) {
183 for (i = 0; i < length && i < name.length(); ++i) {
184 buf[offset + i] = (byte) name.charAt(i);
187 for (; i < length; ++i) {
191 return offset + length;
195 * Creates a new header for a file/directory entry.
203 * Last modification time in numeric Unix time format
209 public static TarHeader createHeader(String entryName, long size, long modTime, boolean dir) {
210 String name = entryName;
211 name = TarUtils.trim(name.replace(File.separatorChar, '/'), '/');
213 TarHeader header = new TarHeader();
214 header.linkName = new StringBuffer("");
216 if (name.length() > 100) {
217 header.namePrefix = new StringBuffer(name.substring(0, name.lastIndexOf('/')));
218 header.name = new StringBuffer(name.substring(name.lastIndexOf('/') + 1));
220 header.name = new StringBuffer(name);
224 header.mode = 040755;
225 header.linkFlag = TarHeader.LF_DIR;
226 if (header.name.charAt(header.name.length() - 1) != '/') {
227 header.name.append("/");
231 header.mode = 0100644;
232 header.linkFlag = TarHeader.LF_NORMAL;
236 header.modTime = modTime;