--- scalp-0.4.py	2016-01-24 01:35:28.000000000 +0900
+++ scalp-0.4.1.py	2017-09-07 16:25:07.181926730 +0900
@@ -22,7 +22,8 @@
 from __future__ import with_statement
 import time, base64
 import os,sys,re,random
-from StringIO import StringIO
+#from StringIO import StringIO
+from io import StringIO
 try:
 	from lxml import etree
 except ImportError:
@@ -32,7 +33,7 @@ except ImportError:
 		try:
 			import xml.etree.ElementTree as etree
 		except ImportError:
-			print "Cannot find the ElementTree in your python packages"
+			print( "Cannot find the ElementTree in your python packages" )
 
 __application__ = "scalp"
 __version__     = "0.4"
@@ -129,7 +130,7 @@ def parse(xml_file):
 		xml_handler.close()
 		return object_dict({doc.tag: __parse_node(doc)})
 	except IOError:
-		print "error: problem with the filter's file"
+		print( "error: problem with the filter's file" )
 		return {}
 
 def get_value(array, default):
@@ -255,14 +256,14 @@ def analyzer(data):
 def scalper(access, filters, preferences = [], output = "text"):
 	global table
 	if not os.path.isfile(access):
-		print "error: the log file doesn't exist"
+		print( "error: the log file doesn't exist" )
 		return
 	if not os.path.isfile(filters):
-		print "error: the filters file (XML) doesn't exist"
-		print "please download it at https://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xml"
+		print( "error: the filters file (XML) doesn't exist")
+		print( "please download it at https://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xml")
 		return
 	if output not in ('html', 'text', 'xml'):
-		print "error: the output format '%s' hasn't been recognized" % output
+		print( "error: the output format '{0)' hasn't been recognized".format(output))
 		return
 	# load the XML file
 	xml_filters = parse(filters)
