/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.commons.compress.archivers.dump;

import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.compress.archivers.ArchiveEntry;

This class represents an entry in a Dump archive. It consists of the entry's header, the entry's File and any extended attributes.

DumpEntries that are created from the header bytes read from an archive are instantiated with the DumpArchiveEntry( byte[] ) constructor. These entries will be used when extracting from or listing the contents of an archive. These entries have their header filled in using the header bytes. They also set the File to null, since they reference an archive entry not a file.

DumpEntries can also be constructed from nothing but a name. This allows the programmer to construct the entry by hand, for instance when only an InputStream is available for writing to the archive, and the header information is constructed from other information. In this case the header fields are set to defaults and the File is set to null.

The C structure for a Dump Entry's header is:

#define TP_BSIZE    1024          // size of each file block
#define NTREC       10            // number of blocks to write at once
#define HIGHDENSITYTREC 32        // number of blocks to write on high-density tapes
#define TP_NINDIR   (TP_BSIZE/2)  // number if indirect inodes in record
#define TP_NINOS    (TP_NINDIR / sizeof (int32_t))
#define LBLSIZE     16
#define NAMELEN     64
#define OFS_MAGIC     (int)60011  // old format magic value
#define NFS_MAGIC     (int)60012  // new format magic value
#define FS_UFS2_MAGIC (int)0x19540119
#define CHECKSUM      (int)84446  // constant used in checksum algorithm
struct  s_spcl {
  int32_t c_type;             // record type (see below)
  int32_t c_date;             // date of this dump
  int32_t c_ddate;            // date of previous dump
  int32_t c_volume;           // dump volume number
  u_int32_t c_tapea;          // logical block of this record
  dump_ino_t c_ino;           // number of inode
  int32_t c_magic;            // magic number (see above)
  int32_t c_checksum;         // record checksum
#ifdef  __linux__
  struct  new_bsd_inode c_dinode;
#else
#ifdef sunos
  struct  new_bsd_inode c_dinode;
#else
  struct  dinode  c_dinode;   // ownership and mode of inode
#endif
#endif
  int32_t c_count;            // number of valid c_addr entries
  union u_data c_data;        // see above
  char    c_label[LBLSIZE];   // dump label
  int32_t c_level;            // level of this dump
  char    c_filesys[NAMELEN]; // name of dumpped file system
  char    c_dev[NAMELEN];     // name of dumpped device
  char    c_host[NAMELEN];    // name of dumpped host
  int32_t c_flags;            // additional information (see below)
  int32_t c_firstrec;         // first record on volume
  int32_t c_ntrec;            // blocksize on volume
  int32_t c_extattributes;    // additional inode info (see below)
  int32_t c_spare[30];        // reserved for future uses
} s_spcl;
//
// flag values
//
#define DR_NEWHEADER     0x0001  // new format tape header
#define DR_NEWINODEFMT   0x0002  // new format inodes on tape
#define DR_COMPRESSED    0x0080  // dump tape is compressed
#define DR_METAONLY      0x0100  // only the metadata of the inode has been dumped
#define DR_INODEINFO     0x0002  // [SIC] TS_END header contains c_inos information
#define DR_EXTATTRIBUTES 0x8000
//
// extattributes inode info
//
#define EXT_REGULAR         0
#define EXT_MACOSFNDRINFO   1
#define EXT_MACOSRESFORK    2
#define EXT_XATTR           3
// used for EA on tape
#define EXT2_GOOD_OLD_INODE_SIZE    128
#define EXT2_XATTR_MAGIC        0xEA020000  // block EA
#define EXT2_XATTR_MAGIC2       0xEA020001  // in inode EA

The fields in bold are the same for all blocks. (This permitted multiple dumps to be written to a single tape.)

The C structure for the inode (file) information is:

struct bsdtimeval {           //  **** alpha-*-linux is deviant
  __u32   tv_sec;
  __u32   tv_usec;
};
#define NDADDR      12
#define NIADDR       3
//
// This is the new (4.4) BSD inode structure
// copied from the FreeBSD 2.0 <ufs/ufs/dinode.h> include file
//
struct new_bsd_inode {
  __u16       di_mode;           // file type, standard Unix permissions
  __s16       di_nlink;          // number of hard links to file.
  union {
     __u16       oldids[2];
     __u32       inumber;
  }           di_u;
  u_quad_t    di_size;           // file size
  struct bsdtimeval   di_atime;  // time file was last accessed
  struct bsdtimeval   di_mtime;  // time file was last modified
  struct bsdtimeval   di_ctime;  // time file was created
  __u32       di_db[NDADDR];
  __u32       di_ib[NIADDR];
  __u32       di_flags;          //
  __s32       di_blocks;         // number of disk blocks
  __s32       di_gen;            // generation number
  __u32       di_uid;            // user id (see /etc/passwd)
  __u32       di_gid;            // group id (see /etc/group)
  __s32       di_spare[2];       // unused
};

