[Xfce4-commits] <xfce4-weather-plugin:master> Remove old weather http code and complete libsoup migration.
Harald Judt
noreply at xfce.org
Tue Nov 20 20:18:10 CET 2012
Updating branch refs/heads/master
to ea0e5a5d5e9e6878d2a163c393c841bfd9ee1b00 (commit)
from aa5ef7f3044b5b2d40b7d588f40e97b449664c85 (commit)
commit ea0e5a5d5e9e6878d2a163c393c841bfd9ee1b00
Author: Harald Judt <h.judt at gmx.at>
Date: Tue Nov 20 20:05:47 2012 +0100
Remove old weather http code and complete libsoup migration.
panel-plugin/weather-http.c | 489 -------------------------------------------
panel-plugin/weather-http.h | 14 --
panel-plugin/weather.c | 1 -
3 files changed, 0 insertions(+), 504 deletions(-)
diff --git a/panel-plugin/weather-http.c b/panel-plugin/weather-http.c
index 491b0b4..6a8b6a9 100644
--- a/panel-plugin/weather-http.c
+++ b/panel-plugin/weather-http.c
@@ -20,500 +20,11 @@
#include <config.h>
#endif
-/* Some GLIBC library functions require the following #defines to
- * appear before the appropriate #includes, or compilation might
- * fail. */
-#define _XOPEN_SOURCE
-#define _XOPEN_SOURCE_EXTENDED 1
-#define _BSD_SOURCE
-
-#include <sys/select.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <netinet/in.h>
-#include <resolv.h>
-#include <signal.h>
-#include <setjmp.h>
-
#include <glib.h>
-#include <gtk/gtk.h>
-#include <libxfce4util/libxfce4util.h>
-#include <libxfce4panel/libxfce4panel.h>
#include "weather-http.h"
-
-#define WEATHER_MAX_CONN_TIMEOUT (10) /* connection timeout in seconds */
-#define WEATHER_RESCHEDULE_TIMEOUT (30 * 1000) /* reschedule timeout in ms */
-#define WEATHER_RESCHEDULE_N_TIMES (5) /* maximum number or reschedule tries */
-
-
-
-/* global */
-static GSList *queued_transfers = NULL;
-
-enum {
- STATUS_NOT_EXECUTED,
- STATUS_RUNNING,
- STATUS_SUCCEED,
- STATUS_RESCHEDULE,
- STATUS_ERROR,
- STATUS_LEAVE_IMMEDIATELY,
- STATUS_TIMEOUT
-};
-
-typedef struct _WeatherConnection WeatherConnection;
-struct _WeatherConnection {
- /* thread id */
- gint id;
-
- /* reschedule counter */
- guint counter;
-
- /* connection data */
- gchar *hostname;
- gchar *url;
- gchar *proxy_host;
- gint proxy_port;
-
- /* receive status */
- gint status;
-
- /* received data */
- gchar *received;
- size_t received_len;
-
- /* connection descriptor */
- gint fd;
-
- /* callback data */
- WeatherFunc cb_func;
- gpointer cb_user_data;
-};
-
-
-static gboolean
-weather_http_receive_data_check(WeatherConnection *connection,
- const GTimeVal timeout)
-{
- GTimeVal now;
-
- /* check if we need to leave */
- if (G_UNLIKELY(connection->status == STATUS_LEAVE_IMMEDIATELY))
- return TRUE;
-
- /* get the current time */
- g_get_current_time(&now);
-
- /* check if we timed out */
- if (G_UNLIKELY((gint) timeout.tv_sec +
- WEATHER_MAX_CONN_TIMEOUT < (gint) now.tv_sec)) {
- /* set status */
- connection->status = STATUS_TIMEOUT;
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-static void
-refresh_resolvers(void)
-{
-#ifdef G_OS_UNIX
- res_init();
-#endif /*G_OS_UNIX*/
-}
-
-
-#ifdef G_OS_UNIX
-static sigjmp_buf jmpenv;
-
-G_GNUC_NORETURN static void
-timeout_handler(gint sig)
-{
- siglongjmp(jmpenv, 1);
-}
-#endif /*G_OS_UNIX*/
-
-
-static gboolean
-weather_http_receive_data_idle(gpointer user_data)
-{
- WeatherConnection *connection = user_data;
- struct timeval select_timeout;
- struct addrinfo h, *r, *a;
- const gchar *p;
- gchar buffer[1024], *request, *port = NULL;
- gint bytes = 0, n, m = 0, err, cts_len;
- fd_set fds;
- GTimeVal timeout;
-
-#ifdef G_OS_UNIX
- void (*prev_handler) (gint);
-
- alarm(0);
- prev_handler = signal(SIGALRM, timeout_handler);
- if (sigsetjmp(jmpenv, 1)) {
- alarm(0);
- signal(SIGALRM, prev_handler);
- connection->status = STATUS_TIMEOUT;
- return FALSE;
- }
-#endif
- /* set the current time */
- g_get_current_time(&timeout);
-
- /* force the libc to get resolvers right, if they changed for some reason */
- refresh_resolvers();
-
- /* try to get the hostname */
-#ifdef G_OS_UNIX
- alarm(WEATHER_MAX_CONN_TIMEOUT);
-#endif
-
- memset(&h, 0, sizeof(h));
- h.ai_family = AF_UNSPEC;
- h.ai_socktype = SOCK_STREAM;
- h.ai_protocol = IPPROTO_TCP;
-
- if (connection->proxy_port)
- port = g_strdup_printf("%d", connection->proxy_port);
- else
- port = g_strdup("80");
-
- err = getaddrinfo(connection->proxy_host
- ? connection->proxy_host : connection->hostname,
- port, &h, &r);
-
- g_free(port);
-#ifdef G_OS_UNIX
- alarm(0);
- signal(SIGALRM, prev_handler);
-#endif
-
- if (G_UNLIKELY(err != 0)) {
- /* display error */
- g_message(_("Failed to get the hostname %s. Retry in %d seconds."),
- gai_strerror(err),
- WEATHER_RESCHEDULE_TIMEOUT / 1000);
-
- /* try again later */
- connection->status = STATUS_RESCHEDULE;
-
- return FALSE;
- }
-
- if (weather_http_receive_data_check(connection, timeout))
- return FALSE;
-
- /* open the socket */
- for (a = r; a != NULL; a = a->ai_next) {
- connection->fd = socket(a->ai_family, a->ai_socktype, a->ai_protocol);
- if (connection->fd < 0)
- continue;
-
-#ifdef G_OS_UNIX
- signal(SIGALRM, timeout_handler);
- alarm(WEATHER_MAX_CONN_TIMEOUT);
-#endif
-
- m = connect(connection->fd, a->ai_addr, a->ai_addrlen);
-
-#ifdef G_OS_UNIX
- alarm(0);
- signal(SIGALRM, prev_handler);
-#endif
-
- if (m == 0)
- break;
-
- if (weather_http_receive_data_check(connection, timeout))
- break;
- }
-
- if (G_UNLIKELY(connection->fd < 0)) {
- g_warning(_("Failed to open the socket(%s)."), g_strerror(errno));
- connection->status = STATUS_ERROR;
- return FALSE;
- }
-
- if (G_UNLIKELY(m < 0)) {
- g_warning(_("Failed to create a connection with the host(%s)."),
- g_strerror(errno));
- connection->status = STATUS_ERROR;
- return FALSE;
- }
-
- if (weather_http_receive_data_check(connection, timeout))
- return FALSE;
-
- /* create the request */
- if (connection->proxy_host)
- request = g_strdup_printf("GET http://%s%s HTTP/1.0\r\n\r\n",
- connection->hostname, connection->url);
- else
- request = g_strdup_printf("GET %s HTTP/1.%d\r\n"
- "Host: %s\r\n"
- "Connection: close\r\n"
- "\r\n",
- connection->url,
- strcmp(connection->hostname, "geoip.xfce.org")
- ? 1 : 0,
- connection->hostname);
-
- /* send the request */
- for (m = 0, n = strlen(request); m < n;) {
- /* send some info to the host */
- bytes = send(connection->fd, request + m, n - m, 0);
-
- if (weather_http_receive_data_check(connection, timeout)) {
- g_free(request);
- return FALSE;
- }
-
- /* check for problems */
- if (G_UNLIKELY(bytes < 0)) {
- /* just try again on EAGAIN/EINTR */
- if (G_LIKELY(errno != EAGAIN && errno != EINTR)) {
- g_warning(_("Failed to send the request(%s)."),
- g_strerror(errno));
- g_free(request);
- connection->status = STATUS_ERROR;
- return FALSE;
- }
- } else {
- /* advance the offset */
- m += bytes;
- }
- }
-
- /* cleanup the request */
- g_free(request);
-
- /* create an empty string */
- connection->received_len = 0;
-
- /* download the file content */
- FD_ZERO(&fds);
- do {
- /*
- * FIXME: recv() may block. send() and connect() may block too and the
- * only right solution is to rewrite whole code using non-blocking
- * sockets, but that's hard, connect() is already protected with alarm()
- * and send() blocks only when socket buffers are ultra-small
- */
- FD_SET(connection->fd, &fds);
- select_timeout.tv_sec = WEATHER_MAX_CONN_TIMEOUT;
- select_timeout.tv_usec = 0;
-
- m = select(connection->fd+1, &fds, 0, 0, &select_timeout);
- if (G_LIKELY(m == 1)) {
- bytes = recv(connection->fd, buffer,
- sizeof(buffer) - sizeof(gchar), 0);
- if (G_LIKELY(bytes > 0)) {
- /* prepend the downloaded data */
- connection->received =
- g_realloc(connection->received,
- connection->received_len + bytes);
- memcpy(connection->received + connection->received_len,
- buffer, bytes);
- connection->received_len += bytes;
- }
- }
-
- /* check for problems */
- if (G_UNLIKELY(m < 0 || bytes < 0)) {
- g_warning(_("Failed to receive data(%s)"), g_strerror(errno));
- connection->status = STATUS_ERROR;
- return FALSE;
- }
-
- if (weather_http_receive_data_check(connection, timeout))
- return FALSE;
- } while(bytes > 0);
-
- if (G_LIKELY(connection->received_len > 0)) {
- /* get the pointer to the content-length */
- cts_len = -1;
- p = strstr((char *) connection->received, "Content-Length:");
- if (G_LIKELY(p)) {
- /* advance the pointer */
- p += strlen("Content-Length:");
-
- cts_len = strtol(p, NULL, 10);
- if (G_UNLIKELY(cts_len < 0)) {
- g_warning(_("Negative content length"));
- connection->status = STATUS_ERROR;
- }
- } else {
- /* hack for geoip.xfce.org, which return no content-length */
- p = strstr((char *)connection->received, "<Response>");
- if (G_LIKELY(p))
- cts_len = connection->received_len - (p - connection->received);
- }
-
- if (cts_len > -1) {
- /* calculate the header length */
- n = connection->received_len - cts_len;
-
- if (G_LIKELY(n > 0)) {
- /* erase the header from the received string */
- void *tmp = g_malloc(cts_len+1);
- memcpy(tmp, connection->received+n, cts_len);
- ((gchar *) tmp)[cts_len] = 0;
- g_free(connection->received);
- connection->received = tmp;
- connection->received_len = cts_len;
- }
-
- connection->status = STATUS_SUCCEED;
- } else {
- g_warning(_("Unable to detect the content length."));
- connection->status = STATUS_ERROR;
- }
- } else {
- g_warning(_("No content received."));
- connection->status = STATUS_ERROR;
- }
- return FALSE;
-}
-
-
-static void
-weather_http_receive_data_destroyed(gpointer user_data)
-{
- WeatherConnection *connection = user_data;
-
- /* close the socket */
- if (connection->fd >= 0) {
- close(connection->fd);
- connection->fd = -1;
- }
-
- if (connection->status == STATUS_TIMEOUT)
- g_message("Connection timeout");
-
- if (connection->status == STATUS_SUCCEED && connection->cb_func) {
- /* execute the callback process */
- (*connection->cb_func) (TRUE,
- connection->received,
- connection->received_len,
- connection->cb_user_data);
- } else if (connection->status == STATUS_RESCHEDULE &&
- connection->counter < WEATHER_RESCHEDULE_N_TIMES) {
- /* cleanup the received data */
- if (connection->received) {
- g_free(connection->received);
- connection->received = NULL;
- }
-
- /* increase counter */
- connection->counter++;
-
- /* reschedule request */
- connection->id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE,
- WEATHER_RESCHEDULE_TIMEOUT,
- weather_http_receive_data_idle,
- connection,
- weather_http_receive_data_destroyed);
-
- /* leave without freeing data */
- return;
- } else {
- /* execute empty callback */
- if (connection->cb_func)
- (*connection->cb_func) (FALSE, NULL, 0, connection->cb_user_data);
-
- /* cleanup */
- if (connection->received) {
- g_free(connection->received);
- connection->received = NULL;
- }
- }
-
- /* remove from the list */
- queued_transfers = g_slist_remove(queued_transfers, connection);
-
- /* free other data */
- g_free(connection->hostname);
- g_free(connection->url);
- g_free(connection->proxy_host);
-
- /* cleanup */
- g_slice_free(WeatherConnection, connection);
-}
-
-
-
-void
-weather_http_receive_data(const gchar *hostname,
- const gchar *url,
- const gchar *proxy_host,
- const gint proxy_port,
- const WeatherFunc cb_func,
- gpointer user_data)
-{
- WeatherConnection *connection;
-
- /* create slice */
- connection = g_slice_new0(WeatherConnection);
-
- /* set connection properties */
- connection->hostname = g_strdup(hostname);
- connection->url = g_strdup(url);
- connection->proxy_host = g_strdup(proxy_host);
- connection->proxy_port = proxy_port;
- connection->cb_func = cb_func;
- connection->cb_user_data = user_data;
- connection->status = STATUS_NOT_EXECUTED;
- connection->received = NULL;
- connection->received_len = 0;
- connection->fd = -1;
- connection->counter = 1;
-
- /* start idle function */
- connection->id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
- weather_http_receive_data_idle,
- connection,
- weather_http_receive_data_destroyed);
-
- /* add the idle function to the running tasks list */
- queued_transfers = g_slist_prepend(queued_transfers, connection);
-}
-
-
-void
-weather_http_cleanup_queue(void)
-{
- GSList *li;
- WeatherConnection *connection;
-
- for (li = queued_transfers; li; li = li->next) {
- connection = li->data;
-
- if (connection->status == STATUS_RUNNING) {
- /* change status */
- connection->status = STATUS_LEAVE_IMMEDIATELY;
- connection->cb_func = NULL;
- } else {
- /* remove timeout */
- g_source_remove(connection->id);
- }
- }
-}
-
-
void
weather_http_queue_request(const gchar *uri,
SoupSessionCallback callback_func,
diff --git a/panel-plugin/weather-http.h b/panel-plugin/weather-http.h
index c423ed4..5dfab75 100644
--- a/panel-plugin/weather-http.h
+++ b/panel-plugin/weather-http.h
@@ -23,25 +23,11 @@
G_BEGIN_DECLS
-typedef void (*WeatherFunc) (gboolean succeed,
- gchar *received,
- size_t len,
- gpointer user_data);
-
typedef void (*SoupSessionCallback) (SoupSession *session,
SoupMessage *msg,
gpointer user_data);
-void weather_http_cleanup_queue(void);
-
-void weather_http_receive_data(const gchar *hostname,
- const gchar *url,
- const gchar *proxy_host,
- gint proxy_port,
- const WeatherFunc cb_func,
- gpointer user_data);
-
void weather_http_queue_request(const gchar *uri,
SoupSessionCallback callback_func,
gpointer user_data);
diff --git a/panel-plugin/weather.c b/panel-plugin/weather.c
index cce4d4c..7721eab 100644
--- a/panel-plugin/weather.c
+++ b/panel-plugin/weather.c
@@ -1072,7 +1072,6 @@ xfceweather_free(XfcePanelPlugin *plugin,
{
weather_debug("Freeing plugin data.");
g_assert(data != NULL);
- weather_http_cleanup_queue();
if (data->weatherdata)
xml_weather_free(data->weatherdata);
More information about the Xfce4-commits
mailing list