Example #1
0
int server_unref(SERVER_REC *server)
{
    g_return_val_if_fail(IS_SERVER(server), FALSE);

    if (--server->refcount > 0)
        return TRUE;

    if (g_slist_find(servers, server) != NULL) {
        g_warning("Non-referenced server wasn't disconnected");
        server_disconnect(server);
        return TRUE;
    }

    MODULE_DATA_DEINIT(server);
    server_connect_unref(server->connrec);
    if (server->rawlog != NULL) rawlog_destroy(server->rawlog);
    g_free(server->version);
    g_free(server->away_reason);
    g_free(server->nick);
    g_free(server->tag);

    server->type = 0;
    g_free(server);
    return FALSE;
}
Example #2
0
static void server_connect_callback_init_ssl(SERVER_REC *server, GIOChannel *handle)
{
    int error;

    g_return_if_fail(IS_SERVER(server));

    error = irssi_ssl_handshake(handle);
    if (error == -1) {
        server->connection_lost = TRUE;
        server_connect_failed(server, NULL);
        return;
    }
    if (error & 1) {
        if (server->connect_tag != -1)
            g_source_remove(server->connect_tag);
        server->connect_tag = g_input_add(handle, error == 1 ? G_INPUT_READ : G_INPUT_WRITE,
                                          (GInputFunction)
                                          server_connect_callback_init_ssl,
                                          server);
        return;
    }

    lookup_servers = g_slist_remove(lookup_servers, server);
    if (server->connect_tag != -1) {
        g_source_remove(server->connect_tag);
        server->connect_tag = -1;
    }

    server_connect_finished(server);
}
Example #3
0
/* connection to server failed */
void server_connect_failed(SERVER_REC *server, const char *msg)
{
    g_return_if_fail(IS_SERVER(server));

    lookup_servers = g_slist_remove(lookup_servers, server);

    signal_emit("server connect failed", 2, server, msg);

    if (server->connect_tag != -1) {
        g_source_remove(server->connect_tag);
        server->connect_tag = -1;
    }
    if (server->handle != NULL) {
        net_sendbuffer_destroy(server->handle, TRUE);
        server->handle = NULL;
    }

    if (server->connect_pipe[0] != NULL) {
        g_io_channel_shutdown(server->connect_pipe[0], TRUE, NULL);
        g_io_channel_unref(server->connect_pipe[0]);
        g_io_channel_shutdown(server->connect_pipe[1], TRUE, NULL);
        g_io_channel_unref(server->connect_pipe[1]);
        server->connect_pipe[0] = NULL;
        server->connect_pipe[1] = NULL;
    }

    server_unref(server);
}
Example #4
0
/* SYNTAX: WAIT [-<server tag>] <milliseconds> */
static void cmd_wait(const char *data, IRC_SERVER_REC *server)
{
	GHashTable *optlist;
	char *msecs;
	void *free_arg;
	int n;

	g_return_if_fail(data != NULL);
	if (!IS_SERVER(server) || !server->connected)
		cmd_return_error(CMDERR_NOT_CONNECTED);

	if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST,
			    NULL, &optlist, &msecs))
		return;

	if (*msecs == '\0')
		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	/* -<server tag> */
	server = IRC_SERVER(cmd_options_get_server(NULL, optlist,
						   SERVER(server)));

	n = atoi(msecs);
	if (server != NULL && n > 0) {
		g_get_current_time(&server->wait_cmd);
		server->wait_cmd.tv_sec += n/1000;
		server->wait_cmd.tv_usec += n%1000;
		if (server->wait_cmd.tv_usec >= 1000) {
			server->wait_cmd.tv_sec++;
			server->wait_cmd.tv_usec -= 1000;
		}
	}
	cmd_params_free(free_arg);
}
Example #5
0
/* SYNTAX: CYCLE [<channel>] [<message>] */
static void cmd_cycle(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
{
	CHANNEL_REC *chanrec;
	char *channame, *msg, *joindata;
	void *free_arg;

	g_return_if_fail(data != NULL);
	if (!IS_SERVER(server) || !server->connected)
		cmd_return_error(CMDERR_NOT_CONNECTED);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN,
			    item, &channame, &msg))
		return;
	if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	chanrec = channel_find(server, channame);
	if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND);

	joindata = chanrec->get_join_data(chanrec);
	window_bind_add(window_item_window(chanrec),
			chanrec->server->tag, chanrec->name);

	/* FIXME: kludgy kludgy... */
	signal_emit("command part", 3, data, server, item);

	if (g_slist_find(channels, chanrec) != NULL) {
		chanrec->left = TRUE;
		channel_destroy(chanrec);
	}

	server->channels_join(server, joindata, FALSE);
	g_free(joindata);

	cmd_params_free(free_arg);
}
Example #6
0
	CmdResult Handle (const std::vector<std::string>& parameters, User *user)
	{
		User* dest = ServerInstance->FindNick(parameters[0]);
		if ((dest) && (!IS_SERVER(dest)))
		{
			if (ServerInstance->ULine(dest->server))
			{
				user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Cannot use an SA command on a u-lined client",user->nick.c_str());
				return CMD_FAILURE;
			}

			// Pass the command on, so the client's server can quit it properly.
			if (!IS_LOCAL(dest))
				return CMD_SUCCESS;

			ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used SAQUIT to make "+dest->nick+" quit with a reason of "+parameters[1]);

			ServerInstance->Users->QuitUser(dest, parameters[1]);
			return CMD_SUCCESS;
		}
		else
		{
			user->WriteNotice("*** Invalid nickname '" + parameters[0] + "'");
			return CMD_FAILURE;
		}
	}
