#!/usr/bin/python2

from __future__ import print_function

import sys, os, time
import GeoIP

gi = GeoIP.new(GeoIP.GEOIP_STANDARD)

class watcher:
  def __init__(self, filename):
      self.filename = filename
      self.reopen()
      #self.f.seek(0, 2) # seek to end of file
  def fstat(self):
      return os.stat(self.filename).st_ino
  def reopen(self):
      self.f = open(self.filename, "r")
      self.fd = self.f.fileno()
      self.stat = self.fstat()
  def readline(self):
      row = self.f.readline()
      if row:
        return row
      time.sleep(1)
      if self.fstat()!=self.stat:
        self.reopen()
      return ""
  def process(self):
      row = self.readline()
      if not row:
        return
      elif "SASL LOGIN authentication failed:" in row:
        ip = row.split("[", 2)[-1].split("]", 1)[0]
      else:
        return
      country = gi.country_code_by_addr(ip)
      print(ip, country)
      yield ip, country

class ipset_target:
  cmd = "sudo ipset"
  def __init__(self, setname="blocker"):
      self.setname = setname
      print("Loading")
      self.load()
  def parse_row(self, row):
      a = row.split(" ")
      return a[0], "XX", "now"
  def load(self):
      self.data = {}
      s = os.popen("%s list %s" % (self.cmd, self.setname))
      # search for Members: string
      for i in range(100):
        row = s.readline().strip()
        if not row:
          break
        if s == "Members:":
          print("members found")
          break
      # load current settings
      for i in range(1000):
        row = s.readline().strip()
        if not row:
          break
        ip, country, date = self.parse_row(row)
        self.data[ip] = dict(country=country, date=date)
  def add(self, ip, country=""):
      if ip in self.data:
        return # already added
      date = time.strftime("%Y%m%d-%H%M%S")
      os.popen(
        "%s add blocker %s comment '%s %s'"
        % (self.cmd, ip, country, date)
      ).read()
      self.data[ip] = dict(country=country, date=date)

if sys.argv>1:
  worker = watcher(sys.argv[1])
else:
  worker = watcher("/var/log/messages")

ipset = ipset_target()
print("loaded")
while True:
  for ip, country in worker.process():
    ipset.add(ip, country)
