Commit | Line | Data |
---|---|---|
21979019 | 1 | #!/usr/bin/perl -w |
0e270f45 AJ |
2 | |
3 | # This program generates wine.conf files on STDOUT. | |
0799c1a7 AJ |
4 | # Copyright (C) 1996 Stephen Simmons |
5 | # | |
6 | # This library is free software; you can redistribute it and/or | |
7 | # modify it under the terms of the GNU Lesser General Public | |
8 | # License as published by the Free Software Foundation; either | |
9 | # version 2.1 of the License, or (at your option) any later version. | |
10 | # | |
11 | # This library is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | # Lesser General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU Lesser General Public | |
17 | # License along with this library; if not, write to the Free Software | |
18 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | # | |
20 | # NOTES: | |
21 | # | |
0e270f45 AJ |
22 | # This program examines the contents of the DOS filesystems and |
23 | # attempts to generate a sensible wine.conf file. This is output | |
24 | # to STDOUT. | |
f32f9181 | 25 | # It reads /etc/fstab to find mounting locations of the hard disk drives |
0e270f45 AJ |
26 | # It uses the correct algorithm for ordering DOS drives, with the |
27 | # exception of the case of multiple drive controller types, where I don't | |
28 | # know what DOS's algorithm is. | |
29 | # It uses find to find all of the win.ini files on any DOS partition | |
30 | # and sorts them by age to guess which is part of the active Windows | |
31 | # installation. | |
32 | # It reads the autoexec.bat file (if found) and records all variable | |
33 | # settings. There are some inaccuracies in its determination. | |
34 | # First, while variables are interpolated properly, no control | |
35 | # structures are supported so calls and execs to other batch files are | |
36 | # ignored, and all variable settings take effect regardless of whether | |
37 | # they would in DOS (i,e., both if and else clauses are read). | |
38 | # This is used to determine the path and temp directories. Duplicate | |
39 | # path directories and path directories that don't exist are thrown | |
40 | # out. | |
41 | # On failing to find C:\AUTOEXEC.BAT, wineconf finds all executables | |
42 | # in the windows directory and subdirectories, and generates an | |
43 | # optimized path statement encompassing all the executables. | |
44 | # Then it also looks for \TEMP and \TMP on all drives taking the first | |
45 | # one it finds. | |
46 | # wineconf doesn't support floppy drives, network drives, printers, | |
47 | # and serial device configuration is hardcoded and not configured for | |
48 | # the machine it runs on. Similarly, spy parameters are hard coded. | |
49 | ||
696ff195 | 50 | # It would make sense to incorporate much of the heuristic code in |
0e270f45 AJ |
51 | # this program into a library to be shared with a dosemu configuration |
52 | # program, because it seems that at least some of the same stuff will | |
53 | # be wanted. The program needs to be cleaned up still. A better tmp | |
54 | # search algorithm could be written. A fast option is planned. Less | |
55 | # Linux-dependence is desired. Should look for devices independent | |
56 | # of /etc/fstab; then sanity checks on /etc/fstab can be performed. | |
57 | ||
58 | use Getopt::Long; | |
59 | use File::Basename; | |
455414cf | 60 | use strict; |
0e270f45 AJ |
61 | use Carp; |
62 | ||
d654f94f | 63 | GetOptions('windir=s', 'sysdir=s', 'thorough', 'debug:s', 'inifile=s') || &Usage; |
0e270f45 | 64 | |
696ff195 AM |
65 | print "WINE REGISTRY Version 2\n"; |
66 | print ";; All keys relative to \\\\Machine\\\\Software\\\\Wine\\\\Wine\\\\Config\n\n"; | |
0e270f45 AJ |
67 | &ReadFSTAB(); |
68 | &FindWindowsDir(); | |
69 | &ReadAutoexecBat(); | |
70 | &StandardStuff(); | |
71 | ||
72 | sub Usage { | |
73 | print "Usage: $0 <options>\n"; | |
74 | # print "-fstab <filename> Location of alternate fstab file\n"; | |
75 | print "-windir <filename> Location of windows dir in DOS space\n"; | |
76 | print "-thorough Do careful analysis (default)\n"; | |
77 | print "-sysdir <filename> Location of systems dir in DOS space\n"; | |
d654f94f | 78 | print "-inifile <filename> Path to the wine.ini file (by default './wine.ini')\n"; |
0e270f45 AJ |
79 | # print "-tmpdir <filename> Location of tmp directory\n"; |
80 | print "Generates (to STDOUT) a wine configuration file based on\n"; | |
81 | print "/etc/fstab and searching around in DOS directories\n"; | |
82 | print "The options above can override certain values\n"; | |
83 | print "This should be considered ALPHA code\n"; | |
84 | exit(0); | |
85 | } | |
86 | ||
87 | sub ReadFSTAB { | |
455414cf EP |
88 | $::opt_f = $::opt_f ? $::opt_f : '/etc/fstab'; |
89 | open(FSTAB, $::opt_f) || die "Cannot read $::opt_f\n"; | |
0e270f45 AJ |
90 | while(<FSTAB>) { |
91 | next if /^\s*\#/; | |
92 | next if /^\s*$/; | |
455414cf EP |
93 | |
94 | my ($device, $mntpoint, $type, @rest) = split(' ', $_); | |
21979019 | 95 | if ($device !~ m"^/dev/fd") { |
4940c377 DN |
96 | if ($type eq "ntfs") { |
97 | push(@::FatDrives, [$device, $mntpoint, 'win95']); | |
98 | } | |
99 | elsif ($type eq "msdos" || $type eq "vfat") { | |
9bd682d8 | 100 | push(@::FatDrives, [$device, $mntpoint, $type]); |
21979019 | 101 | } |
9bd682d8 | 102 | elsif ($type eq "iso9660" || |
4940c377 | 103 | ($mntpoint eq "/cdrom" && ! $type eq 'supermount') || |
9bd682d8 OK |
104 | ($device eq '/dev/cdrom' && $type eq 'auto') ) { |
105 | push(@::CdromDrives, [$device, $mntpoint, 'win95']); | |
21979019 | 106 | } |
7cae558b | 107 | elsif ( ($mntpoint eq '/mnt/cdrom' || $mntpoint eq '/cdrom') |
4940c377 DN |
108 | && $type eq 'supermount') { |
109 | push(@::CdromDrives, [ '/dev/cdrom', $mntpoint, 'win95']); | |
110 | } | |
0e270f45 AJ |
111 | } |
112 | } | |
455414cf | 113 | if (!@::FatDrives) { |
0e270f45 AJ |
114 | warn "ERROR ($0): Cannot find any MSDOS drives.\n"; |
115 | warn "This does not mean you cannot run Wine, but $0\n"; | |
116 | warn "cannot help you (yet)\n"; | |
117 | exit(1); | |
118 | } | |
9bd682d8 OK |
119 | push(@::UnixDrives, ['', '/tmp', 'hd']); |
120 | push(@::UnixDrives, ['', '${HOME}', 'network']); | |
455414cf EP |
121 | my $MagicDrive = 'C'; |
122 | @::FatDrives = sort byDriveOrder @::FatDrives; | |
123 | @::CdromDrives = sort byCdOrder @::CdromDrives; | |
124 | foreach my $FatDrive (@::FatDrives) { | |
0e270f45 | 125 | print "[Drive $MagicDrive]\n"; |
455414cf | 126 | my $MntPoint = $FatDrive->[1]; |
9bd682d8 | 127 | my $FileSys = $FatDrive->[2]; |
696ff195 AM |
128 | print "\"Path\" = \"$MntPoint\"\n"; |
129 | print "\"Type\" = \"hd\"\n"; | |
130 | print "\"Filesystem\" = \"$FileSys\"\n"; | |
0e270f45 AJ |
131 | print "\n"; |
132 | &RegisterDrive($MagicDrive, $FatDrive); | |
133 | if(!&IsMounted($FatDrive->[0])) { | |
7cae558b | 134 | warn "WARNING: DOS Drive $MagicDrive (" . $FatDrive->[0] . |
0e270f45 AJ |
135 | ") is not mounted\n"; |
136 | } | |
137 | $MagicDrive++; | |
138 | } | |
455414cf | 139 | foreach my $CdromDrive (@::CdromDrives) { |
0e270f45 | 140 | print "[Drive $MagicDrive]\n"; |
9bd682d8 | 141 | my $Device = $CdromDrive->[0]; |
455414cf | 142 | my $MntPoint = $CdromDrive->[1]; |
9bd682d8 | 143 | my $FileSys = $CdromDrive->[2]; |
696ff195 AM |
144 | print "\"Path\" = \"$MntPoint\"\n"; |
145 | print "\"Type\" = \"cdrom\"\n"; | |
146 | print "\"Device\" = \"$Device\"\n"; | |
147 | print "\"Filesystem\" = \"$FileSys\"\n"; | |
0e270f45 AJ |
148 | print "\n"; |
149 | &RegisterDrive($MagicDrive, $CdromDrive); | |
150 | $MagicDrive++; | |
151 | } | |
9bd682d8 OK |
152 | foreach my $UnixDrive (@::UnixDrives) { |
153 | print "[Drive $MagicDrive]\n"; | |
154 | my $MntPoint = $UnixDrive->[1]; | |
155 | my $Type = $UnixDrive->[2]; | |
696ff195 AM |
156 | print "\"Path\" = \"$MntPoint\"\n"; |
157 | print "\"Type\" = \"$Type\"\n"; | |
158 | print "\"Filesystem\" = \"win95\"\n"; | |
9bd682d8 OK |
159 | print "\n"; |
160 | $MagicDrive++; | |
161 | } | |
0e270f45 AJ |
162 | } |
163 | ||
164 | sub FindWindowsDir { | |
165 | my($MagicDrive) = 'C'; | |
455414cf | 166 | my(@FATD)=@::FatDrives; |
0e270f45 | 167 | my(@wininis) = (); |
455414cf | 168 | my ($winini); |
322d0873 | 169 | my ($ThisDrive); |
455414cf EP |
170 | |
171 | if (!$::opt_windir && !$::opt_fast && !$::opt_thorough) { | |
172 | $::opt_thorough++; | |
0e270f45 | 173 | } |
455414cf EP |
174 | if ($::opt_windir) { |
175 | $winini = &ToUnix($::opt_windir); | |
0e270f45 AJ |
176 | if (!-e $winini) { |
177 | die "ERROR: Specified winini file does not exist\n"; | |
178 | } | |
179 | } | |
455414cf | 180 | elsif ($::opt_fast) { |
0e270f45 AJ |
181 | die "-fast code can be implemented\n"; |
182 | } | |
455414cf EP |
183 | elsif ($::opt_thorough) { |
184 | if ($::opt_debug) { print STDERR "DEBUG: Num FATD = ", $#FATD+1, "\n"; } | |
322d0873 | 185 | foreach $ThisDrive (@FATD) { |
455414cf | 186 | my $MntPoint = $ThisDrive->[1]; |
6562310d | 187 | push(@wininis, `find $MntPoint -iname win.ini -print`); |
0e270f45 AJ |
188 | } |
189 | foreach $winini (@wininis) { | |
190 | chomp $winini; | |
191 | } | |
455414cf | 192 | my ($winini_cnt) = $#wininis+1; |
7cae558b | 193 | if ($::opt_debug) { |
0e270f45 AJ |
194 | print STDERR "DEBUG: Num wininis found: $winini_cnt\n";} |
195 | if ($winini_cnt > 1) { | |
196 | warn "$winini_cnt win.ini files found:\n"; | |
197 | @wininis = sort byFileAge @wininis; | |
198 | warn join("\n", @wininis), "\n"; | |
199 | $winini = $wininis[0]; | |
200 | warn "Using most recent one: $winini\n"; | |
201 | } | |
202 | elsif ($winini_cnt == 0) { | |
203 | die "ERROR: No win.ini found in DOS partitions\n"; | |
204 | } | |
205 | else { | |
206 | $winini = $wininis[0]; | |
207 | } | |
208 | } | |
209 | else { | |
210 | die "ERROR: None of -windir, -fast, or -thorough set\n"; | |
211 | } | |
455414cf | 212 | $::windir = &ToDos(dirname($winini)); |
0e270f45 | 213 | print "[wine]\n"; |
1da4707f | 214 | print "\"windows\" = ", &marshall ($::windir), "\n"; |
455414cf | 215 | if ($::opt_sysdir) { |
1da4707f | 216 | print "\"system\" = ", &marshall ($::opt_sysdir), "\n"; |
0e270f45 AJ |
217 | } |
218 | else { | |
1da4707f | 219 | print "\"system\" = ", &marshall ("$::windir\\SYSTEM"), "\n"; |
0e270f45 AJ |
220 | } |
221 | } | |
222 | ||
223 | # Returns 1 if the device is mounted; -1 if mount check failed; 0 if not | |
224 | # mounted. | |
225 | # This code is Linux specific, and needs to be broadened. | |
226 | sub IsMounted { | |
227 | my($Device) = @_; | |
228 | if (-d "/proc") { | |
229 | if (-e "/proc/mounts") { | |
7cae558b | 230 | open(MOUNTS, "/proc/mounts") || |
0e270f45 AJ |
231 | (warn "Cannot open /proc/mounts, although it exists\n" && |
232 | return -1); | |
233 | while(<MOUNTS>) { | |
7cae558b | 234 | if (/^$Device/) { |
0e270f45 AJ |
235 | return 1; # Tested 1.4 |
236 | } | |
237 | } | |
238 | return 0; # Tested 1.4 | |
239 | } | |
240 | } | |
241 | return -1; | |
242 | } | |
243 | ||
244 | sub RegisterDrive { | |
690142dc | 245 | my($DOSdrive, $Drive) = @_; |
455414cf EP |
246 | $::DOS2Unix{$DOSdrive} = $Drive; |
247 | $::Device2DOS{$Drive->[0]} = $DOSdrive; | |
248 | $::MntPoint2DOS{$Drive->[1]} = $DOSdrive; | |
249 | $::DOS2MntPoint{$DOSdrive} = $Drive->[1]; | |
250 | $::DOS2Device{$DOSdrive} = $Drive->[0]; | |
0e270f45 AJ |
251 | } |
252 | ||
253 | sub ReadAutoexecBat { | |
455414cf EP |
254 | if (!%::DOS2Unix) { &ReadFSTAB; } |
255 | my($DriveC) = $::DOS2MntPoint{"C"}; | |
0e270f45 AJ |
256 | $DriveC =~ s%/$%%; |
257 | my($path); | |
7cae558b | 258 | if ($::opt_debug) { |
0e270f45 AJ |
259 | print STDERR "DEBUG: Looking for $DriveC/autoexec.bat\n"; } |
260 | if (-e "$DriveC/autoexec.bat") { | |
261 | # Tested 1.4 | |
7cae558b | 262 | open(AUTOEXEC, "$DriveC/autoexec.bat") || |
0e270f45 AJ |
263 | die "Cannot read autoexec.bat\n"; |
264 | while(<AUTOEXEC>) { | |
265 | s/\015//; | |
266 | if (/^\s*(set\s+)?(\w+)\s*[\s\=]\s*(.*)$/i) { | |
267 | my($varname) = $2; | |
268 | my($varvalue) = $3; | |
269 | chomp($varvalue); | |
270 | $varname =~ tr/A-Z/a-z/; | |
271 | while ($varvalue =~ /%(\w+)%/) { | |
455414cf EP |
272 | my $matchname = $1; |
273 | my $subname = $1; | |
0e270f45 | 274 | $subname =~ tr/A-Z/a-z/; |
696ff195 | 275 | if (($::opt_debug) && ($::opt_debug =~ /path/i)) { |
0e270f45 AJ |
276 | print STDERR "DEBUG: Found $matchname as $subname\n"; |
277 | print STDERR "DEBUG: Old varvalue:\n$varvalue\n"; | |
278 | print STDERR "DEBUG: Old subname value:\n" . | |
455414cf | 279 | $::DOSenv{$subname} . "\n"; |
0e270f45 | 280 | } |
455414cf EP |
281 | if ($::DOSenv{$subname}) { |
282 | $varvalue =~ s/\%$matchname\%/$::DOSenv{$subname}/; | |
0e270f45 AJ |
283 | } |
284 | else { | |
7cae558b | 285 | warn "DOS environment variable $subname not\n"; |
0e270f45 AJ |
286 | warn "defined in autoexec.bat. (Reading config.sys\n"; |
287 | warn "is not implemented.) Using null value\n"; | |
288 | $varvalue =~ s/%$matchname%//; | |
289 | } | |
696ff195 | 290 | if (($::opt_debug) && ($::opt_debug =~ /path/i)) { |
0e270f45 AJ |
291 | print STDERR "DEBUG: New varvalue:\n$varvalue\n"; |
292 | } | |
293 | } | |
455414cf | 294 | if ($::opt_debug) { |
0e270f45 AJ |
295 | print STDERR "DEBUG: $varname = $varvalue\n"; |
296 | } | |
455414cf | 297 | $::DOSenv{$varname} = $varvalue; |
0e270f45 AJ |
298 | } |
299 | } | |
300 | close(AUTOEXEC); | |
301 | } | |
302 | else { | |
303 | # Tested 1.4 | |
21979019 | 304 | warn "WARNING: C:\\AUTOEXEC.BAT was not found.\n"; |
0e270f45 AJ |
305 | } |
306 | ||
455414cf EP |
307 | if ($::DOSenv{"path"}) { |
308 | my @pathdirs = split(/\s*;\s*/, $::DOSenv{"path"}); | |
696ff195 | 309 | if (($::opt_debug) && ($::opt_debug =~ /path/i)) { |
0e270f45 AJ |
310 | print STDERR "DEBUG (path): @pathdirs\n"; |
311 | } | |
455414cf | 312 | foreach my $pathdir (@pathdirs) { |
0e270f45 | 313 | if (-d &ToUnix($pathdir)) { |
455414cf | 314 | if ($::DOSpathdir{$pathdir}++) { |
0e270f45 AJ |
315 | warn "Ignoring duplicate DOS path entry $pathdir\n"; |
316 | } | |
317 | else { | |
696ff195 | 318 | if (($::opt_debug) && ($::opt_debug =~ /path/i)) { |
0e270f45 AJ |
319 | print STDERR "DEBUG (path): Found $pathdir\n"; |
320 | } | |
455414cf | 321 | push(@::DOSpathlist, $pathdir); |
0e270f45 AJ |
322 | } |
323 | } | |
324 | else { | |
325 | warn "Ignoring DOS path directory $pathdir, as it does not\n"; | |
326 | warn "exist\n"; | |
327 | } | |
328 | } | |
1da4707f | 329 | print "\"path\" = ", &marshall (join (";", @::DOSpathlist)), "\n"; |
0e270f45 AJ |
330 | } |
331 | else { | |
332 | # Code status: tested 1.4 | |
333 | warn "WARNING: Making assumptions for PATH\n"; | |
334 | warn "Will scan windows directory for executables and generate\n"; | |
335 | warn "path from that\n"; | |
455414cf | 336 | my $shellcmd = 'find ' . &ToUnix($::windir) . " -iregex '" . |
0e270f45 | 337 | '.*\.\(exe\|bat\|com\|dll\)' . "' -print"; |
7cae558b | 338 | if ($::opt_debug) { |
0e270f45 AJ |
339 | print STDERR "DEBUG: autoexec.bat search command:\n $shellcmd\n"; |
340 | } | |
455414cf | 341 | push(@::DOScommand, `$shellcmd`); |
7cae558b | 342 | if ($::opt_debug && $::opt_debug =~ /autoexec/i) { |
455414cf | 343 | print STDERR "DEBUG: autoexec.bat search results:\n\@DOS::command\n"; |
0e270f45 | 344 | } |
455414cf | 345 | foreach my $command (@::DOScommand) { |
0e270f45 | 346 | $command =~ s%[^/]+$%%; |
67019ae0 | 347 | $::DOSexecdir{&ToDos($command)}++; |
0e270f45 | 348 | } |
1da4707f | 349 | print "\"path\" = " . |
7cae558b AJ |
350 | &marshall (join(";", |
351 | grep(s%\\$%%, | |
1da4707f MW |
352 | sort {$::DOSexecdir{$b} <=> $::DOSexecdir{$a}} |
353 | (keys %::DOSexecdir)))) . "\n"; | |
0e270f45 AJ |
354 | } |
355 | ||
455414cf | 356 | if ($::DOSenv{"temp"} && -d &ToUnix($::DOSenv{"temp"})) { |
1da4707f | 357 | print "\"temp\" = ", &marshall ($::DOSenv{"temp"}), "\n"; |
0e270f45 AJ |
358 | } |
359 | else { | |
455414cf EP |
360 | my $TheTemp; |
361 | ||
0e270f45 AJ |
362 | warn "WARNING: Making assumptions for TEMP\n"; |
363 | warn "Looking for \\TEMP and then \\TMP on every drive\n"; | |
364 | # Watch out .. might pick CDROM drive :-) | |
455414cf EP |
365 | foreach my $DOSdrive (keys %::DOS2Unix) { |
366 | my $tmp = &ToUnix("$DOSdrive:\\temp"); | |
0e270f45 AJ |
367 | if (-d $tmp) { $TheTemp = "$DOSdrive:\\temp"; last; } |
368 | $tmp = &ToUnix("$DOSdrive:\\tmp"); | |
369 | if (-d $tmp) { $TheTemp = "$DOSdrive:\\tmp"; last; } | |
370 | } | |
455414cf | 371 | $TheTemp = '/tmp' if (!$TheTemp && -d '/tmp'); |
0e270f45 AJ |
372 | if ($TheTemp) { |
373 | warn "Using $TheTemp\n"; | |
1da4707f | 374 | print "\"temp\" = ", &marshall ($TheTemp), "\n"; |
0e270f45 AJ |
375 | } |
376 | else { | |
377 | warn "Using C:\\\n"; | |
1da4707f | 378 | print "\"temp\" = ", &marshall ("C:\\"), "\n"; |
0e270f45 AJ |
379 | } |
380 | } | |
381 | print "\n"; | |
382 | } | |
383 | ||
384 | # FNunix = &ToUnix(FNdos); | |
385 | # Converts DOS filenames to Unix filenames, leaving Unix filenames | |
386 | # untouched. | |
387 | sub ToUnix { | |
388 | my($FNdos) = @_; | |
389 | my($FNunix); | |
390 | ||
391 | # Initialize tables if necessary. | |
455414cf | 392 | if (!%::DOS2Unix) { &ReadFSTAB; } |
0e270f45 AJ |
393 | |
394 | # Determine which type of conversion is necessary | |
395 | if ($FNdos =~ /^([A-Z])\:(.*)$/) { # DOS drive specified | |
455414cf | 396 | $FNunix = $::DOS2MntPoint{$1} . "/$2"; |
0e270f45 AJ |
397 | } |
398 | elsif ($FNdos =~ m%\\%) { # DOS drive not specified, C: is default | |
455414cf | 399 | $FNunix = $::DOS2MntPoint{"C"} . "/$FNdos"; |
0e270f45 AJ |
400 | } |
401 | else { # Unix filename | |
402 | $FNunix = $FNdos; | |
403 | } | |
404 | 1 while ($FNunix =~ s%\\%/%); # Convert \ to / | |
405 | $FNunix =~ tr/A-Z/a-z/; # Translate to lower case | |
406 | 1 while ($FNunix =~ s%//%/%); # Translate double / to / | |
407 | return $FNunix; | |
408 | } | |
409 | ||
410 | # FNdos = &ToDOS(FNunix) | |
411 | # Converts Unix filenames to DOS filenames | |
412 | sub ToDos { | |
413 | my($FNunix) = @_; | |
455414cf EP |
414 | my(@MntList) = keys %::MntPoint2DOS; |
415 | my ($TheMntPt, $FNdos); | |
416 | ||
417 | foreach my $MntPt (@MntList) { # Scan mount point list to see if path matches | |
0e270f45 AJ |
418 | if ($FNunix =~ /^$MntPt/) { |
419 | $TheMntPt = $MntPt; | |
420 | last; | |
421 | } | |
422 | } | |
423 | if (!$TheMntPt) { | |
424 | Carp("ERROR: $FNunix not found in DOS directories\n"); | |
425 | exit(1); | |
426 | } | |
427 | $FNdos = $FNunix; | |
428 | $FNdos =~ s/^$TheMntPt//; | |
455414cf | 429 | $FNdos = $::MntPoint2DOS{$TheMntPt} . ":" . $FNdos; |
0e270f45 AJ |
430 | 1 while($FNdos =~ s%/%\\%); |
431 | return $FNdos; | |
432 | } | |
433 | ||
455414cf EP |
434 | sub InsertDefaultFile { |
435 | my ($fileName, $tag) = @_; | |
436 | my $state = 0; | |
437 | ||
438 | if (open(DEFFILE, "$fileName")) { | |
439 | while (<DEFFILE>) { | |
440 | $state = 0 if ($state == 1 && $_ =~ /^[ \t]*\#/o && index($_, "</$tag>") >= 0); | |
441 | print $_ if ($state == 1); | |
442 | $state = 1 if ($state == 0 && $_ =~ /^[ \t]*\#/o && index($_, "<$tag>" ) >= 0); | |
443 | } | |
444 | close(DEFFILE); | |
445 | } else { | |
446 | print STDERR "Cannot read $fileName\n"; | |
447 | } | |
448 | } | |
0e270f45 | 449 | |
1da4707f MW |
450 | sub marshall { |
451 | my ($s) = @_; | |
452 | $s =~ s/\\/\\\\/g; | |
453 | return "\"$s\""; | |
454 | } | |
455 | ||
456 | ||
0e270f45 | 457 | sub StandardStuff { |
d654f94f LU |
458 | if (!$::opt_inifile) { |
459 | &InsertDefaultFile("./wine.ini", "wineconf"); | |
460 | } else { | |
461 | &InsertDefaultFile($::opt_inifile, "wineconf"); | |
462 | } | |
0e270f45 AJ |
463 | } |
464 | ||
465 | sub byFileAge { | |
466 | -M $a <=> -M $b; | |
467 | } | |
468 | ||
469 | sub byDriveOrder { | |
470 | my($DeviceA) = $a->[0]; | |
471 | my($DeviceB) = $b->[0]; | |
472 | ||
473 | # Primary drives come first, logical drives last | |
474 | # DOS User's Guide (version 6) p. 70, IBM version. | |
475 | # If both drives are the same type, sort alphabetically | |
476 | # This makes drive a come before b, etc. | |
477 | # It also makes SCSI drives come before IDE drives; | |
478 | # this may or may not be right :-( | |
479 | my($Alogical, $Blogical); | |
480 | if (substr($DeviceA, 3, 1) >= 5) { $Alogical++; } | |
481 | if (substr($DeviceB, 3, 1) >= 5) { $Blogical++; } | |
482 | if ($Alogical && !$Blogical) { return -1; } | |
483 | elsif ($Blogical && !$Alogical) { return 1; } | |
484 | else { return ($DeviceA cmp $DeviceB); } | |
485 | } | |
486 | ||
487 | sub byCdOrder { | |
488 | my($DeviceA) = $a->[0]; | |
489 | my($DeviceB) = $b->[0]; | |
490 | $DeviceA cmp $DeviceB; | |
491 | } |