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