001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.commons.compress.archivers.dump;
020
021import java.io.IOException;
022import java.util.Date;
023
024import org.apache.commons.compress.archivers.zip.ZipEncoding;
025
026/**
027 * This class represents identifying information about a Dump archive volume.
028 * It consists the archive's dump date, label, hostname, device name and possibly
029 * last mount point plus the volume's volume id andfirst record number.
030 *
031 * For the corresponding C structure see the header of {@link DumpArchiveEntry}.
032 */
033public class DumpArchiveSummary {
034    private long dumpDate;
035    private long previousDumpDate;
036    private int volume;
037    private String label;
038    private int level;
039    private String filesys;
040    private String devname;
041    private String hostname;
042    private int flags;
043    private int firstrec;
044    private int ntrec;
045
046    DumpArchiveSummary(byte[] buffer, ZipEncoding encoding) throws IOException {
047        dumpDate = 1000L * DumpArchiveUtil.convert32(buffer, 4);
048        previousDumpDate = 1000L * DumpArchiveUtil.convert32(buffer, 8);
049        volume = DumpArchiveUtil.convert32(buffer, 12);
050        label = DumpArchiveUtil.decode(encoding, buffer, 676, DumpArchiveConstants.LBLSIZE).trim();
051        level = DumpArchiveUtil.convert32(buffer, 692);
052        filesys = DumpArchiveUtil.decode(encoding, buffer, 696, DumpArchiveConstants.NAMELEN).trim();
053        devname = DumpArchiveUtil.decode(encoding, buffer, 760, DumpArchiveConstants.NAMELEN).trim();
054        hostname = DumpArchiveUtil.decode(encoding, buffer, 824, DumpArchiveConstants.NAMELEN).trim();
055        flags = DumpArchiveUtil.convert32(buffer, 888);
056        firstrec = DumpArchiveUtil.convert32(buffer, 892);
057        ntrec = DumpArchiveUtil.convert32(buffer, 896);
058
059        //extAttributes = DumpArchiveUtil.convert32(buffer, 900);
060    }
061
062    /**
063     * Get the date of this dump.
064     * @return the date of this dump.
065     */
066    public Date getDumpDate() {
067        return new Date(dumpDate);
068    }
069
070    /**
071     * Set dump date.
072     */
073    public void setDumpDate(Date dumpDate) {
074        this.dumpDate = dumpDate.getTime();
075    }
076
077    /**
078     * Get the date of the previous dump at this level higher.
079     * @return dumpdate may be null
080     */
081    public Date getPreviousDumpDate() {
082        return new Date(previousDumpDate);
083    }
084
085    /**
086     * Set previous dump date.
087     */
088    public void setPreviousDumpDate(Date previousDumpDate) {
089        this.previousDumpDate = previousDumpDate.getTime();
090    }
091
092    /**
093     * Get volume (tape) number.
094     * @return volume (tape) number.
095     */
096    public int getVolume() {
097        return volume;
098    }
099
100    /**
101     * Set volume (tape) number.
102     */
103    public void setVolume(int volume) {
104        this.volume = volume;
105    }
106
107    /**
108     * Get the level of this dump. This is a number between 0 and 9, inclusive,
109     * and a level 0 dump is a complete dump of the partition. For any other dump
110     * 'n' this dump contains all files that have changed since the last dump
111     * at this level or lower. This is used to support different levels of
112     * incremental backups.
113     * @return dump level
114     */
115    public int getLevel() {
116        return level;
117    }
118
119    /**
120     * Set level.
121     */
122    public void setLevel(int level) {
123        this.level = level;
124    }
125
126    /**
127     * Get dump label. This may be autogenerated or it may be specified
128     * bu the user.
129     * @return dump label
130     */
131    public String getLabel() {
132        return label;
133    }
134
135    /**
136     * Set dump label.
137     * @param label
138     */
139    public void setLabel(String label) {
140        this.label = label;
141    }
142
143    /**
144     * Get the last mountpoint, e.g., /home.
145     * @return last mountpoint
146     */
147    public String getFilesystem() {
148        return filesys;
149    }
150
151    /**
152     * Set the last mountpoint.
153     */
154    public void setFilesystem(String filesystem) {
155        this.filesys = filesystem;
156    }
157
158    /**
159     * Get the device name, e.g., /dev/sda3 or /dev/mapper/vg0-home.
160     * @return device name
161     */
162    public String getDevname() {
163        return devname;
164    }
165
166    /**
167     * Set the device name.
168     * @param devname
169     */
170    public void setDevname(String devname) {
171        this.devname = devname;
172    }
173
174    /**
175     * Get the hostname of the system where the dump was performed.
176     * @return hostname
177     */
178    public String getHostname() {
179        return hostname;
180    }
181
182    /**
183     * Set the hostname.
184     */
185    public void setHostname(String hostname) {
186        this.hostname = hostname;
187    }
188
189    /**
190     * Get the miscellaneous flags. See below.
191     * @return flags
192     */
193    public int getFlags() {
194        return flags;
195    }
196
197    /**
198     * Set the miscellaneous flags.
199     * @param flags
200     */
201    public void setFlags(int flags) {
202        this.flags = flags;
203    }
204
205    /**
206     * Get the inode of the first record on this volume.
207     * @return inode of the first record on this volume.
208     */
209    public int getFirstRecord() {
210        return firstrec;
211    }
212
213    /**
214     * Set the inode of the first record.
215     * @param firstrec
216     */
217    public void setFirstRecord(int firstrec) {
218        this.firstrec = firstrec;
219    }
220
221    /**
222     * Get the number of records per tape block. This is typically
223     * between 10 and 32.
224     * @return the number of records per tape block
225     */
226    public int getNTRec() {
227        return ntrec;
228    }
229
230    /**
231     * Set the number of records per tape block.
232     */
233    public void setNTRec(int ntrec) {
234        this.ntrec = ntrec;
235    }
236
237    /**
238     * Is this the new header format? (We do not currently support the
239     * old format.)
240     *
241     * @return true if using new header format
242     */
243    public boolean isNewHeader() {
244        return (flags & 0x0001) == 0x0001;
245    }
246
247    /**
248     * Is this the new inode format? (We do not currently support the
249     * old format.)
250     * @return true if using new inode format
251     */
252    public boolean isNewInode() {
253        return (flags & 0x0002) == 0x0002;
254    }
255
256    /**
257     * Is this volume compressed? N.B., individual blocks may or may not be compressed.
258     * The first block is never compressed.
259     * @return true if volume is compressed
260     */
261    public boolean isCompressed() {
262        return (flags & 0x0080) == 0x0080;
263    }
264
265    /**
266     * Does this volume only contain metadata?
267     * @return true if volume only contains meta-data
268     */
269    public boolean isMetaDataOnly() {
270        return (flags & 0x0100) == 0x0100;
271    }
272
273    /**
274     * Does this volume cotain extended attributes.
275     * @return true if volume cotains extended attributes.
276     */
277    public boolean isExtendedAttributes() {
278        return (flags & 0x8000) == 0x8000;
279    }
280
281    /**
282     * @see java.lang.Object#hashCode()
283     */
284    @Override
285    public int hashCode() {
286        int hash = 17;
287
288        if (label != null) {
289            hash = label.hashCode();
290        }
291
292        hash += 31 * dumpDate;
293
294        if (hostname != null) {
295            hash = (31 * hostname.hashCode()) + 17;
296        }
297
298        if (devname != null) {
299            hash = (31 * devname.hashCode()) + 17;
300        }
301
302        return hash;
303    }
304
305    /**
306     * @see java.lang.Object#equals(Object)
307     */
308    @Override
309    public boolean equals(Object o) {
310        if (this == o) {
311            return true;
312        }
313
314        if (o == null || !o.getClass().equals(getClass())) {
315            return false;
316        }
317
318        DumpArchiveSummary rhs = (DumpArchiveSummary) o;
319
320        if (dumpDate != rhs.dumpDate) {
321            return false;
322        }
323
324        if ((getHostname() == null) ||
325                !getHostname().equals(rhs.getHostname())) {
326            return false;
327        }
328
329        if ((getDevname() == null) || !getDevname().equals(rhs.getDevname())) {
330            return false;
331        }
332
333        return true;
334    }
335}