private int writeEntryHeaderField( long value, byte[] outbuf, int offset, int length, boolean starMode) { if (!starMode && (value < 0 || value >= (1l << (3 * (length - 1))))) { // value doesn't fit into field when written as octal // number, will be written to PAX header or causes an // error return TarUtils.formatLongOctalBytes(0, outbuf, offset, length); } return TarUtils.formatLongOctalOrBinaryBytes(value, outbuf, offset, length); }
/** * Write an entry's header information to a header buffer. * * @param outbuf The tar entry header buffer to fill in. * @param encoding encoding to use when writing the file name. * @param starMode whether to use the star/GNU tar/BSD tar extension for numeric fields if their * value doesn't fit in the maximum size of standard tar archives * @since 1.4 */ public void writeEntryHeader(byte[] outbuf, ZipEncoding encoding, boolean starMode) throws IOException { int offset = 0; offset = TarUtils.formatNameBytes(name, outbuf, offset, NAMELEN, encoding); offset = writeEntryHeaderField(mode, outbuf, offset, MODELEN, starMode); offset = writeEntryHeaderField(userId, outbuf, offset, UIDLEN, starMode); offset = writeEntryHeaderField(groupId, outbuf, offset, GIDLEN, starMode); offset = writeEntryHeaderField(size, outbuf, offset, SIZELEN, starMode); offset = writeEntryHeaderField(modTime, outbuf, offset, MODTIMELEN, starMode); int csOffset = offset; for (int c = 0; c < CHKSUMLEN; ++c) { outbuf[offset++] = (byte) ' '; } outbuf[offset++] = linkFlag; offset = TarUtils.formatNameBytes(linkName, outbuf, offset, NAMELEN, encoding); offset = TarUtils.formatNameBytes(magic, outbuf, offset, MAGICLEN); offset = TarUtils.formatNameBytes(version, outbuf, offset, VERSIONLEN); offset = TarUtils.formatNameBytes(userName, outbuf, offset, UNAMELEN, encoding); offset = TarUtils.formatNameBytes(groupName, outbuf, offset, GNAMELEN, encoding); offset = writeEntryHeaderField(devMajor, outbuf, offset, DEVLEN, starMode); offset = writeEntryHeaderField(devMinor, outbuf, offset, DEVLEN, starMode); while (offset < outbuf.length) { outbuf[offset++] = 0; } long chk = TarUtils.computeCheckSum(outbuf); TarUtils.formatCheckSumOctalBytes(chk, outbuf, csOffset, CHKSUMLEN); }
/** * Creates a new header for a file/directory entry. * * @param name File name * @param size File size in bytes * @param modTime Last modification time in numeric Unix time format * @param dir Is directory * @return */ public static TarHeader createHeader(String entryName, long size, long modTime, boolean dir) { String name = entryName; name = TarUtils.trim(name.replace(File.separatorChar, '/'), '/'); TarHeader header = new TarHeader(); header.linkName = new StringBuffer(""); if (name.length() > 100) { header.namePrefix = new StringBuffer(name.substring(0, name.lastIndexOf('/'))); header.name = new StringBuffer(name.substring(name.lastIndexOf('/') + 1)); } else { header.name = new StringBuffer(name); } if (dir) { header.mode = 040755; header.linkFlag = TarHeader.LF_DIR; if (header.name.charAt(header.name.length() - 1) != '/') { header.name.append("/"); } header.size = 0; } else { header.mode = 0100644; header.linkFlag = TarHeader.LF_NORMAL; header.size = size; } header.modTime = modTime; header.checkSum = 0; header.devMajor = 0; header.devMinor = 0; return header; }
@Test( expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Packing item is a directory") public void testPackDirectoryAsFileException() throws IOException { TarUtils.compressFile(Paths.get("target"), Paths.get("somePack")); }
@Test( expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Packing file doesn't exist") public void testPackNonExistsFileException() throws IOException { TarUtils.compressFile(Paths.get("non-exists"), Paths.get("somePack")); }
/** * Parse an entry's header information from a header buffer. * * @param header The tar entry header buffer to get information from. */ public void parseTarHeader(byte[] header) { int offset = 0; this.name = TarUtils.parseName(header, offset, NAMELEN); offset += NAMELEN; this.mode = (int) TarUtils.parseOctal(header, offset, MODELEN); offset += MODELEN; this.userId = (int) TarUtils.parseOctal(header, offset, UIDLEN); offset += UIDLEN; this.groupId = (int) TarUtils.parseOctal(header, offset, GIDLEN); offset += GIDLEN; this.size = TarUtils.parseOctal(header, offset, SIZELEN); offset += SIZELEN; this.modTime = TarUtils.parseOctal(header, offset, MODTIMELEN); offset += MODTIMELEN; this.checkSum = (int) TarUtils.parseOctal(header, offset, CHKSUMLEN); offset += CHKSUMLEN; this.linkFlag = header[offset++]; this.linkName = TarUtils.parseName(header, offset, NAMELEN); offset += NAMELEN; this.magic = TarUtils.parseName(header, offset, MAGICLEN); offset += MAGICLEN; this.userName = TarUtils.parseName(header, offset, UNAMELEN); offset += UNAMELEN; this.groupName = TarUtils.parseName(header, offset, GNAMELEN); offset += GNAMELEN; this.devMajor = (int) TarUtils.parseOctal(header, offset, DEVLEN); offset += DEVLEN; this.devMinor = (int) TarUtils.parseOctal(header, offset, DEVLEN); }
/** * Write an entry's header information to a header buffer. * * @param outbuf The tar entry header buffer to fill in. */ public void writeEntryHeader(byte[] outbuf) { int offset = 0; offset = TarUtils.getNameBytes(this.name, outbuf, offset, NAMELEN); offset = TarUtils.getOctalBytes(this.mode, outbuf, offset, MODELEN); offset = TarUtils.getOctalBytes(this.userId, outbuf, offset, UIDLEN); offset = TarUtils.getOctalBytes(this.groupId, outbuf, offset, GIDLEN); offset = TarUtils.getLongOctalBytes(this.size, outbuf, offset, SIZELEN); offset = TarUtils.getLongOctalBytes(this.modTime, outbuf, offset, MODTIMELEN); int csOffset = offset; for (int c = 0; c < CHKSUMLEN; ++c) { outbuf[offset++] = (byte) ' '; } outbuf[offset++] = this.linkFlag; offset = TarUtils.getNameBytes(this.linkName, outbuf, offset, NAMELEN); offset = TarUtils.getNameBytes(this.magic, outbuf, offset, MAGICLEN); offset = TarUtils.getNameBytes(this.userName, outbuf, offset, UNAMELEN); offset = TarUtils.getNameBytes(this.groupName, outbuf, offset, GNAMELEN); offset = TarUtils.getOctalBytes(this.devMajor, outbuf, offset, DEVLEN); offset = TarUtils.getOctalBytes(this.devMinor, outbuf, offset, DEVLEN); while (offset < outbuf.length) { outbuf[offset++] = 0; } long checkSum = TarUtils.computeCheckSum(outbuf); TarUtils.getCheckSumOctalBytes(checkSum, outbuf, csOffset, CHKSUMLEN); }
private void parseTarHeader(byte[] header, ZipEncoding encoding, final boolean oldStyle) throws IOException { int offset = 0; name = oldStyle ? TarUtils.parseName(header, offset, NAMELEN) : TarUtils.parseName(header, offset, NAMELEN, encoding); offset += NAMELEN; mode = (int) TarUtils.parseOctalOrBinary(header, offset, MODELEN); offset += MODELEN; userId = (int) TarUtils.parseOctalOrBinary(header, offset, UIDLEN); offset += UIDLEN; groupId = (int) TarUtils.parseOctalOrBinary(header, offset, GIDLEN); offset += GIDLEN; size = TarUtils.parseOctalOrBinary(header, offset, SIZELEN); offset += SIZELEN; modTime = TarUtils.parseOctalOrBinary(header, offset, MODTIMELEN); offset += MODTIMELEN; offset += CHKSUMLEN; linkFlag = header[offset++]; linkName = oldStyle ? TarUtils.parseName(header, offset, NAMELEN) : TarUtils.parseName(header, offset, NAMELEN, encoding); offset += NAMELEN; magic = TarUtils.parseName(header, offset, MAGICLEN); offset += MAGICLEN; version = TarUtils.parseName(header, offset, VERSIONLEN); offset += VERSIONLEN; userName = oldStyle ? TarUtils.parseName(header, offset, UNAMELEN) : TarUtils.parseName(header, offset, UNAMELEN, encoding); offset += UNAMELEN; groupName = oldStyle ? TarUtils.parseName(header, offset, GNAMELEN) : TarUtils.parseName(header, offset, GNAMELEN, encoding); offset += GNAMELEN; devMajor = (int) TarUtils.parseOctalOrBinary(header, offset, DEVLEN); offset += DEVLEN; devMinor = (int) TarUtils.parseOctalOrBinary(header, offset, DEVLEN); offset += DEVLEN; int type = evaluateType(header); switch (type) { case FORMAT_OLDGNU: { offset += ATIMELEN_GNU; offset += CTIMELEN_GNU; offset += OFFSETLEN_GNU; offset += LONGNAMESLEN_GNU; offset += PAD2LEN_GNU; offset += SPARSELEN_GNU; isExtended = TarUtils.parseBoolean(header, offset); offset += ISEXTENDEDLEN_GNU; realSize = TarUtils.parseOctal(header, offset, REALSIZELEN_GNU); offset += REALSIZELEN_GNU; break; } case FORMAT_POSIX: default: { String prefix = oldStyle ? TarUtils.parseName(header, offset, PREFIXLEN) : TarUtils.parseName(header, offset, PREFIXLEN, encoding); // SunOS tar -E does not add / to directory names, so fix // up to be consistent if (isDirectory() && !name.endsWith("/")) { name = name + "/"; } if (prefix.length() > 0) { name = prefix + "/" + name; } } } }