/* * Copyright (c) 1996-2007, OpenFWTK Development Group * All rights reserved. See LICENSE. */ /* squid-log.c */ /* Copyright 1997-2000 by Eberhard Mattes Donated to the public domain. No warranty. 1997-08-27 Initial version 2000-07-07 Use instead of */ #include #include #include #include #include #include #include "libemfw.h" #define ISDIGIT(c) ((c) >= '0' && (c) <= '9') struct connection { struct connection *next; struct connection *prev; char *content_type; unsigned long pid; }; #define HASH_SIZE 997 #define HASH(x) ((x) % HASH_SIZE) static struct connection *hash_table[HASH_SIZE]; static void usage (void) { puts ("Usage: squid-log [...]"); exit (1); } static struct connection *new_connection (long pid) { unsigned h; struct connection *p; h = HASH (pid); p = xmalloc (sizeof (struct connection)); p->pid = pid; p->content_type = NULL; p->prev = NULL; p->next = hash_table[h]; if (hash_table[h] != NULL) hash_table[h]->prev = p; hash_table[h] = p; return p; } static void do_content_type (const char *s, unsigned long pid, struct connection *p) { if (p != NULL) free (p->content_type); else p = new_connection (pid); p->content_type = xstrdup (s); } static void do_exit (const char *s, unsigned long pid, struct connection *p) { int host_len; const char *req = NULL, *ct = NULL, *host, *in, *out; if (p != NULL) { ct = p->content_type; } if (! (req =strstr(s,"cmd='")) || !*(req +=5)) req = "- - -"; if (ct == NULL) ct = "-"; if (strchr (s, '\t') != NULL) return; host = s; s = strchr (s, ' '); if (s == NULL) return; host_len = s - host; ++s; if (strncmp(s,"in=",3)) return; in = (s+=3); while (ISDIGIT (*s)) s++; if (*s++ == ' ') { if (!strncmp(s,"out=",4)) out = (s+=4); else return; } else return; printf ("%.*s\t", host_len, host); while (*req && (*req != '\'')) putchar (*req++); printf("\t%s\t",ct); while (ISDIGIT (*out)) putchar (*out++); putchar(' '); while (ISDIGIT (*in)) putchar (*in++); putchar ('\n'); if (p != NULL) { if (p->prev == NULL) hash_table[HASH (pid)] = p->next; else p->prev->next = p->next; if (p->next != NULL) p->next->prev = p->prev; free (p); } } static void read_log (FILE *f) { static char buf[65536]; size_t len; int c, i; unsigned long pid; char *s; struct connection *p; const char *pattern = " squid-gw["; for (i = 0; i < HASH_SIZE; ++i) hash_table[i] = NULL; while (fgets (buf, sizeof (buf), f) != NULL) { len = strlen (buf); if (len == 0 || buf[len-1] != '\n') { do { c = fgetc (f); } while (c != EOF && c != '\n'); if (c == EOF) break; continue; } buf[len-1] = 0; s = strstr (buf, pattern); if (s == NULL) continue; s += strlen (pattern); if (!ISDIGIT (*s)) continue; pid = 0; while (ISDIGIT (*s)) { pid = pid * 10 + *s - '0'; ++s; } if (strncmp (s, "]: ", 3) != 0) continue; s += 3; for (p = hash_table[HASH (pid)]; p != NULL; p = p->next) if (p->pid == pid) break; if (strncmp (s, "Content-Type: ", 14) == 0) do_content_type (s + 14, pid, p); else if (strncmp (s, "exit host=", 10) == 0) do_exit (s + 10, pid, p); } } int main (int argc, char *argv[]) { int i; FILE *f; if (argc > 1 && argv[1][0] == '-' && argv[1][1] != 0) usage (); if (argc == 1) read_log (stdin); else { for (i = 1; i < argc; ++i) { f = fopen (argv[i], "r"); if (f == NULL) { perror (argv[i]); exit (1); } read_log (f); fclose (f); } } return 0; }