blob: cd10b78ee0a87d77ef127889e5da93b665d39be3 [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
Sebastian Bazley70ce4712009-04-14 15:38:08 +0000144 * @see "http://people.freebsd.org/~kientzle/libarchive/man/cpio.5.txt"
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 * <br/>
196 * Possible format values are:
197 * <p>
198 * CpioConstants.FORMAT_NEW<br/>
199 * CpioConstants.FORMAT_NEW_CRC<br/>
200 * CpioConstants.FORMAT_OLD_BINARY<br/>
201 * CpioConstants.FORMAT_OLD_ASCII<br/>
202 *
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.
246 * <br/>
247 * Possible format values are:
248 * <p>
249 * CpioConstants.FORMAT_NEW<br/>
250 * CpioConstants.FORMAT_NEW_CRC<br/>
251 * CpioConstants.FORMAT_OLD_BINARY<br/>
252 * CpioConstants.FORMAT_OLD_ASCII<br/>
Sebastian Bazley6209f812010-05-10 17:36:40 +0000253 *
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +0000254 * @since 1.1
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000255 */
256 public CpioArchiveEntry(final short format, final String name) {
257 this(format);
Torsten Curdt70c83202009-01-12 11:09:21 +0000258 this.name = name;
259 }
260
261 /**
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000262 * Creates a CPIOArchiveEntry with a specified name. The format of
263 * this entry will be the new format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000264 *
265 * @param name
266 * The name of this entry.
267 * @param size
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000268 * The size of this entry
Torsten Curdt70c83202009-01-12 11:09:21 +0000269 */
270 public CpioArchiveEntry(final String name, final long size) {
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000271 this(name);
Torsten Curdt70c83202009-01-12 11:09:21 +0000272 this.setSize(size);
273 }
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000274
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000275 /**
276 * Creates a CPIOArchiveEntry with a specified name.
277 *
278 * @param format
279 * The cpio format for this entry.
280 * @param name
281 * The name of this entry.
282 * @param size
283 * The size of this entry
284 * <br/>
285 * Possible format values are:
286 * <p>
287 * CpioConstants.FORMAT_NEW<br/>
288 * CpioConstants.FORMAT_NEW_CRC<br/>
289 * CpioConstants.FORMAT_OLD_BINARY<br/>
290 * CpioConstants.FORMAT_OLD_ASCII<br/>
Sebastian Bazley6209f812010-05-10 17:36:40 +0000291 *
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +0000292 * @since 1.1
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000293 */
294 public CpioArchiveEntry(final short format, final String name,
295 final long size) {
296 this(format, name);
297 this.setSize(size);
298 }
299
300 /**
301 * Creates a CPIOArchiveEntry with a specified name for a
302 * specified file. The format of this entry will be the new
303 * format.
304 *
305 * @param inputFile
306 * The file to gather information from.
307 * @param entryName
308 * The name of this entry.
309 */
Sebastian Bazleyfec51a12009-03-31 00:35:56 +0000310 public CpioArchiveEntry(File inputFile, String entryName) {
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000311 this(FORMAT_NEW, inputFile, entryName);
312 }
313
314 /**
315 * Creates a CPIOArchiveEntry with a specified name for a
316 * specified file.
317 *
318 * @param format
319 * The cpio format for this entry.
320 * @param inputFile
321 * The file to gather information from.
322 * @param entryName
323 * The name of this entry.
324 * <br/>
325 * Possible format values are:
326 * <p>
327 * CpioConstants.FORMAT_NEW<br/>
328 * CpioConstants.FORMAT_NEW_CRC<br/>
329 * CpioConstants.FORMAT_OLD_BINARY<br/>
330 * CpioConstants.FORMAT_OLD_ASCII<br/>
Sebastian Bazley6209f812010-05-10 17:36:40 +0000331 *
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +0000332 * @since 1.1
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000333 */
334 public CpioArchiveEntry(final short format, File inputFile,
335 String entryName) {
336 this(format, entryName, inputFile.isFile() ? inputFile.length() : 0);
Sebastian Bazleyfec51a12009-03-31 00:35:56 +0000337 long mode=0;
338 if (inputFile.isDirectory()){
339 mode |= C_ISDIR;
340 } else if (inputFile.isFile()){
341 mode |= C_ISREG;
342 } else {
Stefan Bodewig57cb8c82010-02-18 13:08:31 +0000343 throw new IllegalArgumentException("Cannot determine type of file "
344 + inputFile.getName());
Sebastian Bazleyfec51a12009-03-31 00:35:56 +0000345 }
346 // TODO set other fields as needed
347 setMode(mode);
Stefan Bodewige1640e52009-08-01 20:07:53 +0000348 setTime(inputFile.lastModified() / 1000);
Sebastian Bazleyfec51a12009-03-31 00:35:56 +0000349 }
350
Torsten Curdt70c83202009-01-12 11:09:21 +0000351 /**
352 * Check if the method is allowed for the defined format.
353 */
354 private void checkNewFormat() {
355 if ((this.fileFormat & FORMAT_NEW_MASK) == 0) {
356 throw new UnsupportedOperationException();
357 }
358 }
359
360 /**
361 * Check if the method is allowed for the defined format.
362 */
363 private void checkOldFormat() {
364 if ((this.fileFormat & FORMAT_OLD_MASK) == 0) {
365 throw new UnsupportedOperationException();
366 }
367 }
368
369 /**
370 * Get the checksum.
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000371 * Only supported for the new formats.
Torsten Curdt70c83202009-01-12 11:09:21 +0000372 *
373 * @return Returns the checksum.
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000374 * @throws UnsupportedOperationException if the format is not a new format
Torsten Curdt70c83202009-01-12 11:09:21 +0000375 */
376 public long getChksum() {
377 checkNewFormat();
378 return this.chksum;
379 }
380
381 /**
382 * Get the device id.
383 *
384 * @return Returns the device id.
385 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000386 * if this method is called for a CPIOArchiveEntry with a new
387 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000388 */
389 public long getDevice() {
390 checkOldFormat();
391 return this.min;
392 }
393
394 /**
395 * Get the major device id.
396 *
397 * @return Returns the major device id.
398 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000399 * if this method is called for a CPIOArchiveEntry with an old
400 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000401 */
402 public long getDeviceMaj() {
403 checkNewFormat();
404 return this.maj;
405 }
406
407 /**
408 * Get the minor device id
409 *
410 * @return Returns the minor device id.
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000411 * @throws UnsupportedOperationException if format is not a new format
Torsten Curdt70c83202009-01-12 11:09:21 +0000412 */
413 public long getDeviceMin() {
414 checkNewFormat();
415 return this.min;
416 }
417
418 /**
419 * Get the filesize.
420 *
421 * @return Returns the filesize.
Torsten Curdt70c83202009-01-12 11:09:21 +0000422 * @see org.apache.commons.compress.archivers.ArchiveEntry#getSize()
423 */
424 public long getSize() {
425 return this.filesize;
426 }
427
428 /**
429 * Get the format for this entry.
430 *
431 * @return Returns the format.
432 */
433 public short getFormat() {
434 return this.fileFormat;
435 }
436
437 /**
438 * Get the group id.
439 *
440 * @return Returns the group id.
441 */
442 public long getGID() {
443 return this.gid;
444 }
445
446 /**
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000447 * Get the header size for this CPIO format
Torsten Curdt70c83202009-01-12 11:09:21 +0000448 *
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000449 * @return Returns the header size in bytes.
Torsten Curdt70c83202009-01-12 11:09:21 +0000450 */
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000451 public int getHeaderSize() {
Torsten Curdt70c83202009-01-12 11:09:21 +0000452 return this.headerSize;
453 }
454
455 /**
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000456 * Get the alignment boundary for this CPIO format
457 *
458 * @return Returns the aligment boundary (0, 2, 4) in bytes
459 */
460 public int getAlignmentBoundary() {
461 return this.alignmentBoundary;
462 }
463
464 /**
465 * Get the number of bytes needed to pad the header to the alignment boundary.
466 *
467 * @return the number of bytes needed to pad the header (0,1,2,3)
468 */
469 public int getHeaderPadCount(){
Sebastian Bazleya0e435e2012-03-31 10:59:47 +0000470 if (this.alignmentBoundary == 0) { return 0; }
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000471 int size = this.headerSize+this.name.length()+1; // Name has terminating null
472 int remain = size % this.alignmentBoundary;
473 if (remain > 0){
474 return this.alignmentBoundary - remain;
475 }
476 return 0;
477 }
478
479 /**
480 * Get the number of bytes needed to pad the data to the alignment boundary.
481 *
482 * @return the number of bytes needed to pad the data (0,1,2,3)
483 */
484 public int getDataPadCount(){
Sebastian Bazleya0e435e2012-03-31 10:59:47 +0000485 if (this.alignmentBoundary == 0) { return 0; }
Sebastian Bazley1b2e3002009-03-27 17:44:16 +0000486 long size = this.filesize;
487 int remain = (int) (size % this.alignmentBoundary);
488 if (remain > 0){
489 return this.alignmentBoundary - remain;
490 }
491 return 0;
492 }
493
494 /**
Torsten Curdt70c83202009-01-12 11:09:21 +0000495 * Set the inode.
496 *
497 * @return Returns the inode.
498 */
499 public long getInode() {
500 return this.inode;
501 }
502
503 /**
504 * Get the mode of this entry (e.g. directory, regular file).
505 *
506 * @return Returns the mode.
507 */
508 public long getMode() {
Stefan Bodewigb11dca22010-02-18 11:55:21 +0000509 return mode == 0 && !CPIO_TRAILER.equals(name) ? C_ISREG : mode;
Torsten Curdt70c83202009-01-12 11:09:21 +0000510 }
511
512 /**
513 * Get the name.
514 *
515 * @return Returns the name.
516 */
517 public String getName() {
518 return this.name;
519 }
520
521 /**
522 * Get the number of links.
523 *
524 * @return Returns the number of links.
525 */
526 public long getNumberOfLinks() {
Stefan Bodewigb11dca22010-02-18 11:55:21 +0000527 return nlink == 0 ?
528 (isDirectory() ? 2 : 1)
529 : nlink;
Torsten Curdt70c83202009-01-12 11:09:21 +0000530 }
531
532 /**
533 * Get the remote device id.
534 *
535 * @return Returns the remote device id.
536 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000537 * if this method is called for a CPIOArchiveEntry with a new
538 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000539 */
540 public long getRemoteDevice() {
541 checkOldFormat();
542 return this.rmin;
543 }
544
545 /**
546 * Get the remote major device id.
547 *
548 * @return Returns the remote major device id.
549 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000550 * if this method is called for a CPIOArchiveEntry with an old
551 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000552 */
553 public long getRemoteDeviceMaj() {
554 checkNewFormat();
555 return this.rmaj;
556 }
557
558 /**
559 * Get the remote minor device id.
560 *
561 * @return Returns the remote minor device id.
562 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000563 * if this method is called for a CPIOArchiveEntry with an old
564 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000565 */
566 public long getRemoteDeviceMin() {
567 checkNewFormat();
568 return this.rmin;
569 }
570
571 /**
572 * Get the time in seconds.
573 *
574 * @return Returns the time.
575 */
576 public long getTime() {
577 return this.mtime;
578 }
579
Stefan Bodewig17ffd7f2009-08-01 14:52:15 +0000580 public Date getLastModifiedDate() {
581 return new Date(1000 * getTime());
582 }
583
Torsten Curdt70c83202009-01-12 11:09:21 +0000584 /**
585 * Get the user id.
586 *
587 * @return Returns the user id.
588 */
589 public long getUID() {
590 return this.uid;
591 }
592
593 /**
594 * Check if this entry represents a block device.
595 *
596 * @return TRUE if this entry is a block device.
597 */
598 public boolean isBlockDevice() {
599 return (this.mode & S_IFMT) == C_ISBLK;
600 }
601
602 /**
603 * Check if this entry represents a character device.
604 *
605 * @return TRUE if this entry is a character device.
606 */
607 public boolean isCharacterDevice() {
608 return (this.mode & S_IFMT) == C_ISCHR;
609 }
610
611 /**
612 * Check if this entry represents a directory.
613 *
614 * @return TRUE if this entry is a directory.
615 */
616 public boolean isDirectory() {
617 return (this.mode & S_IFMT) == C_ISDIR;
618 }
619
620 /**
621 * Check if this entry represents a network device.
622 *
623 * @return TRUE if this entry is a network device.
624 */
625 public boolean isNetwork() {
626 return (this.mode & S_IFMT) == C_ISNWK;
627 }
628
629 /**
630 * Check if this entry represents a pipe.
631 *
632 * @return TRUE if this entry is a pipe.
633 */
634 public boolean isPipe() {
635 return (this.mode & S_IFMT) == C_ISFIFO;
636 }
637
638 /**
639 * Check if this entry represents a regular file.
640 *
641 * @return TRUE if this entry is a regular file.
642 */
643 public boolean isRegularFile() {
644 return (this.mode & S_IFMT) == C_ISREG;
645 }
646
647 /**
648 * Check if this entry represents a socket.
649 *
650 * @return TRUE if this entry is a socket.
651 */
652 public boolean isSocket() {
653 return (this.mode & S_IFMT) == C_ISSOCK;
654 }
655
656 /**
657 * Check if this entry represents a symbolic link.
658 *
659 * @return TRUE if this entry is a symbolic link.
660 */
661 public boolean isSymbolicLink() {
662 return (this.mode & S_IFMT) == C_ISLNK;
663 }
664
665 /**
666 * Set the checksum. The checksum is calculated by adding all bytes of a
667 * file to transfer (crc += buf[pos] & 0xFF).
668 *
669 * @param chksum
670 * The checksum to set.
671 */
672 public void setChksum(final long chksum) {
673 checkNewFormat();
674 this.chksum = chksum;
675 }
676
677 /**
678 * Set the device id.
679 *
680 * @param device
681 * The device id to set.
682 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000683 * if this method is called for a CPIOArchiveEntry with a new
684 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000685 */
686 public void setDevice(final long device) {
687 checkOldFormat();
688 this.min = device;
689 }
690
691 /**
692 * Set major device id.
693 *
694 * @param maj
695 * The major device id to set.
696 */
697 public void setDeviceMaj(final long maj) {
698 checkNewFormat();
699 this.maj = maj;
700 }
701
702 /**
703 * Set the minor device id
704 *
705 * @param min
706 * The minor device id to set.
707 */
708 public void setDeviceMin(final long min) {
709 checkNewFormat();
710 this.min = min;
711 }
712
713 /**
714 * Set the filesize.
715 *
716 * @param size
717 * The filesize to set.
718 */
719 public void setSize(final long size) {
720 if (size < 0 || size > 0xFFFFFFFFL) {
721 throw new IllegalArgumentException("invalid entry size <" + size
Stefan Bodewig06fbac92009-08-01 14:53:32 +0000722 + ">");
Torsten Curdt70c83202009-01-12 11:09:21 +0000723 }
724 this.filesize = size;
725 }
726
727 /**
Torsten Curdt70c83202009-01-12 11:09:21 +0000728 * Set the group id.
729 *
730 * @param gid
731 * The group id to set.
732 */
733 public void setGID(final long gid) {
734 this.gid = gid;
735 }
736
737 /**
738 * Set the inode.
739 *
740 * @param inode
741 * The inode to set.
742 */
743 public void setInode(final long inode) {
744 this.inode = inode;
745 }
746
747 /**
748 * Set the mode of this entry (e.g. directory, regular file).
749 *
750 * @param mode
751 * The mode to set.
752 */
753 public void setMode(final long mode) {
Sebastian Bazley8c36ce32009-03-26 13:40:38 +0000754 final long maskedMode = mode & S_IFMT;
755 switch ((int) maskedMode) {
Torsten Curdt70c83202009-01-12 11:09:21 +0000756 case C_ISDIR:
757 case C_ISLNK:
758 case C_ISREG:
759 case C_ISFIFO:
760 case C_ISCHR:
761 case C_ISBLK:
762 case C_ISSOCK:
763 case C_ISNWK:
764 break;
765 default:
Sebastian Bazley84f836e2009-03-26 20:54:47 +0000766 throw new IllegalArgumentException(
Stefan Bodewig06fbac92009-08-01 14:53:32 +0000767 "Unknown mode. "
768 + "Full: " + Long.toHexString(mode)
769 + " Masked: " + Long.toHexString(maskedMode));
Torsten Curdt70c83202009-01-12 11:09:21 +0000770 }
771
772 this.mode = mode;
773 }
774
775 /**
776 * Set the name.
777 *
778 * @param name
779 * The name to set.
780 */
781 public void setName(final String name) {
782 this.name = name;
783 }
784
785 /**
786 * Set the number of links.
787 *
788 * @param nlink
789 * The number of links to set.
790 */
791 public void setNumberOfLinks(final long nlink) {
792 this.nlink = nlink;
793 }
794
795 /**
796 * Set the remote device id.
797 *
798 * @param device
799 * The remote device id to set.
800 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000801 * if this method is called for a CPIOArchiveEntry with a new
802 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000803 */
804 public void setRemoteDevice(final long device) {
805 checkOldFormat();
806 this.rmin = device;
807 }
808
809 /**
810 * Set the remote major device id.
811 *
812 * @param rmaj
813 * The remote major device id to set.
814 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000815 * if this method is called for a CPIOArchiveEntry with an old
816 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000817 */
818 public void setRemoteDeviceMaj(final long rmaj) {
819 checkNewFormat();
820 this.rmaj = rmaj;
821 }
822
823 /**
824 * Set the remote minor device id.
825 *
826 * @param rmin
827 * The remote minor device id to set.
828 * @throws UnsupportedOperationException
Stefan Bodewig41f4a202009-03-20 15:42:37 +0000829 * if this method is called for a CPIOArchiveEntry with an old
830 * format.
Torsten Curdt70c83202009-01-12 11:09:21 +0000831 */
832 public void setRemoteDeviceMin(final long rmin) {
833 checkNewFormat();
834 this.rmin = rmin;
835 }
836
837 /**
838 * Set the time in seconds.
839 *
840 * @param time
841 * The time to set.
842 */
843 public void setTime(final long time) {
844 this.mtime = time;
845 }
846
847 /**
848 * Set the user id.
849 *
850 * @param uid
851 * The user id to set.
852 */
853 public void setUID(final long uid) {
854 this.uid = uid;
855 }
Christian Grobmeier28c23fb2009-04-17 05:14:49 +0000856
857 /* (non-Javadoc)
858 * @see java.lang.Object#hashCode()
859 */
Stefan Bodewig46628ef2011-08-06 16:30:40 +0000860 @Override
Christian Grobmeier28c23fb2009-04-17 05:14:49 +0000861 public int hashCode() {
862 final int prime = 31;
863 int result = 1;
864 result = prime * result + ((name == null) ? 0 : name.hashCode());
865 return result;
866 }
867
868 /* (non-Javadoc)
869 * @see java.lang.Object#equals(java.lang.Object)
870 */
Stefan Bodewig46628ef2011-08-06 16:30:40 +0000871 @Override
Christian Grobmeier28c23fb2009-04-17 05:14:49 +0000872 public boolean equals(Object obj) {
873 if (this == obj) {
874 return true;
875 }
876 if (obj == null || getClass() != obj.getClass()) {
877 return false;
878 }
879 CpioArchiveEntry other = (CpioArchiveEntry) obj;
880 if (name == null) {
881 if (other.name != null) {
882 return false;
883 }
884 } else if (!name.equals(other.name)) {
885 return false;
886 }
887 return true;
888 }
Torsten Curdt70c83202009-01-12 11:09:21 +0000889}