Exemplo n.º 1
0
static void event_text(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
{
	char *line, *str;

	g_return_if_fail(data != NULL);
	if (item == NULL) return;

	line = settings_get_bool("expand_escapes") ?
		expand_escapes(data, server, item) : g_strdup(data);

	/* check for automatic nick completion */
	if (completion_auto && IS_CHANNEL(item)) {
		str = auto_complete(CHANNEL(item), line);
		if (str != NULL) {
			g_free(line);
                        line = str;
		}
	}

	str = g_strdup_printf(IS_CHANNEL(item) ? "-channel %s %s" :
			      IS_QUERY(item) ? "-nick %s %s" : "%s %s",
			      item->name, line);

	signal_emit("command msg", 3, str, server, item);

	g_free(str);
	g_free(line);

	signal_stop();
}
Exemplo n.º 2
0
/* Send the auto send command to channel */
void channel_send_autocommands(CHANNEL_REC *channel)
{
	CHANNEL_SETUP_REC *rec;
	NICK_REC *nick;
	char **bots, **bot;

	g_return_if_fail(IS_CHANNEL(channel));

	rec = channel_setup_find(channel->name, channel->server->connrec->chatnet);
	if (rec == NULL || rec->autosendcmd == NULL || !*rec->autosendcmd)
		return;

	if (rec->botmasks == NULL || !*rec->botmasks) {
		/* just send the command. */
		eval_special_string(rec->autosendcmd, "", channel->server, channel);
		return;
	}

	/* find first available bot.. */
	bots = g_strsplit(rec->botmasks, " ", -1);
	for (bot = bots; *bot != NULL; bot++) {
		const char *botnick = *bot;

		nick = nicklist_find_mask(channel,
					  channel->server->isnickflag(*botnick) ?
					  botnick+1 : botnick);
		if (nick != NULL &&
		    match_nick_flags(channel->server, nick, *botnick)) {
			eval_special_string(rec->autosendcmd, nick->nick,
					    channel->server, channel);
			break;
		}
	}
	g_strfreev(bots);
}
Exemplo n.º 3
0
static void sig_layout_save_item(WINDOW_REC *window, WI_ITEM_REC *item,
				 CONFIG_NODE *node)
{
	CONFIG_NODE *subnode;
        CHAT_PROTOCOL_REC *proto;
	const char *type;
	WINDOW_BIND_REC *rec;

	type = module_find_id_str("WINDOW ITEM TYPE", item->type);
	if (type == NULL)
		return;

	subnode = iconfig_node_section(node, NULL, NODE_TYPE_BLOCK);

	iconfig_node_set_str(subnode, "type", type);
	proto = item->chat_type == 0 ? NULL :
		chat_protocol_find_id(item->chat_type);
	if (proto != NULL)
		iconfig_node_set_str(subnode, "chat_type", proto->name);
	iconfig_node_set_str(subnode, "name", item->visible_name);

	if (item->server != NULL) {
		iconfig_node_set_str(subnode, "tag", item->server->tag);
		if (IS_CHANNEL(item)) {
			rec = window_bind_add(window, item->server->tag, item->visible_name);
			if (rec != NULL)
				rec->sticky = TRUE;
		}
	} else if (IS_QUERY(item)) {
		iconfig_node_set_str(subnode, "tag", QUERY(item)->server_tag);
	}
}
Exemplo n.º 4
0
Arquivo: nicklist.c Projeto: GPF/irssi
static void sig_channel_created(CHANNEL_REC *channel)
{
	g_return_if_fail(IS_CHANNEL(channel));

	channel->nicks = g_hash_table_new((GHashFunc) g_istr_hash,
					  (GCompareFunc) g_istr_equal);
}
Exemplo n.º 5
0
void channel_destroy(CHANNEL_REC *channel)
{
	g_return_if_fail(IS_CHANNEL(channel));

	if (channel->destroying) return;
	channel->destroying = TRUE;

	channels = g_slist_remove(channels, channel);
	channel->server->channels =
		g_slist_remove(channel->server->channels, channel);

	signal_emit("channel destroyed", 1, channel);

        MODULE_DATA_DEINIT(channel);
	g_free_not_null(channel->hilight_color);
	g_free_not_null(channel->topic);
	g_free_not_null(channel->topic_by);
	g_free_not_null(channel->key);
	g_free(channel->mode);
	g_free(channel->name);
	g_free(channel->visible_name);

        channel->type = 0;
	g_free(channel);
}
Exemplo n.º 6
0
Arquivo: nicklist.c Projeto: GPF/irssi
/* Find nick mask, wildcards allowed */
NICK_REC *nicklist_find_mask(CHANNEL_REC *channel, const char *mask)
{
	NICK_REC *nickrec;
	char *nick, *host;

	g_return_val_if_fail(IS_CHANNEL(channel), NULL);
	g_return_val_if_fail(mask != NULL, NULL);

	nick = g_strdup(mask);
	host = strchr(nick, '!');
	if (host != NULL) *host++ = '\0';

	if (strchr(nick, '*') || strchr(nick, '?')) {
		g_free(nick);
		return nicklist_find_wildcards(channel, mask);
	}

	nickrec = g_hash_table_lookup(channel->nicks, nick);

	if (host != NULL) {
		while (nickrec != NULL) {
			if (nickrec->host != NULL &&
			    match_wildcards(host, nickrec->host))
				break; /* match */
			nickrec = nickrec->next;
		}
	}
	g_free(nick);
	return nickrec;
}
Exemplo n.º 7
0
static void
sig_get_active_channel(const char **name)
{
	*name = IS_XMPP_SERVER(active_win->active_server)
	    && IS_CHANNEL(active_win->active) ?
	    ((CHANNEL_REC *)active_win->active)->name : NULL;
}
Exemplo n.º 8
0
static void autolog_open_check(TEXT_DEST_REC *dest)
{
	const char *deftarget;
	SERVER_REC *server = dest->server;
	const char *server_tag = dest->server_tag;
	const char *target = dest->target;
	int level = dest->level;

	/* FIXME: kind of a kludge, but we don't want to reopen logs when
	   we're parting the channel with /WINDOW CLOSE.. Maybe a small
	   timeout would be nice instead of immediately closing the log file
	   after "window item destroyed" */
	if (level == MSGLEVEL_PARTS ||
	    (autolog_level & level) == 0 || target == NULL || *target == '\0')
		return;

	deftarget = server ? server->nick : "unknown";

	/* log only channels that have been saved to the config */
	if (settings_get_bool("autolog_only_saved_channels") && IS_CHANNEL(window_item_find(server, target))
		&& channel_setup_find(target, server_tag) == NULL)
		return;

	if (autolog_ignore_targets != NULL &&
	    strarray_find_dest(autolog_ignore_targets, dest))
		return;

	if (target != NULL)
		autolog_open(server, server_tag, g_strcmp0(target, "*") ? target : deftarget);
}
Exemplo n.º 9
0
Arquivo: nicklist.c Projeto: GPF/irssi
/* Find nick */
NICK_REC *nicklist_find(CHANNEL_REC *channel, const char *nick)
{
	g_return_val_if_fail(IS_CHANNEL(channel), NULL);
	g_return_val_if_fail(nick != NULL, NULL);

	return g_hash_table_lookup(channel->nicks, nick);
}
Exemplo n.º 10
0
Arquivo: nicklist.c Projeto: GPF/irssi
static void sig_channel_destroyed(CHANNEL_REC *channel)
{
	g_return_if_fail(IS_CHANNEL(channel));

	g_hash_table_foreach(channel->nicks,
			     (GHFunc) nicklist_remove_hash, channel);
	g_hash_table_destroy(channel->nicks);
}
Exemplo n.º 11
0
Arquivo: nicklist.c Projeto: GPF/irssi
/* Remove nick from list */
void nicklist_remove(CHANNEL_REC *channel, NICK_REC *nick)
{
	g_return_if_fail(IS_CHANNEL(channel));
	g_return_if_fail(nick != NULL);

        nick_hash_remove(channel, nick);
	nicklist_destroy(channel, nick);
}
Exemplo n.º 12
0
/* expands to your usermode on channel, op '@', halfop '%', "+" voice */
static char *expando_cumode(SERVER_REC *server, void *item, int *free_ret)
{
	if (IS_CHANNEL(item) && CHANNEL(item)->ownnick) {
		return NICK(CHANNEL(item)->ownnick)->op ? "@" :
		       NICK(CHANNEL(item)->ownnick)->halfop ? "%" :
		       NICK(CHANNEL(item)->ownnick)->voice ? "+" : "";
	}
	return "";
}
Exemplo n.º 13
0
void channel_change_visible_name(CHANNEL_REC *channel, const char *name)
{
	g_return_if_fail(IS_CHANNEL(channel));

	g_free(channel->visible_name);
	channel->visible_name = g_strdup(name);

	signal_emit("window item name changed", 1, channel);
}
Exemplo n.º 14
0
Arquivo: nicklist.c Projeto: GPF/irssi
/* Get list of nicks */
GSList *nicklist_getnicks(CHANNEL_REC *channel)
{
	GSList *list;

	g_return_val_if_fail(IS_CHANNEL(channel), NULL);

	list = NULL;
	g_hash_table_foreach(channel->nicks, (GHFunc) get_nicks_hash, &list);
	return list;
}
Exemplo n.º 15
0
static void event_text(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
{
	char *line, *str, *target;

	g_return_if_fail(data != NULL);

	if (item == NULL)
		return;

	if (*data == '\0') {
		/* empty line, forget it. */
                signal_stop();
		return;
	}

	line = settings_get_bool("expand_escapes") ?
		expand_escapes(data, server, item) : g_strdup(data);

	/* check for automatic nick completion */
	if (completion_auto && IS_CHANNEL(item)) {
		str = auto_complete(CHANNEL(item), line);
		if (str != NULL) {
			g_free(line);
                        line = str;
		}
	}

	/* the nick is quoted in case it contains '-' character. also
	   spaces should work too now :) The nick is also escaped in case
	   it contains '\' characters */
	target = escape_string(window_item_get_target(item));
	str = g_strdup_printf(IS_CHANNEL(item) ? "-channel \"%s\" %s" :
			      IS_QUERY(item) ? "-nick \"%s\" %s" : "%s %s",
			      target, line);
	g_free(target);

	signal_emit("command msg", 3, str, server, item);

	g_free(str);
	g_free(line);

	signal_stop();
}
Exemplo n.º 16
0
static void signal_window_item_changed(WINDOW_REC *window, WI_ITEM_REC *item)
{
	g_return_if_fail(window != NULL);
	if (item == NULL) return;

	if (g_slist_length(window->items) > 1 && IS_CHANNEL(item)) {
		printformat(item->server, item->name, MSGLEVEL_CLIENTNOTICE,
			    IRCTXT_TALKING_IN, item->name);
                signal_stop();
	}
}
Exemplo n.º 17
0
Arquivo: nicklist.c Projeto: GPF/irssi
NICK_REC *nicklist_find_unique(CHANNEL_REC *channel, const char *nick,
			       void *id)
{
	NICK_REC *rec;

	g_return_val_if_fail(IS_CHANNEL(channel), NULL);
	g_return_val_if_fail(nick != NULL, NULL);

	rec = g_hash_table_lookup(channel->nicks, nick);
	while (rec != NULL && rec->unique_id != id)
                rec = rec->next;

        return rec;
}
Exemplo n.º 18
0
char *
xmpp_get_dest(const char *cmd_dest, XMPP_SERVER_REC *server, WI_ITEM_REC *item)
{
	NICK_REC *nick;
	char *dest;

	if (cmd_dest == NULL || *cmd_dest == '\0')
		return IS_QUERY(item) ? g_strdup(QUERY(item)->name)
		    : g_strconcat(server->jid, "/", server->resource, (void *)NULL);
	if (IS_CHANNEL(item)
	    && (nick = nicklist_find(CHANNEL(item), cmd_dest)) != NULL)
		return g_strdup(nick->host);
	if ((dest = rosters_resolve_name(server, cmd_dest)) != NULL)
		return dest;
	return g_strdup(cmd_dest);
}
Exemplo n.º 19
0
static void sig_complete_topic(GList **list, WINDOW_REC *window,
			       const char *word, const char *line,
			       int *want_space)
{
	const char *topic;

	g_return_if_fail(list != NULL);
	g_return_if_fail(word != NULL);

	if (*word == '\0' && IS_CHANNEL(window->active)) {
		topic = CHANNEL(window->active)->topic;
		if (topic != NULL) {
			*list = g_list_append(NULL, g_strdup(topic));
                        signal_stop();
		}
	}
}
Exemplo n.º 20
0
Arquivo: nicklist.c Projeto: GPF/irssi
GSList *nicklist_find_multiple(CHANNEL_REC *channel, const char *mask)
{
	GSList *nicks, *tmp, *next;

	g_return_val_if_fail(IS_CHANNEL(channel), NULL);
	g_return_val_if_fail(mask != NULL, NULL);

	nicks = nicklist_getnicks(channel);
	for (tmp = nicks; tmp != NULL; tmp = next) {
		NICK_REC *nick = tmp->data;

		next = tmp->next;
		if (!mask_match_address(channel->server, mask,
					nick->nick, nick->host))
                        nicks = g_slist_remove(nicks, tmp->data);
	}

	return nicks;
}
Exemplo n.º 21
0
static void
sig_complete_word(GList **list, WINDOW_REC *window, const char *word,
    const char *linestart, int *want_space)
{
	XMPP_SERVER_REC *server;

	g_return_if_fail(list != NULL);
	g_return_if_fail(window != NULL);
	g_return_if_fail(word != NULL);
	if ((server = XMPP_SERVER(window->active_server)) == NULL)
		return;
	if (g_ascii_strncasecmp(linestart,
	    settings_get_str("cmdchars"), 1) == 0) {
		*list = g_list_concat(*list, get_nicks(server, *word == '"' ?
		    word+1 : word , TRUE, TRUE));
	} else if (!IS_CHANNEL(window->active))
		*list = g_list_concat(*list, get_nicks(server, word, FALSE,
		    TRUE));
}
Exemplo n.º 22
0
static void sig_complete_topic_plus(GList **list, WINDOW_REC *window,
                                    const char *word, const char *line,
                                    int *want_space)
{
	char *p;

	char *topic;
	int topic_len;

	const char *mark;
	int mark_len;

	g_return_if_fail(list != NULL);
	g_return_if_fail(word != NULL);

	if (*word == '\0' && IS_CHANNEL(window->active)) {
		topic = g_strdup(CHANNEL(window->active)->topic);
		if (topic != NULL) {
			mark = settings_get_str("mark_encrypted");
			if (!IsNULLorEmpty(mark)) {
				topic_len = strlen(topic);
				mark_len = strlen(mark);
				if (settings_get_int("mark_position") == 0) { // suffix
					p = topic + (topic_len - mark_len);
					if (strncmp(p, mark, mark_len) == 0) {
						*p = '\0'; // Remove mark
					}
				}
				else { // prefix
					if (strncmp(topic, mark, mark_len) == 0) {
						g_memmove(topic, topic + mark_len, topic_len - mark_len);
					}
				}
			}

			*list = g_list_append(NULL, topic);
			signal_stop();
		}
	}
}
Exemplo n.º 23
0
/* SYNTAX: ME <message> */
static void
cmd_me(const char *data, XMPP_SERVER_REC *server, WI_ITEM_REC *item)
{
	const char *target;
	char *str, *recoded;
	int type;

	CMD_XMPP_SERVER(server);
	if (*data == '\0')
		return;
	g_strstrip((char *)data);
	if (*data == '\0')
		return;
	target = window_item_get_target(item);
	type = IS_CHANNEL(item) ? SEND_TARGET_CHANNEL : SEND_TARGET_NICK;
	if (type == SEND_TARGET_NICK)
		signal_emit("message xmpp own_action", 4, server, data, target,
		    SEND_TARGET_NICK);
	str = g_strconcat("/me ", data, (void *)NULL);
	recoded = recode_out(SERVER(server), str, target);
	g_free(str);
	server->send_message(SERVER(server), target, recoded, type);
	g_free(recoded);
}
Exemplo n.º 24
0
/* modes of current channel, if any */
static char *expando_chanmode(SERVER_REC *server, void *item, int *free_ret)
{
	return !IS_CHANNEL(item) ? NULL : CHANNEL(item)->mode;
}
Exemplo n.º 25
0
/* convert _underlined_, /italics/, and *bold* words (and phrases) to use real
   underlining or bolding */
char *expand_emphasis(WI_ITEM_REC *item, const char *text)
{
	GString *str;
	char *ret;
	int pos;
	int emphasis_italics;

        g_return_val_if_fail(text != NULL, NULL);

	emphasis_italics = settings_get_bool("emphasis_italics");

	str = g_string_new(text);

	for (pos = 0; pos < str->len; pos++) {
		char type, *bgn, *end;

		bgn = str->str + pos;

		if (*bgn == '*')
			type = 2; /* bold */
		else if (*bgn == '/' && emphasis_italics)
			type = 29; /* italics */
		else if (*bgn == '_')
			type = 31; /* underlined */
		else
			continue;

		/* check that the beginning marker starts a word, and
		   that the matching end marker ends a word */
		if ((pos > 0 && bgn[-1] != ' ') || !ishighalnum(bgn[1]))
			continue;
		if ((end = strchr(bgn+1, *bgn)) == NULL)
			continue;
		if (!ishighalnum(end[-1]) || ishighalnum(end[1]) ||
		    end[1] == type || end[1] == '*' || end[1] == '_' ||
		    /* special case for italics to not emphasise
		       common paths by skipping /.../.X */
		    (type == 29 && i_ispunct(end[1]) && ishighalnum(end[2])))
			continue;

		if (IS_CHANNEL(item)) {
			/* check that this isn't a _nick_, we don't want to
			   use emphasis on them. */
			int found;
                        char c;
			char *end2;

			/* check if _foo_ is a nick */
			c = end[1];
                        end[1] = '\0';
                        found = nicklist_find(CHANNEL(item), bgn) != NULL;
			end[1] = c;
			if (found) continue;

			/* check if the whole 'word' (e.g. "_foo_^") is a nick
			   in "_foo_^ ", end will be the second _, end2 the ^ */
			end2 = end;
			while (isnickchar(end2[1]))
				end2++;
			c = end2[1];
			end2[1] = '\0';
			found = nicklist_find(CHANNEL(item), bgn) != NULL;
			end2[1] = c;
			if (found) continue;
		}

		/* allow only *word* emphasis, not *multiple words* */
		if (!settings_get_bool("emphasis_multiword")) {
			char *c;
			for (c = bgn+1; c != end; c++) {
				if (!ishighalnum(*c))
					break;
			}
			if (c != end) continue;
		}

		if (settings_get_bool("emphasis_replace")) {
			*bgn = *end = type;
                        pos += (end-bgn);
		} else {
			g_string_insert_c(str, pos, type);
                        pos += (end - bgn) + 2;
			g_string_insert_c(str, pos++, type);
		}
	}

	ret = str->str;
	g_string_free(str, FALSE);
	return ret;
}
Exemplo n.º 26
0
/* if you are a channel operator in $C, expands to a '@' */
static char *expando_chanop(SERVER_REC *server, void *item, int *free_ret)
{
	return IS_CHANNEL(item) && CHANNEL(item)->chanop ? "@" : "";
}
Exemplo n.º 27
0
/* SYNTAX: NAMES [-count | -ops -halfops -voices -normal] [<channels> | **] */
static void cmd_names(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
{
	CHANNEL_REC *chanrec;
	GHashTable *optlist;
        GString *unknowns;
	char *channel, **channels, **tmp;
        int flags;
	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, 1 | PARAM_FLAG_OPTIONS,
			    "names", &optlist, &channel))
		return;

	if (strcmp(channel, "*") == 0 || *channel == '\0') {
		if (!IS_CHANNEL(item))
                        cmd_param_error(CMDERR_NOT_JOINED);

		channel = CHANNEL(item)->name;
	}

	flags = 0;
	if (g_hash_table_lookup(optlist, "ops") != NULL)
		flags |= CHANNEL_NICKLIST_FLAG_OPS;
	if (g_hash_table_lookup(optlist, "halfops") != NULL)
		flags |= CHANNEL_NICKLIST_FLAG_HALFOPS;
	if (g_hash_table_lookup(optlist, "voices") != NULL)
		flags |= CHANNEL_NICKLIST_FLAG_VOICES;
	if (g_hash_table_lookup(optlist, "normal") != NULL)
		flags |= CHANNEL_NICKLIST_FLAG_NORMAL;
	if (g_hash_table_lookup(optlist, "count") != NULL)
		flags |= CHANNEL_NICKLIST_FLAG_COUNT;

        if (flags == 0) flags = CHANNEL_NICKLIST_FLAG_ALL;

        unknowns = g_string_new(NULL);

	channels = g_strsplit(channel, ",", -1);
	for (tmp = channels; *tmp != NULL; tmp++) {
		chanrec = channel_find(server, *tmp);
		if (chanrec == NULL)
			g_string_sprintfa(unknowns, "%s,", *tmp);
		else {
			fe_channels_nicklist(chanrec, flags);
			signal_stop();
		}
	}
	g_strfreev(channels);

	if (unknowns->len > 1)
                g_string_truncate(unknowns, unknowns->len-1);

	if (unknowns->len > 0 && strcmp(channel, unknowns->str) != 0)
                signal_emit("command names", 3, unknowns->str, server, item);
        g_string_free(unknowns, TRUE);

	cmd_params_free(free_arg);
}
Exemplo n.º 28
0
/* redraw channel */
static void statusbar_channel(SBAR_ITEM_REC *item, int ypos)
{
    WINDOW_REC *window;
    WI_ITEM_REC *witem;
    CHANNEL_REC *channel;
    SERVER_REC *server;
    gchar channame[21], winnum[MAX_INT_STRLEN], *tmpname;
    int size_needed;
    int mode_size;

    window = item->bar->pos != STATUSBAR_POS_MIDDLE ? active_win :
            mainwindow_find_sbar(item);
    server = window == NULL ? NULL : window->active_server;

    ltoa(winnum, window == NULL ? 0 : window->refnum);

    witem = window != NULL && (IS_CHANNEL(window->active) || IS_QUERY(window->active)) ?
	    window->active : NULL;
    if (witem == NULL)
    {
	/* display server tag */
        channame[0] = '\0';
	mode_size = 0;
	channel = NULL;

	size_needed = 3 + strlen(winnum) + (server == NULL ? 0 : (17+strlen(server->tag)));
    }
    else
    {
	/* display channel + mode */
        tmpname = show_lowascii(witem->name);
        strncpy(channame, tmpname, 20); channame[20] = '\0';
        g_free(tmpname);

	channel = CHANNEL(witem);
	if (channel == NULL) {
                mode_size = 0;
	} else {
		mode_size = strlen(channel->mode);
		if (mode_size > 0) mode_size += 3; /* (+) */
	}

	size_needed = 3 + strlen(winnum) + strlen(channame) + mode_size;
    }

    if (item->size != size_needed)
    {
        /* we need more (or less..) space! */
        statusbar_item_resize(item, size_needed);
        return;
    }

    move(ypos, item->xpos);
    set_color(stdscr, sbar_color_dim); addch('[');

    /* window number */
    set_color(stdscr, sbar_color_normal); addstr(winnum);
    set_color(stdscr, sbar_color_dim); addch(':');

    if (channame[0] == '\0' && server != NULL)
    {
	/* server tag */
	set_color(stdscr, sbar_color_normal); addstr(server->tag);
        addstr(" (change with ^X)");
    }
    else if (channame[0] != '\0')
    {
	/* channel + mode */
	set_color(stdscr, sbar_color_normal); addstr(channame);
	if (mode_size)
	{
	    set_color(stdscr, sbar_color_bold); addch('(');
	    set_color(stdscr, sbar_color_dim); addch('+');
	    set_color(stdscr, sbar_color_normal); addstr(channel->mode);
	    set_color(stdscr, sbar_color_bold); addch(')');
	}
    }
    set_color(stdscr, sbar_color_dim); addch(']');
    screen_refresh(NULL);
}
Exemplo n.º 29
0
/* convert _underlined_ and *bold* words (and phrases) to use real
   underlining or bolding */
char *expand_emphasis(WI_ITEM_REC *item, const char *text)
{
	GString *str;
	char *ret;
	int pos;

        g_return_val_if_fail(text != NULL, NULL);

	str = g_string_new(text);

	for (pos = 0; pos < str->len; pos++) {
		char type, *bgn, *end;

		bgn = str->str + pos;

		if (*bgn == '*') 
			type = 2; /* bold */
		else if (*bgn == '_') 
			type = 31; /* underlined */
		else
			continue;

		/* check that the beginning marker starts a word, and
		   that the matching end marker ends a word */
		if ((pos > 0 && !i_isspace(bgn[-1])) || !ishighalnum(bgn[1]))
			continue;
		if ((end = strchr(bgn+1, *bgn)) == NULL)
			continue;
		if (!ishighalnum(end[-1]) || ishighalnum(end[1]) ||
		    end[1] == type || end[1] == '*' || end[1] == '_')
			continue;

		if (IS_CHANNEL(item)) {
			/* check that this isn't a _nick_, we don't want to
			   use emphasis on them. */
			int found;
                        char c;

			c = end[1];
                        end[1] = '\0';
                        found = nicklist_find(CHANNEL(item), bgn) != NULL;
			end[1] = c;
			if (found) continue;
		}

		/* allow only *word* emphasis, not *multiple words* */
		if (!settings_get_bool("emphasis_multiword")) {
			char *c;
			for (c = bgn+1; c != end; c++) {
				if (!ishighalnum(*c))
					break;
			}
			if (c != end) continue;
		}

		if (settings_get_bool("emphasis_replace")) {
			*bgn = *end = type;
                        pos += (end-bgn);
		} else {
			g_string_insert_c(str, pos, type);
                        pos += (end - bgn) + 2;
			g_string_insert_c(str, pos++, type);
		}
	}

	ret = str->str;
	g_string_free(str, FALSE);
	return ret;
}
Exemplo n.º 30
0
/* SYNTAX: MSG [-<server tag>] [-channel | -nick] <targets> <message> */
static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
{
	GHashTable *optlist;
	char *target, *origtarget, *msg;
	void *free_arg;
	int free_ret, target_type = SEND_TARGET_NICK;

	g_return_if_fail(data != NULL);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST,
			    "msg", &optlist, &target, &msg))
		return;
	if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	server = cmd_options_get_server("msg", optlist, server);
	if (server == NULL || !server->connected)
		cmd_param_error(CMDERR_NOT_CONNECTED);

        origtarget = target;
	free_ret = FALSE;
	if (strcmp(target, ",") == 0 || strcmp(target, ".") == 0) {
		target = parse_special(&target, server, item,
				       NULL, &free_ret, NULL, 0);
		if (target != NULL && *target == '\0') {
			if (free_ret)
				g_free(target);
			target = NULL;
			free_ret = FALSE;
		}
	}

	if (target != NULL) {
		if (strcmp(target, "*") == 0) {
                        /* send to active channel/query */
			if (item == NULL)
				cmd_param_error(CMDERR_NOT_JOINED);

			target_type = IS_CHANNEL(item) ?
				SEND_TARGET_CHANNEL : SEND_TARGET_NICK;
			target = (char *) window_item_get_target(item);
		} else if (g_hash_table_lookup(optlist, "channel") != NULL)
                        target_type = SEND_TARGET_CHANNEL;
		else if (g_hash_table_lookup(optlist, "nick") != NULL)
			target_type = SEND_TARGET_NICK;
		else {
			/* Need to rely on server_ischannel(). If the protocol
			   doesn't really know if it's channel or nick based on
			   the name, it should just assume it's nick, because
			   when typing text to channels it's always sent with
			   /MSG -channel. */
			target_type = server_ischannel(server, target) ?
				SEND_TARGET_CHANNEL : SEND_TARGET_NICK;
		}
	}
	if (target != NULL) {
		char **splitmsgs;
		char **tmp = NULL;
		char *singlemsg[] = { msg, NULL };
		char *m;
		int n = 0;

		/*
		 * If split_message is NULL, the server doesn't need to split
		 * long messages.
		 */
		if (server->split_message != NULL)
			splitmsgs = tmp = server->split_message(server, target,
								msg);
		else
			splitmsgs = singlemsg;

		while ((m = splitmsgs[n++])) {
			signal_emit("server sendmsg", 4, server, target, m,
				    GINT_TO_POINTER(target_type));
			signal_emit(target_type == SEND_TARGET_CHANNEL ?
				    "message own_public" :
				    "message own_private", 4, server, m,
				    target, origtarget);
		}
		g_strfreev(tmp);
	} else {
		signal_emit("message own_private", 4, server, msg, target,
			    origtarget);
	}

	if (free_ret && target != NULL) g_free(target);
	cmd_params_free(free_arg);
}