Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

share.c File Reference


Detailed Description

Handle sharing of our own files and answers to remote queries.

Author:
Daniel Walker (dwalker@cats.ucsc.edu)
Date:
2000
Author:
Raphael Manfredi
Date:
2001-2005

#include "common.h"
#include "share.h"
#include "gmsg.h"
#include "huge.h"
#include "qrp.h"
#include "extensions.h"
#include "nodes.h"
#include "uploads.h"
#include "ggep_type.h"
#include "gnet_stats.h"
#include "search.h"
#include "guid.h"
#include "hostiles.h"
#include "matching.h"
#include "qhit.h"
#include "oob.h"
#include "oob_proxy.h"
#include "fileinfo.h"
#include "settings.h"
#include "hosts.h"
#include "if/gnet_property.h"
#include "if/gnet_property_priv.h"
#include "if/bridge/c2ui.h"
#include "lib/atoms.h"
#include "lib/endian.h"
#include "lib/file.h"
#include "lib/hashlist.h"
#include "lib/listener.h"
#include "lib/glib-missing.h"
#include "lib/tm.h"
#include "lib/utf8.h"
#include "lib/walloc.h"
#include "lib/override.h"

Data Structures

struct  shared_file
struct  special_file
 Describes special files which are served by GTKG. More...
struct  query_context
 A query context. More...

Defines

#define MIN_WORD_LENGTH   1
 For compaction.
#define APPEND_WORD()

Enumerations

enum  shared_file_magic { SHARED_FILE_MAGIC = 0x3702b437U }

Functions

gint compare_share_sha1 (gconstpointer s1, gconstpointer s2)
 Compare binary SHA1 hashes.
void reinit_sha1_table (void)
 Reset sha1_to_share.
void share_add_search_request_listener (search_request_listener_t l)
void share_remove_search_request_listener (search_request_listener_t l)
void share_emit_search_request (query_type_t type, const gchar *query, const host_addr_t addr, guint16 port)
query_contextshare_query_context_make (void)
 Create new query context.
void share_query_context_free (struct query_context *ctx)
 Get rid of the query context.
gboolean shared_file_already_found (struct query_context *ctx, const shared_file_t *sf)
 Check if a given shared_file has been added to the QueryHit.
void shared_file_mark_found (struct query_context *ctx, const shared_file_t *sf)
 Add the shared_file to the set of files already added to the QueryHit.
void got_match (gpointer context, gpointer data)
 Invoked for each new match we get.
void shared_file_check (const struct shared_file *sf)
shared_file_tshared_file_alloc (void)
 Allocate a shared_file_t structure.
void shared_file_deindex (shared_file_t *sf)
void shared_file_free (shared_file_t **sf_ptr)
 Dispose of a shared_file_t structure and nullify the pointer.
gboolean shared_file_set_names (shared_file_t *sf, const gchar *filename)
shared_file_tshare_special_load (const struct special_file *sp)
 Initialize special file entry, returning shared_file_t structure if the file exists, NULL otherwise.
void share_special_init (void)
 Initialize the special files we're sharing.
shared_file_tshared_special (const gchar *path)
 Look up a possibly shared special file, updating the entry with current file size and modification time.
void query_muid_map_init (void)
gboolean query_muid_map_remove_oldest (void)
void query_muid_map_close (void)
void query_muid_map_garbage_collect (void)
void record_query_string (const gchar muid[GUID_RAW_SIZE], const gchar *query)
const gchar * map_muid_to_query_string (const gchar muid[GUID_RAW_SIZE])
void share_init (void)
 Initialization of the sharing library.
shared_file_tshared_file (guint idx)
 Given a valid index, returns the `struct shared_file' entry describing the shared file bearing that index if found, NULL if not found (invalid index) and SHARE_REBUILDING when we're rebuilding the library.
guint shared_file_get_index (const gchar *filename)
 Get index of shared file identified by its name.
shared_file_tshared_file_by_name (const gchar *filename)
 Given a file basename, returns the `struct shared_file' entry describing the shared file bearing that basename, provided it is unique, NULL if we either don't have a unique filename or SHARE_REBUILDING if the library is being rebuilt.
