Exemplo n.º 1
0
static void dcc_chat_passive(CHAT_DCC_REC *dcc)
{
	IPADDR own_ip;
	int port;
	GIOChannel *handle;
	char host[MAX_IP_LEN];

	g_return_if_fail(IS_DCC_CHAT(dcc));

	if (dcc->addrstr[0] == '\0' ||
	    dcc->starttime != 0 || dcc->handle != NULL) {
		/* already sent a chat request / already chatting */
		return;
	}

	handle = dcc_listen(net_sendbuffer_handle(dcc->server->handle),
			    &own_ip, &port);
	if (handle == NULL)
		cmd_return_error(CMDERR_ERRNO);

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

	/* Let's send the reply to the other client! */
	dcc_ip2str(&own_ip, host);
	irc_send_cmdv(dcc->server, "PRIVMSG %s :\001DCC CHAT CHAT %s %d %d\001",
		      dcc->nick, host, port, dcc->pasv_id);

}
Exemplo n.º 2
0
int dcc_start_send(const char *nick, const char *fname, int timeout)
{
	dcc_listen_t *listen;
	dcc_send_t *send;
	int idx, size, fd;
	char *quote, *slash;

	fd = open(fname, O_RDONLY);
	if (!fd)
		return(-2); /* File could not be opened. */

	size = lseek(fd, 0, SEEK_END);
	lseek(fd, 0, SEEK_SET);

	listen = dcc_listen(timeout);
	if (!listen) {
		close(fd);
		return(-1);
	}

	/* Create an empty sockbuf that will eventually be used for the
	 * dcc chat (when they connect to us). */
	idx = sockbuf_new();
	send = calloc(1, sizeof(*send));
	sockbuf_attach_filter(idx, &dcc_send_filter, send);

	listen->client = idx;
	send->next = dcc_send_head;
	dcc_send_head = send;
	send->serv = listen->serv;
	send->port = listen->port;
	send->fd = fd;
	send->idx = idx;
	send->size = size;
	send->bytes_sent = 0;
	send->bytes_left = size;
	timer_get_now_sec(&send->request_time);
	send->fname = strdup(fname);
	send->nick = strdup(nick);

	slash = strrchr(fname, '/');
	if (slash)
		fname = slash+1;

	if (strchr(fname, ' '))
		quote = "\"";
	else
		quote = "";

	printserv(SERVER_NORMAL, "PRIVMSG %s :%cDCC SEND %s%s%s %u %d %d%c", nick, 1, quote, fname, quote,
		  current_server.mylongip, listen->port, size, 1);

	return(idx);
}
Exemplo n.º 3
0
/* Starts a chat with the specified nick.
 * If timeout is 0, the default timeout is used.
 * If timeout is -1, there is no timeout.
 * We don't make sure the nick is valid, so if it's not, you won't know until
 * the chat times out. */
int dcc_start_chat(const char *nick, int timeout)
{
	dcc_listen_t *listen;
	int idx;

	/* Create a listening idx to accept the chat connection. */
	listen = dcc_listen(timeout);
	if (!listen) return(-1);

	/* Create an empty sockbuf that will eventually be used for the
	 * dcc chat (when they connect to us). */
	idx = sockbuf_new();
	sockbuf_attach_filter(idx, &dcc_chat_filter, (void *)listen->serv);
	listen->client = idx;

	printserv(SERVER_NORMAL, "PRIVMSG %s :%cDCC CHAT chat %u %d%c", nick, 1, current_server.mylongip, listen->port, 1);
	return(idx);
}
Exemplo n.º 4
0
Arquivo: dcc-get.c Projeto: Liaf/irssi
void dcc_get_passive(GET_DCC_REC *dcc)
{
	GIOChannel *handle;
	IPADDR own_ip;
	int port;
	char host[MAX_IP_LEN];

	handle = dcc_listen(net_sendbuffer_handle(dcc->server->handle),
			    &own_ip, &port);
	if (handle == NULL)
		cmd_return_error(CMDERR_ERRNO);

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

	/* Let's send the reply to the other client! */
	dcc_ip2str(&own_ip, host);
	irc_send_cmdv(dcc->server,
		      "PRIVMSG %s :\001DCC SEND %s %s %d %"PRIuUOFF_T" %d\001",
		      dcc->nick, dcc->arg, host, port, dcc->size, dcc->pasv_id);
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
static int dcc_send_one_file(int queue, const char *target, const char *fname,
			     IRC_SERVER_REC *server, CHAT_DCC_REC *chat)
{
	struct stat st;
	char *str;
	char host[MAX_IP_LEN];
	int hfile, port;
        SEND_DCC_REC *dcc;
	IPADDR own_ip;
        GIOChannel *handle;

	if (dcc_find_request(DCC_SEND_TYPE, target, fname)) {
	        signal_emit("dcc error send exists", 2, target, fname);
		return FALSE;
	}

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

	if (hfile == -1) {
		signal_emit("dcc error file open", 3, target, fname,
			    GINT_TO_POINTER(errno));
		return FALSE;
	}

	if (fstat(hfile, &st) < 0) {
		g_warning("fstat() failed: %s", strerror(errno));
		close(hfile);
		return FALSE;
	}

        /* start listening */
	handle = dcc_listen(chat != NULL ? chat->handle :
			    net_sendbuffer_handle(server->handle),
			    &own_ip, &port);
	if (handle == NULL) {
		close(hfile);
		g_warning("dcc_listen() failed: %s", strerror(errno));
		return FALSE;
	}

	fname = g_basename(fname);

	/* Replace all the spaces with underscore so that lesser
	   intellgent clients can communicate.. */
	if (!settings_get_bool("dcc_send_replace_space_with_underscore"))
		str = NULL;
	else {
		str = g_strdup(fname);
		g_strdelimit(str, " ", '_');
		fname = str;
	}

	dcc = dcc_send_create(server, chat, target, fname);
	g_free(str);

	dcc->handle = handle;
	dcc->port = port;
	dcc->size = st.st_size;
	dcc->fhandle = hfile;
	dcc->queue = queue;
        dcc->file_quoted = strchr(fname, ' ') != NULL;
	dcc->tagconn = g_input_add(handle, G_INPUT_READ,
				   (GInputFunction) dcc_send_connected, dcc);

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

	dcc_ip2str(&own_ip, host);
	str = g_strdup_printf(dcc->file_quoted ?
			      "DCC SEND \"%s\" %s %d %"PRIuUOFF_T :
			      "DCC SEND %s %s %d %"PRIuUOFF_T,
			      dcc->arg, host, port, dcc->size);
	dcc_ctcp_message(server, target, chat, FALSE, str);
	g_free(str);

	return TRUE;
}