VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/zip/tar.h@ 78365

Last change on this file since 78365 was 76585, checked in by vboxsync, 6 years ago

*: scm --fix-header-guard-endif

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.4 KB
Line 
1/* $Id: tar.h 76585 2019-01-01 06:31:29Z vboxsync $ */
2/** @file
3 * IPRT - TAR Virtual Filesystem.
4 */
5
6/*
7 * Copyright (C) 2010-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27#ifndef IPRT_INCLUDED_SRC_common_zip_tar_h
28#define IPRT_INCLUDED_SRC_common_zip_tar_h
29#ifndef RT_WITHOUT_PRAGMA_ONCE
30# pragma once
31#endif
32
33#include <iprt/assert.h>
34
35/** @name RTZIPTARHDRPOSIX::typeflag
36 * @{ */
37#define RTZIPTAR_TF_OLDNORMAL '\0' /**< Normal disk file, Unix compatible */
38#define RTZIPTAR_TF_NORMAL '0' /**< Normal disk file */
39#define RTZIPTAR_TF_LINK '1' /**< Link to previously dumped file */
40#define RTZIPTAR_TF_SYMLINK '2' /**< Symbolic link */
41#define RTZIPTAR_TF_CHR '3' /**< Character special file */
42#define RTZIPTAR_TF_BLK '4' /**< Block special file */
43#define RTZIPTAR_TF_DIR '5' /**< Directory */
44#define RTZIPTAR_TF_FIFO '6' /**< FIFO special file */
45#define RTZIPTAR_TF_CONTIG '7' /**< Contiguous file */
46
47#define RTZIPTAR_TF_X_HDR 'x' /**< Extended header. */
48#define RTZIPTAR_TF_X_GLOBAL 'g' /**< Global extended header. */
49
50#define RTZIPTAR_TF_SOLARIS_XHDR 'X'
51
52#define RTZIPTAR_TF_GNU_DUMPDIR 'D'
53#define RTZIPTAR_TF_GNU_LONGLINK 'K' /**< GNU long link header. */
54#define RTZIPTAR_TF_GNU_LONGNAME 'L' /**< GNU long name header. */
55#define RTZIPTAR_TF_GNU_MULTIVOL 'M'
56#define RTZIPTAR_TF_GNU_SPARSE 'S'
57#define RTZIPTAR_TF_GNU_VOLDHR 'V'
58/** @} */
59
60
61/**
62 * The ancient tar header.
63 *
64 * The posix and gnu headers are compatible with the members up to and including
65 * link name, from there on they differ.
66 */
67typedef struct RTZIPTARHDRANCIENT
68{
69 char name[100];
70 char mode[8];
71 char uid[8];
72 char gid[8];
73 char size[12];
74 char mtime[12];
75 char chksum[8];
76 char typeflag;
77 char linkname[100]; /**< Was called linkflag. */
78 char unused[8+64+16+155+12];
79} RTZIPTARHDRANCIENT;
80AssertCompileSize(RTZIPTARHDRANCIENT, 512);
81AssertCompileMemberOffset(RTZIPTARHDRANCIENT, name, 0);
82AssertCompileMemberOffset(RTZIPTARHDRANCIENT, mode, 100);
83AssertCompileMemberOffset(RTZIPTARHDRANCIENT, uid, 108);
84AssertCompileMemberOffset(RTZIPTARHDRANCIENT, gid, 116);
85AssertCompileMemberOffset(RTZIPTARHDRANCIENT, size, 124);
86AssertCompileMemberOffset(RTZIPTARHDRANCIENT, mtime, 136);
87AssertCompileMemberOffset(RTZIPTARHDRANCIENT, chksum, 148);
88AssertCompileMemberOffset(RTZIPTARHDRANCIENT, typeflag, 156);
89AssertCompileMemberOffset(RTZIPTARHDRANCIENT, linkname, 157);
90AssertCompileMemberOffset(RTZIPTARHDRANCIENT, unused, 257);
91
92
93/** The uniform standard tape archive format magic value. */
94#define RTZIPTAR_USTAR_MAGIC "ustar"
95/** The ustar version string.
96 * @remarks The terminator character is not part of the field. */
97#define RTZIPTAR_USTAR_VERSION "00"
98
99/** The GNU magic + version value. */
100#define RTZIPTAR_GNU_MAGIC "ustar "
101
102
103/**
104 * The posix header (according to SuS).
105 */
106typedef struct RTZIPTARHDRPOSIX
107{
108 char name[100];
109 char mode[8];
110 char uid[8];
111 char gid[8];
112 char size[12];
113 char mtime[12];
114 char chksum[8];
115 char typeflag;
116 char linkname[100];
117 char magic[6];
118 char version[2];
119 char uname[32];
120 char gname[32];
121 char devmajor[8];
122 char devminor[8];
123 char prefix[155];
124 char unused[12];
125} RTZIPTARHDRPOSIX;
126AssertCompileSize(RTZIPTARHDRPOSIX, 512);
127AssertCompileMemberOffset(RTZIPTARHDRPOSIX, name, 0);
128AssertCompileMemberOffset(RTZIPTARHDRPOSIX, mode, 100);
129AssertCompileMemberOffset(RTZIPTARHDRPOSIX, uid, 108);
130AssertCompileMemberOffset(RTZIPTARHDRPOSIX, gid, 116);
131AssertCompileMemberOffset(RTZIPTARHDRPOSIX, size, 124);
132AssertCompileMemberOffset(RTZIPTARHDRPOSIX, mtime, 136);
133AssertCompileMemberOffset(RTZIPTARHDRPOSIX, chksum, 148);
134AssertCompileMemberOffset(RTZIPTARHDRPOSIX, typeflag, 156);
135AssertCompileMemberOffset(RTZIPTARHDRPOSIX, linkname, 157);
136AssertCompileMemberOffset(RTZIPTARHDRPOSIX, magic, 257);
137AssertCompileMemberOffset(RTZIPTARHDRPOSIX, version, 263);
138AssertCompileMemberOffset(RTZIPTARHDRPOSIX, uname, 265);
139AssertCompileMemberOffset(RTZIPTARHDRPOSIX, gname, 297);
140AssertCompileMemberOffset(RTZIPTARHDRPOSIX, devmajor, 329);
141AssertCompileMemberOffset(RTZIPTARHDRPOSIX, devminor, 337);
142AssertCompileMemberOffset(RTZIPTARHDRPOSIX, prefix, 345);
143
144/**
145 * GNU sparse data segment descriptor.
146 */
147typedef struct RTZIPTARGNUSPARSE
148{
149 char offset[12]; /**< Absolute offset relative to the start of the file. */
150 char numbytes[12];
151} RTZIPTARGNUSPARSE;
152AssertCompileSize(RTZIPTARGNUSPARSE, 24);
153AssertCompileMemberOffset(RTZIPTARGNUSPARSE, offset, 0);
154AssertCompileMemberOffset(RTZIPTARGNUSPARSE, numbytes, 12);
155/** Pointer to a GNU sparse data segment descriptor. */
156typedef RTZIPTARGNUSPARSE *PRTZIPTARGNUSPARSE;
157/** Pointer to a const GNU sparse data segment descriptor. */
158typedef RTZIPTARGNUSPARSE *PCRTZIPTARGNUSPARSE;
159
160/**
161 * The GNU header.
162 */
163typedef struct RTZIPTARHDRGNU
164{
165 char name[100];
166 char mode[8];
167 char uid[8];
168 char gid[8];
169 char size[12];
170 char mtime[12];
171 char chksum[8];
172 char typeflag;
173 char linkname[100];
174 char magic[8];
175 char uname[32];
176 char gname[32];
177 char devmajor[8];
178 char devminor[8];
179 char atime[12];
180 char ctime[12];
181 char offset[12]; /**< for multi-volume? */
182 char longnames[4]; /**< Seems to be unused. */
183 char unused[1];
184 RTZIPTARGNUSPARSE sparse[4];
185 char isextended; /**< More headers about sparse stuff if binary value 1. */
186 char realsize[12];
187 char unused2[17];
188} RTZIPTARHDRGNU;
189AssertCompileSize(RTZIPTARHDRGNU, 512);
190AssertCompileMemberOffset(RTZIPTARHDRGNU, name, 0);
191AssertCompileMemberOffset(RTZIPTARHDRGNU, mode, 100);
192AssertCompileMemberOffset(RTZIPTARHDRGNU, uid, 108);
193AssertCompileMemberOffset(RTZIPTARHDRGNU, gid, 116);
194AssertCompileMemberOffset(RTZIPTARHDRGNU, size, 124);
195AssertCompileMemberOffset(RTZIPTARHDRGNU, mtime, 136);
196AssertCompileMemberOffset(RTZIPTARHDRGNU, chksum, 148);
197AssertCompileMemberOffset(RTZIPTARHDRGNU, typeflag, 156);
198AssertCompileMemberOffset(RTZIPTARHDRGNU, linkname, 157);
199AssertCompileMemberOffset(RTZIPTARHDRGNU, magic, 257);
200AssertCompileMemberOffset(RTZIPTARHDRGNU, uname, 265);
201AssertCompileMemberOffset(RTZIPTARHDRGNU, gname, 297);
202AssertCompileMemberOffset(RTZIPTARHDRGNU, devmajor, 329);
203AssertCompileMemberOffset(RTZIPTARHDRGNU, devminor, 337);
204AssertCompileMemberOffset(RTZIPTARHDRGNU, atime, 345);
205AssertCompileMemberOffset(RTZIPTARHDRGNU, ctime, 357);
206AssertCompileMemberOffset(RTZIPTARHDRGNU, offset, 369);
207AssertCompileMemberOffset(RTZIPTARHDRGNU, longnames, 381);
208AssertCompileMemberOffset(RTZIPTARHDRGNU, unused, 385);
209AssertCompileMemberOffset(RTZIPTARHDRGNU, sparse, 386);
210AssertCompileMemberOffset(RTZIPTARHDRGNU, isextended,482);
211AssertCompileMemberOffset(RTZIPTARHDRGNU, realsize, 483);
212AssertCompileMemberOffset(RTZIPTARHDRGNU, unused2, 495);
213
214
215/**
216 * GNU sparse header.
217 */
218typedef struct RTZIPTARHDRGNUSPARSE
219{
220 RTZIPTARGNUSPARSE sp[21];
221 char isextended;
222 char unused[7];
223} RTZIPTARHDRGNUSPARSE;
224AssertCompileSize(RTZIPTARHDRGNUSPARSE, 512);
225AssertCompileMemberOffset(RTZIPTARHDRGNUSPARSE, sp, 0);
226AssertCompileMemberOffset(RTZIPTARHDRGNUSPARSE, isextended, 504);
227AssertCompileMemberOffset(RTZIPTARHDRGNUSPARSE, unused, 505);
228
229
230/**
231 * The bits common to posix and GNU.
232 */
233typedef struct RTZIPTARHDRCOMMON
234{
235 char name[100];
236 char mode[8];
237 char uid[8];
238 char gid[8];
239 char size[12];
240 char mtime[12];
241 char chksum[8];
242 char typeflag;
243 char linkname[100];
244 char magic[6];
245 char version[2];
246 char uname[32];
247 char gname[32];
248 char devmajor[8];
249 char devminor[8];
250 char not_common[155+12];
251} RTZIPTARHDRCOMMON;
252AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, name, RTZIPTARHDRPOSIX, name);
253AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mode, RTZIPTARHDRPOSIX, mode);
254AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uid, RTZIPTARHDRPOSIX, uid);
255AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gid, RTZIPTARHDRPOSIX, gid);
256AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, size, RTZIPTARHDRPOSIX, size);
257AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mtime, RTZIPTARHDRPOSIX, mtime);
258AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, chksum, RTZIPTARHDRPOSIX, chksum);
259AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, typeflag, RTZIPTARHDRPOSIX, typeflag);
260AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, linkname, RTZIPTARHDRPOSIX, linkname);
261AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, magic, RTZIPTARHDRPOSIX, magic);
262AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, version, RTZIPTARHDRPOSIX, version);
263AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uname, RTZIPTARHDRPOSIX, uname);
264AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gname, RTZIPTARHDRPOSIX, gname);
265AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devmajor, RTZIPTARHDRPOSIX, devmajor);
266AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devminor, RTZIPTARHDRPOSIX, devminor);
267
268AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, name, RTZIPTARHDRGNU, name);
269AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mode, RTZIPTARHDRGNU, mode);
270AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uid, RTZIPTARHDRGNU, uid);
271AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gid, RTZIPTARHDRGNU, gid);
272AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, size, RTZIPTARHDRGNU, size);
273AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mtime, RTZIPTARHDRGNU, mtime);
274AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, chksum, RTZIPTARHDRGNU, chksum);
275AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, typeflag, RTZIPTARHDRGNU, typeflag);
276AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, linkname, RTZIPTARHDRGNU, linkname);
277AssertCompileMembersAtSameOffset( RTZIPTARHDRCOMMON, magic, RTZIPTARHDRGNU, magic);
278AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uname, RTZIPTARHDRGNU, uname);
279AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gname, RTZIPTARHDRGNU, gname);
280AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devmajor, RTZIPTARHDRGNU, devmajor);
281AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devminor, RTZIPTARHDRGNU, devminor);
282
283
284
285/**
286 * Tar header union.
287 */
288typedef union RTZIPTARHDR
289{
290 /** Byte view. */
291 char ab[512];
292 /** The standard header. */
293 RTZIPTARHDRANCIENT Ancient;
294 /** The standard header. */
295 RTZIPTARHDRPOSIX Posix;
296 /** The GNU header. */
297 RTZIPTARHDRGNU Gnu;
298 /** The bits common to both GNU and the standard header. */
299 RTZIPTARHDRCOMMON Common;
300 /** GNU sparse header. */
301 RTZIPTARHDRGNUSPARSE GnuSparse;
302} RTZIPTARHDR;
303AssertCompileSize(RTZIPTARHDR, 512);
304/** Pointer to a tar file header. */
305typedef RTZIPTARHDR *PRTZIPTARHDR;
306/** Pointer to a const tar file header. */
307typedef RTZIPTARHDR const *PCRTZIPTARHDR;
308
309
310/**
311 * Tar header type.
312 */
313typedef enum RTZIPTARTYPE
314{
315 /** Invalid type value. */
316 RTZIPTARTYPE_INVALID = 0,
317 /** Posix header. */
318 RTZIPTARTYPE_POSIX,
319 /** The old GNU header, has layout conflicting with posix. */
320 RTZIPTARTYPE_GNU,
321 /** Ancient tar header which does not use anything beyond the magic. */
322 RTZIPTARTYPE_ANCIENT,
323 /** End of the valid type values (this is not valid). */
324 RTZIPTARTYPE_END,
325 /** The usual type blow up. */
326 RTZIPTARTYPE_32BIT_HACK = 0x7fffffff
327} RTZIPTARTYPE;
328typedef RTZIPTARTYPE *PRTZIPTARTYPE;
329
330
331/**
332 * Calculates the TAR header checksums and detects if it's all zeros.
333 *
334 * @returns true if all zeros, false if not.
335 * @param pHdr The header to checksum.
336 * @param pi32Unsigned Where to store the checksum calculated using
337 * unsigned chars. This is the one POSIX specifies.
338 * @param pi32Signed Where to store the checksum calculated using
339 * signed chars.
340 *
341 * @remarks The reason why we calculate the checksum as both signed and unsigned
342 * has to do with various the char C type being signed on some hosts
343 * and unsigned on others.
344 */
345DECLINLINE(bool) rtZipTarCalcChkSum(PCRTZIPTARHDR pHdr, int32_t *pi32Unsigned, int32_t *pi32Signed)
346{
347 int32_t i32Unsigned = 0;
348 int32_t i32Signed = 0;
349
350 /*
351 * Sum up the entire header.
352 */
353 const char *pch = (const char *)pHdr;
354 const char *pchEnd = pch + sizeof(*pHdr);
355 do
356 {
357 i32Unsigned += *(unsigned char *)pch;
358 i32Signed += *(signed char *)pch;
359 } while (++pch != pchEnd);
360
361 /*
362 * Check if it's all zeros and replace the chksum field with spaces.
363 */
364 bool const fZeroHdr = i32Unsigned == 0;
365
366 pch = pHdr->Common.chksum;
367 pchEnd = pch + sizeof(pHdr->Common.chksum);
368 do
369 {
370 i32Unsigned -= *(unsigned char *)pch;
371 i32Signed -= *(signed char *)pch;
372 } while (++pch != pchEnd);
373
374 i32Unsigned += (unsigned char)' ' * sizeof(pHdr->Common.chksum);
375 i32Signed += (signed char)' ' * sizeof(pHdr->Common.chksum);
376
377 *pi32Unsigned = i32Unsigned;
378 if (pi32Signed)
379 *pi32Signed = i32Signed;
380 return fZeroHdr;
381}
382
383
384#endif /* !IPRT_INCLUDED_SRC_common_zip_tar_h */
385
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette