blob: ab5a3beded8b5fe024271559f1a9130c200af83a [file] [log] [blame]
bigbiff bigbiff9c754052013-01-09 09:09:08 -05001/*
2** Copyright 1998-2003 University of Illinois Board of Trustees
3** Copyright 1998-2003 Mark D. Roth
4** All rights reserved.
5**
6** libtar.h - header file for libtar library
7**
8** Mark D. Roth <roth@uiuc.edu>
9** Campus Information Technologies and Educational Services
10** University of Illinois at Urbana-Champaign
11*/
12
13#ifndef LIBTAR_H
14#define LIBTAR_H
15
16#include <sys/types.h>
17#include <sys/stat.h>
18#include "tar.h"
19
20#include "libtar_listhash.h"
21
Ethan Yonker79f88bd2016-12-09 14:52:12 -060022#ifdef HAVE_EXT4_CRYPT
23#define EXT4_KEY_DESCRIPTOR_SIZE 8
24#define EXT4_KEY_DESCRIPTOR_HEX 17
25#endif
26
bigbiff bigbiff9c754052013-01-09 09:09:08 -050027#ifdef __cplusplus
28extern "C"
29{
30#endif
31
32
33/* useful constants */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -050034/* see FIXME note in block.c regarding T_BLOCKSIZE */
bigbiff bigbiff9c754052013-01-09 09:09:08 -050035#define T_BLOCKSIZE 512
36#define T_NAMELEN 100
37#define T_PREFIXLEN 155
38#define T_MAXPATHLEN (T_NAMELEN + T_PREFIXLEN)
39
40/* GNU extensions for typeflag */
41#define GNU_LONGNAME_TYPE 'L'
42#define GNU_LONGLINK_TYPE 'K'
43
Vojtech Bocek25fd68d2013-08-27 03:10:10 +020044/* extended metadata for next file - used to store selinux_context */
45#define TH_EXT_TYPE 'x'
Ethan Yonker79f88bd2016-12-09 14:52:12 -060046#define TH_POL_TYPE 'p'
Vojtech Bocek25fd68d2013-08-27 03:10:10 +020047
bigbiff bigbiff9c754052013-01-09 09:09:08 -050048/* our version of the tar header structure */
49struct tar_header
50{
51 char name[100];
52 char mode[8];
53 char uid[8];
54 char gid[8];
55 char size[12];
56 char mtime[12];
57 char chksum[8];
58 char typeflag;
59 char linkname[100];
60 char magic[6];
61 char version[2];
62 char uname[32];
63 char gname[32];
64 char devmajor[8];
65 char devminor[8];
66 char prefix[155];
67 char padding[12];
68 char *gnu_longname;
69 char *gnu_longlink;
Vojtech Bocek25fd68d2013-08-27 03:10:10 +020070#ifdef HAVE_SELINUX
71 char *selinux_context;
72#endif
Ethan Yonker79f88bd2016-12-09 14:52:12 -060073#ifdef HAVE_EXT4_CRYPT
74 char *e4crypt_policy;
75#endif
bigbiff bigbiff9c754052013-01-09 09:09:08 -050076};
77
78
79/***** handle.c ************************************************************/
80
81typedef int (*openfunc_t)(const char *, int, ...);
82typedef int (*closefunc_t)(int);
83typedef ssize_t (*readfunc_t)(int, void *, size_t);
84typedef ssize_t (*writefunc_t)(int, const void *, size_t);
85
86typedef struct
87{
88 openfunc_t openfunc;
89 closefunc_t closefunc;
90 readfunc_t readfunc;
91 writefunc_t writefunc;
92}
93tartype_t;
94
95typedef struct
96{
97 tartype_t *type;
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -050098 const char *pathname;
bigbiff bigbiff9c754052013-01-09 09:09:08 -050099 long fd;
100 int oflags;
101 int options;
102 struct tar_header th_buf;
103 libtar_hash_t *h;
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500104
105 /* introduced in libtar 1.2.21 */
106 char *th_pathname;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500107}
108TAR;
109
110/* constant values for the TAR options field */
111#define TAR_GNU 1 /* use GNU extensions */
112#define TAR_VERBOSE 2 /* output file info to stdout */
113#define TAR_NOOVERWRITE 4 /* don't overwrite existing files */
114#define TAR_IGNORE_EOT 8 /* ignore double zero blocks as EOF */
115#define TAR_CHECK_MAGIC 16 /* check magic in file header */
116#define TAR_CHECK_VERSION 32 /* check version in file header */
117#define TAR_IGNORE_CRC 64 /* ignore CRC in file header */
Vojtech Bocek25fd68d2013-08-27 03:10:10 +0200118#define TAR_STORE_SELINUX 128 /* store selinux context */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500119#define TAR_USE_NUMERIC_ID 256 /* favor numeric owner over names */
Ethan Yonker79f88bd2016-12-09 14:52:12 -0600120#define TAR_STORE_EXT4_POL 512 /* store ext4 crypto policy */
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500121
122/* this is obsolete - it's here for backwards-compatibility only */
123#define TAR_IGNORE_MAGIC 0
124
125extern const char libtar_version[];
126
127
128/* open a new tarfile handle */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500129int tar_open(TAR **t, const char *pathname, tartype_t *type,
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500130 int oflags, int mode, int options);
131
132/* make a tarfile handle out of a previously-opened descriptor */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500133int tar_fdopen(TAR **t, int fd, const char *pathname, tartype_t *type,
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500134 int oflags, int mode, int options);
135
136/* returns the descriptor associated with t */
137int tar_fd(TAR *t);
138
139/* close tarfile handle */
140int tar_close(TAR *t);
141
142
143/***** append.c ************************************************************/
144
145/* forward declaration to appease the compiler */
146struct tar_dev;
147
148/* cleanup function */
149void tar_dev_free(struct tar_dev *tdp);
150
151/* Appends a file to the tar archive.
152 * Arguments:
153 * t = TAR handle to append to
154 * realname = path of file to append
155 * savename = name to save the file under in the archive
156 */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500157int tar_append_file(TAR *t, const char *realname, const char *savename);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500158
159/* write EOF indicator */
160int tar_append_eof(TAR *t);
161
162/* add file contents to a tarchive */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500163int tar_append_regfile(TAR *t, const char *realname);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500164
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500165/* Appends in-memory file contents to a tarchive.
166 * Arguments:
167 * t = TAR handle to append to
168 * savename = name to save the file under in the archive
169 * mode = mode
170 * uid, gid = owner
171 * buf, len = in-memory buffer
172 */
173int tar_append_file_contents(TAR *t, const char *savename, mode_t mode,
174 uid_t uid, gid_t gid, void *buf, size_t len);
175
176/* add buffer to a tarchive */
177int tar_append_buffer(TAR *t, void *buf, size_t len);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500178
179/***** block.c *************************************************************/
180
181/* macros for reading/writing tarchive blocks */
182#define tar_block_read(t, buf) \
183 (*((t)->type->readfunc))((t)->fd, (char *)(buf), T_BLOCKSIZE)
184#define tar_block_write(t, buf) \
185 (*((t)->type->writefunc))((t)->fd, (char *)(buf), T_BLOCKSIZE)
186
187/* read/write a header block */
188int th_read(TAR *t);
189int th_write(TAR *t);
190
191
192/***** decode.c ************************************************************/
193
194/* determine file type */
195#define TH_ISREG(t) ((t)->th_buf.typeflag == REGTYPE \
196 || (t)->th_buf.typeflag == AREGTYPE \
197 || (t)->th_buf.typeflag == CONTTYPE \
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500198 || (S_ISREG((mode_t)oct_to_int((t)->th_buf.mode, sizeof((t)->th_buf.mode))) \
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500199 && (t)->th_buf.typeflag != LNKTYPE))
200#define TH_ISLNK(t) ((t)->th_buf.typeflag == LNKTYPE)
201#define TH_ISSYM(t) ((t)->th_buf.typeflag == SYMTYPE \
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500202 || S_ISLNK((mode_t)oct_to_int((t)->th_buf.mode, sizeof((t)->th_buf.mode))))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500203#define TH_ISCHR(t) ((t)->th_buf.typeflag == CHRTYPE \
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500204 || S_ISCHR((mode_t)oct_to_int((t)->th_buf.mode, sizeof((t)->th_buf.mode))))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500205#define TH_ISBLK(t) ((t)->th_buf.typeflag == BLKTYPE \
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500206 || S_ISBLK((mode_t)oct_to_int((t)->th_buf.mode, sizeof((t)->th_buf.mode))))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500207#define TH_ISDIR(t) ((t)->th_buf.typeflag == DIRTYPE \
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500208 || S_ISDIR((mode_t)oct_to_int((t)->th_buf.mode, sizeof((t)->th_buf.mode))) \
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500209 || ((t)->th_buf.typeflag == AREGTYPE \
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500210 && strnlen((t)->th_buf.name, T_NAMELEN) \
211 && ((t)->th_buf.name[strnlen((t)->th_buf.name, T_NAMELEN) - 1] == '/')))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500212#define TH_ISFIFO(t) ((t)->th_buf.typeflag == FIFOTYPE \
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500213 || S_ISFIFO((mode_t)oct_to_int((t)->th_buf.mode, sizeof((t)->th_buf.mode))))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500214#define TH_ISLONGNAME(t) ((t)->th_buf.typeflag == GNU_LONGNAME_TYPE)
215#define TH_ISLONGLINK(t) ((t)->th_buf.typeflag == GNU_LONGLINK_TYPE)
Vojtech Bocek25fd68d2013-08-27 03:10:10 +0200216#define TH_ISEXTHEADER(t) ((t)->th_buf.typeflag == TH_EXT_TYPE)
Ethan Yonker79f88bd2016-12-09 14:52:12 -0600217#define TH_ISPOLHEADER(t) ((t)->th_buf.typeflag == TH_POL_TYPE)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500218
219/* decode tar header info */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500220#define th_get_crc(t) oct_to_int((t)->th_buf.chksum, sizeof((t)->th_buf.chksum))
221#define th_get_size(t) oct_to_int_ex((t)->th_buf.size, sizeof((t)->th_buf.size))
222#define th_get_mtime(t) oct_to_int_ex((t)->th_buf.mtime, sizeof((t)->th_buf.mtime))
223#define th_get_devmajor(t) oct_to_int((t)->th_buf.devmajor, sizeof((t)->th_buf.devmajor))
224#define th_get_devminor(t) oct_to_int((t)->th_buf.devminor, sizeof((t)->th_buf.devminor))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500225#define th_get_linkname(t) ((t)->th_buf.gnu_longlink \
226 ? (t)->th_buf.gnu_longlink \
227 : (t)->th_buf.linkname)
228char *th_get_pathname(TAR *t);
229mode_t th_get_mode(TAR *t);
230uid_t th_get_uid(TAR *t);
231gid_t th_get_gid(TAR *t);
232
233
234/***** encode.c ************************************************************/
235
236/* encode file info in th_header */
237void th_set_type(TAR *t, mode_t mode);
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500238void th_set_path(TAR *t, const char *pathname);
239void th_set_link(TAR *t, const char *linkname);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500240void th_set_device(TAR *t, dev_t device);
241void th_set_user(TAR *t, uid_t uid);
242void th_set_group(TAR *t, gid_t gid);
243void th_set_mode(TAR *t, mode_t fmode);
244#define th_set_mtime(t, fmtime) \
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500245 int_to_oct_ex((fmtime), (t)->th_buf.mtime, sizeof((t)->th_buf.mtime))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500246#define th_set_size(t, fsize) \
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500247 int_to_oct_ex((fsize), (t)->th_buf.size, sizeof((t)->th_buf.size))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500248
249/* encode everything at once (except the pathname and linkname) */
250void th_set_from_stat(TAR *t, struct stat *s);
251
252/* encode magic, version, and crc - must be done after everything else is set */
253void th_finish(TAR *t);
254
255
256/***** extract.c ***********************************************************/
257
258/* sequentially extract next file from t */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500259int tar_extract_file(TAR *t, const char *realname, const char *prefix, const int *progress_fd);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500260
261/* extract different file types */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500262int tar_extract_dir(TAR *t, const char *realname);
263int tar_extract_hardlink(TAR *t, const char *realname, const char *prefix);
264int tar_extract_symlink(TAR *t, const char *realname);
265int tar_extract_chardev(TAR *t, const char *realname);
266int tar_extract_blockdev(TAR *t, const char *realname);
267int tar_extract_fifo(TAR *t, const char *realname);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500268
269/* for regfiles, we need to extract the content blocks as well */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500270int tar_extract_regfile(TAR *t, const char *realname, const int *progress_fd);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500271int tar_skip_regfile(TAR *t);
272
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500273/* extract regfile to buffer */
274int tar_extract_file_contents(TAR *t, void *buf, size_t *lenp);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500275
276/***** output.c ************************************************************/
277
278/* print the tar header */
279void th_print(TAR *t);
280
281/* print "ls -l"-like output for the file described by th */
282void th_print_long_ls(TAR *t);
283
284
285/***** util.c *************************************************************/
286
287/* hashing function for pathnames */
288int path_hashfunc(char *key, int numbuckets);
289
290/* matching function for dev_t's */
291int dev_match(dev_t *dev1, dev_t *dev2);
292
293/* matching function for ino_t's */
294int ino_match(ino_t *ino1, ino_t *ino2);
295
296/* hashing function for dev_t's */
297int dev_hash(dev_t *dev);
298
299/* hashing function for ino_t's */
300int ino_hash(ino_t *inode);
301
302/* create any necessary dirs */
303int mkdirhier(char *path);
304
305/* calculate header checksum */
306int th_crc_calc(TAR *t);
307
308/* calculate a signed header checksum */
309int th_signed_crc_calc(TAR *t);
310
311/* compare checksums in a forgiving way */
312#define th_crc_ok(t) (th_get_crc(t) == th_crc_calc(t) || th_get_crc(t) == th_signed_crc_calc(t))
313
314/* string-octal to integer conversion */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500315int64_t oct_to_int(char *oct, size_t len);
316
317/* string-octal or binary to integer conversion */
318int64_t oct_to_int_ex(char *oct, size_t len);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500319
320/* integer to NULL-terminated string-octal conversion */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500321void int_to_oct(int64_t num, char *oct, size_t octlen);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500322
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500323/* integer to string-octal conversion, or binary as necessary */
324void int_to_oct_ex(int64_t num, char *oct, size_t octlen);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500325
326
327/***** wrapper.c **********************************************************/
328
329/* extract groups of files */
330int tar_extract_glob(TAR *t, char *globname, char *prefix);
Ethan Yonker1b7a31b2014-07-03 15:09:22 -0500331int tar_extract_all(TAR *t, char *prefix, const int *progress_fd);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500332
333/* add a whole tree of files */
James Christopher Adduono6f57f7c2016-03-01 16:01:53 -0500334int tar_append_tree(TAR *t, char *realdir, char *savedir);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500335
n0d33b511632013-03-06 21:14:15 +0200336/* find an entry */
337int tar_find(TAR *t, char *searchstr);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500338
339#ifdef __cplusplus
340}
341#endif
342
343#endif /* ! LIBTAR_H */
344