Beispiel #1
0
static char *logs_prepare_path(session_t *session, const char *logs_path, const char *uid, time_t sent) {
	char *uidtmp, datetime[5];
	struct tm *tm = NULL;
	string_t buf;

	if (!logs_path)
		return NULL;

	buf = string_init(NULL);

	while (*logs_path) {
		if ((char)*logs_path == '%' && (logs_path+1) != NULL) {
			switch (*(logs_path+1)) {
				case 'S':	string_append_n(buf, session ? session->uid : "_null_", -1);
						break;
				case 'P':	string_append_n(buf, config_profile ? config_profile : "_default_", -1);
						break;
				case 'u':	uidtmp = xstrdup(get_uid(session, uid));
						goto attach; /* avoid code duplication */
				case 'U':	uidtmp = xstrdup(get_nickname(session, uid));
attach:
						if (!uidtmp) uidtmp = xstrdup(uid);

						if (xstrchr(uidtmp, '/'))
							*(xstrchr(uidtmp, '/')) = 0; // strip resource
						string_append_n(buf, uidtmp ? uidtmp : uid, -1);
						xfree(uidtmp);
						break;
				case 'Y':	if (!tm) tm = localtime(&sent);
							snprintf(datetime, 5, "%4d", tm->tm_year+1900);
						string_append_n(buf, datetime, 4);
						break;
				case 'M':	if (!tm) tm = localtime(&sent);
							snprintf(datetime, 3, "%02d", tm->tm_mon+1);
						string_append_n(buf, datetime, 2);
						break;
				case 'D':	if (!tm) tm = localtime(&sent);
							snprintf(datetime, 3, "%02d", tm->tm_mday);
						string_append_n(buf, datetime, 2);
						break;
				default:	string_append_c(buf, *(logs_path+1));
			};

			logs_path++;
		} else if (*logs_path == '~' && (*(logs_path+1) == '/' || *(logs_path+1) == '\0')) {
			string_append_n(buf, home_dir, -1);
			//string_append_c(buf, '/');
		} else
			string_append_c(buf, *logs_path);
		logs_path++;
	};

	// sanityzacja sciezki - wywalic "../", zamienic znaki spec. na inne
	// zamieniamy szkodliwe znaki na minusy, spacje na podkreslenia
	// TODO
	xstrtr(buf->str, ' ', '_');

	return string_free(buf, 0);
}
Beispiel #2
0
static bool get_info(netplay_t *netplay)
{
   unsigned sram_size;
   uint32_t header[3];
   const void *sram = NULL;
   global_t *global = global_get_ptr();

   if (!socket_receive_all_blocking(netplay->fd, header, sizeof(header)))
   {
      RARCH_ERR("Failed to receive header from client.\n");
      return false;
   }

   if (global->content_crc != ntohl(header[0]))
   {
      RARCH_ERR("Content CRC32s differ. Cannot use different games.\n");
      return false;
   }

   if (implementation_magic_value() != ntohl(header[1]))
   {
      RARCH_ERR("Implementations differ, make sure you're using exact same libretro implementations and RetroArch version.\n");
      return false;
   }

   if (core.retro_get_memory_size(RETRO_MEMORY_SAVE_RAM) != ntohl(header[2]))
   {
      RARCH_ERR("Content SRAM sizes do not correspond.\n");
      return false;
   }

   if (!get_nickname(netplay, netplay->fd))
   {
      RARCH_ERR("Failed to get nickname from client.\n");
      return false;
   }

   /* Send SRAM data to our User 2. */
   sram      = core.retro_get_memory_data(RETRO_MEMORY_SAVE_RAM);
   sram_size = core.retro_get_memory_size(RETRO_MEMORY_SAVE_RAM);

   if (!socket_send_all_blocking(netplay->fd, sram, sram_size))
   {
      RARCH_ERR("Failed to send SRAM data to client.\n");
      return false;
   }

   if (!send_nickname(netplay, netplay->fd))
   {
      RARCH_ERR("Failed to send nickname to client.\n");
      return false;
   }

#ifndef HAVE_SOCKET_LEGACY
   log_connection(&netplay->other_addr, 0, netplay->other_nick);
#endif

   return true;
}
Beispiel #3
0
static bool get_info_spectate(netplay_t *netplay)
{
   size_t save_state_size, size;
   void *buf          = NULL;
   uint32_t header[4] = {0};
   char msg[512]      = {0};
   bool ret           = true;

   if (!send_nickname(netplay, netplay->fd))
   {
      RARCH_ERR("Failed to send nickname to host.\n");
      return false;
   }

   if (!get_nickname(netplay, netplay->fd))
   {
      RARCH_ERR("Failed to receive nickname from host.\n");
      return false;
   }

   snprintf(msg, sizeof(msg), "Connected to \"%s\"", netplay->other_nick);
   rarch_main_msg_queue_push(msg, 1, 180, false);
   RARCH_LOG("%s\n", msg);


   if (!socket_receive_all_blocking(netplay->fd, header, sizeof(header)))
   {
      RARCH_ERR("Cannot get header from host.\n");
      return false;
   }

   save_state_size = core.retro_serialize_size();
   if (!bsv_parse_header(header, implementation_magic_value()))
   {
      RARCH_ERR("Received invalid BSV header from host.\n");
      return false;
   }

   buf = malloc(save_state_size);
   if (!buf)
      return false;

   size = save_state_size;

   if (!socket_receive_all_blocking(netplay->fd, buf, size))
   {
      RARCH_ERR("Failed to receive save state from host.\n");
      free(buf);
      return false;
   }

   if (save_state_size)
      ret = core.retro_unserialize(buf, save_state_size);

   free(buf);
   return ret;
}
Beispiel #4
0
static bool get_info(netplay_t *handle)
{
   uint32_t header[3];

   if (!recv_all(handle->fd, header, sizeof(header)))
   {
      RARCH_ERR("Failed to receive header from client.\n");
      return false;
   }

   if (g_extern.cart_crc != ntohl(header[0]))
   {
      RARCH_ERR("Cart CRC32s differ. Cannot use different games.\n");
      return false;
   }

   if (implementation_magic_value() != ntohl(header[1]))
   {
      RARCH_ERR("Implementations differ, make sure you're using exact same libretro implementations and RetroArch version.\n");
      return false;
   }

   if (pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM) != ntohl(header[2]))
   {
      RARCH_ERR("Cartridge SRAM sizes do not correspond.\n");
      return false;
   }

   if (!get_nickname(handle, handle->fd))
   {
      RARCH_ERR("Failed to get nickname from client.\n");
      return false;
   }

   // Send SRAM data to our Player 2.
   const void *sram = pretro_get_memory_data(RETRO_MEMORY_SAVE_RAM);
   unsigned sram_size = pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM);
   if (!send_all(handle->fd, sram, sram_size))
   {
      RARCH_ERR("Failed to send SRAM data to client.\n");
      return false;
   }

   if (!send_nickname(handle, handle->fd))
   {
      RARCH_ERR("Failed to send nickname to client.\n");
      return false;
   }

