#!/usr/bin/perl -w

# This program generates wine.conf files on STDOUT.
# Copyright (C) 1996 Stephen Simmons
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# NOTES:
#
# This program examines the contents of the DOS filesystems and
# attempts to generate a sensible wine.conf file.  This is output
# to STDOUT.
# It reads /etc/fstab to find mounting locations of the hard disk drives
# It uses the correct algorithm for ordering DOS drives, with the
# exception of the case of multiple drive controller types, where I don't
# know what DOS's algorithm is.
# It uses find to find all of the win.ini files on any DOS partition
# and sorts them by age to guess which is part of the active Windows
# installation.
# It reads the autoexec.bat file (if found) and records all variable
# settings.   There are some inaccuracies in its determination.
# First, while variables are interpolated properly, no control
# structures are supported so calls and execs to other batch files are
# ignored, and all variable settings take effect regardless of whether
# they would in DOS (i,e., both if and else clauses are read).
# This is used to determine the path and temp directories.  Duplicate
# path directories and path directories that don't exist are thrown
# out.
# On failing to find C:\AUTOEXEC.BAT, wineconf finds all executables
# in the windows directory and subdirectories, and generates an
# optimized path statement encompassing all the executables.
# Then it also looks for \TEMP and \TMP on all drives taking the first
# one it finds.
# wineconf doesn't support floppy drives, network drives, printers,
# and serial device configuration is hardcoded and not configured for
# the machine it runs on.  Similarly, spy parameters are hard coded.

# It would make sense to incorporate much of the heuristic code in
# this program into a library to be shared with a dosemu configuration
# program, because it seems that at least some of the same stuff will
# be wanted.  The program needs to be cleaned up still.  A better tmp
# search algorithm could be written.  A fast option is planned.  Less
# Linux-dependence is desired.  Should look for devices independent
# of /etc/fstab; then sanity checks on /etc/fstab can be performed.

use Getopt::Long;
use File::Basename;
use strict;
use Carp;

GetOptions('windir=s', 'sysdir=s', 'thorough', 'debug:s', 'inifile=s') || &Usage;

print "WINE REGISTRY Version 2\n";
print ";; All keys relative to \\\\Machine\\\\Software\\\\Wine\\\\Wine\\\\Config\n\n";
&ReadFSTAB();
&FindWindowsDir();
&ReadAutoexecBat();
&StandardStuff();

sub Usage {
    print "Usage: $0 <options>\n";
#    print "-fstab <filename>    Location of alternate fstab file\n";
    print "-windir <filename>   Location of windows dir in DOS space\n";
    print "-thorough            Do careful analysis (default)\n";
    print "-sysdir <filename>   Location of systems dir in DOS space\n";
    print "-inifile <filename>  Path to the wine.ini file (by default './wine.ini')\n";
#    print "-tmpdir <filename>   Location of tmp directory\n";
    print "Generates (to STDOUT) a wine configuration file based on\n";
    print "/etc/fstab and searching around in DOS directories\n";
    print "The options above can override certain values\n";
    print "This should be considered ALPHA code\n";
    exit(0);
}

