Exemple #1
0
/* Massjoin support - really useful when trying to do things (like op/deop)
   to people after netjoins. It sends
   "massjoin #channel nick!user@host nick2!user@host ..." signals */
static void event_join(IRC_SERVER_REC *server, const char *data,
		       const char *nick, const char *address)
{
	char *params, *channel, *ptr;
	IRC_CHANNEL_REC *chanrec;
	NICK_REC *nickrec;
	GSList *nicks, *tmp;

	g_return_if_fail(data != NULL);

	if (g_strcasecmp(nick, server->nick) == 0) {
		/* You joined, no need to do anything here */
		return;
	}

	params = event_get_params(data, 1, &channel);
	ptr = strchr(channel, 7); /* ^G does something weird.. */
	if (ptr != NULL) *ptr = '\0';

	/* find channel */
	chanrec = irc_channel_find(server, channel);
	g_free(params);
	if (chanrec == NULL) return;

	/* check that the nick isn't already in nicklist. seems to happen
	   sometimes (server desyncs or something?) */
	nickrec = nicklist_find(CHANNEL(chanrec), nick);
	if (nickrec != NULL) {
		/* destroy the old record */
		nicklist_remove(CHANNEL(chanrec), nickrec);
	}

	/* add user to nicklist */
	nickrec = irc_nicklist_insert(chanrec, nick, FALSE, FALSE, FALSE, TRUE);
        nicklist_set_host(CHANNEL(chanrec), nickrec, address);

	if (chanrec->massjoins == 0) {
		/* no nicks waiting in massjoin queue */
		chanrec->massjoin_start = time(NULL);
		chanrec->last_massjoins = 0;
	}

	if (nickrec->realname == NULL) {
		/* Check if user is already in some other channel,
		   get the realname and other stuff from there */
		nicks = nicklist_get_same(SERVER(server), nick);
		for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) {
			NICK_REC *rec = tmp->next->data;

			if (rec->realname != NULL) {
				nickrec->last_check = rec->last_check;
				nickrec->realname = g_strdup(rec->realname);
				nickrec->gone = rec->gone;
				break;
			}
		}
		g_slist_free(nicks);
	}

	chanrec->massjoins++;
}
Exemple #2
0
static void event_names_list(IRC_SERVER_REC *server, const char *data)
{
	IRC_CHANNEL_REC *chanrec;
	NICK_REC *rec;
	char *params, *type, *channel, *names, *ptr, *host;
        int op, halfop, voice;
	char prefixes[MAX_USER_PREFIXES+1];

	g_return_if_fail(data != NULL);

	params = event_get_params(data, 4, NULL, &type, &channel, &names);

	chanrec = irc_channel_find(server, channel);
	if (chanrec == NULL || chanrec->names_got) {
		/* unknown channel / names list already read */
		g_free(params);
		return;
	}

	/* type = '=' = public, '*' = private, '@' = secret.

	   This is actually pretty useless to check here, but at least we
	   get to know if the channel is +p or +s a few seconds before
	   we receive the MODE reply...

	   If the channel key is set, assume the channel is +k also until
           we know better, so parse_channel_modes() won't clear the key */
	if (*type == '*') {
		parse_channel_modes(chanrec, NULL,
				    chanrec->key ? "+kp" : "+p", FALSE);
	} else if (*type == '@') {
		parse_channel_modes(chanrec, NULL,
				    chanrec->key ? "+ks" : "+s", FALSE);
	}

	while (*names != '\0') {
		while (*names == ' ') names++;
		ptr = names;
		while (*names != '\0' && *names != ' ') names++;
		if (*names != '\0') *names++ = '\0';

		/* some servers show ".@nick", there's also been talk about
		   showing "@+nick" and since none of these chars are valid
		   nick chars, just check them until a non-nickflag char is
		   found. */
		op = halfop = voice = FALSE;
		prefixes[0] = '\0';
		while (isnickflag(server, *ptr)) {
			prefix_add(prefixes, *ptr, (SERVER_REC *) server);
			switch (*ptr) {
			case '@':
                                op = TRUE;
                                break;
			case '%':
                                halfop = TRUE;
                                break;
			case '+':
                                voice = TRUE;
                                break;
			}
                        ptr++;
		}

		host = strchr(ptr, '!');
		if (host != NULL)
			*host++ = '\0';

		if (nicklist_find((CHANNEL_REC *) chanrec, ptr) == NULL) {
			rec = irc_nicklist_insert(chanrec, ptr, op, halfop,
						  voice, FALSE, prefixes);
			if (host != NULL)
				nicklist_set_host(CHANNEL(chanrec), rec, host);
		}
	}

	g_free(params);
}