PageRenderTime 53ms CodeModel.GetById 32ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre14/installer/TarHeader.java

#
Java | 422 lines | 196 code | 42 blank | 184 comment | 27 complexity | 55ea734223d5ef54bffde8564a9ba65b MD5 | raw file
  1/*
  2** Authored by Timothy Gerard Endres
  3** <mailto:time@gjt.org>  <http://www.trustice.com>
  4** 
  5** This work has been placed into the public domain.
  6** You may use this work in any way and for any purpose you wish.
  7**
  8** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
  9** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
 10** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
 11** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
 12** REDISTRIBUTION OF THIS SOFTWARE. 
 13** 
 14*/
 15
 16package installer;
 17
 18/**
 19 * This class encapsulates the Tar Entry Header used in Tar Archives.
 20 * The class also holds a number of tar constants, used mostly in headers.
 21 */
 22
 23public class
 24TarHeader extends Object
 25	{
 26	/**
 27	 * The length of the name field in a header buffer.
 28	 */
 29	public static final int		NAMELEN = 100;
 30	/**
 31	 * The length of the mode field in a header buffer.
 32	 */
 33	public static final int		MODELEN = 8;
 34	/**
 35	 * The length of the user id field in a header buffer.
 36	 */
 37	public static final int		UIDLEN = 8;
 38	/**
 39	 * The length of the group id field in a header buffer.
 40	 */
 41	public static final int		GIDLEN = 8;
 42	/**
 43	 * The length of the checksum field in a header buffer.
 44	 */
 45	public static final int		CHKSUMLEN = 8;
 46	/**
 47	 * The length of the size field in a header buffer.
 48	 */
 49	public static final int		SIZELEN = 12;
 50	/**
 51	 * The length of the magic field in a header buffer.
 52	 */
 53	public static final int		MAGICLEN = 8;
 54	/**
 55	 * The length of the modification time field in a header buffer.
 56	 */
 57	public static final int		MODTIMELEN = 12;
 58	/**
 59	 * The length of the user name field in a header buffer.
 60	 */
 61	public static final int		UNAMELEN = 32;
 62	/**
 63	 * The length of the group name field in a header buffer.
 64	 */
 65	public static final int		GNAMELEN = 32;
 66	/**
 67	 * The length of the devices field in a header buffer.
 68	 */
 69	public static final int		DEVLEN = 8;
 70
 71	/**
 72	 * LF_ constants represent the "link flag" of an entry, or more commonly,
 73	 * the "entry type". This is the "old way" of indicating a normal file.
 74	 */
 75	public static final byte	LF_OLDNORM	= 0;
 76	/**
 77	 * Normal file type.
 78	 */
 79	public static final byte	LF_NORMAL	= (byte) '0';
 80	/**
 81	 * Link file type.
 82	 */
 83	public static final byte	LF_LINK		= (byte) '1';
 84	/**
 85	 * Symbolic link file type.
 86	 */
 87	public static final byte	LF_SYMLINK	= (byte) '2';
 88	/**
 89	 * Character device file type.
 90	 */
 91	public static final byte	LF_CHR		= (byte) '3';
 92	/**
 93	 * Block device file type.
 94	 */
 95	public static final byte	LF_BLK		= (byte) '4';
 96	/**
 97	 * Directory file type.
 98	 */
 99	public static final byte	LF_DIR		= (byte) '5';
100	/**
101	 * FIFO (pipe) file type.
102	 */
103	public static final byte	LF_FIFO		= (byte) '6';
104	/**
105	 * Contiguous file type.
106	 */
107	public static final byte	LF_CONTIG	= (byte) '7';
108
109	/**
110	 * The magic tag representing a POSIX tar archive.
111	 */
112	public static final String	TMAGIC		= "ustar";
113
114	/**
115	 * The magic tag representing a GNU tar archive.
116	 */
117	public static final String	GNU_TMAGIC	= "ustar  ";
118
119	/**
120	 * The entry's name.
121	 */
122	public StringBuffer		name;
123	/**
124	 * The entry's permission mode.
125	 */
126	public int				mode;
127	/**
128	 * The entry's user id.
129	 */
130	public int				userId;
131	/**
132	 * The entry's group id.
133	 */
134	public int				groupId;
135	/**
136	 * The entry's size.
137	 */
138	public long				size;
139	/**
140	 * The entry's modification time.
141	 */
142	public long				modTime;
143	/**
144	 * The entry's checksum.
145	 */
146	public int				checkSum;
147	/**
148	 * The entry's link flag.
149	 */
150	public byte				linkFlag;
151	/**
152	 * The entry's link name.
153	 */
154	public StringBuffer		linkName;
155	/**
156	 * The entry's magic tag.
157	 */
158	public StringBuffer		magic;
159	/**
160	 * The entry's user name.
161	 */
162	public StringBuffer		userName;
163	/**
164	 * The entry's group name.
165	 */
166	public StringBuffer		groupName;
167	/**
168	 * The entry's major device number.
169	 */
170	public int				devMajor;
171	/**
172	 * The entry's minor device number.
173	 */
174	public int				devMinor;
175
176
177	public
178	TarHeader()
179		{
180		this.magic = new StringBuffer( TarHeader.TMAGIC );
181
182		this.name = new StringBuffer();
183		this.linkName = new StringBuffer();
184
185		String user =
186			System.getProperty( "user.name", "" );
187
188		if ( user.length() > 31 )
189			user = user.substring( 0, 31 );
190
191		this.userId = 0;
192		this.groupId = 0;
193		this.userName = new StringBuffer( user );
194		this.groupName = new StringBuffer( "" );
195		}
196
197	/**
198	 * TarHeaders can be cloned.
199	 */
200	public Object
201	clone()
202		{
203		TarHeader hdr = null;
204
205		try {
206			hdr = (TarHeader) super.clone();
207
208			hdr.name =
209				(this.name == null ) ? null
210					: new StringBuffer( this.name.toString() );
211			hdr.mode = this.mode;
212			hdr.userId = this.userId;
213			hdr.groupId = this.groupId;
214			hdr.size = this.size;
215			hdr.modTime = this.modTime;
216			hdr.checkSum = this.checkSum;
217			hdr.linkFlag = this.linkFlag;
218			hdr.linkName =
219				(this.linkName == null ) ? null
220					: new StringBuffer( this.linkName.toString() );
221			hdr.magic =
222				(this.magic == null ) ? null
223					: new StringBuffer( this.magic.toString() );
224			hdr.userName =
225				(this.userName == null ) ? null
226					: new StringBuffer( this.userName.toString() );
227			hdr.groupName =
228				(this.groupName == null ) ? null
229					: new StringBuffer( this.groupName.toString() );
230			hdr.devMajor = this.devMajor;
231			hdr.devMinor = this.devMinor;
232			}
233		catch ( CloneNotSupportedException ex )
234			{
235			ex.printStackTrace();
236			}
237
238		return hdr;
239		}
240
241	/**
242	 * Get the name of this entry.
243	 *
244	 * @return Teh entry's name.
245	 */
246	public String
247	getName()
248		{
249		return this.name.toString();
250		}
251
252	/**
253	 * Parse an octal string from a header buffer. This is used for the
254	 * file permission mode value.
255	 *
256	 * @param header The header buffer from which to parse.
257	 * @param offset The offset into the buffer from which to parse.
258	 * @param length The number of header bytes to parse.
259	 * @return The long value of the octal string.
260	 */
261	public static long
262	parseOctal( byte[] header, int offset, int length )
263		throws InvalidHeaderException
264		{
265		long result = 0;
266		boolean stillPadding = true;
267
268		int end = offset + length;
269		for ( int i = offset ; i < end ; ++i )
270			{
271			if ( header[i] == 0 )
272				break;
273
274			if ( header[i] == (byte) ' ' || header[i] == '0' )
275				{
276				if ( stillPadding )
277					continue;
278
279				if ( header[i] == (byte) ' ' )
280					break;
281				}
282			
283			stillPadding = false;
284
285			result =
286				(result << 3)
287					+ (header[i] - '0');
288			}
289
290		return result;
291		}
292
293	/**
294	 * Parse an entry name from a header buffer.
295	 *
296	 * @param header The header buffer from which to parse.
297	 * @param offset The offset into the buffer from which to parse.
298	 * @param length The number of header bytes to parse.
299	 * @return The header's entry name.
300	 */
301	public static StringBuffer
302	parseName( byte[] header, int offset, int length )
303		throws InvalidHeaderException
304		{
305		StringBuffer result = new StringBuffer( length );
306
307		int end = offset + length;
308		for ( int i = offset ; i < end ; ++i )
309			{
310			if ( header[i] == 0 )
311				break;
312			result.append( (char)header[i] );
313			}
314
315		return result;
316		}
317
318	/**
319	 * Determine the number of bytes in an entry name.
320	 *
321	 * @param header The header buffer from which to parse.
322	 * @param offset The offset into the buffer from which to parse.
323	 * @param length The number of header bytes to parse.
324	 * @return The number of bytes in a header's entry name.
325	 */
326	public static int
327	getNameBytes( StringBuffer name, byte[] buf, int offset, int length )
328		{
329		int i;
330
331		for ( i = 0 ; i < length && i < name.length() ; ++i )
332			{
333			buf[ offset + i ] = (byte) name.charAt( i );
334			}
335
336		for ( ; i < length ; ++i )
337			{
338			buf[ offset + i ] = 0;
339			}
340
341		return offset + length;
342		}
343
344	/**
345	 * Parse an octal integer from a header buffer.
346	 *
347	 * @param header The header buffer from which to parse.
348	 * @param offset The offset into the buffer from which to parse.
349	 * @param length The number of header bytes to parse.
350	 * @return The integer value of the octal bytes.
351	 */
352	public static int
353	getOctalBytes( long value, byte[] buf, int offset, int length )
354		{
355		byte[] result = new byte[ length ];
356
357		int idx = length - 1;
358
359		buf[ offset + idx ] = 0;
360		--idx;
361		buf[ offset + idx ] = (byte) ' ';
362		--idx;
363
364		if ( value == 0 )
365			{
366			buf[ offset + idx ] = (byte) '0';
367			--idx;
368			}
369		else
370			{
371			for ( long val = value ; idx >= 0 && val > 0 ; --idx )
372				{
373				buf[ offset + idx ] = (byte)
374					( (byte) '0' + (byte) (val & 7) );
375				val = val >> 3;
376				}
377			}
378
379		for ( ; idx >= 0 ; --idx )
380			{
381			buf[ offset + idx ] = (byte) ' ';
382			}
383
384		return offset + length;
385		}
386
387	/**
388	 * Parse an octal long integer from a header buffer.
389	 *
390	 * @param header The header buffer from which to parse.
391	 * @param offset The offset into the buffer from which to parse.
392	 * @param length The number of header bytes to parse.
393	 * @return The long value of the octal bytes.
394	 */
395	public static int
396	getLongOctalBytes( long value, byte[] buf, int offset, int length )
397		{
398		byte[] temp = new byte[ length + 1 ];
399		TarHeader.getOctalBytes( value, temp, 0, length + 1 );
400		System.arraycopy( temp, 0, buf, offset, length );
401		return offset + length;
402		}
403
404	/**
405	 * Parse the checksum octal integer from a header buffer.
406	 *
407	 * @param header The header buffer from which to parse.
408	 * @param offset The offset into the buffer from which to parse.
409	 * @param length The number of header bytes to parse.
410	 * @return The integer value of the entry's checksum.
411	 */
412	public static int
413	getCheckSumOctalBytes( long value, byte[] buf, int offset, int length )
414		{
415		TarHeader.getOctalBytes( value, buf, offset, length );
416		buf[ offset + length - 1 ] = (byte) ' ';
417		buf[ offset + length - 2 ] = 0;
418		return offset + length;
419		}
420
421	}
422