Example #1
0
void bot_send_cmd(BOT_REC *bot, char *data)
{
	g_return_if_fail(bot != NULL);
	g_return_if_fail(data != NULL);

	net_transmit(bot->handle, data, strlen(data));
	net_transmit(bot->handle, "\n", 1);
}
Example #2
0
static gboolean sig_server_event(gchar *line, SERVER_REC *server, gchar *nick, gchar *address)
{
    GSList *tmp, *list;
    gchar *event, *args;

    g_return_val_if_fail(line != NULL, FALSE);

    /* get command.. */
    event = g_strconcat("event ", line, NULL);
    args = strchr(event+6, ' ');
    if (args != NULL) *args++ = '\0'; else args = "";
    while (*args == ' ') args++;

    list = server_redirect_getqueue(server, event, args);

    if (list != NULL)
    {
	/* we want to send this to one client (or proxy itself) only */
	REDIRECT_REC *rec;
	gint handle;

	rec = list->data;
	if (g_strncasecmp(rec->name, "proxy ", 6) != 0)
	{
	    /* proxy only */
	    g_free(event);
	    return TRUE;
	}

	if (sscanf(rec->name+6, "%d", &handle) == 1)
	{
            /* send it to specific client only */
	    server_redirect_remove_next(server, event, list);
	    net_transmit(handle, next_line->str, next_line->len);
	    g_free(event);
	    return FALSE;
	}
    }

    if (g_strcasecmp(event, "event ping") == 0)
    {
	/* We want to answer ourself to PINGs.. */
	g_free(event);
	return TRUE;
    }

    /* send the data to clients.. */
    for (tmp = proxy_data->clients; tmp != NULL; tmp = tmp->next)
    {
	CLIENT_REC *rec = tmp->data;

	if (rec->server == server)
	    net_transmit(rec->handle, next_line->str, next_line->len);
    }

    g_free(event);
    return TRUE;
}
Example #3
0
/* Send `data' to dcc chat. */
void dcc_chat_send(DCC_REC *dcc, const char *data)
{
        g_return_if_fail(dcc != NULL);
	g_return_if_fail(data != NULL);

	/* FIXME: we need output queue! */
	net_transmit(dcc->handle, data, strlen(data));
	net_transmit(dcc->handle, "\n", 1);
}
Example #4
0
/* input function: DCC GET is free to send data */
static void sig_dccget_send(GET_DCC_REC *dcc)
{
	guint32 recd;
	int ret;

	if (dcc->count_pos != 0) {
		ret = net_transmit(dcc->handle, dcc->count_buf+dcc->count_pos,
				   4-dcc->count_pos);

		if (dcc->count_pos <= 0)
			dcc->count_pos = ret;
		else if (ret > 0)
			dcc->count_pos += ret;

		if (dcc->count_pos == 4) dcc->count_pos = 0;

	}

	if (dcc->count_pos == 0) {
		g_source_remove(dcc->tagwrite);
                dcc->tagwrite = -1;
	}

	memcpy(&recd, dcc->count_buf, 4);
	if (recd != (guint32) htonl(dcc->transfd))
                dcc_get_send_received(dcc);
}
Example #5
0
static void ssl_input(struct ssl_proxy *proxy)
{
	int rcvd, sent;

	rcvd = proxy_recv_ssl(proxy, proxy->outbuf_plain,
			      sizeof(proxy->outbuf_plain));
	if (rcvd <= 0)
		return;

	sent = net_transmit(proxy->fd_plain, proxy->outbuf_plain, (size_t)rcvd);
	if (sent == rcvd)
		return;

	if (sent < 0) {
		/* disconnected */
		ssl_proxy_destroy(proxy);
		return;
	}

	/* everything wasn't sent - don't read anything until we've
	   sent it all */
        proxy->outbuf_pos_plain = 0;
	proxy->send_left_plain = rcvd - sent;

	io_remove(proxy->io_ssl);
	proxy->io_ssl = io_add(proxy->fd_ssl, IO_WRITE, ssl_output, proxy);
}
Example #6
0
/* Send data, if all of it couldn't be sent immediately, it will be resent
   automatically after a while. Returns -1 if some unrecoverable error
   occured. */
