Guest User

Untitled

a guest
Aug 14th, 2022
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.22 KB | None | 0 0
  1. #!/usr/bin/python3
  2. import base64
  3. import glob
  4. import struct
  5. import traceback
  6.  
  7.  
  8. files_to_scan = '/mountpoint/lost+found/**'
  9.  
  10.  
  11. def from_base128(data, cursor):
  12.     numbers = []
  13.     while True:
  14.         number = data[cursor]
  15.         cursor += 1
  16.         numbers.append(number & 127)
  17.         if number & 128 == 0:
  18.             break
  19.     result = 0
  20.     for number in reversed(numbers):
  21.         result = result * 128 + number
  22.     return result, cursor
  23.  
  24.  
  25. def iter_protobuf(data):  # https://developers.google.com/protocol-buffers/docs/encoding
  26.     cursor = 0
  27.     while cursor < len(data):
  28.         key = data[cursor]
  29.         cursor += 1
  30.  
  31.         wire_type = key & 7
  32.         field_number = key >> 3
  33.  
  34.         if wire_type == 0:  # varint
  35.             value, cursor = from_base128(data, cursor)
  36.             yield 'varint', field_number, value
  37.         elif wire_type == 2:  # length-delimited
  38.             length, cursor = from_base128(data, cursor)
  39.             value = data[cursor:cursor + length]
  40.             cursor += length
  41.             yield 'length-delimited', field_number, value
  42.         else:
  43.             print(f'wire_type = {wire_type}, field_number = {field_number}; unknown wire_type, sorry')
  44.             break
  45.  
  46.  
  47. def id_to_string(v):  # https://github.com/storj/storj/blob/bd36a41a9ebe4d855ad654daf3856728e2796d98/storage/filestore/dir.go#L37
  48.     return base64.b32encode(v).lower().strip(b'=').decode('ascii')
  49.  
  50.  
  51. def extract(file_name):
  52.     with open(file_name, 'rb') as fh:
  53.         data = fh.read(512)  # V1PieceHeaderReservedArea, https://github.com/storj/storj/blob/bd36a41a9ebe4d855ad654daf3856728e2796d98/storagenode/pieces/readwrite.go#L259
  54.  
  55.     header_size, = struct.unpack('>h', data[:2])
  56.     assert header_size <= 510
  57.  
  58.     for wire_type, field_number, value in iter_protobuf(data[2:2 + header_size]):
  59.         if field_number == 1:  # https://github.com/storj/proto/blob/c713232da63d9e8221f057591edd7fbf91909e33/pkg/pb/piecestore2.proto#L119
  60.             assert wire_type == 'varint'
  61.             assert value == 1
  62.         if field_number == 5:  # https://github.com/storj/proto/blob/c713232da63d9e8221f057591edd7fbf91909e33/pkg/pb/piecestore2.proto#L119
  63.             for wire_type, field_number, value in iter_protobuf(value):
  64.                 if field_number == 2:  # https://github.com/storj/proto/blob/c713232da63d9e8221f057591edd7fbf91909e33/pkg/pb/orders.proto#L63
  65.                     assert wire_type == 'length-delimited'
  66.                     extracted_satellite_id = id_to_string(value)
  67.                 elif field_number == 5:  # https://github.com/storj/proto/blob/c713232da63d9e8221f057591edd7fbf91909e33/pkg/pb/orders.proto#L72
  68.                     assert wire_type == 'length-delimited'
  69.                     extracted_piece_id = id_to_string(value)
  70.  
  71.     return extracted_satellite_id, extracted_piece_id
  72.  
  73.  
  74. for file_name in glob.iglob(files_to_scan, recursive=True):
  75.     try:
  76.         extracted_satellite_id, extracted_piece_id = extract(file_name)
  77.         print(f'File {file_name} should probably go do {extracted_satellite_id}/{extracted_piece_id[:2]}/{extracted_piece_id[2:]}.sj1')
  78.     except:
  79.         print(f'Error for file {file_name}, maybe it is not a piece file?')
  80.         traceback.print_exc()
  81.         print()
  82.  
Add Comment
Please, Sign In to add comment