ENH: make this work for older versions of OSX
[cmake.git] / Utilities / cmtar / libtar.h
blob1eba00267991386a359de19c69f80ba30015b330
1 /*
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
13 #ifndef LIBTAR_H
14 #define LIBTAR_H
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <libtar/tar.h>
20 #include <libtar/libtar_listhash.h>
21 #include <libtar/compat.h>
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
27 /* useful constants */
28 #define T_BLOCKSIZE 512
29 #define T_NAMELEN 100
30 #define T_PREFIXLEN 155
31 #define T_MAXPATHLEN (T_NAMELEN + T_PREFIXLEN)
33 /* GNU extensions for typeflag */
34 #define GNU_LONGNAME_TYPE 'L'
35 #define GNU_LONGLINK_TYPE 'K'
37 /* our version of the tar header structure */
38 struct tar_header
40 char name[100];
41 char mode[8];
42 char uid[8];
43 char gid[8];
44 char size[12];
45 char mtime[12];
46 char chksum[8];
47 char typeflag;
48 char linkname[100];
49 char magic[6];
50 char version[2];
51 char uname[32];
52 char gname[32];
53 char devmajor[8];
54 char devminor[8];
55 char prefix[155];
56 char padding[12];
57 char *gnu_longname;
58 char *gnu_longlink;
62 /***** handle.c ************************************************************/
64 typedef int (*openfunc_t)(void* call_data, const char *, int, mode_t);
65 typedef int (*closefunc_t)(void* call_data);
66 typedef ssize_t (*readfunc_t)(void* call_data, void *, size_t);
67 typedef ssize_t (*writefunc_t)(void* call_data, const void *, size_t);
69 typedef struct
71 openfunc_t openfunc;
72 closefunc_t closefunc;
73 readfunc_t readfunc;
74 writefunc_t writefunc;
75 void* call_data;
77 tartype_t;
79 typedef struct
81 tartype_t *type;
82 char *pathname;
83 int oflags;
84 int options;
85 struct tar_header th_buf;
86 libtar_hash_t *h;
88 TAR;
90 /* constant values for the TAR options field */
91 #define TAR_GNU 1 /* use GNU extensions */
92 #define TAR_VERBOSE 2 /* output file info to stdout */
93 #define TAR_NOOVERWRITE 4 /* don't overwrite existing files */
94 #define TAR_IGNORE_EOT 8 /* ignore double zero blocks as EOF */
95 #define TAR_CHECK_MAGIC 16 /* check magic in file header */
96 #define TAR_CHECK_VERSION 32 /* check version in file header */
97 #define TAR_IGNORE_CRC 64 /* ignore CRC in file header */
99 /* this is obsolete - it's here for backwards-compatibility only */
100 #define TAR_IGNORE_MAGIC 0
102 extern const char libtar_version[];
104 /* open a new tarfile handle */
105 int tar_open(TAR **t, char *pathname, tartype_t *type,
106 int oflags, int mode, int options);
108 /* make a tarfile handle out of a previously-opened descriptor */
109 int tar_fdopen(TAR **t, int fd, char *pathname, tartype_t *type,
110 int oflags, int mode, int options);
112 /* close tarfile handle */
113 int tar_close(TAR *t);
116 /***** append.c ************************************************************/
118 /* forward declaration to appease the compiler */
119 struct tar_dev;
121 /* cleanup function */
122 void tar_dev_free(struct tar_dev *tdp);
124 /* Appends a file to the tar archive.
125 * Arguments:
126 * t = TAR handle to append to
127 * realname = path of file to append
128 * savename = name to save the file under in the archive
130 int tar_append_file(TAR *t, char *realname, char *savename);
132 /* write EOF indicator */
133 int tar_append_eof(TAR *t);
135 /* add file contents to a tarchive */
136 int tar_append_regfile(TAR *t, char *realname);
139 /***** block.c *************************************************************/
141 /* macros for reading/writing tarchive blocks */
142 #define tar_block_read(t, buf) \
143 (*((t)->type->readfunc))((t)->type->call_data, (char *)(buf), T_BLOCKSIZE)
144 #define tar_block_write(t, buf) \
145 (*((t)->type->writefunc))((t)->type->call_data, (char *)(buf), T_BLOCKSIZE)
147 /* read/write a header block */
148 int th_read(TAR *t);
149 int th_write(TAR *t);
152 /***** decode.c ************************************************************/
154 /* determine file type */
155 #define TH_ISREG(t) ((t)->th_buf.typeflag == REGTYPE \
156 || (t)->th_buf.typeflag == AREGTYPE \
157 || (t)->th_buf.typeflag == CONTTYPE \
158 || (S_ISREG((mode_t)oct_to_int((t)->th_buf.mode)) \
159 && (t)->th_buf.typeflag != LNKTYPE))
160 #define TH_ISLNK(t) ((t)->th_buf.typeflag == LNKTYPE)
161 #define TH_ISSYM(t) ((t)->th_buf.typeflag == SYMTYPE \
162 || S_ISLNK((mode_t)oct_to_int((t)->th_buf.mode)))
163 #define TH_ISCHR(t) ((t)->th_buf.typeflag == CHRTYPE \
164 || S_ISCHR((mode_t)oct_to_int((t)->th_buf.mode)))
165 #define TH_ISBLK(t) ((t)->th_buf.typeflag == BLKTYPE \
166 || S_ISBLK((mode_t)oct_to_int((t)->th_buf.mode)))
167 #define TH_ISDIR(t) ((t)->th_buf.typeflag == DIRTYPE \
168 || S_ISDIR((mode_t)oct_to_int((t)->th_buf.mode)) \
169 || ((t)->th_buf.typeflag == AREGTYPE \
170 && ((t)->th_buf.name[strlen((t)->th_buf.name) - 1] == '/')))
171 #define TH_ISFIFO(t) ((t)->th_buf.typeflag == FIFOTYPE \
172 || S_ISFIFO((mode_t)oct_to_int((t)->th_buf.mode)))
173 #define TH_ISLONGNAME(t) ((t)->th_buf.typeflag == GNU_LONGNAME_TYPE)
174 #define TH_ISLONGLINK(t) ((t)->th_buf.typeflag == GNU_LONGLINK_TYPE)
176 /* decode tar header info */
177 #define th_get_crc(t) oct_to_int((t)->th_buf.chksum)
178 #define th_get_size(t) oct_to_int((t)->th_buf.size)
179 #define th_get_mtime(t) oct_to_int((t)->th_buf.mtime)
180 #define th_get_devmajor(t) oct_to_int((t)->th_buf.devmajor)
181 #define th_get_devminor(t) oct_to_int((t)->th_buf.devminor)
182 #define th_get_linkname(t) ((t)->th_buf.gnu_longlink \
183 ? (t)->th_buf.gnu_longlink \
184 : (t)->th_buf.linkname)
185 char *th_get_pathname(TAR *t);
186 mode_t th_get_mode(TAR *t);
187 uid_t th_get_uid(TAR *t);
188 gid_t th_get_gid(TAR *t);
191 /***** encode.c ************************************************************/
193 /* encode file info in th_header */
194 void th_set_type(TAR *t, mode_t mode);
195 void th_set_path(TAR *t, char *pathname);
196 void th_set_link(TAR *t, char *linkname);
197 void th_set_device(TAR *t, dev_t device);
198 void th_set_user(TAR *t, uid_t uid);
199 void th_set_group(TAR *t, gid_t gid);
200 void th_set_mode(TAR *t, mode_t fmode);
201 #define th_set_mtime(t, fmtime) \
202 int_to_oct_nonull((int)(fmtime), (t)->th_buf.mtime, 12)
203 #define th_set_size(t, fsize) \
204 int_to_oct_nonull((int)(fsize), (t)->th_buf.size, 12)
206 /* encode everything at once (except the pathname and linkname) */
207 void th_set_from_stat(TAR *t, struct stat *s);
209 /* encode magic, version, and crc - must be done after everything else is set */
210 void th_finish(TAR *t);
213 /***** extract.c ***********************************************************/
215 /* sequentially extract next file from t */
216 int tar_extract_file(TAR *t, char *realname);
218 /* extract different file types */
219 int tar_extract_dir(TAR *t, char *realname);
220 int tar_extract_hardlink(TAR *t, char *realname);
221 int tar_extract_symlink(TAR *t, char *realname);
222 int tar_extract_chardev(TAR *t, char *realname);
223 int tar_extract_blockdev(TAR *t, char *realname);
224 int tar_extract_fifo(TAR *t, char *realname);
226 /* for regfiles, we need to extract the content blocks as well */
227 int tar_extract_regfile(TAR *t, char *realname);
228 int tar_skip_regfile(TAR *t);
231 /***** output.c ************************************************************/
233 /* print the tar header */
234 void th_print(TAR *t);
236 /* print "ls -l"-like output for the file described by th */
237 void th_print_long_ls(TAR *t);
240 /***** util.c *************************************************************/
242 /* hashing function for pathnames */
243 int path_hashfunc(char *key, int numbuckets);
245 /* matching function for dev_t's */
246 int dev_match(dev_t *dev1, dev_t *dev2);
248 /* matching function for ino_t's */
249 int ino_match(ino_t *ino1, ino_t *ino2);
251 /* hashing function for dev_t's */
252 int dev_hash(dev_t *dev);
254 /* hashing function for ino_t's */
255 int ino_hash(ino_t *inode);
257 /* create any necessary dirs */
258 int mkdirhier(char *path);
260 /* calculate header checksum */
261 int th_crc_calc(TAR *t);
262 #define th_crc_ok(t) (th_get_crc(t) == th_crc_calc(t))
264 /* string-octal to integer conversion */
265 int oct_to_int(char *oct);
267 /* integer to NULL-terminated string-octal conversion */
268 #define int_to_oct(num, oct, octlen) \
269 snprintf((oct), (octlen), "%*lo ", (octlen) - 2, (unsigned long)(num))
271 /* integer to string-octal conversion, no NULL */
272 void int_to_oct_nonull(int num, char *oct, size_t octlen);
275 /***** wrapper.c **********************************************************/
277 /* extract groups of files */
278 int tar_extract_glob(TAR *t, char *globname, char *prefix);
279 int tar_extract_all(TAR *t, char *prefix);
281 /* add a whole tree of files */
282 int tar_append_tree(TAR *t, char *realdir, char *savedir);
285 #ifdef __cplusplus
287 #endif
289 #endif /* ! LIBTAR_H */