Main Page | Modules | Alphabetical List | Data Structures | 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 "gnet_stats.h"
#include "search.h"
#include "guid.h"
#include "hostiles.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/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  special_file
 Describes special files which are served by GTKG. More...

struct  query_context
 A query context. More...


Defines

#define FILENAME_CLASH   0xffffffff /**< Indicates basename clashes */
 Indicates basename clashes.

#define MIN_WORD_LENGTH   1 /**< For compaction */
 For compaction.

#define APPEND_WORD()

Functions

 RCSID ("$Id:share.c, v 1.64 2005/12/02 22:54:02 cbiere Exp $")
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, shared_file_t *sf)
 Invoked for each new match we get.

void setup_char_map (char_map_t map)
 Set up keymapping table for Gnutella.

void use_map_on_query (gchar *query, int len)
 Apply the proper charset mapping on the query, depending on their locale, so that the query has no accent.

shared_file_tshare_special_load (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 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.

shared_file_tshared_file_by_name (const gchar *basename)
 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 (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.

void shared_file_free (shared_file_t *sf)
 Dispose of a shared_file_t structure.

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)
 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.

void recurse_scan (const gchar *dir, const gchar *basedir)
 The directories that are given as shared will be completly transversed including all files and directories.

void share_free (void)
 Free up memory used by the shared library.

void reinit_sha1_table (void)
 Reset sha1_to_share.

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 (gnutella_node_t *n, gchar *data)
 Remove the OOB delivery flag by patching the query message inplace.

void query_set_oob_flag (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.

gint compare_share_sha1 (const gchar *s1, const gchar *s2)
 Compare binary SHA1 hashes.

void set_sha1 (struct shared_file *f, const char *sha1)
 Set the SHA1 hash of a given shared_file.

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.

shared_fileshared_file_complete_by_sha1 (gchar *sha1_digest)
shared_file_tshared_file_by_sha1 (gchar *sha1_digest)
 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 guchar iso_8859_1 [96]
const guchar cp1252 [30]
const guchar macroman [126]
special_file specials []
GHashTable * special_names = NULL
 Maps special names (e.g.

guint64 files_scanned = 0
guint64 kbytes_scanned = 0
guint64 bytes_scanned = 0
GSList * extensions = NULL
 Global Data.

GSList * shared_dirs = NULL
 Global Data.

GSList * shared_files = NULL
shared_file ** file_table = NULL
search_table_t search_table
GHashTable * file_basenames = NULL
gchar stmp_1 [4096]
listeners_t search_request_listeners = NULL
char_map_t query_map
GTree * sha1_to_share = NULL
 This tree maps a SHA1 hash (base-32 encoded) onto the corresponding shared_file if we have one.


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 FILENAME_CLASH   0xffffffff /**< Indicates basename clashes */
 

Indicates basename clashes.

#define MIN_WORD_LENGTH   1 /**< For compaction */
 

For compaction.


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 const gchar *  s1,
const gchar *  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.

void free_extensions void   )  [static]
 

Free existing extensions.

void got_match gpointer  context,
shared_file_t sf
[static]
 

Invoked for each new match we get.

void parse_extensions const gchar *  str  ) 
 

Get the file extensions to scan.

void query_set_oob_flag gnutella_node_t n,
gchar *  data
 

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

void query_strip_oob_flag 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.

RCSID "$Id:share.  c,
v 1.64 2005/12/02 22:54:02 cbiere Exp $" 
 

void recurse_scan const gchar *  dir,
const gchar *  basedir
[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.

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?

void set_sha1 struct shared_file f,
const char *  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 setup_char_map char_map_t  map  )  [static]
 

Set up keymapping table for Gnutella.

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.

< direct hashing

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.

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 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.

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 *  basename  ) 
 

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 gchar *  sha1_digest  ) 
 

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.

struct shared_file* shared_file_complete_by_sha1 gchar *  sha1_digest  )  [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.

void shared_file_free shared_file_t sf  )  [static]
 

Dispose of a shared_file_t structure.

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.

shared_file_t* shared_file_ref shared_file_t sf  ) 
 

Add one more reference to a shared_file_t.

Returns:
its argument, for convenience.

void shared_file_unref shared_file_t sf  ) 
 

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

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?

void use_map_on_query gchar *  query,
int  len
 

Apply the proper charset mapping on the query, depending on their locale, so that the query has no accent.


Variable Documentation

guint64 bytes_scanned = 0 [static]
 

const guchar cp1252[30] [static]
 

GSList* extensions = NULL
 

Global Data.

GHashTable* file_basenames = NULL [static]
 

struct shared_file** file_table = NULL [static]
 

guint64 files_scanned = 0 [static]
 

const guchar iso_8859_1[96] [static]
 

guint64 kbytes_scanned = 0 [static]
 

const guchar macroman[126] [static]
 

char_map_t query_map [static]
 

listeners_t search_request_listeners = NULL [static]
 

search_table_t search_table [static]
 

GTree* sha1_to_share = NULL [static]
 

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

GSList* shared_dirs = NULL
 

Global Data.

GSList* shared_files = NULL [static]
 

GHashTable* special_names = NULL [static]
 

Maps special names (e.g.

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

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" },
}

gchar stmp_1[4096] [static]
 


Generated on Sun Feb 12 10:50:08 2006 for Gtk-Gnutella by doxygen 1.3.6