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 new = malloc(sizeof(ccurl_location_t));
54 memset(new, 0, sizeof(ccurl_location_t));
55 new->uri = strndup(uri, text_buffer_size);
56 tail = *locations_head;
57 while (tail && tail->next) {
61 /* omg the first one!!!!!!! */
62 *locations_head = new;
70 void ccurl_free_locations(ccurl_location_t **locations_head)
72 ccurl_location_t *tail = *locations_head;
73 ccurl_location_t *last = 0;
76 if (tail->uri) free(tail->uri);
77 if (tail->result) free(tail->result);
85 size_t ccurl_write_memory_callback(void *ptr, size_t size, size_t nmemb, void *data)
87 size_t realsize = size * nmemb;
88 ccurl_memory_t *mem = (ccurl_memory_t*)data;
90 mem->memory = (char *) realloc(mem->memory, mem->size + realsize + 1);
92 memcpy(&(mem->memory[mem->size]), ptr, realsize);
93 mem->size += realsize;
94 mem->memory[mem->size] = 0;
101 void ccurl_fetch_data(ccurl_location_t *curloc)
107 ccurl_memory_t chunk;
112 curl = curl_easy_init();
114 curl_easy_setopt(curl, CURLOPT_URL, curloc->uri);
115 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
116 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ccurl_write_memory_callback);
117 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk);
118 curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-curl/1.0");
120 res = curl_easy_perform(curl);
121 if (res == CURLE_OK && chunk.size) {
122 timed_thread_lock(curloc->p_timed_thread);
123 (*curloc->process_function)(curloc->result, chunk.memory);
124 timed_thread_unlock(curloc->p_timed_thread);
127 ERR("weather: no data from server");
130 curl_easy_cleanup(curl);
136 void *ccurl_thread(void *) __attribute__((noreturn));
138 void ccurl_init_thread(ccurl_location_t *curloc, int interval)
141 assert(curloc->result);
143 curloc->p_timed_thread =
144 timed_thread_create(&ccurl_thread,
145 (void *)curloc, interval * 1000000);
147 if (!curloc->p_timed_thread) {
148 ERR("curl thread: error creating timed thread");
150 timed_thread_register(curloc->p_timed_thread,
151 &curloc->p_timed_thread);
152 if (timed_thread_run(curloc->p_timed_thread)) {
153 ERR("curl thread: error running timed thread");
157 void *ccurl_thread(void *arg)
159 ccurl_location_t *curloc = (ccurl_location_t*)arg;
162 ccurl_fetch_data(curloc);
163 if (timed_thread_test(curloc->p_timed_thread, 0)) {
164 timed_thread_exit(curloc->p_timed_thread);
170 static ccurl_location_t *ccurl_locations_head = 0;
172 void ccurl_free_info(void)
174 ccurl_free_locations(&ccurl_locations_head);
177 void ccurl_parse_data(void *result, const char *data)
179 strncpy(result, data, max_user_text);
182 void ccurl_process_info(char *p, int p_max_size, char *uri, int interval)
184 ccurl_location_t *curloc = ccurl_find_location(&ccurl_locations_head, uri);
185 if (!curloc->p_timed_thread) {
186 curloc->result = malloc(max_user_text);
187 memset(curloc->result, 0, max_user_text);
188 curloc->process_function = &ccurl_parse_data;
189 ccurl_init_thread(curloc, interval);
190 if (!curloc->p_timed_thread) {
191 ERR("error setting up weather thread");
195 timed_thread_lock(curloc->p_timed_thread);
196 strncpy(p, curloc->result, p_max_size);
197 timed_thread_unlock(curloc->p_timed_thread);