Raphael Manfredi
#include "common.h"
#include "fileinfo.h"
#include "sockets.h"
#include "downloads.h"
#include "uploads.h"
#include "hosts.h"
#include "routing.h"
#include "gmsg.h"
#include "bsched.h"
#include "huge.h"
#include "dmesh.h"
#include "search.h"
#include "guid.h"
#include "share.h"
#include "settings.h"
#include "nodes.h"
#include "namesize.h"
#include "http.h"
#include "lib/atoms.h"
#include "lib/base32.h"
#include "lib/endian.h"
#include "lib/file.h"
#include "lib/fuzzy.h"
#include "lib/header.h"
#include "lib/idtable.h"
#include "lib/tm.h"
#include "lib/utf8.h"
#include "lib/walloc.h"
#include "lib/glib-missing.h"
#include "if/gnet_property.h"
#include "if/gnet_property_priv.h"
#include "lib/override.h"
Data Structures | |
struct | dl_file_chunk |
struct | trailer |
The trailer fields of the fileinfo trailer. More... | |
struct | fi_tag |
Defines | |
#define | FI_MIN_CHUNK_SPLIT 512 /**< Smallest chunk we can split */ |
Smallest chunk we can split. | |
#define | FI_MAX_FIELD_LEN 1024 /**< Max field length we accept to save */ |
Max field length we accept to save. | |
#define | FILE_INFO_MAGIC32 0xD1BB1ED0U |
#define | FILE_INFO_MAGIC64 0X91E63640U |
#define | FILE_INFO_VERSION 6 |
#define | FI_STORE_DELAY 10 /**< Max delay (secs) for flushing fileinfo */ |
Max delay (secs) for flushing fileinfo. | |
#define | FI_TRAILER_INT 6 /**< Amount of guint32 in the trailer */ |
Amount of guint32 in the trailer. | |
#define | TBUF_SIZE 512 /**< Initial trailing buffer size */ |
Initial trailing buffer size. | |
#define | TBUF_GROW_BITS 9 /**< Growing chunks */ |
Growing chunks. | |
#define | TBUF_GROW (1 << TBUF_GROW_BITS) |
#define | TBUF_GROW_MASK (TBUF_GROW - 1) |
#define | round_grow(x) ((guint32) (((guint32) (x) + TBUF_GROW_MASK) & ~TBUF_GROW_MASK)) |
#define | trunc_int32(x) ((gulong) ((gulong) (x) & ~(sizeof(guint32) - 1))) |
#define | int32_aligned(x) ((gulong) (x) == trunc_int32(x)) |
#define | TBUF_INIT_READ(s) |
#define | TBUF_INIT_WRITE() |
#define | TBUF_WRITTEN_LEN() (tbuf.wptr - tbuf.arena) |
#define | TBUF_CHECK(x) |
#define | TBUF_GETCHAR(x) |
#define | TBUF_GETINT32(x) |
#define | TBUF_READ(x, s) |
#define | TBUF_PUTCHAR(x) |
#define | TBUF_PUTINT32(x) |
#define | TBUF_WRITE(x, s) |
#define | WRITE_CHAR(a) |
#define | WRITE_INT32(a) |
#define | WRITE_UINT32(a) |
#define | WRITE_STR(a, b) |
#define | READ_CHAR(a) |
#define | READ_INT32(a) |
#define | READ_STR(a, b) |
#define | FIELD_ADD(a, b, c) |
#define | file_info_find_by_handle(n) (fileinfo_t *) idtable_get_value(fi_handle_map, n) |
#define | file_info_request_handle(n) idtable_new_id(fi_handle_map, n) |
#define | file_info_drop_handle(n) idtable_free_id(fi_handle_map, n); |
#define | BAILOUT(x) |
#define | GET_KEY(i) (fi_tag_map[(i)].str) |
#define | FOUND(i) |
#define | bs_nop(x) (x) |
Typedefs | |
typedef guint32 | fi_magic_t |
Enumerations | |
enum | dl_file_info_field { FILE_INFO_FIELD_NAME = 1, FILE_INFO_FIELD_ALIAS, FILE_INFO_FIELD_SHA1, FILE_INFO_FIELD_CHUNK, FILE_INFO_FIELD_END, FILE_INFO_FIELD_CHA1, FILE_INFO_FIELD_GUID, NUM_FILE_INFO_FIELDS } |
enum | fi_tag_t { FI_TAG_UNKNOWN = 0, FI_TAG_NAME, FI_TAG_PATH, FI_TAG_GENR, FI_TAG_ALIA, FI_TAG_SIZE, FI_TAG_FSKN, FI_TAG_SHA1, FI_TAG_CHA1, FI_TAG_DONE, FI_TAG_TIME, FI_TAG_CTIM, FI_TAG_NTIM, FI_TAG_SWRM, FI_TAG_CHNK, FI_TAG_GUID, NUM_FI_TAGS } |
Functions | |
RCSID ("$Id:fileinfo.c, v 1.81 2006/01/31 08:16:13 cbiere Exp $") | |
fileinfo_t * | file_info_retrieve_binary (const gchar *file, const gchar *path) |
Reads the file metainfo from the trailer of a file, if it exists. | |
void | fi_free (fileinfo_t *fi) |
Free a `file_info' structure. | |
void | file_info_hash_remove (fileinfo_t *fi) |
Remove fileinfo data from all the hash tables. | |
void | fi_update_seen_on_network (gnet_src_t srcid) |
Callback for updates to ranges available on the network. | |
gchar * | file_info_new_outname (const gchar *name, const gchar *dir) |
Allocate unique output name for file `name', stored in `dir'. | |
gboolean | looks_like_urn (const gchar *filename) |
Check whether filename looks like an URN. | |
gboolean | trailer_is_64bit (const struct trailer *tb) |
Checks the kind of trailer. | |
void | tbuf_extend (guint32 x, gboolean writing) |
Make sure there is enough room in the buffer for `x' more bytes. | |
void | tbuf_write (gint fd, gchar *name) |
Write trailer buffer at current position on `fd', whose name is `name'. | |
gint | tbuf_read (gint fd, gint len) |
Read trailer buffer at current position from `fd'. | |
void | file_info_checksum (guint32 *checksum, gchar *d, int len) |
gboolean | file_info_check_chunklist (fileinfo_t *fi, gboolean assertion) |
Checks the chunklist of fi. | |
void | file_info_fd_store_binary (fileinfo_t *fi, int fd, gboolean force) |
Store a binary record of the file metainformation at the end of the supplied file descriptor, opened for writing. | |
void | file_info_store_binary (fileinfo_t *fi) |
Store a binary record of the file metainformation at the end of the output file, if it exists. | |
void | file_info_strip_binary (fileinfo_t *fi) |
Strips the file metainfo trailer off a file. | |
void | file_info_strip_binary_from_file (fileinfo_t *fi, const gchar *file) |
Strips the file metainfo trailer off specified file. | |
void | file_info_chunklist_free (fileinfo_t *fi) |
Frees the chunklist and all its elements of a fileinfo struct. | |
void | fi_resize (fileinfo_t *fi, filesize_t size) |
Resize fileinfo to be `size' bytes, by adding empty chunk at the tail. | |
void | fi_alias (fileinfo_t *fi, gchar *name, gboolean record) |
Add `name' as an alias for `fi' if not already known. | |
gboolean | file_info_get_trailer (gint fd, struct trailer *tb, const gchar *name) |
Extract fixed trailer at the end of the file `name', already opened as `fd'. | |
gboolean | file_info_has_trailer (const gchar *path) |
Check whether file has a trailer. | |
gboolean | file_info_has_filename (fileinfo_t *fi, gchar *file) |
fileinfo_t * | file_info_lookup (gchar *name, filesize_t size, const gchar *sha1) |
Lookup our existing fileinfo structs to see if we can spot one referencing the supplied file `name' and `size', as well as the optional `sha1' hash. | |
fileinfo_t * | file_info_lookup_dup (fileinfo_t *fi) |
Given a fileinfo structure, look for any other known duplicate. | |
const gchar * | file_info_readable_filename (const fileinfo_t *fi) |
Determines a human-readable filename for the file, using heuristics to skip what looks like an URN. | |
shared_file_t * | file_info_shared_sha1 (const gchar *sha1) |
Look whether we have a partially downloaded file bearing the given SHA1. | |
gchar * | fi_random_guid_atom (void) |
Allocate random GUID to use as the file ID. | |
gboolean | fi_upgrade_older_version (fileinfo_t *fi) |
Ensure potentially old fileinfo structure is brought up-to-date by inferring or allocating missing fields. | |
void | file_info_store_one (FILE *f, fileinfo_t *fi) |
Stores a file info record to the config_dir/fileinfo file, and appends it to the output file in question if needed. | |
void | file_info_store_list (gpointer key, gpointer val, gpointer x) |
Callback for hash table iterator. | |
void | file_info_store (void) |
Stores the list of output files and their metainfo to the configdir/fileinfo database. | |
void | file_info_store_if_dirty (void) |
Store global file information cache if dirty. | |
void | fi_dispose (fileinfo_t *fi) |
void | file_info_free_sha1_kv (gpointer key, gpointer val, gpointer unused_x) |
Callback for hash table iterator. | |
void | file_info_free_namesize_kv (gpointer key, gpointer val, gpointer unused_x) |
Callback for hash table iterator. | |
void | file_info_free_size_kv (gpointer unused_key, gpointer val, gpointer unused_x) |
Callback for hash table iterator. | |
void | file_info_free_guid_kv (gpointer key, gpointer val, gpointer unused_x) |
Callback for hash table iterator. | |
void | file_info_free_outname_kv (gpointer key, gpointer val, gpointer unused_x) |
Callback for hash table iterator. | |
void | file_info_changed (fileinfo_t *fi) |
Signals that some information in the fileinfo has changed, warranting a display update in the GUI. | |
void | file_info_close_pre (void) |
Pre-close some file_info information. | |
void | file_info_close (void) |
Close and free all file_info structs in the list. | |
void | file_info_hash_insert (fileinfo_t *fi) |
Inserts a file_info struct into the hash tables. | |
void | file_info_upload_stop (fileinfo_t *fi, const gchar *reason) |
Stop all sharing occuring for this fileinfo. | |
void | file_info_unlink (fileinfo_t *fi) |
Unlink file from disk. | |
void | file_info_reparent_all (fileinfo_t *from, fileinfo_t *to) |
Reparent all downloads using `from' as a fileinfo, so they use `to' now. | |
gboolean | file_info_got_sha1 (fileinfo_t *fi, const gchar *sha1) |
Called when we discover the SHA1 of a running download. | |
gchar * | extract_guid (const gchar *s) |
Extract GUID from GUID line in the ASCII "fileinfo" summary file and return NULL if none or invalid, the GUID atom otherwise. | |
gchar * | extract_sha1 (const gchar *s) |
Extract sha1 from SHA1/CHA1 line in the ASCII "fileinfo" summary file and return NULL if none or invalid, the SHA1 atom otherwise. | |
fi_tag_t | file_info_string_to_tag (const gchar *s) |
Transform fileinfo tag string into tag constant. | |
void | fi_reset_chunks (fileinfo_t *fi) |
Reset CHUNK info: everything will have to be downloaded again. | |
void | fi_copy_chunks (fileinfo_t *fi, fileinfo_t *trailer) |
Copy CHUNK info from binary trailer `trailer' into `fi'. | |
void | file_info_retrieve (void) |
Loads the fileinfo database from disk, and saves a copy in fileinfo.orig. | |
fileinfo_t * | file_info_create (gchar *file, const gchar *path, filesize_t size, const gchar *sha1, gboolean file_size_known) |
Create a fileinfo structure from existing file with no swarming trailer. | |
fileinfo_t * | file_info_get_browse (const gchar *name) |
Create a transient fileinfo structure to be perused by browse host. | |
void | fi_rename_dead (fileinfo_t *fi, const gchar *path, const gchar *basename) |
Rename dead file we cannot use, either because it bears a duplicate SHA1 or because its file trailer bears a duplicate file ID. | |
fileinfo_t * | file_info_get (gchar *file, const gchar *path, filesize_t size, gchar *sha1, gboolean file_size_known) |
fileinfo_t * | file_info_has_identical (gchar *file, filesize_t size, gchar *sha1) |
void | file_info_set_discard (fileinfo_t *fi, gboolean state) |
Set or clear the discard state for a fileinfo. | |
void | file_info_merge_adjacent (fileinfo_t *fi) |
Go through the chunk list and merge adjacent chunks that share the same status and download. | |
void | file_info_size_known (struct download *d, filesize_t size) |
Signals that file size became known suddenly. | |
void | file_info_update (struct download *d, filesize_t from, filesize_t to, enum dl_chunk_status status) |
Marks a chunk of the file with given status. | |
void | file_info_clear_download (struct download *d, gboolean lifecount) |
Go through all chunks that belong to the download, and unmark them as busy. | |
void | file_info_reset (fileinfo_t *fi) |
Reset all chunks to EMPTY, clear computed SHA1 if any. | |
enum dl_chunk_status | file_info_chunk_status (fileinfo_t *fi, filesize_t from, filesize_t to) |
enum dl_chunk_status | file_info_pos_status (fileinfo_t *fi, filesize_t pos) |
void | fi_check_file (fileinfo_t *fi) |
This routine is called each time we start a new download, before making the request to the remote server. | |
gint | fi_busy_count (fileinfo_t *fi, struct download *d) |
Count the amount of BUSY chunks attached to a given download. | |
GSList * | list_clone_shift (fileinfo_t *fi) |
Clone fileinfo's chunk list, shifting the origin of the list to a randomly selected offset within the file. | |
filesize_t | fi_chunksize (fileinfo_t *fi) |
Compute chunksize to be used for the current request. | |
enum dl_chunk_status | file_info_find_hole (struct download *d, filesize_t *from, filesize_t *to) |
Finds a range to download, and stores it in *from and *to. | |
gboolean | file_info_find_available_hole (struct download *d, GSList *ranges, filesize_t *from, filesize_t *to) |
Find free chunk that also fully belongs to the `ranges' list. | |
fileinfo_t * | file_info_active (const gchar *sha1) |
void | file_info_try_to_swarm_with (gchar *file_name, guint32 idx, const host_addr_t addr, guint16 port, gchar *sha1) |
Called when we add something to the dmesh. | |
void | file_info_scandir (const gchar *dir) |
Scan the given directory for files, looking at those bearing a valid fileinfo trailer, yet which we know nothing about. | |
void | fi_spot_completed_kv (gpointer key, gpointer val, gpointer unused_x) |
Callback for hash table iterator. | |
void | file_info_spot_completed_orphans (void) |
Look through all the known fileinfo structures, looking for orphaned files that are complete. | |
void | fi_add_listener (fi_listener_t cb, gnet_fi_ev_t ev, frequency_t t, guint32 interval) |
void | fi_remove_listener (fi_listener_t cb, gnet_fi_ev_t ev) |
gnet_fi_info_t * | fi_get_info (gnet_fi_t fih) |
Get an information structure summarizing the file info. | |
void | fi_free_info (gnet_fi_info_t *info) |
Dispose of the info structure. | |
void | fi_get_status (gnet_fi_t fih, gnet_fi_status_t *s) |
Fill in the fileinfo status structure "s" using the fileinfo associated with the fileinfo handle "fih". | |
GSList * | fi_get_chunks (gnet_fi_t fih) |
Get a list with information about each chunk and status. | |
void | fi_free_chunks (GSList *chunks) |
Free chunk list got by calling fi_get_chunks. | |
GSList * | fi_get_ranges (gnet_fi_t fih) |
Get a list of available ranges for this fileinfo handle. | |
void | fi_free_ranges (GSList *ranges) |
gchar ** | fi_get_aliases (gnet_fi_t fih) |
void | file_info_add_new_source (fileinfo_t *fi, struct download *dl) |
Add new download source for the file. | |
void | file_info_add_source (fileinfo_t *fi, struct download *dl) |
Add download source for the file, but preserve original "ntime". | |
void | file_info_remove_source (fileinfo_t *fi, struct download *dl, gboolean discard) |
Removing one source reference from the fileinfo. | |
void | file_info_remove (fileinfo_t *fi) |
Remove non-referenced fileinfo and reclaim its data structures. | |
void | fi_notify_helper (gpointer unused_key, gpointer value, gpointer unused_udata) |
void | file_info_timer (void) |
gboolean | fi_purge (gnet_fi_t fih) |
Kill all downloads associated with a fi and remove the fi itself. | |
void | fi_purge_by_handle_list (const GSList *list) |
Purge all handles contained in list. | |
gint | file_info_available_ranges (fileinfo_t *fi, gchar *buf, gint size) |
Emit an X-Available-Ranges header listing the ranges within the file that we have on disk and we can share as a PFSP-server. | |
gboolean | file_info_restrict_range (fileinfo_t *fi, filesize_t start, filesize_t *end) |
Given a request range `start' (included) and `end' (included) for the partially downloaded file represented by `fi', see whether we can satisfy it, even partially, without touching `start' but only only by possibly moving `end' down. | |
GSList * | fi_range_for_complete_file (filesize_t size) |
Create a ranges list with one item covering the whole file. | |
void | file_info_init (void) |
Initialize fileinfo handling. | |
void | file_info_init_post (void) |
Finish initialization of fileinfo handling. | |
Variables | |
GHashTable * | fi_by_sha1 = NULL |
GHashTable * | fi_by_namesize = NULL |
GHashTable * | fi_by_size = NULL |
GHashTable * | fi_by_outname = NULL |
GHashTable * | fi_by_guid = NULL |
const gchar | file_info_file [] = "fileinfo" |
const gchar | file_info_what [] = "the fileinfo database" |
gboolean | fileinfo_dirty = FALSE |
gboolean | can_swarm = FALSE |
Set by file_info_retrieve(). | |
gchar | fi_tmp [4096] |
struct { | |
gchar * arena | |
gchar * wptr | |
gchar * rptr | |
gchar * end | |
guint32 size | |
} | tbuf |
The swarming trailer is built within a memory buffer first, to avoid having to issue mutliple write() system calls. | |
idtable_t * | fi_handle_map = NULL |
event_t * | fi_events [EV_FI_EVENTS] |
const struct fi_tag | fi_tag_map [] |
|
Value: G_STMT_START { \ reason = (x); \ goto bailout; \ /* NOTREACHED */ \ } G_STMT_END |
|
|
|
Max field length we accept to save.
|
|
Smallest chunk we can split.
|
|
Max delay (secs) for flushing fileinfo.
|
|
Amount of guint32 in the trailer.
|
|
Value: do { \ guint32 l = (b); \ WRITE_INT32(a); \ WRITE_INT32(l); \ WRITE_STR(c, l); \ } while(0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
Value: G_STMT_START { \ return fi_tag_map[(i)].tag; \ /* NOTREACHED */ \ } G_STMT_END |
|
|
|
|
|
Value: do { \ guint8 val; \ TBUF_GETCHAR(&val); \ file_info_checksum(&checksum, (gchar *) &val, sizeof(val)); \ } while(0) |
|
Value: do { \ gint32 val; \ TBUF_GETINT32(&val); \ STATIC_ASSERT(sizeof val <= sizeof(*a)); \ *a = ntohl(val); \ file_info_checksum(&checksum, (gchar *) &val, sizeof(val)); \ } while(0) |
|
Value: do { \ TBUF_READ(a, b); \ file_info_checksum(&checksum, (gchar *) a, b); \ } while(0) |
|
|
|
Value: do { \ if ((tbuf.wptr + (x)) > tbuf.end) \ tbuf_extend(x, TRUE); \ } while (0) |
|
Value: do { \ if (tbuf.rptr + sizeof(guint8) <= tbuf.end) { \ *x = *(guint8 *) tbuf.rptr; \ tbuf.rptr++; \ } else \ goto eof; \ } while (0) |
|
Value: do { \ if (tbuf.rptr + sizeof(gint32) <= tbuf.end) { \ if (int32_aligned(tbuf.rptr)) \ *x = *(gint32 *) tbuf.rptr; \ else \ memcpy(x, tbuf.rptr, sizeof(gint32)); \ tbuf.rptr += sizeof(gint32); \ } else \ goto eof; \ } while (0) |
|
|
|
Growing chunks.
|
|
|
|
Value: do { \ if ((tbuf.arena + (s)) > tbuf.end) \ tbuf_extend(s, FALSE); \ tbuf.wptr = NULL; \ tbuf.rptr = tbuf.arena; \ tbuf.end = tbuf.arena + (s); \ } while (0) |
|
Value: do { \ tbuf.rptr = NULL; \ tbuf.wptr = tbuf.arena; \ tbuf.end = tbuf.arena + tbuf.size; \ } while (0) |
|
Value: do { \ TBUF_CHECK(sizeof(guint8)); \ *(guint8 *) tbuf.wptr = x; \ tbuf.wptr++; \ } while (0) |
|
Value: do { \ TBUF_CHECK(sizeof(guint32)); \ if (int32_aligned(tbuf.wptr)) \ *(guint32 *) tbuf.wptr = x; \ else \ memcpy(tbuf.wptr, &x, sizeof(gint32)); \ tbuf.wptr += sizeof(gint32); \ } while (0) |
|
Value: |
|
Initial trailing buffer size.
|
|
Value: do { \ TBUF_CHECK(s); \ memcpy(tbuf.wptr, x, s); \ tbuf.wptr += s; \ } while (0) |
|
|
|
|
|
Value: do { \ guint8 val = a; \ TBUF_PUTCHAR(val); \ file_info_checksum(&checksum, (gchar *) &val, sizeof(val)); \ } while (0) |
|
Value: do { \ gint32 val = htonl(a); \ TBUF_PUTINT32(val); \ file_info_checksum(&checksum, (gchar *) &val, sizeof(val)); \ } while(0) |
|
Value: do { \ TBUF_WRITE(a, b); \ file_info_checksum(&checksum, (gchar *) a, b); \ } while(0) |
|
Value: do { \ guint32 val = htonl(a); \ TBUF_PUTINT32(val); \ file_info_checksum(&checksum, (gchar *) &val, sizeof(val)); \ } while(0) |
|
|
|
|
|
|
|
Extract GUID from GUID line in the ASCII "fileinfo" summary file and return NULL if none or invalid, the GUID atom otherwise.
|
|
Extract sha1 from SHA1/CHA1 line in the ASCII "fileinfo" summary file and return NULL if none or invalid, the SHA1 atom otherwise.
|
|
|
|
Add `name' as an alias for `fi' if not already known. If `record' is TRUE, also record new alias entry in `fi_by_namesize'. |
|
Count the amount of BUSY chunks attached to a given download.
|
|
This routine is called each time we start a new download, before making the request to the remote server. If we detect that the file is "gone", then it means the user manually deleted the file. In that case, we need to reset all the chunks and mark the whole thing as being EMPTY. --RAM, 21/08/2002. |
|
Compute chunksize to be used for the current request.
|
|
Copy CHUNK info from binary trailer `trailer' into `fi'.
|
|
|
|
Free a `file_info' structure.
|
|
Free chunk list got by calling fi_get_chunks.
|
|
Dispose of the info structure.
|
|
|
|
|
|
Get a list with information about each chunk and status. Returns a linked list of chunks with just the end byte and the status. The list is fully allocated and the receiver is responsible for freeing up the memory. |
|
Get an information structure summarizing the file info. This is used by the GUI to avoid peeking into the file info structure directly: it has its own little pre-digested information to display. |
|
Get a list of available ranges for this fileinfo handle. The list is fully allocated and the receiver is responsible for freeing up the memory, for example using fi_free_ranges(). |
|
Fill in the fileinfo status structure "s" using the fileinfo associated with the fileinfo handle "fih".
|
|
|
|
Kill all downloads associated with a fi and remove the fi itself. Will return FALSE if download could not be removed because it was still in use, e.g. when it is being verified. -- JA 25/10/03 |
|
Purge all handles contained in list.
|
|
Allocate random GUID to use as the file ID.
|
|
Create a ranges list with one item covering the whole file. This may be better placed in http.c, but since it is only used here as a utility function for fi_update_seen_on_network it is now placed here.
|
|
|
|
Rename dead file we cannot use, either because it bears a duplicate SHA1 or because its file trailer bears a duplicate file ID. The file is really dead, so unfortunately we have to strip its fileinfo trailer so that we do not try to reparent it at a later time. |
|
Reset CHUNK info: everything will have to be downloaded again.
|
|
Resize fileinfo to be `size' bytes, by adding empty chunk at the tail.
|
|
Callback for hash table iterator. Used by file_info_completed_orphans(). |
|
Callback for updates to ranges available on the network. This function gets triggered by an event when new ranges information has become available for a download source. We collect the set of currently available ranges in file_info->seen_on_network. Currently we only fold in new ranges from a download source, but we should also remove sets of ranges when a download source is no longer available.
|
|
Ensure potentially old fileinfo structure is brought up-to-date by inferring or allocating missing fields.
|
|
|
|
Add new download source for the file.
|
|
Add download source for the file, but preserve original "ntime".
|
|
Emit an X-Available-Ranges header listing the ranges within the file that we have on disk and we can share as a PFSP-server. The header is emitted in `buf', which is `size' bytes long. If there is not enough room to emit all the ranges, emit a random subset of the ranges.
|
|
Signals that some information in the fileinfo has changed, warranting a display update in the GUI.
|
|
Checks the chunklist of fi.
|
|
|
|
|
|
Frees the chunklist and all its elements of a fileinfo struct. Note that the consistency of the list isn't checked to explicitely allow freeing inconsistent chunklists.
|
|
Go through all chunks that belong to the download, and unmark them as busy. If `lifecount' is TRUE, the download is still counted as being "alive", and this is only used for assertions. < For assertions only |
|
Close and free all file_info structs in the list.
|
|
Pre-close some file_info information. This should be separate from file_info_close so that we can avoid circular dependencies with other close routines, in this case with download_close. |
|
Create a fileinfo structure from existing file with no swarming trailer. The given `size' argument reflect the final size of the (complete) file. The `sha1' is the known SHA1 for the file (NULL if unknown). |
|
Store a binary record of the file metainformation at the end of the supplied file descriptor, opened for writing. When `force' is false, we don't store unless FI_STORE_DELAY seconds have elapsed since last flush to disk. |
|
Find free chunk that also fully belongs to the `ranges' list. If found, the returned chunk is marked BUSY and linked to the download `d'.
|
|
Finds a range to download, and stores it in *from and *to. If "aggressive" is off, it will return only ranges that are EMPTY. If on, and no EMPTY ranges are available, it will grab a chunk out of the longest BUSY chunk instead, and "compete" with the download that reserved it. |
|
Callback for hash table iterator. Used by file_info_close(). |
|
Callback for hash table iterator. Used by file_info_close(). |
|
Callback for hash table iterator. Used by file_info_close(). |
|
Callback for hash table iterator. Used by file_info_close(). |
|
Callback for hash table iterator. Used by file_info_close(). |
|
|
|
Create a transient fileinfo structure to be perused by browse host.
|
|
Extract fixed trailer at the end of the file `name', already opened as `fd'. The supplied trailer buffer `tb' is filled.
|
|
Called when we discover the SHA1 of a running download. Make sure there is no other entry already bearing that SHA1, and record the information.
|
|
|
|
|
|
Check whether file has a trailer.
|
|
Inserts a file_info struct into the hash tables.
|
|
Remove fileinfo data from all the hash tables.
|
|
Initialize fileinfo handling.
|
|
Finish initialization of fileinfo handling. This post initialization is needed to avoid circular dependencies during the init phase. The listener we set up here is set up in download_init, but that must be called after file_info_init. |
|
Lookup our existing fileinfo structs to see if we can spot one referencing the supplied file `name' and `size', as well as the optional `sha1' hash.
|
|
Given a fileinfo structure, look for any other known duplicate.
|
|
Go through the chunk list and merge adjacent chunks that share the same status and download. Keeps the chunk list short and tidy. |
|
Allocate unique output name for file `name', stored in `dir'.
|
|
|
|
Determines a human-readable filename for the file, using heuristics to skip what looks like an URN.
|
|
Remove non-referenced fileinfo and reclaim its data structures.
|
|
Removing one source reference from the fileinfo. When no sources reference the fileinfo structure, free it if `discard' is TRUE, or if the fileinfo has been marked with FI_F_DISCARD. This replaces file_info_free() |
|
Reparent all downloads using `from' as a fileinfo, so they use `to' now.
|
|
Reset all chunks to EMPTY, clear computed SHA1 if any.
|
|
Given a request range `start' (included) and `end' (included) for the partially downloaded file represented by `fi', see whether we can satisfy it, even partially, without touching `start' but only only by possibly moving `end' down.
|
|
Loads the fileinfo database from disk, and saves a copy in fileinfo.orig.
|
|
Reads the file metainfo from the trailer of a file, if it exists.
|
|
Scan the given directory for files, looking at those bearing a valid fileinfo trailer, yet which we know nothing about.
|
|
Set or clear the discard state for a fileinfo.
|
|
Look whether we have a partially downloaded file bearing the given SHA1. If we do, return a "shared_file" structure suitable for uploading the parts of the file we have (will happen only when PFSP-server is enabled).
|
|
Signals that file size became known suddenly. The download becomes the owner of the "busy" part between what we have done and the end of the file. |
|
Look through all the known fileinfo structures, looking for orphaned files that are complete. A fake download is created for them, so that download_resume_bg_tasks() can pick them up. |
|
Stores the list of output files and their metainfo to the configdir/fileinfo database.
|
|
Store a binary record of the file metainformation at the end of the output file, if it exists.
|
|
Store global file information cache if dirty.
|
|
Callback for hash table iterator. Used by file_info_store(). |
|
Stores a file info record to the config_dir/fileinfo file, and appends it to the output file in question if needed.
|
|
Transform fileinfo tag string into tag constant. For instance, "TIME" would yield FI_TAG_TIME. An unknown tag yieldd FI_TAG_UNKNOWN. |
|
Strips the file metainfo trailer off a file.
|
|
Strips the file metainfo trailer off specified file.
|
|
|
|
Called when we add something to the dmesh. Add the corresponding file to the download list if we're swarming on it.
|
|
Unlink file from disk.
|
|
Marks a chunk of the file with given status. The bytes range from `from' (included) to `to' (excluded). When not marking the chunk as EMPTY, the range is linked to the supplied download `d' so we know who "owns" it currently. |
|
Stop all sharing occuring for this fileinfo.
|
|
Clone fileinfo's chunk list, shifting the origin of the list to a randomly selected offset within the file. If the first chunk is not completed or not at least `pfsp_first_chunk' bytes long, the original list is returned. |
|
Check whether filename looks like an URN.
|
|
|
|
Make sure there is enough room in the buffer for `x' more bytes. If `writing' is TRUE, we update the write pointer. |
|
Read trailer buffer at current position from `fd'.
|
|
Write trailer buffer at current position on `fd', whose name is `name'.
|
|
Checks the kind of trailer. The trailer must be initialized.
|
|
Base arena.
|
|
Set by file_info_retrieve().
|
|
First byte off arena.
|
|
|
|
|
|
|
|
|
|
|
|
Initial value: { NULL, NULL, NULL, NULL, NULL, NULL } |
|
|
|
|
|
|
|
|
|
|
|
|
|
Read pointer.
|
|
Current size of arena.
|
|
The swarming trailer is built within a memory buffer first, to avoid having to issue mutliple write() system calls. We can't use stdio's buffering since we can sometime reuse the download's file descriptor. |
|
Write pointer.
|