int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size)
{
	int ret;

	g_return_val_if_fail(rec != NULL, -1);
	g_return_val_if_fail(data != NULL, -1);
	if (size <= 0) return 0;

	if (rec->buffer == NULL) {
                /* nothing in buffer - transmit immediately */
		ret = net_transmit(rec->handle, data, size);
		if (ret < 0) return -1;
		size -= ret;
		data = ((const char *) data) + ret;
	}

	if (size <= 0)
		return 0;

	/* everything couldn't be sent. */
	if (rec->send_tag == -1) {
		rec->send_tag =
			g_input_add(rec->handle, G_INPUT_WRITE,
				    (GInputFunction) sig_sendbuffer, rec);
	}

	return buffer_add(rec, data, size) ? 0 : -1;
}
Example #7
0
/* input function: DCC SEND - we're ready to send more data */
static void dcc_send_data(DCC_REC *dcc)
{
	int ret;

	g_return_if_fail(dcc != NULL);

	if (!dcc->fastsend && !dcc->gotalldata) {
		/* haven't received everything we've send there yet.. */
		return;
	}

	ret = read(dcc->fhandle, dcc->databuf, dcc->databufsize);
	if (ret <= 0) {
		/* end of file .. or some error .. */
		if (dcc->fastsend) {
			/* no need to call this function anymore..
			   in fact it just eats all the cpu.. */
			dcc->waitforend = TRUE;
			g_source_remove(dcc->tagwrite);
			dcc->tagwrite = -1;
		} else {
			signal_emit("dcc closed", 1, dcc);
			dcc_destroy(dcc);
		}
		return;
	}

	ret = net_transmit(dcc->handle, dcc->databuf, ret);
	if (ret > 0) dcc->transfd += ret;
	dcc->gotalldata = FALSE;

	lseek(dcc->fhandle, dcc->transfd, SEEK_SET);

	signal_emit("dcc transfer update", 1, dcc);
}
Example #8
0
void proxy_outdata(CLIENT_REC *client, const char *data, ...)
{
	va_list args;
	char *str;

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

	va_start(args, data);

	str = g_strdup_vprintf(data, args);
	net_transmit(client->handle, str, strlen(str));
	g_free(str);

	va_end(args);
}
Example #9
0
/* Transmit all data from buffer - return TRUE if the whole buffer was sent */
static int buffer_send(NET_SENDBUF_REC *rec)
{
	int ret;

	ret = net_transmit(rec->handle, rec->buffer, rec->bufpos);
	if (ret < 0 || rec->bufpos == ret) {
		/* error/all sent - don't try to send it anymore */
                g_free_and_null(rec->buffer);
		return TRUE;
	}

	if (ret > 0) {
                rec->bufpos -= ret;
		g_memmove(rec->buffer, rec->buffer+ret, rec->bufpos);
	}
	return FALSE;
}
Example #10
0
void dcc_get_send_received(DCC_REC *dcc)
{
	guint32 recd;

	recd = (guint32) htonl(dcc->transfd);
	memcpy(dcc->count_buf, &recd, 4);

	dcc->count_pos = net_transmit(dcc->handle, dcc->count_buf+dcc->count_pos, 4-dcc->count_pos);
	if (dcc->count_pos == 4) dcc->count_pos = 0;

	/* count_pos might be -1 here. if this happens, the
	   count_buf should be re-sent.. also, if it's 1, 2 or 3, the
	   last 1-3 bytes should be sent later. these happen probably
	   never, but I just want to do it right.. :) */
	if (dcc->tagwrite != -1) {
		dcc->tagwrite = g_input_add(dcc->handle, G_INPUT_WRITE,
					    (GInputFunction) sig_dccget_send, dcc);
	}
}
Example #11
0
static void ssl_output(struct ssl_proxy *proxy)
{
	int sent;

	sent = net_transmit(proxy->fd_plain,
			    proxy->outbuf_plain + proxy->outbuf_pos_plain,
			    proxy->send_left_plain);
	if (sent < 0) {
		/* disconnected */
		ssl_proxy_destroy(proxy);
		return;
	}

	proxy->send_left_plain -= sent;
	proxy->outbuf_pos_plain += sent;

	if (proxy->send_left_plain > 0)
		return;

	/* everything is sent, start reading again */
	io_remove(proxy->io_ssl);
	proxy->io_ssl = io_add(proxy->fd_ssl, IO_READ, ssl_input, proxy);
}
Example #12
0
/* input function: DCC SEND - we're ready to send more data */
static void dcc_send_data(SEND_DCC_REC *dcc)
{
        char buffer[512];
	int ret;

	ret = read(dcc->fhandle, buffer, sizeof(buffer));
	if (ret <= 0) {
		/* no need to call this function anymore..
		   in fact it just eats all the cpu.. */
		dcc->waitforend = TRUE;
		g_source_remove(dcc->tagwrite);
		dcc->tagwrite = -1;
		return;
	}

	ret = net_transmit(dcc->handle, buffer, ret);
	if (ret > 0) dcc->transfd += ret;
	dcc->gotalldata = FALSE;

	lseek(dcc->fhandle, dcc->transfd, SEEK_SET);

	signal_emit("dcc transfer update", 1, dcc);
}
Example #13
0
void proxy_outdata_all(IRC_SERVER_REC *server, const char *data, ...)
{
	va_list args;
	GSList *tmp;
	char *str;
	int len;

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

	va_start(args, data);

	str = g_strdup_vprintf(data, args);
	len = strlen(str);
	for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
		CLIENT_REC *rec = tmp->data;

		if (rec->connected && rec->server == server)
			net_transmit(rec->handle, str, len);
	}
	g_free(str);

	va_end(args);
}
Example #14
0
File: dcc-get.c Project: Liaf/irssi
/* callback: net_connect() finished for DCC GET */
void sig_dccget_connected(GET_DCC_REC *dcc)
{
	struct stat statbuf;
	char *fname, *tempfname, *str;
        int ret, ret_errno, temphandle, old_umask;

	if (!dcc->from_dccserver) {
		if (net_geterror(dcc->handle) != 0) {
			/* error connecting */
			signal_emit("dcc error connect", 1, dcc);
			dcc_destroy(DCC(dcc));
			return;
		}

		g_source_remove(dcc->tagconn);
		dcc->tagconn = -1;
	}

	g_free_not_null(dcc->file);
	dcc->file = dcc_get_download_path(dcc->arg);

	/* if some plugin wants to change the file name/path here.. */
	signal_emit("dcc get receive", 1, dcc);

	if (stat(dcc->file, &statbuf) == 0 &&
	    dcc->get_type == DCC_GET_RENAME) {
		/* file exists, rename.. */
		fname = dcc_get_rename_file(dcc->file);
		g_free(dcc->file);
		dcc->file = fname;
	}

	if (dcc->get_type != DCC_GET_RESUME) {
		int dcc_file_create_mode = octal2dec(settings_get_int("dcc_file_create_mode"));

		/* we want to overwrite the file, remove it here.
		   if it gets created after this, we'll fail. */
		unlink(dcc->file);

		/* just to make sure we won't run into race conditions
		   if download_path is in some global temp directory */
		tempfname = g_strconcat(dcc->file, ".XXXXXX", NULL);

                old_umask = umask(0077);
		temphandle = mkstemp(tempfname);
		umask(old_umask);

		if (temphandle == -1)
			ret = -1;
		else
			ret = fchmod(temphandle, dcc_file_create_mode);

		close(temphandle);

		if (ret != -1) {
			ret = link(tempfname, dcc->file);

			if (ret == -1 &&
			    /* Linux */
			    (errno == EPERM ||
			     /* FUSE */
			     errno == ENOSYS ||
			     /* BSD */
			     errno == EOPNOTSUPP)) {
				/* hard links aren't supported - some people
				   want to download stuff to FAT/NTFS/etc
				   partitions, so fallback to rename() */
				ret = rename(tempfname, dcc->file);
			}
		}

		/* if ret = 0, we're the file owner now */
		dcc->fhandle = ret == -1 ? -1 :
			open(dcc->file, O_WRONLY | O_TRUNC);

		/* close/remove the temp file */
		ret_errno = errno;
		unlink(tempfname);
		g_free(tempfname);

		if (dcc->fhandle == -1) {
			signal_emit("dcc error file create", 3,
				    dcc, dcc->file, g_strerror(ret_errno));
			dcc_destroy(DCC(dcc));
			return;
		}
	}

	dcc->starttime = time(NULL);
	if (dcc->size == 0) {
		dcc_close(DCC(dcc));
		return;
	}
	dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ,
				   (GInputFunction) sig_dccget_receive, dcc);
	signal_emit("dcc connected", 1, dcc);

	if (dcc->from_dccserver) {
		str = g_strdup_printf("121 %s %d\n",
				      dcc->server ? dcc->server->nick : "??", 0);
		net_transmit(dcc->handle, str, strlen(str));
	}
}
Example #15
0
static void sig_listen_client(CLIENT_REC *client, gint handle)
{
    char tmpbuf[1024], *str, *cmd, *args, *p;
    int ret, recvlen;

    g_return_if_fail(client != NULL);

    for (;;)
    {
	recvlen = net_receive(handle, tmpbuf, sizeof(tmpbuf));
	ret = line_split(tmpbuf, recvlen, &str, &client->buffer);
        if (ret == -1)
        {
            /* connection lost */
            remove_client(proxy_data, client);
            break;
        }
	if (ret == 0) break;

	if (client->server == NULL)
	    continue;

	cmd = g_strdup(str);
	args = strchr(cmd, ' ');
	if (args != NULL) *args++ = '\0'; else args = "";
	if (*args == ':') args++;
	g_strup(cmd);

	if (!client->connected)
	{
	    if (proxy_data->password != NULL && strcmp(cmd, "PASS") == 0)
	    {
		if (strcmp(proxy_data->password, args) != 0)
		{
		    /* wrong password! */
		    remove_client(proxy_data, client);
                    break;
		}
		client->pass_sent = TRUE;
	    }
	    else if (strcmp(cmd, "NICK") == 0)
		client->nick = g_strdup(args);
	    else if (strcmp(cmd, "USER") == 0)
	    {
		if (client->nick == NULL || (proxy_data->password != NULL && !client->pass_sent))
		{
		    /* stupid client didn't send us NICK/PASS or, kill it */
		    remove_client(proxy_data, client);
		    break;
		}
		client->connected = TRUE;
		plugin_proxy_dump_data(client);
	    }
	}
        else if (strcmp(cmd, "QUIT") == 0)
        {
            remove_client(proxy_data, client);
            break;
        }
	else if (strcmp(cmd, "PING") == 0)
	{
	    net_transmit(handle, "PONG proxy :nick\n", 17);
	}
	else
	{
	    net_transmit(net_sendbuffer_handle(client->server->handle), str, strlen(str));
	    net_transmit(net_sendbuffer_handle(client->server->handle), "\n", 1);

	    if (strcmp(cmd, "WHO") == 0)
	    {
		grab_who(client, args);
	    }
	    else if (strcmp(cmd, "WHOIS") == 0)
	    {
		/* convert dots to spaces */
		for (p = args; *p != '\0'; p++)
		    if (*p == ',') *p = ' ';

		proxy_redirect_event(client, args, 2,
				     "event 318", -1, "event 402", -1,
				     "event 401", 1, "event 311", 1,
				     "event 301", 1, "event 312", 1,
				     "event 313", 1, "event 317", 1,
				     "event 319", 1, NULL);
	    }
	    else if (strcmp(cmd, "ISON") == 0)
	    {
		proxy_redirect_event(client, NULL, 1, "event 303", -1, NULL);
	    }
	    else if (strcmp(cmd, "USERHOST") == 0)
	    {
		proxy_redirect_event(client, args, 1, "event 302", -1, "event 401", 1, NULL);
	    }
	    else if (strcmp(cmd, "MODE") == 0)
	    {
		/* convert dots to spaces */
		gchar *slist, *str, mode;
		gint argc;

		p = strchr(args, ' ');
		if (p != NULL) *p++ = '\0';
		mode = p == NULL ? '\0' : *p;

		slist = g_strdup(args);
		argc = 1;
		for (p = slist; *p != '\0'; p++)
		{
		    if (*p == ',')
		    {
			*p = ' ';
			argc++;
		    }
		}

		/* get channel mode / bans / exception / invite list */
		str = g_strdup_printf("%s %s", args, slist);
		switch (mode)
		{
		    case '\0':
                        while (argc-- > 0)
			    proxy_redirect_event(client, str, 3, "event 403", 1,
						 "event 443", 1, "event 324", 1, NULL);
			break;
		    case 'b':
                        while (argc-- > 0)
			    proxy_redirect_event(client, str, 2, "event 403", 1,
						 "event 368", 1, "event 367", 1, NULL);
			break;
		    case 'e':
			while (argc-- > 0)
			    proxy_redirect_event(client, str, 4, "event 403", 1,
						 "event 482", 1, "event 472", -1,
						 "event 349", 1, "event 348", 1, NULL);
			break;
		    case 'I':
                        while (argc-- > 0)
			    proxy_redirect_event(client, str, 4, "event 403", 1,
						 "event 482", 1, "event 472", -1,
						 "event 347", 1, "event 346", 1, NULL);
			break;
		}
		g_free(str);
		g_free(slist);
	    }
	}
	g_free(cmd);
    }
}