blob: 641fae447b22e019a23ed934bc6eddbb9ecf3ce1 [file] [log] [blame]
Torsten Curdt70c83202009-01-12 11:09:21 +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.cpio;
20
Sebastian Bazleyfec51a12009-03-31 00:35:56 +000021import java.io.File;
Stefan Bodewig17ffd7f2009-08-01 14:52:15 +000022import java.util.Date;
Sebastian Bazleyfec51a12009-03-31 00:35:56 +000023
Torsten Curdt70c83202009-01-12 11:09:21 +000024import org.apache.commons.compress.archivers.ArchiveEntry;
25
26/**
27 * A cpio archive consists of a sequence of files. There are several types of
28 * headers defided in two categories of new and old format. The headers are
Stefan Bodewig176337a2009-03-23 09:10:50 +000029 * recognized by magic numbers:
Torsten Curdt70c83202009-01-12 11:09:21 +000030 *
Stefan Bodewig176337a2009-03-23 09:10:50 +000031 * <ul>
32 * <li>"070701" ASCII for new portable format</li>
Stefan Bodewig46212e52013-01-20 17:07:40 +000033 * <li>"070702" ASCII for new portable format with CRC</li>
Stefan Bodewig176337a2009-03-23 09:10:50 +000034 * <li>"070707" ASCII for old ascii (also known as Portable ASCII, odc or old
35 * character format</li>
Sebastian Bazleyb7ea6712009-03-26 15:38:47 +000036 * <li>070707 binary for old binary</li>
Stefan Bodewig176337a2009-03-23 09:10:50 +000037 * </ul>
Sebastian Bazleyb7ea6712009-03-26 15:38:47 +000038 *
Stefan Bodewig176337a2009-03-23 09:10:50 +000039 * <p>The old binary format is limited to 16 bits for user id, group
40 * id, device, and inode numbers. It is limited to 4 gigabyte file
41 * sizes.
Torsten Curdt70c83202009-01-12 11:09:21 +000042 *
Stefan Bodewig176337a2009-03-23 09:10:50 +000043 * The old ASCII format is limited to 18 bits for the user id, group
44 * id, device, and inode numbers. It is limited to 8 gigabyte file
45 * sizes.
Torsten Curdt70c83202009-01-12 11:09:21 +000046 *
Stefan Bodewig176337a2009-03-23 09:10:50 +000047 * The new ASCII format is limited to 4 gigabyte file sizes.
Torsten Curdt70c83202009-01-12 11:09:21 +000048 *
Stefan Bodewig176337a2009-03-23 09:10:50 +000049 * CPIO 2.5 knows also about tar, but it is not recognized here.</p>
Torsten Curdt70c83202009-01-12 11:09:21 +000050 *
Torsten Curdt70c83202009-01-12 11:09:21 +000051 *
Stefan Bodewig176337a2009-03-23 09:10:50 +000052 * <h3>OLD FORMAT</h3>
Stefan Bodewig41f4a202009-03-20 15:42:37 +000053 *
Stefan Bodewig176337a2009-03-23 09:10:50 +000054 * <p>Each file has a 76 (ascii) / 26 (binary) byte header, a variable
55 * length, NUL terminated filename, and variable length file data. A
56 * header for a filename "TRAILER!!!" indicates the end of the
57 * archive.</p>
58 *
59 * <p>All the fields in the header are ISO 646 (approximately ASCII)
60 * strings of octal numbers, left padded, not NUL terminated.</p>
61 *
62 * <pre>
63 * FIELDNAME NOTES
64 * c_magic The integer value octal 070707. This value can be used to deter-
65 * mine whether this archive is written with little-endian or big-
66 * endian integers.
67 * c_dev Device that contains a directory entry for this file
68 * c_ino I-node number that identifies the input file to the file system
69 * c_mode The mode specifies both the regular permissions and the file type.
70 * c_uid Numeric User ID of the owner of the input file
71 * c_gid Numeric Group ID of the owner of the input file
72 * c_nlink Number of links that are connected to the input file
73 * c_rdev For block special and character special entries, this field
74 * contains the associated device number. For all other entry types,
75 * it should be set to zero by writers and ignored by readers.
76 * c_mtime[2] Modification time of the file, indicated as the number of seconds
77 * since the start of the epoch, 00:00:00 UTC January 1, 1970. The
78 * four-byte integer is stored with the most-significant 16 bits
79 * first followed by the least-significant 16 bits. Each of the two
80 * 16 bit values are stored in machine-native byte order.
81 * c_namesize Length of the path name, including the terminating null byte
82 * c_filesize[2] Length of the file in bytes. This is the length of the data
83 * section that follows the header structure. Must be 0 for
84 * FIFOs and directories
Stefan Bodewig06fbac92009-08-01 14:53:32 +000085 *
Stefan Bodewig176337a2009-03-23 09:10:50 +000086 * All fields are unsigned short fields with 16-bit integer values
Sebastian Bazley1b2e3002009-03-27 17:44:16 +000087 * apart from c_mtime and c_filesize which are 32-bit integer values
Stefan Bodewig176337a2009-03-23 09:10:50 +000088 * </pre>
89 *
Sebastian Bazley1b2e3002009-03-27 17:44:16 +000090 * <p>If necessary, the filename and file data are padded with a NUL byte to an even length</p>
91 *
Stefan Bodewig176337a2009-03-23 09:10:50 +000092 * <p>Special files, directories, and the trailer are recorded with
93 * the h_filesize field equal to 0.</p>
94 *
Sebastian Bazley1b2e3002009-03-27 17:44:16 +000095 * <p>In the ASCII version of this format, the 16-bit entries are represented as 6-byte octal numbers,
96 * and the 32-bit entries are represented as 11-byte octal numbers. No padding is added.</p>
Stefan Bodewig176337a2009-03-23 09:10:50 +000097 *
98 * <h3>NEW FORMAT</h3>
99 *
100 * <p>Each file has a 110 byte header, a variable length, NUL
101 * terminated filename, and variable length file data. A header for a
102 * filename "TRAILER!!!" indicates the end of the archive. All the
103 * fields in the header are ISO 646 (approximately ASCII) strings of
104 * hexadecimal numbers, left padded, not NUL terminated.</p>
105 *
106 * <pre>
107 * FIELDNAME NOTES
108 * c_magic[6] The string 070701 for new ASCII, the string 070702 for new ASCII with CRC
109 * c_ino[8]
110 * c_mode[8]
111 * c_uid[8]
112 * c_gid[8]
113 * c_nlink[8]
114 * c_mtim[8]
115 * c_filesize[8] must be 0 for FIFOs and directories
116 * c_maj[8]
117 * c_min[8]
118 * c_rmaj[8] only valid for chr and blk special files
119 * c_rmin[8] only valid for chr and blk special files
120 * c_namesize[8] count includes terminating NUL in pathname
121 * c_check[8] 0 for "new" portable format; for CRC format
122 * the sum of all the bytes in the file
123 * </pre>
124 *
125 * <p>New ASCII Format The "new" ASCII format uses 8-byte hexadecimal
126 * fields for all numbers and separates device numbers into separate
127 * fields for major and minor numbers.</p>
128 *
129 * <p>The pathname is followed by NUL bytes so that the total size of
130 * the fixed header plus pathname is a multiple of four. Likewise, the
131 * file data is padded to a multiple of four bytes.</p>
132 *
133 * <p>This class uses mutable fields and is not considered to be
134 * threadsafe.</p>
135 *
Sebastian Bazley70ce4712009-04-14 15:38:08 +0000136 * <p>Based on code from the jRPM project (http://jrpm.sourceforge.net).</p>
Stefan Bodewig176337a2009-03-23 09:10:50 +0000137 *
Sebastian Bazley70ce4712009-04-14 15:38:08 +0000138 * <p>The MAGIC numbers and other constants are defined in {@link CpioConstants}</p>
Sebastian Bazleyf17ce4b2009-03-27 20:47:56 +0000139 *
Sebastian Bazley17367192009-03-28 19:33:56 +0000140 * <p>
141 * N.B. does not handle the cpio "tar" format
142 * </p>
Sebastian Bazleyf17ce4b2009-03-27 20:47:56 +0000143 * @NotThreadSafe
Stefan Bodewig45e51c22013-12-22 07:03:43 +0000144 * @see <a href="http://people.freebsd.org/~kientzle/libarchive/man/cpio.5.txt">http://people.freebsd.org/~kientzle/libarchive/man/cpio.5.txt</a>
Torsten Curdt70c83202009-01-12 11:09:21 +0000145 */
146public class CpioArchiveEntry implements CpioConstants, ArchiveEntry {
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000147
Sebastian Bazleydb7f5772009-03-26 20:27:25 +0000148 // Header description fields - should be same throughout an archive
Stefan Bodewig06fbac92009-08-01 14:53:32 +0000149
Sebastian Bazley0a8aaa52009-03-26 15:56:48 +0000150 /**
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000151 * See constructor documenation for possible values.
Sebastian Bazley0a8aaa52009-03-26 15:56:48 +0000152 */
Sebastian Bazleyf17ce4b2009-03-27 20:47:56 +0000153 private final short fileFormat;
Sebastian Bazleydb7f5772009-03-26 20:27:25 +0000154
155 /** The number of bytes in each header record; depends on the file format */
Sebastian Bazleyf17ce4b2009-03-27 20:47:56 +0000156 private final int headerSize;
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000157
158 /** The boundary to which the header and data elements are aligned: 0, 2 or 4 bytes */
Sebastian Bazleyf17ce4b2009-03-27 20:47:56 +0000159 private final int alignmentBoundary;
Sebastian Bazleydb7f5772009-03-26 20:27:25 +0000160
161 // Header fields
Stefan Bodewig06fbac92009-08-01 14:53:32 +0000162
Sebastian Bazleydb7f5772009-03-26 20:27:25 +0000163 private long chksum = 0;
Torsten Curdt70c83202009-01-12 11:09:21 +0000164
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000165 /** Number of bytes in the file */
Torsten Curdt70c83202009-01-12 11:09:21 +0000166 private long filesize = 0;
167
168 private long gid = 0;
169
Torsten Curdt70c83202009-01-12 11:09:21 +0000170 private long inode = 0;
171
172 private long maj = 0;
173
174 private long min = 0;
175
Sebastian Bazleydb7f5772009-03-26 20:27:25 +0000176 private long mode = 0;
Torsten Curdt70c83202009-01-12 11:09:21 +0000177
Sebastian Bazleydb7f5772009-03-26 20:27:25 +0000178 private long mtime = 0;
Torsten Curdt70c83202009-01-12 11:09:21 +0000179
180 private String name;
181
182 private long nlink = 0;
183
184 private long rmaj = 0;
185
186 private long rmin = 0;
187
188 private long uid = 0;
189
190 /**
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000191 * Creates a CPIOArchiveEntry with a specified format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000192 *
193 * @param format
194 * The cpio format for this entry.
Sebastian Bazleyf17ce4b2009-03-27 20:47:56 +0000195 * <p>
Stefan Bodewig45e51c22013-12-22 07:03:43 +0000196 * Possible format values are:
197 * <pre>
198 * CpioConstants.FORMAT_NEW
199 * CpioConstants.FORMAT_NEW_CRC
200 * CpioConstants.FORMAT_OLD_BINARY
201 * CpioConstants.FORMAT_OLD_ASCII
202 * </pre>
Torsten Curdt70c83202009-01-12 11:09:21 +0000203 */
204 public CpioArchiveEntry(final short format) {
Sebastian Bazleyf17ce4b2009-03-27 20:47:56 +0000205 switch (format) {
206 case FORMAT_NEW:
207 this.headerSize = 110;
208 this.alignmentBoundary = 4;
209 break;
210 case FORMAT_NEW_CRC:
211 this.headerSize = 110;
212 this.alignmentBoundary = 4;
213 break;
214 case FORMAT_OLD_ASCII:
215 this.headerSize = 76;
216 this.alignmentBoundary = 0;
217 break;
218 case FORMAT_OLD_BINARY:
219 this.headerSize = 26;
220 this.alignmentBoundary = 2;
221 break;
222 default:
223 throw new IllegalArgumentException("Unknown header type");
224 }
225 this.fileFormat = format;
Torsten Curdt70c83202009-01-12 11:09:21 +0000226 }
227
228 /**
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000229 * Creates a CPIOArchiveEntry with a specified name. The format of
230 * this entry will be the new format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000231 *
232 * @param name
233 * The name of this entry.
234 */
235 public CpioArchiveEntry(final String name) {
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000236 this(FORMAT_NEW, name);
237 }
238
239 /**
240 * Creates a CPIOArchiveEntry with a specified name.
241 *
242 * @param format
243 * The cpio format for this entry.
244 * @param name
245 * The name of this entry.
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000246 * <p>
Stefan Bodewig45e51c22013-12-22 07:03:43 +0000247 * Possible format values are:
248 * <pre>
249 * CpioConstants.FORMAT_NEW
250 * CpioConstants.FORMAT_NEW_CRC
251 * CpioConstants.FORMAT_OLD_BINARY
252 * CpioConstants.FORMAT_OLD_ASCII
253 * </pre>
Sebastian Bazley6209f812010-05-10 17:36:40 +0000254 *
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +0000255 * @since 1.1
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000256 */
257 public CpioArchiveEntry(final short format, final String name) {
258 this(format);
Torsten Curdt70c83202009-01-12 11:09:21 +0000259 this.name = name;
260 }
261
262 /**
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000263 * Creates a CPIOArchiveEntry with a specified name. The format of
264 * this entry will be the new format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000265 *
266 * @param name
267 * The name of this entry.
268 * @param size
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000269 * The size of this entry
Torsten Curdt70c83202009-01-12 11:09:21 +0000270 */
271 public CpioArchiveEntry(final String name, final long size) {
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000272 this(name);
Torsten Curdt70c83202009-01-12 11:09:21 +0000273 this.setSize(size);
274 }
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000275
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000276 /**
277 * Creates a CPIOArchiveEntry with a specified name.
278 *
279 * @param format
280 * The cpio format for this entry.
281 * @param name
282 * The name of this entry.
283 * @param size
284 * The size of this entry
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000285 * <p>
Stefan Bodewig45e51c22013-12-22 07:03:43 +0000286 * Possible format values are:
287 * <pre>
288 * CpioConstants.FORMAT_NEW
289 * CpioConstants.FORMAT_NEW_CRC
290 * CpioConstants.FORMAT_OLD_BINARY
291 * CpioConstants.FORMAT_OLD_ASCII
292 * </pre>
Sebastian Bazley6209f812010-05-10 17:36:40 +0000293 *
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +0000294 * @since 1.1
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000295 */
296 public CpioArchiveEntry(final short format, final String name,
297 final long size) {
298 this(format, name);
299 this.setSize(size);
300 }
301
302 /**
303 * Creates a CPIOArchiveEntry with a specified name for a
304 * specified file. The format of this entry will be the new
305 * format.
306 *
307 * @param inputFile
308 * The file to gather information from.
309 * @param entryName
310 * The name of this entry.
311 */
Sebastian Bazleyfec51a12009-03-31 00:35:56 +0000312 public CpioArchiveEntry(File inputFile, String entryName) {
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000313 this(FORMAT_NEW, inputFile, entryName);
314 }
315
316 /**
317 * Creates a CPIOArchiveEntry with a specified name for a
318 * specified file.
319 *
320 * @param format
321 * The cpio format for this entry.
322 * @param inputFile
323 * The file to gather information from.
324 * @param entryName
325 * The name of this entry.
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000326 * <p>
Stefan Bodewig45e51c22013-12-22 07:03:43 +0000327 * Possible format values are:
328 * <pre>
329 * CpioConstants.FORMAT_NEW
330 * CpioConstants.FORMAT_NEW_CRC
331 * CpioConstants.FORMAT_OLD_BINARY
332 * CpioConstants.FORMAT_OLD_ASCII
333 * </pre>
Sebastian Bazley6209f812010-05-10 17:36:40 +0000334 *
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +0000335 * @since 1.1
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000336 */
337 public CpioArchiveEntry(final short format, File inputFile,
338 String entryName) {
339 this(format, entryName, inputFile.isFile() ? inputFile.length() : 0);
Sebastian Bazleyfec51a12009-03-31 00:35:56 +0000340 long mode=0;
341 if (inputFile.isDirectory()){
342 mode |= C_ISDIR;
343 } else if (inputFile.isFile()){
344 mode |= C_ISREG;
345 } else {
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000346 throw new IllegalArgumentException("Cannot determine type of file "
347 + inputFile.getName());
Sebastian Bazleyfec51a12009-03-31 00:35:56 +0000348 }
349 // TODO set other fields as needed
350 setMode(mode);
Stefan Bodewige1640e52009-08-01 20:07:53 +0000351 setTime(inputFile.lastModified() / 1000);
Sebastian Bazleyfec51a12009-03-31 00:35:56 +0000352 }
353
Torsten Curdt70c83202009-01-12 11:09:21 +0000354 /**
355 * Check if the method is allowed for the defined format.
356 */
357 private void checkNewFormat() {
358 if ((this.fileFormat & FORMAT_NEW_MASK) == 0) {
359 throw new UnsupportedOperationException();
360 }
361 }
362
363 /**
364 * Check if the method is allowed for the defined format.
365 */
366 private void checkOldFormat() {
367 if ((this.fileFormat & FORMAT_OLD_MASK) == 0) {
368 throw new UnsupportedOperationException();
369 }
370 }
371
372 /**
373 * Get the checksum.
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000374 * Only supported for the new formats.
Torsten Curdt70c83202009-01-12 11:09:21 +0000375 *
376 * @return Returns the checksum.
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000377 * @throws UnsupportedOperationException if the format is not a new format
Torsten Curdt70c83202009-01-12 11:09:21 +0000378 */
379 public long getChksum() {
380 checkNewFormat();
381 return this.chksum;
382 }
383
384 /**
385 * Get the device id.
386 *
387 * @return Returns the device id.
388 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000389 * if this method is called for a CPIOArchiveEntry with a new
390 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000391 */
392 public long getDevice() {
393 checkOldFormat();
394 return this.min;
395 }
396
397 /**
398 * Get the major device id.
399 *
400 * @return Returns the major device id.
401 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000402 * if this method is called for a CPIOArchiveEntry with an old
403 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000404 */
405 public long getDeviceMaj() {
406 checkNewFormat();
407 return this.maj;
408 }
409
410 /**
411 * Get the minor device id
412 *
413 * @return Returns the minor device id.
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000414 * @throws UnsupportedOperationException if format is not a new format
Torsten Curdt70c83202009-01-12 11:09:21 +0000415 */
416 public long getDeviceMin() {
417 checkNewFormat();
418 return this.min;
419 }
420
421 /**
422 * Get the filesize.
423 *
424 * @return Returns the filesize.
Torsten Curdt70c83202009-01-12 11:09:21 +0000425 * @see org.apache.commons.compress.archivers.ArchiveEntry#getSize()
426 */
427 public long getSize() {
428 return this.filesize;
429 }
430
431 /**
432 * Get the format for this entry.
433 *
434 * @return Returns the format.
435 */
436 public short getFormat() {
437 return this.fileFormat;
438 }
439
440 /**
441 * Get the group id.
442 *
443 * @return Returns the group id.
444 */
445 public long getGID() {
446 return this.gid;
447 }
448
449 /**
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000450 * Get the header size for this CPIO format
Torsten Curdt70c83202009-01-12 11:09:21 +0000451 *
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000452 * @return Returns the header size in bytes.
Torsten Curdt70c83202009-01-12 11:09:21 +0000453 */
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000454 public int getHeaderSize() {
Torsten Curdt70c83202009-01-12 11:09:21 +0000455 return this.headerSize;
456 }
457
458 /**
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000459 * Get the alignment boundary for this CPIO format
460 *
461 * @return Returns the aligment boundary (0, 2, 4) in bytes
462 */
463 public int getAlignmentBoundary() {
464 return this.alignmentBoundary;
465 }
466
467 /**
468 * Get the number of bytes needed to pad the header to the alignment boundary.
469 *
470 * @return the number of bytes needed to pad the header (0,1,2,3)
471 */
472 public int getHeaderPadCount(){
Sebastian Bazleya0e435e2012-03-31 10:59:47 +0000473 if (this.alignmentBoundary == 0) { return 0; }
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000474 int size = this.headerSize+this.name.length()+1; // Name has terminating null
475 int remain = size % this.alignmentBoundary;
476 if (remain > 0){
477 return this.alignmentBoundary - remain;
478 }
479 return 0;
480 }
481
482 /**
483 * Get the number of bytes needed to pad the data to the alignment boundary.
484 *
485 * @return the number of bytes needed to pad the data (0,1,2,3)
486 */
487 public int getDataPadCount(){
Sebastian Bazleya0e435e2012-03-31 10:59:47 +0000488 if (this.alignmentBoundary == 0) { return 0; }
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000489 long size = this.filesize;
490 int remain = (int) (size % this.alignmentBoundary);
491 if (remain > 0){
492 return this.alignmentBoundary - remain;
493 }
494 return 0;
495 }
496
497 /**
Torsten Curdt70c83202009-01-12 11:09:21 +0000498 * Set the inode.
499 *
500 * @return Returns the inode.
501 */
502 public long getInode() {
503 return this.inode;
504 }
505
506 /**
507 * Get the mode of this entry (e.g. directory, regular file).
508 *
509 * @return Returns the mode.
510 */
511 public long getMode() {
Stefan Bodewigb11dca22010-02-18 11:55:21 +0000512 return mode == 0 && !CPIO_TRAILER.equals(name) ? C_ISREG : mode;
Torsten Curdt70c83202009-01-12 11:09:21 +0000513 }
514
515 /**
516 * Get the name.
517 *
518 * @return Returns the name.
519 */
520 public String getName() {
521 return this.name;
522 }
523
524 /**
525 * Get the number of links.
526 *
527 * @return Returns the number of links.
528 */
529 public long getNumberOfLinks() {
Stefan Bodewigb11dca22010-02-18 11:55:21 +0000530 return nlink == 0 ?
Gary D. Gregory8a2f04c2013-12-20 17:11:27 +0000531 isDirectory() ? 2 : 1
Stefan Bodewigb11dca22010-02-18 11:55:21 +0000532 : nlink;
Torsten Curdt70c83202009-01-12 11:09:21 +0000533 }
534
535 /**
536 * Get the remote device id.
537 *
538 * @return Returns the remote device id.
539 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000540 * if this method is called for a CPIOArchiveEntry with a new
541 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000542 */
543 public long getRemoteDevice() {
544 checkOldFormat();
545 return this.rmin;
546 }
547
548 /**
549 * Get the remote major device id.
550 *
551 * @return Returns the remote major device id.
552 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000553 * if this method is called for a CPIOArchiveEntry with an old
554 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000555 */
556 public long getRemoteDeviceMaj() {
557 checkNewFormat();
558 return this.rmaj;
559 }
560
561 /**
562 * Get the remote minor device id.
563 *
564 * @return Returns the remote minor device id.
565 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000566 * if this method is called for a CPIOArchiveEntry with an old
567 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000568 */
569 public long getRemoteDeviceMin() {
570 checkNewFormat();
571 return this.rmin;
572 }
573
574 /**
575 * Get the time in seconds.
576 *
577 * @return Returns the time.
578 */
579 public long getTime() {
580 return this.mtime;
581 }
582
Stefan Bodewig17ffd7f2009-08-01 14:52:15 +0000583 public Date getLastModifiedDate() {
584 return new Date(1000 * getTime());
585 }
586
Torsten Curdt70c83202009-01-12 11:09:21 +0000587 /**
588 * Get the user id.
589 *
590 * @return Returns the user id.
591 */
592 public long getUID() {
593 return this.uid;
594 }
595
596 /**
597 * Check if this entry represents a block device.
598 *
599 * @return TRUE if this entry is a block device.
600 */
601 public boolean isBlockDevice() {
Stefan Bodewig040e42d2013-08-08 16:18:45 +0000602 return CpioUtil.fileType(mode) == C_ISBLK;
Torsten Curdt70c83202009-01-12 11:09:21 +0000603 }
604
605 /**
606 * Check if this entry represents a character device.
607 *
608 * @return TRUE if this entry is a character device.
609 */
610 public boolean isCharacterDevice() {
Stefan Bodewig040e42d2013-08-08 16:18:45 +0000611 return CpioUtil.fileType(mode) == C_ISCHR;
Torsten Curdt70c83202009-01-12 11:09:21 +0000612 }
613
614 /**
615 * Check if this entry represents a directory.
616 *
617 * @return TRUE if this entry is a directory.
618 */
619 public boolean isDirectory() {
Stefan Bodewig040e42d2013-08-08 16:18:45 +0000620 return CpioUtil.fileType(mode) == C_ISDIR;
Torsten Curdt70c83202009-01-12 11:09:21 +0000621 }
622
623 /**
624 * Check if this entry represents a network device.
625 *
626 * @return TRUE if this entry is a network device.
627 */
628 public boolean isNetwork() {
Stefan Bodewig040e42d2013-08-08 16:18:45 +0000629 return CpioUtil.fileType(mode) == C_ISNWK;
Torsten Curdt70c83202009-01-12 11:09:21 +0000630 }
631
632 /**
633 * Check if this entry represents a pipe.
634 *
635 * @return TRUE if this entry is a pipe.
636 */
637 public boolean isPipe() {
Stefan Bodewig040e42d2013-08-08 16:18:45 +0000638 return CpioUtil.fileType(mode) == C_ISFIFO;
Torsten Curdt70c83202009-01-12 11:09:21 +0000639 }
640
641 /**
642 * Check if this entry represents a regular file.
643 *
644 * @return TRUE if this entry is a regular file.
645 */
646 public boolean isRegularFile() {
Stefan Bodewig040e42d2013-08-08 16:18:45 +0000647 return CpioUtil.fileType(mode) == C_ISREG;
Torsten Curdt70c83202009-01-12 11:09:21 +0000648 }
649
650 /**
651 * Check if this entry represents a socket.
652 *
653 * @return TRUE if this entry is a socket.
654 */
655 public boolean isSocket() {
Stefan Bodewig040e42d2013-08-08 16:18:45 +0000656 return CpioUtil.fileType(mode) == C_ISSOCK;
Torsten Curdt70c83202009-01-12 11:09:21 +0000657 }
658
659 /**
660 * Check if this entry represents a symbolic link.
661 *
662 * @return TRUE if this entry is a symbolic link.
663 */
664 public boolean isSymbolicLink() {
Stefan Bodewig040e42d2013-08-08 16:18:45 +0000665 return CpioUtil.fileType(mode) == C_ISLNK;
Torsten Curdt70c83202009-01-12 11:09:21 +0000666 }
667
668 /**
669 * Set the checksum. The checksum is calculated by adding all bytes of a
Stefan Bodewig45e51c22013-12-22 07:03:43 +0000670 * file to transfer (crc += buf[pos] &amp; 0xFF).
Torsten Curdt70c83202009-01-12 11:09:21 +0000671 *
672 * @param chksum
673 * The checksum to set.
674 */
675 public void setChksum(final long chksum) {
676 checkNewFormat();
677 this.chksum = chksum;
678 }
679
680 /**
681 * Set the device id.
682 *
683 * @param device
684 * The device id to set.
685 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000686 * if this method is called for a CPIOArchiveEntry with a new
687 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000688 */
689 public void setDevice(final long device) {
690 checkOldFormat();
691 this.min = device;
692 }
693
694 /**
695 * Set major device id.
696 *
697 * @param maj
698 * The major device id to set.
699 */
700 public void setDeviceMaj(final long maj) {
701 checkNewFormat();
702 this.maj = maj;
703 }
704
705 /**
706 * Set the minor device id
707 *
708 * @param min
709 * The minor device id to set.
710 */
711 public void setDeviceMin(final long min) {
712 checkNewFormat();
713 this.min = min;
714 }
715
716 /**
717 * Set the filesize.
718 *
719 * @param size
720 * The filesize to set.
721 */
722 public void setSize(final long size) {
723 if (size < 0 || size > 0xFFFFFFFFL) {
724 throw new IllegalArgumentException("invalid entry size <" + size
Stefan Bodewig06fbac92009-08-01 14:53:32 +0000725 + ">");
Torsten Curdt70c83202009-01-12 11:09:21 +0000726 }
727 this.filesize = size;
728 }
729
730 /**
Torsten Curdt70c83202009-01-12 11:09:21 +0000731 * Set the group id.
732 *
733 * @param gid
734 * The group id to set.
735 */
736 public void setGID(final long gid) {
737 this.gid = gid;
738 }
739
740 /**
741 * Set the inode.
742 *
743 * @param inode
744 * The inode to set.
745 */
746 public void setInode(final long inode) {
747 this.inode = inode;
748 }
749
750 /**
751 * Set the mode of this entry (e.g. directory, regular file).
752 *
753 * @param mode
754 * The mode to set.
755 */
756 public void setMode(final long mode) {
Sebastian Bazley8c36ce32009-03-26 13:40:38 +0000757 final long maskedMode = mode & S_IFMT;
758 switch ((int) maskedMode) {
Torsten Curdt70c83202009-01-12 11:09:21 +0000759 case C_ISDIR:
760 case C_ISLNK:
761 case C_ISREG:
762 case C_ISFIFO:
763 case C_ISCHR:
764 case C_ISBLK:
765 case C_ISSOCK:
766 case C_ISNWK:
767 break;
768 default:
Sebastian Bazley84f836e2009-03-26 20:54:47 +0000769 throw new IllegalArgumentException(
Stefan Bodewig06fbac92009-08-01 14:53:32 +0000770 "Unknown mode. "
771 + "Full: " + Long.toHexString(mode)
772 + " Masked: " + Long.toHexString(maskedMode));
Torsten Curdt70c83202009-01-12 11:09:21 +0000773 }
774
775 this.mode = mode;
776 }
777
778 /**
779 * Set the name.
780 *
781 * @param name
782 * The name to set.
783 */
784 public void setName(final String name) {
785 this.name = name;
786 }
787
788 /**
789 * Set the number of links.
790 *
791 * @param nlink
792 * The number of links to set.
793 */
794 public void setNumberOfLinks(final long nlink) {
795 this.nlink = nlink;
796 }
797
798 /**
799 * Set the remote device id.
800 *
801 * @param device
802 * The remote device id to set.
803 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000804 * if this method is called for a CPIOArchiveEntry with a new
805 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000806 */
807 public void setRemoteDevice(final long device) {
808 checkOldFormat();
809 this.rmin = device;
810 }
811
812 /**
813 * Set the remote major device id.
814 *
815 * @param rmaj
816 * The remote major device id to set.
817 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000818 * if this method is called for a CPIOArchiveEntry with an old
819 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000820 */
821 public void setRemoteDeviceMaj(final long rmaj) {
822 checkNewFormat();
823 this.rmaj = rmaj;
824 }
825
826 /**
827 * Set the remote minor device id.
828 *
829 * @param rmin
830 * The remote minor device id to set.
831 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000832 * if this method is called for a CPIOArchiveEntry with an old
833 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000834 */
835 public void setRemoteDeviceMin(final long rmin) {
836 checkNewFormat();
837 this.rmin = rmin;
838 }
839
840 /**
841 * Set the time in seconds.
842 *
843 * @param time
844 * The time to set.
845 */
846 public void setTime(final long time) {
847 this.mtime = time;
848 }
849
850 /**
851 * Set the user id.
852 *
853 * @param uid
854 * The user id to set.
855 */
856 public void setUID(final long uid) {
857 this.uid = uid;
858 }
Christian Grobmeier28c23fb2009-04-17 05:14:49 +0000859
860 /* (non-Javadoc)
861 * @see java.lang.Object#hashCode()
862 */
Stefan Bodewig46628ef2011-08-06 16:30:40 +0000863 @Override
Christian Grobmeier28c23fb2009-04-17 05:14:49 +0000864 public int hashCode() {
865 final int prime = 31;
866 int result = 1;
Gary D. Gregory8a2f04c2013-12-20 17:11:27 +0000867 result = prime * result + (name == null ? 0 : name.hashCode());
Christian Grobmeier28c23fb2009-04-17 05:14:49 +0000868 return result;
869 }
870
871 /* (non-Javadoc)
872 * @see java.lang.Object#equals(java.lang.Object)
873 */
Stefan Bodewig46628ef2011-08-06 16:30:40 +0000874 @Override
Christian Grobmeier28c23fb2009-04-17 05:14:49 +0000875 public boolean equals(Object obj) {
876 if (this == obj) {
877 return true;
878 }
879 if (obj == null || getClass() != obj.getClass()) {
880 return false;
881 }
882 CpioArchiveEntry other = (CpioArchiveEntry) obj;
883 if (name == null) {
884 if (other.name != null) {
885 return false;
886 }
887 } else if (!name.equals(other.name)) {
888 return false;
889 }
890 return true;
891 }
Torsten Curdt70c83202009-01-12 11:09:21 +0000892}