'''
filetype module, version 0.3.1

(c) 2003 Jan ONDREJ (SAL) <ondrejj(at)salstar.sk>
                                                                                
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

String constants are based on Magdir/* from file package.
Extended to better support sfx archives.
 
Function returns an array of filetypes. For example for zip/sfx is returned:
  ['zip','exe'] in this order.
'''

import re,avlib

class rsc:
      def __init__(self,ext,*res):
          self.ext=ext
          self.fx=[]
          for r in res:
            self.fx.append(re.compile(r,re.DOTALL))
      def check(self,s):
          for i in self.fx:
            if i.search(s):
              return 1
          return 0

class rsc_multipos(rsc):
      def __init__(self,ext,res,*pos):
          self.ext=ext
          self.fx=[]
          for n in pos:
            self.fx.append(re.compile(
              re.sub('\{\}','{'+str(n)+'}',res),
              re.DOTALL))

type_table = [
  rsc('Z','^\037\235'),
  rsc('gz','^\037\213'),
  rsc('bz2','^BZh'),
  rsc('bz','^BZ'),
  rsc('lzop','^\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a'),
  rsc('tar','^.{257}ustar(\0|\040\040\0)'),
  rsc('zip','^PK\003\004'),
  rsc('zoo','^.{20}\xdc\xa7\xc4\xfd'),
  rsc('rar','^Rar!'),
  rsc('arj','^\x60\xea'),
  rsc('lha','^..-l[hz].-'),
  rsc('uc2','^UC2\x1a'),
  rsc('cab','^MSCF\0\0\0\0'),
  rsc('deb','^!<arch>\ndebian'),
  rsc('cpio','^(07070[712]|\xc7\x71|\x71\xc7)'),
  rsc('arc','^\x1a[\x01\x02\x03\x04\x05\x06\x07\x08\x09]'),
  rsc('rpm','^\xab\xed\xdb\xee'),
  rsc('uu','^begin\040'),
  # Executables
  rsc_multipos('zip','^MZ.{}PK\003\004',
               11694,13297,15588,15770,28374,25115,26331,47031,49845,69120),
  rsc_multipos('rar','^MZ.{}Rar!',7193,38910,51710,95110),
  rsc('arj','^MZ.{28}RJSX\xff\xff'),
  rsc('lha','^MZ.{34}LHa\'s SFX','^MZ.{1636}-lh5-'),
  rsc('winpe''^.{128}PE\0\0'),
  rsc('exe','^[LM]Z'),
  rsc('elf','^\177ELF')
]

def what(buffer):
    r=[]
    for f in type_table:
      if f.check(buffer):
        r.append(f.ext)
    return r

def file(filename):
    return what(avlib.safe.open(filename,'rb').read(99999))
