2 * Conky, a system monitor, based on torsmo
4 * Please see COPYING for details
6 * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al.
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "ccurl_thread.h"
32 #include <curl/curl.h>
33 #include <curl/types.h>
34 #include <curl/easy.h>
36 typedef struct _ccurl_memory_t {
41 ccurl_location_t *ccurl_find_location(ccurl_location_t **locations_head, char *uri)
43 ccurl_location_t *tail = *locations_head;
44 ccurl_location_t *new = 0;
47 strcmp(tail->uri, uri) == EQUAL) {
52 if (!tail) { /* new location!!!!!!! */
53 DBGP("new curl location: '%s'", uri);
54 new = malloc(sizeof(ccurl_location_t));
55 memset(new, 0, sizeof(ccurl_location_t));
56 new->uri = strndup(uri, text_buffer_size);
57 tail = *locations_head;
58 while (tail && tail->next) {
62 /* omg the first one!!!!!!! */
63 *locations_head = new;
71 void ccurl_free_locations(ccurl_location_t **locations_head)
73 ccurl_location_t *tail = *locations_head;
74 ccurl_location_t *last = 0;
77 if (tail->uri) free(tail->uri);
78 if (tail->result) free(tail->result);
86 size_t ccurl_write_memory_callback(void *ptr, size_t size, size_t nmemb, void *data)
88 size_t realsize = size * nmemb;
89 ccurl_memory_t *mem = (ccurl_memory_t*)data;
91 mem->memory = (char *) realloc(mem->memory, mem->size + realsize + 1);
93 memcpy(&(mem->memory[mem->size]), ptr, realsize);
94 mem->size += realsize;
95 mem->memory[mem->size] = 0;
102 void ccurl_fetch_data(ccurl_location_t *curloc)
108 ccurl_memory_t chunk;
113 curl = curl_easy_init();
115 DBGP("reading curl data from '%s'", curloc->uri);
116 curl_easy_setopt(curl, CURLOPT_URL, curloc->uri);
117 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
118 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ccurl_write_memory_callback);
119 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk);
120 curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-curl/1.0");
122 res = curl_easy_perform(curl);
123 if (res == CURLE_OK && chunk.size) {
124 timed_thread_lock(curloc->p_timed_thread);
125 (*curloc->process_function)(curloc->result, chunk.memory);
126 timed_thread_unlock(curloc->p_timed_thread);
129 ERR("weather: no data from server");
132 curl_easy_cleanup(curl);
138 void *ccurl_thread(void *) __attribute__((noreturn));
140 void ccurl_init_thread(ccurl_location_t *curloc, int interval)
143 assert(curloc->result);
145 curloc->p_timed_thread =
146 timed_thread_create(&ccurl_thread,
147 (void *)curloc, interval * 1000000);
149 if (!curloc->p_timed_thread) {
150 ERR("curl thread: error creating timed thread");
152 timed_thread_register(curloc->p_timed_thread,
153 &curloc->p_timed_thread);
154 if (timed_thread_run(curloc->p_timed_thread)) {
155 ERR("curl thread: error running timed thread");
159 void *ccurl_thread(void *arg)
161 ccurl_location_t *curloc = (ccurl_location_t*)arg;
164 ccurl_fetch_data(curloc);
165 if (timed_thread_test(curloc->p_timed_thread, 0)) {
166 timed_thread_exit(curloc->p_timed_thread);
172 static ccurl_location_t *ccurl_locations_head = 0;
174 void ccurl_free_info(void)
176 ccurl_free_locations(&ccurl_locations_head);
179 void ccurl_parse_data(void *result, const char *data)
181 strncpy(result, data, max_user_text);
184 void ccurl_process_info(char *p, int p_max_size, char *uri, int interval)
186 ccurl_location_t *curloc = ccurl_find_location(&ccurl_locations_head, uri);
187 if (!curloc->p_timed_thread) {
188 curloc->result = malloc(max_user_text);
189 memset(curloc->result, 0, max_user_text);
190 curloc->process_function = &ccurl_parse_data;
191 ccurl_init_thread(curloc, interval);
192 if (!curloc->p_timed_thread) {
193 ERR("error setting up weather thread");
197 timed_thread_lock(curloc->p_timed_thread);
198 strncpy(p, curloc->result, p_max_size);
199 timed_thread_unlock(curloc->p_timed_thread);