LCOV - code coverage report
Current view: top level - discof/restore/utils - fd_ssarchive.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 97 0.0 %
Date: 2025-08-05 05:04:49 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #include "fd_ssarchive.h"
       2             : 
       3             : #include "../../../util/log/fd_log.h"
       4             : 
       5             : #include <errno.h>
       6             : #include <dirent.h>
       7             : #include <stdlib.h>
       8             : 
       9             : int
      10             : fd_ssarchive_parse_filename( char *  _name,
      11             :                              ulong * full_slot,
      12             :                              ulong * incremental_slot,
      13           0 :                              uchar   hash[ static FD_HASH_FOOTPRINT ] ) {
      14           0 :   char name[ PATH_MAX ] = {0};
      15           0 :   strncpy( name, _name, PATH_MAX-1 );
      16             : 
      17           0 :   char * ptr = name;
      18           0 :   int is_incremental;
      19           0 :   if( !strncmp( ptr, "incremental-snapshot-", 21UL ) ) {
      20           0 :     is_incremental = 1;
      21           0 :     ptr += 21UL;
      22           0 :   } else if( !strncmp( ptr, "snapshot-", 9UL ) ) {
      23           0 :     is_incremental = 0;
      24           0 :     ptr += 9UL;
      25           0 :   } else {
      26           0 :     return -1;
      27           0 :   }
      28             : 
      29           0 :   char * next = strchr( ptr, '-' );
      30           0 :   if( FD_UNLIKELY( !next ) ) return -1;
      31             : 
      32           0 :   *next = '\0';
      33           0 :   char * endptr;
      34           0 :   ulong slot = strtoul( ptr, &endptr, 10 );
      35           0 :   if( FD_UNLIKELY( *endptr!='\0' || slot==ULONG_MAX ) ) return -1;
      36             : 
      37           0 :   *full_slot = slot;
      38             : 
      39           0 :   if( is_incremental ) {
      40           0 :     ptr = next + 1;
      41           0 :     next = strchr( ptr, '-' );
      42           0 :     if( FD_UNLIKELY( !next ) ) return -1;
      43             : 
      44           0 :     *next = '\0';
      45           0 :     slot = strtoul( ptr, &endptr, 10 );
      46           0 :     if( FD_UNLIKELY( *endptr!='\0' || slot==ULONG_MAX ) ) return -1;
      47             : 
      48           0 :     *incremental_slot = slot;
      49           0 :   } else {
      50           0 :     *incremental_slot = ULONG_MAX;
      51           0 :   }
      52             : 
      53           0 :   ptr = next + 1;
      54           0 :   next = strchr( ptr, '.' );
      55           0 :   if( FD_UNLIKELY( !next ) ) return -1;
      56             : 
      57           0 :   ulong sz = (ulong)(next - ptr);
      58             : 
      59           0 :   if( FD_UNLIKELY( sz>FD_BASE58_ENCODED_32_LEN ) ) return -1;
      60             : 
      61           0 :   char encoded_hash[ FD_BASE58_ENCODED_32_SZ ];
      62           0 :   fd_memcpy( encoded_hash, ptr, sz );
      63           0 :   encoded_hash[ sz ] = '\0';
      64           0 :   uchar * result = fd_base58_decode_32( encoded_hash, hash );
      65             : 
      66           0 :   if( FD_UNLIKELY( !result ) ) return -1;
      67             : 
      68           0 :   if( FD_UNLIKELY( strncmp( next, ".tar.zst", 8UL ) ) ) return -1;
      69           0 :   return 0;
      70           0 : }
      71             : 
      72             : int
      73             : fd_ssarchive_latest_pair( char const * directory,
      74             :                           int          incremental_snapshot,
      75             :                           ulong *      full_slot,
      76             :                           ulong *      incremental_slot,
      77             :                           char         full_path[ static PATH_MAX ],
      78           0 :                           char         incremental_path[ static PATH_MAX ] ) {
      79           0 :   *full_slot = ULONG_MAX;
      80           0 :   *incremental_slot = ULONG_MAX;
      81             : 
      82           0 :   DIR * dir = opendir( directory );
      83           0 :   if( FD_UNLIKELY( !dir ) ) {
      84           0 :     if( FD_LIKELY( errno==ENOENT ) ) return -1;
      85           0 :     FD_LOG_ERR(( "opendir() failed `%s` (%i-%s)", directory, errno, fd_io_strerror( errno ) ));
      86           0 :   }
      87             : 
      88           0 :   struct dirent * entry;
      89             : 
      90           0 :   errno = 0;
      91           0 :   while(( entry = readdir( dir ) )) {
      92           0 :     if( FD_LIKELY( !strcmp( entry->d_name, "." ) || !strcmp( entry->d_name, ".." ) ) ) continue;
      93             : 
      94           0 :     ulong entry_full_slot, entry_incremental_slot;
      95           0 :     uchar decoded_hash[ FD_HASH_FOOTPRINT ];
      96           0 :     if( FD_UNLIKELY( -1==fd_ssarchive_parse_filename( entry->d_name, &entry_full_slot, &entry_incremental_slot, decoded_hash ) ) ) {
      97           0 :       FD_LOG_INFO(( "unrecognized snapshot file `%s/%s` in snapshots directory", directory, entry->d_name ));
      98           0 :       continue;
      99           0 :     }
     100             : 
     101           0 :     if( FD_LIKELY( entry_incremental_slot==ULONG_MAX && (entry_full_slot>*full_slot || *full_slot==ULONG_MAX) ) ) {
     102           0 :       *full_slot = entry_full_slot;
     103           0 :       if( FD_UNLIKELY( !fd_cstr_printf_check( full_path, PATH_MAX, NULL, "%s/%s", directory, entry->d_name ) ) ) {
     104           0 :         FD_LOG_ERR(( "snapshot path too long `%s/%s`", directory, entry->d_name ));
     105           0 :       }
     106           0 :     }
     107           0 :   }
     108             : 
     109           0 :   if( FD_UNLIKELY( -1==closedir( dir ) ) ) FD_LOG_ERR(( "closedir() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
     110           0 :   if( FD_UNLIKELY( errno && errno!=ENOENT ) ) FD_LOG_ERR(( "readdir() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
     111             : 
     112           0 :   if( FD_UNLIKELY( *full_slot==ULONG_MAX ) ) return -1;
     113           0 :   if( FD_UNLIKELY( !incremental_snapshot ) ) return 0;
     114             : 
     115           0 :   dir = opendir( directory );
     116           0 :   if( FD_UNLIKELY( !dir ) ) {
     117           0 :     if( FD_LIKELY( errno==ENOENT ) ) return 0;
     118           0 :     FD_LOG_ERR(( "opendir() failed `%s` (%i-%s)", directory, errno, fd_io_strerror( errno ) ));
     119           0 :   }
     120             : 
     121           0 :   errno = 0;
     122           0 :   while(( entry = readdir( dir ) )) {
     123           0 :     if( FD_LIKELY( !strcmp( entry->d_name, "." ) || !strcmp( entry->d_name, ".." ) ) ) continue;
     124             : 
     125           0 :     ulong entry_full_slot, entry_incremental_slot;
     126           0 :     uchar decoded_hash[ FD_HASH_FOOTPRINT ];
     127           0 :     if( FD_UNLIKELY( -1==fd_ssarchive_parse_filename( entry->d_name, &entry_full_slot, &entry_incremental_slot, decoded_hash ) ) ) continue;
     128             : 
     129           0 :     if( FD_UNLIKELY( entry_incremental_slot==ULONG_MAX || *full_slot!=entry_full_slot ) ) continue;
     130             : 
     131           0 :     if( FD_LIKELY( *incremental_slot==ULONG_MAX || entry_incremental_slot>*incremental_slot ) ) {
     132           0 :       *incremental_slot = entry_incremental_slot;
     133           0 :       if( FD_UNLIKELY( !fd_cstr_printf_check( incremental_path, PATH_MAX, NULL, "%s/%s", directory, entry->d_name ) ) ) {
     134           0 :         FD_LOG_ERR(( "snapshot path too long `%s/%s`", directory, entry->d_name ));
     135           0 :       }
     136           0 :     }
     137           0 :   }
     138             : 
     139           0 :   if( FD_UNLIKELY( -1==closedir( dir ) ) ) FD_LOG_ERR(( "closedir() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
     140           0 :   if( FD_UNLIKELY( errno && errno!=ENOENT ) ) FD_LOG_ERR(( "readdir() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
     141           0 :   return 0;
     142           0 : }

Generated by: LCOV version 1.14