#!/usr/bin/perl

use strict;
use warnings 'all' => 'FATAL';
use diagnostics;

my @oldfuncs = qw( open acl aclcheck aclfrommode aclfrompbits aclfromtext aclsort acltomode acltopbits acltotext chown facl fchown fdopen fgetpos fopen freopen fseeko fsetpos fstat ftello ftruncate getegid geteuid getgid getgrent getgrgid getgrnam getgroups getpwuid getpwuid_r getuid initgroups lchown lseek lstat mknod mmap seekdir setegid seteuid setgid setgroups setregid setreuid setuid stat telldir truncate );
my @newfuncs = qw( _open64 _acl32 _aclcheck32 _aclfrommode32 _aclfrompbits32 _aclfromtext32 _aclsort32 _acltomode32 _acltopbits32 _acltotext32 _chown32 _facl32 _fchown32 _fdopen64 _fgetpos64 _fopen64 _freopen64 _fseeko64 _fsetpos64 _fstat64 _ftello64 _ftruncate64 _getegid32 _geteuid32 _getgid32 _getgrent32 _getgrgid32 _getgrnam32 _getgroups32 _getpwuid32 _getpwuid_r32 _getuid32 _initgroups32 _lchown32 _lseek64 _lstat64 _mknod32 _mmap64 _seekdir64 _setegid32 _seteuid32 _setgid32 _setgroups32 _setregid32 _setreuid32 _setuid32 _stat64 _telldir64 _truncate64 );
my (%is_old, %is_new);
@is_old{ @oldfuncs } = (1) x @oldfuncs;
@is_new{ @newfuncs } = (1) x @newfuncs;

sub idver($)
{
  -f($_) or return "ERR";

  undef $/;
  open(FH, "objdump -p \"".$_[0]."\" |") or die;
  my $odmp = <FH>;
  close(FH);

  $odmp =~ m/(^The Import Tables.*?)(^\S|\Z)/ms or die;
  $odmp = $1;
  $odmp =~ m/^\s*DLL Name: cygwin1\.dll$(.*?)^\s*$/ms or return "non-cyg";

  my @imps = split /\n/, $1;
  $_ = shift @imps; m/^\s*$/ or die "Unexpected: \'$_\'\n";
  $_ = shift @imps; m/vma: / or die "Unexpected: \'$_\'\n";

  my ($has_old, $has_new);

  foreach (@imps)
  {
    m/^\s*(\S+)\s+(\S+)\s+(\S+)\s*$/ or die;
    $has_old = 1 if $is_old{$3};
    $has_new = 1 if $is_new{$3};
  }

  my $type;
  if ($has_old and $has_new) { $type = "mixed"; }
  elsif ($has_old) { $type = "old"; }
  elsif ($has_new) { $type = "new"; }
  else { $type = "immune"; }

  my @dlls = grep { m/^\s*DLL Name: (?!cygwin1)/ } split(/\n/, $odmp);
  @dlls = map { m/^\s*DLL Name: (?:cyg)?(.*?)(?:\.dll|\.DLL)?$/; $1; } @dlls;
  my %dlls;
  @dlls{@dlls} = (1)x@dlls;
  for (qw(
ADVAPI32
COMCTL32
COMDLG32
GDI32
IMM32
KERNEL32
NETAPI32
OLE32
SHELL32
USER32
WINSPOOL.DRV
    )) { delete $dlls{$_}; }
  @dlls = keys %dlls;

  return $type . " (" . join(' ', @dlls).")";
};

for (@ARGV)
{
  print $_.": ".idver($_)."\n";
}


