1
+ /**
2
+ * Copyright 2012 Kamran Zafar
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ package org .kamranzafar .jtar ;
19
+
20
+ import java .io .File ;
21
+ import java .util .Date ;
22
+
23
+ /**
24
+ * @author Kamran Zafar
25
+ *
26
+ */
27
+ public class TarEntry {
28
+ protected File file ;
29
+ protected TarHeader header ;
30
+
31
+ private TarEntry () {
32
+ this .file = null ;
33
+ header = new TarHeader ();
34
+ }
35
+
36
+ public TarEntry (File file , String entryName ) {
37
+ this ();
38
+ this .file = file ;
39
+ this .extractTarHeader (entryName );
40
+ }
41
+
42
+ public TarEntry (byte [] headerBuf ) {
43
+ this ();
44
+ this .parseTarHeader (headerBuf );
45
+ }
46
+
47
+ /**
48
+ * Constructor to create an entry from an existing TarHeader object.
49
+ *
50
+ * This method is useful to add new entries programmatically (e.g. for
51
+ * adding files or directories that do not exist in the file system).
52
+ *
53
+ * @param header
54
+ *
55
+ */
56
+ public TarEntry (TarHeader header ) {
57
+ this .file = null ;
58
+ this .header = header ;
59
+ }
60
+
61
+ public boolean equals (TarEntry it ) {
62
+ return header .name .toString ().equals (it .header .name .toString ());
63
+ }
64
+
65
+ public boolean isDescendent (TarEntry desc ) {
66
+ return desc .header .name .toString ().startsWith (header .name .toString ());
67
+ }
68
+
69
+ public TarHeader getHeader () {
70
+ return header ;
71
+ }
72
+
73
+ public String getName () {
74
+ String name = header .name .toString ();
75
+ if (header .namePrefix != null && !header .namePrefix .toString ().equals ("" )) {
76
+ name = header .namePrefix .toString () + "/" + name ;
77
+ }
78
+
79
+ return name ;
80
+ }
81
+
82
+ public void setName (String name ) {
83
+ header .name = new StringBuffer (name );
84
+ }
85
+
86
+ public int getUserId () {
87
+ return header .userId ;
88
+ }
89
+
90
+ public void setUserId (int userId ) {
91
+ header .userId = userId ;
92
+ }
93
+
94
+ public int getGroupId () {
95
+ return header .groupId ;
96
+ }
97
+
98
+ public void setGroupId (int groupId ) {
99
+ header .groupId = groupId ;
100
+ }
101
+
102
+ public String getUserName () {
103
+ return header .userName .toString ();
104
+ }
105
+
106
+ public void setUserName (String userName ) {
107
+ header .userName = new StringBuffer (userName );
108
+ }
109
+
110
+ public String getGroupName () {
111
+ return header .groupName .toString ();
112
+ }
113
+
114
+ public void setGroupName (String groupName ) {
115
+ header .groupName = new StringBuffer (groupName );
116
+ }
117
+
118
+ public void setIds (int userId , int groupId ) {
119
+ this .setUserId (userId );
120
+ this .setGroupId (groupId );
121
+ }
122
+
123
+ public void setModTime (long time ) {
124
+ header .modTime = time / 1000 ;
125
+ }
126
+
127
+ public void setModTime (Date time ) {
128
+ header .modTime = time .getTime () / 1000 ;
129
+ }
130
+
131
+ public Date getModTime () {
132
+ return new Date (header .modTime * 1000 );
133
+ }
134
+
135
+ public File getFile () {
136
+ return this .file ;
137
+ }
138
+
139
+ public long getSize () {
140
+ return header .size ;
141
+ }
142
+
143
+ public void setSize (long size ) {
144
+ header .size = size ;
145
+ }
146
+
147
+ /**
148
+ * Checks if the org.kamrazafar.jtar entry is a directory
149
+ *
150
+ * @return
151
+ */
152
+ public boolean isDirectory () {
153
+ if (this .file != null )
154
+ return this .file .isDirectory ();
155
+
156
+ if (header != null ) {
157
+ if (header .linkFlag == TarHeader .LF_DIR )
158
+ return true ;
159
+
160
+ if (header .name .toString ().endsWith ("/" ))
161
+ return true ;
162
+ }
163
+
164
+ return false ;
165
+ }
166
+
167
+ /**
168
+ * Extract header from File
169
+ *
170
+ * @param entryName
171
+ */
172
+ public void extractTarHeader (String entryName ) {
173
+ header = TarHeader .createHeader (entryName , file .length (), file .lastModified () / 1000 , file .isDirectory ());
174
+ }
175
+
176
+ /**
177
+ * Calculate checksum
178
+ *
179
+ * @param buf
180
+ * @return
181
+ */
182
+ public long computeCheckSum (byte [] buf ) {
183
+ long sum = 0 ;
184
+
185
+ for (int i = 0 ; i < buf .length ; ++i ) {
186
+ sum += 255 & buf [i ];
187
+ }
188
+
189
+ return sum ;
190
+ }
191
+
192
+ /**
193
+ * Writes the header to the byte buffer
194
+ *
195
+ * @param outbuf
196
+ */
197
+ public void writeEntryHeader (byte [] outbuf ) {
198
+ int offset = 0 ;
199
+
200
+ offset = TarHeader .getNameBytes (header .name , outbuf , offset , TarHeader .NAMELEN );
201
+ offset = Octal .getOctalBytes (header .mode , outbuf , offset , TarHeader .MODELEN );
202
+ offset = Octal .getOctalBytes (header .userId , outbuf , offset , TarHeader .UIDLEN );
203
+ offset = Octal .getOctalBytes (header .groupId , outbuf , offset , TarHeader .GIDLEN );
204
+
205
+ long size = header .size ;
206
+
207
+ offset = Octal .getLongOctalBytes (size , outbuf , offset , TarHeader .SIZELEN );
208
+ offset = Octal .getLongOctalBytes (header .modTime , outbuf , offset , TarHeader .MODTIMELEN );
209
+
210
+ int csOffset = offset ;
211
+ for (int c = 0 ; c < TarHeader .CHKSUMLEN ; ++c )
212
+ outbuf [offset ++] = (byte ) ' ' ;
213
+
214
+ outbuf [offset ++] = header .linkFlag ;
215
+
216
+ offset = TarHeader .getNameBytes (header .linkName , outbuf , offset , TarHeader .NAMELEN );
217
+ offset = TarHeader .getNameBytes (header .magic , outbuf , offset , TarHeader .USTAR_MAGICLEN );
218
+ offset = TarHeader .getNameBytes (header .userName , outbuf , offset , TarHeader .USTAR_USER_NAMELEN );
219
+ offset = TarHeader .getNameBytes (header .groupName , outbuf , offset , TarHeader .USTAR_GROUP_NAMELEN );
220
+ offset = Octal .getOctalBytes (header .devMajor , outbuf , offset , TarHeader .USTAR_DEVLEN );
221
+ offset = Octal .getOctalBytes (header .devMinor , outbuf , offset , TarHeader .USTAR_DEVLEN );
222
+ offset = TarHeader .getNameBytes (header .namePrefix , outbuf , offset , TarHeader .USTAR_FILENAME_PREFIX );
223
+
224
+ for (; offset < outbuf .length ;)
225
+ outbuf [offset ++] = 0 ;
226
+
227
+ long checkSum = this .computeCheckSum (outbuf );
228
+
229
+ Octal .getCheckSumOctalBytes (checkSum , outbuf , csOffset , TarHeader .CHKSUMLEN );
230
+ }
231
+
232
+ /**
233
+ * Parses the tar header to the byte buffer
234
+ *
235
+ * @param header
236
+ * @param bh
237
+ */
238
+ public void parseTarHeader (byte [] bh ) {
239
+ int offset = 0 ;
240
+
241
+ header .name = TarHeader .parseName (bh , offset , TarHeader .NAMELEN );
242
+ offset += TarHeader .NAMELEN ;
243
+
244
+ header .mode = (int ) Octal .parseOctal (bh , offset , TarHeader .MODELEN );
245
+ offset += TarHeader .MODELEN ;
246
+
247
+ header .userId = (int ) Octal .parseOctal (bh , offset , TarHeader .UIDLEN );
248
+ offset += TarHeader .UIDLEN ;
249
+
250
+ header .groupId = (int ) Octal .parseOctal (bh , offset , TarHeader .GIDLEN );
251
+ offset += TarHeader .GIDLEN ;
252
+
253
+ header .size = Octal .parseOctal (bh , offset , TarHeader .SIZELEN );
254
+ offset += TarHeader .SIZELEN ;
255
+
256
+ header .modTime = Octal .parseOctal (bh , offset , TarHeader .MODTIMELEN );
257
+ offset += TarHeader .MODTIMELEN ;
258
+
259
+ header .checkSum = (int ) Octal .parseOctal (bh , offset , TarHeader .CHKSUMLEN );
260
+ offset += TarHeader .CHKSUMLEN ;
261
+
262
+ header .linkFlag = bh [offset ++];
263
+
264
+ header .linkName = TarHeader .parseName (bh , offset , TarHeader .NAMELEN );
265
+ offset += TarHeader .NAMELEN ;
266
+
267
+ header .magic = TarHeader .parseName (bh , offset , TarHeader .USTAR_MAGICLEN );
268
+ offset += TarHeader .USTAR_MAGICLEN ;
269
+
270
+ header .userName = TarHeader .parseName (bh , offset , TarHeader .USTAR_USER_NAMELEN );
271
+ offset += TarHeader .USTAR_USER_NAMELEN ;
272
+
273
+ header .groupName = TarHeader .parseName (bh , offset , TarHeader .USTAR_GROUP_NAMELEN );
274
+ offset += TarHeader .USTAR_GROUP_NAMELEN ;
275
+
276
+ header .devMajor = (int ) Octal .parseOctal (bh , offset , TarHeader .USTAR_DEVLEN );
277
+ offset += TarHeader .USTAR_DEVLEN ;
278
+
279
+ header .devMinor = (int ) Octal .parseOctal (bh , offset , TarHeader .USTAR_DEVLEN );
280
+ offset += TarHeader .USTAR_DEVLEN ;
281
+
282
+ header .namePrefix = TarHeader .parseName (bh , offset , TarHeader .USTAR_FILENAME_PREFIX );
283
+ }
284
+ }
0 commit comments