#!/usr/bin/env python2
# vim600: sw=4 fdm=marker expandtab sm ts=3
"""

    Find active (php or cgi) pages in the apache logs

    If a directory is given will search all files in that directory

    Copyright  Afrihost.com (PTY) Ltd 2006
    Original file by: Ed Pascoe <ed@pascoe.co.za>
"""
__author__  = "Ed Pascoe <ed@pascoe.co.za>"
__credits__ = "Afrihost.com -- The best webhosting. Ever."

import os.path, sys, dircache, urllib
import optparse,re

if __name__=='__main__': sys.path.append(os.path.dirname(os.path.realpath(sys.argv[0]))+'/../pylib')

reIsIP=re.compile(r'\S+\.\S+\.\S+\.\S+')

def apachelogsearch(fhandle,datesearch=None):
    """Given a filehandle will look through given file looking for active pages"""
    lineno=0
    for line in fhandle:
        lineno+=1
        parts=line.split(' ')
        try:
            ip=parts[0]
            logdate=parts[3]
            method=parts[5]; method=method[1:]  #There is a leading " in place
            pgcall=parts[6]
            status=parts[8]
        except IndexError:
            sys.stderr.write("This isn't an apache log file, skipping\n")
            sys.stderr.write(line)
            return
        if lineno==1 and not reIsIP.search(ip):
            sys.stderr.write("This isn't an apache log file, skipping\n")
            sys.stderr.write(line)
            return
        if datesearch and logdate.find(datesearch)==-1: continue #Not the date we are looking for

        if status=="200": pass #We want this page
        elif status=="404": continue #missing page

        if method=="POST" or pgcall.find('?') > -1 or pgcall.find('.cgi') > -1 or pgcall.find('.php') > -1 or pgcall.find('.pl')  > -1 or pgcall.find('.shtml') > -1:
            pgcall=urllib.unquote(pgcall)
            print "ACTIVE: %s %s" % (method,pgcall)
            print line, #Line already has a \n on the end
            

if __name__=='__main__':
    usage="Usage: %prog [<options>] time <files or directory>" +"\n"+__doc__+"\n"
    parser=optparse.OptionParser(usage)
    parser.add_option("-d","--date", dest="logdate", type="string", help="Search for the given date, in format 31/Jul/2006:19:27:55, will match on partial dates if given")

    (options,args) = parser.parse_args()
    if not args: apachelogsearch(sys.stdin) #Must be getting data via stdin
    else:
        for i in args:
            if os.path.isdir(i): #Must mean we want a grep
                print "=============================================================================="
                print "                    Directory ",i
                print "=============================================================================="
                if options.logdate:
                    p=os.popen("grep -ir '%s' '%s' 2>/dev/null " % (options.logdate,i),"r")
                    apachelogsearch(p)
                    p.close()
                else:
                    for root,dirs,files in os.walk(i):
                        for f in files:
                            fname=os.path.join(root,f)
                            print "--------------------------------------",fname
                            lf=open(fname,"r")
                            apachelogsearch(lf)
                            lf.close()
                                    
                
            else:
                print "------------------------------------------------------------------------------"
                print "                    ",i
                print "------------------------------------------------------------------------------"
                f=open(i,"r")
                apachelogsearch(f)
                f.close()
    