Example #7
0
	void unserialize(SerializeFormat format, Extensible* container, const std::string& value)
	{
		if (format == FORMAT_NETWORK)
			return;

		callerid_data* dat = new callerid_data;
		irc::commasepstream s(value);
		std::string tok;
		if (s.GetToken(tok))
			dat->lastnotify = ConvToInt(tok);

		while (s.GetToken(tok))
		{
			User *u = ServerInstance->FindNick(tok);
			if ((u) && (u->registered == REG_ALL) && (!u->quitting) && (!IS_SERVER(u)))
			{
				if (dat->accepting.insert(u).second)
				{
					callerid_data* other = this->get(u, true);
					other->wholistsme.push_back(dat);
				}
			}
		}

		void* old = set_raw(container, dat);
		if (old)
			this->free(old);
	}
Example #8
0
bool TreeSocket::Away(const std::string &prefix, parameterlist &params)
{
	User* u = ServerInstance->FindNick(prefix);
	if ((!u) || (IS_SERVER(u)))
		return true;
	if (params.size())
	{
		FOREACH_MOD(I_OnSetAway, OnSetAway(u, params[params.size() - 1]));

		if (params.size() > 1)
			u->awaytime = atoi(params[0].c_str());
		else
			u->awaytime = ServerInstance->Time();

		u->awaymsg = params[params.size() - 1];

		params[params.size() - 1] = ":" + params[params.size() - 1];
	}
	else
	{
		FOREACH_MOD(I_OnSetAway, OnSetAway(u, ""));
		u->awaymsg.clear();
	}
	Utils->DoOneToAllButSender(prefix,"AWAY",params,u->server);
	return true;
}
Example #9
0
static void
sig_not_in_roster(XMPP_SERVER_REC *server, const char *jid)
{
	g_return_if_fail(IS_SERVER(server));
	g_return_if_fail(jid != NULL);
	printformat_module(MODULE_NAME, server, NULL,
	    MSGLEVEL_CLIENTERROR, XMPPTXT_NOT_IN_ROSTER, jid);
}
Example #10
0
static void sig_connected(SERVER_REC *server)
{
	g_return_if_fail(IS_SERVER(server));
	if (!server->connrec->reconnection)
		return;

	if (server->connrec->channels != NULL)
		server->channels_join(server, server->connrec->channels, TRUE);
}
Example #11
0
static void
show_group(XMPP_SERVER_REC *server, XMPP_ROSTER_GROUP_REC *group)
{
	g_return_if_fail(IS_SERVER(server));
	g_return_if_fail(group != NULL);
	printformat_module(MODULE_NAME, server, NULL, MSGLEVEL_CRAP,
	    XMPPTXT_ROSTER_GROUP, (group->name != NULL) ?
	    group->name : settings_get_str("xmpp_roster_default_group"));
}
GVariant *
server_get_variant (Server * server)
{
	/* Okay, this doesn't do anything useful, but it will generate an error
	   which could be a good thing */
	g_return_val_if_fail(IS_SERVER(server), NULL);

	ServerClass * klass = SERVER_GET_CLASS(server);
	if (klass->get_properties != NULL) {
		GVariantBuilder tuple;
		g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE);

		if (IS_CITRIX_SERVER(server)) {
			g_variant_builder_add_value(&tuple, g_variant_new_string("ica"));
		} else if (IS_RDP_SERVER(server)) {
			g_variant_builder_add_value(&tuple, g_variant_new_string("freerdp"));
		} else if (IS_UCCS_SERVER(server)) {
			g_variant_builder_add_value(&tuple, g_variant_new_string("uccs"));
		} else if (IS_X2GO_SERVER(server)) {
			g_variant_builder_add_value(&tuple, g_variant_new_string("x2go"));
		} else {
			g_assert_not_reached();
		}

		if (server->name != NULL) {
			g_variant_builder_add_value(&tuple, g_variant_new_string(server->name));
		} else {
			g_warning("Server has no name");
			g_variant_builder_add_value(&tuple, g_variant_new_string(""));
		}

		if (server->uri != NULL) {
			g_variant_builder_add_value(&tuple, g_variant_new_string(server->uri));
		} else {
			g_warning("Server has no URI");
			g_variant_builder_add_value(&tuple, g_variant_new_string(""));
		}

		g_variant_builder_add_value(&tuple, g_variant_new_boolean(server->last_used));

		GVariant * props = klass->get_properties(server);
		g_variant_builder_add_value(&tuple, props);

		if (klass->get_applications != NULL) {
			GVariant * array = klass->get_applications(server);
			g_variant_builder_add_value(&tuple, array);
		} else {
			/* NULL array of applications */
			g_variant_builder_add_value(&tuple, g_variant_new_array(G_VARIANT_TYPE("(si)"), NULL, 0));
		}

		return g_variant_builder_end(&tuple);
	}

	return NULL;
}
Example #13
0
		ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
		{
			if (IS_SERVER(source) || ServerInstance->ULine(source->server))
				return MODEACTION_ALLOW;
			else
			{
				if (source && channel)
					source->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Only servers are permitted to change channel mode '%c'", source->nick.c_str(), channel->name.c_str(), 'y');
				return MODEACTION_DENY;
			}
		}