const gchar * share_mime_type (enum share_mime_type type)
 Returns the MIME content type string.
void free_extensions_helper (gpointer key, gpointer unused_value, gpointer unused_data)
void free_extensions (void)
 Free existing extensions.
void parse_extensions (const gchar *str)
 Get the file extensions to scan.
void shared_dirs_free (void)
 Release shared dirs.
void shared_dirs_update_prop (void)
 Update the property holding the shared directories.
gboolean shared_dirs_parse (const gchar *str)
 Parses the given string and updated the internal list of shared dirs.
void shared_dir_add (const gchar *path)
 Add directory to the list of shared directories.
shared_file_tshared_file_ref (shared_file_t *sf)
 Add one more reference to a shared_file_t.
void shared_file_unref (shared_file_t **sf_ptr)
 Remove one reference to a shared_file_t, freeing entry if there are no reference left.
gboolean too_big_for_gnutella (off_t size)
 Is file too big to be shared on Gnutella?
gboolean contains_control_chars (const gchar *pathname)
 Checks whether it's OK to share the pathname with respect to special characters in the string.
const gchar * get_relative_path (const gchar *base_dir, const gchar *pathname)
 Extracts the relative path from a pathname relative to base_dir.
gboolean shared_file_valid_extension (const gchar *filename)
 Verify that a file extension is valid for sharing.
shared_file_tshare_scan_add_file (const gchar *relative_path, const gchar *pathname, const struct stat *sb)
mode_t dir_entry_mode (const struct dirent *dir_entry)
 Tries to extrace the file mode from a struct dirent.
void recurse_scan_intern (const gchar *const base_dir, const gchar *const dir)
 The directories that are given as shared will be completly transversed including all files and directories.
void recurse_scan (const gchar *base_dir)
void share_free (void)
 Free up memory used by the shared library.
gint shared_file_sort_by_mtime (gconstpointer f1, gconstpointer f2)
 Sort function - shared files by descending mtime.
void share_scan (void)
 Perform scanning of the shared directories to build up the list of shared files.
void special_free_kv (gpointer unused_key, gpointer val, gpointer unused_udata)
 Hash table iterator callback to free the value.
void share_special_close (void)
 Get rid of the special file descriptions, if any.
void share_close (void)
 Shutdown cleanup.
size_t compact_query_utf8 (gchar *search)
 Remove unnecessary ballast from a query before processing it.
gboolean query_utf8_decode (const gchar *text, guint *retoff)
 Determine whether the given string is UTF-8 encoded.
size_t compact_query (gchar *search)
 Remove unnecessary ballast from a query string, in-place.
void query_strip_oob_flag (const gnutella_node_t *n, gchar *data)
 Remove the OOB delivery flag by patching the query message inplace.
void query_set_oob_flag (const gnutella_node_t *n, gchar *data)
 Set the OOB delivery flag by patching the query message inplace.
gboolean search_request (struct gnutella_node *n, query_hashvec_t *qhv)
 Searches requests (from others nodes) Basic matching.
void shared_file_set_sha1 (struct shared_file *sf, const struct sha1 *sha1)
 Set the SHA1 hash of a given shared_file.
void shared_file_set_tth (struct shared_file *sf, const struct tth *tth)
void shared_file_set_modification_time (struct shared_file *sf, time_t mtime)
gboolean sha1_hash_available (const struct shared_file *sf)
 Predicate returning TRUE if the SHA1 hash is available for a given shared_file, FALSE otherwise.
gboolean sha1_hash_is_uptodate (struct shared_file *sf)
 Predicate returning TRUE if the SHA1 hash is available AND is up to date for the shared file.
gboolean shared_file_is_partial (const struct shared_file *sf)
filesize_t shared_file_size (const shared_file_t *sf)
guint32 shared_file_index (const shared_file_t *sf)
const struct sha1shared_file_sha1 (const shared_file_t *sf)
const struct tthshared_file_tth (const shared_file_t *sf)
const gchar * shared_file_name_nfc (const shared_file_t *sf)
const gchar * shared_file_name_canonic (const shared_file_t *sf)
size_t shared_file_name_nfc_len (const shared_file_t *sf)
size_t shared_file_name_canonic_len (const shared_file_t *sf)
const gchar * shared_file_relative_path (const shared_file_t *sf)
 Returns the relative path of the shared files unless there was none or exposing relative paths is disabled.
