Ejemplo n.º 1
0
Archivo: irc.c Proyecto: VoxOx/VoxOx
static void irc_close(GaimConnection *gc)
{
	struct irc_conn *irc = gc->proto_data;

	if (irc == NULL)
		return;

	if (irc->gsc || (irc->fd >= 0))
		irc_cmd_quit(irc, "quit", NULL, NULL);

	if (gc->inpa)
		gaim_input_remove(gc->inpa);

	g_free(irc->inbuf);
	if (irc->gsc) {
		gaim_ssl_close(irc->gsc);
	} else if (irc->fd >= 0) {
		close(irc->fd);
	}
	if (irc->timer)
		gaim_timeout_remove(irc->timer);
	g_hash_table_destroy(irc->cmds);
	g_hash_table_destroy(irc->msgs);
	g_hash_table_destroy(irc->buddies);
	if (irc->motd)
		g_string_free(irc->motd, TRUE);
	g_free(irc->server);

	if (irc->writeh)
		gaim_input_remove(irc->writeh);

	gaim_circ_buffer_destroy(irc->outbuf);

	g_free(irc);
}
Ejemplo n.º 2
0
Archivo: si.c Proyecto: VoxOx/VoxOx
static void
jabber_si_xfer_bytestreams_send_read_again_resp_cb(gpointer data, gint source,
		GaimInputCondition cond)
{
	GaimXfer *xfer = data;
	JabberSIXfer *jsx = xfer->data;
	int len;

	len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen);
	if (len < 0 && errno == EAGAIN)
		return;
	else if (len < 0) {
		gaim_input_remove(xfer->watcher);
		xfer->watcher = 0;
		g_free(jsx->rxqueue);
		jsx->rxqueue = NULL;
		close(source);
		gaim_xfer_cancel_remote(xfer);
		return;
	}
	jsx->rxlen += len;

	if (jsx->rxlen < jsx->rxmaxlen)
		return;

	gaim_input_remove(xfer->watcher);
	xfer->watcher = 0;
	g_free(jsx->rxqueue);
	jsx->rxqueue = NULL;

	gaim_xfer_start(xfer, source, NULL, -1);
}
Ejemplo n.º 3
0
/* just in case you were wondering, this is why DCC is gay */
static void irc_dccsend_send_read(gpointer data, int source, GaimInputCondition cond)
{
	GaimXfer *xfer = data;
	struct irc_xfer_send_data *xd = xfer->data;
	char *buffer[16];
	int len;

	len = read(source, buffer, sizeof(buffer));

	if (len < 0 && errno == EAGAIN)
		return;
	else if (len <= 0) {
		/* XXX: Shouldn't this be canceling the transfer? */
		gaim_input_remove(xd->inpa);
		xd->inpa = 0;
		return;
	}

	xd->rxqueue = g_realloc(xd->rxqueue, len + xd->rxlen);
	memcpy(xd->rxqueue + xd->rxlen, buffer, len);
	xd->rxlen += len;

	while (1) {
		size_t acked;

		if (xd->rxlen < 4)
			break;

		acked = ntohl(*((gint32 *)xd->rxqueue));

		xd->rxlen -= 4;
		if (xd->rxlen) {
			unsigned char *tmp = g_memdup(xd->rxqueue + 4, xd->rxlen);
			g_free(xd->rxqueue);
			xd->rxqueue = tmp;
		} else {
			g_free(xd->rxqueue);
			xd->rxqueue = NULL;
		}

		if (acked >= gaim_xfer_get_size(xfer)) {
			gaim_input_remove(xd->inpa);
			xd->inpa = 0;
			gaim_xfer_set_completed(xfer, TRUE);
			gaim_xfer_end(xfer);
			return;
		}
	}
}
Ejemplo n.º 4
0
static void gaym_close(GaimConnection * gc)
{
    struct gaym_conn *gaym = gc->proto_data;

    gaim_debug_misc("gaym", "gaym close function has been called\n");
    if (gaym == NULL)
        return;

    gaym_cmd_quit(gaym, "quit", NULL, NULL);

    if (gc->inpa)
        gaim_input_remove(gc->inpa);

    g_free(gaym->inbuf);
    gaim_debug_misc("gaym", "closing fd %i\n", gaym->fd);
    close(gaym->fd);

    if (gaym->timer)
        gaim_timeout_remove(gaym->timer);

    if (gaym->thumbnail)
        g_free(gaym->thumbnail);

    if (gaym->chat_key)
        g_free(gaym->chat_key);

    if (gaym->server_bioline)
        g_free(gaym->server_bioline);

    if (gaym->server_stats)
        g_free(gaym->server_stats);

    if (gaym->roomlist_filter)
        g_free(gaym->roomlist_filter);

    if (gaym->bio)
        g_free(gaym->bio);

    g_hash_table_destroy(gaym->cmds);
    g_hash_table_destroy(gaym->msgs);
    g_hash_table_destroy(gaym->info_window_needed);
    g_hash_table_destroy(gaym->entry_order);
    if (gaym->motd)
        g_string_free(gaym->motd, TRUE);

    if (gaym->names)
        g_string_free(gaym->names, TRUE);

    if (gaym->nameconv)
        g_free(gaym->nameconv);
    if (gaym->subroom)
        g_free(gaym->subroom);

    g_hash_table_destroy(gaym->confighash);

    g_hash_table_foreach(gaym->hammers, (GHFunc)kill_hammer, NULL);

    g_free(gaym->server);
    g_free(gaym);
}
Ejemplo n.º 5
0
void
gaim_xfer_end(GaimXfer *xfer)
{
	g_return_if_fail(xfer != NULL);

	/* See if we are actually trying to cancel this. */
	if (!xfer->completed) {
		gaim_xfer_cancel_local(xfer);
		return;
	}

	if (xfer->ops.end != NULL)
		xfer->ops.end(xfer);

	if (xfer->watcher != 0) {
		gaim_input_remove(xfer->watcher);
		xfer->watcher = 0;
	}

	if (xfer->fd != 0)
		close(xfer->fd);

	if (xfer->dest_fp != NULL) {
		fclose(xfer->dest_fp);
		xfer->dest_fp = NULL;
	}
}
Ejemplo n.º 6
0
void
msn_servconn_destroy(MsnServConn *servconn)
{
	g_return_if_fail(servconn != NULL);

	if (servconn->processing)
	{
		servconn->wasted = TRUE;
		return;
	}

	if (servconn->connected)
		msn_servconn_disconnect(servconn);

	if (servconn->destroy_cb)
		servconn->destroy_cb(servconn);

	if (servconn->httpconn != NULL)
		msn_httpconn_destroy(servconn->httpconn);

	g_free(servconn->host);

	gaim_circ_buffer_destroy(servconn->tx_buf);
	if (servconn->tx_handler > 0)
		gaim_input_remove(servconn->tx_handler);

	msn_cmdproc_destroy(servconn->cmdproc);
	g_free(servconn);
}
Ejemplo n.º 7
0
Archivo: irc.c Proyecto: VoxOx/VoxOx
static void
irc_send_cb(gpointer data, gint source, GaimInputCondition cond)
{
	struct irc_conn *irc = data;
	int ret, writelen;

	writelen = gaim_circ_buffer_get_max_read(irc->outbuf);

	if (writelen == 0) {
		gaim_input_remove(irc->writeh);
		irc->writeh = 0;
		return;
	}

	ret = do_send(irc, irc->outbuf->outptr, writelen);

	if (ret < 0 && errno == EAGAIN)
		return;
	else if (ret <= 0) {
		gaim_connection_error(gaim_account_get_connection(irc->account),
			      _("Server has disconnected"));
		return;
	}

	gaim_circ_buffer_mark_read(irc->outbuf, ret);

#if 0
	/* We *could* try to write more if we wrote it all */
	if (ret == write_len) {
		irc_send_cb(data, source, cond);
	}
#endif
}
Ejemplo n.º 8
0
static void
servconn_write_cb(gpointer data, gint source, GaimInputCondition cond)
{
	MsnServConn *servconn = data;
	int ret, writelen;

	writelen = gaim_circ_buffer_get_max_read(servconn->tx_buf);

	if (writelen == 0) {
		gaim_input_remove(servconn->tx_handler);
		servconn->tx_handler = -1;
		return;
	}

	ret = write(servconn->fd, servconn->tx_buf->outptr, writelen);

	if (ret < 0 && errno == EAGAIN)
		return;
	else if (ret <= 0) {
		msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE);
		return;
	}

	gaim_circ_buffer_mark_read(servconn->tx_buf, ret);
}
Ejemplo n.º 9
0
static void
yahoo_packet_send_can_write(gpointer data, gint source, GaimInputCondition cond)
{
	struct yahoo_data *yd = data;
	int ret, writelen;

	writelen = gaim_circ_buffer_get_max_read(yd->txbuf);

	if (writelen == 0) {
		gaim_input_remove(yd->txhandler);
		yd->txhandler = -1;
		return;
	}

	ret = write(yd->fd, yd->txbuf->outptr, writelen);

	if (ret < 0 && errno == EAGAIN)
		return;
	else if (ret < 0) {
		/* TODO: what to do here - do we really have to disconnect? */
		gaim_connection_error(yd->gc, _("Write Error"));
		return;
	}

	gaim_circ_buffer_mark_read(yd->txbuf, ret);
}
Ejemplo n.º 10
0
static void _qq_s5_canwrite(gpointer data, gint source, GaimInputCondition cond)
{
	unsigned char buf[512];
	int i;
	struct PHB *phb = data;
	unsigned int len;
	int error = ETIMEDOUT;

	gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Connected.\n");

	if (phb->inpa > 0)
		gaim_input_remove(phb->inpa);

	len = sizeof(error);
	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
		gaim_debug(GAIM_DEBUG_INFO, "getsockopt", "%s\n", strerror(errno));
		close(source);
		if (phb->account == NULL || gaim_account_get_connection(phb->account) != NULL) {

			phb->func(phb->data, -1, _("Unable to connect"));
		}

		g_free(phb->host);
		g_free(phb);
		return;
	}
	fcntl(source, F_SETFL, 0);

	i = 0;
	buf[0] = 0x05;		/* SOCKS version 5 */

	if (gaim_proxy_info_get_username(phb->gpi) != NULL) {
		buf[1] = 0x02;	/* two methods */
		buf[2] = 0x00;	/* no authentication */
		buf[3] = 0x02;	/* username/password authentication */
		i = 4;
	} else {
		buf[1] = 0x01;
		buf[2] = 0x00;
		i = 3;
	}

	if (write(source, buf, i) < i) {
		gaim_debug(GAIM_DEBUG_INFO, "write", "%s\n", strerror(errno));
		gaim_debug(GAIM_DEBUG_ERROR, "socks5 proxy", "Unable to write\n");
		close(source);

		if (phb->account == NULL || gaim_account_get_connection(phb->account) != NULL) {

			phb->func(phb->data, -1, _("Unable to connect"));
		}

		g_free(phb->host);
		g_free(phb);
		return;
	}

	phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, _qq_s5_canread, phb);
}
Ejemplo n.º 11
0
/* just in case you were wondering, this is why DCC is gay */
static void gaym_dccsend_send_read(gpointer data, int source, GaimInputCondition cond)
{
	GaimXfer *xfer = data;
	struct gaym_xfer_send_data *xd = xfer->data;
	char *buffer[16];
	int len;

	if ((len = read(source, buffer, sizeof(buffer))) <= 0) {
		gaim_input_remove(xd->inpa);
		xd->inpa = 0;
		return;
	}

	xd->rxqueue = g_realloc(xd->rxqueue, len + xd->rxlen);
	memcpy(xd->rxqueue + xd->rxlen, buffer, len);
	xd->rxlen += len;

	while (1) {
		int acked;

		if (xd->rxlen < 4)
			break;

		acked = ntohl(*((gint32 *)xd->rxqueue));

		xd->rxlen -= 4;
		if (xd->rxlen) {
			char *tmp = g_memdup(xd->rxqueue + 4, xd->rxlen);
			g_free(xd->rxqueue);
			xd->rxqueue = tmp;
		} else {
			g_free(xd->rxqueue);
			xd->rxqueue = NULL;
		}

		if (acked >= gaim_xfer_get_size(xfer)) {
			gaim_input_remove(xd->inpa);
			xd->inpa = 0;
			gaim_xfer_set_completed(xfer, TRUE);
			gaim_xfer_end(xfer);
			return;
		}


	}
}
Ejemplo n.º 12
0
static gboolean
    parse_redirect(const char *data, size_t data_len, gint sock,
                   GaimFetchUrlData *gfud)
{
  gchar *s;

  if ((s = g_strstr_len(data, data_len, "Location: ")) != NULL)
  {
    gchar *new_url, *temp_url, *end;
    gboolean full;
    int len;

    s += strlen("Location: ");
    end = strchr(s, '\r');

    /* Just in case :) */
    if (end == NULL)
      end = strchr(s, '\n');

    len = end - s;

    new_url = g_malloc(len + 1);
    strncpy(new_url, s, len);
    new_url[len] = '\0';

    full = gfud->full;

    if (*new_url == '/' || g_strstr_len(new_url, len, "://") == NULL)
    {
      temp_url = new_url;

      new_url = g_strdup_printf("%s:%d%s", gfud->website.address,
                                gfud->website.port, temp_url);

      g_free(temp_url);

      full = FALSE;
    }

    /* Close the existing stuff. */
    gaim_input_remove(gfud->inpa);
    close(sock);

    gaim_debug_info("gaim_url_fetch", "Redirecting to %s\n", new_url);

    /* Try again, with this new location. */
    gaim_url_fetch(new_url, full, gfud->user_agent, gfud->http11,
                   gfud->callback, gfud->user_data);

    /* Free up. */
    g_free(new_url);
    destroy_fetch_url_data(gfud);

    return TRUE;
  }

  return FALSE;
}
Ejemplo n.º 13
0
static void
sippy_logout(GaimConnection *gc)
{
   if (!gaginitialized) {return;}
   gaim_debug(GAIM_DEBUG_INFO,"sippy","sending LOGOUT to gag aor=%s\n",gc->account->username);
   sippy_send_command( SIMPLE_LOGOUT );
   sippy_send_string( gc->account->username );
   gaim_debug(GAIM_DEBUG_INFO,"sippy","Removing gag's gaim_input\n");
   gaim_input_remove(gc->inpa);
}
Ejemplo n.º 14
0
static void yahoo_roomlist_destroy(struct yahoo_roomlist *yrl)
{
	if (yrl->inpa)
		gaim_input_remove(yrl->inpa);
	g_free(yrl->txbuf);
	g_free(yrl->rxqueue);
	g_free(yrl->path);
	g_free(yrl->host);
	if (yrl->parse)
		g_markup_parse_context_free(yrl->parse);
	g_free(yrl);
}
Ejemplo n.º 15
0
static void
connect_cb(gpointer data, gint source, const gchar *error_message)
{
	MsnDirectConn* directconn;
	int fd;

	gaim_debug_misc("msn", "directconn: connect_cb: %d\n", source);

	directconn = data;
	directconn->connect_data = NULL;

	if (TRUE)
	{
		fd = source;
	}
	else
	{
		struct sockaddr_in client_addr;
		unsigned int client;
		fd = accept (source, (struct sockaddr *)&client_addr, &client);
	}

	directconn->fd = fd;

	if (fd > 0)
	{
		directconn->inpa = gaim_input_add(fd, GAIM_INPUT_READ, read_cb,
										  directconn);

		if (TRUE)
		{
			/* Send foo. */
			msn_directconn_write(directconn, "foo", strlen("foo") + 1);

			/* Send Handshake */
			msn_directconn_send_handshake(directconn);
		}
		else
		{
		}
	}
	else
	{
		/* ERROR */
		gaim_debug_error("msn", "could not add input\n");

		if (directconn->inpa)
			gaim_input_remove(directconn->inpa);

		close(directconn->fd);
	}
}
Ejemplo n.º 16
0
void
msn_servconn_disconnect(MsnServConn *servconn)
{
	g_return_if_fail(servconn != NULL);

	if (!servconn->connected)
	{
		/* We could not connect. */
		if (servconn->disconnect_cb != NULL)
			servconn->disconnect_cb(servconn);

		return;
	}

	if (servconn->session->http_method)
	{
		/* Fake disconnection. */
		if (servconn->disconnect_cb != NULL)
			servconn->disconnect_cb(servconn);

		return;
	}

	if (servconn->connect_data != NULL)
	{
		gaim_proxy_connect_cancel(servconn->connect_data);
		servconn->connect_data = NULL;
	}

	if (servconn->inpa > 0)
	{
		gaim_input_remove(servconn->inpa);
		servconn->inpa = 0;
	}

	close(servconn->fd);

	servconn->rx_buf = NULL;
	servconn->rx_len = 0;
	servconn->payload_len = 0;

	servconn->connected = FALSE;

	if (servconn->disconnect_cb != NULL)
		servconn->disconnect_cb(servconn);
}
Ejemplo n.º 17
0
static void gaym_dccsend_send_destroy(GaimXfer *xfer)
{
	struct gaym_xfer_send_data *xd = xfer->data;

	if (xd == NULL)
		return;

	if (xd->inpa > 0)
		gaim_input_remove(xd->inpa);
	if (xd->fd != -1)
		close(xd->fd);

	if (xd->rxqueue)
		g_free(xd->rxqueue);

	g_free(xd);
}
Ejemplo n.º 18
0
void
msn_directconn_destroy(MsnDirectConn *directconn)
{
	if (directconn->connect_data != NULL)
		gaim_proxy_connect_cancel(directconn->connect_data);

	if (directconn->inpa != 0)
		gaim_input_remove(directconn->inpa);

	if (directconn->fd >= 0)
		close(directconn->fd);

	if (directconn->nonce != NULL)
		g_free(directconn->nonce);

	directconn->slplink->directconn = NULL;

	g_free(directconn);
}
Ejemplo n.º 19
0
static void irc_dccsend_send_destroy(GaimXfer *xfer)
{
	struct irc_xfer_send_data *xd = xfer->data;

	if (xd == NULL)
		return;

	if (xd->listen_data != NULL)
		gaim_network_listen_cancel(xd->listen_data);
	if (xd->inpa > 0)
		gaim_input_remove(xd->inpa);
	if (xd->fd != -1)
		close(xd->fd);

	if (xd->rxqueue)
		g_free(xd->rxqueue);

	g_free(xd);
}
Ejemplo n.º 20
0
Archivo: dnssrv.c Proyecto: VoxOx/VoxOx
void
gaim_srv_cancel(GaimSrvQueryData *query_data)
{
	if (query_data->handle > 0)
		gaim_input_remove(query_data->handle);
#ifdef _WIN32
	if (query_data->resolver != NULL)
	{
		/*
		 * It's not really possible to kill a thread.  So instead we
		 * just set the callback to NULL and let the DNS lookup
		 * finish.
		 */
		query_data->cb = NULL;
		return;
	}
	g_free(query_data->query);
	g_free(query_data->error_message);
#endif
	g_free(query_data);
}
Ejemplo n.º 21
0
static void ice_process_messages(gpointer data, gint fd,
                                 GaimInputCondition condition) {
    struct ice_connection_info *conninfo = (struct ice_connection_info*) data;
    IceProcessMessagesStatus status;

    /* please don't block... please! */
    status = IceProcessMessages(conninfo->connection, NULL, NULL);

    if (status == IceProcessMessagesIOError) {
        gaim_debug(GAIM_DEBUG_INFO, "Session Management",
                   "ICE IO error, closing connection... ");

        /* IO error, please disconnect */
        IceSetShutdownNegotiation(conninfo->connection, False);
        IceCloseConnection(conninfo->connection);

        gaim_debug(GAIM_DEBUG_INFO, "Session Management", "done.");

        /* cancel the handler */
        gaim_input_remove(conninfo->input_id);
    }
}
Ejemplo n.º 22
0
void
gaim_ssl_close(GaimSslConnection *gsc)
{
	GaimSslOps *ops;

	g_return_if_fail(gsc != NULL);

	ops = gaim_ssl_get_ops();
	(ops->close)(gsc);

	if (gsc->connect_data != NULL)
		gaim_proxy_connect_cancel(gsc->connect_data);

	if (gsc->inpa > 0)
		gaim_input_remove(gsc->inpa);

	if (gsc->fd >= 0)
		close(gsc->fd);

	g_free(gsc->host);
	g_free(gsc);
}
Ejemplo n.º 23
0
void
gaim_xfer_cancel_remote(GaimXfer *xfer)
{
	GaimXferUiOps *ui_ops;

	g_return_if_fail(xfer != NULL);

	if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND)
	{
		if (xfer->ops.cancel_send != NULL)
			xfer->ops.cancel_send(xfer);
	}
	else
	{
		if (xfer->ops.cancel_recv != NULL)
			xfer->ops.cancel_recv(xfer);
	}	

	if (xfer->watcher != 0) {
		gaim_input_remove(xfer->watcher);
		xfer->watcher = 0;
	}

	if (xfer->fd != 0)
		close(xfer->fd);

	if (xfer->dest_fp != NULL) {
		fclose(xfer->dest_fp);
		xfer->dest_fp = NULL;
	}

	ui_ops = gaim_xfer_get_ui_ops(xfer);

	if (ui_ops != NULL && ui_ops->cancel_remote != NULL)
		ui_ops->cancel_remote(xfer);

	xfer->bytes_remaining = 0;
}
Ejemplo n.º 24
0
Archivo: si.c Proyecto: VoxOx/VoxOx
static void
jabber_si_xfer_bytestreams_send_connected_cb(gpointer data, gint source,
		GaimInputCondition cond)
{
	GaimXfer *xfer = data;
	int acceptfd;

	gaim_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_connected_cb\n");

	acceptfd = accept(source, NULL, 0);
	if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
		return;
	else if(acceptfd == -1) {
		gaim_debug_warning("jabber", "accept: %s\n", strerror(errno));
		return;
	}

	gaim_input_remove(xfer->watcher);
	close(source);

	xfer->watcher = gaim_input_add(acceptfd, GAIM_INPUT_READ,
			jabber_si_xfer_bytestreams_send_read_cb, xfer);
}
Ejemplo n.º 25
0
static void _qq_s5_readauth(gpointer data, gint source, GaimInputCondition cond)
{
	unsigned char buf[512];
	struct PHB *phb = data;

	gaim_input_remove(phb->inpa);
	gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Got auth response.\n");

	if (read(source, buf, 2) < 2) {
		close(source);

		if (phb->account == NULL || gaim_account_get_connection(phb->account) != NULL) {

			phb->func(phb->data, -1, _("Unable to connect"));
		}

		g_free(phb->host);
		g_free(phb);
		return;
	}

	if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
		close(source);

		if (phb->account == NULL || gaim_account_get_connection(phb->account) != NULL) {

			phb->func(phb->data, -1, _("Unable to connect"));
		}

		g_free(phb->host);
		g_free(phb);
		return;
	}

	_qq_s5_sendconnect(phb, source);
}
Ejemplo n.º 26
0
static void irc_dccsend_send_connected(gpointer data, int source, GaimInputCondition cond) {
	GaimXfer *xfer = (GaimXfer *) data;
	struct irc_xfer_send_data *xd = xfer->data;
	int conn;

	conn = accept(xd->fd, NULL, 0);
	if (conn == -1) {
		/* Accepting the connection failed. This could just be related
		 * to the nonblocking nature of the listening socket, so we'll
		 * just try again next time */
		/* Let's print an error message anyway */
		gaim_debug_warning("irc", "accept: %s\n", strerror(errno));
		return;
	}

	gaim_input_remove(xfer->watcher);
	xfer->watcher = 0;
	close(xd->fd);
	xd->fd = -1;

	xd->inpa = gaim_input_add(conn, GAIM_INPUT_READ, irc_dccsend_send_read, xfer);
	/* Start the transfer */
	gaim_xfer_start(xfer, conn, NULL, 0);
}
Ejemplo n.º 27
0
// This is a modified version of gaim's url_fetched_cb function. It has
// been
// modified to pass cookies during requests. The cookies are set in
// user_data,
// cast as a GaimUrlSession item. Any cookies in the response are added to 
// 
// 
// 
// 
// this
// structure, as well.
static void
session_fetched_cb(gpointer url_data, gint sock, GaimInputCondition cond)
{

    GaimFetchUrlData *gfud = url_data;
    char data;
    gboolean got_eof = FALSE;
    if (sock == -1) {
        gfud->callback(gfud->user_data, NULL, 0);

        destroy_fetch_url_data(gfud);

        return;
    }

    if (!gfud->sentreq) {
        char buf[2048];

        if (gfud->session->cookies == NULL)
            gfud->session->cookies = g_strdup("");

        if (gfud->user_agent) {
            /* Host header is not forbidden in HTTP/1.0 requests, and
               HTTP/1.1 clients must know how to handle the "chunked"
               transfer encoding. Gaim doesn't know how to handle
               "chunked", so should always send the Host header
               regardless, to get around some observed problems */
            g_snprintf(buf, sizeof(buf), "GET %s%s HTTP/%s\r\n" "User-Agent: %s\r\n" "Host: %s\r\n" "Cookie: %s\r\n",   // (1) 
                                                                                                                        // 
                       // 
                       // 
                       // 
                       // (see 
                       // above)
                       (gfud->full ? "" : "/"),
                       (gfud->full ? gfud->url : gfud->website.page),
                       (gfud->http11 ? "1.1" : "1.0"),
                       gfud->user_agent, gfud->website.address,
                       gfud->session->cookies);
        } else {
            g_snprintf(buf, sizeof(buf), "GET %s%s HTTP/%s\r\n" "Host: %s\r\n" "Accept-Encoding: identity\r\n" "Cookie: %s\r\n",        // (1) 
                                                                                                                                        // 
                       // 
                       // 
                       // 
                       // See 
                       // above
                       (gfud->full ? "" : "/"),
                       (gfud->full ? gfud->url : gfud->website.page),
                       (gfud->http11 ? "1.1" : "1.0"),
                       gfud->website.address, gfud->session->cookies);
        }
        if (gfud->session->hasFormData)
            strcat(buf,
                   "Content-Type: application/x-www-form-urlencoded\r\n\r\n");
        else
            strcat(buf, "\r\n");
        gaim_debug_misc("gaim_url_fetch", "Request: %s\n", buf);

        write(sock, buf, strlen(buf));
        fcntl(sock, F_SETFL, O_NONBLOCK);
        gfud->sentreq = TRUE;
        gfud->inpa = gaim_input_add(sock, GAIM_INPUT_READ,
                                    session_fetched_cb, url_data);
        gfud->data_len = 4096;
        gfud->webdata = g_malloc(gfud->data_len);

        return;
    }

    if (read(sock, &data, 1) > 0 || errno == EWOULDBLOCK) {
        if (errno == EWOULDBLOCK) {
            errno = 0;

            return;
        }

        gfud->len++;

        if (gfud->len == gfud->data_len + 1) {
            gfud->data_len += (gfud->data_len) / 2;

            gfud->webdata = g_realloc(gfud->webdata, gfud->data_len);
        }

        gfud->webdata[gfud->len - 1] = data;

        if (!gfud->startsaving) {
            if (data == '\r')
                return;

            if (data == '\n') {
                if (gfud->newline) {
                    size_t content_len;
                    gfud->startsaving = TRUE;

                    gaim_debug_misc("gaim_url_fetch",
                                    "Response headers: '%*.*s'\n",
                                    gfud->len, gfud->len, gfud->webdata);

                    // JBL 10-16-2004: Put cookies into session
                    gaim_debug(GAIM_DEBUG_MISC, "gaym",
                               "Parsing cookies...");

                    parse_cookies(gfud->webdata, gfud->session, gfud->len);
                    gaim_debug(GAIM_DEBUG_MISC, "gaym",
                               "Found cookies: %s\n",
                               (gfud->session->cookies));
                    gaim_debug_misc("gaim_url_fetch",
                                    "Parsing of cookies successful\n");
                    /* See if we can find a redirect. */
                    if (parse_redirect
                        (gfud->webdata, gfud->len, sock, gfud))
                        return;

                    /* No redirect. See if we can find a content length. */
                    content_len =
                        parse_content_len(gfud->webdata, gfud->len);

                    if (content_len == 0) {
                        /* We'll stick with an initial 8192 */
                        content_len = 8192;
                    } else {
                        gfud->has_explicit_data_len = TRUE;
                    }

                    /* Out with the old... */
                    gfud->len = 0;
                    g_free(gfud->webdata);
                    gfud->webdata = NULL;

                    /* In with the new. */
                    gfud->data_len = content_len;
                    gfud->webdata = g_try_malloc(gfud->data_len);
                    if (gfud->webdata == NULL) {
                        gaim_debug_error("gaim_url_fetch",
                                         "Failed to allocate %u bytes: %s\n",
                                         gfud->data_len, strerror(errno));
                        gaim_input_remove(gfud->inpa);
                        close(sock);
                        gfud->callback(gfud->user_data, NULL, 0);
                        destroy_fetch_url_data(gfud);
                    }
                } else
                    gfud->newline = TRUE;

                return;
            }

            gfud->newline = FALSE;
        } else if (gfud->has_explicit_data_len
                   && gfud->len == gfud->data_len) {
            got_eof = TRUE;
        }
    } else if (errno != ETIMEDOUT) {
        got_eof = TRUE;
    } else {
        gaim_input_remove(gfud->inpa);
        close(sock);

        gfud->callback(gfud->user_data, NULL, 0);

        destroy_fetch_url_data(gfud);
    }

    if (got_eof) {
        gfud->webdata = g_realloc(gfud->webdata, gfud->len + 1);
        gfud->webdata[gfud->len] = 0;

        /* gaim_debug_misc("gaim_url_fetch", "Received: '%s'\n",
           gfud->webdata); */

        gaim_input_remove(gfud->inpa);
        close(sock);
        gfud->callback(gfud->user_data, gfud->webdata, gfud->len);

        destroy_fetch_url_data(gfud);
    }
}
Ejemplo n.º 28
0
static void _qq_s5_canread(gpointer data, gint source, GaimInputCondition cond)
{
	unsigned char buf[512];
	struct PHB *phb;
	int ret;

	phb = data;

	gaim_input_remove(phb->inpa);
	gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Able to read.\n");

	ret = read(source, buf, 2);
	if (ret < 2) {
		gaim_debug(GAIM_DEBUG_INFO, "s5_canread", "packet smaller than 2 octet\n");
		close(source);

		if (phb->account == NULL || gaim_account_get_connection(phb->account) != NULL) {

			phb->func(phb->data, -1, _("Unable to connect"));
		}

		g_free(phb->host);
		g_free(phb);
		return;
	}

	if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
		gaim_debug(GAIM_DEBUG_INFO, "s5_canread", "unsupport\n");
		close(source);

		if (phb->account == NULL || gaim_account_get_connection(phb->account) != NULL) {

			phb->func(phb->data, -1, _("Unable to connect"));
		}

		g_free(phb->host);
		g_free(phb);
		return;
	}

	if (buf[1] == 0x02) {
		unsigned int i, j;

		i = strlen(gaim_proxy_info_get_username(phb->gpi));
		j = strlen(gaim_proxy_info_get_password(phb->gpi));

		buf[0] = 0x01;	/* version 1 */
		buf[1] = i;
		memcpy(buf + 2, gaim_proxy_info_get_username(phb->gpi), i);
		buf[2 + i] = j;
		memcpy(buf + 2 + i + 1, gaim_proxy_info_get_password(phb->gpi), j);

		if (write(source, buf, 3 + i + j) < 3 + i + j) {
			close(source);

			if (phb->account == NULL || gaim_account_get_connection(phb->account) != NULL) {

				phb->func(phb->data, -1, _("Unable to connect"));
			}

			g_free(phb->host);
			g_free(phb);
			return;
		}

		phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, _qq_s5_readauth, phb);
	} else {
		gaim_debug(GAIM_DEBUG_INFO, "s5_canread", "calling s5_sendconnect\n");
		_qq_s5_sendconnect(phb, source);
	}
}
Ejemplo n.º 29
0
Archivo: si.c Proyecto: VoxOx/VoxOx
static void
jabber_si_xfer_bytestreams_send_read_cb(gpointer data, gint source,
		GaimInputCondition cond)
{
	GaimXfer *xfer = data;
	JabberSIXfer *jsx = xfer->data;
	int i;
	int len;
	char buffer[256];

	gaim_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_cb\n");

	xfer->fd = source;

	if(jsx->rxlen < 2) {
		gaim_debug_info("jabber", "reading those first two bytes\n");
		len = read(source, buffer, 2 - jsx->rxlen);
		if(len < 0 && errno == EAGAIN)
			return;
		else if(len <= 0) {
			gaim_input_remove(xfer->watcher);
			xfer->watcher = 0;
			close(source);
			gaim_xfer_cancel_remote(xfer);
			return;
		}
		jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen);
		memcpy(jsx->rxqueue + jsx->rxlen, buffer, len);
		jsx->rxlen += len;
		return;
	} else if(jsx->rxlen - 2 <  jsx->rxqueue[1]) {
		gaim_debug_info("jabber", "reading the next umpteen bytes\n");
		len = read(source, buffer, jsx->rxqueue[1] + 2 - jsx->rxlen);
		if(len < 0 && errno == EAGAIN)
			return;
		else if(len <= 0) {
			gaim_input_remove(xfer->watcher);
			xfer->watcher = 0;
			close(source);
			gaim_xfer_cancel_remote(xfer);
			return;
		}
		jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen);
		memcpy(jsx->rxqueue + jsx->rxlen, buffer, len);
		jsx->rxlen += len;
	}

	if(jsx->rxlen -2 < jsx->rxqueue[1])
		return;

	gaim_input_remove(xfer->watcher);
	xfer->watcher = 0;

	gaim_debug_info("jabber", "checking to make sure we're socks FIVE\n");

	if(jsx->rxqueue[0] != 0x05) {
		close(source);
		gaim_xfer_cancel_remote(xfer);
		return;
	}

	gaim_debug_info("jabber", "going to test %hhu different methods\n", jsx->rxqueue[1]);

	for(i=0; i<jsx->rxqueue[1]; i++) {

		gaim_debug_info("jabber", "testing %hhu\n", jsx->rxqueue[i+2]);
		if(jsx->rxqueue[i+2] == 0x00) {
			g_free(jsx->rxqueue);
			jsx->rxlen = 0;
			jsx->rxmaxlen = 2;
			jsx->rxqueue = g_malloc(jsx->rxmaxlen);
			jsx->rxqueue[0] = 0x05;
			jsx->rxqueue[1] = 0x00;
			xfer->watcher = gaim_input_add(source, GAIM_INPUT_WRITE,
				jabber_si_xfer_bytestreams_send_read_response_cb,
				xfer);
			jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
				source, GAIM_INPUT_WRITE);
			jsx->rxqueue = NULL;
			jsx->rxlen = 0;
			return;
		}
	}

	g_free(jsx->rxqueue);
	jsx->rxlen = 0;
	jsx->rxmaxlen = 2;
	jsx->rxqueue = g_malloc(jsx->rxmaxlen);
	jsx->rxqueue[0] = 0x05;
	jsx->rxqueue[1] = 0xFF;
	xfer->watcher = gaim_input_add(source, GAIM_INPUT_WRITE,
		jabber_si_xfer_bytestreams_send_read_response_cb, xfer);
	jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
		source, GAIM_INPUT_WRITE);
}
Ejemplo n.º 30
0
static void _qq_s5_canread_again(gpointer data, gint source, GaimInputCondition cond)
{
	unsigned char buf[512];
	struct PHB *phb = data;
	struct sockaddr_in sin;
	int len, error;
	socklen_t errlen;

	gaim_input_remove(phb->inpa);
	gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Able to read again.\n");

	len = read(source, buf, 10);
	if (len < 10) {
		gaim_debug(GAIM_DEBUG_WARNING, "socks5 proxy", "or not...\n");
		close(source);

		if (phb->account == NULL || gaim_account_get_connection(phb->account) != NULL) {

			phb->func(phb->data, source, NULL);
		}

		g_free(phb->host);
		g_free(phb);
		return;
	}
	if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
		if ((buf[0] == 0x05) && (buf[1] < 0x09))
			gaim_debug(GAIM_DEBUG_ERROR, "socks5 proxy", "socks5 error: %x\n", buf[1]);
		else
			gaim_debug(GAIM_DEBUG_ERROR, "socks5 proxy", "Bad data.\n");
		close(source);

		if (phb->account == NULL || gaim_account_get_connection(phb->account) != NULL) {

			phb->func(phb->data, -1, _("Unable to connect"));
		}

		g_free(phb->host);
		g_free(phb);
		return;
	}

	sin.sin_family = AF_INET;
	memcpy(&sin.sin_addr.s_addr, buf + 4, 4);
	memcpy(&sin.sin_port, buf + 8, 2);

	if (connect(phb->udpsock, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) < 0) {
		gaim_debug(GAIM_DEBUG_INFO, "s5_canread_again", "connect failed: %s\n", strerror(errno));
		close(phb->udpsock);
		close(source);
		g_free(phb->host);
		g_free(phb);
		return;
	}

	error = ETIMEDOUT;
	gaim_debug(GAIM_DEBUG_INFO, "QQ", "Connect didn't block\n");
	errlen = sizeof(error);
	if (getsockopt(phb->udpsock, SOL_SOCKET, SO_ERROR, &error, &errlen) < 0) {
		gaim_debug(GAIM_DEBUG_ERROR, "QQ", "getsockopt failed.\n");
		close(phb->udpsock);
		return;
	}
	fcntl(phb->udpsock, F_SETFL, 0);

	if (phb->account == NULL || gaim_account_get_connection(phb->account) != NULL) {
		phb->func(phb->data, phb->udpsock, NULL);
	}

	g_free(phb->host);
	g_free(phb);
}