Beispiel #1
0
/* SYNTAX: HILIGHT [-nick | -nonick] [-mask | -regexp | -word]
                   [-color <color>] [-level <level>]
		   [-channels <channels>] <text> */
static void cmd_hilight(const char *data)
{
        GHashTable *optlist;
	HILIGHT_REC *rec;
	char *colorarg, *levelarg, *chanarg, *text;
	char **channels;
	void *free_arg;

	g_return_if_fail(data != NULL);

	if (*data == '\0') {
		cmd_hilight_show();
		return;
	}

	if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_GETREST, "hilight", &optlist, &text))
		return;

	chanarg = g_hash_table_lookup(optlist, "channels");
	levelarg = g_hash_table_lookup(optlist, "level");
	colorarg = g_hash_table_lookup(optlist, "color");

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

	channels = (chanarg == NULL || *chanarg == '\0') ? NULL :
		g_strsplit(replace_chars(chanarg, ',', ' '), " ", -1);

	rec = hilight_find(text, channels);
	if (rec == NULL) {
		rec = g_new0(HILIGHT_REC, 1);

		rec->text = g_strdup(text);
		rec->channels = channels;
	} else {
                g_free_and_null(rec->color);
		g_strfreev(channels);

                hilight_remove_config(rec);
		hilights = g_slist_remove(hilights, rec);
	}

	rec->level = (levelarg == NULL || *levelarg == '\0') ? 0 :
		level2bits(replace_chars(levelarg, ',', ' '));
	rec->nick = settings_get_bool("hilight_only_nick") &&
		(rec->level == 0 || (rec->level & DEFAULT_HILIGHT_LEVEL) == rec->level) ?
		g_hash_table_lookup(optlist, "nonick") == NULL :
		g_hash_table_lookup(optlist, "nick") != NULL;
	rec->nickmask = g_hash_table_lookup(optlist, "mask") != NULL;
	rec->fullword = g_hash_table_lookup(optlist, "word") != NULL;
	rec->regexp = g_hash_table_lookup(optlist, "regexp") != NULL;

	if (colorarg != NULL && *colorarg != '\0')
		rec->color = g_strdup(colorarg);

	hilights = g_slist_append(hilights, rec);
	hilight_add_config(rec);

	hilight_print(g_slist_index(hilights, rec)+1, rec);
        cmd_params_free(free_arg);
}
Beispiel #2
0
static void cmd_completion(const char *data)
{
	GHashTable *optlist;
	CONFIG_NODE *node;
	GSList *tmp;
	char *key, *value;
	void *free_arg;
	int len;

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_GETREST,
			    "completion", &optlist, &key, &value))
		return;

	node = iconfig_node_traverse("completions", *value != '\0');
	if (node != NULL && node->type != NODE_TYPE_BLOCK) {
		/* FIXME: remove after 0.8.5 */
		iconfig_node_remove(mainconfig->mainnode, node);
		node = iconfig_node_traverse("completions", *value != '\0');
	}

	if (node == NULL || (node->value == NULL && *value == '\0')) {
		printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
			    TXT_NO_COMPLETIONS);
		cmd_params_free(free_arg);
		return;
	}

	if (g_hash_table_lookup(optlist, "delete") != NULL && *key != '\0') {
		printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
			    TXT_COMPLETION_REMOVED, key);

		iconfig_set_str("completions", key, NULL);
		signal_emit("completion removed", 1, key);
	} else if (*key != '\0' && *value != '\0') {
		int automatic = g_hash_table_lookup(optlist, "auto") != NULL;

		node = config_node_section(node, key, NODE_TYPE_BLOCK);
		iconfig_node_set_str(node, "value", value);
		if (automatic)
			iconfig_node_set_bool(node, "auto", TRUE);
		else
			iconfig_node_set_str(node, "auto", NULL);

		printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
			    TXT_COMPLETION_LINE,
			    key, value, automatic ? "yes" : "no");

		signal_emit("completion added", 1, key);
	} else {
		printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
			    TXT_COMPLETION_HEADER);

		len = strlen(key);
		for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
			node = tmp->data;

			if (len == 0 ||
			    g_strncasecmp(node->key, key, len) == 0) {
				printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
					    TXT_COMPLETION_LINE, node->key,
					    config_node_get_str(node, "value", ""),
					    config_node_get_bool(node, "auto", FALSE) ? "yes" : "no");
			}
		}

		printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
			    TXT_COMPLETION_FOOTER);
	}

	cmd_params_free(free_arg);
}
Beispiel #3
0
/* SYNTAX: STATUSBAR ADD|MODIFY [-disable | -nodisable] [-type window|root]
           [-placement top|bottom] [-position #] [-visible always|active|inactive] <statusbar> */
