コード例 #1
0
ファイル: dcc-chat.c プロジェクト: svn2github/irssi
/* input function: DCC CHAT - someone tried to connect to our socket */
static void dcc_chat_listen(DCC_REC *dcc)
{
	IPADDR ip;
	int handle, port;

	g_return_if_fail(dcc != NULL);

	/* accept connection */
	handle = net_accept(dcc->handle, &ip, &port);
	if (handle == -1)
		return;

	/* TODO: add paranoia check - see dcc-files.c */

	g_source_remove(dcc->tagread);
	close(dcc->handle);

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

	signal_emit("dcc connected", 1, dcc);
}
コード例 #2
0
ファイル: dcc-server.c プロジェクト: svn2github/irssi
/* input function: DCC SERVER - someone tried to connect to our socket */
static void dcc_server_listen(SERVER_DCC_REC *dcc)
{
	SERVER_DCC_REC *newdcc;
	IPADDR ip;
	GIOChannel *handle;
	int port;

	g_return_if_fail(IS_DCC_SERVER(dcc));

	/* accept connection */
	handle = net_accept(dcc->handle, &ip, &port);
	if (handle == NULL)
		return;

	/* Create a new DCC SERVER to handle this connection */
	newdcc = dcc_server_clone(dcc);

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

	signal_emit("dcc connected", 1, newdcc);
}
コード例 #3
0
ファイル: servers.c プロジェクト: TrapSquad/irssi-sctp
static void server_real_connect(SERVER_REC *server, IPADDR *ip,
				const char *unix_socket)
{
	GIOChannel *handle;
	IPADDR *own_ip = NULL;
	const char *errmsg;
	char *errmsg2;
	char ipaddr[MAX_IP_LEN];
        int port, protonum;

	g_return_if_fail(ip != NULL || unix_socket != NULL);

	signal_emit("server connecting", 2, server, ip);

	if (server->connrec->no_connect)
		return;

	if (ip != NULL) {
		own_ip = IPADDR_IS_V6(ip) ? server->connrec->own_ip6 : server->connrec->own_ip4;
		port = server->connrec->proxy != NULL ?
			server->connrec->proxy_port : server->connrec->port;
		protonum = server->connrec->use_sctp ? 132 : 0;
		handle = server->connrec->use_ssl ?
			net_connect_ip_ssl(ip, port, own_ip, server, protonum) : net_connect_ip(ip, port, own_ip, protonum);
	} else {
		handle = net_connect_unix(unix_socket);
	}

	if (handle == NULL) {
		/* failed */
		errmsg = g_strerror(errno);
		errmsg2 = NULL;
		if (errno == EADDRNOTAVAIL) {
			if (own_ip != NULL) {
				/* show the IP which is causing the error */
				net_ip2host(own_ip, ipaddr);
				errmsg2 = g_strconcat(errmsg, ": ", ipaddr, NULL);
			}
			server->no_reconnect = TRUE;
		}
		if (server->connrec->use_ssl && errno == ENOSYS)
			server->no_reconnect = TRUE;

		server->connection_lost = TRUE;
		server_connect_failed(server, errmsg2 ? errmsg2 : errmsg);
		g_free(errmsg2);
	} else {
		server->handle = net_sendbuffer_create(handle, 0);
#ifdef HAVE_OPENSSL
		if (server->connrec->use_ssl)
			server_connect_callback_init_ssl(server, handle);
		else
#endif
		server->connect_tag =
			g_input_add(handle, G_INPUT_WRITE | G_INPUT_READ,
				    (GInputFunction)
				    server_connect_callback_init,
				    server);
	}
}
コード例 #4
0
ファイル: dcc-chat.c プロジェクト: irssi/irssi
/* input function: DCC CHAT - someone tried to connect to our socket */
static void dcc_chat_listen(CHAT_DCC_REC *dcc)
{
	IPADDR ip;
        GIOChannel *handle;
	int port;

	g_return_if_fail(IS_DCC_CHAT(dcc));

	/* accept connection */
	handle = net_accept(dcc->handle, &ip, &port);
	if (handle == NULL)
		return;

	/* TODO: add paranoia check - see dcc-files.c */

	net_disconnect(dcc->handle);
	g_source_remove(dcc->tagconn);
	dcc->tagconn = -1;

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

	signal_emit("dcc connected", 1, dcc);
}
コード例 #5
0
ファイル: dcc-send.c プロジェクト: svn2github/irssi
/* input function: DCC SEND - someone tried to connect to our socket */
static void dcc_send_connected(SEND_DCC_REC *dcc)
{
        GIOChannel *handle;
	IPADDR addr;
	int port;

	/* accept connection */
	handle = net_accept(dcc->handle, &addr, &port);
	if (handle == NULL)
		return;

	/* TODO: some kind of paranoia check would be nice. it would check
	   that the host of the nick who we sent the request matches the
	   address who connected us. */

	net_disconnect(dcc->handle);
	g_source_remove(dcc->tagconn);
        dcc->tagconn = -1;

	dcc->starttime = time(NULL);
	dcc->handle = handle;
	memcpy(&dcc->addr, &addr, sizeof(IPADDR));
	net_ip2host(&dcc->addr, dcc->addrstr);
	dcc->port = port;

	dcc->tagread = g_input_add(handle, G_INPUT_READ,
				   (GInputFunction) dcc_send_read_size, dcc);
	dcc->tagwrite = g_input_add(handle, G_INPUT_WRITE,
				    (GInputFunction) dcc_send_data, dcc);

	signal_emit("dcc connected", 1, dcc);
}
コード例 #6
0
ファイル: dcc-get.c プロジェクト: svn2github/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;
        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);
}
コード例 #7
0
ファイル: fe-server.c プロジェクト: svn2github/irssi
static void sig_server_connecting(SERVER_REC *server, IPADDR *ip)
{
	char ipaddr[MAX_IP_LEN];

	g_return_if_fail(server != NULL);
	g_return_if_fail(ip != NULL);

	net_ip2host(ip, ipaddr);
	printformat(server, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CONNECTING,
		    server->connrec->address, ipaddr, server->connrec->port);
}
コード例 #8
0
ファイル: dcc.c プロジェクト: svn2github/irssi
void dcc_make_address(IPADDR *ip, char *host)
{
	unsigned long addr;

	if (is_ipv6_addr(ip)) {
		/* IPv6 */
		net_ip2host(ip, host);
	} else {
		memcpy(&addr, &ip->addr, 4);
		sprintf(host, "%lu", (unsigned long) htonl(addr));
	}
}
コード例 #9
0
NSAPI_PUBLIC char *session_dns_lookup(Session *s, int verify)
{
    pb_param *dns = pblock_findkey(pb_key_dns, s->client);
    char *hn;

    if(!dns) {
        char *ip = pblock_findkeyval(pb_key_ip, s->client);
        if(!ip || !(hn = net_ip2host(ip, verify))) {
            pblock_kvinsert(pb_key_dns, "-none", 5, s->client);
            return NULL;
        }
        dns = pblock_kvinsert(pb_key_dns, hn, strlen(hn), s->client);
    }
    else if(!strcmp(dns->value, "-none"))
        return NULL;
    ((ClAuth_t *) s->clauth)->cla_dns = dns->value;
    return dns->value;
}
コード例 #10
0
ファイル: dcc-files.c プロジェクト: svn2github/irssi
/* input function: DCC SEND - someone tried to connect to our socket */
static void dcc_send_init(DCC_REC *dcc)
{
	int handle, port;
	IPADDR addr;

	g_return_if_fail(dcc != NULL);

	/* accept connection */
	handle = net_accept(dcc->handle, &addr, &port);
	if (handle == -1)
		return;

	/* TODO: some kind of paranoia check would be nice. it would check
	   that the host of the nick who we sent the request matches the
	   address who connected us. */

	g_source_remove(dcc->tagread);
	close(dcc->handle);

	dcc->starttime = time(NULL);
	dcc->fastsend = settings_get_bool("dcc_fast_send");
	dcc->handle = handle;
	memcpy(&dcc->addr, &addr, sizeof(IPADDR));
	net_ip2host(&dcc->addr, dcc->addrstr);
	dcc->port = port;

	dcc->databufsize = settings_get_int("dcc_block_size");
        if (dcc->databufsize <= 0) dcc->databufsize = 2048;
	dcc->databuf = g_malloc(dcc->databufsize);

	dcc->tagread = g_input_add(handle, G_INPUT_READ,
				   (GInputFunction) dcc_send_read_size, dcc);
	dcc->tagwrite = !dcc->fastsend ? -1 :
		g_input_add(handle, G_INPUT_WRITE, (GInputFunction) dcc_send_data, dcc);

	signal_emit("dcc connected", 1, dcc);

	if (!dcc->fastsend) {
		/* send first block */
		dcc->gotalldata = TRUE;
		dcc_send_data(dcc);
	}
}
コード例 #11
0
ファイル: dcc.c プロジェクト: Manishearth/irssi
void dcc_ip2str(IPADDR *ip, char *host)
{
	IPADDR temp_ip;
	guint32 addr;

	if (*settings_get_str("dcc_own_ip") != '\0') {
                /* overridden IP address */
		net_host2ip(settings_get_str("dcc_own_ip"), &temp_ip);
                ip = &temp_ip;
	}

	if (IPADDR_IS_V6(ip)) {
		/* IPv6 */
		net_ip2host(ip, host);
	} else {
		memcpy(&addr, &ip->ip, sizeof(addr));
		g_snprintf(host, MAX_IP_LEN, "%lu",
			   (unsigned long) htonl(addr));
	}
}
コード例 #12
0
ファイル: network.c プロジェクト: svn2github/irssi
/* Get name for host, *name should be g_free()'d unless it's NULL.
   Return values are the same as with net_gethostbyname() */
