diff --git a/src/core.c b/src/core.c index ca470f5a..d9d77491 100644 --- a/src/core.c +++ b/src/core.c @@ -1439,10 +1439,7 @@ void free_text_objects(struct text_object *root, int internal) break; case OBJ_head: case OBJ_tail: - free(data.headtail.logfile); - if(data.headtail.buffer) { - free(data.headtail.buffer); - } + free_tailhead(obj); break; case OBJ_text: case OBJ_font: diff --git a/src/tailhead.c b/src/tailhead.c index 81ec8e47..43478fff 100644 --- a/src/tailhead.c +++ b/src/tailhead.c @@ -37,7 +37,16 @@ #define MAX_HEADTAIL_LINES 30 #define DEFAULT_MAX_HEADTAIL_USES 2 -void tailstring(char *string, int endofstring, int wantedlines) { +struct headtail { + int wantedlines; + char *logfile; + char *buffer; + int current_use; + int max_uses; + int reported; +}; + +static void tailstring(char *string, int endofstring, int wantedlines) { int i, linescounted = 0; string[endofstring] = 0; @@ -56,53 +65,77 @@ void tailstring(char *string, int endofstring, int wantedlines) { } } +void free_tailhead(struct text_object *obj) +{ + struct headtail *ht = obj->data.opaque; + if (!ht) + return; + if (ht->logfile) + free(ht->logfile); + if (ht->buffer) + free(ht->buffer); + free(obj->data.opaque); + obj->data.opaque = NULL; +} + void init_tailhead(const char* type, const char* arg, struct text_object *obj, void* free_at_crash) { unsigned int args; + struct headtail *ht; - obj->data.headtail.logfile=malloc(DEFAULT_TEXT_BUFFER_SIZE); - obj->data.headtail.max_uses = DEFAULT_MAX_HEADTAIL_USES; - args = sscanf(arg, "%s %d %d", obj->data.headtail.logfile, &obj->data.headtail.wantedlines, &obj->data.headtail.max_uses); - if(args == 2 || args == 3) { - if(obj->data.headtail.max_uses < 1) { - free(obj->data.headtail.logfile); - CRIT_ERR(obj, free_at_crash, "invalid arg for %s, next_check must be larger than 0", type); - } - if (obj->data.headtail.wantedlines > 0 && obj->data.headtail.wantedlines <= MAX_HEADTAIL_LINES) { - to_real_path(obj->data.headtail.logfile, obj->data.headtail.logfile); - obj->data.headtail.buffer = NULL; - obj->data.headtail.current_use = 0; - }else{ - free(obj->data.headtail.logfile); - CRIT_ERR(obj, free_at_crash, "invalid arg for %s, number of lines must be between 1 and %d", type, MAX_HEADTAIL_LINES); - } - } else { - free(obj->data.headtail.logfile); + ht = malloc(sizeof(struct headtail)); + memset(ht, 0, sizeof(struct headtail)); + + ht->logfile = malloc(DEFAULT_TEXT_BUFFER_SIZE); + memset(ht->logfile, 0, DEFAULT_TEXT_BUFFER_SIZE); + + ht->max_uses = DEFAULT_MAX_HEADTAIL_USES; + + args = sscanf(arg, "%s %d %d", ht->logfile, &ht->wantedlines, &ht->max_uses); + if (args < 2 || args > 3) { + free_tailhead(obj); CRIT_ERR(obj, free_at_crash, "%s needs a file as 1st and a number of lines as 2nd argument", type); } + if (ht->max_uses < 1) { + free_tailhead(obj); + CRIT_ERR(obj, free_at_crash, "invalid arg for %s, next_check must be larger than 0", type); + } + if (ht->wantedlines > 0 && ht->wantedlines <= MAX_HEADTAIL_LINES) { + to_real_path(ht->logfile, ht->logfile); + ht->buffer = NULL; + ht->current_use = 0; + } else { + free_tailhead(obj); + CRIT_ERR(obj, free_at_crash, "invalid arg for %s, number of lines must be between 1 and %d", type, MAX_HEADTAIL_LINES); + } + obj->data.opaque = ht; } void print_tailhead(const char* type, struct text_object *obj, char *p, int p_max_size) { int fd, i, endofstring = 0, linescounted = 0; FILE *fp; struct stat st; + struct headtail *ht = obj->data.opaque; + + if (!ht) + return; //empty the buffer and reset the counter if we used it the max number of times - if(obj->data.headtail.buffer && obj->data.headtail.current_use >= obj->data.headtail.max_uses - 1) { - free(obj->data.headtail.buffer); - obj->data.headtail.buffer = NULL; - obj->data.headtail.current_use = 0; + if(ht->buffer && ht->current_use >= ht->max_uses - 1) { + free(ht->buffer); + ht->buffer = NULL; + ht->current_use = 0; } //use the buffer if possible - if(obj->data.headtail.buffer) { - strcpy(p, obj->data.headtail.buffer); - obj->data.headtail.current_use++; + if(ht->buffer) { + strcpy(p, ht->buffer); + ht->current_use++; }else{ //otherwise find the needed data - if(stat(obj->data.headtail.logfile, &st) == 0) { + if(stat(ht->logfile, &st) == 0) { if (S_ISFIFO(st.st_mode)) { - fd = open_fifo(obj->data.headtail.logfile, &obj->a); + fd = open_fifo(ht->logfile, &ht->reported); if(fd != -1) { if(strcmp(type, "head") == 0) { - for(i = 0; linescounted < obj->data.headtail.wantedlines; i++) { + for(i = 0; linescounted < ht->wantedlines; i++) { read(fd, p + i, 1); if(p[i] == '\n') { linescounted++; @@ -111,33 +144,33 @@ void print_tailhead(const char* type, struct text_object *obj, char *p, int p_ma p[i] = 0; } else if(strcmp(type, "tail") == 0) { i = read(fd, p, p_max_size - 1); - tailstring(p, i, obj->data.headtail.wantedlines); + tailstring(p, i, ht->wantedlines); } else { CRIT_ERR(NULL, NULL, "If you are seeing this then there is a bug in the code, report it !"); } } close(fd); } else { - fp = open_file(obj->data.headtail.logfile, &obj->a); + fp = open_file(ht->logfile, &ht->reported); if(fp != NULL) { if(strcmp(type, "head") == 0) { - for(i = 0; i < obj->data.headtail.wantedlines; i++) { + for(i = 0; i < ht->wantedlines; i++) { fgets(p + endofstring, p_max_size - endofstring, fp); endofstring = strlen(p); } } else if(strcmp(type, "tail") == 0) { fseek(fp, - p_max_size, SEEK_END); i = fread(p, 1, p_max_size - 1, fp); - tailstring(p, i, obj->data.headtail.wantedlines); + tailstring(p, i, ht->wantedlines); } else { CRIT_ERR(NULL, NULL, "If you are seeing this then there is a bug in the code, report it !"); } fclose(fp); } } - obj->data.headtail.buffer = strdup(p); + ht->buffer = strdup(p); } else { - CRIT_ERR(NULL, NULL, "$%s can't find information about %s", type, obj->data.headtail.logfile); + CRIT_ERR(NULL, NULL, "$%s can't find information about %s", type, ht->logfile); } } return; diff --git a/src/tailhead.h b/src/tailhead.h index d3ef45f8..ded4f1c8 100644 --- a/src/tailhead.h +++ b/src/tailhead.h @@ -27,5 +27,11 @@ * */ -void init_tailhead(const char* type, const char* arg, struct text_object *obj, void* free_at_crash); -void print_tailhead(const char* type, struct text_object *obj, char *p, int p_max_size); +#ifndef _TAILHEAD_H +#define _TAILHEAD_H + +void free_tailhead(struct text_object *); +void init_tailhead(const char *, const char *, struct text_object *, void *); +void print_tailhead(const char *, struct text_object *, char *, int); + +#endif /* _TAILHEAD_H */ diff --git a/src/text_object.h b/src/text_object.h index 3555980f..8bcea1b9 100644 --- a/src/text_object.h +++ b/src/text_object.h @@ -489,14 +489,6 @@ struct text_object { char *s; } top; - struct { - int wantedlines; - char *logfile; - char *buffer; - int current_use; - int max_uses; - } headtail; - struct { double last_update; float interval;