root/src/vfs/tar/tar-internal.h

/* [previous][next][first][last][top][bottom][index][help]  */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. tar_represent_uintmax

   1 
   2 #ifndef MC__VFS_TAR_INTERNAL_H
   3 #define MC__VFS_TAR_INTERNAL_H
   4 
   5 #include <inttypes.h>           /* (u)intmax_t */
   6 #include <limits.h>             /* CHAR_BIT, INT_MAX, etc */
   7 #include <sys/stat.h>
   8 #include <sys/types.h>
   9 
  10 #include "lib/vfs/xdirentry.h"  /* vfs_s_super */
  11 
  12 /*** typedefs(not structures) and defined constants **********************************************/
  13 
  14 /* tar files are made in basic blocks of this size.  */
  15 #define BLOCKSIZE 512
  16 
  17 #define DEFAULT_BLOCKING 20
  18 
  19 /* Sparse files are not supported in POSIX ustar format.  For sparse files
  20    with a POSIX header, a GNU extra header is provided which holds overall
  21    sparse information and a few sparse descriptors.  When an old GNU header
  22    replaces both the POSIX header and the GNU extra header, it holds some
  23    sparse descriptors too.  Whether POSIX or not, if more sparse descriptors
  24    are still needed, they are put into as many successive sparse headers as
  25    necessary.  The following constants tell how many sparse descriptors fit
  26    in each kind of header able to hold them.  */
  27 
  28 #define SPARSES_IN_EXTRA_HEADER  16
  29 #define SPARSES_IN_OLDGNU_HEADER 4
  30 #define SPARSES_IN_SPARSE_HEADER 21
  31 
  32 #define SPARSES_IN_STAR_HEADER      4
  33 #define SPARSES_IN_STAR_EXT_HEADER 21
  34 
  35 /* *BEWARE* *BEWARE* *BEWARE* that the following information is still
  36    boiling, and may change.  Even if the OLDGNU format description should be
  37    accurate, the so-called GNU format is not yet fully decided.  It is
  38    surely meant to use only extensions allowed by POSIX, but the sketch
  39    below repeats some ugliness from the OLDGNU format, which should rather
  40    go away.  Sparse files should be saved in such a way that they do *not*
  41    require two passes at archive creation time.  Huge files get some POSIX
  42    fields to overflow, alternate solutions have to be sought for this.  */
  43 
  44 /* This is a dir entry that contains the names of files that were in the
  45    dir at the time the dump was made.  */
  46 #define GNUTYPE_DUMPDIR 'D'
  47 
  48 /* Identifies the *next* file on the tape as having a long linkname.  */
  49 #define GNUTYPE_LONGLINK 'K'
  50 
  51 /* Identifies the *next* file on the tape as having a long name.  */
  52 #define GNUTYPE_LONGNAME 'L'
  53 
  54 /* Solaris extended header */
  55 #define SOLARIS_XHDTYPE 'X'
  56 
  57 #define GNUTYPE_SPARSE 'S'
  58 
  59 
  60 /* These macros work even on ones'-complement hosts (!).
  61    The extra casts work around some compiler bugs. */
  62 #define TYPE_SIGNED(t) (!((t) 0 < (t) (-1)))
  63 #define TYPE_MINIMUM(t) (TYPE_SIGNED (t) ? ~(t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)
  64 #define TYPE_MAXIMUM(t) (~(t) 0 - TYPE_MINIMUM (t))
  65 
  66 #define OFF_FROM_HEADER(where) off_from_header (where, sizeof (where))
  67 
  68 /*** enums ***************************************************************************************/
  69 
  70 /*** structures declarations (and typedefs of structures)*****************************************/
  71 
  72 /* *INDENT-OFF* */
  73 
  74 /* POSIX header */
  75 struct posix_header
  76 {                               /* byte offset */
  77     char name[100];             /*   0 */
  78     char mode[8];               /* 100 */
  79     char uid[8];                /* 108 */
  80     char gid[8];                /* 116 */
  81     char size[12];              /* 124 */
  82     char mtime[12];             /* 136 */
  83     char chksum[8];             /* 148 */
  84     char typeflag;              /* 156 */
  85     char linkname[100];         /* 157 */
  86     char magic[6];              /* 257 */
  87     char version[2];            /* 263 */
  88     char uname[32];             /* 265 */
  89     char gname[32];             /* 297 */
  90     char devmajor[8];           /* 329 */
  91     char devminor[8];           /* 337 */
  92     char prefix[155];           /* 345 */
  93                                 /* 500 */
  94 };
  95 
  96 /* Descriptor for a single file hole */
  97 struct sparse
  98 {                               /* byte offset */
  99     /* cppcheck-suppress unusedStructMember */
 100     char offset[12];            /*   0 */
 101     /* cppcheck-suppress unusedStructMember */
 102     char numbytes[12];          /*  12 */
 103                                 /*  24 */
 104 };
 105 
 106 /* Extension header for sparse files, used immediately after the GNU extra
 107    header, and used only if all sparse information cannot fit into that
 108    extra header.  There might even be many such extension headers, one after
 109    the other, until all sparse information has been recorded.  */
 110 struct sparse_header
 111 {                               /* byte offset */
 112     struct sparse sp[SPARSES_IN_SPARSE_HEADER];
 113                                 /*   0 */
 114     char isextended;            /* 504 */
 115                                 /* 505 */
 116 };
 117 
 118 /* The old GNU format header conflicts with POSIX format in such a way that
 119    POSIX archives may fool old GNU tar's, and POSIX tar's might well be
 120    fooled by old GNU tar archives.  An old GNU format header uses the space
 121    used by the prefix field in a POSIX header, and cumulates information
 122    normally found in a GNU extra header.  With an old GNU tar header, we
 123    never see any POSIX header nor GNU extra header.  Supplementary sparse
 124    headers are allowed, however.  */
 125 struct oldgnu_header
 126 {                               /* byte offset */
 127     char unused_pad1[345];      /*   0 */
 128     char atime[12];             /* 345 Incr. archive: atime of the file */
 129     char ctime[12];             /* 357 Incr. archive: ctime of the file */
 130     char offset[12];            /* 369 Multivolume archive: the offset of start of this volume */
 131     char longnames[4];          /* 381 Not used */
 132     char unused_pad2;           /* 385 */
 133     struct sparse sp[SPARSES_IN_OLDGNU_HEADER];
 134                                 /* 386 */
 135     char isextended;            /* 482 Sparse file: Extension sparse header follows */
 136     char realsize[12];          /* 483 Sparse file: Real size */
 137                                 /* 495 */
 138 };
 139 
 140 /* J@"org Schilling star header */
 141 struct star_header
 142 {                               /* byte offset */
 143     char name[100];             /*   0 */
 144     char mode[8];               /* 100 */
 145     char uid[8];                /* 108 */
 146     char gid[8];                /* 116 */
 147     char size[12];              /* 124 */
 148     char mtime[12];             /* 136 */
 149     char chksum[8];             /* 148 */
 150     char typeflag;              /* 156 */
 151     char linkname[100];         /* 157 */
 152     char magic[6];              /* 257 */
 153     char version[2];            /* 263 */
 154     char uname[32];             /* 265 */
 155     char gname[32];             /* 297 */
 156     char devmajor[8];           /* 329 */
 157     char devminor[8];           /* 337 */
 158     char prefix[131];           /* 345 */
 159     char atime[12];             /* 476 */
 160     char ctime[12];             /* 488 */
 161                                 /* 500 */
 162 };
 163 
 164 struct star_in_header
 165 {
 166     char fill[345];             /*   0  Everything that is before t_prefix */
 167     char prefix[1];             /* 345  t_name prefix */
 168     char fill2;                 /* 346  */
 169     char fill3[8];              /* 347  */
 170     char isextended;            /* 355  */
 171     struct sparse sp[SPARSES_IN_STAR_HEADER]; /* 356  */
 172     char realsize[12];          /* 452  Actual size of the file */
 173     char offset[12];            /* 464  Offset of multivolume contents */
 174     char atime[12];             /* 476  */
 175     char ctime[12];             /* 488  */
 176     char mfill[8];              /* 500  */
 177     char xmagic[4];             /* 508  "tar" */
 178 };
 179 
 180 struct star_ext_header
 181 {
 182     struct sparse sp[SPARSES_IN_STAR_EXT_HEADER];
 183     char isextended;
 184 };
 185 
 186 /* *INDENT-ON* */
 187 
 188 /* tar Header Block, overall structure */
 189 union block
 190 {
 191     char buffer[BLOCKSIZE];
 192     struct posix_header header;
 193     struct star_header star_header;
 194     struct oldgnu_header oldgnu_header;
 195     struct sparse_header sparse_header;
 196     struct star_in_header star_in_header;
 197     struct star_ext_header star_ext_header;
 198 };
 199 
 200 /* Information about a sparse file */
 201 struct sp_array
 202 {
 203     off_t offset;               /* chunk offset in file */
 204     off_t numbytes;             /* length of chunk */
 205     off_t arch_offset;          /* chunk offset in archive */
 206 };
 207 
 208 enum dump_status
 209 {
 210     dump_status_ok,
 211     dump_status_short,
 212     dump_status_fail,
 213     dump_status_not_implemented
 214 };
 215 
 216 enum archive_format
 217 {
 218     TAR_UNKNOWN = 0,            /**< format to be decided later */
 219     TAR_V7,                     /**< old V7 tar format */
 220     TAR_OLDGNU,                 /**< GNU format as per before tar 1.12 */
 221     TAR_USTAR,                  /**< POSIX.1-1988 (ustar) format */
 222     TAR_POSIX,                  /**< POSIX.1-2001 format */
 223     TAR_STAR,                   /**< star format defined in 1994 */
 224     TAR_GNU                     /**< almost same as OLDGNU_FORMAT */
 225 };
 226 
 227 typedef struct
 228 {
 229     struct vfs_s_super base;    /* base class */
 230 
 231     int fd;
 232     struct stat st;
 233     enum archive_format type;   /**< type of the archive */
 234     union block *record_start;  /**< start of record of archive */
 235 } tar_super_t;
 236 
 237 struct xheader
 238 {
 239     size_t size;
 240     char *buffer;
 241 };
 242 
 243 struct tar_stat_info
 244 {
 245     char *orig_file_name;       /**< name of file read from the archive header */
 246     char *file_name;            /**< name of file for the current archive entry after being normalized */
 247     char *link_name;            /**< name of link for the current archive entry  */
 248 #if 0
 249     char *uname;                /**< user name of owner */
 250     char *gname;                /**< group name of owner */
 251 #endif
 252     struct stat stat;           /**< regular filesystem stat */
 253 
 254     /* stat() doesn't always have access, data modification, and status
 255        change times in a convenient form, so store them separately.  */
 256     struct timespec atime;
 257     struct timespec mtime;
 258     struct timespec ctime;
 259 
 260     off_t archive_file_size;    /**< size of file as stored in the archive.
 261                                      Equals stat.st_size for non-sparse files */
 262     gboolean is_sparse;         /**< is the file sparse */
 263 
 264     /* For sparse files */
 265     unsigned int sparse_major;
 266     unsigned int sparse_minor;
 267     GArray *sparse_map;         /**< array of struct sp_array */
 268 
 269     off_t real_size;            /**< real size of sparse file */
 270     gboolean real_size_set;     /**< TRUE when GNU.sparse.realsize is set in archived file */
 271 
 272     gboolean sparse_name_done;  /**< TRUE if 'GNU.sparse.name' header was processed pax header parsing.
 273                                      Following 'path'  header (lower priority) will be ignored. */
 274 
 275     /* Extended headers */
 276     struct xheader xhdr;
 277 
 278     /* For dumpdirs */
 279     gboolean is_dumpdir;        /**< is the member a dumpdir? */
 280     gboolean skipped;           /**< the member contents is already read (for GNUTYPE_DUMPDIR) */
 281     char *dumpdir;              /**< contents of the dump directory */
 282 };
 283 
 284 /*** global variables defined in .c file *********************************************************/
 285 
 286 extern const int blocking_factor;
 287 extern const size_t record_size;
 288 
 289 extern union block *record_end; /* last+1 block of archive record */
 290 extern union block *current_block;      /* current block of archive */
 291 extern off_t record_start_block;        /* block ordinal at record_start */
 292 
 293 extern union block *current_header;
 294 
 295 /* Have we hit EOF yet?  */
 296 extern gboolean hit_eof;
 297 
 298 extern struct tar_stat_info current_stat_info;
 299 
 300 /*** declarations of public functions ************************************************************/
 301 
 302 /* tar-internal.c */
 303 gboolean is_octal_digit (char c);
 304 void tar_base64_init (void);
 305 void tar_assign_string (char **string, char *value);
 306 void tar_assign_string_dup (char **string, const char *value);
 307 void tar_assign_string_dup_n (char **string, const char *value, size_t n);
 308 intmax_t tar_from_header (const char *where0, size_t digs, char const *type, intmax_t minval,
 309                           uintmax_t maxval, gboolean octal_only);
 310 off_t off_from_header (const char *p, size_t s);
 311 union block *tar_find_next_block (tar_super_t * archive);
 312 gboolean tar_set_next_block_after (union block *block);
 313 off_t tar_current_block_ordinal (const tar_super_t * archive);
 314 gboolean tar_skip_file (tar_super_t * archive, off_t size);
 315 
 316 /* tar-sparse.c */
 317 gboolean tar_sparse_member_p (tar_super_t * archive, struct tar_stat_info *st);
 318 gboolean tar_sparse_fixup_header (tar_super_t * archive, struct tar_stat_info *st);
 319 enum dump_status tar_sparse_skip_file (tar_super_t * archive, struct tar_stat_info *st);
 320 
 321 /* tar-xheader.c */
 322 gboolean tar_xheader_decode (struct tar_stat_info *st);
 323 gboolean tar_xheader_read (tar_super_t * archive, struct xheader *xhdr, union block *header,
 324                            off_t size);
 325 gboolean tar_xheader_decode_global (struct xheader *xhdr);
 326 void tar_xheader_destroy (struct xheader *xhdr);
 327 
 328 /*** inline functions ****************************************************************************/
 329 
 330 /**
 331  * Represent @n using a signed integer I such that (uintmax_t) I == @n.
 332    With a good optimizing compiler, this is equivalent to (intmax_t) i
 333    and requires zero machine instructions.  */
 334 #if !(UINTMAX_MAX / 2 <= INTMAX_MAX)
 335 #error "tar_represent_uintmax() returns intmax_t to represent uintmax_t"
 336 #endif
 337 static inline intmax_t
 338 tar_represent_uintmax (uintmax_t n)
     /* [previous][next][first][last][top][bottom][index][help]  */
 339 {
 340     intmax_t nd;
 341 
 342     if (n <= INTMAX_MAX)
 343         return n;
 344 
 345     /* Avoid signed integer overflow on picky platforms. */
 346     nd = n - INTMAX_MIN;
 347     return nd + INTMAX_MIN;
 348 }
 349 
 350 #endif /* MC__VFS_TAR_INTERNAL_H */

/* [previous][next][first][last][top][bottom][index][help]  */