const gchar * shared_file_path (const shared_file_t *sf)
 Get the pathname of a shared file.
time_t shared_file_modification_time (const shared_file_t *sf)
guint32 shared_file_flags (const shared_file_t *sf)
fileinfo_tshared_file_fileinfo (const shared_file_t *sf)
const gchar * shared_file_content_type (const shared_file_t *sf)
void shared_file_remove (struct shared_file *sf)
void shared_file_set_path (struct shared_file *sf, const gchar *pathname)
void shared_file_from_fileinfo (fileinfo_t *fi)
shared_fileshared_file_complete_by_sha1 (const struct sha1 *sha1)
shared_file_tshared_file_by_sha1 (const struct sha1 *sha1)
 Take a given binary SHA1 digest, and return the corresponding shared_file if we have it.
guint64 shared_kbytes_scanned (void)
 Get accessor for ``kbytes_scanned''.
guint64 shared_files_scanned (void)
 Get accessor for ``files_scanned''.

Variables

const struct special_file specials []
GHashTable * special_names = NULL
 Maps special names (e.g.
guint64 files_scanned = 0
guint64 bytes_scanned = 0
GHashTable * extensions = NULL
GSList * shared_dirs = NULL
GSList * shared_files = NULL
shared_file ** file_table = NULL
search_table_tsearch_table
GHashTable * file_basenames = NULL
GHashTable * muid_to_query_map
hash_list_tquery_muids
GTree * sha1_to_share
 This tree maps a SHA1 hash (base-32 encoded) onto the corresponding shared_file if we have one.
listeners_t search_request_listeners = NULL
const guint FILENAME_CLASH = -1
 Indicates basename clashes.


Define Documentation

 
#define APPEND_WORD  ) 
 

Value:

do {                                                \
    /* Append a space unless it's the first word */ \
    if (p != search) {                              \
        if (*p != ' ')                              \
            *p = ' ';                               \
        p++;                                        \
    }                                               \
    if (p != word)                                  \
        memmove(p, word, word_length);              \
    p += word_length;                               \
} while (0)

#define MIN_WORD_LENGTH   1
 

For compaction.


Enumeration Type Documentation

enum shared_file_magic
 

Enumeration values:
SHARED_FILE_MAGIC 


Function Documentation

size_t compact_query gchar *  search  ) 
 

Remove unnecessary ballast from a query string, in-place.

Returns:
new query string length.

size_t compact_query_utf8 gchar *  search  )  [static]
 

Remove unnecessary ballast from a query before processing it.

Works in place on the given string. Removed are all consecutive blocks of whitespace and all words shorter then MIN_WORD_LENGTH.

Parameters:
search the search string to compact, modified in place.
Returns:
the length in bytes of the compacted search string.

gint compare_share_sha1 gconstpointer  s1,
gconstpointer  s2
[static]
 

Compare binary SHA1 hashes.

Returns:
0 if they're the same, a negative or positive number if s1 if greater than s2 or s1 greater than s2, respectively. Used to search the sha1_to_share tree.

gboolean contains_control_chars const gchar *  pathname  )  [static]
 

Checks whether it's OK to share the pathname with respect to special characters in the string.

As the database stores records line-by-line, newline characters in the filename are not acceptable.

Returns:
If the pathname contains ASCII control characters, TRUE is returned. Otherwise, the pathname is considered OK and FALSE is returned.

mode_t dir_entry_mode const struct dirent *  dir_entry  )  [static]
 

Tries to extrace the file mode from a struct dirent.

Not all systems support this, in which case zero is returned. Types other than regular files, directories and symlinks are ignored and gain a value of zero as well.

void free_extensions void   )  [static]
 

Free existing extensions.

void free_extensions_helper gpointer  key,
gpointer  unused_value,
gpointer  unused_data
[static]
 

const gchar* get_relative_path const gchar *  base_dir,
const gchar *  pathname
[static]
 