static void cmd_statusbar_add_modify(const char *data, void *server, void *witem)
{
	GHashTable *optlist;
	CONFIG_NODE *node;
	char *name, *type, *placement, *visible;
	void *free_arg;
	int error;
	int add = GPOINTER_TO_INT(signal_get_user_data());

	if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS,
	                    "statusbar add", &optlist, &name))
		return;

	if (*name == '\0') {
		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
	}

	error = 0;

	type = NULL;
	data = g_hash_table_lookup(optlist, "type");
	if (data != NULL) {
		if (g_ascii_strcasecmp(data, "window") == 0)
			type = "window";
		else if (g_ascii_strcasecmp(data, "root") == 0)
			type = "root";
		else {
			printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_UNKNOWN_TYPE,
			            data);
			error++;
		}
	}

	placement = NULL;
	data = g_hash_table_lookup(optlist, "placement");
	if (data != NULL) {
		if (g_ascii_strcasecmp(data, "top") == 0)
			placement = "top";
		else if (g_ascii_strcasecmp(data, "bottom") == 0)
			placement = "bottom";
		else {
			printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
			            TXT_STATUSBAR_UNKNOWN_PLACEMENT, data);
			error++;
		}
	}

	visible = NULL;
	data = g_hash_table_lookup(optlist, "visible");
	if (data != NULL) {
		if (g_ascii_strcasecmp(data, "always") == 0)
			visible = "always";
		else if (g_ascii_strcasecmp(data, "active") == 0)
			visible = "active";
		else if (g_ascii_strcasecmp(data, "inactive") == 0)
			visible = "inactive";
		else {
			printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
			            TXT_STATUSBAR_UNKNOWN_VISIBILITY, data);
			error++;
		}
	}

	if (!error) {
		node = sbar_node(name, add);
		if (node == NULL && !add && sbar_node_isdefault(name)) {
			/* If this node is a default status bar, we need to create it in the config
			 * to configure it */
			node = sbar_node(name, TRUE);
		}

		if (node == NULL) {
			printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, name);
			error++;
		}
	}

	if (error) {
		cmd_params_free(free_arg);
		return;
	}

	if (g_hash_table_lookup(optlist, "nodisable"))
		iconfig_node_set_str(node, "disabled", NULL);
	if (g_hash_table_lookup(optlist, "disable"))
		iconfig_node_set_bool(node, "disabled", TRUE);
	if (type != NULL)
		iconfig_node_set_str(node, "type", type);
	if (placement != NULL)
		iconfig_node_set_str(node, "placement", placement);
	data = g_hash_table_lookup(optlist, "position");
	if (data != NULL)
		iconfig_node_set_int(node, "position", atoi(data));
	if (visible != NULL)
		iconfig_node_set_str(node, "visible", visible);

	read_statusbar_config();
	cmd_params_free(free_arg);
}
Beispiel #4
0
/* SYNTAX: QUERY [-window] [-<server tag>] <nick> [<message>] */
static void cmd_query(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
{
	GHashTable *optlist;
	QUERY_REC *query;
	char *nick, *msg;
	void *free_arg;

	g_return_if_fail(data != NULL);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST |
			    PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS,
			    "query", &optlist, &nick, &msg))
		return;

	if (*nick == '\0') {
		/* remove current query */
		cmd_unquery("", server, item);
		cmd_params_free(free_arg);
                return;
	}

	server = cmd_options_get_server("query", optlist, server);
	if (server == NULL) {
		cmd_params_free(free_arg);
                return;
	}

	if (*nick != '=' && (server == NULL || !server->connected))
		cmd_param_error(CMDERR_NOT_CONNECTED);

	if (g_hash_table_lookup(optlist, "window") != NULL) {
		signal_add("query created",
			   (SIGNAL_FUNC) signal_query_created_curwin);
	}

	query = query_find(server, nick);
	if (query == NULL)
		query = CHAT_PROTOCOL(server)->
			query_create(server->tag, nick, FALSE);
	else {
		/* query already exists, set it active */
		WINDOW_REC *window = window_item_window(query);

		if (window != active_win)
			window_set_active(window);
		window_item_set_active(active_win, (WI_ITEM_REC *) query);
	}

	if (g_hash_table_lookup(optlist, "window") != NULL) {
		signal_remove("query created",
			      (SIGNAL_FUNC) signal_query_created_curwin);
	}

	if (*msg != '\0') {
                msg = g_strdup_printf("-nick %s %s", nick, msg);
		signal_emit("command msg", 3, msg, server, query);
                g_free(msg);
	}

	cmd_params_free(free_arg);
}
Beispiel #5
0
/* Handle incoming DCC CTCP messages */
static void dcc_ctcp_msg(char *data, IRC_SERVER_REC *server, char *sender, char *sendaddr, char *target, DCC_REC *chat)
{
    char *type, *arg, *addrstr, *portstr, *sizestr, *str;
    void *free_arg;
    const char *cstr;
    DCC_REC *dcc;
    long size;
    int port;

    g_return_if_fail(data != NULL);
    g_return_if_fail(sender != NULL);

    if (!cmd_get_params(data, &free_arg, 5 | PARAM_FLAG_NOQUOTES,
			&type, &arg, &addrstr, &portstr, &sizestr))
	    return;

    if (sscanf(portstr, "%d", &port) != 1) port = 0;
    if (sscanf(sizestr, "%ld", &size) != 1) size = 0;

    dcc = dcc_create(SWAP_SENDGET(dcc_str2type(type)), -1, sender, arg, server, chat);
    dcc_get_address(addrstr, &dcc->addr);
    net_ip2host(&dcc->addr, dcc->addrstr);
    dcc->port = port;
    dcc->size = size;

    switch (dcc->type)
    {
	case DCC_TYPE_GET:
	    cstr = settings_get_str("dcc_autoget_masks");
	    /* check that autoget masks match */
	    if (settings_get_bool("dcc_autoget") && (*cstr == '\0' || masks_match(SERVER(server), cstr, sender, sendaddr)) &&
                /* check file size limit, FIXME: it's possible to send a bogus file size and then just send what ever sized file.. */
		(settings_get_int("dcc_max_autoget_size") <= 0 || (settings_get_int("dcc_max_autoget_size") > 0 && size <= settings_get_int("dcc_max_autoget_size")*1024)))
            {
                /* automatically get */
                str = g_strdup_printf("GET %s %s", dcc->nick, dcc->arg);
                signal_emit("command dcc", 2, str, server);
                g_free(str);
            }
            else
            {
                /* send request */
                signal_emit("dcc request", 1, dcc);
            }
            break;

	case DCC_TYPE_CHAT:
	    cstr = settings_get_str("dcc_autochat_masks");
	    if (*cstr != '\0' && masks_match(SERVER(server), cstr, sender, sendaddr))
	    {
                /* automatically accept chat */
                str = g_strdup_printf("CHAT %s", dcc->nick);
                signal_emit("command dcc", 2, str, server);
                g_free(str);
	    }
	    else
	    {
		/* send request */
		signal_emit("dcc request", 1, dcc);
	    }
	    break;

	case DCC_TYPE_RESUME:
	case DCC_TYPE_ACCEPT:
            /* handle this in dcc-files.c */
            dcc_destroy(dcc);
            break;

        default:
            /* unknown DCC command */
            signal_emit("dcc unknown ctcp", 3, data, sender, sendaddr);
            dcc_destroy(dcc);
            break;
    }

    cmd_params_free(free_arg);
}
Beispiel #6
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, *recoded;
	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;
		}
	}
	recoded = recode_out(server, msg, target);
	if (target != NULL) {
		signal_emit("server sendmsg", 4, server, target, recoded,
			    GINT_TO_POINTER(target_type));
	}
	signal_emit(target != NULL && target_type == SEND_TARGET_CHANNEL ?
		    "message own_public" : "message own_private", 4,
		    server, recoded, target, origtarget);
		    
	g_free(recoded);
	if (free_ret && target != NULL) g_free(target);
	cmd_params_free(free_arg);
}
Beispiel #7
0
/* SYNTAX: IRCNET ADD [-kicks <count>] [-msgs <count>] [-modes <count>]
	              [-whois <count>] [-cmdspeed <ms>] [-cmdmax <count>]
		      [-nick <nick>] [-user <user>] [-realname <name>]
		      [-host <host>] [-autosendcmd <cmd>] <name> */
