/* metainfo.h — .torrent and magnet parsing (v1 / v2 / hybrid). * * The info-hash is computed over the *raw* bytes of the `info` dictionary as * they appear in the file (bencode preserves that span), never by re-encoding: * v1 info-hash = SHA-1 (info-bytes) * v2 info-hash = SHA-256(info-bytes) * A hybrid torrent carries both and so joins both the v1 and v2 swarms. * * Phase 2 parses v1 fully (name, piece length, file list, the 20-byte piece * hash table) and computes the v2 info-hash + version for hybrid/v2 files; the * full v2 file-tree / piece-layer plumbing is wired in Phase 3 (storage). */ #ifndef NAUT_METAINFO_H #define NAUT_METAINFO_H #include "naut/common.h" #include "naut/hash.h" typedef struct { char *path; /* '/'-joined, NUL-terminated */ int64_t length; } naut_file; typedef struct naut_metainfo { bool has_v1, has_v2; uint8_t infohash_v1[NAUT_SHA1_LEN]; uint8_t infohash_v2[NAUT_SHA256_LEN]; char *name; int64_t piece_length; int64_t total_length; /* v1 piece hash table: num_pieces * 20 bytes (owned copy) */ uint32_t num_pieces; const uint8_t *piece_hashes; naut_file *files; size_t num_files; char **trackers; size_t num_trackers; /* announce + announce-list, flattened */ /* internals kept alive so piece_hashes/name stay valid */ void *_owned; } naut_metainfo; naut_err naut_metainfo_parse(const uint8_t *data, size_t len, naut_metainfo *out); /* Parse a raw bencoded info dictionary obtained through BEP-9. Optional * tracker URLs are copied into the resulting metainfo. */ naut_err naut_metainfo_parse_info(const uint8_t *info, size_t info_len, const char *const *trackers, size_t num_trackers, naut_metainfo *out); void naut_metainfo_free(naut_metainfo *mi); /* hex of the v1 info-hash (41 bytes incl NUL) — for logging/RPC. */ void naut_infohash_v1_hex(const naut_metainfo *mi, char out[41]); /* --- magnet links -------------------------------------------------------- */ typedef struct { bool has_v1, has_v2; uint8_t infohash_v1[NAUT_SHA1_LEN]; uint8_t infohash_v2[NAUT_SHA256_LEN]; char *name; /* dn (display name), may be NULL */ char **trackers; size_t num_trackers; /* tr= params */ } naut_magnet; naut_err naut_magnet_parse(const char *uri, naut_magnet *out); void naut_magnet_free(naut_magnet *m); #endif /* NAUT_METAINFO_H */