sub ReadFSTAB {
    $::opt_f = $::opt_f ? $::opt_f : '/etc/fstab';
    open(FSTAB, $::opt_f) || die "Cannot read $::opt_f\n";
    while(<FSTAB>) {
	next if /^\s*\#/;
	next if /^\s*$/;

	my ($device, $mntpoint, $type, @rest) = split(' ', $_);
	if ($device !~ m"^/dev/fd") {
	    if ($type eq "ntfs") {
		push(@::FatDrives, [$device, $mntpoint, 'win95']);
	    }
	    elsif ($type eq "msdos" || $type eq "vfat") {
		push(@::FatDrives, [$device, $mntpoint, $type]);
	    }
	    elsif ($type eq "iso9660" ||
		   ($mntpoint eq "/cdrom" && ! $type eq 'supermount') ||
		   ($device eq '/dev/cdrom' && $type eq 'auto') ) {
		push(@::CdromDrives, [$device, $mntpoint, 'win95']);
	    }
	    elsif ( ($mntpoint eq '/mnt/cdrom' || $mntpoint eq '/cdrom') 
		  && $type eq 'supermount') {
		push(@::CdromDrives, [ '/dev/cdrom', $mntpoint, 'win95']);
	    }
	}
    }
    if (!@::FatDrives) {
	warn "ERROR ($0): Cannot find any MSDOS drives.\n";
	warn "This does not mean you cannot run Wine, but $0\n";
	warn "cannot help you (yet)\n";
	exit(1);
    }
    push(@::UnixDrives, ['', '/tmp', 'hd']);
    push(@::UnixDrives, ['', '${HOME}', 'network']);
    my $MagicDrive = 'C';
    @::FatDrives = sort byDriveOrder @::FatDrives;
    @::CdromDrives = sort byCdOrder @::CdromDrives;
    foreach my $FatDrive (@::FatDrives) {
	print "[Drive $MagicDrive]\n";
	my $MntPoint = $FatDrive->[1];
	my $FileSys = $FatDrive->[2];
	print "\"Path\" = \"$MntPoint\"\n";
	print "\"Type\" = \"hd\"\n";
	print "\"Filesystem\" = \"$FileSys\"\n";
	print "\n";
	&RegisterDrive($MagicDrive, $FatDrive);
	if(!&IsMounted($FatDrive->[0])) {
	    warn "WARNING: DOS Drive $MagicDrive (" . $FatDrive->[0] . 
		") is not mounted\n";
	}
	$MagicDrive++;
    }
    foreach my $CdromDrive (@::CdromDrives) {
	print "[Drive $MagicDrive]\n";
	my $Device = $CdromDrive->[0];
	my $MntPoint = $CdromDrive->[1];
	my $FileSys = $CdromDrive->[2];
	print "\"Path\" = \"$MntPoint\"\n";
	print "\"Type\" = \"cdrom\"\n";
	print "\"Device\" = \"$Device\"\n";
	print "\"Filesystem\" = \"$FileSys\"\n";
	print "\n";
	&RegisterDrive($MagicDrive, $CdromDrive);
	$MagicDrive++;
    }
    foreach my $UnixDrive (@::UnixDrives) {
	print "[Drive $MagicDrive]\n";
	my $MntPoint = $UnixDrive->[1];
	my $Type = $UnixDrive->[2];
	print "\"Path\" = \"$MntPoint\"\n";
	print "\"Type\" = \"$Type\"\n";
	print "\"Filesystem\" = \"win95\"\n";
	print "\n";
	$MagicDrive++;
    }
}

