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

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);
}

# 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 = shift;
    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 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;
}

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++;
    }
}

# FNunix = ToUnix(FNdos);
#   Converts DOS filenames to Unix filenames, leaving Unix filenames
#   untouched.
sub ToUnix($) {
    my $FNdos = shift;
    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 = shift;
    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 = $_[0];
    $s =~ s/\\/\\\\/g;
    return "\"$s\"";
}

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

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";
    }
}

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";
}

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

### Main

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();
