paulo@0: /* paulo@0: * $Id: gt_gnutella.c,v 1.74 2006/08/06 16:53:36 hexwab Exp $ paulo@0: * paulo@0: * Copyright (C) 2001-2004 giFT project (gift.sourceforge.net) paulo@0: * paulo@0: * This program is free software; you can redistribute it and/or modify it paulo@0: * under the terms of the GNU General Public License as published by the paulo@0: * Free Software Foundation; either version 2, or (at your option) any paulo@0: * later version. paulo@0: * paulo@0: * This program is distributed in the hope that it will be useful, but paulo@0: * WITHOUT ANY WARRANTY; without even the implied warranty of paulo@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU paulo@0: * General Public License for more details. paulo@0: */ paulo@0: paulo@0: #include "gt_gnutella.h" paulo@0: paulo@0: #include "gt_conf.h" paulo@0: #include "sha1.h" paulo@0: #include "xml.h" paulo@0: paulo@0: #include "gt_share.h" paulo@0: #include "gt_share_state.h" paulo@0: paulo@0: #include "gt_accept.h" paulo@0: #include "gt_ban.h" paulo@0: #include "gt_bind.h" paulo@0: paulo@0: #include "gt_node.h" paulo@0: #include "gt_node_list.h" paulo@0: #include "gt_netorg.h" paulo@0: paulo@0: #include "gt_xfer_obj.h" paulo@0: #include "gt_xfer.h" paulo@0: paulo@0: #include "gt_search.h" paulo@0: #include "gt_search_exec.h" paulo@0: paulo@0: #include "gt_web_cache.h" paulo@0: #include "gt_stats.h" paulo@0: #include "gt_query_route.h" paulo@0: #include "transfer/source.h" /* gnutella_source_{add,remove,cmp} */ paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: /* giFT protocol pointer */ paulo@0: Protocol *GT; paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: /* The ip address is local if the address is local and the source from which paulo@0: * it was discovered was not local */ paulo@0: BOOL gt_is_local_ip (in_addr_t ip, in_addr_t src) paulo@0: { paulo@0: if (ip == 0) paulo@0: return TRUE; paulo@0: paulo@0: if (net_match_host (ip, "LOCAL") && paulo@0: (src == 0 || !net_match_host (src, "LOCAL"))) paulo@0: { paulo@0: return TRUE; paulo@0: } paulo@0: paulo@0: return FALSE; paulo@0: } paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: /* shutdown */ paulo@0: static void gnutella_destroy (Protocol *p) paulo@0: { paulo@0: GT->DBGFN (GT, "entered"); paulo@0: paulo@0: /* cleanup any network maintenance data */ paulo@0: gt_netorg_cleanup (); paulo@0: paulo@0: /* save the node list to disk */ paulo@0: gt_node_list_save (); paulo@0: paulo@0: /* cleanup any information about banned nodes */ paulo@0: gt_ban_cleanup (); paulo@0: paulo@0: /* destroy query_router tables */ paulo@0: gt_query_router_self_destroy (); paulo@0: paulo@0: /* cleanup remote search data structures */ paulo@0: gt_search_cleanup (); paulo@0: paulo@0: /* cleanup local share state */ paulo@0: gt_share_state_local_cleanup (); paulo@0: paulo@0: /* cleanup local search data structures */ paulo@0: gt_search_exec_cleanup (); paulo@0: paulo@0: /* cleanup XML structures */ paulo@0: gt_xml_cleanup (); paulo@0: paulo@0: /* free and disconnect all nodes */ paulo@0: gt_node_remove_all (); paulo@0: paulo@0: /* destroy web cache information */ paulo@0: gt_web_cache_cleanup (); paulo@0: paulo@0: /* stop binding to the local port */ paulo@0: gt_bind_cleanup (); paulo@0: paulo@0: /* free configuration information */ paulo@0: gt_config_cleanup (); paulo@0: paulo@0: /* free this client's GUID */ paulo@0: gt_guid_self_cleanup (); paulo@0: } paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: static unsigned char *gnutella_sha1_hash (const char *path, size_t *len) paulo@0: { paulo@0: *len = SHA1_BINSIZE; paulo@0: return sha1_digest (path, 0); paulo@0: } paulo@0: paulo@0: static char *gnutella_sha1_dsp (unsigned char *hash, size_t len) paulo@0: { paulo@0: return sha1_string (hash); paulo@0: } paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: static BOOL self_is_too_old (void) paulo@0: { paulo@0: return FALSE; paulo@0: } paulo@0: paulo@0: static void too_old_error_msg (void) paulo@0: { paulo@0: GIFT_ERROR (("\nYour version of the Gnutella plugin is more than 1 year\n" paulo@0: "old. In order to protect the Gnutella network from \n" paulo@0: "older programs, this plugin has deactivated itself.\n\n" paulo@0: "Please update the plugin with a new version from \n" paulo@0: "http://www.giftproject.org/, or stop running the \n" paulo@0: "plugin by runnning gift-setup or removing \"Gnutella\"\n" paulo@0: "from the /main/plugins line in $HOME/.giFT/giftd.conf\n" paulo@0: "manually.\n\n" paulo@0: "Thanks, and sorry for the inconvenience.\n")); paulo@0: } paulo@0: paulo@0: static BOOL gnutella_start (Protocol *p) paulo@0: { paulo@0: p->DBGFN (p, "Starting Gnutella plugin"); paulo@0: paulo@0: /* paulo@0: * If this node is extremely old, deactivate the plugin, but print a paulo@0: * message to the log file. paulo@0: * paulo@0: * This is a temporary hack to clean out old nodes in the future, just paulo@0: * until ultrapeer support is implemented, but we don't want to bother paulo@0: * people that are using other plugins and don't care... paulo@0: */ paulo@0: if (self_is_too_old ()) paulo@0: { paulo@0: too_old_error_msg (); paulo@0: return TRUE; paulo@0: } paulo@0: paulo@0: if (!gt_config_init ()) paulo@0: { paulo@0: GIFT_ERROR (("Unable to load config file. Please copy it to " paulo@0: "~/.giFT/Gnutella/Gnutella.conf")); paulo@0: return FALSE; paulo@0: } paulo@0: paulo@0: if (!gt_web_cache_init ()) paulo@0: { paulo@0: GIFT_ERROR (("Unable to load gwebcaches file. Please copy it to " paulo@0: "~/.giFT/Gnutella/gwebcaches")); paulo@0: return FALSE; paulo@0: } paulo@0: paulo@0: /* load any banned ip addresses */ paulo@0: gt_ban_init (); paulo@0: paulo@0: /* initialize the GUID for this node */ paulo@0: gt_guid_self_init (); paulo@0: paulo@0: /* listen for connections */ paulo@0: gt_bind_init (); paulo@0: paulo@0: /* load the list of all previously contacted nodes */ paulo@0: gt_node_list_load (); paulo@0: paulo@0: /* initialize query router tables */ paulo@0: gt_query_router_self_init (); paulo@0: paulo@0: /* initialize the local search data structures */ paulo@0: gt_search_exec_init (); paulo@0: paulo@0: /* initialize the local sharing state */ paulo@0: gt_share_state_local_init (); paulo@0: paulo@0: /* initialize the remote search data structures */ paulo@0: gt_search_init (); paulo@0: paulo@0: /* initialize support for xml metadata */ paulo@0: gt_xml_init (); paulo@0: paulo@0: /* startup network maintenance */ paulo@0: gt_netorg_init (); paulo@0: paulo@0: return TRUE; paulo@0: } paulo@0: paulo@0: /* paulo@0: * The entry-point for the giFT daemon paulo@0: */ paulo@0: BOOL Gnutella_init (Protocol *p) paulo@0: { paulo@0: if (protocol_compat (p, LIBGIFTPROTO_MKVERSION (0, 11, 4)) != 0) paulo@0: return FALSE; paulo@0: paulo@0: p->version_str = STRDUP (GT_VERSION); paulo@0: GT = p; paulo@0: paulo@0: /* gt_gnutella.c: */ paulo@0: p->start = gnutella_start; paulo@0: paulo@0: /* skip initializing if too old. Note that we still need to provide a paulo@0: * start function since gift's default handler will return FALSE. The paulo@0: * actual error message describing the 'too old' problem is also generated paulo@0: * by our start function. paulo@0: */ paulo@0: if (self_is_too_old ()) paulo@0: return TRUE; paulo@0: paulo@0: /* describe the hash algo */ paulo@0: p->hash_handler (p, "SHA1", HASH_PRIMARY, gnutella_sha1_hash, paulo@0: gnutella_sha1_dsp); paulo@0: paulo@0: /* gt_gnutella.c: */ paulo@0: p->destroy = gnutella_destroy; paulo@0: paulo@0: /* gt_search.c: */ paulo@0: p->search = gnutella_search; paulo@0: #if 0 paulo@0: p->browse = gnutella_browse; paulo@0: #endif paulo@0: p->locate = gnutella_locate; paulo@0: p->search_cancel = gnutella_search_cancel; paulo@0: paulo@0: /* gt_xfer.c: */ paulo@0: p->download_start = gnutella_download_start; paulo@0: p->download_stop = gnutella_download_stop; paulo@0: p->upload_stop = gnutella_upload_stop; paulo@0: p->chunk_suspend = gnutella_chunk_suspend; paulo@0: p->chunk_resume = gnutella_chunk_resume; paulo@0: paulo@0: /* transfer/source.c: */ paulo@0: p->source_cmp = gnutella_source_cmp; paulo@0: p->source_add = gnutella_source_add; paulo@0: p->source_remove = gnutella_source_remove; paulo@0: paulo@0: #if 0 paulo@0: p->upload_avail = gnutella_upload_avail; paulo@0: p->user_cmp = gnutella_user_cmp; paulo@0: #endif paulo@0: paulo@0: /* gt_share.c: */ paulo@0: p->share_new = gnutella_share_new; paulo@0: p->share_free = gnutella_share_free; paulo@0: p->share_add = gnutella_share_add; paulo@0: p->share_remove = gnutella_share_remove; paulo@0: p->share_sync = gnutella_share_sync; paulo@0: paulo@0: /* gt_share_state.c: */ paulo@0: p->share_hide = gnutella_share_hide; paulo@0: p->share_show = gnutella_share_show; paulo@0: paulo@0: /* gt_stats.c: */ paulo@0: p->stats = gnutella_stats; paulo@0: paulo@0: return TRUE; paulo@0: }