tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@hyperreal.org
Subject cvs commit: jakarta-tools/ant/src/main/com/ice/tar InvalidHeaderException.java TarArchive.java TarBuffer.java TarEntry.java TarHeader.java TarProgressDisplay.java
Date Wed, 01 Dec 1999 07:23:05 GMT
jons        99/11/30 23:23:04

  Added:       ant/src/main/com/ice/tar InvalidHeaderException.java
                        TarArchive.java TarBuffer.java TarEntry.java
                        TarHeader.java TarProgressDisplay.java
  Log:
  added in Tim's code. note that i needed to make
  some minor modifications to get it to compile. these modifications
  were limited to changing lines like this:
  
  byte foo = ' ';
  to
  byte foo = new Byte(" ").byteValue();
  
  there is probably a better way to do this, but this should
  work just fine anyways.
  
  Revision  Changes    Path
  1.1                  jakarta-tools/ant/src/main/com/ice/tar/InvalidHeaderException.java
  
  Index: InvalidHeaderException.java
  ===================================================================
  /*
  ** Copyright (c) 1998 by Timothy Gerard Endres
  ** <mailto:time@ice.com>  <http://www.ice.com>
  ** 
  ** This package is free software.
  ** 
  ** You may redistribute it and/or modify it under the terms of the GNU
  ** General Public License as published by the Free Software Foundation.
  ** Version 2 of the license should be included with this distribution in
  ** the file LICENSE, as well as License.html. If the license is not
  ** included	with this distribution, you may find a copy at the FSF web
  ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
  ** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
  **
  ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
  ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
  ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
  ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
  ** REDISTRIBUTION OF THIS SOFTWARE. 
  ** 
  */
  
  package com.ice.tar;
  
  
  public class
  InvalidHeaderException extends Exception
  	{
  
  	public
  	InvalidHeaderException()
  		{
  		super();
  		}
  
  	public
  	InvalidHeaderException( String msg )
  		{
  		super( msg );
  		}
  
  	}
  
  
  
  
  1.1                  jakarta-tools/ant/src/main/com/ice/tar/TarArchive.java
  
  Index: TarArchive.java
  ===================================================================
  /*
  ** Copyright (c) 1998 by Timothy Gerard Endres
  ** <mailto:time@ice.com>  <http://www.ice.com>
  ** 
  ** This package is free software.
  ** 
  ** You may redistribute it and/or modify it under the terms of the GNU
  ** General Public License as published by the Free Software Foundation.
  ** Version 2 of the license should be included with this distribution in
  ** the file LICENSE, as well as License.html. If the license is not
  ** included	with this distribution, you may find a copy at the FSF web
  ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
  ** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
  **
  ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
  ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
  ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
  ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
  ** REDISTRIBUTION OF THIS SOFTWARE. 
  ** 
  */
  
  package com.ice.tar;
  
  import java.io.*;
  
  /**
   * The TarArchive class implements the concept of a
   * tar archive. A tar archive is a series of entries, each of
   * which represents a file system object. Each entry in
   * the archive consists of a header record. Directory entries
   * consist only of the header record, and are followed by entries
   * for the directory's contents. File entries consist of a
   * header record followed by the number of records needed to
   * contain the file's contents. All entries are written on
   * record boundaries. Records are 512 bytes long.
   *
   * TarArchives are instantiated in either read or write mode,
   * based upon whether they are instantiated with an InputStream
   * or an OutputStream. Once instantiated TarArchives read/write
   * mode can not be changed.
   *
   * There is currently no support for random access to tar archives.
   * However, it seems that subclassing TarArchive, and using the
   * TarBuffer.getCurrentRecordNum() and TarBuffer.getCurrentBlockNum()
   * methods, this would be rather trvial.
   *
   * @version $Revision: 1.1 $
   * @author Timothy Gerard Endres,
   *  <a href="mailto:time@ice.com">time@ice.com</a>.
   * @see TarBuffer
   * @see TarHeader
   * @see TarEntry
   */
  
  
  public class
  TarArchive extends Object
  	{
  	public static final int		RECORDSIZE = 512;
  
  	protected boolean			verbose;
  	protected boolean			debug;
  	protected boolean			keepOldFiles;
  
  	protected int				userId;
  	protected String			userName;
  	protected int				groupId;
  	protected String			groupName;
  
  	protected String			pathPrefix;
  
  	protected int				recordSize;
  	protected byte[]			recordBuf;
  
  	protected TarBuffer			buffer;
  
  	protected TarProgressDisplay	progressDisplay;
  
  
  	public
  	TarArchive( InputStream inStream )
  		{
  		this( inStream, TarBuffer.DEFAULT_BLKSIZE );
  		}
  
  	public
  	TarArchive( InputStream inStream, int blockSize )
  		{
  		this( inStream, blockSize, TarArchive.RECORDSIZE );
  		}
  
  	public
  	TarArchive( InputStream inStream, int blockSize, int recordSize )
  		{
  		this.initialize( recordSize );
  		this.buffer = new TarBuffer( this, inStream, blockSize );
  		}
  
  	public
  	TarArchive( OutputStream outStream )
  		{
  		this( outStream, TarBuffer.DEFAULT_BLKSIZE );
  		}
  
  	public
  	TarArchive( OutputStream outStream, int blockSize )
  		{
  		this( outStream, blockSize, TarArchive.RECORDSIZE );
  		}
  
  	public
  	TarArchive( OutputStream outStream, int blockSize, int recordSize )
  		{
  		this.initialize( recordSize );
  		this.buffer = new TarBuffer( this, outStream, blockSize );
  		}
  
  	public void
  	initialize( int recordSize )
  		{
  		this.pathPrefix = null;
  		this.recordSize = recordSize;
  		this.recordBuf = new byte[ recordSize ];
  
  		this.userId = 0;
  		this.userName = "";
  		this.groupId = 0;
  		this.groupName = "";
  
  		this.debug = false;
  		this.verbose = false;
  		this.keepOldFiles = false;
  		this.progressDisplay = null;
  		}
  
  	public void
  	setDebug( boolean debugF )
  		{
  		this.debug = debugF;
  		}
  
  	public void
  	setBufferDebug( boolean debug )
  		{
  		this.buffer.setDebug( debug );
  		}
  
  	public boolean
  	isVerbose()
  		{
  		return this.verbose;
  		}
  
  	public void
  	setVerbose( boolean verbose )
  		{
  		this.verbose = verbose;
  		}
  
  	public void
  	setTarProgressDisplay( TarProgressDisplay display )
  		{
  		this.progressDisplay = display;
  		}
  
  	public void
  	setKeepOldFiles( boolean keepOldFiles )
  		{
  		this.keepOldFiles = keepOldFiles;
  		}
  
  	public void
  	setUserInfo(
  			int userId, String userName,
  			int groupId, String groupName )
  		{
  		this.userId = userId;
  		this.userName = userName;
  		this.groupId = groupId;
  		this.groupName = groupName;
  		}
  
  	public int
  	getUserId()
  		{
  		return this.userId;
  		}
  
  	public String
  	getUserName()
  		{
  		return this.userName;
  		}
  
  	public int
  	getGroupId()
  		{
  		return this.groupId;
  		}
  
  	public String
  	getGroupName()
  		{
  		return this.groupName;
  		}
  
  	public void
  	closeArchive()
  		throws IOException
  		{
  		this.buffer.flushBlock();
  		this.buffer.closeBuffer();
  		}
  
  	public int
  	getRecordSize()
  		{
  		return this.recordSize;
  		}
  
  	public TarEntry
  	parseArchive()
  		{
  		return null;
  		}
  
  	public TarEntry
  	parseEntry()
  		{
  		return null;
  		}
  
  	public void
  	extractArchive()
  		{
  		}
  
  	public void
  	listContents()
  		throws IOException, InvalidHeaderException
  		{
  		TarEntry	entry;
  		byte[]		headerBuf;
  
  		for ( ; ; )
  			{
  			headerBuf = this.buffer.readRecord();
  			if ( headerBuf == null )
  				{
  				if ( this.debug )
  					{
  					System.err.println( "READ NULL RECORD" );
  					}
  				break;
  				}
  
  			if ( this.isEOFRecord( headerBuf ) )
  				{
  				if ( this.debug )
  					{
  					System.err.println( "READ EOF RECORD" );
  					}
  				break;
  				}
  
  			try {
  				entry = new TarEntry( this, headerBuf );
  				}
  			catch ( InvalidHeaderException ex )
  				{
  				throw new InvalidHeaderException
  					( "bad header in block "
  						+ this.buffer.getCurrentBlockNum()
  						+ " record "
  						+ this.buffer.getCurrentRecordNum() );
  				}
  
  			if ( this.progressDisplay != null )
  				this.progressDisplay.showTarProgressMessage
  					( entry.getName() );
  
  			this.buffer.skipBytes( (int)entry.getSize() );
  			}
  		}
  
  	public void
  	extractContents( File destDir )
  		throws IOException, InvalidHeaderException
  		{
  		TarEntry	entry;
  		byte[]		headerBuf;
  
  		for ( ; ; )
  			{
  			headerBuf = this.buffer.readRecord();
  			if ( headerBuf == null )
  				{
  				if ( this.debug )
  					{
  					System.err.println( "READ NULL RECORD" );
  					}
  				break;
  				}
  
  			if ( this.isEOFRecord( headerBuf ) )
  				{
  				if ( this.debug )
  					{
  					System.err.println( "READ EOF RECORD" );
  					}
  				break;
  				}
  
  			try {
  				entry = new TarEntry( this, headerBuf );
  				}
  			catch ( InvalidHeaderException ex )
  				{
  				throw new InvalidHeaderException
  					( "bad header in block "
  						+ this.buffer.getCurrentBlockNum()
  						+ " record "
  						+ this.buffer.getCurrentRecordNum() );
  				}
  
  			this.extractEntry( destDir, entry );
  			}
  		}
  
  	public void
  	extractEntry( File destDir, TarEntry entry )
  		throws IOException
  		{
  		if ( this.verbose )
  			{
  			if ( this.progressDisplay != null )
  				this.progressDisplay.showTarProgressMessage
  					( entry.getName() );
  			}
  
  		File subDir =
  			new File( destDir, entry.getName() );
  
  		if ( entry.isDirectory() )
  			{
  			if ( ! subDir.exists() )
  				{
  				if ( ! subDir.mkdirs() )
  					{
  					throw new IOException
  						( "error making directory path '"
  							+ subDir.getPath() + "'" );
  					}
  				}
  			}
  		else
  			{
  			String name = entry.getName().toString();
  			name = name.replace( '/', File.separatorChar );
  
  			File destFile = new File( destDir, name );
  
  			if ( this.keepOldFiles && destFile.exists() )
  				{
  				if ( this.verbose )
  					{
  					if ( this.progressDisplay != null )
  						this.progressDisplay.showTarProgressMessage
  							( "not overwriting " + entry.getName() );
  					}
  				}
  			else
  				{
  				FileOutputStream out =
  					new FileOutputStream( destFile );
  
  				for ( int num = (int)entry.getSize() ; num > 0 ; )
  					{
  					byte[] record = this.buffer.readRecord();
  
  					int wNum =
  						( num < record.length )
  							? num : record.length;
  
  					out.write( record, 0, wNum );
  
  					num -= wNum;
  					}
  
  				out.close();
  				}
  			}
  		}
  
  	public boolean
  	isEOFRecord( byte[] record )
  		{
  		for ( int i = 0 ; i < this.recordSize ; ++i )
  			if ( record[i] != 0 )
  				return false;
  
  		return true;
  		}
  
  	public void
  	writeEOFRecord()
  		throws IOException
  		{
  		for ( int i = 0 ; i < this.recordSize ; ++i )
  			this.recordBuf[i] = 0;
  		this.buffer.writeRecord( this.recordBuf );
  		}
  
  	public void
  	writeEntry( TarEntry entry, boolean recurse )
  		throws IOException
  		{
  		if ( this.verbose )
  			{
  			if ( this.progressDisplay != null )
  				this.progressDisplay.showTarProgressMessage
  					( entry.getName() );
  			}
  
  		entry.writeEntryHeader( this.recordBuf );
  		this.buffer.writeRecord( this.recordBuf );
  
  		if ( entry.isDirectory() )
  			{
  			TarEntry[] list = entry.getDirectoryEntries();
  
  			for ( int i = 0 ; i < list.length ; ++i )
  				{
  				this.writeEntry( list[i], recurse );
  				}
  			}
  		else
  			{
  			entry.writeEntryContents( this.buffer );
  			}
  		}
  
  	public TarEntry
  	readEntry()
  		throws IOException, InvalidHeaderException
  		{
  		TarEntry result = null;
  
  		byte[] header = this.readRecord();
  
  		TarEntry entry = new TarEntry( this, header );
  
  		return entry;
  		}
  
  	public byte[]
  	readRecord()
  		throws IOException
  		{
  		return this.buffer.readRecord();
  		}
  
  	public void
  	writeRecord( byte[] record )
  		throws IOException
  		{
  		this.buffer.writeRecord( record );
  		}
  
  	}
  
  
  
  
  1.1                  jakarta-tools/ant/src/main/com/ice/tar/TarBuffer.java
  
  Index: TarBuffer.java
  ===================================================================
  /*
  ** Copyright (c) 1998 by Timothy Gerard Endres
  ** <mailto:time@ice.com>  <http://www.ice.com>
  ** 
  ** This package is free software.
  ** 
  ** You may redistribute it and/or modify it under the terms of the GNU
  ** General Public License as published by the Free Software Foundation.
  ** Version 2 of the license should be included with this distribution in
  ** the file LICENSE, as well as License.html. If the license is not
  ** included	with this distribution, you may find a copy at the FSF web
  ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
  ** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
  **
  ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
  ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
  ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
  ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
  ** REDISTRIBUTION OF THIS SOFTWARE. 
  ** 
  */
  
  package com.ice.tar;
  
  import java.io.*;
  
  
  /**
   * The TarBuffer class implements the tar archive concept
   * of a buffered input stream. This concept goes back to the
   * days of blocked tape drives and special io devices. In the
   * Java universe, the only real function that this class
   * performs is to ensure that files have the correct "block"
   * size, or other tars will complain.
   * <p>
   * You should never have a need to access this class directly.
   * TarBuffers are created by TarArchives, which in turn provide
   * several methods to allow you access to the buffer.
   *
   * @version $Revision: 1.1 $
   * @author Timothy Gerard Endres,
   *  <a href="mailto:time@ice.com">time@ice.com</a>.
   * @see TarArchive
   */
  
  public class
  TarBuffer extends Object
  	{
  	public static final int		DEFAULT_BLKSIZE = ( 512 * 20 );
  
  	private InputStream		inStream;
  	private OutputStream	outStream;
  
  	private byte[]	blockBuffer;
  	private int		currBlkIdx;
  	private int		currRecIdx;
  	private int		blockSize;
  	private int		recordSize;
  	private int		recsPerBlock;
  
  	private boolean	debug;
  
  
  	public
  	TarBuffer( TarArchive archive, InputStream inStream )
  		{
  		this( archive, inStream, TarBuffer.DEFAULT_BLKSIZE );
  		}
  
  	public
  	TarBuffer( TarArchive archive, InputStream inStream, int blockSize )
  		{
  		this.inStream = inStream;
  		this.outStream = null;
  		this.initialize( archive, blockSize );
  		}
  
  	public
  	TarBuffer( TarArchive archive, OutputStream outStream )
  		{
  		this( archive, outStream, TarBuffer.DEFAULT_BLKSIZE );
  		}
  
  	public
  	TarBuffer( TarArchive archive, OutputStream outStream, int blockSize )
  		{
  		this.inStream = null;
  		this.outStream = outStream;
  		this.initialize( archive, blockSize );
  		}
  
  	public void
  	initialize( TarArchive archive, int blockSize )
  		{
  		this.debug = false;
  		this.blockSize = blockSize;
  		this.recordSize = archive.getRecordSize();
  		this.recsPerBlock = ( this.blockSize / this.recordSize );
  		this.blockBuffer = new byte[ this.blockSize ];
  
  		if ( inStream != null )
  			{
  			this.currBlkIdx = -1;
  			this.currRecIdx = this.recsPerBlock;
  			}
  		else
  			{
  			this.currBlkIdx = 0;
  			this.currRecIdx = 0;
  			}
  		}
  
  	public void
  	setDebug( boolean debug )
  		{
  		this.debug = debug;
  		}
  
  	public void
  	skipBytes( int bytes )
  		{
  		for ( int num = bytes ; num > 0 ; )
  			{
  			try { this.skipRecord(); }
  			catch ( IOException ex )
  				{
  				break;
  				}
  			num -= this.recordSize;
  			}
  		}
  
  	public void
  	skipRecord()
  		throws IOException
  		{
  		if ( this.debug )
  			{
  			System.err.println
  				( "SkipRecord: recIdx = " + this.currRecIdx
  					+ " blkIdx = " + this.currBlkIdx );
  			}
  
  		if ( this.currRecIdx >= this.recsPerBlock )
  			{
  			if ( ! this.readBlock() )
  				return; // UNDONE
  			}
  
  		this.currRecIdx++;
  		}
  
  	public byte[]
  	readRecord()
  		throws IOException
  		{
  		if ( this.debug )
  			{
  			System.err.println
  				( "ReadRecord: recIdx = " + this.currRecIdx
  					+ " blkIdx = " + this.currBlkIdx );
  			}
  
  		if ( this.currRecIdx >= this.recsPerBlock )
  			{
  			if ( ! this.readBlock() )
  				return null;
  			}
  
  		byte[] result = new byte[ this.recordSize ];
  
  		System.arraycopy(
  			this.blockBuffer, (this.currRecIdx * this.recordSize),
  			result, 0, this.recordSize );
  
  		this.currRecIdx++;
  
  		return result;
  		}
  
  	/**
  	 * @return false if End-Of-File, else true
  	 */
  
  	public boolean
  	readBlock()
  		throws IOException
  		{
  		if ( this.debug )
  			{
  			System.err.println
  				( "ReadBlock: blkIdx = " + this.currBlkIdx );
  			}
  
  		if ( this.inStream == null )
  			throw new IOException( "input stream is null" );
  
  		this.currRecIdx = 0;
  
  		int offset = 0;
  		int bytesNeeded = this.blockSize;
  		for ( ; bytesNeeded > 0 ; )
  			{
  			long numBytes =
  				this.inStream.read
  					( this.blockBuffer, offset, bytesNeeded );
  
  			if ( numBytes == -1 )
  				return false;
  
  			offset += numBytes;
  			bytesNeeded -= numBytes;
  			if ( numBytes != this.blockSize )
  				{
  				if ( this.debug )
  					{
  					System.err.println
  						( "ReadBlock: INCOMPLETE READ " + numBytes
  							+ " of " + this.blockSize + " bytes read." );
  					}
  				}
  			}
  
  		this.currBlkIdx++;
  
  		return true;
  		}
  
  	public int
  	getCurrentBlockNum()
  		{
  		return this.currBlkIdx;
  		}
  
  	public int
  	getCurrentRecordNum()
  		{
  		return this.currRecIdx - 1;
  		}
  
  	public void
  	writeRecord( byte[] record )
  		throws IOException
  		{
  		if ( this.debug )
  			{
  			System.err.println
  				( "WriteRecord: recIdx = " + this.currRecIdx
  					+ " blkIdx = " + this.currBlkIdx );
  			}
  
  		if ( this.currRecIdx >= this.recsPerBlock )
  			{
  			this.writeBlock();
  			}
  
  		System.arraycopy(
  			record, 0,
  			this.blockBuffer, (this.currRecIdx * this.recordSize),
  			this.recordSize );
  
  		this.currRecIdx++;
  		}
  
  	public void
  	writeBlock()
  		throws IOException
  		{
  		if ( this.debug )
  			{
  			System.err.println
  				( "WriteBlock: blkIdx = " + this.currBlkIdx );
  			}
  
  		if ( this.outStream == null )
  			throw new IOException( "output stream is null" );
  
  		this.outStream.write( this.blockBuffer, 0, this.blockSize );
  
  		this.currRecIdx = 0;
  		this.currBlkIdx++;
  		}
  
  	public void
  	flushBlock()
  		throws IOException
  		{
  		if ( this.debug )
  			{
  			System.err.println( "TarBuffer.flushBlock() called." );
  			}
  
  		if ( this.outStream != null )
  			{
  			if ( this.currRecIdx > 0 )
  				{
  				this.writeBlock();
  				}
  			}
  		}
  
  	public void
  	closeBuffer()
  		throws IOException
  		{
  		if ( this.debug )
  			{
  			System.err.println( "TarBuffer.closeBuffer()." );
  			}
  
  		if ( this.outStream != null )
  			{
  			if ( this.outStream != System.out
  					&& this.outStream != System.err )
  				{
  				this.outStream.close();
  				this.outStream = null;
  				}
  			}
  		else if ( this.inStream != null )
  			{
  			if ( this.inStream != System.in )
  				{
  				this.inStream.close();
  				this.inStream = null;
  				}
  			}
  		}
  
  	}
  
  
  
  
  1.1                  jakarta-tools/ant/src/main/com/ice/tar/TarEntry.java
  
  Index: TarEntry.java
  ===================================================================
  /*
  ** Copyright (c) 1998 by Timothy Gerard Endres
  ** <mailto:time@ice.com>  <http://www.ice.com>
  ** 
  ** This package is free software.
  ** 
  ** You may redistribute it and/or modify it under the terms of the GNU
  ** General Public License as published by the Free Software Foundation.
  ** Version 2 of the license should be included with this distribution in
  ** the file LICENSE, as well as License.html. If the license is not
  ** included	with this distribution, you may find a copy at the FSF web
  ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
  ** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
  **
  ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
  ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
  ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
  ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
  ** REDISTRIBUTION OF THIS SOFTWARE. 
  ** 
  */
  
  package com.ice.tar;
  
  import java.io.*;
  
  
  /**
   *
   *
   * struct header {
   *		char	name[NAMSIZ];
   *		char	mode[8];
   *		char	uid[8];
   *		char	gid[8];
   *		char	size[12];
   *		char	mtime[12];
   *		char	chksum[8];
   *		char	linkflag;
   *		char	linkname[NAMSIZ];
   *		char	magic[8];
   *		char	uname[TUNMLEN];
   *		char	gname[TGNMLEN];
   *		char	devmajor[8];
   *		char	devminor[8];
   *	} header;
   *
   */
  
  public class
  TarEntry extends Object
  	{
  	protected TarArchive	archive;
  	protected TarHeader		header;
  	protected File			file;
  
  
  	public
  	TarEntry( TarArchive archive, File file )
  		{
  		this.archive = archive;
  		this.file = file;
  		this.header = this.getFileTarHeader( file );
  		}
  
  	public
  	TarEntry( TarArchive archive, byte[] headerBuf )
  		throws InvalidHeaderException
  		{
  		this.archive = archive;
  		this.file = null;
  		this.header = this.parseTarHeader( headerBuf );
  		}
  
  	public TarArchive
  	getArchive()
  		{
  		return this.archive;
  		}
  
  	public File
  	getFile()
  		{
  		return this.file;
  		}
  
  	public TarHeader
  	getHeader()
  		{
  		return this.header;
  		}
  
  	public String
  	getName()
  		{
  		return this.header.name.toString();
  		}
  
  	public long
  	getSize()
  		{
  		return this.header.size;
  		}
  
  	public TarHeader
  	getFileTarHeader( File file )
  		{
  		TarHeader hdr = new TarHeader();
  
  		String name = file.getPath();
  		String osname = System.getProperty( "os.name" );
  		
  		if ( osname != null )
  			{
  			if ( osname.startsWith( "macos" ) )
  				{
  				// UNDONE
  				}
  			else if ( osname.startsWith( "Windows" ) )
  				{
  				if ( name.length() > 2 )
  					{
  					char ch1 = name.charAt(0);
  					char ch2 = name.charAt(1);
  					if ( ch2 == File.separatorChar
  						&& ( (ch1 >= 'a' && ch1 <= 'z')
  							|| (ch1 >= 'a' && ch1 <= 'z') ) )
  						{
  						name = name.substring( 2 );
  						}
  					}
  				}
  			}
  
  		hdr.name =
  			new StringBuffer
  				( name.replace( File.separatorChar, '/' ) );
  
  		if ( file.isDirectory() )
  			{
  			hdr.mode = 040755;
  			hdr.linkFlag = TarHeader.LF_DIR;
  			hdr.name.append( "/" );
  			}
  		else
  			{
  			hdr.mode = 0100644;
  			hdr.linkFlag = TarHeader.LF_NORMAL;
  			}
  
  		hdr.userId = this.archive.getUserId();
  		hdr.groupId = this.archive.getGroupId();
  		hdr.size = file.length();
  		hdr.modTime = file.lastModified() / 1000;
  		hdr.checkSum = 0;
  
  		hdr.linkName = new StringBuffer( "" );
  
  		hdr.magic = new StringBuffer( TarHeader.TMAGIC );
  
  		String userName = this.archive.getUserName();
  
  		if ( userName == null )
  			userName = System.getProperty( "user.name", "" );
  
  		if ( userName.length() > 31 )
  			userName = userName.substring( 0, 32 );
  
  		hdr.userName = new StringBuffer( userName );
  
  		String grpName = this.archive.getGroupName();
  
  		if ( grpName == null )
  			grpName = "";
  
  		if ( grpName.length() > 31 )
  			grpName = grpName.substring( 0, 32 );
  
  		hdr.groupName = new StringBuffer( grpName );
  
  		hdr.devMajor = 0;
  		hdr.devMinor = 0;
  
  		return hdr;
  		}
  
  	public boolean
  	isDirectory()
  		{
  		if ( this.file != null )
  			return this.file.isDirectory();
  
  		if ( this.header != null )
  			{
  			if ( this.header.linkFlag == TarHeader.LF_DIR )
  				return true;
  
  			if ( this.header.name.toString().endsWith( "/" ) )
  				return true;
  			}
  
  		return false;
  		}
  
  	public TarEntry[]
  	getDirectoryEntries()
  		{
  		if ( this.file == null
  				|| ! this.file.isDirectory() )
  			{
  			return new TarEntry[0];
  			}
  
  		String[] list = this.file.list();
  
  		TarEntry[] result = new TarEntry[ list.length ];
  
  		for ( int i = 0 ; i < list.length ; ++i )
  			{
  			result[i] =
  				new TarEntry
  					( this.archive,
  						new File( this.file, list[i] ) );
  			}
  
  		return result;
  		}
  
  	public long
  	computeCheckSum( byte[] buf )
  		{
  		long sum = 0;
  
  		for ( int i = 0 ; i < buf.length ; ++i )
  			{
  			sum += 255 & buf[ i ];
  			}
  
  		return sum;
  		}
  
  	public void
  	writeEntryHeader( byte[] outbuf )
  		{
  		int offset = 0;
  
  		offset = TarHeader.getNameBytes
  			( this.header.name, outbuf, offset, TarHeader.NAMELEN );
  
  		offset = TarHeader.getOctalBytes
  			( this.header.mode, outbuf, offset, TarHeader.MODELEN );
  
  		offset = TarHeader.getOctalBytes
  			( this.header.userId, outbuf, offset, TarHeader.UIDLEN );
  
  		offset = TarHeader.getOctalBytes
  			( this.header.groupId, outbuf, offset, TarHeader.GIDLEN );
  
  		offset = TarHeader.getLongOctalBytes
  			( this.header.size, outbuf, offset, TarHeader.SIZELEN );
  
  		offset = TarHeader.getLongOctalBytes
  			( this.header.modTime, outbuf, offset, TarHeader.MODTIMELEN );
  
  		int csOffset = offset;
  		for ( int c = 0 ; c < TarHeader.CHKSUMLEN ; ++c )
  			outbuf[ offset++ ] = new Byte(" ").byteValue();
  
      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 = TarHeader.getOctalBytes
  			( this.header.devMajor, outbuf, offset, TarHeader.DEVLEN );
  
  		offset = TarHeader.getOctalBytes
  			( this.header.devMinor, outbuf, offset, TarHeader.DEVLEN );
  
  		long checkSum = this.computeCheckSum( outbuf );
  
  		TarHeader.getCheckSumOctalBytes
  			( checkSum, outbuf, csOffset, TarHeader.CHKSUMLEN );
  		}
  
  	public void
  	writeEntryContents( TarBuffer buffer )
  		throws IOException
  		{
  		if ( this.file == null )
  			throw new IOException( "file is null" );
  
  		if ( ! this.file.exists() )
  			throw new IOException
  				( "file '" + this.file.getPath()
  					+ "' does not exist" );
  
  		// UNDONE - handle ASCII line termination translation!!!!
  
  		FileInputStream in =
  			new FileInputStream( this.file );
  
  		int recSize = this.archive.getRecordSize();
  
  		byte[] recbuf = new byte[ recSize ];
  
  		for ( ; ; )
  			{
  			int num = in.read( recbuf, 0, recSize );
  			if ( num == -1 )
  				break;
  
  			if ( num < recSize )
  				{
  				for ( int j = num ; j < recSize ; ++j )
  					recbuf[j] = 0;
  				}
  
  			buffer.writeRecord( recbuf );
  			}
  
  		in.close();
  		}
  
  	public TarHeader
  	parseTarHeader( byte[] header )
  		throws InvalidHeaderException
  		{
  		TarHeader hdr = new TarHeader();
  
  		int offset = 0;
  
  		hdr.name =
  			TarHeader.parseName( header, offset, TarHeader.NAMELEN );
  
  		offset += TarHeader.NAMELEN;
  
  		hdr.mode = (int)
  			TarHeader.parseOctal( header, offset, TarHeader.MODELEN );
  
  		offset += TarHeader.MODELEN;
  
  		hdr.userId = (int)
  			TarHeader.parseOctal( header, offset, TarHeader.UIDLEN );
  
  		offset += TarHeader.UIDLEN;
  
  		hdr.groupId = (int)
  			TarHeader.parseOctal( header, offset, TarHeader.GIDLEN );
  
  		offset += TarHeader.GIDLEN;
  
  		hdr.size =
  			TarHeader.parseOctal( header, offset, TarHeader.SIZELEN );
  
  		offset += TarHeader.SIZELEN;
  
  		hdr.modTime =
  			TarHeader.parseOctal( header, offset, TarHeader.MODTIMELEN );
  
  		offset += TarHeader.MODTIMELEN;
  
  		hdr.checkSum = (int)
  			TarHeader.parseOctal( header, offset, TarHeader.CHKSUMLEN );
  
  		offset += TarHeader.CHKSUMLEN;
  
  		hdr.linkFlag = header[ offset++ ];
  
  		hdr.linkName =
  			TarHeader.parseName( header, offset, TarHeader.NAMELEN );
  
  		offset += TarHeader.NAMELEN;
  
  		hdr.magic =
  			TarHeader.parseName( header, offset, TarHeader.MAGICLEN );
  
  		offset += TarHeader.MAGICLEN;
  
  		hdr.userName =
  			TarHeader.parseName( header, offset, TarHeader.UNAMELEN );
  
  		offset += TarHeader.UNAMELEN;
  
  		hdr.groupName =
  			TarHeader.parseName( header, offset, TarHeader.GNAMELEN );
  
  		offset += TarHeader.GNAMELEN;
  
  		hdr.devMajor = (int)
  			TarHeader.parseOctal( header, offset, TarHeader.DEVLEN );
  
  		offset += TarHeader.DEVLEN;
  
  		hdr.devMinor = (int)
  			TarHeader.parseOctal( header, offset, TarHeader.DEVLEN );
  
  		return hdr;
  		}
  
  	}
  
  
  
  
  1.1                  jakarta-tools/ant/src/main/com/ice/tar/TarHeader.java
  
  Index: TarHeader.java
  ===================================================================
  /*
  ** Copyright (c) 1998 by Timothy Gerard Endres
  ** <mailto:time@ice.com>  <http://www.ice.com>
  ** 
  ** This package is free software.
  ** 
  ** You may redistribute it and/or modify it under the terms of the GNU
  ** General Public License as published by the Free Software Foundation.
  ** Version 2 of the license should be included with this distribution in
  ** the file LICENSE, as well as License.html. If the license is not
  ** included	with this distribution, you may find a copy at the FSF web
  ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
  ** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
  **
  ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
  ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
  ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
  ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
  ** REDISTRIBUTION OF THIS SOFTWARE. 
  ** 
  */
  
  package com.ice.tar;
  
  
  public class
  TarHeader extends Object
  	{
  	public static final int		NAMELEN = 100;
  	public static final int		MODELEN = 8;
  	public static final int		UIDLEN = 8;
  	public static final int		GIDLEN = 8;
  	public static final int		CHKSUMLEN = 8;
  	public static final int		SIZELEN = 12;
  	public static final int		MAGICLEN = 8;
  	public static final int		MODTIMELEN = 12;
  	public static final int		UNAMELEN = 32;
  	public static final int		GNAMELEN = 32;
  	public static final int		DEVLEN = 8;
  
  	public static final byte	LF_OLDNORM	= 0;
  	public static final byte	LF_NORMAL	= new Byte("0").byteValue();
  	public static final byte	LF_LINK		= new Byte("1").byteValue();
  	public static final byte	LF_SYMLINK	= new Byte("2").byteValue();
  	public static final byte	LF_CHR		= new Byte("3").byteValue();
  	public static final byte	LF_BLK		= new Byte("4").byteValue();
  	public static final byte	LF_DIR		= new Byte("5").byteValue();
  	public static final byte	LF_FIFO		= new Byte("6").byteValue();
  	public static final byte	LF_CONTIG	= new Byte("7").byteValue();
  
  	public static final String	TMAGIC		= "ustar  ";
  
  	public StringBuffer		name;
  	public int				mode;
  	public int				userId;
  	public int				groupId;
  	public long				size;
  	public long				modTime;
  	public int				checkSum;
  	public byte				linkFlag;
  	public StringBuffer		linkName;
  	public StringBuffer		magic;
  	public StringBuffer		userName;
  	public StringBuffer		groupName;
  	public int				devMajor;
  	public int				devMinor;
  
  	public
  	TarHeader()
  		{
  		}
  
  	public static long
  	parseOctal( byte[] header, int offset, int length )
  		throws InvalidHeaderException
  		{
  		long result = 0;
  		boolean stillPadding = true;
  
  		int end = offset + length;
  		for ( int i = offset ; i < end ; ++i )
  			{
  			if ( header[i] == 0 )
  				break;
  
  			if ( header[i] == ' ' || header[i] == '0' )
  				{
  				if ( stillPadding )
  					continue;
  
  				if ( header[i] == ' ' )
  					break;
  				}
  			
  			stillPadding = false;
  
  			result =
  				(result << 3)
  					+ (header[i] - '0');
  			}
  
  		return result;
  		}
  
  	public static StringBuffer
  	parseName( byte[] header, int offset, int length )
  		throws InvalidHeaderException
  		{
  		StringBuffer result = new StringBuffer( length );
  
  		int end = offset + length;
  		for ( int i = offset ; i < end ; ++i )
  			{
  			if ( header[i] == 0 )
  				break;
  			result.append( (char)header[i] );
  			}
  
  		return result;
  		}
  
  	public static int
  	getNameBytes( StringBuffer name, byte[] buf, int offset, int length )
  		{
  		int i;
  
  		for ( i = 0 ; i < length && i < name.length() ; ++i )
  			{
  			buf[ offset + i ] = (byte)name.charAt( i );
  			}
  
  		for ( ; i < length ; ++i )
  			{
  			buf[ offset + i ] = 0;
  			}
  
  		return offset + length;
  		}
  
  	public static int
  	getOctalBytes( long value, byte[] buf, int offset, int length )
  		{
  		byte[] result = new byte[ length ];
  
  		int idx = length - 1;
  
  		buf[ offset + idx ] = 0;
  		--idx;
  		buf[ offset + idx ] = new Byte(" ").byteValue();
  		--idx;
  
  		if ( value == 0 )
  			{
  			buf[ offset + idx ] = new Byte("0").byteValue();
  			--idx;
  			}
  		else
  			{
  			for ( long val = value ; idx >= 0 && val > 0 ; --idx )
  				{
  				buf[ offset + idx ] =
  					(byte) ( '0' + (val & 7) );
  				val = val >> 3;
  				}
  			}
  
  		for ( ; idx >= 0 ; --idx )
  			{
  			buf[ offset + idx ] = new Byte(" ").byteValue();
  			}
  
  		return offset + length;
  		}
  
  	public static int
  	getLongOctalBytes( long value, byte[] buf, int offset, int length )
  		{
  		byte[] temp = new byte[ length + 1 ];
  		TarHeader.getOctalBytes( value, temp, 0, length + 1 );
  		System.arraycopy( temp, 0, buf, offset, length );
  		return offset + length;
  		}
  
  	public static int
  	getCheckSumOctalBytes( long value, byte[] buf, int offset, int length )
  		{
  		TarHeader.getOctalBytes( value, buf, offset, length );
  		buf[ offset + length - 1 ] = new Byte(" ").byteValue();
  		buf[ offset + length - 2 ] = 0;
  		return offset + length;
  		}
  
  	public String
  	getName()
  		{
  		return this.name.toString();
  		}
  
  	}
   
  
  
  
  1.1                  jakarta-tools/ant/src/main/com/ice/tar/TarProgressDisplay.java
  
  Index: TarProgressDisplay.java
  ===================================================================
  /*
  ** Copyright (c) 1998 by Timothy Gerard Endres
  ** <mailto:time@ice.com>  <http://www.ice.com>
  ** 
  ** This package is free software.
  ** 
  ** You may redistribute it and/or modify it under the terms of the GNU
  ** General Public License as published by the Free Software Foundation.
  ** Version 2 of the license should be included with this distribution in
  ** the file LICENSE, as well as License.html. If the license is not
  ** included	with this distribution, you may find a copy at the FSF web
  ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
  ** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
  **
  ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
  ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
  ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
  ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
  ** REDISTRIBUTION OF THIS SOFTWARE. 
  ** 
  */
  
  package com.ice.tar;
  
  
  public interface
  TarProgressDisplay
  	{
  	public void
  		showTarProgressMessage( String msg );
  	}
  
  
  
  

Mime
View raw message