Improve curl code.
[monky] / src / ccurl_thread.c
index 52f3c45..a062899 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Please see COPYING for details
  *
- * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al.
+ * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al.
  *     (see AUTHORS)
  * All rights reserved.
  *
@@ -26,6 +26,7 @@
 #include "conky.h"
 #include "logging.h"
 #include "ccurl_thread.h"
+#include "text_object.h"
 
 #ifdef DEBUG
 #include <assert.h>
@@ -129,12 +130,30 @@ void ccurl_fetch_data(ccurl_location_t *curloc)
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ccurl_write_memory_callback);
                curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk);
                curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-curl/1.0");
+               curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
 
                res = curl_easy_perform(curl);
                if (res == CURLE_OK && chunk.size) {
-                       timed_thread_lock(curloc->p_timed_thread);
-                       (*curloc->process_function)(curloc->result, chunk.memory);
-                       timed_thread_unlock(curloc->p_timed_thread);
+                       long http_status_code;
+
+                       if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE,
+                                               &http_status_code) == CURLE_OK) {
+                               switch (http_status_code) {
+                                       case 200:
+                                               timed_thread_lock(curloc->p_timed_thread);
+                                               (*curloc->process_function)(curloc->result, chunk.memory);
+                                               timed_thread_unlock(curloc->p_timed_thread);
+                                               break;
+                                       case 304:
+                                               break;
+                                       default:
+                                               NORM_ERR("curl: no data from server, got HTTP status %d %s",
+                                                               http_status_code);
+                                               break;
+                               }
+                       } else {
+                               NORM_ERR("curl: no HTTP status from server");
+                       }
                        free(chunk.memory);
                } else {
                        NORM_ERR("curl: no data from server");
@@ -183,6 +202,11 @@ void *ccurl_thread(void *arg)
  * This is where the $curl section begins.
  */
 
+struct curl_data {
+       char uri[128];
+       float interval;
+};
+
 /* internal location pointer for use by $curl, no touchy */
 static ccurl_location_t *ccurl_locations_head = 0;
 
@@ -193,7 +217,7 @@ void ccurl_free_info(void)
 }
 
 /* straight copy, used by $curl */
-void ccurl_parse_data(void *result, const char *data)
+static void ccurl_parse_data(void *result, const char *data)
 {
        strncpy(result, data, max_user_text);
 }
@@ -217,3 +241,40 @@ void ccurl_process_info(char *p, int p_max_size, char *uri, int interval)
        timed_thread_unlock(curloc->p_timed_thread);
 }
 
+void curl_parse_arg(struct text_object *obj, const char *arg)
+{
+       int argc;
+       struct curl_data *cd;
+       float interval = 0;
+
+       cd = malloc(sizeof(struct curl_data));
+       memset(cd, 0, sizeof(struct curl_data));
+
+       argc = sscanf(arg, "%127s %f", cd->uri, &interval);
+       if (argc < 1) {
+               free(cd);
+               NORM_ERR("wrong number of arguments for $curl");
+               return;
+       }
+       cd->interval = interval > 0 ? interval * 60 : 15*60;
+       obj->data.opaque = cd;
+}
+
+void curl_print(struct text_object *obj, char *p, int p_max_size)
+{
+       struct curl_data *cd = obj->data.opaque;
+
+       if (!cd || !cd->uri) {
+               NORM_ERR("error processing Curl data");
+               return;
+       }
+       ccurl_process_info(p, p_max_size, cd->uri, cd->interval);
+}
+
+void curl_obj_free(struct text_object *obj)
+{
+       if (obj->data.opaque) {
+               free(obj->data.opaque);
+               obj->data.opaque = NULL;
+       }
+}