예제 #1
0
int main (int argc, char * argv[])
{
	int i, status, lsockfd, csockfd;  /* local/connection socket file descriptor */
	struct sockaddr_in raddr;      /* remote address object */
	socklen_t raddr_len = sizeof (struct sockaddr_in);
	pthread_t connThread;   /* thread identifier */
	User_Settings * o_stngs; /* user suplied settings struct (stores user settings)*/

	/* set global variables */
	server = "simpleText";
	version = 1.0f;

	/* allocate user suplied settings struct */
	o_stngs = malloc(sizeof(User_Settings));

	/* read configuration file */
	read_conf_file (o_stngs);

	/* parse and set cli options */
	parse_cli_opts (argc, (char **) &argv[0], o_stngs);

	/* make daemon and start logging */
	status = init_daemon (server, o_stngs);
	if (status == 0)
		return EXIT_SUCCESS; /* parent returns success */
	else if (status == 1)
		return EXIT_FAILURE; /* parent returns failure */

	syslog (LOG_NOTICE, "[PID: %u, SID: %u] > %s started..",
					getpid (), getsid (getpid ()), server);

	/* Read Hosts File */
	host_cnt = read_host_file (NULL, 1);
	for (i = 0; i < host_cnt; i++)
		read_host_file (&o_vhost[i], 0);

	/* start listening for TCP connections */
	lsockfd = start_listen (o_stngs->port);
	free(o_stngs);

	/* loop through accepting and handling connections */
	while (1)
	{
		/* accept connection or skip to next conection if accept fails */
		csockfd = accept (lsockfd, (struct sockaddr *) &raddr, &raddr_len);
		if (csockfd == -1) /* if connection fails ignore it and continue */
			continue;

		Connect_Args * o_args = malloc(sizeof(Connect_Args *));
		o_args->socket = csockfd;
		strcpy (o_args->client_addr, inet_ntoa (raddr.sin_addr));

		/* create thread to handle connection */
		pthread_create(&connThread, NULL, (void *) &attent_connection, o_args);

		/* wait for one second before accepting next connection */
		sleep (1);
	}
}
/**
 * Add a host to the list and notify clients about this event
 *
 * @param identity the identity of the host
 * @return the HostEntry
 */
static struct HostEntry *
add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
{
  struct HostEntry *entry;
  struct ReadHostFileContext r;
  char *fn;

  entry = GNUNET_CONTAINER_multipeermap_get (hostmap, identity);
  if (NULL == entry)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding new peer `%s'\n", GNUNET_i2s (identity));
    GNUNET_STATISTICS_update (stats, gettext_noop ("# peers known"), 1,
			      GNUNET_NO);
    entry = GNUNET_new (struct HostEntry);
    entry->identity = *identity;
    GNUNET_assert (GNUNET_OK ==
                   GNUNET_CONTAINER_multipeermap_put (hostmap, &entry->identity, entry,
                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
    notify_all (entry);
    fn = get_host_filename (identity);
    if (NULL != fn)
    {
      read_host_file (fn, GNUNET_YES, &r);
      if (NULL != r.hello)
      	update_hello (identity, r.hello);
      if (NULL != r.friend_only_hello)
      	update_hello (identity, r.friend_only_hello);
      GNUNET_free_non_null (r.hello);
      GNUNET_free_non_null (r.friend_only_hello);
      GNUNET_free (fn);
    }
  }
/**
 * Function that is called on each HELLO file in a particular directory.
 * Try to parse the file and add the HELLO to our list.
 *
 * @param cls pointer to 'unsigned int' to increment for each file, or NULL
 *            if the file is from a read-only, read-once resource directory
 * @param fullname name of the file to parse
 * @return GNUNET_OK (continue iteration)
 */
static int
hosts_directory_scan_callback (void *cls, const char *fullname)
{
  unsigned int *matched = cls;
  struct GNUNET_PeerIdentity identity;
  const char *filename;
  struct HostEntry *entry;
  struct GNUNET_HELLO_Message *hello;

  if (GNUNET_DISK_file_test (fullname) != GNUNET_YES)
    return GNUNET_OK;           /* ignore non-files */
  if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))
  {
    if (NULL != matched)
      remove_garbage (fullname);
    return GNUNET_OK;
  }
  filename =
      &fullname[strlen (fullname) -
                sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1];
  if (filename[-1] != DIR_SEPARATOR)
  {
    if (NULL != matched)
      remove_garbage (fullname);
    return GNUNET_OK;
  }
  if (GNUNET_OK !=
      GNUNET_CRYPTO_hash_from_string (filename, &identity.hashPubKey))
  {
    if (NULL != (hello = read_host_file (filename)))
    {
      entry = GNUNET_malloc (sizeof (struct HostEntry));
      if (GNUNET_OK ==
	  GNUNET_HELLO_get_id (hello,
			       &entry->identity))
      {
	GNUNET_CONTAINER_multihashmap_put (hostmap, &entry->identity.hashPubKey, entry,
					   GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
	entry->hello = hello;
	notify_all (entry);
	return GNUNET_OK;
      }
      GNUNET_free (entry);
    }
    if (NULL != matched)
      remove_garbage (fullname);
    return GNUNET_OK;
  }
  if (NULL != matched)
    (*matched)++;
  add_host_to_known_hosts (&identity);
  return GNUNET_OK;
}
/**
 * Add a host to the list.
 *
 * @param identity the identity of the host
 */
static void
add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
{
  struct HostEntry *entry;
  char *fn;

  entry = GNUNET_CONTAINER_multihashmap_get (hostmap, &identity->hashPubKey);
  if (entry != NULL)
    return;
  GNUNET_STATISTICS_update (stats, gettext_noop ("# peers known"), 1,
                            GNUNET_NO);
  entry = GNUNET_malloc (sizeof (struct HostEntry));
  entry->identity = *identity;
  GNUNET_CONTAINER_multihashmap_put (hostmap, &identity->hashPubKey, entry,
                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
  fn = get_host_filename (identity);
  entry->hello = read_host_file (fn);
  GNUNET_free (fn);
  notify_all (entry);
}