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