Ejemplo n.º 1
0
/* CTCP: DCC SEND */
static void ctcp_msg_dcc_send(IRC_SERVER_REC *server, const char *data,
			      const char *nick, const char *addr,
			      const char *target, CHAT_DCC_REC *chat)
{
	GET_DCC_REC *dcc;
        IPADDR ip;
	char **params, *fname;
	int paramcount, fileparams;
	int port, len, quoted = FALSE;
        long size;

	/* SEND <file name> <address> <port> <size> [...] */
	params = g_strsplit(data, " ", -1);
	paramcount = strarray_length(params);

	if (paramcount < 4) {
		signal_emit("dcc error ctcp", 5, "SEND", data,
			    nick, addr, target);
		g_strfreev(params);
                return;
	}

	fileparams = get_file_params_count(params, paramcount);

	dcc_str2ip(params[fileparams], &ip);
	port = atoi(params[fileparams+1]);
	size = atol(params[fileparams+2]);

	params[fileparams] = NULL;
        fname = g_strjoinv(" ", params);
	g_strfreev(params);

        len = strlen(fname);
	if (len > 1 && *fname == '"' && fname[len-1] == '"') {
		/* "file name" - MIRC sends filenames with spaces like this */
		fname[len-1] = '\0';
		g_memmove(fname, fname+1, len);
                quoted = TRUE;
	}

	dcc = DCC_GET(dcc_find_request(DCC_GET_TYPE, nick, fname));
	if (dcc != NULL) {
		/* same DCC request offered again, remove the old one */
		dcc_destroy(DCC(dcc));
	}

	dcc = dcc_get_create(server, chat, nick, fname);
	dcc->target = g_strdup(target);
        memcpy(&dcc->addr, &ip, sizeof(ip));
	net_ip2host(&dcc->addr, dcc->addrstr);
	dcc->port = port;
	dcc->size = size;
        dcc->file_quoted = quoted;

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

        g_free(fname);
}
Ejemplo n.º 2
0
/* DCC SERVER: text received */
static void dcc_server_msg(SERVER_DCC_REC *dcc, const char *msg)
{
	g_return_if_fail(IS_DCC_SERVER(dcc));
	g_return_if_fail(msg != NULL);

	/* Check for CHAT protocol */
	if (g_strncasecmp(msg, "100 ", 4) == 0) {
		msg += 4;
		/* Check if this server is accepting chat requests.*/
		if (dcc->accept_chat) {
			/* Connect and start DCC Chat */
			char *str;
			CHAT_DCC_REC *dccchat = dcc_chat_create(dcc->server, NULL, msg, "chat");

			dccchat->starttime = time(NULL);
			dccchat->handle = dcc->handle;
			dccchat->sendbuf = net_sendbuffer_create(dccchat->handle, 0);
			memcpy(&dccchat->addr, &dcc->addr, sizeof(IPADDR));
			net_ip2host(&dccchat->addr, dccchat->addrstr);
			dccchat->port = dcc->port;
			dccchat->tagread = g_input_add(dccchat->handle, G_INPUT_READ,
						       (GInputFunction) dcc_chat_input, dccchat);

			dcc->connection_established = 1;
			signal_emit("dcc connected", 1, dccchat);

			str = g_strdup_printf("101 %s\n",
					      (dccchat->server) ? dccchat->server->nick : "??");
			net_sendbuffer_send(dccchat->sendbuf, str, strlen(str));
			g_free(str);
		}
	}

	/* Check for FSERVE protocol */
	if (g_strncasecmp(msg, "110 ", 4) == 0) {
		msg += 4;
		/* Check if this server is accepting fserve requests.*/
		if (dcc->accept_fserve) {
			/* TODO - Connect and start DCC Fserve */
		}
	}

	/* Check for SEND protocol */
	if (g_strncasecmp(msg, "120 ", 4) == 0) {
		msg += 4;
		/* Check if this server is accepting send requests.*/
		if (dcc->accept_send) {
			/* Connect and start DCC Send */
			GET_DCC_REC *dccget;
			char **params, *fname, *nick;
			int paramcount, len, quoted = FALSE;
			uoff_t size;

			/* 120 clientnickname filesize filename */
			params = g_strsplit(msg, " ", -1);
			paramcount = strarray_length(params);

			if (paramcount < 3) {
				g_strfreev(params);
				signal_stop();
				return;
			}

			nick = params[0];
			size = str_to_uofft(params[1]);
			fname = g_strjoinv(" ", &params[2]);

			len = strlen(fname);
			if (len > 1 && *fname == '"' && fname[len-1] == '"') {
				/* "file name" - MIRC sends filenames with spaces like this */
				fname[len-1] = '\0';
				g_memmove(fname, fname+1, len);
				quoted = TRUE;
			}

			dccget = dcc_get_create(dcc->server, NULL, nick, fname);
			dccget->handle = dcc->handle;
			dccget->target = g_strdup(dcc->server ? dcc->server->nick : "??");
			memcpy(&dccget->addr, &dcc->addr, sizeof(dcc->addr));
			if (dccget->addr.family == AF_INET) {
				net_ip2host(&dccget->addr, dccget->addrstr);
			} else {
				/* with IPv6, show it to us as it was sent */
				memcpy(dccget->addrstr, dcc->addrstr, sizeof(dccget->addrstr));
			}
			dccget->port = dcc->port;
			dccget->size = size;
			dccget->file_quoted = quoted;
			dccget->from_dccserver = 1;

			dcc->connection_established = 1;
			signal_emit("dcc request", 2, dccget, dccget->addrstr);

			g_strfreev(params);
			g_free(fname);
		}
	}

	signal_stop();
}
Ejemplo n.º 3
0
Archivo: dcc-get.c Proyecto: Liaf/irssi
/* CTCP: DCC SEND */
static void ctcp_msg_dcc_send(IRC_SERVER_REC *server, const char *data,
			      const char *nick, const char *addr,
			      const char *target, CHAT_DCC_REC *chat)
{
	GET_DCC_REC *dcc;
	SEND_DCC_REC *temp_dcc;
	IPADDR ip;
	char *address, **params, *fname;
	int paramcount, fileparams;
	int port, len, quoted = FALSE;
        uoff_t size;
	int p_id = -1;
	int passive = FALSE;

	/* SEND <file name> <address> <port> <size> [...] */
	/* SEND <file name> <address> 0 <size> <id> (DCC SEND passive protocol) */
	params = g_strsplit(data, " ", -1);
	paramcount = strarray_length(params);

	if (paramcount < 4) {
		signal_emit("dcc error ctcp", 5, "SEND", data,
			    nick, addr, target);
		g_strfreev(params);
                return;
	}

	fileparams = get_file_params_count(params, paramcount);

	address = g_strdup(params[fileparams]);
	dcc_str2ip(address, &ip);
	port = atoi(params[fileparams+1]);
	size = str_to_uofft(params[fileparams+2]);

	/* If this DCC uses passive protocol then store the id for later use. */
	if (paramcount == fileparams + 4) {
		p_id = atoi(params[fileparams+3]);
		passive = TRUE;
	}

	fname = get_file_name(params, fileparams);
	g_strfreev(params);

        len = strlen(fname);
	if (len > 1 && *fname == '"' && fname[len-1] == '"') {
		/* "file name" - MIRC sends filenames with spaces like this */
		fname[len-1] = '\0';
		g_memmove(fname, fname+1, len);
                quoted = TRUE;
	}

	if (passive && port != 0) {
		/* This is NOT a DCC SEND request! This is a reply to our
		   passive request. We MUST check the IDs and then connect to
		   the remote host. */

		temp_dcc = DCC_SEND(dcc_find_request(DCC_SEND_TYPE, nick, fname));
		if (temp_dcc != NULL && p_id == temp_dcc->pasv_id) {
			temp_dcc->target = g_strdup(target);
			temp_dcc->port = port;
			temp_dcc->size = size;
			temp_dcc->file_quoted = quoted;

			memcpy(&temp_dcc->addr, &ip, sizeof(IPADDR));
			if (temp_dcc->addr.family == AF_INET)
				net_ip2host(&temp_dcc->addr, temp_dcc->addrstr);
			else {
				/* with IPv6, show it to us as it was sent */
				strocpy(temp_dcc->addrstr, address,
					sizeof(temp_dcc->addrstr));
			}

			/* This new signal is added to let us invoke
			   dcc_send_connect() which is found in dcc-send.c */
			signal_emit("dcc reply send pasv", 1, temp_dcc);
			g_free(address);
			g_free(fname);
			return;
		} else if (temp_dcc != NULL && p_id != temp_dcc->pasv_id) {
			/* IDs don't match... remove the old DCC SEND and
			   return */
			dcc_destroy(DCC(temp_dcc));
			g_free(address);
			g_free(fname);
			return;
		}
	}

	dcc = DCC_GET(dcc_find_request(DCC_GET_TYPE, nick, fname));
	if (dcc != NULL)
		dcc_destroy(DCC(dcc)); /* remove the old DCC */

	dcc = dcc_get_create(server, chat, nick, fname);
	dcc->target = g_strdup(target);

	if (passive && port == 0)
		dcc->pasv_id = p_id; /* Assign the ID to the DCC */

	memcpy(&dcc->addr, &ip, sizeof(ip));
	if (dcc->addr.family == AF_INET)
		net_ip2host(&dcc->addr, dcc->addrstr);
	else {
		/* with IPv6, show it to us as it was sent */
		strocpy(dcc->addrstr, address, sizeof(dcc->addrstr));
	}
	dcc->port = port;
	dcc->size = size;
	dcc->file_quoted = quoted;

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

	g_free(address);
	g_free(fname);
}