| 44 | | |
|---|
| 45 | | #define TMAGIC "ustar" /* ustar and a null */ |
|---|
| 46 | | #define TMAGLEN 6 |
|---|
| 47 | | #define TVERSION "00" /* 00 and no null */ |
|---|
| 48 | | #define TVERSLEN 2 |
|---|
| 49 | | |
|---|
| 50 | | /* Values used in typeflag field. */ |
|---|
| 51 | | #define REGTYPE '0' /* regular file */ |
|---|
| 52 | | #define AREGTYPE '\0' /* regular file */ |
|---|
| 53 | | #define LNKTYPE '1' /* link */ |
|---|
| 54 | | #define SYMTYPE '2' /* reserved */ |
|---|
| 55 | | #define CHRTYPE '3' /* character special */ |
|---|
| 56 | | #define BLKTYPE '4' /* block special */ |
|---|
| 57 | | #define DIRTYPE '5' /* directory */ |
|---|
| 58 | | #define FIFOTYPE '6' /* FIFO special */ |
|---|
| 59 | | #define CONTTYPE '7' /* reserved */ |
|---|
| 60 | | |
|---|
| 61 | | #define XHDTYPE 'x' /* Extended header referring to the |
|---|
| 62 | | next file in the archive */ |
|---|
| 63 | | #define XGLTYPE 'g' /* Global extended header */ |
|---|
| 64 | | |
|---|
| 65 | | /* Bits used in the mode field, values in octal. */ |
|---|
| 66 | | #define TSUID 04000 /* set UID on execution */ |
|---|
| 67 | | #define TSGID 02000 /* set GID on execution */ |
|---|
| 68 | | #define TSVTX 01000 /* reserved */ |
|---|
| 69 | | /* file permissions */ |
|---|
| 70 | | #define TUREAD 00400 /* read by owner */ |
|---|
| 71 | | #define TUWRITE 00200 /* write by owner */ |
|---|
| 72 | | #define TUEXEC 00100 /* execute/search by owner */ |
|---|
| 73 | | #define TGREAD 00040 /* read by group */ |
|---|
| 74 | | #define TGWRITE 00020 /* write by group */ |
|---|
| 75 | | #define TGEXEC 00010 /* execute/search by group */ |
|---|
| 76 | | #define TOREAD 00004 /* read by other */ |
|---|
| 77 | | #define TOWRITE 00002 /* write by other */ |
|---|
| 78 | | #define TOEXEC 00001 /* execute/search by other */ |
|---|
| 79 | | |
|---|
| 80 | | /* tar Header Block, GNU extensions. */ |
|---|
| 81 | | |
|---|
| 82 | | /* In GNU tar, SYMTYPE is for to symbolic links, and CONTTYPE is for |
|---|
| 83 | | contiguous files, so maybe disobeying the `reserved' comment in POSIX |
|---|
| 84 | | header description. I suspect these were meant to be used this way, and |
|---|
| 85 | | should not have really been `reserved' in the published standards. */ |
|---|
| 86 | | |
|---|
| 87 | | /* *BEWARE* *BEWARE* *BEWARE* that the following information is still |
|---|
| 88 | | boiling, and may change. Even if the OLDGNU format description should be |
|---|
| 89 | | accurate, the so-called GNU format is not yet fully decided. It is |
|---|
| 90 | | surely meant to use only extensions allowed by POSIX, but the sketch |
|---|
| 91 | | below repeats some ugliness from the OLDGNU format, which should rather |
|---|
| 92 | | go away. Sparse files should be saved in such a way that they do *not* |
|---|
| 93 | | require two passes at archive creation time. Huge files get some POSIX |
|---|
| 94 | | fields to overflow, alternate solutions have to be sought for this. */ |
|---|
| 95 | | |
|---|
| 96 | | /* Descriptor for a single file hole. */ |
|---|
| 97 | | |
|---|
| 98 | | struct sparse |
|---|
| 99 | | { /* byte offset */ |
|---|
| 100 | | char offset[12]; /* 0 */ |
|---|
| 101 | | char numbytes[12]; /* 12 */ |
|---|
| 102 | | /* 24 */ |
|---|
| 103 | | }; |
|---|
| 104 | | |
|---|
| 105 | | /* Sparse files are not supported in POSIX ustar format. For sparse files |
|---|
| 106 | | with a POSIX header, a GNU extra header is provided which holds overall |
|---|
| 107 | | sparse information and a few sparse descriptors. When an old GNU header |
|---|
| 108 | | replaces both the POSIX header and the GNU extra header, it holds some |
|---|
| 109 | | sparse descriptors too. Whether POSIX or not, if more sparse descriptors |
|---|
| 110 | | are still needed, they are put into as many successive sparse headers as |
|---|
| 111 | | necessary. The following constants tell how many sparse descriptors fit |
|---|
| 112 | | in each kind of header able to hold them. */ |
|---|
| 113 | | |
|---|
| 114 | | #define SPARSES_IN_EXTRA_HEADER 16 |
|---|
| 115 | | #define SPARSES_IN_OLDGNU_HEADER 4 |
|---|
| 116 | | #define SPARSES_IN_SPARSE_HEADER 21 |
|---|
| 117 | | |
|---|
| 118 | | /* Extension header for sparse files, used immediately after the GNU extra |
|---|
| 119 | | header, and used only if all sparse information cannot fit into that |
|---|
| 120 | | extra header. There might even be many such extension headers, one after |
|---|
| 121 | | the other, until all sparse information has been recorded. */ |
|---|
| 122 | | |
|---|
| 123 | | struct sparse_header |
|---|
| 124 | | { /* byte offset */ |
|---|
| 125 | | struct sparse sp[SPARSES_IN_SPARSE_HEADER]; |
|---|
| 126 | | /* 0 */ |
|---|
| 127 | | char isextended; /* 504 */ |
|---|
| 128 | | /* 505 */ |
|---|
| 129 | | }; |
|---|
| 130 | | |
|---|
| 131 | | /* The old GNU format header conflicts with POSIX format in such a way that |
|---|
| 132 | | POSIX archives may fool old GNU tar's, and POSIX tar's might well be |
|---|
| 133 | | fooled by old GNU tar archives. An old GNU format header uses the space |
|---|
| 134 | | used by the prefix field in a POSIX header, and cumulates information |
|---|
| 135 | | normally found in a GNU extra header. With an old GNU tar header, we |
|---|
| 136 | | never see any POSIX header nor GNU extra header. Supplementary sparse |
|---|
| 137 | | headers are allowed, however. */ |
|---|
| 138 | | |
|---|
| 139 | | struct oldgnu_header |
|---|
| 140 | | { /* byte offset */ |
|---|
| 141 | | char unused_pad1[345]; /* 0 */ |
|---|
| 142 | | char atime[12]; /* 345 Incr. archive: atime of the file */ |
|---|
| 143 | | char ctime[12]; /* 357 Incr. archive: ctime of the file */ |
|---|
| 144 | | char offset[12]; /* 369 Multivolume archive: the offset of |
|---|
| 145 | | the start of this volume */ |
|---|
| 146 | | char longnames[4]; /* 381 Not used */ |
|---|
| 147 | | char unused_pad2; /* 385 */ |
|---|
| 148 | | struct sparse sp[SPARSES_IN_OLDGNU_HEADER]; |
|---|
| 149 | | /* 386 */ |
|---|
| 150 | | char isextended; /* 482 Sparse file: Extension sparse header |
|---|
| 151 | | follows */ |
|---|
| 152 | | char realsize[12]; /* 483 Sparse file: Real size*/ |
|---|
| 153 | | /* 495 */ |
|---|
| 154 | | }; |
|---|
| 155 | | |
|---|
| 156 | | /* OLDGNU_MAGIC uses both magic and version fields, which are contiguous. |
|---|
| 157 | | Found in an archive, it indicates an old GNU header format, which will be |
|---|
| 158 | | hopefully become obsolescent. With OLDGNU_MAGIC, uname and gname are |
|---|
| 159 | | valid, though the header is not truly POSIX conforming. */ |
|---|
| 160 | | #define OLDGNU_MAGIC "ustar " /* 7 chars and a null */ |
|---|
| 161 | | |
|---|
| 162 | | /* The standards committee allows only capital A through capital Z for |
|---|
| 163 | | user-defined expansion. Other letters in use include: |
|---|
| 164 | | |
|---|
| 165 | | 'A' Solaris Access Control List |
|---|
| 166 | | 'E' Solaris Extended Attribute File |
|---|
| 167 | | 'I' Inode only, as in 'star' |
|---|
| 168 | | 'N' Obsolete GNU tar, for file names that do not fit into the main header. |
|---|
| 169 | | 'X' POSIX 1003.1-2001 eXtended (VU version) */ |
|---|
| 170 | | |
|---|
| 171 | | /* This is a dir entry that contains the names of files that were in the |
|---|
| 172 | | dir at the time the dump was made. */ |
|---|
| 173 | | #define GNUTYPE_DUMPDIR 'D' |
|---|
| 174 | | |
|---|
| 175 | | /* Identifies the *next* file on the tape as having a long linkname. */ |
|---|
| 176 | | #define GNUTYPE_LONGLINK 'K' |
|---|
| 177 | | |
|---|
| 178 | | /* Identifies the *next* file on the tape as having a long name. */ |
|---|
| 179 | | #define GNUTYPE_LONGNAME 'L' |
|---|
| 180 | | |
|---|
| 181 | | /* This is the continuation of a file that began on another volume. */ |
|---|
| 182 | | #define GNUTYPE_MULTIVOL 'M' |
|---|
| 183 | | |
|---|
| 184 | | /* This is for sparse files. */ |
|---|
| 185 | | #define GNUTYPE_SPARSE 'S' |
|---|
| 186 | | |
|---|
| 187 | | /* This file is a tape/volume header. Ignore it on extraction. */ |
|---|
| 188 | | #define GNUTYPE_VOLHDR 'V' |
|---|
| 189 | | |
|---|
| 190 | | /* Solaris extended header */ |
|---|
| 191 | | #define SOLARIS_XHDTYPE 'X' |
|---|
| 192 | | |
|---|
| 193 | | /* J@"org Schilling star header */ |
|---|
| 194 | | |
|---|
| 195 | | struct star_header |
|---|
| 196 | | { /* byte offset */ |
|---|
| 197 | | char name[100]; /* 0 */ |
|---|
| 198 | | char mode[8]; /* 100 */ |
|---|
| 199 | | char uid[8]; /* 108 */ |
|---|
| 200 | | char gid[8]; /* 116 */ |
|---|
| 201 | | char size[12]; /* 124 */ |
|---|
| 202 | | char mtime[12]; /* 136 */ |
|---|
| 203 | | char chksum[8]; /* 148 */ |
|---|
| 204 | | char typeflag; /* 156 */ |
|---|
| 205 | | char linkname[100]; /* 157 */ |
|---|
| 206 | | char magic[6]; /* 257 */ |
|---|
| 207 | | char version[2]; /* 263 */ |
|---|
| 208 | | char uname[32]; /* 265 */ |
|---|
| 209 | | char gname[32]; /* 297 */ |
|---|
| 210 | | char devmajor[8]; /* 329 */ |
|---|
| 211 | | char devminor[8]; /* 337 */ |
|---|
| 212 | | char prefix[131]; /* 345 */ |
|---|
| 213 | | char atime[12]; /* 476 */ |
|---|
| 214 | | char ctime[12]; /* 488 */ |
|---|
| 215 | | /* 500 */ |
|---|
| 216 | | }; |
|---|
| 217 | | |
|---|
| 218 | | #define SPARSES_IN_STAR_HEADER 4 |
|---|
| 219 | | #define SPARSES_IN_STAR_EXT_HEADER 21 |
|---|
| 220 | | |
|---|
| 221 | | struct star_in_header |
|---|
| 222 | | { |
|---|
| 223 | | char fill[345]; /* 0 Everything that is before t_prefix */ |
|---|
| 224 | | char prefix[1]; /* 345 t_name prefix */ |
|---|
| 225 | | char fill2; /* 346 */ |
|---|
| 226 | | char fill3[8]; /* 347 */ |
|---|
| 227 | | char isextended; /* 355 */ |
|---|
| 228 | | struct sparse sp[SPARSES_IN_STAR_HEADER]; /* 356 */ |
|---|
| 229 | | char realsize[12]; /* 452 Actual size of the file */ |
|---|
| 230 | | char offset[12]; /* 464 Offset of multivolume contents */ |
|---|
| 231 | | char atime[12]; /* 476 */ |
|---|
| 232 | | char ctime[12]; /* 488 */ |
|---|
| 233 | | char mfill[8]; /* 500 */ |
|---|
| 234 | | char xmagic[4]; /* 508 "tar" */ |
|---|
| 235 | | }; |
|---|
| 236 | | |
|---|
| 237 | | struct star_ext_header |
|---|
| 238 | | { |
|---|
| 239 | | struct sparse sp[SPARSES_IN_STAR_EXT_HEADER]; |
|---|
| 240 | | char isextended; |
|---|
| 241 | | }; |
|---|
| 242 | | |
|---|
| 243 | | /* END */ |
|---|
| 244 | | |
|---|
| 245 | | |
|---|
| 246 | | /* tar Header Block, overall structure. */ |
|---|
| 247 | | |
|---|
| 248 | | /* tar files are made in basic blocks of this size. */ |
|---|
| 249 | | #define BLOCKSIZE 512 |
|---|
| 250 | | |
|---|
| 251 | | enum archive_format |
|---|
| 252 | | { |
|---|
| 253 | | DEFAULT_FORMAT, /* format to be decided later */ |
|---|
| 254 | | V7_FORMAT, /* old V7 tar format */ |
|---|
| 255 | | OLDGNU_FORMAT, /* GNU format as per before tar 1.12 */ |
|---|
| 256 | | USTAR_FORMAT, /* POSIX.1-1988 (ustar) format */ |
|---|
| 257 | | POSIX_FORMAT, /* POSIX.1-2001 format */ |
|---|
| 258 | | STAR_FORMAT, /* Star format defined in 1994 */ |
|---|
| 259 | | GNU_FORMAT /* Same as OLDGNU_FORMAT with one exception: |
|---|
| 260 | | see FIXME note for to_chars() function |
|---|
| 261 | | (create.c:189) */ |
|---|
| 262 | | }; |
|---|
| 263 | | |
|---|
| 264 | | /* Information about a sparse file. */ |
|---|
| 265 | | struct sp_array |
|---|
| 266 | | { |
|---|
| 267 | | off_t offset; |
|---|
| 268 | | size_t numbytes; |
|---|
| 269 | | }; |
|---|
| 270 | | |
|---|
| 271 | | struct xheader |
|---|
| 272 | | { |
|---|
| 273 | | struct obstack *stk; |
|---|
| 274 | | size_t size; |
|---|
| 275 | | char *buffer; |
|---|
| 276 | | uintmax_t string_length; |
|---|
| 277 | | }; |
|---|
| 278 | | |
|---|
| 279 | | struct tar_stat_info |
|---|
| 280 | | { |
|---|
| 281 | | char *orig_file_name; /* name of file read from the archive header */ |
|---|
| 282 | | char *file_name; /* name of file for the current archive entry |
|---|
| 283 | | after being normalized. */ |
|---|
| 284 | | bool had_trailing_slash; /* true if the current archive entry had a |
|---|
| 285 | | trailing slash before it was normalized. */ |
|---|
| 286 | | char *link_name; /* name of link for the current archive entry. */ |
|---|
| 287 | | |
|---|
| 288 | | char *uname; /* user name of owner */ |
|---|
| 289 | | char *gname; /* group name of owner */ |
|---|
| 290 | | struct stat stat; /* regular filesystem stat */ |
|---|
| 291 | | |
|---|
| 292 | | /* STAT doesn't always have access, data modification, and status |
|---|
| 293 | | change times in a convenient form, so store them separately. */ |
|---|
| 294 | | struct timespec atime; |
|---|
| 295 | | struct timespec mtime; |
|---|
| 296 | | struct timespec ctime; |
|---|
| 297 | | |
|---|
| 298 | | off_t archive_file_size; /* Size of file as stored in the archive. |
|---|
| 299 | | Equals stat.st_size for non-sparse files */ |
|---|
| 300 | | |
|---|
| 301 | | bool is_sparse; /* Is the file sparse */ |
|---|
| 302 | | |
|---|
| 303 | | /* For sparse files: */ |
|---|
| 304 | | unsigned sparse_major; |
|---|
| 305 | | unsigned sparse_minor; |
|---|
| 306 | | size_t sparse_map_avail; /* Index to the first unused element in |
|---|
| 307 | | sparse_map array. Zero if the file is |
|---|
| 308 | | not sparse */ |
|---|
| 309 | | size_t sparse_map_size; /* Size of the sparse map */ |
|---|
| 310 | | struct sp_array *sparse_map; |
|---|
| 311 | | |
|---|
| 312 | | /* Extended headers */ |
|---|
| 313 | | struct xheader xhdr; |
|---|
| 314 | | |
|---|
| 315 | | /* For dumpdirs */ |
|---|
| 316 | | bool is_dumpdir; /* Is the member a dumpdir? */ |
|---|
| 317 | | bool skipped; /* The member contents is already read |
|---|
| 318 | | (for GNUTYPE_DUMPDIR) */ |
|---|
| 319 | | char *dumpdir; /* Contents of the dump directory */ |
|---|
| 320 | | }; |
|---|
| 321 | | |
|---|
| 322 | | union block |
|---|
| 323 | | { |
|---|
| 324 | | char buffer[BLOCKSIZE]; |
|---|
| 325 | | struct posix_header header; |
|---|
| 326 | | struct star_header star_header; |
|---|
| 327 | | struct oldgnu_header oldgnu_header; |
|---|
| 328 | | struct sparse_header sparse_header; |
|---|
| 329 | | struct star_in_header star_in_header; |
|---|
| 330 | | struct star_ext_header star_ext_header; |
|---|
| 331 | | }; |
|---|