Skip to main content

simple_archive/
lib.rs

1mod carchive;
2mod error;
3mod prelude;
4pub mod reader;
5pub mod writer;
6
7use std::fs::Metadata as FSMeta;
8use std::os::unix::fs::MetadataExt;
9
10/// Metadata information for an archive entry.
11#[derive(Clone)]
12pub struct Metadata {
13    filepath: String,
14    size: i64,
15    nodetype: u32,
16    perm: mode_t,
17    ctime: i64,
18    ctime_nano: i64,
19    atime: i64,
20    atime_nano: i64,
21    mtime: i64,
22    mtime_nano: i64,
23    owner: libc::uid_t,
24    group: libc::gid_t,
25}
26
27fn into_nodetype(source: &FSMeta) -> u32 {
28    if source.is_dir() {
29        AE_IFDIR
30    } else if source.is_file() {
31        AE_IFREG
32    } else if source.is_symlink() {
33        AE_IFLNK
34    } else {
35        0
36    }
37}
38
39impl From<FSMeta> for Metadata {
40    fn from(meta: FSMeta) -> Self {
41        Metadata {
42            filepath: "".to_owned(),
43            size: meta.size() as i64, // Iḿ assuming anything above 2**63 is way to much for
44            // a single file
45            nodetype: into_nodetype(&meta),
46            perm: meta.mode(),
47            ctime: meta.ctime(),
48            ctime_nano: meta.ctime_nsec(),
49            atime: meta.atime(),
50            atime_nano: meta.atime_nsec(),
51            mtime: meta.mtime(),
52            mtime_nano: meta.mtime_nsec(),
53            owner: meta.uid(),
54            group: meta.gid(),
55        }
56    }
57}
58
59impl Metadata {
60    /// Create metadata for in-memory entries without filesystem dependency.
61    pub fn from_fields(
62        size: i64,
63        nodetype: u32,
64        perm: mode_t,
65        mtime: i64,
66        mtime_nano: i64,
67    ) -> Self {
68        Self {
69            filepath: String::new(),
70            size,
71            nodetype,
72            perm,
73            ctime: 0,
74            ctime_nano: 0,
75            atime: 0,
76            atime_nano: 0,
77            mtime,
78            mtime_nano,
79            owner: 0,
80            group: 0,
81        }
82    }
83
84    /// Returns the filepath of the entry.
85    pub fn filepath(&self) -> &str {
86        &self.filepath
87    }
88
89    /// Returns the size of the entry in bytes.
90    pub fn size(&self) -> i64 {
91        self.size
92    }
93
94    /// Returns the node type (file, directory, etc.)
95    pub fn nodetype(&self) -> u32 {
96        self.nodetype
97    }
98
99    /// Returns the permissions mode.
100    pub fn perm(&self) -> mode_t {
101        self.perm
102    }
103
104    /// Returns the creation time in seconds.
105    pub fn ctime(&self) -> i64 {
106        self.ctime
107    }
108
109    /// Returns the creation time nanoseconds part.
110    pub fn ctime_nano(&self) -> i64 {
111        self.ctime_nano
112    }
113
114    /// Returns the last access time in seconds.
115    pub fn atime(&self) -> i64 {
116        self.atime
117    }
118
119    /// Returns the last access time nanoseconds part.
120    pub fn atime_nano(&self) -> i64 {
121        self.atime_nano
122    }
123
124    /// Returns the last modification time in seconds.
125    pub fn mtime(&self) -> i64 {
126        self.mtime
127    }
128
129    /// Returns the last modification time nanoseconds part.
130    pub fn mtime_nano(&self) -> i64 {
131        self.mtime_nano
132    }
133
134    /// Returns the owner UID.
135    pub fn owner(&self) -> libc::uid_t {
136        self.owner
137    }
138
139    /// Returns the group GID.
140    pub fn group(&self) -> libc::gid_t {
141        self.group
142    }
143
144    /// Returns true if the entry is a directory.
145    pub fn is_dir(&self) -> bool {
146        self.nodetype == AE_IFDIR
147    }
148
149    /// Returns true if the entry is a regular file.
150    pub fn is_file(&self) -> bool {
151        self.nodetype == AE_IFREG
152    }
153
154    /// Returns true if the entry is a symbolic link.
155    pub fn is_symlink(&self) -> bool {
156        self.nodetype == AE_IFLNK
157    }
158
159    /// Returns true if the entry is a block device.
160    pub fn is_block_device(&self) -> bool {
161        self.nodetype == AE_IFBLK
162    }
163
164    /// Returns true if the entry is a character device.
165    pub fn is_char_device(&self) -> bool {
166        self.nodetype == AE_IFCHR
167    }
168
169    /// Returns true if the entry is a FIFO (named pipe).
170    pub fn is_fifo(&self) -> bool {
171        self.nodetype == AE_IFIFO
172    }
173
174    /// Returns true if the entry is a socket.
175    pub fn is_socket(&self) -> bool {
176        self.nodetype == AE_IFSOCK
177    }
178}
179
180use carchive::mode_t;
181
182pub use error::Error;
183
184// Re-export common libarchive constants
185pub use carchive::AE_IFBLK;
186pub use carchive::AE_IFCHR;
187pub use carchive::AE_IFDIR;
188pub use carchive::AE_IFIFO;
189pub use carchive::AE_IFLNK;
190pub use carchive::AE_IFMT;
191pub use carchive::AE_IFREG;
192pub use carchive::AE_IFSOCK;
193
194pub use carchive::ARCHIVE_FAILED;
195pub use carchive::ARCHIVE_FATAL;
196pub use carchive::ARCHIVE_OK;
197pub use carchive::ARCHIVE_WARN;
198
199pub use carchive::ARCHIVE_FORMAT_CPIO;
200pub use carchive::ARCHIVE_FORMAT_CPIO_BIN_LE;
201pub use carchive::ARCHIVE_FORMAT_CPIO_POSIX;
202pub use carchive::ARCHIVE_FORMAT_CPIO_PWB;
203pub use carchive::ARCHIVE_FORMAT_CPIO_SVR4_NOCRC;
204
205pub use carchive::ARCHIVE_FORMAT_SHAR;
206pub use carchive::ARCHIVE_FORMAT_SHAR_DUMP;
207
208pub use carchive::ARCHIVE_FORMAT_TAR;
209pub use carchive::ARCHIVE_FORMAT_TAR_GNUTAR;
210pub use carchive::ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
211pub use carchive::ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
212pub use carchive::ARCHIVE_FORMAT_TAR_USTAR;
213
214pub use carchive::ARCHIVE_FORMAT_EMPTY;
215pub use carchive::ARCHIVE_FORMAT_ISO9660;
216pub use carchive::ARCHIVE_FORMAT_ZIP;
217
218pub use carchive::ARCHIVE_FORMAT_7ZIP;
219pub use carchive::ARCHIVE_FORMAT_CAB;
220pub use carchive::ARCHIVE_FORMAT_MTREE;
221pub use carchive::ARCHIVE_FORMAT_RAR;
222pub use carchive::ARCHIVE_FORMAT_RAW;
223pub use carchive::ARCHIVE_FORMAT_WARC;
224pub use carchive::ARCHIVE_FORMAT_XAR;
225
226pub use carchive::ARCHIVE_FILTER_BZIP2;
227pub use carchive::ARCHIVE_FILTER_COMPRESS;
228pub use carchive::ARCHIVE_FILTER_GRZIP;
229pub use carchive::ARCHIVE_FILTER_GZIP;
230pub use carchive::ARCHIVE_FILTER_LRZIP;
231pub use carchive::ARCHIVE_FILTER_LZ4;
232pub use carchive::ARCHIVE_FILTER_LZIP;
233pub use carchive::ARCHIVE_FILTER_LZMA;
234pub use carchive::ARCHIVE_FILTER_LZOP;
235pub use carchive::ARCHIVE_FILTER_NONE;
236pub use carchive::ARCHIVE_FILTER_PROGRAM;
237pub use carchive::ARCHIVE_FILTER_RPM;
238pub use carchive::ARCHIVE_FILTER_UU;
239pub use carchive::ARCHIVE_FILTER_XZ;
240pub use carchive::ARCHIVE_FILTER_ZSTD;
241
242pub use carchive::ARCHIVE_EXTRACT_ACL;
243pub use carchive::ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS;
244pub use carchive::ARCHIVE_EXTRACT_FFLAGS;
245pub use carchive::ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED;
246pub use carchive::ARCHIVE_EXTRACT_MAC_METADATA;
247pub use carchive::ARCHIVE_EXTRACT_NO_AUTODIR;
248pub use carchive::ARCHIVE_EXTRACT_NO_HFS_COMPRESSION;
249pub use carchive::ARCHIVE_EXTRACT_NO_OVERWRITE;
250pub use carchive::ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
251pub use carchive::ARCHIVE_EXTRACT_OWNER;
252pub use carchive::ARCHIVE_EXTRACT_PERM;
253pub use carchive::ARCHIVE_EXTRACT_SAFE_WRITES;
254pub use carchive::ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS;
255pub use carchive::ARCHIVE_EXTRACT_SECURE_NODOTDOT;
256pub use carchive::ARCHIVE_EXTRACT_SECURE_SYMLINKS;
257pub use carchive::ARCHIVE_EXTRACT_TIME;
258pub use carchive::ARCHIVE_EXTRACT_UNLINK;
259pub use carchive::ARCHIVE_EXTRACT_XATTR;