LCOV - code coverage report
Current view: top level - util/archive - fd_tar.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 6 27 22.2 %
Date: 2025-12-28 05:17:03 Functions: 1 20 5.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_util_archive_fd_tar_h
       2             : #define HEADER_fd_src_util_archive_fd_tar_h
       3             : 
       4             : /* fd_tar implements the ustar and old-GNU versions of the TAR file
       5             :    format. This is not a general-purpose TAR implementation.  It is
       6             :    currently only intended for loading and writing Solana snapshots. */
       7             : 
       8             : #include "../bits/fd_bits.h"
       9             : 
      10             : /* File Format ********************************************************/
      11             : 
      12             : /* The high level format of a tar archive/ball is a set of 512 byte blocks.
      13             :    Each file will be described a tar header (fd_tar_meta_t) and will be
      14             :    followed by the raw bytes of the file. The last block that is used for
      15             :    the file will be padded to fit into a tar block. When the archive is
      16             :    completed, it will be trailed by two EOF blocks which are populated with
      17             :    zero bytes. */
      18             : 
      19             : /* fd_tar_meta_t is the ustar/OLDGNU version of the TAR header. */
      20             : 
      21             : #define FD_TAR_BLOCK_SZ (512UL)
      22             : 
      23             : struct __attribute__((packed)) fd_tar_meta {
      24             : # define FD_TAR_NAME_SZ (100)
      25             :   /* 0x000 */ char name    [ FD_TAR_NAME_SZ ];
      26             :   /* 0x064 */ char mode    [   8 ];
      27             :   /* 0x06c */ char uid     [   8 ];
      28             :   /* 0x074 */ char gid     [   8 ];
      29             :   /* 0x07c */ char size    [  12 ];
      30             :   /* 0x088 */ char mtime   [  12 ];
      31             :   /* 0x094 */ char chksum  [   8 ];
      32             :   /* 0x09c */ char typeflag;
      33             :   /* 0x09d */ char linkname[ 100 ];
      34             :   /* 0x101 */ char magic   [   6 ];
      35             :   /* 0x107 */ char version [   2 ];
      36             :   /* 0x109 */ char uname   [  32 ];
      37             :   /* 0x129 */ char gname   [  32 ];
      38             :   /* 0x149 */ char devmajor[   8 ];
      39             :   /* 0x151 */ char devminor[   8 ];
      40             :   /* 0x159 */ char prefix  [ 155 ];
      41             :   /* 0x1f4 */ char padding [  12 ];
      42             : };
      43             : 
      44             : typedef struct fd_tar_meta fd_tar_meta_t;
      45             : 
      46             : /* FD_TAR_MAGIC is the only value of fd_tar_meta::magic supported by
      47             :    fd_tar. */
      48             : 
      49           0 : #define FD_TAR_MAGIC "ustar"
      50             : 
      51             : /* Known file types */
      52             : 
      53           0 : #define FD_TAR_TYPE_NULL      ('\0')  /* implies FD_TAR_TYPE_REGULAR */
      54           0 : #define FD_TAR_TYPE_REGULAR   ('0')
      55             : #define FD_TAR_TYPE_HARD_LINK ('1')
      56             : #define FD_TAR_TYPE_SYM_LINK  ('2')
      57             : #define FD_TAR_TYPE_CHAR_DEV  ('3')
      58             : #define FD_TAR_TYPE_BLOCK_DEV ('4')
      59             : #define FD_TAR_TYPE_DIR       ('5')
      60             : #define FD_TAR_TYPE_FIFO      ('6')
      61             : 
      62             : FD_PROTOTYPES_BEGIN
      63             : 
      64             : /* fd_tar_meta_is_reg returns 1 if the file type is 'regular', and 0
      65             :    otherwise. */
      66             : 
      67             : FD_FN_PURE static inline int
      68           0 : fd_tar_meta_is_reg( fd_tar_meta_t const * meta ) {
      69           0 :   return ( meta->typeflag == FD_TAR_TYPE_NULL    )
      70           0 :        | ( meta->typeflag == FD_TAR_TYPE_REGULAR );
      71           0 : }
      72             : 
      73             : /* fd_tar_meta_get_size parses the size field of the TAR header.
      74             :    Returns ULONG_MAX if parsing failed. */
      75             : 
      76             : FD_FN_PURE FD_FN_UNUSED static ulong
      77           3 : fd_tar_meta_get_size( fd_tar_meta_t const * meta ) {
      78           3 :   char const * buf = meta->size;
      79           3 :   if( ((uchar)buf[0]) & 0x80U ) {
      80             :     /* OLDGNU tar files may use a binary size encoding */
      81           3 :     return fd_ulong_bswap( FD_LOAD( ulong, buf+4 ) );
      82           3 :   }
      83             : 
      84           0 :   ulong ret = 0UL;
      85           0 :   for( char const * p=buf; p<buf+12; p++ ) {
      86           0 :     if( *p == '\0' ) break;
      87           0 :     ret = (ret << 3) + (ulong)(*p - '0');
      88           0 :   }
      89             : 
      90           0 :   return ret;
      91           3 : }
      92             : 
      93             : /* fd_tar_set_octal is a helper function to write 12-byte octal fields */
      94             : 
      95             : int
      96             : fd_tar_set_octal( char  buf[ static 12 ],
      97             :                   ulong val );
      98             : 
      99             : /* fd_tar_meta_set_size sets the size field.  Returns 1 on success, 0
     100             :    if sz is too large to be represented in TAR header. Set size using the
     101             :    OLDGNU size extension to allow for unlimited file sizes. The first byte
     102             :    must be 0x80 followed by 0s and then the size in binary. */
     103             : 
     104             : static inline int
     105             : fd_tar_meta_set_size( fd_tar_meta_t * meta,
     106           0 :                       ulong           sz ) {
     107           0 :   meta->size[ 0 ] = (char)0x80;
     108           0 :   FD_STORE( ulong, meta->size + 4UL, fd_ulong_bswap( sz ) );
     109           0 :   return 1;
     110           0 : }
     111             : 
     112             : /* fd_tar_meta_set_mtime sets the modification time field.  Returns 1
     113             :    on success, 0 if time cannot be represented in TAR header. */
     114             : 
     115             : static inline int
     116             : fd_tar_meta_set_mtime( fd_tar_meta_t * meta,
     117           0 :                        ulong           mtime ) {
     118           0 :   return fd_tar_set_octal( meta->mtime, mtime );
     119           0 : }
     120             : 
     121             : FD_PROTOTYPES_END
     122             : 
     123             : #endif /* HEADER_fd_src_util_archive_fd_tar_h */

Generated by: LCOV version 1.14