static void cmd_ircnet_add(const char *data)
{
	GHashTable *optlist;
	char *name, *value;
	void *free_arg;
	IRCNET_REC *rec;

	if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS,
			    "ircnet add", &optlist, &name))
		return;
	if (*name == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	rec = ircnet_find(name);
	if (rec == NULL) {
		rec = g_new0(IRCNET_REC, 1);
		rec->name = g_strdup(name);
	} else {
		if (g_hash_table_lookup(optlist, "nick")) g_free_and_null(rec->nick);
		if (g_hash_table_lookup(optlist, "user")) g_free_and_null(rec->username);
		if (g_hash_table_lookup(optlist, "realname")) g_free_and_null(rec->realname);
		if (g_hash_table_lookup(optlist, "host")) {
			g_free_and_null(rec->own_host);
                        rec->own_ip = NULL;
		}
		if (g_hash_table_lookup(optlist, "autosendcmd")) g_free_and_null(rec->autosendcmd);
	}

	value = g_hash_table_lookup(optlist, "kicks");
	if (value != NULL) rec->max_kicks = atoi(value);
	value = g_hash_table_lookup(optlist, "msgs");
	if (value != NULL) rec->max_msgs = atoi(value);
	value = g_hash_table_lookup(optlist, "modes");
	if (value != NULL) rec->max_modes = atoi(value);
	value = g_hash_table_lookup(optlist, "whois");
	if (value != NULL) rec->max_whois = atoi(value);

	value = g_hash_table_lookup(optlist, "cmdspeed");
	if (value != NULL) rec->cmd_queue_speed = atoi(value);
	value = g_hash_table_lookup(optlist, "cmdmax");
	if (value != NULL) rec->max_cmds_at_once = atoi(value);

	value = g_hash_table_lookup(optlist, "nick");
	if (value != NULL && *value != '\0') rec->nick = g_strdup(value);
	value = g_hash_table_lookup(optlist, "user");
	if (value != NULL && *value != '\0') rec->username = g_strdup(value);
	value = g_hash_table_lookup(optlist, "realname");
	if (value != NULL && *value != '\0') rec->realname = g_strdup(value);

	value = g_hash_table_lookup(optlist, "host");
	if (value != NULL && *value != '\0') {
		rec->own_host = g_strdup(value);
		rec->own_ip = NULL;
	}

	value = g_hash_table_lookup(optlist, "autosendcmd");
	if (value != NULL && *value != '\0') rec->autosendcmd = g_strdup(value);

	ircnet_create(rec);
	printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_IRCNET_ADDED, name);

	cmd_params_free(free_arg);
}
Beispiel #8
0
/* SYNTAX: DCC CHAT [-passive] [<nick>] */
static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server)
{
	void *free_arg;
	CHAT_DCC_REC *dcc;
	IPADDR own_ip;
	GIOChannel *handle;
	GHashTable *optlist;
	int p_id;
	char *nick, host[MAX_IP_LEN];
	int port;

	g_return_if_fail(data != NULL);

	if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS,
			    "dcc chat", &optlist, &nick))
		return;

	if (*nick == '\0') {
		dcc = DCC_CHAT(dcc_find_request_latest(DCC_CHAT_TYPE));
		if (dcc != NULL) {
			if (!dcc_is_passive(dcc))
				dcc_chat_connect(dcc);
			else
				dcc_chat_passive(dcc);
		}
		cmd_params_free(free_arg);
		return;
	}

	dcc = dcc_chat_find_id(nick);
	if (dcc != NULL && dcc_is_waiting_user(dcc)) {
		if (!dcc_is_passive(dcc)) {
			/* found from dcc chat requests,
			   we're the connecting side */
			dcc_chat_connect(dcc);
		} else {
			/* We are accepting a passive DCC CHAT. */
			dcc_chat_passive(dcc);
		}
		cmd_params_free(free_arg);
		return;
	}

	if (dcc != NULL && dcc_is_listening(dcc) &&
	    dcc->server == server) {
		/* sending request again even while old request is
		   still waiting, remove it. */
		dcc_destroy(DCC(dcc));
	}

	if (!IS_IRC_SERVER(server) || !server->connected)
		cmd_param_error(CMDERR_NOT_CONNECTED);

	dcc = dcc_chat_create(server, NULL, nick, "chat");
	if (dcc == NULL) {
		cmd_params_free(free_arg);
		g_warn_if_reached();
		return;
	}

	if (g_hash_table_lookup(optlist, "passive") == NULL) {
		/* Standard DCC CHAT... let's listen for incoming connections */
		handle = dcc_listen(net_sendbuffer_handle(server->handle),
				    &own_ip, &port);
		if (handle == NULL)
			cmd_param_error(CMDERR_ERRNO);

		dcc->handle = handle;
		dcc->tagconn =
			g_input_add(dcc->handle, G_INPUT_READ,
				    (GInputFunction) dcc_chat_listen, dcc);

		/* send the chat request */
		signal_emit("dcc request send", 1, dcc);

		dcc_ip2str(&own_ip, host);
		irc_send_cmdv(server, "PRIVMSG %s :\001DCC CHAT CHAT %s %d\001",
			      nick, host, port);
	} else {
		/* Passive protocol... we want the other side to listen */
		/* send the chat request */
		dcc->port = 0;
		signal_emit("dcc request send", 1, dcc);

		/* generate a random id */
		p_id = rand() % 64;
		dcc->pasv_id = p_id;

		/* 16843009 is the long format of 1.1.1.1, we use a fake IP
		   since the other side shouldn't care of it: they will send
		   the address for us to connect to in the reply */
		irc_send_cmdv(server,
			      "PRIVMSG %s :\001DCC CHAT CHAT 16843009 0 %d\001",
			      nick, p_id);
	}
	cmd_params_free(free_arg);
}
Beispiel #9
0
/* NOTE: -network replaces the old -ircnet flag. */
static void cmd_ignore(const char *data)
{
    GHashTable *optlist;
    IGNORE_REC *rec;
    char *patternarg, *chanarg, *mask, *levels, *timestr, *servertag;
    char **channels;
    void *free_arg;
    int new_ignore, msecs, level;

    if (*data == '\0') {
        cmd_ignore_show();
        return;
    }

    if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS |
                        PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS,
                        "ignore", &optlist, &mask, &levels))
        return;

    patternarg = g_hash_table_lookup(optlist, "pattern");
    chanarg = g_hash_table_lookup(optlist, "channels");
    servertag = g_hash_table_lookup(optlist, "network");
    /* Allow -ircnet for backwards compatibility */
    if (!servertag)
        servertag = g_hash_table_lookup(optlist, "ircnet");

    if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
    if (*levels == '\0') levels = "ALL";
    level = level2bits(levels, NULL);

    msecs = 0;
    timestr = g_hash_table_lookup(optlist, "time");
    if (timestr != NULL) {
        if (!parse_time_interval(timestr, &msecs))
            cmd_param_error(CMDERR_INVALID_TIME);
    }

    if (active_win->active_server != NULL &&
            server_ischannel(active_win->active_server, mask)) {
        chanarg = mask;
        mask = NULL;
    }
    channels = (chanarg == NULL || *chanarg == '\0') ? NULL :
               g_strsplit(chanarg, ",", -1);

    rec = patternarg != NULL ? NULL: ignore_find_noact(servertag, mask, channels,
            (level & MSGLEVEL_NO_ACT));
    new_ignore = rec == NULL;

    if (rec == NULL) {
        rec = g_new0(IGNORE_REC, 1);

        rec->mask = mask == NULL || *mask == '\0' ||
                    g_strcmp0(mask, "*") == 0 ? NULL : g_strdup(mask);
        rec->channels = channels;
    } else {
        g_free_and_null(rec->pattern);
        g_strfreev(channels);
    }

    rec->level = combine_level(rec->level, levels);

    if (rec->level == MSGLEVEL_NO_ACT) {
        /* If only NO_ACT was specified add all levels; it makes no
         * sense on its own. */
        rec->level |= MSGLEVEL_ALL;
    }

    if (new_ignore && rec->level == 0) {
        /* tried to unignore levels from nonexisting ignore */
        printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
                    TXT_IGNORE_NOT_FOUND, rec->mask);
        g_free(rec->mask);
        g_strfreev(rec->channels);
        g_free(rec);
        cmd_params_free(free_arg);
        return;
    }
    rec->servertag = (servertag == NULL || *servertag == '\0') ?
                     NULL : g_strdup(servertag);
    rec->pattern = (patternarg == NULL || *patternarg == '\0') ?
                   NULL : g_strdup(patternarg);
    rec->exception = g_hash_table_lookup(optlist, "except") != NULL;
    rec->regexp = g_hash_table_lookup(optlist, "regexp") != NULL;
    rec->fullword = g_hash_table_lookup(optlist, "full") != NULL;
    rec->replies = g_hash_table_lookup(optlist, "replies") != NULL;
    if (msecs != 0)
        rec->unignore_time = time(NULL)+msecs/1000;

    if (new_ignore)
        ignore_add_rec(rec);
    else
        ignore_update_rec(rec);

    cmd_params_free(free_arg);
}
Beispiel #10
0
/* SYNTAX: WHOIS [-<server tag>] [<server>] [<nicks>] */
static void cmd_whois(const char *data, IRC_SERVER_REC *server,
                      WI_ITEM_REC *item)
{
	GHashTable *optlist;
	char *qserver, *query, *event_402, *str;
	void *free_arg;
	int free_nick;

	CMD_IRC_SERVER(server);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS |
	                    PARAM_FLAG_UNKNOWN_OPTIONS,
	                    "whois", &optlist, &qserver, &query))
		return;

	/* -<server tag> */
	server = IRC_SERVER(cmd_options_get_server("whois", optlist,
	                                           SERVER(server)));
	if (server == NULL) {
		cmd_params_free(free_arg);
		return;
	}

	if (*query == '\0') {
		query = qserver;
		qserver = "";
	}
	if (*query == '\0') {
		QUERY_REC *queryitem = QUERY(item);
		if (queryitem == NULL)
			query = server->nick;
		else
			query = qserver = queryitem->name;
	}

	if (g_strcmp0(query, "*") == 0 &&
	    g_hash_table_lookup(optlist, "yes") == NULL)
		cmd_param_error(CMDERR_NOT_GOOD_IDEA);

	event_402 = "event 402";
	if (*qserver == '\0')
		g_string_printf(tmpstr, "WHOIS %s", query);
	else {
		g_string_printf(tmpstr, "WHOIS %s %s", qserver, query);
		if (g_ascii_strcasecmp(qserver, query) == 0)
			event_402 = "whois event not found";
	}

	query = get_redirect_nicklist(query, &free_nick);

	str = g_strconcat(qserver, " ", query, NULL);
	server_redirect_event(server, "whois", 1, str, TRUE,
	              NULL,
	              "event 318", "whois end",
	              "event 402", event_402,
	              "event 301", "whois away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */
	              "event 313", "whois oper",
	              "event 401", (settings_get_bool("auto_whowas") ? "whois try whowas" : "whois event not found"),
	              "event 311", "whois event",
	              "", "whois default event", NULL);
	g_free(str);

	server->whois_found = FALSE;
	irc_send_cmd_split(server, tmpstr->str, 2, server->max_whois_in_cmd);

	if (free_nick) g_free(query);
	cmd_params_free(free_arg);
}
Beispiel #11
0
/* SYNTAX: KNOCKOUT [<time>] <nicks> <reason> */
static void cmd_knockout(const char *data, IRC_SERVER_REC *server,
                         IRC_CHANNEL_REC *channel)
{
	KNOCKOUT_REC *rec;
	char *nicks, *reason, *timeoutstr, *kickcmd, *bancmd, *recoded;
	char **nicklist, *spacenicks, *banmasks;
	void *free_arg;
	int timeleft;
	GSList *ptr;

	CMD_IRC_SERVER(server);

	if (!IS_IRC_CHANNEL(channel))
		cmd_return_error(CMDERR_NOT_JOINED);

	if (i_isdigit(*data)) {
		/* first argument is the timeout */
		if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST,
		                    &timeoutstr, &nicks, &reason))
                        return;

		if (!parse_time_interval(timeoutstr, &timeleft))
			cmd_param_error(CMDERR_INVALID_TIME);
	} else {
		if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST,
		                    &nicks, &reason))
			return;
                timeleft = settings_get_time("knockout_time");
	}

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

	nicklist = g_strsplit(nicks, ",", -1);
	spacenicks = g_strjoinv(" ", nicklist);
	g_strfreev(nicklist);

	banmasks = ban_get_masks(channel, spacenicks, 0);
	g_free(spacenicks);

	recoded = recode_out(SERVER(server), reason, channel->name);
	kickcmd = g_strdup_printf("%s %s %s", channel->name, nicks, recoded);
	g_free(recoded);

	bancmd = *banmasks == '\0'? NULL :
		g_strdup_printf("%s %s", channel->name, banmasks);

	if (settings_get_bool("kick_first_on_kickban")) {
		signal_emit("command kick", 3, kickcmd, server, channel);
		if (bancmd != NULL)
			signal_emit("command ban", 3, bancmd, server, channel);
	} else {
		if (bancmd != NULL)
			signal_emit("command ban", 3, bancmd, server, channel);
		signal_emit("command kick", 3, kickcmd, server, channel);
	}
	g_free(kickcmd);
	g_free_not_null(bancmd);

	if (*banmasks == '\0')
		g_free(banmasks);
	else {
		/* check if we already have this knockout */
		for (ptr = server->knockoutlist; ptr != NULL; ptr = ptr->next) {
			rec = ptr->data;
			if (channel == rec->channel &&
			    !g_strcmp0(rec->ban, banmasks))
				break;
		}
		if (ptr == NULL) {
			rec = g_new(KNOCKOUT_REC, 1);
			rec->channel = channel;
			rec->ban = banmasks;
			server->knockoutlist = g_slist_append(server->knockoutlist, rec);
		}
		rec->unban_time = time(NULL)+timeleft/1000;
	}

	cmd_params_free(free_arg);
}
Beispiel #12
0
static void cmd_server_add(const char *data)
{
        GHashTable *optlist;
	SERVER_SETUP_REC *rec;
	char *addr, *portstr, *password, *value, *chatnet;
	void *free_arg;
	int port;

	if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS,
			    "server add", &optlist, &addr, &portstr, &password))
		return;

	if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
	port = *portstr == '\0' ? DEFAULT_SERVER_ADD_PORT : atoi(portstr);

	chatnet = g_hash_table_lookup(optlist, "network");

	rec = server_setup_find(addr, port, chatnet);

	if (rec == NULL) {
		rec = create_server_setup(optlist);
		if (rec == NULL) {
			cmd_params_free(free_arg);
			return;
		}
		rec->address = g_strdup(addr);
		rec->port = port;
	} else {
		value = g_hash_table_lookup(optlist, "port");
		if (value != NULL && *value != '\0') rec->port = atoi(value);

		if (*password != '\0') g_free_and_null(rec->password);
		if (g_hash_table_lookup(optlist, "host")) {
			g_free_and_null(rec->own_host);
			rec->own_ip4 = rec->own_ip6 = NULL;
		}
	}

	if (g_hash_table_lookup(optlist, "6"))
		rec->family = AF_INET6;
        else if (g_hash_table_lookup(optlist, "4"))
		rec->family = AF_INET;

	if (g_hash_table_lookup(optlist, "ssl"))
		rec->use_ssl = TRUE;

	value = g_hash_table_lookup(optlist, "ssl_tpm");
	if (value != NULL)
		rec->ssl_tpm = g_strdup(value);

	value = g_hash_table_lookup(optlist, "ssl_cert");
	if (value != NULL && *value != '\0')
		rec->ssl_cert = g_strdup(value);

	value = g_hash_table_lookup(optlist, "ssl_pkey");
	if (value != NULL && *value != '\0')
		rec->ssl_pkey = g_strdup(value);

	if (g_hash_table_lookup(optlist, "ssl_verify"))
		rec->ssl_verify = TRUE;

	value = g_hash_table_lookup(optlist, "ssl_cafile");
	if (value != NULL && *value != '\0')
		rec->ssl_cafile = g_strdup(value);

	value = g_hash_table_lookup(optlist, "ssl_capath");
	if (value != NULL && *value != '\0')
		rec->ssl_capath = g_strdup(value);

	if ((rec->ssl_cafile != NULL && rec->ssl_cafile[0] != '\0')
	||  (rec->ssl_capath != NULL && rec->ssl_capath[0] != '\0'))
		rec->ssl_verify = TRUE;

	if ((rec->ssl_cert != NULL && rec->ssl_cert[0] != '\0') || rec->ssl_verify == TRUE)
		rec->use_ssl = TRUE;

	if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE;
	if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE;
	if (g_hash_table_lookup(optlist, "proxy")) rec->no_proxy = FALSE;
	if (g_hash_table_lookup(optlist, "noproxy")) rec->no_proxy = TRUE;

	if (*password != '\0' && strcmp(password, "-") != 0) rec->password = g_strdup(password);
	value = g_hash_table_lookup(optlist, "host");
	if (value != NULL && *value != '\0') {
		rec->own_host = g_strdup(value);
		rec->own_ip4 = rec->own_ip6 = NULL;
	}

	signal_emit("server add fill", 2, rec, optlist);

	server_setup_add(rec);
	printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
		    TXT_SETUPSERVER_ADDED, addr, port);

	cmd_params_free(free_arg);
}
Beispiel #13
0
/**
 * Sets the key for a nick / channel in a server
 * @param data command
 * @param server irssi server record
 * @param item irssi window/item
 */