int net_gethostbyaddr(IPADDR *ip, char **name)
{
#ifdef HAVE_IPV6
	struct addrinfo req, *ai;
	char hbuf[NI_MAXHOST];
	int host_error;
#else
	struct hostent *hp;
#endif
	char ipname[MAX_IP_LEN];

	g_return_val_if_fail(ip != NULL, -1);
	g_return_val_if_fail(name != NULL, -1);

	net_ip2host(ip, ipname);

	*name = NULL;
#ifdef HAVE_IPV6
	memset(&req, 0, sizeof(struct addrinfo));
	req.ai_socktype = SOCK_STREAM;

	/* save error to host_error for later use */
	host_error = getaddrinfo(ipname, NULL, &req, &ai);
	if (host_error != 0)
		return host_error;

	if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, 0))
		return 1;

	/*FIXME: how does this work? *name = g_strdup(ai->?);*/
	freeaddrinfo(ai);
	return 1;
#else
	hp = gethostbyaddr(ipname, strlen(ipname), AF_INET);
	if (hp == NULL) return -1;

	*name = g_strdup(hp->h_name);
#endif

	return 0;
}
コード例 #13
0
ファイル: listen.c プロジェクト: Manishearth/irssi
static void sig_listen(LISTEN_REC *listen)
{
	CLIENT_REC *rec;
	IPADDR ip;
	NET_SENDBUF_REC *sendbuf;
        GIOChannel *handle;
	char host[MAX_IP_LEN];
	int port;

	g_return_if_fail(listen != NULL);

	/* accept connection */
	handle = net_accept(listen->handle, &ip, &port);
	if (handle == NULL)
		return;
	net_ip2host(&ip, host);
	sendbuf = net_sendbuffer_create(handle, 0);
	rec = g_new0(CLIENT_REC, 1);
	rec->listen = listen;
	rec->handle = sendbuf;
        rec->host = g_strdup(host);
	rec->port = port;
	if (g_strcmp0(listen->ircnet, "*") == 0) {
		rec->proxy_address = g_strdup("irc.proxy");
		rec->server = servers == NULL ? NULL : IRC_SERVER(servers->data);
	} else {
		rec->proxy_address = g_strdup_printf("%s.proxy", listen->ircnet);
		rec->server = servers == NULL ? NULL :
			IRC_SERVER(server_find_chatnet(listen->ircnet));
	}
	rec->recv_tag = g_input_add(handle, G_INPUT_READ,
			       (GInputFunction) sig_listen_client, rec);

	proxy_clients = g_slist_prepend(proxy_clients, rec);
	rec->listen->clients = g_slist_prepend(rec->listen->clients, rec);

	signal_emit("proxy client connecting", 1, rec);
	printtext(rec->server, NULL, MSGLEVEL_CLIENTNOTICE,
		  "Proxy: New client %s:%d on port %d (%s)",
		  rec->host, rec->port, listen->port, listen->ircnet);
}
コード例 #14
0
ファイル: network.c プロジェクト: svn2github/irssi
/* Get name for host, *name should be g_free()'d unless it's NULL.
   Return values are the same as with net_gethostbyname() */
