Line data Source code
1 : #ifndef HEADER_fd_src_discof_restore_utils_fd_ssarchive_h 2 : #define HEADER_fd_src_discof_restore_utils_fd_ssarchive_h 3 : 4 : #include "../../../flamenco/fd_flamenco_base.h" 5 : 6 : #include <stdlib.h> 7 : 8 : /* FD_SNAP_NAME_MAX is the max length of a snapshot filename (cstr) 9 : including NUL terminator. */ 10 0 : #define FD_SNAP_NAME_MAX (128UL) 11 : 12 : /* FD_SSARCHIVE_MAX_ENTRIES is the number of snapshots of each class 13 : (full, incremental) that fd_ssarchive_latest_pair considers. If a 14 : directory holds more than this, only the newest 15 : FD_SSARCHIVE_MAX_ENTRIES of each class are considered. */ 16 3 : #define FD_SSARCHIVE_MAX_ENTRIES (512UL) 17 : 18 : FD_PROTOTYPES_BEGIN 19 : 20 : /* Parses a snapshot filename into components. 21 : 22 : incremental-snapshot-344185432-344209085-45eJ5C91fEenPRFc8NiqaDXMCHcPFwRUTMH3k1zY6a1B.tar.zst 23 : snapshot-344185432-BSP9ztdFEjwvkBo2LhHA47g9Q3PDwja9x5fj7taFRKH5.tar.zst 24 : snapshot-369927872-AaswH3EY2QJtTL1rTGxKCKsJ6SAjAeAvNfJhgM9D4ytU.tar 25 : 26 : Returns -1 on failure and 0 on success. */ 27 : 28 : static inline int 29 : fd_ssarchive_parse_filename( char const * _name, 30 : ulong * full_slot, 31 : ulong * incremental_slot, 32 : uchar hash[ static FD_HASH_FOOTPRINT ], 33 1620 : int * is_zstd ) { 34 1620 : char name[ PATH_MAX ]; 35 1620 : fd_cstr_ncpy( name, _name, sizeof(name) ); 36 : 37 1620 : char * ptr = name; 38 1620 : int is_incremental; 39 1620 : if( !strncmp( ptr, "incremental-snapshot-", 21UL ) ) { 40 15 : is_incremental = 1; 41 15 : ptr += 21UL; 42 1605 : } else if( !strncmp( ptr, "snapshot-", 9UL ) ) { 43 1605 : is_incremental = 0; 44 1605 : ptr += 9UL; 45 1605 : } else { 46 0 : return -1; 47 0 : } 48 : 49 1620 : char * next = strchr( ptr, '-' ); 50 1620 : if( FD_UNLIKELY( !next ) ) return -1; 51 1620 : *next = '\0'; 52 1620 : char * endptr; 53 1620 : *full_slot = strtoul( ptr, &endptr, 10 ); 54 1620 : if( FD_UNLIKELY( *endptr!='\0' || endptr==ptr || *full_slot==ULONG_MAX ) ) return -1; 55 : 56 1620 : if( is_incremental ) { 57 15 : ptr = next + 1; 58 15 : next = strchr( ptr, '-' ); 59 15 : if( FD_UNLIKELY( !next ) ) return -1; 60 15 : *next = '\0'; 61 15 : *incremental_slot = strtoul( ptr, &endptr, 10 ); 62 15 : if( FD_UNLIKELY( *endptr!='\0' || endptr==ptr || *incremental_slot==ULONG_MAX ) ) return -1; 63 1605 : } else { 64 1605 : *incremental_slot = ULONG_MAX; 65 1605 : } 66 : 67 1620 : ptr = next + 1; 68 1620 : next = strchr( ptr, '.' ); 69 1620 : if( FD_UNLIKELY( !next ) ) return -1; 70 1620 : *next = '\0'; 71 1620 : ulong sz = (ulong)(next - ptr); 72 1620 : if( FD_UNLIKELY( sz>FD_BASE58_ENCODED_32_LEN ) ) return -1; 73 1620 : uchar * result = fd_base58_decode_32( ptr, hash ); 74 1620 : if( FD_UNLIKELY( result!=hash ) ) return -1; 75 : 76 1620 : ptr = next + 1; 77 : 78 1620 : if( FD_LIKELY( 0==strcmp( ptr, "tar.zst" ) ) ) *is_zstd = 1; 79 0 : else if ( FD_LIKELY( 0==strcmp( ptr, "tar" ) ) ) *is_zstd = 0; 80 0 : else return -1; 81 : 82 1620 : return 0; 83 1620 : } 84 : 85 : /* Given a directory on the filesystem, determine the most recent (full, 86 : incremental) slot pair, whether each snapshot is zstd compressed, the 87 : associated full and incremental hashes, and the snapshot paths. The 88 : incremental slot is set to ULONG_MAX if the highest pair is just a 89 : full snapshot alone, or if incremental_snapshot is 0 (only full 90 : snapshots are considered). In this case, incremental_path is left 91 : empty, *incremental_is_zstd is set to 0, and incremental_hash is 92 : zeroed. 93 : 94 : Returns -1 on failure, and 0 on success. */ 95 : 96 : int 97 : fd_ssarchive_latest_pair( char const * directory, 98 : int incremental_snapshot, 99 : ulong * full_slot, 100 : ulong * incremental_slot, 101 : char full_path[ static PATH_MAX ], 102 : char incremental_path[ static PATH_MAX ], 103 : int * full_is_zstd, 104 : int * incremental_is_zstd, 105 : uchar full_hash[ static FD_HASH_FOOTPRINT ], 106 : uchar incremental_hash[ static FD_HASH_FOOTPRINT ] ); 107 : 108 : FD_PROTOTYPES_END 109 : 110 : #endif /* HEADER_fd_src_discof_restore_utils_fd_ssarchive_h */