sub FindWindowsDir {
    my($MagicDrive) = 'C';
    my(@FATD)=@::FatDrives;
    my(@wininis) = ();
    my ($winini);
    my ($ThisDrive);

    if (!$::opt_windir && !$::opt_fast && !$::opt_thorough) {
	$::opt_thorough++;
    }
    if ($::opt_windir) {
	$winini = &ToUnix($::opt_windir);
	if (!-e $winini) {
	    die "ERROR: Specified winini file does not exist\n";
	}
    }
    elsif ($::opt_fast) {
	die "-fast code can be implemented\n";
    }
    elsif ($::opt_thorough) {
	if ($::opt_debug) { print STDERR "DEBUG: Num FATD = ", $#FATD+1, "\n"; }
       foreach $ThisDrive (@FATD) {
	    my $MntPoint = $ThisDrive->[1];
	    push(@wininis, `find $MntPoint -iname win.ini -print`);
	}
	foreach $winini (@wininis) {
	    chomp $winini;
	}
	my ($winini_cnt) = $#wininis+1;
	if ($::opt_debug) { 
	    print STDERR "DEBUG: Num wininis found: $winini_cnt\n";}
	if ($winini_cnt > 1) {
	    warn "$winini_cnt win.ini files found:\n";
	    @wininis = sort byFileAge @wininis;
	    warn join("\n", @wininis), "\n";
	    $winini = $wininis[0];
	    warn "Using most recent one: $winini\n";
	}
	elsif ($winini_cnt == 0) {
	    die "ERROR: No win.ini found in DOS partitions\n";
	}
	else {
	    $winini = $wininis[0];
	}
    }
    else {
	die "ERROR: None of -windir, -fast, or -thorough set\n";
    }
    $::windir = &ToDos(dirname($winini));
    print "[wine]\n";
    print "\"windows\" = ", &marshall ($::windir), "\n";
    if ($::opt_sysdir) {
	print "\"system\" = ", &marshall ($::opt_sysdir), "\n";
    }
    else {
	print "\"system\" = ", &marshall ("$::windir\\SYSTEM"), "\n";
    }
}

# Returns 1 if the device is mounted; -1 if mount check failed; 0 if not
# mounted.
# This code is Linux specific, and needs to be broadened.
sub IsMounted {
    my($Device) = @_;
    if (-d "/proc") {
	if (-e "/proc/mounts") {
	    open(MOUNTS, "/proc/mounts") || 
		(warn "Cannot open /proc/mounts, although it exists\n" &&
		 return -1);
	    while(<MOUNTS>) {
		if (/^$Device/) { 
		    return 1; # Tested 1.4
		}
	    }
	    return 0; # Tested 1.4
	}
    }
    return -1;
}

sub RegisterDrive {
    my($DOSdrive, $Drive) = @_;
    $::DOS2Unix{$DOSdrive} = $Drive;
    $::Device2DOS{$Drive->[0]} = $DOSdrive;
    $::MntPoint2DOS{$Drive->[1]} = $DOSdrive;
    $::DOS2MntPoint{$DOSdrive} = $Drive->[1];
    $::DOS2Device{$DOSdrive} = $Drive->[0];
}

sub ReadAutoexecBat {
    if (!%::DOS2Unix) { &ReadFSTAB; }
    my($DriveC) = $::DOS2MntPoint{"C"};
    $DriveC =~ s%/$%%;
    my($path);
    if ($::opt_debug) { 
	print STDERR "DEBUG: Looking for $DriveC/autoexec.bat\n"; }
    if (-e "$DriveC/autoexec.bat") {
	# Tested 1.4
        open(AUTOEXEC, "$DriveC/autoexec.bat") || 
            die "Cannot read autoexec.bat\n";
        while(<AUTOEXEC>) {
	    s/\015//;
            if (/^\s*(set\s+)?(\w+)\s*[\s\=]\s*(.*)$/i) {
		my($varname) = $2;
	        my($varvalue) = $3;
		chomp($varvalue);
		$varname =~ tr/A-Z/a-z/;
		while ($varvalue =~ /%(\w+)%/) {
		    my $matchname = $1;
		    my $subname = $1;
		    $subname =~ tr/A-Z/a-z/;
		    if (($::opt_debug) && ($::opt_debug =~ /path/i)) {
			print STDERR "DEBUG: Found $matchname as $subname\n";
			print STDERR "DEBUG: Old varvalue:\n$varvalue\n";
			print STDERR "DEBUG: Old subname value:\n" .
			    $::DOSenv{$subname} . "\n";
		    }
		    if ($::DOSenv{$subname}) {
			$varvalue =~ s/\%$matchname\%/$::DOSenv{$subname}/;
		    }
		    else {
			warn "DOS environment variable $subname not\n"; 
			warn "defined in autoexec.bat. (Reading config.sys\n";
			warn "is not implemented.)  Using null value\n";
			$varvalue =~ s/%$matchname%//;
		    }
		    if (($::opt_debug) && ($::opt_debug =~ /path/i)) {
			print STDERR "DEBUG: New varvalue:\n$varvalue\n";
		    }
		}
		if ($::opt_debug) {
		    print STDERR "DEBUG: $varname = $varvalue\n";
		}
		$::DOSenv{$varname} = $varvalue;
            }
        }
	close(AUTOEXEC);
    }
    else {
	# Tested 1.4
	warn "WARNING: C:\\AUTOEXEC.BAT was not found.\n";
    }

    if ($::DOSenv{"path"}) {
	my @pathdirs = split(/\s*;\s*/, $::DOSenv{"path"});
	if (($::opt_debug) && ($::opt_debug =~ /path/i)) {
	    print STDERR "DEBUG (path): @pathdirs\n";
	}
	foreach my $pathdir (@pathdirs) {
	    if (-d &ToUnix($pathdir)) {
		if ($::DOSpathdir{$pathdir}++) {
		    warn "Ignoring duplicate DOS path entry $pathdir\n";
		}
		else {
		    if (($::opt_debug) && ($::opt_debug =~ /path/i)) {
			print STDERR "DEBUG (path): Found $pathdir\n";
		    }
		    push(@::DOSpathlist, $pathdir);
		}
	    }
	    else {
	        warn "Ignoring DOS path directory $pathdir, as it does not\n";
		warn "exist\n";
	    }
	}
	print "\"path\" = ", &marshall (join (";", @::DOSpathlist)), "\n";
    }
    else {
	# Code status: tested 1.4
	warn "WARNING: Making assumptions for PATH\n";
	warn "Will scan windows directory for executables and generate\n";
	warn "path from that\n";
	my $shellcmd = 'find ' . &ToUnix($::windir) . " -iregex '" .
	    '.*\.\(exe\|bat\|com\|dll\)' . "' -print";
	if ($::opt_debug) { 
	    print STDERR "DEBUG: autoexec.bat search command:\n $shellcmd\n";
	}
	push(@::DOScommand, `$shellcmd`);
	if ($::opt_debug && $::opt_debug =~ /autoexec/i) { 
	    print STDERR "DEBUG: autoexec.bat search results:\n\@DOS::command\n";
	}
	foreach my $command (@::DOScommand) {
	    $command =~ s%[^/]+$%%;
	    $::DOSexecdir{&ToDos($command)}++;
	}
	print "\"path\" = " .
	    &marshall (join(";", 
			    grep(s%\\$%%, 
				 sort {$::DOSexecdir{$b} <=> $::DOSexecdir{$a}}
				 (keys %::DOSexecdir)))) . "\n";
    }

    if ($::DOSenv{"temp"} && -d &ToUnix($::DOSenv{"temp"})) {
	print "\"temp\" = ", &marshall ($::DOSenv{"temp"}), "\n";
    }
    else {
        my $TheTemp;

        warn "WARNING: Making assumptions for TEMP\n";
	warn "Looking for \\TEMP and then \\TMP on every drive\n";
	# Watch out .. might pick CDROM drive :-)
	foreach my $DOSdrive (keys %::DOS2Unix) {
	    my $tmp = &ToUnix("$DOSdrive:\\temp");
	    if (-d $tmp) { $TheTemp = "$DOSdrive:\\temp"; last; }
	    $tmp = &ToUnix("$DOSdrive:\\tmp");
	    if (-d $tmp) { $TheTemp = "$DOSdrive:\\tmp"; last; }
	}
	$TheTemp = '/tmp' if (!$TheTemp && -d '/tmp');
	if ($TheTemp) {
	    warn "Using $TheTemp\n";
	    print "\"temp\" = ", &marshall ($TheTemp), "\n";
	}
	else {
	    warn "Using C:\\\n";
	    print "\"temp\" = ", &marshall ("C:\\"), "\n";
	}
    }
    print "\n";
}

# FNunix = &ToUnix(FNdos);
#   Converts DOS filenames to Unix filenames, leaving Unix filenames
#   untouched.
sub ToUnix {
    my($FNdos) = @_;
    my($FNunix);

    # Initialize tables if necessary.
    if (!%::DOS2Unix) { &ReadFSTAB; }

    # Determine which type of conversion is necessary
    if ($FNdos =~ /^([A-Z])\:(.*)$/) { # DOS drive specified
	$FNunix = $::DOS2MntPoint{$1} . "/$2";
    }
    elsif ($FNdos =~ m%\\%) { # DOS drive not specified, C: is default
	$FNunix = $::DOS2MntPoint{"C"} . "/$FNdos";
    }
    else { # Unix filename
	$FNunix = $FNdos;
    }
    1 while ($FNunix =~ s%\\%/%);    # Convert \ to /
    $FNunix =~ tr/A-Z/a-z/;          # Translate to lower case
    1 while ($FNunix =~ s%//%/%);    # Translate double / to /
    return $FNunix;
}

# FNdos = &ToDOS(FNunix)
#   Converts Unix filenames to DOS filenames
sub ToDos {
    my($FNunix) = @_;
    my(@MntList) = keys %::MntPoint2DOS;
    my ($TheMntPt, $FNdos);

    foreach my $MntPt (@MntList) { # Scan mount point list to see if path matches
	if ($FNunix =~ /^$MntPt/) {
	    $TheMntPt = $MntPt;
	    last;
	}
    }
    if (!$TheMntPt) {
	Carp("ERROR: $FNunix not found in DOS directories\n");
	exit(1);
    }
    $FNdos = $FNunix;
    $FNdos =~ s/^$TheMntPt//;
    $FNdos = $::MntPoint2DOS{$TheMntPt} . ":" . $FNdos;
    1 while($FNdos =~ s%/%\\%);
    return $FNdos;
}

sub InsertDefaultFile {
    my ($fileName, $tag) = @_;
    my $state = 0;

    if (open(DEFFILE, "$fileName")) {
       while (<DEFFILE>) {
	  $state = 0 if ($state == 1 && $_ =~ /^[ \t]*\#/o && index($_, "</$tag>") >= 0);
	  print $_ if ($state == 1);
	  $state = 1 if ($state == 0 && $_ =~ /^[ \t]*\#/o && index($_, "<$tag>" ) >= 0);
       }
       close(DEFFILE);
    } else {
       print STDERR "Cannot read $fileName\n";
    }
}

sub marshall {
    my ($s) = @_;
    $s =~ s/\\/\\\\/g;
    return "\"$s\"";
}


sub StandardStuff {
    if (!$::opt_inifile) {
	&InsertDefaultFile("./wine.ini", "wineconf");
    } else {
	&InsertDefaultFile($::opt_inifile, "wineconf");
    }
}

sub byFileAge {
    -M $a <=> -M $b;
}

sub byDriveOrder {
    my($DeviceA) = $a->[0];
    my($DeviceB) = $b->[0];

    # Primary drives come first, logical drives last
    # DOS User's Guide (version 6) p. 70, IBM version.
    # If both drives are the same type, sort alphabetically
    # This makes drive a come before b, etc.
    # It also makes SCSI drives come before IDE drives;
    # this may or may not be right :-(
    my($Alogical, $Blogical);
    if (substr($DeviceA, 3, 1) >= 5) { $Alogical++; }
    if (substr($DeviceB, 3, 1) >= 5) { $Blogical++; }
    if ($Alogical && !$Blogical) { return -1; }
    elsif ($Blogical && !$Alogical) { return 1; }
    else { return ($DeviceA cmp $DeviceB); }
}

sub byCdOrder {
    my($DeviceA) = $a->[0];
    my($DeviceB) = $b->[0];
    $DeviceA cmp $DeviceB;
}
