⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gnutella.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 3 页
字号:
      return -1;    }  p = cfg->save_path + strlen (cfg->save_path) - 1;  if (*p == '/' || *p == '\\')    *p = '\0';  p = cfg->share_path + strlen (cfg->share_path) - 1;  if (*p == '/' || *p == '\\')    *p = '\0';  /* check for existence and create them if necessary */  if (cfg->save_path[0])    {      if (stat (cfg->save_path, &buf) == -1)	{	  /* create the download directory */	  if (mkdir (cfg->save_path, 0755) == -1)	    {	      svz_log (LOG_ERROR, "nut: mkdir: %s\n", SYS_ERROR);	      return -1;	    }	}      /* check if the given path is a directory already */      else if (!S_ISDIR (buf.st_mode))	{	  svz_log (LOG_ERROR, "nut: %s is not a directory\n", 		   cfg->save_path);	  return -1;	}    }  /* read shared files */  nut_read_database (cfg, cfg->share_path[0] ? cfg->share_path : "/");  svz_log (LOG_NOTICE, "nut: %d files in database\n", cfg->db_files);  /* calculate forced local ip and port if necessary */  if (cfg->force_ip)    {      cfg->ip = inet_addr (cfg->force_ip);    }  cfg->port = htons ((unsigned short) cfg->force_port);  /* create and modify packet hash */  cfg->packet = svz_hash_create (4);  cfg->packet->code = nut_hash_code;  cfg->packet->equals = nut_hash_equals;  cfg->packet->keylen = nut_hash_keylen;  /* create and modify reply hash */  cfg->reply = svz_hash_create (4);  cfg->reply->code = nut_hash_code;  cfg->reply->equals = nut_hash_equals;  cfg->reply->keylen = nut_hash_keylen;  /* create current connection hash */  cfg->conn = svz_hash_create (4);  /* create host catcher hash */  cfg->net = svz_hash_create (4);  /* create recent query hash */  cfg->query = svz_hash_create (4);  /* create push request hash */  cfg->push = svz_hash_create (4);  /* create and modify the routing table hash */  cfg->route = svz_hash_create (4);  cfg->route->code = nut_hash_code;  cfg->route->equals = nut_hash_equals;  cfg->route->keylen = nut_hash_keylen;  /* calculate this server instance's GUID */  nut_calc_guid (cfg->guid);  /* create detection string for gnutella host list */  cfg->net_detect = svz_malloc (strlen (NUT_HOSTS) + 				strlen (cfg->net_url) + 1);  sprintf (cfg->net_detect, NUT_HOSTS, cfg->net_url);  /* go through all given hosts and try to connect to them */  svz_array_foreach (cfg->hosts, p, n)    nut_connect_host (cfg, p);  /* bind listening server to configurable port address      FIXME: how can we disable bindings ?  if (!cfg->disable)    server_bind (server, cfg->netport);*/  return 0;}/* * Instance finalizer. */intnut_finalize (svz_server_t *server){  nut_config_t *cfg = server->cfg;  nut_host_t **client;  nut_packet_t **pkt;  nut_transfer_t **transfer;  int n;  /* destroy sharing files */  nut_destroy_database (cfg);  svz_hash_destroy (cfg->conn);  svz_hash_destroy (cfg->route);  svz_hash_destroy (cfg->query);  svz_hash_destroy (cfg->reply);  /* destroy sent packet hash */  if ((pkt = (nut_packet_t **) svz_hash_values (cfg->packet)) != NULL)    {      for (n = 0; n < svz_hash_size (cfg->packet); n++)	{	  svz_free (pkt[n]);	}      svz_hash_xfree (pkt);    }  svz_hash_destroy (cfg->packet);  /* destroy host catcher hash */  if ((client = (nut_host_t **) svz_hash_values (cfg->net)) != NULL)    {      for (n = 0; n < svz_hash_size (cfg->net); n++)	{	  svz_free (client[n]);	}      svz_hash_xfree (client);    }  svz_hash_destroy (cfg->net);  /* destroy push request hash */  if ((transfer = (nut_transfer_t **) svz_hash_values (cfg->push)) != NULL)    {      for (n = 0; n < svz_hash_size (cfg->push); n++)	{	  svz_free (transfer[n]->file);	  svz_free (transfer[n]);	}      svz_hash_xfree (transfer);    }  svz_hash_destroy (cfg->push);  /* free detection string */  svz_free (cfg->net_detect);  return 0;}/* * Global gnutella finalizer. */intnut_global_finalize (svz_servertype_t *server){#ifdef __MINGW32__  if (oleHandle)     FreeLibrary (oleHandle);#endif /* __MINGW32__ */  /* destroy confguration defaults */  svz_config_strarray_destroy (nut_config.search);  return 0;}/* * This is the sock->disconnected_socket callback for gnutella  * connections. */intnut_disconnect (svz_socket_t *sock){  nut_config_t *cfg = sock->cfg;  nut_host_t *host;  svz_uint8_t *id;  char *key, **keys;  int size, n;  nut_packet_t *pkt;  nut_client_t *client = sock->data;  /* delete all push request routing information for this connection */  while ((id = (svz_uint8_t *) svz_hash_contains (cfg->reply, sock)) != NULL)    svz_hash_delete (cfg->reply, (char *) id);  /* delete all routing information for this connection */  while ((id = (svz_uint8_t *) svz_hash_contains (cfg->route, sock)) != NULL)    svz_hash_delete (cfg->route, (char *) id);  /* drop all packet information for this connection */  if ((keys = (char **) svz_hash_keys (cfg->packet)) != NULL)    {      size = svz_hash_size (cfg->packet);      for (n = 0; n < size; n++)	{	  pkt = (nut_packet_t *) svz_hash_get (cfg->packet, keys[n]);	  if (pkt->sock == sock)	    {	      svz_hash_delete (cfg->packet, keys[n]);	      svz_free (pkt);	    }	}      svz_hash_xfree (keys);    }    /* remove this socket from the current connection hash */  key = nut_client_key (sock->remote_addr, sock->remote_port);  svz_hash_delete (cfg->conn, key);  /* remove the connection from the host catcher */  if ((host = svz_hash_delete (cfg->net, key)) != NULL)    svz_free (host);  /* free client structure */  if (client)    {      cfg->nodes -= client->nodes;      cfg->files -= client->files;      cfg->size -= client->size;      svz_free (client);      sock->data = NULL;    }  return 0;}/* * This callback is regularly called in the `server_periodic_tasks' * routine. Here we try connecting to more gnutella hosts. */intnut_server_notify (svz_server_t *server){  nut_config_t *cfg = server->cfg;  static int count = NUT_CONNECT_INTERVAL;  char **keys;  nut_packet_t *pkt;  int n, size, connect;  time_t t, received;  /* go sleep if we still do not want to do something */  if (count-- > 0)    return 0;      /* do we have enough connections ? */  connect = cfg->connections - svz_hash_size (cfg->conn);  if (connect > 0)    {      /* are there hosts in the host catcher hash ? */      if ((keys = (char **) svz_hash_keys (cfg->net)) != NULL)	{	  /* go through all caught hosts */	  for (n = 0; n < svz_hash_size (cfg->net) && connect; n++)	    {	      /* check if we are not already connected */	      if (svz_hash_get (cfg->conn, keys[n]) == NULL)		{		  if (nut_connect_host (cfg, keys[n]) != -1)		    connect--;		}	    }	  svz_hash_xfree (keys);	}    }  /* go through the sent packet hash and drop old entries */  if ((keys = (char **) svz_hash_keys (cfg->packet)) != NULL)    {      t = time (NULL);      size = svz_hash_size (cfg->packet);      for (n = 0; n < size; n++)	{	  pkt = (nut_packet_t *) svz_hash_get (cfg->packet, keys[n]);	  if (t - pkt->sent > NUT_ENTRY_AGE)	    {	      svz_hash_delete (cfg->packet, keys[n]);	      svz_free (pkt);	    }	}      svz_hash_xfree (keys);    }  /* drop older entries from the recent query hash */  if ((keys = (char **) svz_hash_keys (cfg->query)) != NULL)    {      t = time (NULL);      size = svz_hash_size (cfg->query);      for (n = 0; n < size; n++)	{	  received = (time_t) (long) svz_hash_get (cfg->query, keys[n]);	  if (t - received > NUT_ENTRY_AGE)	    {	      svz_hash_delete (cfg->query, keys[n]);	    }	}      svz_hash_xfree (keys);    }  /* wake up in a certain time */  count = NUT_CONNECT_INTERVAL;  return 0;}/* * Whenever there is data arriving for this socket we call this  * routine. */intnut_check_request (svz_socket_t *sock){  nut_client_t *client = sock->data;  nut_header_t *hdr;  svz_uint8_t *packet;  int len = strlen (NUT_OK);  unsigned fill = sock->recv_buffer_fill;  /* go through all packets in the receive queue */  while ((fill = sock->recv_buffer_fill) >= SIZEOF_NUT_HEADER)    {      hdr = nut_get_header ((svz_uint8_t *) sock->recv_buffer);      /* is there enough data to fulfill a complete packet ? */      if (fill >= SIZEOF_NUT_HEADER + hdr->length)	{	  len = SIZEOF_NUT_HEADER + hdr->length;	  packet = (svz_uint8_t *) sock->recv_buffer + SIZEOF_NUT_HEADER;	  client->packets++;#if 0	  svz_hexdump (stdout, "gnutella packet", sock->sock_desc,		       sock->recv_buffer, len, 0);#endif	  	  /* try to route the packet */	  if (nut_route (sock, hdr, packet) == 0)	    {	      /* handle the packet */	      switch (hdr->function)		{		case NUT_PING_REQ:		  nut_ping (sock, hdr, NULL);		  break;		case NUT_PING_ACK:		  nut_pong (sock, hdr, packet);		  break;		case NUT_PUSH_REQ:		  nut_push_request (sock, hdr, packet);		  break;		case NUT_SEARCH_REQ:		  nut_query (sock, hdr, packet);		  break;		case NUT_SEARCH_ACK:		  nut_reply (sock, hdr, packet);		  break;		}	    }	  else if (!(sock->flags & SOCK_FLAG_KILLED))	    {	      client->dropped++;	    }	  /* return if this client connection has been killed */	  if (sock->flags & SOCK_FLAG_KILLED)	    return -1;	  /* cut this packet from the send buffer queue */	  svz_sock_reduce_recv (sock, len);	}      else	break;    }  return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -