PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

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

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