/**
 * server_cached_domains:
 * @server: Where should we find those domains?
 *
 * Gets a list of cached domains for a particular server, if this function
 * isn't overriden, then a null array is returned.
 */
GVariant *
server_cached_domains (Server * server)
{
	g_return_val_if_fail(IS_SERVER(server), NULL);

	ServerClass * klass = SERVER_GET_CLASS(server);
	if (klass->get_domains != NULL) {
		return klass->get_domains(server);
	}

	return g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0);
}
Example #15
0
	ACCEPTAction GetTargetAndAction(std::string& tok)
	{
		bool remove = (tok[0] == '-');
		if ((remove) || (tok[0] == '+'))
			tok.erase(tok.begin());

		User* target = ServerInstance->FindNick(tok);
		if ((!target) || (target->registered != REG_ALL) || (target->quitting) || (IS_SERVER(target)))
			target = NULL;

		return std::make_pair(target, !remove);
	}
Example #16
0
void UserManager::QuitUser(User* user, const std::string& quitreason, const std::string* operreason)
{
	if (user->quitting)
	{
		ServerInstance->Logs->Log("USERS", LOG_DEFAULT, "ERROR: Tried to quit quitting user: "******"USERS", LOG_DEFAULT, "ERROR: Tried to quit server user: "******"USERS", LOG_DEBUG, "QuitUser: %s=%s '%s'", user->uuid.c_str(), user->nick.c_str(), quitreason.c_str());
	user->Write("ERROR :Closing link: (%s@%s) [%s]", user->ident.c_str(), user->host.c_str(), operreason ? operreason->c_str() : quitreason.c_str());

	std::string reason;
	reason.assign(quitreason, 0, ServerInstance->Config->Limits.MaxQuit);
	if (!operreason)
		operreason = &reason;

	ServerInstance->GlobalCulls.AddItem(user);

	if (user->registered == REG_ALL)
	{
		FOREACH_MOD(OnUserQuit, (user, reason, *operreason));
		user->WriteCommonQuit(reason, *operreason);
	}
	else
		unregistered_count--;

	if (IS_LOCAL(user))
	{
		LocalUser* lu = IS_LOCAL(user);
		FOREACH_MOD(OnUserDisconnect, (lu));
		lu->eh.Close();

		if (lu->registered == REG_ALL)
			ServerInstance->SNO->WriteToSnoMask('q',"Client exiting: %s (%s) [%s]", user->GetFullRealHost().c_str(), user->GetIPString().c_str(), operreason->c_str());
	}

	user_hash::iterator iter = this->clientlist->find(user->nick);

	if (iter != this->clientlist->end())
		this->clientlist->erase(iter);
	else
		ServerInstance->Logs->Log("USERS", LOG_DEFAULT, "ERROR: Nick not found in clientlist, cannot remove: " + user->nick);

	uuidlist->erase(user->uuid);
}
Example #17
0
/**
 * SAVE command - force nick change to UID on timestamp match
 */
CmdResult CommandSave::Handle(User* user, std::vector<std::string>& params)
{
	User* u = ServerInstance->FindUUID(params[0]);
	if ((!u) || (IS_SERVER(u)))
		return CMD_FAILURE;

	time_t ts = atol(params[1].c_str());

	if (u->age == ts)
		u->ChangeNick(u->uuid, SavedTimestamp);

	return CMD_SUCCESS;
}
Example #18
0
static void sig_connected(SERVER_REC *server)
{
	CHATNET_REC *rec;

	g_return_if_fail(IS_SERVER(server));

	if (server->connrec->chatnet == NULL || server->session_reconnect)
		return;

	rec = chatnet_find(server->connrec->chatnet);
	if (!server->connrec->no_autosendcmd && rec != NULL && rec->autosendcmd)
		eval_special_string(rec->autosendcmd, "", server, NULL);
}
Example #19
0
CHANNEL_REC *channel_find(SERVER_REC *server, const char *name)
{
	g_return_val_if_fail(server == NULL || IS_SERVER(server), NULL);
	g_return_val_if_fail(name != NULL, NULL);

	if (server != NULL)
		return channel_find_server(server, name);

	/* find from any server */
	return gslist_foreach_find(servers,
				   (FOREACH_FIND_FUNC) channel_find_server,
				   (void *) name);
}
Example #20
0
/* Create a new channel */
CHANNEL_REC *channel_create(int chat_type, SERVER_REC *server,
			    const char *name, int automatic)
{
	CHANNEL_REC *channel;

	g_return_val_if_fail(server == NULL || IS_SERVER(server), NULL);
	g_return_val_if_fail(name != NULL, NULL);

	channel = NULL;
	signal_emit("channel create", 5, &channel, GINT_TO_POINTER(chat_type),
		    server, name, GINT_TO_POINTER(automatic));
	return channel;
}
Example #21
0
CmdResult CommandMetadata::Handle(const std::vector<std::string>& params, User *srcuser)
{
	if (params[0] == "*")
	{
		std::string value = params.size() < 3 ? "" : params[2];
		FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(NULL,params[1],value));
		return CMD_SUCCESS;
	}

	if (params[0][0] == '#')
	{
		// Channel METADATA has an additional parameter: the channel TS
		// :22D METADATA #channel 12345 extname :extdata
		if (params.size() < 3)
			return CMD_INVALID;

		Channel* c = ServerInstance->FindChan(params[0]);
		if (!c)
			return CMD_FAILURE;

		time_t ChanTS = ConvToInt(params[1]);
		if (!ChanTS)
			return CMD_INVALID;

		if (c->age < ChanTS)
			// Their TS is newer than ours, discard this command and do not propagate
			return CMD_FAILURE;

		std::string value = params.size() < 4 ? "" : params[3];

		ExtensionItem* item = ServerInstance->Extensions.GetItem(params[2]);
		if (item)
			item->unserialize(FORMAT_NETWORK, c, value);
		FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(c,params[2],value));
	}
	else
	{
		User* u = ServerInstance->FindUUID(params[0]);
		if ((u) && (!IS_SERVER(u)))
		{
			ExtensionItem* item = ServerInstance->Extensions.GetItem(params[1]);
			std::string value = params.size() < 3 ? "" : params[2];

			if (item)
				item->unserialize(FORMAT_NETWORK, u, value);
			FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(u,params[1],value));
		}
	}

	return CMD_SUCCESS;
}
Example #22
0
static void sig_disconnected(SERVER_REC *server)
{
	WINDOW_REC *window;
	GSList *tmp;

	g_return_if_fail(IS_SERVER(server));

	for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
		CHANNEL_REC *channel = tmp->data;

		window = window_item_window((WI_ITEM_REC *) channel);
		window_bind_add(window, server->tag, channel->name);
	}
}
/**
 * server_set_last_used:
 * @server: Server to look in
 * @uri: URI to set as last used
 *
 * Checks the URI of this server to see if it matches, and then look
 * to see if subclasses have a way to match it another way.
 */