#ifndef HAVE_SOCKET_LEGACY
   log_connection(&handle->other_addr, 0, handle->other_nick);
#endif

   return true;
}
Beispiel #5
0
static bool get_info_spectate(netplay_t *handle)
{
   if (!send_nickname(handle, handle->fd))
   {
      RARCH_ERR("Failed to send nickname to host.\n");
      return false;
   }

   if (!get_nickname(handle, handle->fd))
   {
      RARCH_ERR("Failed to receive nickname from host.\n");
      return false;
   }

   char msg[512];
   snprintf(msg, sizeof(msg), "Connected to \"%s\"", handle->other_nick);
   msg_queue_push(g_extern.msg_queue, msg, 1, 180);
   RARCH_LOG("%s\n", msg);

   uint32_t header[4];

   if (!recv_all(handle->fd, header, sizeof(header)))
   {
      RARCH_ERR("Cannot get header from host.\n");
      return false;
   }

   size_t save_state_size = pretro_serialize_size();
   if (!bsv_parse_header(header, implementation_magic_value()))
   {
      RARCH_ERR("Received invalid BSV header from host.\n");
      return false;
   }

   void *buf = malloc(save_state_size);
   if (!buf)
      return false;

   size_t size = save_state_size;

   if (!recv_all(handle->fd, buf, size))
   {
      RARCH_ERR("Failed to receive save state from host.\n");
      free(buf);
      return false;
   }

   bool ret = true;
   if (save_state_size)
      ret = pretro_unserialize(buf, save_state_size);

   free(buf);
   return ret;
}
Beispiel #6
0
int		send_443(int fd, char *arg, t_user *users)
{
  char		*user_nick;
  char		*tmp1;
  char		*tmp2;

  if ((user_nick = get_nickname(fd, users)) == NULL)
    return (send_response(fd, "444", ":User not logged in"));
  if ((tmp1 = str_concat(user_nick, " ", arg)) == NULL
      || (tmp2 = str_concat(tmp1, " ", ":is already on channel")) == NULL)
    return (-1);
  free(tmp1);
  send_response(fd, "443", tmp2);
  free(tmp2);
  return (0);
}
Beispiel #7
0
static bool send_info(netplay_t *netplay)
{
   unsigned sram_size;
   char msg[512]      = {0};
   void *sram         = NULL;
   uint32_t header[3] = {0};
   global_t *global   = global_get_ptr();
   
   header[0] = htonl(global->content_crc);
   header[1] = htonl(implementation_magic_value());
   header[2] = htonl(core.retro_get_memory_size(RETRO_MEMORY_SAVE_RAM));

   if (!socket_send_all_blocking(netplay->fd, header, sizeof(header)))
      return false;

   if (!send_nickname(netplay, netplay->fd))
   {
      RARCH_ERR("Failed to send nick to host.\n");
      return false;
   }

   /* Get SRAM data from User 1. */
   sram      = core.retro_get_memory_data(RETRO_MEMORY_SAVE_RAM);
   sram_size = core.retro_get_memory_size(RETRO_MEMORY_SAVE_RAM);

   if (!socket_receive_all_blocking(netplay->fd, sram, sram_size))
   {
      RARCH_ERR("Failed to receive SRAM data from host.\n");
      return false;
   }

   if (!get_nickname(netplay, netplay->fd))
   {
      RARCH_ERR("Failed to receive nick from host.\n");
      return false;
   }

   snprintf(msg, sizeof(msg), "Connected to: \"%s\"", netplay->other_nick);
   RARCH_LOG("%s\n", msg);
   rarch_main_msg_queue_push(msg, 1, 180, false);

   return true;
}
Beispiel #8
0
static bool send_info(netplay_t *handle)
{
   uint32_t header[3] = {
      htonl(g_extern.cart_crc),
      htonl(implementation_magic_value()),
      htonl(pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM))
   };

   if (!send_all(handle->fd, header, sizeof(header)))
      return false;

   if (!send_nickname(handle, handle->fd))
   {
      RARCH_ERR("Failed to send nick to host.\n");
      return false;
   }

   // Get SRAM data from Player 1.
   void *sram = pretro_get_memory_data(RETRO_MEMORY_SAVE_RAM);
   unsigned sram_size = pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM);

   if (!recv_all(handle->fd, sram, sram_size))
   {
      RARCH_ERR("Failed to receive SRAM data from host.\n");
      return false;
   }

   if (!get_nickname(handle, handle->fd))
   {
      RARCH_ERR("Failed to receive nick from host.\n");
      return false;
   }

   char msg[512];
   snprintf(msg, sizeof(msg), "Connected to: \"%s\"", handle->other_nick);
   RARCH_LOG("%s\n", msg);
   msg_queue_push(g_extern.msg_queue, msg, 1, 180);

   return true;
}
int		begin_connection(int fd, t_user *root)
{
  char		*nickname;
  char		*tmp1;
  char		*tmp2;
  char		hostname[1024];

  gethostname(hostname, 1024);
  if ((nickname = get_nickname(fd, root)) == NULL
      || !(tmp1 = str_concat(":Welcome to the Internet Relay Network ",
			     nickname, ""))
      || !(tmp2 = str_concat(":Your host is ", hostname,
			     " running version 1.0")))
    return (-1);
  send_response(fd, "001", tmp1);
  send_response(fd, "002", tmp2);
  send_response(fd, "003", ":This server was created 04/2014");
  send_response(fd, "004", ":So nice to see you here");
  free(tmp1);
  free(tmp2);
  send_motd(fd, hostname);
  return (0);
}
Beispiel #10
0
Datei: main.c Projekt: hiciu/ekg2
/*
 * przygotowanie nazwy pliku z rozszerzeniem
 * %S - sesja nasza
 * %u - użytkownik (uid), z którym piszemy
 * %U - użytkownik (nick)   -||-
 * %Y, %M, %D - rok, miesiąc, dzień
 * zwraca ścieżkę, która należy ręcznie zwolnić przez xfree()
 */