Extracts the relative path from a pathname relative to base_dir.

If base_dir and pathname do not overlap, NULL is returned. The resulting is converted to UTF-8 NFC and returned as an atom.

Parameters:
base_dir The base directory.
pathname A pathname that is relative to "base_dir".
Returns:
A string atom holding the relative path or NULL.

void got_match gpointer  context,
gpointer  data
[static]
 

Invoked for each new match we get.

const gchar* map_muid_to_query_string const gchar  muid[GUID_RAW_SIZE]  ) 
 

void parse_extensions const gchar *  str  ) 
 

Get the file extensions to scan.

void query_muid_map_close void   )  [static]
 

void query_muid_map_garbage_collect void   )  [static]
 

void query_muid_map_init void   )  [static]
 

gboolean query_muid_map_remove_oldest void   )  [static]
 

void query_set_oob_flag const gnutella_node_t n,
gchar *  data
 

Set the OOB delivery flag by patching the query message inplace.

void query_strip_oob_flag const gnutella_node_t n,
gchar *  data
 

Remove the OOB delivery flag by patching the query message inplace.

gboolean query_utf8_decode const gchar *  text,
guint *  retoff
[static]
 

Determine whether the given string is UTF-8 encoded.

If query starts with a BOM mark, skip it and set `retoff' accordingly.

Returns:
TRUE if the string is valid UTF-8, FALSE otherwise.

void record_query_string const gchar  muid[GUID_RAW_SIZE],
const gchar *  query
 

void recurse_scan const gchar *  base_dir  )  [static]
 

void recurse_scan_intern const gchar *const   base_dir,
const gchar *const   dir
[static]
 

The directories that are given as shared will be completly transversed including all files and directories.

An entry of "/" would search the the whole file system.

Parameters:
basedir The top-level directory to scan.
dir The current directory to scan recursively; either the same as base_dir or a sub-directory thereof.

void reinit_sha1_table void   )  [static]
 

Reset sha1_to_share.

gboolean search_request struct gnutella_node n,
query_hashvec_t qhv
 

Searches requests (from others nodes) Basic matching.

The search request is made lowercase and is matched to the filenames in the LL.

If `qhv' is not NULL, it is filled with hashes of URN or query words, so that we may later properly route the query among the leaf nodes.

Returns:
TRUE if the message should be dropped and not propagated further.

< Query string start offset

< Wants out-of-band query hit delivery?

gboolean sha1_hash_available const struct shared_file sf  ) 
 

Predicate returning TRUE if the SHA1 hash is available for a given shared_file, FALSE otherwise.

Use sha1_hash_is_uptodate() to check for availability and accurateness.

gboolean sha1_hash_is_uptodate struct shared_file sf  ) 
 

Predicate returning TRUE if the SHA1 hash is available AND is up to date for the shared file.

NB: if the file is found to have changed, the background computation of the SHA1 is requested.

void share_add_search_request_listener search_request_listener_t  l  ) 
 

void share_close void   ) 
 

Shutdown cleanup.

void share_emit_search_request query_type_t  type,
const gchar *  query,
const host_addr_t  addr,
guint16  port
[static]
 

void share_free void   )  [static]
 

Free up memory used by the shared library.

void share_init void   ) 
 

Initialization of the sharing library.

We allocate an empty search_table, which will be de-allocated when we call share_scan(). Why do we do this? Because it ensures the table is correctly setup empty, until we do call share_scan() for the first time (the call is delayed until the GUI is up).

Since we will start processing network packets, we will have a race condition window if we get a Query message before having started the share_scan(). Creating the table right now prevents adding an extra test at the top of st_search(). --RAM, 15/08/2002.

const gchar* share_mime_type enum share_mime_type  type  ) 
 

Returns the MIME content type string.

void share_query_context_free struct query_context ctx  )  [static]
 

Get rid of the query context.

struct query_context* share_query_context_make void   )  [static]
 

Create new query context.

void share_remove_search_request_listener search_request_listener_t  l  ) 
 

void share_scan void   ) 
 

Perform scanning of the shared directories to build up the list of shared files.

shared_file_t* share_scan_add_file const gchar *  relative_path,
const gchar *  pathname,
const struct stat *  sb
[static]
 

Parameters:
relative_path The relative path of the file or NULL.
pathname The absolute pathname of the file.
sb A "stat buffer" that was initialized with stat().
return On success a shared_file_t for the file is returned. Otherwise, NULL is returned.

void share_special_close void   )  [static]
 

Get rid of the special file descriptions, if any.

void share_special_init void   )  [static]
 

Initialize the special files we're sharing.

shared_file_t* share_special_load const struct special_file sp  )  [static]
 

Initialize special file entry, returning shared_file_t structure if the file exists, NULL otherwise.

void shared_dir_add const gchar *  path  ) 
 

Add directory to the list of shared directories.

void shared_dirs_free void   )  [static]
 

Release shared dirs.

gboolean shared_dirs_parse const gchar *  str  ) 
 

Parses the given string and updated the internal list of shared dirs.

The given string was completely parsed, it returns TRUE, otherwise it returns FALSE.

void shared_dirs_update_prop void   ) 
 

Update the property holding the shared directories.

shared_file_t* shared_file guint  idx  ) 
 

Given a valid index, returns the `struct shared_file' entry describing the shared file bearing that index if found, NULL if not found (invalid index) and SHARE_REBUILDING when we're rebuilding the library.

shared_file_t* shared_file_alloc void   )  [static]
 

Allocate a shared_file_t structure.

gboolean shared_file_already_found struct query_context ctx,
const shared_file_t sf
[inline, static]
 

Check if a given shared_file has been added to the QueryHit.

Returns:
TRUE if the shared_file is in the QueryHit already, FALSE otherwise

shared_file_t* shared_file_by_name const gchar *  filename  ) 
 

Given a file basename, returns the `struct shared_file' entry describing the shared file bearing that basename, provided it is unique, NULL if we either don't have a unique filename or SHARE_REBUILDING if the library is being rebuilt.

shared_file_t* shared_file_by_sha1 const struct sha1 sha1  ) 
 

Take a given binary SHA1 digest, and return the corresponding shared_file if we have it.

