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