static void sig_server_reconnect_save_status(IRC_SERVER_CONNECT_REC *conn,
					     IRC_SERVER_REC *server)
{
	if (!IS_IRC_SERVER_CONNECT(conn) || !IS_IRC_SERVER(server))
		return;

	g_free_not_null(conn->channels);
	conn->channels = irc_server_get_channels(server);

	g_free_not_null(conn->usermode);
	conn->usermode = g_strdup(server->usermode);
}
static PyObject *PyIrcServer_get_channels(PyIrcServer *self, PyObject *args)
{
    char *list;
    PyObject *ret;

    RET_NULL_IF_INVALID(self->data);

    list = irc_server_get_channels(self->data);
    ret = PyString_FromString(list);
    g_free(list);

    return ret;
}
Exemple #3
0
/* SYNTAX: SERVER [-ircnet <ircnet>] [-host <hostname>]
                  [+]<address>|<ircnet> [<port> [<password> [<nick>]]] */
static void cmd_server(const char *data, IRC_SERVER_REC *server,
		       void *item)
{
	GHashTable *optlist;
	IRC_SERVER_CONNECT_REC *conn;
	char *addr, *port, *channels, *away_reason, *usermode, *ircnet;
	void *free_arg;
	int no_old_server;

	g_return_if_fail(data != NULL);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS,
			    "connect", &optlist, &addr, &port))
		return;

	if (*addr == '\0' || strcmp(addr, "+") == 0)
		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	conn = server == NULL ? NULL : server->connrec;
	if (*addr != '+' && conn == NULL) {
		/* check if there's a server waiting for removal in
		   reconnection queue.. */
		RECONNECT_REC *rec;

		rec = find_reconnect_server(addr, atoi(port));
		if (rec != NULL) {
			/* remove the reconnection.. */
                        conn = (IRC_SERVER_CONNECT_REC *) rec->conn;
			server_reconnect_destroy(rec, FALSE);
		}
	}

	no_old_server = server == NULL;
	ircnet = conn == NULL ? NULL : g_strdup(conn->chatnet);
	if (*addr == '+' || conn == NULL) {
		channels = away_reason = usermode = NULL;
	} else if (server != NULL) {
		channels = irc_server_get_channels((IRC_SERVER_REC *) server);
		if (*channels == '\0')
			g_free_and_null(channels);
		away_reason = !server->usermode_away ? NULL :
			g_strdup(server->away_reason);
		usermode = g_strdup(server->usermode);
		signal_emit("command disconnect", 3,
			    "* Changing server", server, item);
	} else {
		channels = g_strdup(conn->channels);
		away_reason = g_strdup(conn->away_reason);
		usermode = g_strdup(conn->usermode);
	}

	server = IRC_SERVER(irc_connect_server(data));
	if (*addr == '+' || server == NULL ||
	    (ircnet != NULL && server->connrec->chatnet != NULL &&
	     g_strcasecmp(ircnet, server->connrec->chatnet) != 0)) {
		g_free_not_null(channels);
		g_free_not_null(usermode);
		g_free_not_null(away_reason);
	} else if (server != NULL && conn != NULL) {
		server->connrec->reconnection = TRUE;
		server->connrec->channels = channels;
		server->connrec->usermode = usermode;
		server->connrec->away_reason = away_reason;
		if (no_old_server)
			server_connect_free(SERVER_CONNECT(conn));
	}
	g_free_not_null(ircnet);
	cmd_params_free(free_arg);
}
Exemple #4
0
static void sig_reconnect(IRC_SERVER_REC *server)
{
	IRC_SERVER_CONNECT_REC *conn;
	SETUP_SERVER_REC *sserver;
	GSList *tmp;
	int found, through;
	time_t now;

	g_return_if_fail(server != NULL);

	if (reconnect_time == -1 || !server_should_reconnect(server))
		return;

	conn = g_new0(IRC_SERVER_CONNECT_REC, 1);
	server_connect_copy_skeleton(conn, server->connrec);

	/* save the server status */
	if (!server->connected) {
		conn->channels = g_strdup(server->connrec->channels);
		conn->away_reason = g_strdup(server->connrec->away_reason);
		conn->usermode = g_strdup(server->connrec->usermode);
	} else {
		conn->reconnection = TRUE;
		conn->channels = irc_server_get_channels(server);
		conn->away_reason = !server->usermode_away ? NULL :
			g_strdup(server->away_reason);
		conn->usermode = g_strdup(server->usermode);
	}

	sserver = server_setup_find(server->connrec->address, server->connrec->port);
	if (sserver == NULL) {
		/* port specific record not found, try without port.. */
		sserver = server_setup_find(server->connrec->address, -1);
	}

	if (sserver != NULL) {
		/* save the last connection time/status */
		sserver->last_connect = server->connect_time == 0 ?
			time(NULL) : server->connect_time;
		sserver->last_failed = !server->connected;
                if (server->banned) sserver->banned = TRUE;
	}

	if (sserver == NULL || conn->ircnet == NULL) {
		/* not in any ircnet, just reconnect back to same server */
		conn->address = g_strdup(server->connrec->address);
		conn->port = server->connrec->port;
		conn->password = server->connrec->password == NULL ? NULL :
			g_strdup(server->connrec->password);

		if (server->connect_time != 0 &&
		    time(NULL)-server->connect_time > reconnect_time) {
			/* there's been enough time since last connection,
			   reconnect back immediately */
			irc_server_connect(conn);
		} else {
			/* reconnect later.. */
			server_reconnect_add(conn, (server->connect_time == 0 ? time(NULL) :
						    server->connect_time) + reconnect_time);
		}
		return;
	}

	/* always try to first connect to the first on the list where we
	   haven't got unsuccessful connection attempts for the last half
	   an hour. */

	now = time(NULL);
	for (tmp = setupservers; tmp != NULL; tmp = tmp->next) {
		SETUP_SERVER_REC *rec = tmp->data;

		if (rec->ircnet != NULL && g_strcasecmp(conn->ircnet, rec->ircnet) == 0 &&
		    !rec->banned && (!rec->last_connect || !rec->last_failed ||
				     rec->last_connect < now-FAILED_RECONNECT_WAIT)) {
			sserver_connect(rec, conn);
			return;
		}
	}

	/* just try the next server in list */
	found = through = FALSE;
	for (tmp = setupservers; tmp != NULL; ) {
		SETUP_SERVER_REC *rec = tmp->data;

		if (!found && g_strcasecmp(rec->address, server->connrec->address) == 0 &&
		    server->connrec->port == rec->port)
			found = TRUE;
		else if (found && !rec->banned && rec->ircnet != NULL &&
			 g_strcasecmp(conn->ircnet, rec->ircnet) == 0) {
			sserver_connect(rec, conn);
			break;
		}

		if (tmp->next != NULL) {
			tmp = tmp->next;
			continue;
		}

		if (through) {
			/* shouldn't happen unless there's no servers in
			   this ircnet in setup.. */
                        irc_server_connect_free(conn);
			break;
		}

		tmp = setupservers;
		found = through = TRUE;
	}
}