Attention:
NB: if the returned "shared_file" structure holds a non-NULL `fi', then it means it is a partially shared file.
Returns:
NULL if we don't share a complete file, or SHARE_REBUILDING if the set of shared file is being rebuilt.

void shared_file_check const struct shared_file sf  ) 
 

struct shared_file* shared_file_complete_by_sha1 const struct sha1 sha1  )  [static]
 

Returns:
the shared_file if we share a complete file bearing the given SHA1.

NULL if we don't share a complete file, or SHARE_REBUILDING if the set of shared file is being rebuilt.

const gchar* shared_file_content_type const shared_file_t sf  ) 
 

void shared_file_deindex shared_file_t sf  )  [static]
 

The shared file might not be referenced by the current file_table either because it hasn't been build yet or because of a rescan.

fileinfo_t* shared_file_fileinfo const shared_file_t sf  ) 
 

guint32 shared_file_flags const shared_file_t sf  ) 
 

void shared_file_free shared_file_t **  sf_ptr  )  [static]
 

Dispose of a shared_file_t structure and nullify the pointer.

void shared_file_from_fileinfo fileinfo_t fi  ) 
 

guint shared_file_get_index const gchar *  filename  )  [static]
 

Get index of shared file identified by its name.

Returns:
index > 0 if found, 0 if file is not known.

guint32 shared_file_index const shared_file_t sf  ) 
 

gboolean shared_file_is_partial const struct shared_file sf  ) 
 

void shared_file_mark_found struct query_context ctx,
const shared_file_t sf
[inline, static]
 

Add the shared_file to the set of files already added to the QueryHit.

time_t shared_file_modification_time const shared_file_t sf  ) 
 

const gchar* shared_file_name_canonic const shared_file_t sf  ) 
 

size_t shared_file_name_canonic_len const shared_file_t sf  ) 
 

const gchar* shared_file_name_nfc const shared_file_t sf  ) 
 

size_t shared_file_name_nfc_len const shared_file_t sf  ) 
 

const gchar* shared_file_path const shared_file_t sf  ) 
 

Get the pathname of a shared file.

Parameters:
sf an initialized shared file.
Returns:
the full pathname of the shared file. The returned pointer is a string atom.

shared_file_t* shared_file_ref shared_file_t sf  ) 
 

Add one more reference to a shared_file_t.

Returns:
its argument, for convenience.

const gchar* shared_file_relative_path const shared_file_t sf  ) 
 

Returns the relative path of the shared files unless there was none or exposing relative paths is disabled.

Returns:
A string or NULL.

void shared_file_remove struct shared_file sf  ) 
 

void shared_file_set_modification_time struct shared_file sf,
time_t  mtime
 

gboolean shared_file_set_names shared_file_t sf,
const gchar *  filename
[static]
 

void shared_file_set_path struct shared_file sf,
const gchar *  pathname
 

void shared_file_set_sha1 struct shared_file sf,
const struct sha1 sha1
 

Set the SHA1 hash of a given shared_file.

Take care of updating the sha1_to_share structure. This function is called from inside the bowels of huge.c when it knows what the hash associated to a file is.

void shared_file_set_tth struct shared_file sf,
const struct tth tth
 

const struct sha1* shared_file_sha1 const shared_file_t sf  ) 
 

filesize_t shared_file_size const shared_file_t sf  ) 
 

gint shared_file_sort_by_mtime gconstpointer  f1,
gconstpointer  f2
[static]
 

Sort function - shared files by descending mtime.

const struct tth* shared_file_tth const shared_file_t sf  ) 
 

void shared_file_unref shared_file_t **  sf_ptr  ) 
 

Remove one reference to a shared_file_t, freeing entry if there are no reference left.

The pointer itself is nullified.

gboolean shared_file_valid_extension const gchar *  filename  )  [static]
 

Verify that a file extension is valid for sharing.

Parameters:
filename The name of the file to check.
Returns:
TRUE if the file should be shared, FALSE if not.

guint64 shared_files_scanned void   ) 
 

Get accessor for ``files_scanned''.

guint64 shared_kbytes_scanned void   ) 
 

Get accessor for ``kbytes_scanned''.

shared_file_t* shared_special const gchar *  path  ) 
 

Look up a possibly shared special file, updating the entry with current file size and modification time.

Parameters:
path the URL path on the server (case sensitive, of course)
Returns:
the shared file information if there is something shared at path, or NULL if the path is invalid.

void special_free_kv gpointer  unused_key,
gpointer  val,
gpointer  unused_udata
[static]
 

Hash table iterator callback to free the value.

gboolean too_big_for_gnutella off_t  size  )  [inline, static]
 

Is file too big to be shared on Gnutella?

Note: The original purpose was to avoid files larger than 2^32-1 bytes. Keep it just in case that a platform has an off_t with more than 64 bits.


Variable Documentation

guint64 bytes_scanned = 0 [static]
 

GHashTable* extensions = NULL [static]
 

GHashTable* file_basenames = NULL [static]
 

struct shared_file** file_table = NULL [static]
 

const guint FILENAME_CLASH = -1 [static]
 

Indicates basename clashes.

guint64 files_scanned = 0 [static]
 

GHashTable* muid_to_query_map [static]
 

hash_list_t* query_muids [static]
 

listeners_t search_request_listeners = NULL [static]
 

search_table_t* search_table [static]
 

GTree* sha1_to_share [static]
 

This tree maps a SHA1 hash (base-32 encoded) onto the corresponding shared_file if we have one.

GSList* shared_dirs = NULL [static]
 

GSList* shared_files = NULL [static]
 

GHashTable* special_names = NULL [static]
 

Maps special names (e.g.

"/favicon.ico") to the shared_file_t structure.

const struct special_file specials[] [static]
 

Initial value:

 {
    { "/favicon.ico",
            "favicon.png",  SHARE_M_IMAGE_PNG,  "Favorite web icon" },
    { "/robots.txt",
            "robots.txt",   SHARE_M_TEXT_PLAIN, "Robot exclusion" },
}


Generated on Sat Jun 30 17:53:30 2007 for gtk-gnutella by  doxygen 1.3.9.1