#!/usr/bin/gawk -f # function quote(string) { gsub(/'/, "'\\''", string); string = "'" string "'"; return (string); } function namesubst(string, arr, p, x) { while (match(string, /\$([a-z]+)/, x) > 0) { p = p substr(string, 1, RSTART-1) arr "[\"" x[1] "\"]"; string = substr(string, RSTART + RLENGTH); } p = p string; return (p); } function nextarg(option, arg) { if (argi >= ARGC) { printf ("%s: missing argument: %s%s\n", program, (length(option) == 1? "-": ""), option); exit (1); } arg = ARGV[argi]; ARGV[argi++] = ""; return (arg); } BEGIN { program = "chl"; STDERR = "/dev/stderr"; IGNORECASE = 1; __bold = "\033[01m"; __red = "\033[31m"; __green = "\033[32m"; __yellow = "\033[33m"; __blue = "\033[34m"; __c5 = "\033[35m"; __c6 = "\033[36m"; __grey = "\033[37m"; __normal = "\033[0m"; refmarker = "(freshmeat.net|\\.google\\.[a-z]+)$"; argi = 1; issub = debug = 0; while (argi < ARGC && substr(ARGV[argi], 1, 1) == "-") { options = nextarg("option"); if (options == "--") break; for (i = 2; i<=length(options); i++) { c = substr(options, i, 1); if (c == "0") issub = 1; else if (c == "d") debug = 1; else if (c == "q") noprint = 1; else { printf ("%s: unkown option: -%s\n", program, c) exit (1); } } } if (issub == 0) { if (argi < ARGC) expr = nextarg("expression"); if (expr == ".") expr = ""; } if (issub == 0 && expr != "") { cmd = program; p = namesubst(expr, "q"); if (noprint == 0) p = p " { printline(); }"; cmd = cmd " --source " quote(p); # Append flag that to prevent endless recursion. cmd = cmd " -- -0"; # Append any command line arguments we have. while (argi < ARGC) cmd = cmd " " nextarg("command line argument"); if (debug != 0) { printf ("cmd= %s\n", cmd); exit (0); } rc = system(cmd); exit (rc); } } function parserequest(req, arr, p, r, var, val, x) { delete arr; if (match(req, /^(.*)\?(.*)$/, x) == 0) { p = __yellow req __normal; return (p); # no QUERY_STRING } p = __yellow x[1] __normal "?"; req = x[2]; while (match(req, /^([^=&]*)=([^&]*)(&)?/, x) > 0) { p = p __grey x[1] __normal "=" __yellow __bold x[2]__normal x[3]; arr[x[1]] = x[2]; req = substr(req, RSTART+RLENGTH); } p = p req; return (p); } function printline() { print client, ident, cuser, date, "\"" method, crequest, proto "\"", cstatus, bytes, \ "\"" cref "\"", "\"" agent "\"" __normal; } /./ { # Read the data fields ... client = $1; ident = $2; user = $3; date = $4 " " $5; method = substr($6, 2); request = $7; proto = substr($8, 1, length($8) - 1); status = $9; bytes = $10 referer = $11; gsub(/(^"|"$)/, "", referer); if (match($0, /"([^"]*)"$/, x) == 0) agent = ""; else agent = x[1]; refhost = (match(referer, /^[a-z]+:\/\/([^/]+)\//, x) > 0)? x[1]: ""; # ... color the interesting parts ... if (status ~ /^5/) cstatus = __red status __normal; else if (status ~ /^4/) cstatus = __red __bold status __normal; else cstatus = status; cref = match(refhost, refmarker)? __c6 bold referer __normal: referer; cuser = (user != "-")? __blue user __normal: user; crequest = parserequest(request, q); # ... and print the line. if (issub == 0 && expr == "") printline(); }