@@ -272,7 +273,7 @@ def scalper(access, filters, preferences
 	# prepare to load the compiled regular expression
 	regs = {} # type => (reg.compiled, impact, description, rule)
 
-	print "Loading XML file '%s'..." % filters
+	print( "Loading XML file '{0}'...".format(filters))
 	for group in xml_filters:
 		for f in xml_filters[group]:
 			if f == 'filter':
@@ -299,17 +300,17 @@ def scalper(access, filters, preferences
 							try:
 								compiled = re.compile(rule)
 							except Exception:
-								print "The rule '%s' cannot be compiled properly" % rule
+								print( "The rule '{0}' cannot be compiled properly".format(rule))
 								return
 							_hash = hash(rule)
-							if impact > -1:
+							if int(impact) > -1:
 								table[_hash] = (compiled, impact, description, rule, _hash)
 								regs[t].append(_hash)
 	if len(preferences['attack_type']) < 1:
 		preferences['attack_type'] = regs.keys()
 	flag = {} # {type => { impact => ({log_line dict}, rule, description, org_line) }}
 
-	print "Processing the file '%s'..." % access
+	print("Processing the file '{0}'...".format(access))
 
 	sample, sampled_lines = False, []
 	if preferences['sample'] != float(100):
@@ -360,13 +361,13 @@ def scalper(access, filters, preferences
 	for t in flag:
 		for i in flag[t]:
 			n += len(flag[t][i])
-	print "Scalp results:"
-	print "\tProcessed %d lines over %d" % (loc,lines)
-	print "\tFound %d attack patterns in %f s" % (n,tt)
+	print ("Scalp results:")
+	print ("\tProcessed (0) lines over {1}".format(loc,lines))
+	print ("\tFound {0} attack patterns in {1}".format(n,tt))
 
 	short_name = access[access.rfind(os.sep)+1:]
 	if n > 0:
-		print "Generating output in %s%s%s_scalp_*" % (preferences['odir'],os.sep,short_name)
+		print ("Generating output in {0}{1}{2}_scalp_*".format(preferences['odir'],os.sep,short_name))
 		if 'html' in preferences['output']:
 			generate_html_file(flag, short_name, filters, preferences['odir'])
 		elif 'text' in preferences['output']:
@@ -406,7 +407,7 @@ def generate_text_file(flag, access, fil
 					out.write("\tReason: \"%s\"\n\n" % e[2])
 		out.close()
 	except IOError:
-		print "Cannot open the file:", fname
+		print ("Cannot open the file:" + fname)
 	return
 
 
@@ -437,7 +438,7 @@ def generate_xml_file(flag, access, filt
 		out.write("</scalp>")
 		out.close()
 	except IOError:
-		print "Cannot open the file:", fname
+		print ("Cannot open the file:" +  fname)
 	return
 	return
 
@@ -456,7 +457,7 @@ def generate_html_file(flag, access, fil
 			if len(flag[attack_type].values()) < 1:
 				continue
 			out.write("  <h2>%s (%s)</h2>\n" % (attack_type, name))
-			impacts = flag[attack_type].keys()
+			impacts = list(flag[attack_type].keys())
 			impacts.sort(reverse=True)
 			# order by impact
 			for i in impacts:
@@ -474,7 +475,7 @@ def generate_html_file(flag, access, fil
 		out.write(html_footer)
 		out.close()
 	except IOError:
-		print "Cannot open the file:", fname
+		print( "Cannot open the file:" + fname)
 	return
 
 months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
@@ -499,7 +500,8 @@ def correct_period(date, period):
 def analyze_date(date):
 	"""04/Apr/2008:15:45;*/May/2008"""
 
-	d_min = [01, 00, 0000, 00, 00, 00]
+	#d_min = [01, 00, 0000, 00, 00, 00]
+	d_min = [1, 0, 0, 0, 0, 0]
 	d_max = [31, 11, 9999, 24, 59, 59]
 
 	date   = date.replace(':', '/')
@@ -507,7 +509,8 @@ def analyze_date(date):
 	l_start= l_date[0].split('/')
 	l_end  = l_date[1].split('/')
 
-	v_start = [01, 00, 0000, 00, 00, 00]
+	#v_start = [01, 00, 0000, 00, 00, 00]
+	v_start = [1, 0, 0, 0, 0, 0]
 	v_end   = [31, 11, 9999, 24, 59, 59]
 
 	for i in range(len(l_start)):
@@ -533,32 +536,32 @@ def analyze_date(date):
 	return {'start' : v_start, 'end' : v_end}
 
 def help():
-	print "Scalp the apache log! by Romain Gaucher - http://rgaucher.info"
-	print "usage:  ./scalp.py [--log|-l log_file] [--filters|-f filter_file] [--period time-frame] [OPTIONS] [--attack a1,a2,..,an]"
-	print "                   [--sample|-s 4.2]"
-	print "   --log       |-l:  the apache log file './access_log' by default"
-	print "   --filters   |-f:  the filter file     './default_filter.xml' by default"
-	print "   --exhaustive|-e:  will report all type of attacks detected and not stop"
-	print "                     at the first found"
-	print "   --tough     |-u:  try to decode the potential attack vectors (may increase"
-	print "                     the examination time)"
-	print "   --period    |-p:  the period must be specified in the same format as in"
-	print "                     the Apache logs using * as wild-card"
-	print "                     ex: 04/Apr/2008:15:45;*/Mai/2008"
-	print "                     if not specified at the end, the max or min are taken"
-	print "   --html      |-h:  generate an HTML output"
-	print "   --xml       |-x:  generate an XML output"
-	print "   --text      |-t:  generate a simple text output (default)"
-	print "   --except    |-c:  generate a file that contains the non examined logs due to the"
-	print "                     main regular expression; ill-formed Apache log etc."
-	print "   --attack    |-a:  specify the list of attacks to look for"
-	print "                     list: xss, sqli, csrf, dos, dt, spam, id, ref, lfi"
-	print "                     the list of attacks should not contains spaces and comma separated"
-	print "                     ex: xss,sqli,lfi,ref"
-	print "   --output    |-o:  specifying the output directory; by default, scalp will try to write"
-	print "                     in the same directory as the log file"
-	print "   --sample    |-s:  use a random sample of the lines, the number (float in [0,100]) is"
-	print "                     the percentage, ex: --sample 0.1 for 1/1000"
+	print( "Scalp the apache log! by Romain Gaucher - http://rgaucher.info" )
+	print( "usage:  ./scalp.py [--log|-l log_file] [--filters|-f filter_file] [--period time-frame] [OPTIONS] [--attack a1,a2,..,an]" )
+	print( "                   [--sample|-s 4.2]")
+	print( "   --log       |-l:  the apache log file './access_log' by default")
+	print( "   --filters   |-f:  the filter file     './default_filter.xml' by default")
+	print( "   --exhaustive|-e:  will report all type of attacks detected and not stop")
+	print( "                     at the first found")
+	print( "   --tough     |-u:  try to decode the potential attack vectors (may increase")
+	print( "                     the examination time)")
+	print( "   --period    |-p:  the period must be specified in the same format as in")
+	print( "                     the Apache logs using * as wild-card")
+	print( "                     ex: 04/Apr/2008:15:45;*/Mai/2008")
+	print( "                     if not specified at the end, the max or min are taken")
+	print( "   --html      |-h:  generate an HTML output")
+	print( "   --xml       |-x:  generate an XML output")
+	print( "   --text      |-t:  generate a simple text output (default)")
+	print( "   --except    |-c:  generate a file that contains the non examined logs due to the")
+	print( "                     main regular expression; ill-formed Apache log etc.")
+	print( "   --attack    |-a:  specify the list of attacks to look for")
+	print( "                     list: xss, sqli, csrf, dos, dt, spam, id, ref, lfi")
+	print( "                     the list of attacks should not contains spaces and comma separated")
+	print( "                     ex: xss,sqli,lfi,ref")
+	print( "   --output    |-o:  specifying the output directory; by default, scalp will try to write")
+	print( "                     in the same directory as the log file")
+	print( "   --sample    |-s:  use a random sample of the lines, the number (float in [0,100]) is")
+	print( "                     the percentage, ex: --sample 0.1 for 1/1000")
 
 def main(argc, argv):
 	filters = "default_filter.xml"
@@ -567,7 +570,8 @@ def main(argc, argv):
 	preferences = {
 		'attack_type' : [],
 		'period' : {
-			'start' : [01, 00, 0000, 00, 00, 00],# day, month, year, hour, minute, second
+			#'start' : [01, 00, 0000, 00, 00, 00],# day, month, year, hour, minute, second
+			'start' : [1, 0, 0, 0, 0, 0],# day, month, year, hour, minute, second
 			'end'   : [31, 11, 9999, 24, 59, 59]
 		},
 		'except'     : False,
@@ -596,7 +600,7 @@ def main(argc, argv):
 						preferences['sample'] = float(argv[i+1])
 					except:
 						preferences['sample'] = float(4.2)
-						print "/!\ Error in the sample size, will be 4.2%"
+						print( "/!\ Error in the sample size, will be 4.2%")
 				elif s in ("--period", "-p"):
 					preferences['period'] = analyze_date(argv[i+1])
 				elif s in ("--exhaustive", "-e"):
@@ -615,16 +619,16 @@ def main(argc, argv):
 				elif s in ("--attack", "-a"):
 					preferences['attack_type'] = argv[i+1].split(',')
 			else:
-				print "argument error, '%s' has been ignored" % s
+				print( "argument error, '{0}' has been ignored".format(s))
 		if len(preferences['output']) < 1:
 			preferences['output'] = "text"
 		if not os.path.isdir(preferences['odir']):
-			print "The directory %s doesn't exist, scalp will try to create it"
+			print( "The directory %s doesn't exist, scalp will try to create it")
 			try:
 				os.mkdir(preferences['odir'])
 			except:
-				print "/!\ scalp cannot write in",preferences['odir']
-				print "/!\ Ising /tmp/scalp/ as new directory..."
+				print( "/!\ scalp cannot write in",preferences['odir'])
+				print( "/!\ Ising /tmp/scalp/ as new directory...")
 				preferences['odir'] = '/tmp/scalp'
 				os.mkdir(preferences['odir'])
 		scalper(access, filters, preferences)