int net_gethostbyaddr(IPADDR *ip, char **name)
{
#ifdef HAVE_IPV6
	struct addrinfo req, *ai;
	int host_error;
#else
	struct hostent *hp;
#endif
	char ipname[MAX_IP_LEN];

	g_return_val_if_fail(ip != NULL, -1);
	g_return_val_if_fail(name != NULL, -1);

	net_ip2host(ip, ipname);

	*name = NULL;
#ifdef HAVE_IPV6
	memset(&req, 0, sizeof(struct addrinfo));
	req.ai_socktype = SOCK_STREAM;
	req.ai_flags = AI_CANONNAME;

	/* save error to host_error for later use */
	host_error = getaddrinfo(ipname, NULL, &req, &ai);
	if (host_error != 0)
		return host_error;
	*name = g_strdup(ai->ai_canonname);

	freeaddrinfo(ai);
#else
	hp = gethostbyaddr(ipname, strlen(ipname), AF_INET);
	if (hp == NULL) return -1;

	*name = g_strdup(hp->h_name);
#endif

	return 0;
}
コード例 #15
0
ファイル: botnet.c プロジェクト: svn2github/irssi
BOT_DOWNLINK_REC *bot_downlink_find(BOTNET_REC *botnet, IPADDR *ip, const char *host)
{
	GSList *tmp, *tmp2;
	char ipname[MAX_IP_LEN];

	g_return_val_if_fail(botnet != NULL, NULL);
	g_return_val_if_fail(ip != NULL, NULL);

	net_ip2host(ip, ipname);

	for (tmp = botnet->downlinks; tmp != NULL; tmp = tmp->next) {
		BOT_DOWNLINK_REC *rec = tmp->data;

		for (tmp2 = rec->valid_addrs; tmp2 != NULL; tmp2 = tmp2->next) {
			if (match_wildcards(tmp2->data, ipname))
				return rec;
			if (match_wildcards(tmp2->data, host) &&
			    !is_ip_mask(tmp2->data))
				return rec;
		}
	}

	return NULL;
}
コード例 #16
0
ファイル: dcc-get.c プロジェクト: Liaf/irssi
static void dcc_get_listen(GET_DCC_REC *dcc)
{
	GIOChannel *handle;
	IPADDR addr;
	int port;

	/* accept connection */
	handle = net_accept(dcc->handle, &addr, &port);
	if (handle == NULL)
		return;

	net_disconnect(dcc->handle);
	g_source_remove(dcc->tagconn);
	dcc->tagconn = -1;

	dcc->starttime = time(NULL);
	dcc->handle = handle;
	memcpy(&dcc->addr, &addr, sizeof(IPADDR));
	net_ip2host(&dcc->addr, dcc->addrstr);
	dcc->port = port;

	dcc->tagconn = g_input_add(handle, G_INPUT_READ | G_INPUT_WRITE,
				   (GInputFunction) sig_dccget_connected, dcc);
}
コード例 #17
0
ファイル: proxy.c プロジェクト: svn2github/irssi
gboolean proxy_init(void)
{

    gchar ipaddr[MAX_IP_LEN];

    const char *password;
    const char *addr;
    int port;

    proxy_settings_init();

    proxy_data = g_new0(PLUGIN_DATA, 1);
    password = settings_get_str("proxy_listen_password");
    addr = settings_get_str("proxy_listen_addr");
    port = settings_get_int("proxy_listen_port");

    plug = module_find("proxy");
    proxy_data->plugin = plug;

    if (*password != '\0')
    {
       	/* args = password */
       	proxy_data->password = g_strdup(password);
    }
    if (*addr != '\0')
    {
       	/* specify ip address to listen */
       	net_host2ip(addr, &proxy_data->ip);
    }
    if (port != 0)
    {
       	/* specify port to use */
       	proxy_data->port = port;
    }
    
    if (proxy_data->password == NULL)
    {
    	/* no password - bad idea! */
    	printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "Warning!! Password not specified, everyone can use this proxy! Use /set proxy_listen_password <password> to set it");
    }

    if (servers == NULL)
    {
    	/* FIXME: not good */
    	printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "You need to specify IP address to listen with /set proxy_listen_addr <address>");
    	deinit();
    	return FALSE;
    }
    else
    {
    	SERVER_REC *server;

    	server = servers->data;
    	if (net_getsockname(net_sendbuffer_handle(server->handle), &proxy_data->ip, NULL))
    	{
	    deinit();
	    return FALSE;
	}
    }

    net_ip2host(&proxy_data->ip, ipaddr);
    printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "Proxy plugin loaded - listening in interface %s port %d", ipaddr, proxy_data->port);

    plugin_proxy_listen_init(proxy_data);

    proxy_data->loaded = TRUE;
    return TRUE;
}
コード例 #18
0
ファイル: dcc.c プロジェクト: svn2github/irssi
/* 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 *params, *type, *arg, *addrstr, *portstr, *sizestr, *str;
    const char *cstr;
    DCC_REC *dcc;
    gulong size;
    int port;

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

    params = cmd_get_params(data, 5 | PARAM_FLAG_NOQUOTES,
			    &type, &arg, &addrstr, &portstr, &sizestr);

    if (sscanf(portstr, "%d", &port) != 1) port = 0;
    if (sscanf(sizestr, "%lu", &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' || irc_masks_match(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' && irc_masks_match(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;
    }

    g_free(params);
}
コード例 #19
0
ファイル: dcc-chat.c プロジェクト: irssi/irssi
/* 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);
}
コード例 #20
0
ファイル: dcc-server.c プロジェクト: svn2github/irssi
/* 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();
}
コード例 #21
0
ファイル: dcc-get.c プロジェクト: 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);
}
コード例 #22
0
ファイル: dcc.c プロジェクト: svn2github/irssi
/* 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, *olddcc;
    long size;
    int dcctype, 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;

    dcctype = SWAP_SENDGET(dcc_str2type(type));
    olddcc = dcc_find_item(dcctype, sender,
			   dcctype == DCC_TYPE_CHAT ? NULL : arg);
    if (olddcc != NULL) {
	    /* same DCC request offered again */
	    if (olddcc->type == DCC_TYPE_CHAT &&
		olddcc->handle != -1 && olddcc->starttime == 0) {
		    /* we requested dcc chat, they requested
		       dcc chat from us .. allow it. */
		    dcc_destroy(olddcc);
	    } else {
		    /* if the connection isn't open, update the port,
		       otherwise just ignore */
		    if (olddcc->handle == -1)
			    olddcc->port = port;
		    cmd_params_free(free_arg);
		    return;
	    }
    }

    dcc = dcc_create(dcctype, -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 (olddcc != NULL ||
		(*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);
}