void
server_set_last_used_server (Server * server, const gchar * uri)
{
	g_return_if_fail(IS_SERVER(server));

	if (g_strcmp0(server->uri, uri) == 0) {
		server->last_used = TRUE;
	} else {
		ServerClass * klass = SERVER_GET_CLASS(server);

		if (klass->set_last_used_server != NULL) {
			klass->set_last_used_server(server, uri);
		}
	}
}
Example #24
0
static void sig_disconnected(SERVER_REC *server)
{
	WINDOW_REC *window;
	GSList *tmp;

	g_return_if_fail(IS_SERVER(server));

	for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
		CHANNEL_REC *channel = tmp->data;

		window = window_item_window((WI_ITEM_REC *) channel);
		window->waiting_channels =
			g_slist_append(window->waiting_channels, g_strdup_printf("%s %s", server->tag, channel->name));
	}
}
Example #25
0
GSList *nicklist_get_same(SERVER_REC *server, const char *nick)
{
	NICKLIST_GET_SAME_REC rec;
	GSList *tmp;

	g_return_val_if_fail(IS_SERVER(server), NULL);

	rec.nick = nick;
	rec.list = NULL;
	for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
		rec.channel = tmp->data;
		g_hash_table_foreach(rec.channel->nicks,
				     (GHFunc) get_nicks_same_hash, &rec);
	}
	return rec.list;
}
/**
 * server_find_uri:
 * @server: Server to look in
 * @uri: URI to search for
 *
 * Checks the URI of this server to see if it matches, and then look
 * to see if subclasses have a way to match it another way.
 */
