LCOV - code coverage report
Current view: top level - util/archive - fd_tar.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 6 19 31.6 %
Date: 2024-11-13 11:58:15 Functions: 1 60 1.7 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_archive_fd_tar_h
       2             : #define HEADER_fd_src_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 Solana snapshots. */
       7             : 
       8             : #include "../fd_util_base.h"
       9             : 
      10             : /* File Format ********************************************************/
      11             : 
      12             : /* fd_tar_meta_t is the ustar/OLDGNU version of the TAR header. */
      13             : 
      14             : struct __attribute__((packed)) fd_tar_meta {
      15           0 : # define FD_TAR_NAME_SZ (100)
      16             :   /* 0x000 */ char name    [ FD_TAR_NAME_SZ ];
      17             :   /* 0x064 */ char mode    [   8 ];
      18             :   /* 0x06c */ char uid     [   8 ];
      19             :   /* 0x074 */ char gid     [   8 ];
      20             :   /* 0x07c */ char size    [  12 ];
      21             :   /* 0x088 */ char mtime   [  12 ];
      22             :   /* 0x094 */ char chksum  [   8 ];
      23             :   /* 0x09c */ char typeflag;
      24             :   /* 0x09d */ char linkname[ 100 ];
      25             :   /* 0x101 */ char magic   [   6 ];
      26             :   /* 0x107 */ char version [   2 ];
      27             :   /* 0x109 */ char uname   [  32 ];
      28             :   /* 0x129 */ char gname   [  32 ];
      29             :   /* 0x149 */ char devmajor[   8 ];
      30             :   /* 0x151 */ char devminor[   8 ];
      31             :   /* 0x159 */ char prefix  [ 155 ];
      32             :   /* 0x1f4 */ char padding [  12 ];
      33             : };
      34             : 
      35             : typedef struct fd_tar_meta fd_tar_meta_t;
      36             : 
      37             : /* FD_TAR_MAGIC is the only value of fd_tar_meta::magic supported by
      38             :    fd_tar. */
      39             : 
      40             : #define FD_TAR_MAGIC "ustar"
      41             : 
      42             : /* Known file types */
      43             : 
      44          54 : #define FD_TAR_TYPE_NULL      ('\0')  /* implies FD_TAR_TYPE_REGULAR */
      45         108 : #define FD_TAR_TYPE_REGULAR   ('0')
      46             : #define FD_TAR_TYPE_HARD_LINK ('1')
      47             : #define FD_TAR_TYPE_SYM_LINK  ('2')
      48             : #define FD_TAR_TYPE_CHAR_DEV  ('3')
      49             : #define FD_TAR_TYPE_BLOCK_DEV ('4')
      50             : #define FD_TAR_TYPE_DIR       ('5')
      51             : #define FD_TAR_TYPE_FIFO      ('6')
      52             : 
      53             : FD_PROTOTYPES_BEGIN
      54             : 
      55             : /* fd_tar_meta_is_reg returns 1 if the file type is 'regular', and 0
      56             :    otherwise. */
      57             : 
      58             : FD_FN_PURE static inline int
      59          54 : fd_tar_meta_is_reg( fd_tar_meta_t const * meta ) {
      60          54 :   return ( meta->typeflag == FD_TAR_TYPE_NULL    )
      61          54 :        | ( meta->typeflag == FD_TAR_TYPE_REGULAR );
      62          54 : }
      63             : 
      64             : /* fd_tar_meta_get_size parses the size field of the TAR header.
      65             :    Returns ULONG_MAX if parsing failed. */
      66             : 
      67             : FD_FN_PURE ulong
      68             : fd_tar_meta_get_size( fd_tar_meta_t const * meta );
      69             : 
      70             : /* fd_tar_set_octal is a helper function to write 12-byte octal fields */
      71             : 
      72             : int
      73             : fd_tar_set_octal( char  buf[ static 12 ],
      74             :                   ulong val );
      75             : 
      76             : /* fd_tar_meta_set_size sets the size field.  Returns 1 on success, 0
      77             :    if sz is too large to be represented in TAR header. */
      78             : 
      79             : static inline int
      80             : fd_tar_meta_set_size( fd_tar_meta_t * meta,
      81           0 :                       ulong           sz ) {
      82           0 :   return fd_tar_set_octal( meta->size, sz );
      83           0 : }
      84             : 
      85             : /* fd_tar_meta_set_mtime sets the modification time field.  Returns 1
      86             :    on success, 0 if time cannot be represented in TAR header. */
      87             : 
      88             : static inline int
      89             : fd_tar_meta_set_mtime( fd_tar_meta_t * meta,
      90           0 :                        ulong           mtime ) {
      91           0 :   return fd_tar_set_octal( meta->mtime, mtime );
      92           0 : }
      93             : 
      94             : FD_PROTOTYPES_END
      95             : 
      96             : /* Streaming reader ***************************************************/
      97             : 
      98             : typedef struct fd_tar_reader fd_tar_reader_t;
      99             : 
     100             : /* fd_tar_file_fn_t is called by fd_tar when a new file was encountered.
     101             :    cb_arg is the callback context value. meta is the file header
     102             :    (lifetime until return).  sz is the expected file size that follows
     103             :    (via read callbacks).  The actual read size might differ in case of
     104             :    errors (e.g. unexpected EOF).  Returns 0 on success and non-zero if
     105             :    tar reader should stop. */
     106             : 
     107             : typedef int
     108             : (* fd_tar_file_fn_t)( void *                cb_arg,
     109             :                       fd_tar_meta_t const * meta,
     110             :                       ulong                 sz );
     111             : 
     112             : /* fd_tar_read_cb_t is called by fd_tar when a new chunk of data has
     113             :    been read.  Each read callback is associated with the last file
     114             :    callback.  Read callbacks are issued in order such that concatenating
     115             :    all buffers results in the correct file content.  Returns 0 on
     116             :    success and non-zero if tar reader should stop.
     117             : 
     118             :    cb_arg is the callback context value.  buf points to the first byte
     119             :    of the chunk.  bufsz is the byte count.  The lifetime of buf is until
     120             :    the callback returns. */
     121             : 
     122             : typedef int
     123             : (* fd_tar_read_fn_t)( void *       cb_arg,
     124             :                       void const * buf,
     125             :                       ulong        bufsz );
     126             : 
     127             : /* fd_tar_read_vtable_t is the virtual function table of the
     128             :    fd_tar_reader_t consumer object. */
     129             : 
     130             : struct fd_tar_read_vtable {
     131             :   fd_tar_file_fn_t file;
     132             :   fd_tar_read_fn_t read;
     133             : };
     134             : 
     135             : typedef struct fd_tar_read_vtable fd_tar_read_vtable_t;
     136             : 
     137             : /* fd_tar_reader_t is a streaming TAR reader using a callback API for
     138             :    delivering data.  To use, feed it the chunks of the TAR stream via
     139             :    fd_tar_read.  There is no restriction on the size and alignment of
     140             :    these chunks, other than that the chunks are supplied in order and
     141             :    gapless.  The resulting callback sequence is (1x file, Nx read, 1x
     142             :    file, Nx read ...).  As in: Each new file encountered creates a file
     143             :    callback and a variable number of read callbacks. */
     144             : 
     145             : struct fd_tar_reader {
     146             : 
     147             :   /* Buffered file header.  Required because a file header might be
     148             :      split across multiple fd_tar_read calls. */
     149             :   union {
     150             :     uchar         buf[ sizeof(fd_tar_meta_t) ];
     151             :     fd_tar_meta_t header;
     152             :   };
     153             : 
     154             :   ulong pos;      /* Number of bytes consumed */
     155             :   ulong buf_ctr;  /* Write cursor in file header */
     156             :   ulong file_sz;  /* Number of file bytes left */
     157             : 
     158             :   /* Callback parameters */
     159             :   fd_tar_read_vtable_t cb_vt;
     160             :   void *               cb_arg;
     161             : 
     162             : };
     163             : 
     164             : FD_PROTOTYPES_BEGIN
     165             : 
     166             : /* fd_tar_reader_{align,footprint} return parameters for the memory
     167             :    region backing a fd_tar_reader_t. */
     168             : 
     169             : FD_FN_CONST static inline ulong
     170           0 : fd_tar_reader_align( void ) {
     171           0 :   return alignof(fd_tar_reader_t);
     172           0 : }
     173             : 
     174             : FD_FN_CONST static inline ulong
     175           0 : fd_tar_reader_footprint( void ) {
     176           0 :   return sizeof(fd_tar_reader_t);
     177           0 : }
     178             : 
     179             : /* fd_tar_reader_new creates a new TAR reader.  mem is the memory region
     180             :    that will hold the fd_tar_reader_t (matches above align/ footprint
     181             :    requirements).  cb_vt contains the callback function pointers of
     182             :    the recipient.  cb_vt pointer is borrowed until this function
     183             :    returns.  cb_arg is the callback context value (usually a pointer to
     184             :    the recipient object).  Returns a qualified handle to the reader
     185             :    object in mem on success.  On failure, returns NULL and writes reason
     186             :    to warning log.  Reasons for failure include invalid memory region or
     187             :    NULL callback. */
     188             : 
     189             : fd_tar_reader_t *
     190             : fd_tar_reader_new( void *                       mem,
     191             :                    fd_tar_read_vtable_t const * cb_vt,
     192             :                    void *                       cb_arg );
     193             : 
     194             : /* fd_tar_reader_delete destroys a .tar reader and frees any allocated
     195             :    resources.  Returns the underlying memory region back to the caller. */
     196             : 
     197             : void *
     198             : fd_tar_reader_delete( fd_tar_reader_t * reader );
     199             : 
     200             : /* fd_tar_read processes a chunk of the TAR stream.  Issues callbacks
     201             :    when file headers or content are read.  reader is an fd_tar_reader_t
     202             :    pointer.  data points to the first byte of the data chunk.  data_sz
     203             :    is the byte count.  data_sz==0UL is a no-op.  Returns 0 on success.
     204             :    Returns -1 on end-of-file.  On failure, returns positive errno
     205             :    compatible error code.  In case of error, caller should delete reader
     206             :    and must not issue any more fd_tar_read calls.  Suitable as a
     207             :    fd_decompress_cb_t callback. */
     208             : 
     209             : int
     210             : fd_tar_read( void *        reader,
     211             :              uchar const * data,
     212             :              ulong         data_sz );
     213             : 
     214             : FD_PROTOTYPES_END
     215             : 
     216             : #endif /* HEADER_fd_src_archive_fd_tar_h */

Generated by: LCOV version 1.14