static char *logs_prepare_fname(logs_log_t *log) {
	session_t *s;
	const char *logs_path;
	struct tm *tm = NULL;
	string_t buf;
	time_t sent = time(NULL);

	g_return_val_if_fail(log != NULL, NULL);
	g_return_val_if_fail(log->format != LOG_FORMAT_NONE, NULL);

	logs_path = (LOG_FORMAT_RAW == log->format) ? EKG_RAW_LOGS_PATH : config_logs_path;

	g_return_val_if_fail(logs_path != NULL, NULL);

	buf = g_string_new(NULL);
	s = session_find(log->session);

	while (*logs_path) {
		if (*logs_path == '%' && *(logs_path+1) != '\0') {
			char *append = NULL;
			logs_path++;
			switch (*logs_path) {
				case 'S':	append = g_strdup(s ? s->uid : "_null_");
						break;
				case 'P':	append = g_strdup(config_profile ? config_profile : "_default_");
						break;
				case 'U':
				case 'u':	append = g_strdup(*logs_path=='u' ? log->uid : get_nickname(s, log->uid));
						if (!append)
							append = g_strdup(log->uid);
						break;
				case 'Y':	if (!tm) tm = localtime(&sent);
						append = g_strdup_printf("%4d", tm->tm_year+1900);
						break;
				case 'M':	if (!tm) tm = localtime(&sent);
						append = g_strdup_printf("%02d", tm->tm_mon+1);
						break;
				case 'D':	if (!tm) tm = localtime(&sent);
						append = g_strdup_printf("%02d", tm->tm_mday);
						break;
				default:	g_string_append_c(buf, *logs_path);
			};
			if (append) {
				// XXX g_uri_escape_string( , , allow_utf8) ?
				char *tmp = g_uri_escape_string(append, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, TRUE);
				g_string_append(buf, tmp);
				g_free(tmp);
				g_free(append);
			}

		} else if (*logs_path == '~' && (*(logs_path+1) == '/' || *(logs_path+1) == '\0')) {
			g_string_append(buf, home_dir);
		} else
			string_append_c(buf, *logs_path);
		logs_path++;
	};

	switch (log->format) {
		case LOG_FORMAT_RAW:	g_string_append(buf, ".raw");	break;
		case LOG_FORMAT_SIMPLE:	g_string_append(buf, ".txt");	break;
		case LOG_FORMAT_IRSSI:	g_string_append(buf, ".log");	break;
		case LOG_FORMAT_XML:	g_string_append(buf, ".xml");	break;
	}

	// TODO sanityzacja sciezki - wywalic "../",
	xstrtr(buf->str, ' ', '_');

	return g_string_free(buf, FALSE);
}
Beispiel #11
0
	return fopen(fullname, "a+");
}

