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

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