tailhead: convert to generic object payload
authorPhil Sutter <phil@nwl.cc>
Sun, 4 Oct 2009 12:41:51 +0000 (14:41 +0200)
committerPhil Sutter <phil@nwl.cc>
Tue, 3 Nov 2009 22:23:22 +0000 (23:23 +0100)
src/core.c
src/tailhead.c
src/tailhead.h
src/text_object.h

index ca470f5..d9d7749 100644 (file)
@@ -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:
index 81ec8e4..43478ff 100644 (file)
 #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;
index d3ef45f..ded4f1c 100644 (file)
  *
  */
 
-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 */
index 3555980..8bcea1b 100644 (file)
@@ -490,14 +490,6 @@ struct text_object {
                } top;
 
                struct {
-                       int wantedlines;
-                       char *logfile;
-                       char *buffer;
-                       int current_use;
-                       int max_uses;
-               } headtail;
-
-               struct {
                        double last_update;
                        float interval;
                        char *cmd;