/*
 * zapis w formacie znanym z ekg1
 * typ,uid,nickname,timestamp,{timestamp wyslania dla odleglych}, text
 */

static void logs_simple(FILE *file, const char *session, const char *uid, const char *text, time_t sent, msgclass_t class, const char *status) {
	char *textcopy;
	const char *timestamp = prepare_timestamp_format(config_logs_timestamp, time(0));

	session_t *s = session_find((const char*)session);
	const char *gotten_uid = get_uid(s, uid);
	const char *gotten_nickname = get_nickname(s, uid);

	const gchar *logsenc = config_logs_encoding ? config_logs_encoding : console_charset;
	GString *tmp;

	if (!file)
		return;
	textcopy = log_escape(text);

	if (!gotten_uid)	gotten_uid = uid;
	if (!gotten_nickname)	gotten_nickname = uid;

	switch (class) {
		case EKG_MSGCLASS_MESSAGE	: fputs("msgrecv,", file);
						  break;
		case EKG_MSGCLASS_CHAT		: fputs("chatrecv,", file);
Beispiel #12
0
static const char *
help_iw(void)
{
	static xsg_string_t *string = NULL;
	xsg_list_t *l;
	int i = 0;

	init_iw();

	if (skfd < 0) {
		return NULL;
	}

	if (string == NULL) {
		string = xsg_string_new(NULL);
	} else {
		xsg_string_truncate(string, 0);
	}

	get_iw_device_list();

	for (l = device_list; l; l = l->next) {
		char name[128];

		snprintf(name, sizeof(name), "IW_INTERFACE%d", i++);
		xsg_setenv(name, (char *) device_list->data, TRUE);

		xsg_string_append_printf(string, "%s:   %s\n", name,
				(char *) device_list->data);
	}

	xsg_string_append(string, "\n");

	for (l = device_list; l; l = l->next) {
		char *ifname = (char *) l->data;

		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "config:name",
				get_name(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "config:nwid",
				get_nwid(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "config:freq",
				get_freq_number(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "config:freq",
				get_freq_string(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "config:channel",
				get_channel(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "config:key",
				get_key(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "config:keyid",
				get_keyid(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "config:essid",
				get_essid(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "config:mode",
				get_mode_number(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "config:mode",
				get_mode_string(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "info:sensitivity",
				get_sens(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "info:nickname",
				get_nickname(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "info:access_point",
				get_ap(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "info:bitrate",
				get_bitrate_number(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "info:bitrate",
				get_bitrate_string(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "info:rts",
				get_rts_number(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "info:rts",
				get_rts_string(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "info:fragment",
				get_frag_number(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "info:fragment",
				get_frag_string(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "info:power_management",
				get_power_management(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "info:txpower:dbm",
				get_txpower_dbm(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.2f\n",
				XSG_MODULE_NAME, ifname, "info:txpower:mw",
				get_txpower_mw(ifname));
		xsg_string_append_printf(string, "S %s:%s:%-36s%s\n",
				XSG_MODULE_NAME, ifname, "info:retry",
				get_retry(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "stats:quality:quality",
				get_stats_quality_quality(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "stats:quality:signal",
				get_stats_quality_signal(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "stats:quality:noise",
				get_stats_quality_noise(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "stats:discarded:nwid",
				get_stats_discarded_nwid(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "stats:discarded:code",
				get_stats_discarded_code(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "stats:discarded:fragment",
				get_stats_discarded_fragment(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "stats:discarded:retries",
				get_stats_discarded_retries(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "stats:discarded:misc",
				get_stats_discarded_misc(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "stats:missed:beacon",
				get_stats_missed_beacon(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "range:sensitivity",
				get_range_sensitivity(ifname));
		xsg_string_append_printf(string, "N %s:%s:%-36s%.0f\n",
				XSG_MODULE_NAME, ifname, "range:max_quality:quality",
				get_range_max_quality_quality(ifname));
	}

	return string->str;
}
Beispiel #13
0
static void netplay_pre_frame_spectate(netplay_t *handle)
{
   unsigned i;
   if (handle->spectate_client)
      return;

   fd_set fds;
   FD_ZERO(&fds);
   FD_SET(handle->fd, &fds);

   struct timeval tmp_tv = {0};
   if (select(handle->fd + 1, &fds, NULL, NULL, &tmp_tv) <= 0)
      return;

   if (!FD_ISSET(handle->fd, &fds))
      return;

   struct sockaddr_storage their_addr;
   socklen_t addr_size = sizeof(their_addr);
   int new_fd = accept(handle->fd, (struct sockaddr*)&their_addr, &addr_size);
   if (new_fd < 0)
   {
      RARCH_ERR("Failed to accept incoming spectator.\n");
      return;
   }

   int index = -1;
   for (i = 0; i < MAX_SPECTATORS; i++)
   {
      if (handle->spectate_fds[i] == -1)
      {
         index = i;
         break;
      }
   }

   // No vacant client streams :(
   if (index == -1)
   {
      close(new_fd);
      return;
   }

   if (!get_nickname(handle, new_fd))
   {
      RARCH_ERR("Failed to get nickname from client.\n");
      close(new_fd);
      return;
   }

   if (!send_nickname(handle, new_fd))
   {
      RARCH_ERR("Failed to send nickname to client.\n");
      close(new_fd);
      return;
   }

   size_t header_size;
   uint32_t *header = bsv_header_generate(&header_size, implementation_magic_value());
   if (!header)
   {
      RARCH_ERR("Failed to generate BSV header.\n");
      close(new_fd);
      return;
   }

   int bufsize = header_size;
   setsockopt(new_fd, SOL_SOCKET, SO_SNDBUF, CONST_CAST &bufsize, sizeof(int));

   if (!send_all(new_fd, header, header_size))
   {
      RARCH_ERR("Failed to send header to client.\n");
      close(new_fd);
      free(header);
      return;
   }

   free(header);
   handle->spectate_fds[index] = new_fd;

#ifndef HAVE_SOCKET_LEGACY
   log_connection(&their_addr, index, handle->other_nick);
#endif
}