void cmd_setkey(const char *data, SERVER_REC * server, WI_ITEM_REC * item)
{
	GHashTable *optlist;
	char contactName[CONTACT_SIZE] = "", encryptedKey[150] = "";
	const char *target, *key;
	void *free_arg;

	if (IsNULLorEmpty(data)) {
		printtext(server,
			  item != NULL ? window_item_get_target(item) : NULL,
			  MSGLEVEL_CRAP,
			  "\002FiSH:\002 No parameters. Usage: /setkey [-<server tag>] [<nick | #channel>] <key>");
		return;
	}

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST,
			    "setkey", &optlist, &target, &key))
		return;

	if (*target == '\0') {
		printtext(server,
			  item != NULL ? window_item_get_target(item) : NULL,
			  MSGLEVEL_CRAP,
			  "\002FiSH:\002 No parameters. Usage: /setkey [-<server tag>] [<nick | #channel>] <key>");
		cmd_params_free(free_arg);
		return;
	}

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

	if (*key == '\0') {
		// one paramter given - it's the key
		key = target;
		if (item != NULL)
			target = window_item_get_target(item);
		else {
			printtext(NULL, NULL, MSGLEVEL_CRAP,
				  "\002FiSH:\002 Please define nick/#channel. Usage: /setkey [-<server tag>] [<nick | #channel>] <key>");
			cmd_params_free(free_arg);
			return;
		}
	}

	encrypt_key((char *)key, encryptedKey);

	if (getIniSectionForContact(server, target, contactName) == FALSE)
		return;

	if (setIniValue(contactName, "key", encryptedKey, iniPath) == -1) {
		ZeroMemory(encryptedKey, sizeof(encryptedKey));
		printtext(server,
			  item != NULL ? window_item_get_target(item) : NULL,
			  MSGLEVEL_CRAP,
			  "\002FiSH ERROR:\002 Unable to write to blow.ini, probably out of space or permission denied.");
		cmd_params_free(free_arg);
		return;
	}

	ZeroMemory(encryptedKey, sizeof(encryptedKey));

	printtext(server, item != NULL ? window_item_get_target(item) : NULL,
		  MSGLEVEL_CRAP,
		  "\002FiSH:\002 Key for %s@%s successfully set!", target,
		  server->tag);

	cmd_params_free(free_arg);
}
Beispiel #14
0
static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
					      char **rawlog_file)
{
        CHAT_PROTOCOL_REC *proto;
	SERVER_CONNECT_REC *conn;
	GHashTable *optlist;
	char *addr, *portstr, *password, *nick, *chatnet, *host, *tmp;
	void *free_arg;

	g_return_val_if_fail(data != NULL, NULL);

	if (!cmd_get_params(data, &free_arg, 4 | PARAM_FLAG_OPTIONS,
			    "connect", &optlist, &addr, &portstr,
			    &password, &nick))
		return NULL;
	if (plus_addr != NULL) *plus_addr = *addr == '+';
	if (*addr == '+') addr++;
	if (*addr == '\0') {
		signal_emit("error command", 1,
			    GINT_TO_POINTER(CMDERR_NOT_ENOUGH_PARAMS));
		cmd_params_free(free_arg);
		return NULL;
	}

	if (strcmp(password, "-") == 0)
		*password = '******';

        /* check if -<chatnet> option is used to specify chat protocol */
	proto = chat_protocol_find_net(optlist);

	/* connect to server */
	chatnet = proto == NULL ? NULL :
		g_hash_table_lookup(optlist, proto->chatnet);

	if (chatnet == NULL)
		chatnet = g_hash_table_lookup(optlist, "network");
	
	conn = server_create_conn(proto != NULL ? proto->id : -1, addr,
				  atoi(portstr), chatnet, password, nick);
	if (proto == NULL)
		proto = chat_protocol_find_id(conn->chat_type);

	if (proto->not_initialized) {
		/* trying to use protocol that isn't yet initialized */
		signal_emit("chat protocol unknown", 1, proto->name);
		server_connect_unref(conn);
                cmd_params_free(free_arg);
		return NULL;
	}

	if (strchr(addr, '/') != NULL)
		conn->unix_socket = TRUE;

	if (g_hash_table_lookup(optlist, "6") != NULL)
		conn->family = AF_INET6;
	else if (g_hash_table_lookup(optlist, "4") != NULL)
		conn->family = AF_INET;

	if (g_hash_table_lookup(optlist, "ssl") != NULL)
		conn->use_ssl = TRUE;
	if ((tmp = g_hash_table_lookup(optlist, "ssl_cert")) != NULL)
		conn->ssl_cert = g_strdup(tmp);
	if ((tmp = g_hash_table_lookup(optlist, "ssl_pkey")) != NULL)
		conn->ssl_pkey = g_strdup(tmp);
	if (g_hash_table_lookup(optlist, "ssl_verify") != NULL)
		conn->ssl_verify = TRUE;
	if ((tmp = g_hash_table_lookup(optlist, "ssl_cafile")) != NULL)
		conn->ssl_cafile = g_strdup(tmp);
	if ((tmp = g_hash_table_lookup(optlist, "ssl_capath")) != NULL)
		conn->ssl_capath = g_strdup(tmp);
	if ((conn->ssl_capath != NULL && conn->ssl_capath[0] != '\0')
	||  (conn->ssl_cafile != NULL && conn->ssl_cafile[0] != '\0'))
		conn->ssl_verify = TRUE;
	if ((conn->ssl_cert != NULL && conn->ssl_cert[0] != '\0') || conn->ssl_verify)
		conn->use_ssl = TRUE;

	if (g_hash_table_lookup(optlist, "!") != NULL)
		conn->no_autojoin_channels = TRUE;

	if (g_hash_table_lookup(optlist, "noproxy") != NULL)
                g_free_and_null(conn->proxy);


	*rawlog_file = g_strdup(g_hash_table_lookup(optlist, "rawlog"));

        host = g_hash_table_lookup(optlist, "host");
	if (host != NULL && *host != '\0') {
		IPADDR ip4, ip6;

		if (net_gethostbyname(host, &ip4, &ip6) == 0)
                        server_connect_own_ip_save(conn, &ip4, &ip6);
	}

	cmd_params_free(free_arg);
        return conn;
}
Beispiel #15
0
/* SYNTAX: SCROLLBACK GOTO <+|-linecount>|<linenum>|<timestamp> */
static void cmd_scrollback_goto(gchar *data)
{
    GList *pos;
    gchar *arg1, *arg2;
    void *free_arg;
    gint lines;

    if (!cmd_get_params(data, &free_arg, 2, &arg1, &arg2))
	    return;
    if (*arg2 == '\0' && (*arg1 == '-' || *arg1 == '+'))
    {
	/* go forward/backward n lines */
	if (sscanf(arg1 + (*arg1 == '-' ? 0 : 1), "%d", &lines) == 1)
	    gui_window_scroll(active_win, lines);
    }
    else if (*arg2 == '\0' && strchr(arg1, ':') == NULL && strchr(arg1, '.') == NULL &&
	     sscanf(arg1, "%d", &lines) == 1)
    {
        /* go to n'th line. */
	pos = g_list_nth(WINDOW_GUI(active_win)->lines, lines);
	if (pos != NULL)
            scrollback_goto_pos(active_win, pos);
    }
    else
    {
	struct tm tm;
	time_t stamp;
	gint day, month;

	/* [dd.mm | -<days ago>] hh:mi[:ss] */
	stamp = time(NULL);
	if (*arg1 == '-')
	{
	    /* -<days ago> */
	    if (sscanf(arg1+1, "%d", &day) == 1)
		stamp -= day*3600*24;
	    memcpy(&tm, localtime(&stamp), sizeof(struct tm));
	}
	else if (*arg2 != '\0')
	{
	    /* dd.mm */
	    if (sscanf(arg1, "%d.%d", &day, &month) == 2)
	    {
		month--;
		memcpy(&tm, localtime(&stamp), sizeof(struct tm));

		if (tm.tm_mon < month)
		    tm.tm_year--;
		tm.tm_mon = month;
		tm.tm_mday = day;
		stamp = mktime(&tm);
	    }
	}
	else
	{
            /* move time argument to arg2 */
	    arg2 = arg1;
	}

	/* hh:mi[:ss] */
	memcpy(&tm, localtime(&stamp), sizeof(struct tm));
        tm.tm_sec = 0;
	sscanf(arg2, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
	stamp = mktime(&tm);

	if (stamp > time(NULL) && arg1 == arg2) {
		/* we used /SB GOTO 23:59 or something, we want to jump to
		   previous day's 23:59 time instead of into future. */
                stamp -= 3600*24;
	}

	if (stamp > time(NULL)) {
		/* we're still looking into future, don't bother checking */
		cmd_params_free(free_arg);
		return;
	}

	/* find the first line after timestamp */
	for (pos = WINDOW_GUI(active_win)->lines; pos != NULL; pos = pos->next)
	{
	    LINE_REC *rec = pos->data;

	    if (rec->time >= stamp)
	    {
		scrollback_goto_pos(active_win, pos);
		break;
	    }
	}
    }
    cmd_params_free(free_arg);
}
Beispiel #16
0
/* SYNTAX: HILIGHT [-nick | -word | -line] [-mask | -full | -regexp]
                   [-color <color>] [-actcolor <color>] [-level <level>]
		   [-channels <channels>] <text> */
static void cmd_hilight(const char *data)
{
        GHashTable *optlist;
	HILIGHT_REC *rec;
	char *colorarg, *actcolorarg, *levelarg, *priorityarg, *chanarg, *text;
	char **channels;
	void *free_arg;

	g_return_if_fail(data != NULL);

	if (*data == '\0') {
		cmd_hilight_show();
		return;
	}

	if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_GETREST, "hilight", &optlist, &text))
		return;

	chanarg = g_hash_table_lookup(optlist, "channels");
	levelarg = g_hash_table_lookup(optlist, "level");
	priorityarg = g_hash_table_lookup(optlist, "priority");
	colorarg = g_hash_table_lookup(optlist, "color");
	actcolorarg = g_hash_table_lookup(optlist, "actcolor");

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

	channels = (chanarg == NULL || *chanarg == '\0') ? NULL :
		g_strsplit(replace_chars(chanarg, ',', ' '), " ", -1);

	rec = hilight_find(text, channels);
	if (rec == NULL) {
		rec = g_new0(HILIGHT_REC, 1);

		/* default to nick/word hilighting */
                rec->nick = TRUE;
		rec->word = TRUE;

		rec->text = g_strdup(text);
		rec->channels = channels;
	} else {
		g_strfreev(channels);
	}

	rec->level = (levelarg == NULL || *levelarg == '\0') ? 0 :
		level2bits(replace_chars(levelarg, ',', ' '));
	rec->priority = priorityarg == NULL ? 0 : atoi(priorityarg);

	if (g_hash_table_lookup(optlist, "line") != NULL) {
		rec->word = FALSE;
		rec->nick = FALSE;
	}

	if (g_hash_table_lookup(optlist, "word") != NULL) {
		rec->word = TRUE;
                rec->nick = FALSE;
	}

	if (g_hash_table_lookup(optlist, "nick") != NULL)
                rec->nick = TRUE;

	rec->nickmask = g_hash_table_lookup(optlist, "mask") != NULL;
	rec->fullword = g_hash_table_lookup(optlist, "full") != NULL;
	rec->regexp = g_hash_table_lookup(optlist, "regexp") != NULL;

	if (colorarg != NULL) {
		g_free_and_null(rec->color);
		if (*colorarg != '\0')
			rec->color = g_strdup(colorarg);
	}
	if (actcolorarg != NULL) {
		g_free_and_null(rec->act_color);
		if (*actcolorarg != '\0')
			rec->act_color = g_strdup(actcolorarg);
	}

	hilight_create(rec);

	hilight_print(g_slist_index(hilights, rec)+1, rec);
        cmd_params_free(free_arg);

	reset_cache();
}
Beispiel #17
0
/* SYNTAX: RECONNECT <tag> [<quit message>] */
static void cmd_reconnect(const char *data, SERVER_REC *server)
{
	SERVER_CONNECT_REC *conn;
	RECONNECT_REC *rec;
	char *tag, *msg;
	void *free_arg;
	int tagnum;

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &tag, &msg))
		return;

	if (*tag != '\0' && g_strcmp0(tag, "*") != 0)
		server = server_find_tag(tag);

	if (server != NULL) {
		/* reconnect connected server */
		conn = server_connect_copy_skeleton(server->connrec, TRUE);

		if (server->connected)
			reconnect_save_status(conn, server);

		msg = g_strconcat("* ", *msg == '\0' ?
				  "Reconnecting" : msg, NULL);
		signal_emit("command disconnect", 2, msg, server);
		g_free(msg);

		conn->reconnection = TRUE;
		server_connect(conn);
		server_connect_unref(conn);
		cmd_params_free(free_arg);
                return;
	}

	if (g_ascii_strcasecmp(tag, "all") == 0) {
		/* reconnect all servers in reconnect queue */
                reconnect_all();
		cmd_params_free(free_arg);
                return;
	}

	if (*data == '\0') {
		/* reconnect to first server in reconnection list */
		if (reconnects == NULL)
			cmd_param_error(CMDERR_NOT_CONNECTED);
                rec = reconnects->data;
	} else {
		if (g_ascii_strncasecmp(tag, "RECON-", 6) == 0)
			tag += 6;

		tagnum = atoi(tag);
		rec = tagnum <= 0 ? NULL : reconnect_find_tag(tagnum);
	}

	if (rec == NULL) {
		signal_emit("server reconnect not found", 1, data);
	} else {
		conn = rec->conn;
		server_connect_ref(conn);
		server_reconnect_destroy(rec);
		server_connect(conn);
		server_connect_unref(conn);
	}

	cmd_params_free(free_arg);
}
Beispiel #18
0
/* SYNTAX: DCC SEND <nick> <file> */
static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{
	char *target, *fname, *str, *ptr;
	void *free_arg;
	char host[MAX_IP_LEN];
	int hfile, hlisten, port;
	long fsize;
	DCC_REC *dcc, *chat;
	IPADDR own_ip;

	g_return_if_fail(data != NULL);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &fname))
		return;
	if (*target == '\0' || *fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	/* if we're in dcc chat, send the request via it. */
	chat = item_get_dcc(item);

	if (chat != NULL && (chat->mirc_ctcp || g_strcasecmp(target, chat->nick) != 0))
		chat = NULL;

	if ((server == NULL || !server->connected) && chat == NULL)
		cmd_param_error(CMDERR_NOT_CONNECTED);

	if (dcc_find_item(DCC_TYPE_SEND, target, fname)) {
		signal_emit("dcc error send exists", 2, target, fname);
		cmd_params_free(free_arg);
		return;
	}

	str = convert_home(fname);
	if (!g_path_is_absolute(str)) {
		char *path;

		g_free(str);
		path = convert_home(settings_get_str("dcc_upload_path"));
		str = g_strconcat(path, G_DIR_SEPARATOR_S, fname, NULL);
		g_free(path);
	}

	hfile = open(str, O_RDONLY);
	g_free(str);

	if (hfile == -1) {
		signal_emit("dcc error file not found", 2, target, fname);
		cmd_params_free(free_arg);
		return;
	}
	fsize = lseek(hfile, 0, SEEK_END);
	lseek(hfile, 0, SEEK_SET);

	/* get the IP address we use with IRC server */
	if (net_getsockname(chat != NULL ? chat->handle : net_sendbuffer_handle(server->handle), &own_ip, NULL) == -1) {
		close(hfile);
		cmd_param_error(CMDERR_ERRNO);
	}

	/* start listening */
	port = settings_get_int("dcc_port");
	hlisten = net_listen(&own_ip, &port);
	if (hlisten == -1) {
		close(hfile);
		cmd_param_error(CMDERR_ERRNO);
	}

	/* skip path, change all spaces to _ */
	fname = g_strdup(g_basename(fname));
	for (ptr = fname; *ptr != '\0'; ptr++)
		if (*ptr == ' ') *ptr = '_';

	dcc = dcc_create(DCC_TYPE_SEND, hlisten, target, fname, server, chat);
	dcc->port = port;
	dcc->size = fsize;
	dcc->fhandle = hfile;
	dcc->tagconn = g_input_add(hlisten, G_INPUT_READ,
				   (GInputFunction) dcc_send_init, dcc);

	/* send DCC request */
	dcc_make_address(&own_ip, host);
	str = g_strdup_printf("DCC SEND %s %s %d %lu",
			      fname, host, port, fsize);
	dcc_ctcp_message(target, server, chat, FALSE, str);
	g_free(str);

	g_free(fname);
	cmd_params_free(free_arg);
}