#!/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;
}
