Mega Code Archive

 
Categories / C / Small Application
 

Parse custom httpd log

#include <stdio.h> #include <string.h> #include <stdlib.h> struct tnode { char *string; int count; struct tnode *left, *right; }; /* total nr. of nodes */ static int tnodecount = 0; struct tnode *addtree(struct tnode *, char *); void freetree(struct tnode *); void freetarr(struct tnode **); char *strdup(const char *s); int tree_to_array(struct tnode **, struct tnode *); int cmpr(const void *x, const void *y); int main(void) { FILE *fp = stdin; struct tnode *root = {0}; struct tnode **tnarray = {0}; char line[1024]; char *start = NULL; char *end = NULL; char *filename = NULL; int i = 0; /* get unresponsibly wild with pointers */ while(fgets(line, 1024, fp) != NULL) { if((start = strchr(line, '"')) == NULL) continue; start++; for(end = start; *end; end++) { if(*end == '"') break; } *end = '\0'; if((filename = strchr(start, ' ')) == NULL) continue; filename += 2; end = strrchr(filename, ' '); *end = '\0'; /* grow a tree for world peace */ root = addtree(root, filename); } /* allocate mem for ptr array */ tnarray = malloc(tnodecount * sizeof(*tnarray)); /* read btree into array */ tree_to_array(tnarray, root); /* qsort the array */ qsort(tnarray, tnodecount, sizeof(*tnarray), cmpr); /* print the result */ for(i = 0; i < tnodecount; i++) printf("%4d %s\n", tnarray[i]->count, tnarray[i]->string); /* clean up mess, mom's proud.. */ freetree(root); freetarr(tnarray); fclose(fp); return 0; } struct tnode *addtree(struct tnode *p, char *w) { int cond; if(p == NULL) { p = (struct tnode *)malloc(sizeof(struct tnode)); p->string = strdup(w); p->count = 1; p->left = p->right = NULL; tnodecount++; } else if((cond = strcmp(w, p->string)) == 0) p->count++; else if(cond < 0) p->left = addtree(p->left, w); else p->right = addtree(p->right, w); return p; } void freetree(struct tnode *p) { if(p != NULL) { freetree(p->left); freetree(p->right); free(p->string); free(p); } } void freetarr(struct tnode **p) { int i = 0; if(p != NULL) for(i = 0; i < tnodecount; i++) free(p); } char *strdup(const char *s) { char *result = malloc(strlen(s) + 1); if(result == NULL) return NULL; strcpy(result, s); return result; } int tree_to_array(struct tnode **array, struct tnode *tree) { static struct tnode **write = NULL; if(tree == NULL) return -1; if(array != NULL) write = array; if(tree != NULL) { *write = tree, write++; if(tree->left != NULL) tree_to_array(NULL, tree->left); if(tree->right != NULL) tree_to_array(NULL, tree->right); } return 0; } int cmpr(const void *x, const void *y) { struct tnode * const *a = x; struct tnode * const *b = y; int retval = 0; if(a == NULL || b == NULL) return -2; if((*a)->count > (*b)->count) retval = -1; else if((*a)->count < (*b)->count) retval = 1; else retval = 0; return retval; }