It is important to note that the header DOES NOT have the name of the file. It can't since hard links mean that you may have multiple file names for a single physical file. You must read the contents of the directory entries to learn the mapping(s) from file name to inode.

The C structure that indicates if a specific block is a real block that contains data or is a sparse block that is not persisted to the disk is:

#define TP_BSIZE    1024
#define TP_NINDIR   (TP_BSIZE/2)
union u_data {
  char    s_addrs[TP_NINDIR]; // 1 => data; 0 => hole in inode
  int32_t s_inos[TP_NINOS];   // table of first inode on each volume
} u_data;
@NotThreadSafe
/** * This class represents an entry in a Dump archive. It consists * of the entry's header, the entry's File and any extended attributes. * <p> * DumpEntries that are created from the header bytes read from * an archive are instantiated with the DumpArchiveEntry( byte[] ) * constructor. These entries will be used when extracting from * or listing the contents of an archive. These entries have their * header filled in using the header bytes. They also set the File * to null, since they reference an archive entry not a file. * <p> * DumpEntries can also be constructed from nothing but a name. * This allows the programmer to construct the entry by hand, for * instance when only an InputStream is available for writing to * the archive, and the header information is constructed from * other information. In this case the header fields are set to * defaults and the File is set to null. * * <p> * The C structure for a Dump Entry's header is: * <pre> * #define TP_BSIZE 1024 // size of each file block * #define NTREC 10 // number of blocks to write at once * #define HIGHDENSITYTREC 32 // number of blocks to write on high-density tapes * #define TP_NINDIR (TP_BSIZE/2) // number if indirect inodes in record * #define TP_NINOS (TP_NINDIR / sizeof (int32_t)) * #define LBLSIZE 16 * #define NAMELEN 64 * * #define OFS_MAGIC (int)60011 // old format magic value * #define NFS_MAGIC (int)60012 // new format magic value * #define FS_UFS2_MAGIC (int)0x19540119 * #define CHECKSUM (int)84446 // constant used in checksum algorithm * * struct s_spcl { * int32_t c_type; // record type (see below) * int32_t <b>c_date</b>; // date of this dump * int32_t <b>c_ddate</b>; // date of previous dump * int32_t c_volume; // dump volume number * u_int32_t c_tapea; // logical block of this record * dump_ino_t c_ino; // number of inode * int32_t <b>c_magic</b>; // magic number (see above) * int32_t c_checksum; // record checksum * #ifdef __linux__ * struct new_bsd_inode c_dinode; * #else * #ifdef sunos * struct new_bsd_inode c_dinode; * #else * struct dinode c_dinode; // ownership and mode of inode * #endif * #endif * int32_t c_count; // number of valid c_addr entries * union u_data c_data; // see above * char <b>c_label[LBLSIZE]</b>; // dump label * int32_t <b>c_level</b>; // level of this dump * char <b>c_filesys[NAMELEN]</b>; // name of dumpped file system * char <b>c_dev[NAMELEN]</b>; // name of dumpped device * char <b>c_host[NAMELEN]</b>; // name of dumpped host * int32_t c_flags; // additional information (see below) * int32_t c_firstrec; // first record on volume * int32_t c_ntrec; // blocksize on volume * int32_t c_extattributes; // additional inode info (see below) * int32_t c_spare[30]; // reserved for future uses * } s_spcl; * * // * // flag values * // * #define DR_NEWHEADER 0x0001 // new format tape header * #define DR_NEWINODEFMT 0x0002 // new format inodes on tape * #define DR_COMPRESSED 0x0080 // dump tape is compressed * #define DR_METAONLY 0x0100 // only the metadata of the inode has been dumped * #define DR_INODEINFO 0x0002 // [SIC] TS_END header contains c_inos information * #define DR_EXTATTRIBUTES 0x8000 * * // * // extattributes inode info * // * #define EXT_REGULAR 0 * #define EXT_MACOSFNDRINFO 1 * #define EXT_MACOSRESFORK 2 * #define EXT_XATTR 3 * * // used for EA on tape * #define EXT2_GOOD_OLD_INODE_SIZE 128 * #define EXT2_XATTR_MAGIC 0xEA020000 // block EA * #define EXT2_XATTR_MAGIC2 0xEA020001 // in inode EA * </pre> * <p> * The fields in <b>bold</b> are the same for all blocks. (This permitted * multiple dumps to be written to a single tape.) * </p> * * <p> * The C structure for the inode (file) information is: * <pre> * struct bsdtimeval { // **** alpha-*-linux is deviant * __u32 tv_sec; * __u32 tv_usec; * }; * * #define NDADDR 12 * #define NIADDR 3 * * // * // This is the new (4.4) BSD inode structure * // copied from the FreeBSD 2.0 &lt;ufs/ufs/dinode.h&gt; include file * // * struct new_bsd_inode { * __u16 di_mode; // file type, standard Unix permissions * __s16 di_nlink; // number of hard links to file. * union { * __u16 oldids[2]; * __u32 inumber; * } di_u; * u_quad_t di_size; // file size * struct bsdtimeval di_atime; // time file was last accessed * struct bsdtimeval di_mtime; // time file was last modified * struct bsdtimeval di_ctime; // time file was created * __u32 di_db[NDADDR]; * __u32 di_ib[NIADDR]; * __u32 di_flags; // * __s32 di_blocks; // number of disk blocks * __s32 di_gen; // generation number * __u32 di_uid; // user id (see /etc/passwd) * __u32 di_gid; // group id (see /etc/group) * __s32 di_spare[2]; // unused * }; * </pre> * <p> * It is important to note that the header DOES NOT have the name of the * file. It can't since hard links mean that you may have multiple file names * for a single physical file. You must read the contents of the directory * entries to learn the mapping(s) from file name to inode. * </p> * * <p> * The C structure that indicates if a specific block is a real block * that contains data or is a sparse block that is not persisted to the * disk is:</p> * <pre> * #define TP_BSIZE 1024 * #define TP_NINDIR (TP_BSIZE/2) * * union u_data { * char s_addrs[TP_NINDIR]; // 1 =&gt; data; 0 =&gt; hole in inode * int32_t s_inos[TP_NINOS]; // table of first inode on each volume * } u_data; * </pre> * * @NotThreadSafe */
public class DumpArchiveEntry implements ArchiveEntry { private String name; private TYPE type = TYPE.UNKNOWN; private int mode; private Set<PERMISSION> permissions = Collections.emptySet(); private long size; private long atime; private long mtime; private int uid; private int gid;
Currently unused
/** * Currently unused */
private final DumpArchiveSummary summary = null; // this information is available from standard index. private final TapeSegmentHeader header = new TapeSegmentHeader(); private String simpleName; private String originalName; // this information is available from QFA index private int volume; private long offset; private int ino; private int nlink; private long ctime; private int generation; private boolean isDeleted;
Default constructor.
/** * Default constructor. */
public DumpArchiveEntry() { }
Constructor taking only file name.
Params:
  • name – pathname
  • simpleName – actual file name.
/** * Constructor taking only file name. * @param name pathname * @param simpleName actual file name. */
public DumpArchiveEntry(final String name, final String simpleName) { setName(name); this.simpleName = simpleName; }
Constructor taking name, inode and type.
Params:
  • name – the name
  • simpleName – the simple name
  • ino – the ino
  • type – the type
/** * Constructor taking name, inode and type. * * @param name the name * @param simpleName the simple name * @param ino the ino * @param type the type */
protected DumpArchiveEntry(final String name, final String simpleName, final int ino, final TYPE type) { setType(type); setName(name); this.simpleName = simpleName; this.ino = ino; this.offset = 0; }
Returns the path of the entry.
Returns:the path of the entry.
/** * Returns the path of the entry. * @return the path of the entry. */
public String getSimpleName() { return simpleName; }
Sets the path of the entry.
Params:
  • simpleName – the simple name
/** * Sets the path of the entry. * @param simpleName the simple name */
protected void setSimpleName(final String simpleName) { this.simpleName = simpleName; }
Returns the ino of the entry.
Returns:the ino
/** * Returns the ino of the entry. * @return the ino */
public int getIno() { return header.getIno(); }
Return the number of hard links to the entry.
Returns:the number of hard links
/** * Return the number of hard links to the entry. * @return the number of hard links */
public int getNlink() { return nlink; }
Set the number of hard links.
Params:
  • nlink – the number of hard links
/** * Set the number of hard links. * @param nlink the number of hard links */
public void setNlink(final int nlink) { this.nlink = nlink; }
Get file creation time.
Returns:the creation time
/** * Get file creation time. * @return the creation time */
public Date getCreationTime() { return new Date(ctime); }
Set the file creation time.
Params:
  • ctime – the creation time
/** * Set the file creation time. * @param ctime the creation time */
public void setCreationTime(final Date ctime) { this.ctime = ctime.getTime(); }
Return the generation of the file.
Returns:the generation
/** * Return the generation of the file. * @return the generation */
public int getGeneration() { return generation; }
Set the generation of the file.
Params:
  • generation – the generation
/** * Set the generation of the file. * @param generation the generation */
public void setGeneration(final int generation) { this.generation = generation; }
Has this file been deleted? (On valid on incremental dumps.)
Returns:whether the file has been deleted
/** * Has this file been deleted? (On valid on incremental dumps.) * @return whether the file has been deleted */
public boolean isDeleted() { return isDeleted; }
Set whether this file has been deleted.
Params:
  • isDeleted – whether the file has been deleted
/** * Set whether this file has been deleted. * @param isDeleted whether the file has been deleted */
public void setDeleted(final boolean isDeleted) { this.isDeleted = isDeleted; }
Return the offset within the archive
Returns:the offset
/** * Return the offset within the archive * @return the offset */
public long getOffset() { return offset; }
Set the offset within the archive.
Params:
  • offset – the offset
/** * Set the offset within the archive. * @param offset the offset */
public void setOffset(final long offset) { this.offset = offset; }
Return the tape volume where this file is located.
Returns:the volume
/** * Return the tape volume where this file is located. * @return the volume */
public int getVolume() { return volume; }
Set the tape volume.
Params:
  • volume – the volume
/** * Set the tape volume. * @param volume the volume */
public void setVolume(final int volume) { this.volume = volume; }
Return the type of the tape segment header.
Returns:the segment header
/** * Return the type of the tape segment header. * @return the segment header */
public DumpArchiveConstants.SEGMENT_TYPE getHeaderType() { return header.getType(); }
Return the number of records in this segment.
Returns:the number of records
/** * Return the number of records in this segment. * @return the number of records */
public int getHeaderCount() { return header.getCount(); }
Return the number of sparse records in this segment.
Returns:the number of sparse records
/** * Return the number of sparse records in this segment. * @return the number of sparse records */
public int getHeaderHoles() { return header.getHoles(); }
Is this a sparse record?
Params:
  • idx – index of the record to check
Returns:whether this is a sparse record
/** * Is this a sparse record? * @param idx index of the record to check * @return whether this is a sparse record */
public boolean isSparseRecord(final int idx) { return (header.getCdata(idx) & 0x01) == 0; } @Override public int hashCode() { return ino; } @Override public boolean equals(final Object o) { if (o == this) { return true; } else if (o == null || !o.getClass().equals(getClass())) { return false; } final DumpArchiveEntry rhs = (DumpArchiveEntry) o; if (rhs.header == null) { return false; } if (ino != rhs.ino) { return false; } // summary is always null right now, but this may change some day if ((summary == null && rhs.summary != null) // NOSONAR || (summary != null && !summary.equals(rhs.summary))) { // NOSONAR return false; } return true; } @Override public String toString() { return getName(); }
Populate the dump archive entry and tape segment header with the contents of the buffer.
Params:
  • buffer – buffer to read content from
/** * Populate the dump archive entry and tape segment header with * the contents of the buffer. * * @param buffer buffer to read content from */
static DumpArchiveEntry parse(final byte[] buffer) { final DumpArchiveEntry entry = new DumpArchiveEntry(); final TapeSegmentHeader header = entry.header; header.type = DumpArchiveConstants.SEGMENT_TYPE.find(DumpArchiveUtil.convert32( buffer, 0)); //header.dumpDate = new Date(1000L * DumpArchiveUtil.convert32(buffer, 4)); //header.previousDumpDate = new Date(1000L * DumpArchiveUtil.convert32( // buffer, 8)); header.volume = DumpArchiveUtil.convert32(buffer, 12); //header.tapea = DumpArchiveUtil.convert32(buffer, 16); entry.ino = header.ino = DumpArchiveUtil.convert32(buffer, 20); //header.magic = DumpArchiveUtil.convert32(buffer, 24); //header.checksum = DumpArchiveUtil.convert32(buffer, 28); final int m = DumpArchiveUtil.convert16(buffer, 32); // determine the type of the file. entry.setType(TYPE.find((m >> 12) & 0x0F)); // determine the standard permissions entry.setMode(m); entry.nlink = DumpArchiveUtil.convert16(buffer, 34); // inumber, oldids? entry.setSize(DumpArchiveUtil.convert64(buffer, 40)); long t = (1000L * DumpArchiveUtil.convert32(buffer, 48)) + (DumpArchiveUtil.convert32(buffer, 52) / 1000); entry.setAccessTime(new Date(t)); t = (1000L * DumpArchiveUtil.convert32(buffer, 56)) + (DumpArchiveUtil.convert32(buffer, 60) / 1000); entry.setLastModifiedDate(new Date(t)); t = (1000L * DumpArchiveUtil.convert32(buffer, 64)) + (DumpArchiveUtil.convert32(buffer, 68) / 1000); entry.ctime = t; // db: 72-119 - direct blocks // id: 120-131 - indirect blocks //entry.flags = DumpArchiveUtil.convert32(buffer, 132); //entry.blocks = DumpArchiveUtil.convert32(buffer, 136); entry.generation = DumpArchiveUtil.convert32(buffer, 140); entry.setUserId(DumpArchiveUtil.convert32(buffer, 144)); entry.setGroupId(DumpArchiveUtil.convert32(buffer, 148)); // two 32-bit spare values. header.count = DumpArchiveUtil.convert32(buffer, 160); header.holes = 0; for (int i = 0; (i < 512) && (i < header.count); i++) { if (buffer[164 + i] == 0) { header.holes++; } } System.arraycopy(buffer, 164, header.cdata, 0, 512); entry.volume = header.getVolume(); //entry.isSummaryOnly = false; return entry; }
Update entry with information from next tape segment header.
/** * Update entry with information from next tape segment header. */
void update(final byte[] buffer) { header.volume = DumpArchiveUtil.convert32(buffer, 16); header.count = DumpArchiveUtil.convert32(buffer, 160); header.holes = 0; for (int i = 0; (i < 512) && (i < header.count); i++) { if (buffer[164 + i] == 0) { header.holes++; } } System.arraycopy(buffer, 164, header.cdata, 0, 512); }
Archive entry as stored on tape. There is one TSH for (at most) every 512k in the file.
/** * Archive entry as stored on tape. There is one TSH for (at most) * every 512k in the file. */
static class TapeSegmentHeader { private DumpArchiveConstants.SEGMENT_TYPE type; private int volume; private int ino; private int count; private int holes; private final byte[] cdata = new byte[512]; // map of any 'holes' public DumpArchiveConstants.SEGMENT_TYPE getType() { return type; } public int getVolume() { return volume; } public int getIno() { return ino; } void setIno(final int ino) { this.ino = ino; } public int getCount() { return count; } public int getHoles() { return holes; } public int getCdata(final int idx) { return cdata[idx]; } }
Returns the name of the entry.

This method returns the raw name as it is stored inside of the archive.

Returns:the name of the entry.
/** * Returns the name of the entry. * * <p>This method returns the raw name as it is stored inside of the archive.</p> * * @return the name of the entry. */
@Override public String getName() { return name; }
Returns the unmodified name of the entry.
Returns:the name of the entry.
/** * Returns the unmodified name of the entry. * @return the name of the entry. */
String getOriginalName() { return originalName; }
Sets the name of the entry.
Params:
  • name – the name
/** * Sets the name of the entry. * @param name the name */
public final void setName(String name) { this.originalName = name; if (name != null) { if (isDirectory() && !name.endsWith("/")) { name += "/"; } if (name.startsWith("./")) { name = name.substring(2); } } this.name = name; }
The last modified date.
Returns:the last modified date
/** * The last modified date. * @return the last modified date */
@Override public Date getLastModifiedDate() { return new Date(mtime); }
Is this a directory?
Returns:whether this is a directory
/** * Is this a directory? * @return whether this is a directory */
@Override public boolean isDirectory() { return type == TYPE.DIRECTORY; }
Is this a regular file?
Returns:whether this is a regular file
/** * Is this a regular file? * @return whether this is a regular file */
public boolean isFile() { return type == TYPE.FILE; }
Is this a network device?
Returns:whether this is a socket
/** * Is this a network device? * @return whether this is a socket */
public boolean isSocket() { return type == TYPE.SOCKET; }
Is this a character device?
Returns:whether this is a character device
/** * Is this a character device? * @return whether this is a character device */
public boolean isChrDev() { return type == TYPE.CHRDEV; }
Is this a block device?
Returns:whether this is a block device
/** * Is this a block device? * @return whether this is a block device */
public boolean isBlkDev() { return type == TYPE.BLKDEV; }
Is this a fifo/pipe?
Returns:whether this is a fifo
/** * Is this a fifo/pipe? * @return whether this is a fifo */
public boolean isFifo() { return type == TYPE.FIFO; }
Get the type of the entry.
Returns:the type
/** * Get the type of the entry. * @return the type */
public TYPE getType() { return type; }
Set the type of the entry.
Params:
  • type – the type
/** * Set the type of the entry. * @param type the type */
public void setType(final TYPE type) { this.type = type; }
Return the access permissions on the entry.
Returns:the access permissions
/** * Return the access permissions on the entry. * @return the access permissions */
public int getMode() { return mode; }
Set the access permissions on the entry.
Params:
  • mode – the access permissions
/** * Set the access permissions on the entry. * @param mode the access permissions */
public void setMode(final int mode) { this.mode = mode & 07777; this.permissions = PERMISSION.find(mode); }
Returns the permissions on the entry.
Returns:the permissions
/** * Returns the permissions on the entry. * @return the permissions */
public Set<PERMISSION> getPermissions() { return permissions; }
Returns the size of the entry.
Returns:the size
/** * Returns the size of the entry. * @return the size */
@Override public long getSize() { return isDirectory() ? SIZE_UNKNOWN : size; }
Returns the size of the entry as read from the archive.
/** * Returns the size of the entry as read from the archive. */
long getEntrySize() { return size; }
Set the size of the entry.
Params:
  • size – the size
/** * Set the size of the entry. * @param size the size */
public void setSize(final long size) { this.size = size; }
Set the time the file was last modified.
Params:
  • mtime – the last modified time
/** * Set the time the file was last modified. * @param mtime the last modified time */
public void setLastModifiedDate(final Date mtime) { this.mtime = mtime.getTime(); }
Returns the time the file was last accessed.
Returns:the access time
/** * Returns the time the file was last accessed. * @return the access time */
public Date getAccessTime() { return new Date(atime); }
Set the time the file was last accessed.
Params:
  • atime – the access time
/** * Set the time the file was last accessed. * @param atime the access time */
public void setAccessTime(final Date atime) { this.atime = atime.getTime(); }
Return the user id.
Returns:the user id
/** * Return the user id. * @return the user id */
public int getUserId() { return uid; }
Set the user id.
Params:
  • uid – the user id
/** * Set the user id. * @param uid the user id */
public void setUserId(final int uid) { this.uid = uid; }
Return the group id
Returns:the group id
/** * Return the group id * @return the group id */
public int getGroupId() { return gid; }
Set the group id.
Params:
  • gid – the group id
/** * Set the group id. * @param gid the group id */
public void setGroupId(final int gid) { this.gid = gid; } public enum TYPE { WHITEOUT(14), SOCKET(12), LINK(10), FILE(8), BLKDEV(6), DIRECTORY(4), CHRDEV(2), FIFO(1), UNKNOWN(15); private int code; TYPE(final int code) { this.code = code; } public static TYPE find(final int code) { TYPE type = UNKNOWN; for (final TYPE t : TYPE.values()) { if (code == t.code) { type = t; } } return type; } } public enum PERMISSION { SETUID(04000), SETGUI(02000), STICKY(01000), USER_READ(00400), USER_WRITE(00200), USER_EXEC(00100), GROUP_READ(00040), GROUP_WRITE(00020), GROUP_EXEC(00010), WORLD_READ(00004), WORLD_WRITE(00002), WORLD_EXEC(00001); private int code; PERMISSION(final int code) { this.code = code; } public static Set<PERMISSION> find(final int code) { final Set<PERMISSION> set = new HashSet<>(); for (final PERMISSION p : PERMISSION.values()) { if ((code & p.code) == p.code) { set.add(p); } } if (set.isEmpty()) { return Collections.emptySet(); } return EnumSet.copyOf(set); } } }