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 *   https://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 || getClass() != obj.getClass()) {
070            return false;
071        }
072        final DumpArchiveSummary other = (DumpArchiveSummary) obj;
073        return Objects.equals(devname, other.devname) && dumpDate == other.dumpDate && Objects.equals(hostname, other.hostname);
074    }
075
076    /**
077     * Gets the device name, for example, /dev/sda3 or /dev/mapper/vg0-home.
078     *
079     * @return device name
080     */
081    public String getDevname() {
082        return devname;
083    }
084
085    /**
086     * Gets the date of this dump.
087     *
088     * @return the date of this dump.
089     */
090    public Date getDumpDate() {
091        return new Date(dumpDate);
092    }
093
094    /**
095     * Gets the last mountpoint, for example, /home.
096     *
097     * @return last mountpoint
098     */
099    public String getFilesystem() {
100        return filesys;
101    }
102
103    /**
104     * Gets the inode of the first record on this volume.
105     *
106     * @return inode of the first record on this volume.
107     */
108    public int getFirstRecord() {
109        return firstrec;
110    }
111
112    /**
113     * Gets the miscellaneous flags. See below.
114     *
115     * @return flags
116     */
117    public int getFlags() {
118        return flags;
119    }
120
121    /**
122     * Gets the hostname of the system where the dump was performed.
123     *
124     * @return hostname the host name
125     */
126    public String getHostname() {
127        return hostname;
128    }
129
130    /**
131     * Gets dump label. This may be autogenerated, or it may be specified by the user.
132     *
133     * @return dump label
134     */
135    public String getLabel() {
136        return label;
137    }
138
139    /**
140     * 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'
141     * 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
142     * backups.
143     *
144     * @return dump level
145     */
146    public int getLevel() {
147        return level;
148    }
149
150    /**
151     * Gets the number of records per tape block. This is typically between 10 and 32.
152     *
153     * @return the number of records per tape block
154     */
155    public int getNTRec() {
156        return ntrec;
157    }
158
159    /**
160     * Gets the date of the previous dump at this level higher.
161     *
162     * @return dumpdate may be null
163     */
164    public Date getPreviousDumpDate() {
165        return new Date(previousDumpDate);
166    }
167
168    /**
169     * Gets volume (tape) number.
170     *
171     * @return volume (tape) number.
172     */
173    public int getVolume() {
174        return volume;
175    }
176
177    @Override
178    public int hashCode() {
179        return Objects.hash(devname, dumpDate, hostname);
180    }
181
182    /**
183     * Is this volume compressed? N.B., individual blocks may or may not be compressed. The first block is never compressed.
184     *
185     * @return true if volume is compressed
186     */
187    public boolean isCompressed() {
188        return (flags & 0x0080) == 0x0080;
189    }
190
191    /**
192     * Does this volume contain extended attributes.
193     *
194     * @return true if volume contains extended attributes.
195     */
196    public boolean isExtendedAttributes() {
197        return (flags & 0x8000) == 0x8000;
198    }
199
200    /**
201     * Does this volume only contain metadata?
202     *
203     * @return true if volume only contains meta-data
204     */
205    public boolean isMetaDataOnly() {
206        return (flags & 0x0100) == 0x0100;
207    }
208
209    /**
210     * Is this the new header format? (We do not currently support the old format.)
211     *
212     * @return true if using new header format
213     */
214    public boolean isNewHeader() {
215        return (flags & 0x0001) == 0x0001;
216    }
217
218    /**
219     * Is this the new inode format? (We do not currently support the old format.)
220     *
221     * @return true if using new inode format
222     */
223    public boolean isNewInode() {
224        return (flags & 0x0002) == 0x0002;
225    }
226
227    /**
228     * Sets the device name.
229     *
230     * @param devname the device name
231     */
232    public void setDevname(final String devname) {
233        this.devname = devname;
234    }
235
236    /**
237     * Sets dump date.
238     *
239     * @param dumpDate the dump date
240     */
241    public void setDumpDate(final Date dumpDate) {
242        this.dumpDate = dumpDate.getTime();
243    }
244
245    /**
246     * Sets the last mountpoint.
247     *
248     * @param fileSystem the last mountpoint
249     */
250    public void setFilesystem(final String fileSystem) {
251        this.filesys = fileSystem;
252    }
253
254    /**
255     * Sets the inode of the first record.
256     *
257     * @param firstrec the first record
258     */
259    public void setFirstRecord(final int firstrec) {
260        this.firstrec = firstrec;
261    }
262
263    /**
264     * Sets the miscellaneous flags.
265     *
266     * @param flags flags
267     */
268    public void setFlags(final int flags) {
269        this.flags = flags;
270    }
271
272    /**
273     * Sets the hostname.
274     *
275     * @param hostname the host name
276     */
277    public void setHostname(final String hostname) {
278        this.hostname = hostname;
279    }
280
281    /**
282     * Sets dump label.
283     *
284     * @param label the label
285     */
286    public void setLabel(final String label) {
287        this.label = label;
288    }
289
290    /**
291     * Sets level.
292     *
293     * @param level the level
294     */
295    public void setLevel(final int level) {
296        this.level = level;
297    }
298
299    /**
300     * Sets the number of records per tape block.
301     *
302     * @param ntrec the number of records per tape block
303     */
304    public void setNTRec(final int ntrec) {
305        this.ntrec = ntrec;
306    }
307
308    /**
309     * Sets previous dump date.
310     *
311     * @param previousDumpDate the previous dump dat
312     */
313    public void setPreviousDumpDate(final Date previousDumpDate) {
314        this.previousDumpDate = previousDumpDate.getTime();
315    }
316
317    /**
318     * Sets volume (tape) number.
319     *
320     * @param volume the volume number
321     */
322    public void setVolume(final int volume) {
323        this.volume = volume;
324    }
325}