blob: 4a6491bf2026a26f2e52fcc0a08a6e5a3aa4e3ab [file] [log] [blame]
Torsten Curdtca165392008-07-10 10:17:44 +00001/*
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 */
19package org.apache.commons.compress.archivers.tar;
20
21import java.io.File;
22import java.util.Date;
23import java.util.Locale;
24
25import org.apache.commons.compress.archivers.ArchiveEntry;
26
27/**
Torsten Curdt46ad24d2009-01-08 11:09:25 +000028 * This class represents an entry in a Tar archive. It consists
29 * of the entry's header, as well as the entry's File. Entries
30 * can be instantiated in one of three ways, depending on how
31 * they are to be used.
32 * <p>
33 * TarEntries that are created from the header bytes read from
34 * an archive are instantiated with the TarEntry( byte[] )
35 * constructor. These entries will be used when extracting from
36 * or listing the contents of an archive. These entries have their
37 * header filled in using the header bytes. They also set the File
38 * to null, since they reference an archive entry not a file.
39 * <p>
40 * TarEntries that are created from Files that are to be written
41 * into an archive are instantiated with the TarEntry( File )
42 * constructor. These entries have their header filled in using
43 * the File's information. They also keep a reference to the File
44 * for convenience when writing entries.
45 * <p>
46 * Finally, TarEntries can be constructed from nothing but a name.
47 * This allows the programmer to construct the entry by hand, for
48 * instance when only an InputStream is available for writing to
49 * the archive, and the header information is constructed from
50 * other information. In this case the header fields are set to
51 * defaults and the File is set to null.
Torsten Curdtca165392008-07-10 10:17:44 +000052 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +000053 * <p>
54 * The C structure for a Tar Entry's header is:
55 * <pre>
Torsten Curdtca165392008-07-10 10:17:44 +000056 * struct header {
57 * char name[NAMSIZ];
58 * char mode[8];
59 * char uid[8];
60 * char gid[8];
61 * char size[12];
62 * char mtime[12];
63 * char chksum[8];
64 * char linkflag;
65 * char linkname[NAMSIZ];
66 * char magic[8];
67 * char uname[TUNMLEN];
68 * char gname[TGNMLEN];
69 * char devmajor[8];
70 * char devminor[8];
71 * } header;
72 * </pre>
Torsten Curdt46ad24d2009-01-08 11:09:25 +000073 *
Torsten Curdtca165392008-07-10 10:17:44 +000074 */
Torsten Curdtca165392008-07-10 10:17:44 +000075
Torsten Curdt46ad24d2009-01-08 11:09:25 +000076public class TarArchiveEntry implements TarConstants, ArchiveEntry {
77 /** The entry's name. */
78 private StringBuffer name;
Torsten Curdtca165392008-07-10 10:17:44 +000079
Torsten Curdt46ad24d2009-01-08 11:09:25 +000080 /** The entry's permission mode. */
81 private int mode;
Torsten Curdtca165392008-07-10 10:17:44 +000082
Torsten Curdt46ad24d2009-01-08 11:09:25 +000083 /** The entry's user id. */
84 private int userId;
Torsten Curdtca165392008-07-10 10:17:44 +000085
Torsten Curdt46ad24d2009-01-08 11:09:25 +000086 /** The entry's group id. */
87 private int groupId;
Torsten Curdtca165392008-07-10 10:17:44 +000088
Torsten Curdt46ad24d2009-01-08 11:09:25 +000089 /** The entry's size. */
90 private long size;
Torsten Curdtca165392008-07-10 10:17:44 +000091
Torsten Curdt46ad24d2009-01-08 11:09:25 +000092 /** The entry's modification time. */
93 private long modTime;
Torsten Curdtca165392008-07-10 10:17:44 +000094
Torsten Curdt46ad24d2009-01-08 11:09:25 +000095 /** The entry's link flag. */
96 private byte linkFlag;
Torsten Curdtca165392008-07-10 10:17:44 +000097
Torsten Curdt46ad24d2009-01-08 11:09:25 +000098 /** The entry's link name. */
99 private StringBuffer linkName;
Torsten Curdtca165392008-07-10 10:17:44 +0000100
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000101 /** The entry's magic tag. */
102 private StringBuffer magic;
Torsten Curdtca165392008-07-10 10:17:44 +0000103
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000104 /** The entry's user name. */
105 private StringBuffer userName;
Torsten Curdtca165392008-07-10 10:17:44 +0000106
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000107 /** The entry's group name. */
108 private StringBuffer groupName;
Torsten Curdtca165392008-07-10 10:17:44 +0000109
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000110 /** The entry's major device number. */
111 private int devMajor;
Torsten Curdtca165392008-07-10 10:17:44 +0000112
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000113 /** The entry's minor device number. */
114 private int devMinor;
Torsten Curdtca165392008-07-10 10:17:44 +0000115
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000116 /** The entry's file reference */
117 private File file;
Torsten Curdtca165392008-07-10 10:17:44 +0000118
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000119 /** Maximum length of a user's name in the tar file */
120 public static final int MAX_NAMELEN = 31;
Torsten Curdtca165392008-07-10 10:17:44 +0000121
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000122 /** Default permissions bits for directories */
123 public static final int DEFAULT_DIR_MODE = 040755;
Torsten Curdtca165392008-07-10 10:17:44 +0000124
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000125 /** Default permissions bits for files */
126 public static final int DEFAULT_FILE_MODE = 0100644;
Torsten Curdtca165392008-07-10 10:17:44 +0000127
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000128 /** Convert millis to seconds */
129 public static final int MILLIS_PER_SECOND = 1000;
Torsten Curdtca165392008-07-10 10:17:44 +0000130
131 /**
132 * Construct an empty entry and prepares the header values.
133 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000134 private TarArchiveEntry () {
135 this.magic = new StringBuffer(TMAGIC);
136 this.name = new StringBuffer();
137 this.linkName = new StringBuffer();
Torsten Curdtca165392008-07-10 10:17:44 +0000138
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000139 String user = System.getProperty("user.name", "");
140
141 if (user.length() > MAX_NAMELEN) {
142 user = user.substring(0, MAX_NAMELEN);
Torsten Curdtca165392008-07-10 10:17:44 +0000143 }
144
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000145 this.userId = 0;
146 this.groupId = 0;
147 this.userName = new StringBuffer(user);
148 this.groupName = new StringBuffer("");
149 this.file = null;
Torsten Curdtca165392008-07-10 10:17:44 +0000150 }
151
152 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000153 * Construct an entry with only a name. This allows the programmer
154 * to construct the entry's header "by hand". File is set to null.
Torsten Curdtca165392008-07-10 10:17:44 +0000155 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000156 * @param name the entry name
Torsten Curdtca165392008-07-10 10:17:44 +0000157 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000158 public TarArchiveEntry(String name) {
159 this();
160
161 boolean isDir = name.endsWith("/");
162
163 this.devMajor = 0;
164 this.devMinor = 0;
165 this.name = new StringBuffer(name);
166 this.mode = isDir ? DEFAULT_DIR_MODE : DEFAULT_FILE_MODE;
167 this.linkFlag = isDir ? LF_DIR : LF_NORMAL;
168 this.userId = 0;
169 this.groupId = 0;
170 this.size = 0;
171 this.modTime = (new Date()).getTime() / MILLIS_PER_SECOND;
172 this.linkName = new StringBuffer("");
173 this.userName = new StringBuffer("");
174 this.groupName = new StringBuffer("");
175 this.devMajor = 0;
176 this.devMinor = 0;
177
Torsten Curdtca165392008-07-10 10:17:44 +0000178 }
179
180 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000181 * Construct an entry with a name and a link flag.
Torsten Curdtca165392008-07-10 10:17:44 +0000182 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000183 * @param name the entry name
184 * @param linkFlag the entry link flag.
Torsten Curdtca165392008-07-10 10:17:44 +0000185 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000186 public TarArchiveEntry(String name, byte linkFlag) {
187 this(name);
188 this.linkFlag = linkFlag;
Torsten Curdtca165392008-07-10 10:17:44 +0000189 }
190
191 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000192 * Construct an entry for a file. File is set to file, and the
193 * header is constructed from information from the file.
Torsten Curdtca165392008-07-10 10:17:44 +0000194 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000195 * @param file The file that the entry represents.
Torsten Curdtca165392008-07-10 10:17:44 +0000196 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000197 public TarArchiveEntry(File file) {
198 this();
Torsten Curdtca165392008-07-10 10:17:44 +0000199
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000200 this.file = file;
Torsten Curdtca165392008-07-10 10:17:44 +0000201
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000202 String fileName = file.getPath();
203 String osname = System.getProperty("os.name").toLowerCase(Locale.US);
Torsten Curdtca165392008-07-10 10:17:44 +0000204
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000205 if (osname != null) {
Torsten Curdtca165392008-07-10 10:17:44 +0000206
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000207 // Strip off drive letters!
208 // REVIEW Would a better check be "(File.separator == '\')"?
Torsten Curdtca165392008-07-10 10:17:44 +0000209
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000210 if (osname.startsWith("windows")) {
211 if (fileName.length() > 2) {
212 char ch1 = fileName.charAt(0);
213 char ch2 = fileName.charAt(1);
Torsten Curdtca165392008-07-10 10:17:44 +0000214
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000215 if (ch2 == ':'
216 && ((ch1 >= 'a' && ch1 <= 'z')
217 || (ch1 >= 'A' && ch1 <= 'Z'))) {
218 fileName = fileName.substring(2);
219 }
220 }
221 } else if (osname.indexOf("netware") > -1) {
222 int colon = fileName.indexOf(':');
223 if (colon != -1) {
224 fileName = fileName.substring(colon + 1);
225 }
226 }
Torsten Curdtca165392008-07-10 10:17:44 +0000227 }
228
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000229 fileName = fileName.replace(File.separatorChar, '/');
Torsten Curdtca165392008-07-10 10:17:44 +0000230
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000231 // No absolute pathnames
232 // Windows (and Posix?) paths can start with "\\NetworkDrive\",
233 // so we loop on starting /'s.
234 while (fileName.startsWith("/")) {
235 fileName = fileName.substring(1);
Torsten Curdtca165392008-07-10 10:17:44 +0000236 }
237
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000238 this.linkName = new StringBuffer("");
239 this.name = new StringBuffer(fileName);
240
241 if (file.isDirectory()) {
242 this.mode = DEFAULT_DIR_MODE;
243 this.linkFlag = LF_DIR;
244
245 if (this.name.charAt(this.name.length() - 1) != '/') {
246 this.name.append("/");
247 }
248 } else {
249 this.mode = DEFAULT_FILE_MODE;
250 this.linkFlag = LF_NORMAL;
251 }
252
253 this.size = file.length();
254 this.modTime = file.lastModified() / MILLIS_PER_SECOND;
255 this.devMajor = 0;
256 this.devMinor = 0;
Torsten Curdtca165392008-07-10 10:17:44 +0000257 }
258
259 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000260 * Construct an entry from an archive's header bytes. File is set
261 * to null.
Torsten Curdtca165392008-07-10 10:17:44 +0000262 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000263 * @param headerBuf The header bytes from a tar archive entry.
Torsten Curdtca165392008-07-10 10:17:44 +0000264 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000265 public TarArchiveEntry(byte[] headerBuf) {
266 this();
267 parseTarHeader(headerBuf);
Torsten Curdtca165392008-07-10 10:17:44 +0000268 }
269
270 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000271 * Determine if the two entries are equal. Equality is determined
272 * by the header names being equal.
Torsten Curdtca165392008-07-10 10:17:44 +0000273 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000274 * @param it Entry to be checked for equality.
275 * @return True if the entries are equal.
Torsten Curdtca165392008-07-10 10:17:44 +0000276 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000277 public boolean equals(TarArchiveEntry it) {
278 return getName().equals(it.getName());
Torsten Curdtca165392008-07-10 10:17:44 +0000279 }
280
281 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000282 * Determine if the two entries are equal. Equality is determined
283 * by the header names being equal.
Torsten Curdtca165392008-07-10 10:17:44 +0000284 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000285 * @param it Entry to be checked for equality.
286 * @return True if the entries are equal.
Torsten Curdtca165392008-07-10 10:17:44 +0000287 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000288 public boolean equals(Object it) {
289 if (it == null || getClass() != it.getClass()) {
290 return false;
291 }
292 return equals((TarArchiveEntry) it);
Torsten Curdtca165392008-07-10 10:17:44 +0000293 }
294
295 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000296 * Hashcodes are based on entry names.
Torsten Curdtca165392008-07-10 10:17:44 +0000297 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000298 * @return the entry hashcode
Torsten Curdtca165392008-07-10 10:17:44 +0000299 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000300 public int hashCode() {
301 return getName().hashCode();
Torsten Curdtca165392008-07-10 10:17:44 +0000302 }
303
304 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000305 * Determine if the given entry is a descendant of this entry.
306 * Descendancy is determined by the name of the descendant
307 * starting with this entry's name.
Torsten Curdtca165392008-07-10 10:17:44 +0000308 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000309 * @param desc Entry to be checked as a descendent of this.
310 * @return True if entry is a descendant of this.
Torsten Curdtca165392008-07-10 10:17:44 +0000311 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000312 public boolean isDescendent(TarArchiveEntry desc) {
313 return desc.getName().startsWith(getName());
Torsten Curdtca165392008-07-10 10:17:44 +0000314 }
315
316 /**
317 * Get this entry's name.
318 *
319 * @return This entry's name.
320 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000321 public String getName() {
322 return name.toString();
Torsten Curdtca165392008-07-10 10:17:44 +0000323 }
324
325 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000326 * Set this entry's name.
Torsten Curdtca165392008-07-10 10:17:44 +0000327 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000328 * @param name This entry's new name.
Torsten Curdtca165392008-07-10 10:17:44 +0000329 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000330 public void setName(String name) {
331 this.name = new StringBuffer(name);
Torsten Curdtca165392008-07-10 10:17:44 +0000332 }
333
334 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000335 * Set the mode for this entry
Torsten Curdtca165392008-07-10 10:17:44 +0000336 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000337 * @param mode the mode for this entry
Torsten Curdtca165392008-07-10 10:17:44 +0000338 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000339 public void setMode(int mode) {
340 this.mode = mode;
Torsten Curdtca165392008-07-10 10:17:44 +0000341 }
342
343 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000344 * Get this entry's link name.
Torsten Curdtca165392008-07-10 10:17:44 +0000345 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000346 * @return This entry's link name.
Torsten Curdtca165392008-07-10 10:17:44 +0000347 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000348 public String getLinkName() {
349 return linkName.toString();
Torsten Curdtca165392008-07-10 10:17:44 +0000350 }
351
352 /**
353 * Get this entry's user id.
354 *
355 * @return This entry's user id.
356 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000357 public int getUserId() {
358 return userId;
359 }
360
361 /**
362 * Set this entry's user id.
363 *
364 * @param userId This entry's new user id.
365 */
366 public void setUserId(int userId) {
367 this.userId = userId;
368 }
369
370 /**
371 * Get this entry's group id.
372 *
373 * @return This entry's group id.
374 */
375 public int getGroupId() {
376 return groupId;
377 }
378
379 /**
380 * Set this entry's group id.
381 *
382 * @param groupId This entry's new group id.
383 */
384 public void setGroupId(int groupId) {
385 this.groupId = groupId;
Torsten Curdtca165392008-07-10 10:17:44 +0000386 }
387
388 /**
389 * Get this entry's user name.
390 *
391 * @return This entry's user name.
392 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000393 public String getUserName() {
394 return userName.toString();
Torsten Curdtca165392008-07-10 10:17:44 +0000395 }
396
397 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000398 * Set this entry's user name.
Torsten Curdtca165392008-07-10 10:17:44 +0000399 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000400 * @param userName This entry's new user name.
Torsten Curdtca165392008-07-10 10:17:44 +0000401 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000402 public void setUserName(String userName) {
403 this.userName = new StringBuffer(userName);
404 }
405
406 /**
407 * Get this entry's group name.
408 *
409 * @return This entry's group name.
410 */
411 public String getGroupName() {
412 return groupName.toString();
413 }
414
415 /**
416 * Set this entry's group name.
417 *
418 * @param groupName This entry's new group name.
419 */
420 public void setGroupName(String groupName) {
421 this.groupName = new StringBuffer(groupName);
422 }
423
424 /**
425 * Convenience method to set this entry's group and user ids.
426 *
427 * @param userId This entry's new user id.
428 * @param groupId This entry's new group id.
429 */
430 public void setIds(int userId, int groupId) {
431 setUserId(userId);
432 setGroupId(groupId);
433 }
434
435 /**
436 * Convenience method to set this entry's group and user names.
437 *
438 * @param userName This entry's new user name.
439 * @param groupName This entry's new group name.
440 */
441 public void setNames(String userName, String groupName) {
442 setUserName(userName);
443 setGroupName(groupName);
444 }
445
446 /**
447 * Set this entry's modification time. The parameter passed
448 * to this method is in "Java time".
449 *
450 * @param time This entry's new modification time.
451 */
452 public void setModTime(long time) {
453 modTime = time / MILLIS_PER_SECOND;
454 }
455
456 /**
457 * Set this entry's modification time.
458 *
459 * @param time This entry's new modification time.
460 */
461 public void setModTime(Date time) {
462 modTime = time.getTime() / MILLIS_PER_SECOND;
463 }
464
465 /**
466 * Set this entry's modification time.
467 *
468 * @return time This entry's new modification time.
469 */
470 public Date getModTime() {
471 return new Date(modTime * MILLIS_PER_SECOND);
472 }
473
474 /**
475 * Get this entry's file.
476 *
477 * @return This entry's file.
478 */
479 public File getFile() {
480 return file;
481 }
482
483 /**
484 * Get this entry's mode.
485 *
486 * @return This entry's mode.
487 */
488 public int getMode() {
489 return mode;
490 }
491
492 /**
493 * Get this entry's file size.
494 *
495 * @return This entry's file size.
496 */
497 public long getSize() {
498 return size;
499 }
500
501 /**
502 * Set this entry's file size.
503 *
504 * @param size This entry's new file size.
505 */
506 public void setSize(long size) {
507 this.size = size;
508 }
509
510
511 /**
512 * Indicate if this entry is a GNU long name block
513 *
514 * @return true if this is a long name extension provided by GNU tar
515 */
516 public boolean isGNULongNameEntry() {
517 return linkFlag == LF_GNUTYPE_LONGNAME
518 && name.toString().equals(GNU_LONGLINK);
Torsten Curdtca165392008-07-10 10:17:44 +0000519 }
520
521 /**
522 * Return whether or not this entry represents a directory.
523 *
524 * @return True if this entry is a directory.
525 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000526 public boolean isDirectory() {
527 if (file != null) {
528 return file.isDirectory();
Torsten Curdtca165392008-07-10 10:17:44 +0000529 }
530
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000531 if (linkFlag == LF_DIR) {
Torsten Curdtca165392008-07-10 10:17:44 +0000532 return true;
533 }
534
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000535 if (getName().endsWith("/")) {
Torsten Curdtca165392008-07-10 10:17:44 +0000536 return true;
537 }
538
539 return false;
540 }
541
542 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000543 * If this entry represents a file, and the file is a directory, return
544 * an array of TarEntries for this entry's children.
Torsten Curdtca165392008-07-10 10:17:44 +0000545 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000546 * @return An array of TarEntry's for this entry's children.
Torsten Curdtca165392008-07-10 10:17:44 +0000547 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000548 public TarArchiveEntry[] getDirectoryEntries() {
549 if (file == null || !file.isDirectory()) {
550 return new TarArchiveEntry[0];
551 }
552
553 String[] list = file.list();
554 TarArchiveEntry[] result = new TarArchiveEntry[list.length];
555
556 for (int i = 0; i < list.length; ++i) {
557 result[i] = new TarArchiveEntry(new File(file, list[i]));
558 }
559
560 return result;
Torsten Curdtca165392008-07-10 10:17:44 +0000561 }
562
563 /**
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000564 * Write an entry's header information to a header buffer.
Torsten Curdtca165392008-07-10 10:17:44 +0000565 *
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000566 * @param outbuf The tar entry header buffer to fill in.
Torsten Curdtca165392008-07-10 10:17:44 +0000567 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000568 public void writeEntryHeader(byte[] outbuf) {
569 int offset = 0;
570
571 offset = TarUtils.getNameBytes(name, outbuf, offset, NAMELEN);
572 offset = TarUtils.getOctalBytes(mode, outbuf, offset, MODELEN);
573 offset = TarUtils.getOctalBytes(userId, outbuf, offset, UIDLEN);
574 offset = TarUtils.getOctalBytes(groupId, outbuf, offset, GIDLEN);
575 offset = TarUtils.getLongOctalBytes(size, outbuf, offset, SIZELEN);
576 offset = TarUtils.getLongOctalBytes(modTime, outbuf, offset, MODTIMELEN);
577
578 int csOffset = offset;
579
580 for (int c = 0; c < CHKSUMLEN; ++c) {
581 outbuf[offset++] = (byte) ' ';
582 }
583
584 outbuf[offset++] = linkFlag;
585 offset = TarUtils.getNameBytes(linkName, outbuf, offset, NAMELEN);
586 offset = TarUtils.getNameBytes(magic, outbuf, offset, MAGICLEN);
587 offset = TarUtils.getNameBytes(userName, outbuf, offset, UNAMELEN);
588 offset = TarUtils.getNameBytes(groupName, outbuf, offset, GNAMELEN);
589 offset = TarUtils.getOctalBytes(devMajor, outbuf, offset, DEVLEN);
590 offset = TarUtils.getOctalBytes(devMinor, outbuf, offset, DEVLEN);
591
592 while (offset < outbuf.length) {
593 outbuf[offset++] = 0;
594 }
595
596 long chk = TarUtils.computeCheckSum(outbuf);
597
598 TarUtils.getCheckSumOctalBytes(chk, outbuf, csOffset, CHKSUMLEN);
Torsten Curdtca165392008-07-10 10:17:44 +0000599 }
600
601 /**
602 * Parse an entry's header information from a header buffer.
603 *
604 * @param header The tar entry header buffer to get information from.
605 */
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000606 public void parseTarHeader(byte[] header) {
Torsten Curdtca165392008-07-10 10:17:44 +0000607 int offset = 0;
608
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000609 name = TarUtils.parseName(header, offset, NAMELEN);
Torsten Curdtca165392008-07-10 10:17:44 +0000610 offset += NAMELEN;
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000611 mode = (int) TarUtils.parseOctal(header, offset, MODELEN);
612 offset += MODELEN;
613 userId = (int) TarUtils.parseOctal(header, offset, UIDLEN);
614 offset += UIDLEN;
615 groupId = (int) TarUtils.parseOctal(header, offset, GIDLEN);
616 offset += GIDLEN;
617 size = TarUtils.parseOctal(header, offset, SIZELEN);
618 offset += SIZELEN;
619 modTime = TarUtils.parseOctal(header, offset, MODTIMELEN);
620 offset += MODTIMELEN;
621 offset += CHKSUMLEN;
622 linkFlag = header[offset++];
623 linkName = TarUtils.parseName(header, offset, NAMELEN);
Torsten Curdtca165392008-07-10 10:17:44 +0000624 offset += NAMELEN;
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000625 magic = TarUtils.parseName(header, offset, MAGICLEN);
626 offset += MAGICLEN;
627 userName = TarUtils.parseName(header, offset, UNAMELEN);
628 offset += UNAMELEN;
629 groupName = TarUtils.parseName(header, offset, GNAMELEN);
630 offset += GNAMELEN;
631 devMajor = (int) TarUtils.parseOctal(header, offset, DEVLEN);
632 offset += DEVLEN;
633 devMinor = (int) TarUtils.parseOctal(header, offset, DEVLEN);
Torsten Curdtca165392008-07-10 10:17:44 +0000634 }
635}
Torsten Curdt46ad24d2009-01-08 11:09:25 +0000636