/** * Copyright 2012 Kamran Zafar * * Licensed 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. * */ /** * The original source has been modified by Paul Williams. */ package com.codename1.io.tar; import java.util.Date; import com.codename1.io.FileSystemStorage; import com.codename1.io.Storage; /** * @author Kamran Zafar * */ public class TarEntry { protected String file; protected TarHeader header; private TarEntry() { this.file = null; this.header = new TarHeader(); } public TarEntry(String file, String entryName) { this(); this.file = file; this.extractTarHeader( entryName ); } public TarEntry(byte[] headerBuf) { this(); this.parseTarHeader( headerBuf ); } public boolean equals(TarEntry it) { return this.header.name.toString().equals( it.header.name.toString() ); } public boolean isDescendent(TarEntry desc) { return desc.header.name.toString().startsWith( this.header.name.toString() ); } public TarHeader getHeader() { return this.header; } public String getName() { return this.header.name.toString(); } public void setName(String name) { this.header.name = new StringBuffer( name ); } public int getUserId() { return this.header.userId; } public void setUserId(int userId) { this.header.userId = userId; } public int getGroupId() { return this.header.groupId; } public void setGroupId(int groupId) { this.header.groupId = groupId; } public String getUserName() { return this.header.userName.toString(); } public void setUserName(String userName) { this.header.userName = new StringBuffer( userName ); } public String getGroupName() { return this.header.groupName.toString(); } public void setGroupName(String groupName) { this.header.groupName = new StringBuffer( groupName ); } public void setIds(int userId, int groupId) { this.setUserId( userId ); this.setGroupId( groupId ); } public void setModTime(long time) { this.header.modTime = time / 1000; } public void setModTime(Date time) { this.header.modTime = time.getTime() / 1000; } public Date getModTime() { return new Date( this.header.modTime * 1000 ); } public String getFile() { return this.file; } public long getSize() { return this.header.size; } public void setSize(long size) { this.header.size = size; } /** * Checks if the org.xeustechnologies.jtar entry is a directory * * @return */ public boolean isDirectory() { if (this.file != null) return FileSystemStorage.getInstance().isDirectory(this.file); if (this.header != null) { if (this.header.linkFlag == TarHeader.LF_DIR) return true; if (this.header.name.toString().endsWith( "/" )) return true; } return false; } /** * Extract header from File * * @param entryName */ public void extractTarHeader(String entryName) { String name = entryName; FileSystemStorage fileSystem = FileSystemStorage.getInstance(); name = name.replace( fileSystem.getFileSystemSeparator(), '/' ); if (name.startsWith( "/" )) name = name.substring( 1 ); header.linkName = new StringBuffer( "" ); header.name = new StringBuffer( name ); if (fileSystem.isDirectory(file)) { header.mode = 040755; header.linkFlag = TarHeader.LF_DIR; if (header.name.charAt( header.name.length() - 1 ) != '/') { header.name.append( "/" ); } header.size = 0; } else { header.size = fileSystem.getLength(file); header.mode = 0100644; header.linkFlag = TarHeader.LF_NORMAL; } //header.modTime = file.lastModified() / 1000; header.modTime = 0; header.checkSum = 0; header.devMajor = 0; header.devMinor = 0; } /** * Calculate checksum * * @param buf * @return */ public long computeCheckSum(byte[] buf) { long sum = 0; int blen = buf.length; for (int i = 0; i < blen; ++i) { sum += 255 & buf[i]; } return sum; } /** * Writes the header to the byte buffer * * @param outbuf */ public void writeEntryHeader(byte[] outbuf) { int offset = 0; offset = TarHeader.getNameBytes( this.header.name, outbuf, offset, TarHeader.NAMELEN ); offset = Octal.getOctalBytes( this.header.mode, outbuf, offset, TarHeader.MODELEN ); offset = Octal.getOctalBytes( this.header.userId, outbuf, offset, TarHeader.UIDLEN ); offset = Octal.getOctalBytes( this.header.groupId, outbuf, offset, TarHeader.GIDLEN ); long size = this.header.size; offset = Octal.getLongOctalBytes( size, outbuf, offset, TarHeader.SIZELEN ); offset = Octal.getLongOctalBytes( this.header.modTime, outbuf, offset, TarHeader.MODTIMELEN ); int csOffset = offset; for (int c = 0; c < TarHeader.CHKSUMLEN; ++c) outbuf[offset++] = (byte) ' '; outbuf[offset++] = this.header.linkFlag; offset = TarHeader.getNameBytes( this.header.linkName, outbuf, offset, TarHeader.NAMELEN ); offset = TarHeader.getNameBytes( this.header.magic, outbuf, offset, TarHeader.MAGICLEN ); offset = TarHeader.getNameBytes( this.header.userName, outbuf, offset, TarHeader.UNAMELEN ); offset = TarHeader.getNameBytes( this.header.groupName, outbuf, offset, TarHeader.GNAMELEN ); offset = Octal.getOctalBytes( this.header.devMajor, outbuf, offset, TarHeader.DEVLEN ); offset = Octal.getOctalBytes( this.header.devMinor, outbuf, offset, TarHeader.DEVLEN ); int oblen = outbuf.length; for (; offset < oblen;) outbuf[offset++] = 0; long checkSum = this.computeCheckSum( outbuf ); Octal.getCheckSumOctalBytes( checkSum, outbuf, csOffset, TarHeader.CHKSUMLEN ); } /** * Parses the tar header to the byte buffer * * @param header * @param bh */ public void parseTarHeader(byte[] bh) { int offset = 0; header.name = TarHeader.parseName( bh, offset, TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; header.mode = (int) Octal.parseOctal( bh, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; header.userId = (int) Octal.parseOctal( bh, offset, TarHeader.UIDLEN ); offset += TarHeader.UIDLEN; header.groupId = (int) Octal.parseOctal( bh, offset, TarHeader.GIDLEN ); offset += TarHeader.GIDLEN; header.size = Octal.parseOctal( bh, offset, TarHeader.SIZELEN ); offset += TarHeader.SIZELEN; header.modTime = Octal.parseOctal( bh, offset, TarHeader.MODTIMELEN ); offset += TarHeader.MODTIMELEN; header.checkSum = (int) Octal.parseOctal( bh, offset, TarHeader.CHKSUMLEN ); offset += TarHeader.CHKSUMLEN; header.linkFlag = bh[offset++]; header.linkName = TarHeader.parseName( bh, offset, TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; header.magic = TarHeader.parseName( bh, offset, TarHeader.MAGICLEN ); offset += TarHeader.MAGICLEN; header.userName = TarHeader.parseName( bh, offset, TarHeader.UNAMELEN ); offset += TarHeader.UNAMELEN; header.groupName = TarHeader.parseName( bh, offset, TarHeader.GNAMELEN ); offset += TarHeader.GNAMELEN; header.devMajor = (int) Octal.parseOctal( bh, offset, TarHeader.DEVLEN ); offset += TarHeader.DEVLEN; header.devMinor = (int) Octal.parseOctal( bh, offset, TarHeader.DEVLEN ); } }