Exemple #1
0
/* handle receiving DCC - GET/RESUME. */
void cmd_dcc_receive(const char *data, DCC_GET_FUNC accept_func,
		     DCC_GET_FUNC pasv_accept_func)
{
	GET_DCC_REC *dcc;
	GSList *tmp, *next;
	char *nick, *arg, *fname;
	void *free_arg;
	int found;

	g_return_if_fail(data != NULL);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST |
			    PARAM_FLAG_STRIP_TRAILING_WS, &nick, &arg))
		return;

	if (*nick == '\0') {
		dcc = DCC_GET(dcc_find_request_latest(DCC_GET_TYPE));
		if (dcc != NULL) {
			if (!dcc_is_passive(dcc))
				accept_func(dcc);
			else
				pasv_accept_func(dcc);
		}
		cmd_params_free(free_arg);
		return;
	}

	fname = cmd_get_quoted_param(&arg);

	found = FALSE;
	for (tmp = dcc_conns; tmp != NULL; tmp = next) {
		GET_DCC_REC *dcc = tmp->data;

		next = tmp->next;
		if (IS_DCC_GET(dcc) && g_ascii_strcasecmp(dcc->nick, nick) == 0 &&
		    (dcc_is_waiting_user(dcc) || dcc->from_dccserver) &&
		    (*fname == '\0' || g_strcmp0(dcc->arg, fname) == 0)) {
			found = TRUE;
			if (!dcc_is_passive(dcc))
				accept_func(dcc);
			else
				pasv_accept_func(dcc);
		}
	}

	if (!found)
		signal_emit("dcc error get not found", 1, nick);

	cmd_params_free(free_arg);
}
Exemple #2
0
/* CTCP: DCC RESUME - requesting to resume DCC SEND */
static void ctcp_msg_dcc_resume(IRC_SERVER_REC *server, const char *data,
				const char *nick, const char *addr,
				const char *target, DCC_REC *chat)
{
	FILE_DCC_REC *dcc;
        char *str;
	uoff_t size;
	int pasv_id = -1;

	if (!dcc_ctcp_resume_parse(DCC_SEND_TYPE, data, nick, &dcc, &size, &pasv_id)) {
		signal_emit("dcc error ctcp", 5, "RESUME", data,
			    nick, addr, target);
	} else if (dcc != NULL && dcc_resume_file_check(dcc, server, size)) {
		if (!dcc_is_passive(dcc)) {
			str = g_strdup_printf(DCC_SEND(dcc)->file_quoted ?
					      "DCC ACCEPT \"%s\" %d %"PRIuUOFF_T :
					      "DCC ACCEPT %s %d %"PRIuUOFF_T,
					      dcc->arg, dcc->port, dcc->transfd);
		} else {
			str = g_strdup_printf(DCC_SEND(dcc)->file_quoted ?
					      "DCC ACCEPT \"%s\" 0 %"PRIuUOFF_T" %d" :
					      "DCC ACCEPT %s 0 %"PRIuUOFF_T" %d",
					      dcc->arg, dcc->transfd, dcc->pasv_id);
		}
		dcc_ctcp_message(dcc->server, dcc->nick,
				 dcc->chat, FALSE, str);
		g_free(str);
	}
}
Exemple #3
0
/* CTCP: DCC ACCEPT - accept resuming DCC GET */
static void ctcp_msg_dcc_accept(IRC_SERVER_REC *server, const char *data,
				const char *nick, const char *addr,
				const char *target, DCC_REC *chat)
{
	FILE_DCC_REC *dcc;
        uoff_t size;
	int pasv_id;

	if (!dcc_ctcp_resume_parse(DCC_GET_TYPE, data, nick, &dcc, &size, &pasv_id) ||
	    (dcc != NULL && DCC_GET(dcc)->get_type != DCC_GET_RESUME)) {
		signal_emit("dcc error ctcp", 5, "ACCEPT", data,
			    nick, addr, target);
	} else if (dcc != NULL && dcc_resume_file_check(dcc, server, size)) {
		if (!dcc_is_passive(dcc))
			dcc_get_connect(DCC_GET(dcc));
		else
			dcc_get_passive(DCC_GET(dcc));
	}
}
Exemple #4
0
/* Resume a DCC GET */
static void dcc_send_resume(GET_DCC_REC *dcc)
{
        off_t pos;
	char *str;

        g_return_if_fail(dcc != NULL);

	dcc->file = dcc_get_download_path(dcc->arg);
	dcc->fhandle = open(dcc->file, O_WRONLY);
	if (dcc->fhandle == -1) {
		signal_emit("dcc error file open", 3, dcc->nick, dcc->file,
			    GINT_TO_POINTER(errno));
		return;
	}

	dcc->get_type = DCC_GET_RESUME;

	pos = lseek(dcc->fhandle, 0, SEEK_END);
	dcc->transfd = pos < 0 ? 0 : (uoff_t)pos;
	dcc->skipped = dcc->transfd;

	if (dcc->skipped == dcc->size) {
		/* already received whole file */
		dcc->starttime = time(NULL);
		dcc_reject(DCC(dcc), NULL);
	} else {
		if (!dcc_is_passive(dcc)) {
			str = g_strdup_printf(dcc->file_quoted ?
					      "DCC RESUME \"%s\" %d %"PRIuUOFF_T :
					      "DCC RESUME %s %d %"PRIuUOFF_T,
					      dcc->arg, dcc->port, dcc->transfd);
		} else {
			str = g_strdup_printf(dcc->file_quoted ?
					      "DCC RESUME \"%s\" 0 %"PRIuUOFF_T" %d" :
					      "DCC RESUME %s 0 %"PRIuUOFF_T" %d",
					      dcc->arg, dcc->transfd, dcc->pasv_id);
		}
		dcc_ctcp_message(dcc->server, dcc->nick,
				 dcc->chat, FALSE, str);
		g_free(str);
	}
}
Exemple #5
0
/* CTCP: DCC CHAT */
static void ctcp_msg_dcc_chat(IRC_SERVER_REC *server, const char *data,
			      const char *nick, const char *addr,
			      const char *target, CHAT_DCC_REC *chat)
{
        CHAT_DCC_REC *dcc;
	char **params;
	int paramcount;
        int passive, autoallow = FALSE;

        /* CHAT <unused> <address> <port> */
	/* CHAT <unused> <address> 0 <id> (DCC CHAT passive protocol) */
	params = g_strsplit(data, " ", -1);
	paramcount = g_strv_length(params);

	if (paramcount < 3) {
		g_strfreev(params);
		return;
	}
	passive = paramcount == 4 && g_strcmp0(params[2], "0") == 0;

	if (nick == NULL)
		nick = "";

	dcc = DCC_CHAT(dcc_find_request(DCC_CHAT_TYPE, nick, NULL));
	if (dcc != NULL) {
		if (dcc_is_listening(dcc)) {
			/* we requested dcc chat, they requested
			   dcc chat from us .. allow it. */
			dcc_destroy(DCC(dcc));
			autoallow = TRUE;
		} else if (!dcc_is_passive(dcc)) {
			/* we already have one dcc chat request
			   from this nick, remove it. */
			dcc_destroy(DCC(dcc));
		} else if (passive) {
			if (dcc->pasv_id != atoi(params[3])) {
				/* IDs don't match! */
				dcc_destroy(DCC(dcc));
			} else {
				/* IDs are ok! Update address and port and
				   connect! */
				dcc->target = g_strdup(target);
				dcc->port = atoi(params[2]);
				dcc_str2ip(params[1], &dcc->addr);
				net_ip2host(&dcc->addr, dcc->addrstr);

				dcc_chat_connect(dcc);
				g_strfreev(params);
				return;
			}
		}
	}

	dcc = dcc_chat_create(server, chat, nick, params[0]);
	if (dcc == NULL) {
		g_strfreev(params);
		g_warn_if_reached();
		return;
	}
	dcc->target = g_strdup(target);
	dcc->port = atoi(params[2]);

	if (passive)
		dcc->pasv_id = atoi(params[3]);

	dcc_str2ip(params[1], &dcc->addr);
	net_ip2host(&dcc->addr, dcc->addrstr);

	signal_emit("dcc request", 2, dcc, addr);

	if (autoallow || DCC_CHAT_AUTOACCEPT(dcc, server, nick, addr)) {
		if (passive) {
			/* Passive DCC... let's set up a listening socket
			   and send reply back */
			dcc_chat_passive(dcc);
		} else {
			dcc_chat_connect(dcc);
		}
	}
	g_strfreev(params);
}
Exemple #6
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);
}