Server *
server_find_uri (Server * server, const gchar * uri)
{
	g_return_val_if_fail(IS_SERVER(server), NULL);

	if (g_strcmp0(server->uri, uri) == 0) {
		return server;
	}

	ServerClass * klass = SERVER_GET_CLASS(server);

	if (klass->find_uri != NULL) {
		return klass->find_uri(server, uri);
	}

	return NULL;
}
Example #27
0
/* Return query where to put the private message. */
QUERY_REC *privmsg_get_query(SERVER_REC *server, const char *nick,
			     int own, int level)
{
	QUERY_REC *query;

	g_return_val_if_fail(IS_SERVER(server), NULL);
        g_return_val_if_fail(nick != NULL, NULL);

	query = query_find(server, nick);
	if (query == NULL && (querycreate_level & level) != 0 &&
	    (!own || settings_get_bool("autocreate_own_query"))) {
		query = CHAT_PROTOCOL(server)->
			query_create(server->tag, nick, TRUE);
	}

	return query;
}
Example #28
0
File: masks.c Project: irssi/irssi
int mask_match_address(SERVER_REC *server, const char *mask,
		       const char *nick, const char *address)
{
	char *str;
	int ret, wildcards;

	g_return_val_if_fail(server == NULL || IS_SERVER(server), FALSE);
	g_return_val_if_fail(mask != NULL && nick != NULL, FALSE);
	if (address == NULL) address = "";

	str = !check_address(mask, &wildcards) ? (char *) nick :
		g_strdup_printf("%s!%s", nick, address);
	ret = check_mask(server, mask, str, wildcards);
	if (str != nick) g_free(str);

	return ret;
}
Example #29
0
void server_disconnect(SERVER_REC *server)
{
	int chans;

	g_return_if_fail(IS_SERVER(server));

	if (server->disconnected)
		return;

	if (server->connect_tag != -1) {
		/* still connecting to server.. */
		if (server->connect_pid != -1)
			net_disconnect_nonblock(server->connect_pid);
		server_connect_failed(server, NULL);
		return;
	}

	servers = g_slist_remove(servers, server);

	server->disconnected = TRUE;
	signal_emit("server disconnected", 1, server);

	/* close all channels */
	chans = server_remove_channels(server);

	if (server->handle != NULL) {
		if (!chans || server->connection_lost)
			net_sendbuffer_destroy(server->handle, TRUE);
		else {
			/* we were on some channels, try to let the server
			   disconnect so that our quit message is guaranteed
			   to get displayed */
			net_disconnect_later(net_sendbuffer_handle(server->handle));
			net_sendbuffer_destroy(server->handle, FALSE);
		}
		server->handle = NULL;
	}

	if (server->readtag > 0) {
		g_source_remove(server->readtag);
		server->readtag = -1;
	}

	server_unref(server);
}
	ModeAction OnModeChange(User* source, User* dest, Channel* chan, std::string& parameter, bool adding)
	{
		if (dest->IsModeSet(GetModeChar()) == adding)
			return MODEACTION_DENY;

		dest->SetMode(GetModeChar(), adding);

		LocalUser* const localuser = IS_LOCAL(dest);
		// Send snotices
		char snodest = localuser ? 'v' : 'V';
		if (snoonset && adding)
			ServerInstance->SNO->WriteToSnoMask(snodest, "Oper %s has turned on override", dest->nick.c_str());
		else if (!adding)
		{
			// IS_OPER check is needed to make sure we don't send snotices when the server unsets
			// the mode due to deopering
			if ((snoonunset) && (IS_OPER(dest)) && (!IS_SERVER(source)))
				ServerInstance->SNO->WriteToSnoMask(snodest, "Oper %s has turned off override", dest->nick.c_str());
		}

		// Ignore remote users, their own server handles them
		if (localuser)
		{
			if (adding)
			{
				if (activetime > 0)
					activeopers.push_back(ActiveOper(localuser));
			}
			else
			{
				// Remove this oper from the list
				for (ActiveOperList::iterator i = activeopers.begin(); i != activeopers.end(); ++i)
				{
					ActiveOper& item = *i;
					if (item.uuid == dest->uuid)
					{
						activeopers.erase(i);
						break;
					}
				}
			}
		}

		return MODEACTION_ALLOW;
	}