found bug (shitty overflow ;))

This commit is contained in:
Steffen Vogel 2011-06-05 15:27:40 +02:00
parent 22568636be
commit ce50c2ed4d
5 changed files with 92 additions and 63 deletions

View file

@ -45,17 +45,17 @@ int curl_custom_debug_callback(CURL *curl, curl_infotype type, char *data, size_
case CURLINFO_TEXT:
case CURLINFO_END:
if (end) *end = '\0'; /* terminate without \n */
print(3, "%.*s", (channel_t *) ch, (int) size, data);
print(3, "CURL: %.*s", (channel_t *) ch, (int) size, data);
break;
case CURLINFO_SSL_DATA_IN:
case CURLINFO_DATA_IN:
print(6, "Received %lu bytes", (channel_t *) ch, (unsigned long) size);
print(6, "CURL: Received %lu bytes", (channel_t *) ch, (unsigned long) size);
break;
case CURLINFO_SSL_DATA_OUT:
case CURLINFO_DATA_OUT:
print(6, "Sent %lu bytes.. ", (channel_t *) ch, (unsigned long) size);
print(6, "CURL: Sent %lu bytes.. ", (channel_t *) ch, (unsigned long) size);
break;
case CURLINFO_HEADER_IN:
@ -78,10 +78,8 @@ size_t curl_custom_write_callback(void *ptr, size_t size, size_t nmemb, void *da
memcpy(&(response->data[response->size]), ptr, realsize);
response->size += realsize;
response->data[response->size] = 0;
//response->data[response->size] = 0;
print(1, "Addr: %lu", NULL, &(response->data));
return realsize;
}
@ -109,8 +107,15 @@ json_object * api_build_json(channel_t *ch) {
CURL * api_curl_init(channel_t *ch) {
CURL *curl;
struct curl_slist *header = NULL;
char url[255], agent[255];
char buffer[255];
sprintf(agent, "User-Agent: vzlogger/%s (%s)", VZ_VERSION, curl_version()); /* build user agent */
sprintf(url, "%s/data/%s.json", ch->middleware, ch->uuid); /* build url */
header = curl_slist_append(header, "Content-type: application/json");
header = curl_slist_append(header, "Accept: application/json");
header = curl_slist_append(header, agent);
curl = curl_easy_init();
if (!curl) {
@ -118,12 +123,8 @@ CURL * api_curl_init(channel_t *ch) {
exit(EXIT_FAILURE);
}
sprintf(buffer, "%s/data/%s.json", ch->middleware, ch->uuid); /* build url */
curl_easy_setopt(curl, CURLOPT_URL, buffer);
sprintf(buffer, "vzlogger/%s (%s)", VZ_VERSION, curl_version()); /* build user agent */
curl_easy_setopt(curl, CURLOPT_USERAGENT, buffer);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
curl_easy_setopt(curl, CURLOPT_VERBOSE, (int) opts.verbose);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_custom_debug_callback);
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *) ch);
@ -131,10 +132,9 @@ CURL * api_curl_init(channel_t *ch) {
return curl;
}
char * api_parse_exception(CURLresponse response) {
void api_parse_exception(CURLresponse response, char *err) {
struct json_tokener * json_tok;
struct json_object * json_obj;
char *errstr;
json_tok = json_tokener_new();
json_obj = json_tokener_parse_ex(json_tok, response.data, response.size);
@ -142,19 +142,20 @@ char * api_parse_exception(CURLresponse response) {
json_obj = json_object_object_get(json_obj, "exception");
if (json_obj) {
errstr = json_object_get_string(json_object_object_get(json_obj, "message"));
sprintf(err, "[%s] %s",
json_object_get_string(json_object_object_get(json_obj, "type")),
json_object_get_string(json_object_object_get(json_obj, "message"))
);
}
else {
errstr = "missing exception";
strcpy(err, "missing exception");
}
}
else {
errstr = json_tokener_errors[json_tok->err];
strcpy(err, json_tokener_errors[json_tok->err]);
}
json_tokener_free(json_tok);
return errstr;
}
@ -173,36 +174,33 @@ void *api_thread(void *arg) {
do { /* start thread mainloop */
CURLresponse response;
int curl_code, http_code;
int curl_code;
long int http_code;
char *json_str;
/* initialize response */
response.data = NULL;
response.size = 0;
//pthread_mutex_lock(&ch->mutex);
//while (queue_is_empty(&ch->queue)) { /* detect spurious wakeups */
// pthread_cond_wait(&ch->condition, &ch->mutex); /* sleep until new data has been read */
//}
//pthread_mutex_unlock(&ch->mutex);
pthread_mutex_lock(&ch->mutex);
while (queue_is_empty(&ch->queue)) { /* detect spurious wakeups */
pthread_cond_wait(&ch->condition, &ch->mutex); /* sleep until new data has been read */
}
pthread_mutex_unlock(&ch->mutex);
//if (opts.verbose > 5) queue_print(&ch->queue); /* Debugging */
pthread_mutex_lock(&ch->mutex);
json_str = json_object_to_json_string(api_build_json(ch));
pthread_mutex_unlock(&ch->mutex);
//pthread_mutex_lock(&ch->mutex);
//json_str = json_object_to_json_string(api_build_json(ch));
//pthread_mutex_unlock(&ch->mutex);
print(1, "JSON request body: %s", ch, json_str);
//print(1, "JSON body: %s", ch, json_str);
//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_str);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_str);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_custom_write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &response);
curl_code = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
print(1, "Addr: %lu", ch, &(response.data));
print(1, "Response: %s", ch, response.data);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
if (curl_code == CURLE_OK && http_code == 200) { /* everything is ok */
print(1, "Request succeeded with code: %i", ch, http_code);
@ -211,10 +209,12 @@ void *api_thread(void *arg) {
}
else { /* error */
if (curl_code != CURLE_OK) {
print(-1, "CURL failed: %s", ch, curl_easy_strerror(curl_code));
print(-1, "CURL: %s", ch, curl_easy_strerror(curl_code));
}
else if (http_code != 200) {
print(-1, "Invalid middlware response: %s", ch, api_parse_exception(response));
char err[255];
api_parse_exception(response, &err);
print(-1, "Invalid middlware response: %s", ch, err);
}
print(2, "Sleeping %i seconds due to previous failure", ch, RETRY_PAUSE);
@ -225,7 +225,7 @@ void *api_thread(void *arg) {
free(json_str);
// TODO free json objects
//if (response.data) free(response.data);
if (response.data) free(response.data);
pthread_testcancel(); /* test for cancelation request */
} while (opts.daemon);

View file

@ -43,6 +43,6 @@ int curl_custom_debug_callback(CURL *curl, curl_infotype type, char *data, size_
size_t curl_custom_write_callback(void *ptr, size_t size, size_t nmemb, void *data);
json_object * api_build_json(channel_t *ch);
void *api_thread(void *arg);
void * api_thread(void *arg);
#endif /* _API_H_ */

View file

@ -212,13 +212,21 @@ int parse_channels(char * filename, channel_t * chans) {
}
char line[256];
int j = 0;
int chan_num = 0, line_num = 1;
while (j < MAX_CHANNELS && fgets(line, sizeof line, file) != NULL) { /* read a line */
while (chan_num < MAX_CHANNELS && fgets(line, sizeof line, file) != NULL) { /* read a line */
if (line[0] == ';' || line[0] == '\n') continue; /* skip comments */
channel_t ch;
protocol_t *prot;
channel_t ch = {
chan_num,
NULL,
NULL,
NULL,
0,
NULL,
protocols
};
char *tok = strtok(line, " \t");
for (int i = 0; i < 7 && tok != NULL; i++) {
@ -226,21 +234,39 @@ int parse_channels(char * filename, channel_t * chans) {
switch(i) {
case 0: /* protocol */
prot = protocols; /* reset pointer */
while (prot->name && strcmp(prot->name, tok) != 0) prot++; /* linear search */
ch.prot = prot;
while (ch.prot->name && strcmp(ch.prot->name, tok) != 0) ch.prot++; /* linear search */
if (ch.prot == NULL) {
print(-1, "Invalid protocol: %s in %s:%i", NULL, tok, filename, line_num);
exit(EXIT_FAILURE);
}
break;
case 1: /* interval */
ch.interval = atoi(tok);
ch.interval = strtol(tok, (char **) NULL, 10);
if (errno == EINVAL || errno == ERANGE) {
print(-1, "Invalid interval: %s in %s:%i", NULL, tok, filename, line_num);
exit(EXIT_FAILURE);
}
break;
case 2: /* uuid */
if (len == 0) { // TODO add uuid validation
print(-1, "Missing uuid in %s:%i", NULL, filename, line_num);
exit(EXIT_FAILURE);
}
ch.uuid = (char *) malloc(len+1); /* including string termination */
strcpy(ch.uuid, tok);
break;
case 3: /* middleware */
if (len == 0) { // TODO add uuid validation
print(-1, "Missing middleware in %s:%i", NULL, filename, line_num);
exit(EXIT_FAILURE);
}
ch.middleware = (char *) malloc(len+1); /* including string termination */
strcpy(ch.middleware, tok);
break;
@ -248,22 +274,23 @@ int parse_channels(char * filename, channel_t * chans) {
case 4: /* options */
ch.options = (char *) malloc(len);
strncpy(ch.options, tok, len-1);
ch.options[len] = '\0'; /* replace \n by \0 */
ch.options[len-1] = '\0'; /* replace \n by \0 */
break;
}
tok = strtok(NULL, " \t");
}
ch.id = j;
print(1, "Parsed %s (on %s)", &ch, ch.uuid, ch.middleware);
chans[j++] = ch;
print(1, "Parsed ch#%i (protocol=%s interval=%i uuid=%s middleware=%s options=%s)", &ch, ch.id, ch.prot->name, ch.interval, ch.uuid, ch.middleware, ch.options);
chans[chan_num] = ch;
chan_num++;
line_num++;
}
fclose(file);
return j;
return chan_num;
}
/**
@ -288,7 +315,7 @@ void *read_thread(void *arg) {
pthread_mutex_unlock(&ch->mutex);
print(1, "Value read: %.3f (next reading in %i secs)", ch, rd.value, ch->interval);
if (opts.verbose > 5) queue_print(&ch->queue); /* Debugging */
//if (opts.verbose > 5) queue_print(&ch->queue); /* Debugging */
pthread_testcancel(); /* test for cancelation request */
sleep(ch->interval); /* else sleep and restart aquisition */

View file

@ -28,6 +28,7 @@
#include <sys/time.h>
#include <pthread.h>
#include <errno.h>
#include "protocol.h"
#include "queue.h"
@ -50,16 +51,17 @@
* Datatype for every channel
*/
typedef struct {
char * middleware;
char * uuid;
unsigned int interval;
char * options;
int id; /* only for internal usage & debugging */
char *middleware;
char *uuid;
char *options;
queue_t queue; /* circular queue to buffer readings */
unsigned int interval;
void *handle; /* handle to store connection status */
protocol_t *prot; /* pointer to protocol */
void * handle; /* handle to store connection status */
queue_t queue; /* circular queue to buffer readings */
pthread_t reading_thread; /* pthread for asynchronus reading */
pthread_t logging_thread; /* pthread for asynchronus logging */

View file

@ -5,4 +5,4 @@
;prot intval uuid middleware options
;1wire 3 52960fe0-8882-11e0-b356-85eba28c1922 http://localhost/workspace/volkszaehler.org/htdocs/middleware /mnt/1wire/10.12E6D3000800/temperature
;obis 10 ef0e9adf-cd9e-4d9a-92c5-b4fb4c89ff98 http://volkszaehler.org/demo/middleware.php /dev/ttyS0
obis 10 ef0e9adf-cd9e-4d9a-92c5-b4fb4c89ff98 http://volkszaehler.org/demo/middleware.php /dev/ttyS1
obis 10 ef0e9adf-cd9e-4d9a-92c5-b4fb4c89ff98 http://volksxzaehler.org/demo/middleware.php /dev/ttyS1