summaryrefslogtreecommitdiffstats
path: root/perl-install/unused/demo-frozen-bubble.patch
blob: b2e38f29be15854e6afb45390e67ebce0a2a6db7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
Index: make_boot_img
===================================================================
RCS file: /cooker/gi/make_boot_img,v
retrieving revision 1.103
diff -u -r1.103 make_boot_img
--- make_boot_img	2002/03/15 14:59:55	1.103
+++ make_boot_img	2002/03/20 22:12:43
@@ -10,8 +10,8 @@
 
 ($img, $type) = @ARGV;
 
-$default_append = "ramdisk_size=32000 root=/dev/ram3";
-$default_vga = "vga=788";
+$default_append = "ramdisk_size=48000 root=/dev/ram3";
+$default_vga = "vga=785";
 
 $instdir = "mdk-stage1";
 $mnt = "/tmp/drakx_mnt";
Index: mdk-stage1/Makefile
===================================================================
RCS file: /cooker/gi/mdk-stage1/Makefile,v
retrieving revision 1.53
diff -u -r1.53 Makefile
--- mdk-stage1/Makefile	2002/02/26 22:59:53	1.53
+++ mdk-stage1/Makefile	2002/03/20 22:12:43
@@ -36,7 +36,7 @@
  #*****************************************************************************
 
 
-VERSION = 8.2
+VERSION = 0.9.2
 
 top_dir = .
 
Index: mdk-stage1/cdrom.c
===================================================================
RCS file: /cooker/gi/mdk-stage1/cdrom.c,v
retrieving revision 1.18
diff -u -r1.18 cdrom.c
--- mdk-stage1/cdrom.c	2001/08/22 12:43:27	1.18
+++ mdk-stage1/cdrom.c	2002/03/20 22:12:43
@@ -58,7 +58,7 @@
 	if (test_that_cd()) {
 		enum return_type results;
 		umount(IMAGE_LOCATION);
-		results = ask_yes_no("That CDROM disc does not seem to be a " DISTRIB_NAME " Installation CDROM.\nRetry with another disc?");
+		results = ask_yes_no("That CDROM disc does not seem to be a " DISTRIB_NAME " Demo-CDROM.\nRetry with another disc?");
 		if (results == RETURN_OK)
 			return try_with_device(dev_name, dev_model);
 		return results;
@@ -66,8 +66,7 @@
 
 	log_message("found a " DISTRIB_NAME " CDROM, good news!");
 
-	if (IS_SPECIAL_STAGE2 || ramdisk_possible())
-		load_ramdisk(); /* we don't care about return code, we'll do it live if we failed */
+	load_ramdisk(IMAGE_LOCATION LIVE_LOCATION); /* we don't care about return code, we'll do it live if we failed */
 
 	if (IS_RESCUE)
 		umount(IMAGE_LOCATION);
Index: mdk-stage1/config-stage1.h
===================================================================
RCS file: /cooker/gi/mdk-stage1/config-stage1.h,v
retrieving revision 1.7
diff -u -r1.7 config-stage1.h
--- mdk-stage1/config-stage1.h	2001/07/30 13:28:18	1.7
+++ mdk-stage1/config-stage1.h	2002/03/20 22:12:43
@@ -24,12 +24,12 @@
 /* If we have more than that amount of memory (in Mbytes), we assume we can load the rescue as a ramdisk */
 #define MEM_LIMIT_RESCUE 40
 
-#define DISTRIB_NAME "Mandrake Linux"
+#define DISTRIB_NAME "Frozen Bubble"
 
 #define RAMDISK_COMPRESSION_RATIO 1.95
 
-#define LIVE_LOCATION    "/Mandrake/mdkinst/"
-#define RAMDISK_LOCATION "/Mandrake/base/"
+#define LIVE_LOCATION    "/fbimg.bz2"
+#define RAMDISK_LOCATION "/"
 #define IMAGE_LOCATION   "/tmp/image"
 #define STAGE2_LOCATION  "/tmp/stage2"
 
Index: mdk-stage1/disk.c
===================================================================
RCS file: /cooker/gi/mdk-stage1/disk.c,v
retrieving revision 1.24
diff -u -r1.24 disk.c
--- mdk-stage1/disk.c	2001/09/24 22:39:09	1.24
+++ mdk-stage1/disk.c	2002/03/20 22:12:43
@@ -148,7 +148,7 @@
 
 static enum return_type try_with_device(char *dev_name)
 {
-	char * questions_location[] = { "Directory or ISO image", NULL };
+	char * questions_location[] = { "Location", NULL };
 	char * questions_location_auto[] = { "directory", NULL };
 	static char ** answers_location = NULL;
 	char device_fullname[50];
@@ -197,7 +197,7 @@
 		return RETURN_ERROR;
 	}
 
-	results = ask_from_list_comments_auto("Please choose the partition where is copied the " DISTRIB_NAME " Distribution.",
+	results = ask_from_list_comments_auto("Please choose the partition where is copied the " DISTRIB_NAME " Image File.",
 					      parts, parts_comments, &choice, "partition", parts);
 	if (results != RETURN_OK)
 		return results;
@@ -212,7 +212,7 @@
 		return try_with_device(dev_name);
 	}
 
-	if (ask_from_entries_auto("Please enter the directory (or ISO image file) containing the " DISTRIB_NAME " Distribution.",
+	if (ask_from_entries_auto("Please enter the full path of the " DISTRIB_NAME " Image File.",
 				  questions_location, &answers_location, 24, questions_location_auto, NULL) != RETURN_OK) {
 		umount(disk_own_mount);
 		return try_with_device(dev_name);
@@ -223,9 +223,9 @@
 	strcat(location_full, answers_location[0]);
 
 	if (access(location_full, R_OK)) {
-		stg1_error_message("Directory or ISO image file could not be found on partition.\n"
-			      "Here's a short extract of the files in the root of the partition:\n"
-			      "%s", disk_extract_list_directory(disk_own_mount));
+		stg1_error_message("No such file on partition.\n"
+				   "Here's a short extract of the files in the root of the partition:\n"
+				   "%s", disk_extract_list_directory(disk_own_mount));
 		umount(disk_own_mount);
 		return try_with_device(dev_name);
 	}
@@ -233,14 +233,18 @@
 	unlink(IMAGE_LOCATION);
 
 	if (!stat(location_full, &statbuf) && !S_ISDIR(statbuf.st_mode)) {
-		log_message("%s exists and is not a directory, assuming this is an ISO image", location_full);
-		if (lomount(location_full, IMAGE_LOCATION)) {
-			stg1_error_message("Could not mount file %s as an ISO image of the " DISTRIB_NAME " Distribution.", answers_location[0]);
+		log_message("found file ok");
+		if (load_ramdisk(location_full) != RETURN_OK) {
+			stg1_error_message("Could not load program into memory.");
 			umount(disk_own_mount);
 			return try_with_device(dev_name);
 		}
-	} else
-		symlink(location_full, IMAGE_LOCATION);
+		method_name = strdup("disk");
+		return RETURN_OK;
+	} else {
+		stg1_error_message("It's a directory!");
+		return try_with_device(dev_name);
+	}
 
 	if (IS_SPECIAL_STAGE2 || ramdisk_possible()) {
 		/* RAMDISK install */
@@ -253,12 +257,6 @@
 			umount(disk_own_mount);
 			return try_with_device(dev_name);
 		}
-		if (load_ramdisk() != RETURN_OK) {
-			stg1_error_message("Could not load program into memory.");
-			loumount();
-			umount(disk_own_mount);
-			return try_with_device(dev_name);
-		}
 	} else {
 		/* LIVE install */
 		char p;
@@ -326,7 +324,7 @@
 		return disk_prepare();
 	}
 
-	results = ask_from_list_comments_auto("Please choose the DISK drive on which you copied the " DISTRIB_NAME " Distribution.",
+	results = ask_from_list_comments_auto("Please choose the DISK drive on which you copied the " DISTRIB_NAME " Image File",
 					      medias, medias_models, &choice, "disk", medias);
 
 	if (results != RETURN_OK)
Index: mdk-stage1/network.c
===================================================================
RCS file: /cooker/gi/mdk-stage1/network.c,v
retrieving revision 1.40
diff -u -r1.40 network.c
--- mdk-stage1/network.c	2002/03/20 22:11:43	1.40
+++ mdk-stage1/network.c	2002/03/20 22:12:44
@@ -670,7 +670,7 @@
 	log_message("found the " DISTRIB_NAME " Installation, good news!");
 
 	if (IS_SPECIAL_STAGE2) {
-		if (load_ramdisk() != RETURN_OK) {
+		if (load_ramdisk(NULL) != RETURN_OK) {
 			stg1_error_message("Could not load program into memory.");
 			return nfs_prepare();
 		}
Index: mdk-stage1/stage1.c
===================================================================
RCS file: /cooker/gi/mdk-stage1/stage1.c,v
retrieving revision 1.46
diff -u -r1.46 stage1.c
--- mdk-stage1/stage1.c	2001/12/11 14:48:26	1.46
+++ mdk-stage1/stage1.c	2002/03/20 22:12:44
@@ -394,6 +394,9 @@
 	init_modules_insmoding();
 	init_frontend("Welcome to " DISTRIB_NAME " (" VERSION ") " __DATE__ " " __TIME__);
 
+	if (total_memory() < 66)
+		stg1_error_message("It seems that you have 64 Mbytes or less of RAM. It will probably fail.");
+
 	if (IS_EXPERT)
 		expert_third_party_modules();
 
Index: mdk-stage1/tools.c
===================================================================
RCS file: /cooker/gi/mdk-stage1/tools.c,v
retrieving revision 1.29
diff -u -r1.29 tools.c
--- mdk-stage1/tools.c	2001/08/24 19:11:07	1.29
+++ mdk-stage1/tools.c	2002/03/20 22:12:44
@@ -339,14 +339,10 @@
 }
 
 
-enum return_type load_ramdisk(void)
+enum return_type load_ramdisk(char * img_name)
 {
 	int st2_fd;
 	struct stat statr;
-	char img_name[500];
-
-	strcpy(img_name, IMAGE_LOCATION);
-	strcat(img_name, get_ramdisk_realname());
 
 	log_message("trying to load %s as a ramdisk", img_name);
 
Index: mdk-stage1/tools.h
===================================================================
RCS file: /cooker/gi/mdk-stage1/tools.h,v
retrieving revision 1.9
diff -u -r1.9 tools.h
--- mdk-stage1/tools.h	2001/04/30 17:23:04	1.9
+++ mdk-stage1/tools.h	2002/03/20 22:12:44
@@ -32,7 +32,7 @@
 int total_memory(void);
 int ramdisk_possible(void);
 char * get_ramdisk_realname(void);
-enum return_type load_ramdisk(void);
+enum return_type load_ramdisk(char * img_name);
 enum return_type load_ramdisk_fd(int ramdisk_fd, int size);
 void * memdup(void *src, size_t size);
 void add_to_env(char * name, char * value);
Index: perl-install/Makefile
===================================================================
RCS file: /cooker/gi/perl-install/Makefile,v
retrieving revision 1.225
diff -u -r1.225 Makefile
--- perl-install/Makefile	2002/03/11 11:38:23	1.225
+++ perl-install/Makefile	2002/03/20 22:12:44
@@ -68,8 +68,7 @@
 	chmod a+x $(DESTREP4PMS)/g_auto_install
 	chmod a+x $(DESTREP4PMS)/live_install*
 
-get_needed_files: $(DIRS) $(MOFILES)
-	$(MAKE) -C share
+get_needed_files: $(DIRS)
 
 #	export PERL_INSTALL_TEST=1 ; strace -f -e trace=file -o '| grep -v "(No such file or directory)" | sed -e "s/[^\"]*\"//" -e "s/\".*//" | grep "^/" | grep -v -e "^/tmp" -e "^/home" -e "^/proc" -e "^/var" -e "^/dev" -e "^/etc" -e "^/usr/lib/rpm" > /tmp/list ' $(PERL) -d install2 < /dev/null
 	eval `perl -V:version`; \
@@ -80,6 +79,19 @@
 
 	find auto -follow -name "*.so" >> /tmp/list
 
+	rpm -ql icewm-light | grep /usr/X11R6 >> /tmp/list
+	rpm -ql libSDL_image1.2 libSDL1.2 libSDL_mixer1.2 | grep /usr/lib >> /tmp/list
+	rpm -ql perl-SDL | grep site_perl >> /tmp/list
+	rpm -ql frozen-bubble | grep -v /usr/lib/menu | grep -v /usr/share/doc >> /tmp/list
+	echo /sbin/isapnp >> /tmp/list
+	echo /sbin/pnpdump >> /tmp/list
+	echo /usr/sbin/sndconfig >> /tmp/list
+	echo /bin/vim-minimal >> /tmp/list
+	echo /usr/bin/aumix >> /tmp/list
+	echo /bin/bash >> /tmp/list
+	echo /usr/X11R6/bin/rxvt.bin >> /tmp/list
+	echo /usr/X11R6/lib/X11/rgb.txt >> /tmp/list
+
 	for i in $(LOCALFILES) `cat /tmp/list` ; do \
 		ldd $$i 2>/dev/null | grep "=>" | sed -e 's/.*=> //' -e 's/ .*//' | uniq | sort >> /tmp/list; \
 	done
@@ -160,10 +172,20 @@
 
 	for i in ../all.modules/modules.cz*; do cp -f $$i $(DEST)/lib/; done
 
-	$(MAKE) -C share/po install NAME=libDrakX LOCALEDIR=$(DEST)/usr/share/locale_special
+#	$(MAKE) -C share/po install NAME=libDrakX LOCALEDIR=$(DEST)/usr/share/locale_special
 
 #	echo -e '#!/bin/sh\n\nexec "/usr/bin/sh"' > $(DEST)/usr/bin/runinstall2
 #	chmod a+x $(DEST)/usr/bin/runinstall2
+
+	rm -f $(DEST)/usr/X11R6/lib/X11/fonts/{gb16st,k14,taipei16,baekmuk_gulim_12}.pcf.gz
+	cp -f /usr/X11R6/lib/X11/fonts/75dpi/helv* $(DEST)/usr/X11R6/lib/X11/fonts/
+	cp -f /usr/X11R6/lib/X11/fonts/misc/7x14* $(DEST)/usr/X11R6/lib/X11/fonts/
+	mkfontdir $(DEST)/usr/X11R6/lib/X11/fonts 2>/dev/null
+
+	echo -e "prog frozen-bubble frozen-bubble frozen-bubble\nprog aumix aumix aumix\nprog rxvt rxvt rxvt.bin -sl 2000 -fn -*-fixed-medium-*-*-*-*-*-*-*-*-*-iso8859-15" > $(DEST)/usr/X11R6/lib/X11/icewm/toolbar
+	cat $(DEST)/usr/X11R6/lib/X11/icewm/toolbar > $(DEST)/usr/X11R6/lib/X11/icewm/menu
+	echo -e "Theme=bluePlastic/default.theme" > $(DEST)/usr/X11R6/lib/X11/icewm/preferences
+
 
 ifeq (i386,$(ARCH))
 	cp -a /etc/pcmcia $(DEST)/etc
Index: perl-install/install_steps_gtk.pm
===================================================================
RCS file: /cooker/gi/perl-install/install_steps_gtk.pm,v
retrieving revision 1.263
diff -u -r1.263 install_steps_gtk.pm
--- perl-install/install_steps_gtk.pm	2002/03/15 10:32:48	1.263
+++ perl-install/install_steps_gtk.pm	2002/03/20 22:12:44
@@ -57,7 +57,7 @@
 		    sleep 1;
 		    log::l("Server died"), return 0 if !$ok;
 		    if (c::Xtest($ENV{DISPLAY})) {
-			fork || exec("aewm-drakx") || exec("true");
+#			fork || exec("aewm-drakx") || exec("true");
 			return 1;
 		    }
 		}
@@ -105,6 +105,31 @@
 	}
     }
   OK:
+    require commands;
+    commands::mknod("/dev/dsp", "c", 14, 3);
+    commands::mknod("/dev/mixer", "c", 14, 0);
+    eval { commands::mknod("/dev/ptyp0", "c", 2, 0); };
+    eval { commands::mknod("/dev/ttyp0", "c", 3, 0); };
+    eval { commands::mknod("/dev/ptmx", "c", 5, 2); };
+    eval { commands::mknod("/dev/tty", "c", 5, 0); };
+
+    symlink "/usr/bin/bash", "/bin/bash";
+    symlinkf("/usr/bin/bash", "/bin/sh");
+
+    if (!$::expert) {
+	if (!modules::load_thiskind("sound")) {
+	    eval {
+		symlink "/usr/bin/pnpdump", "/sbin/pnpdump";
+		run_program::run("sndconfig", "--quiet");
+		run_program::run("isapnp", "/etc/isapnp.conf");
+		my @l = cat_("/etc/modules.conf");
+		my $module; /alias sound-slot-0 (\S+)/ and $module = $1 foreach @l;
+		my @options; /options\s+$module\s+(.*)/ and @options = split ' ', $1 foreach @l;
+		modules::load($module, 'sound', @options);
+	    }
+	}
+    }
+    exec "icewm-light" or die;
     install_gtk::init_sizes();
     install_gtk::default_theme($o);
     install_gtk::create_logo_window($o);
Index: tools/make_mdkinst_stage2
===================================================================
RCS file: /cooker/gi/tools/make_mdkinst_stage2,v
retrieving revision 1.21
diff -u -r1.21 make_mdkinst_stage2
--- tools/make_mdkinst_stage2	2002/02/21 14:54:28	1.21
+++ tools/make_mdkinst_stage2	2002/03/20 22:12:44
@@ -61,7 +61,7 @@
 mkdir -p $MNTPOINT 2>/dev/null
 for i in $MNTPOINT $STAGE2; do $SUDO umount $i 2>/dev/null ; done
 dd if=/dev/zero of=$STAGE2 bs=1k count=$[ `du -s $STAGE2TMP | cut -f1` + 1024 + 200 ]
-$MKE2FS -N 1000 $STAGE2
+$MKE2FS -N 2000 $STAGE2
 $SUDO mount -t ext2 $STAGE2 $MNTPOINT -o loop
 
 rmdir $MNTPOINT/lost+found
88 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
package install_steps; # $Id$

use diagnostics;
use strict;
use vars qw(@filesToSaveForUpgrade @filesNewerToUseAfterUpgrade @ISA);

#-######################################################################################
#- misc imports
#-######################################################################################
use common;
use install_any qw(:all);
use partition_table qw(:types);
use detect_devices;
use modules;
use run_program;
use lang;
use keyboard;
use fsedit;
use loopback;
use pkgs;
use any;
use log;
use fs;

@filesToSaveForUpgrade = qw(
/etc/ld.so.conf /etc/fstab /etc/hosts /etc/conf.modules /etc/modules.conf
);

@filesNewerToUseAfterUpgrade = qw(
/etc/profile
);

#-######################################################################################
#- OO Stuff
#-######################################################################################
sub new($$) {
    my ($type, $o) = @_;

    bless $o, ref $type || $type;
    return $o;
}

#-######################################################################################
#- In/Out Steps Functions
#-######################################################################################
sub enteringStep {
    my ($o, $step) = @_;
    log::l("starting step `$step'");
}
sub leavingStep {
    my ($o, $step) = @_;
    log::l("step `$step' finished");

    if (-d "$o->{prefix}/root/drakx") {
	eval { cp_af("/tmp/ddebug.log", "$o->{prefix}/root/drakx") };
	output(install_any::auto_inst_file(), install_any::g_auto_install(1));
    }

    for (my $s = $o->{steps}{first}; $s; $s = $o->{steps}{$s}{next}) {
	#- the reachability property must be recomputed each time to take
	#- into account failed step.
	next if $o->{steps}{$s}{done} && !$o->{steps}{$s}{redoable};

	my $reachable = 1;
	if (my $needs = $o->{steps}{$s}{needs}) {
	    my @l = ref $needs ? @$needs : $needs;
	    $reachable = min(map { $o->{steps}{$_}{done} || 0 } @l);
	}
	$o->{steps}{$s}{reachable} = 1 if $reachable;
    }
    $o->{steps}{$step}{reachable} = $o->{steps}{$step}{redoable};

    while (my $f = shift @{$o->{steps}{$step}{toBeDone} || []}) {
	eval { &$f() };
	$o->ask_warn(_("Error"), [
_("An error occurred, but I don't know how to handle it nicely.
Continue at your own risk."), $@ ]) if $@;
    }
}

sub errorInStep($$) { print "error :(\n"; c::_exit(1) }
sub kill_action {}
sub set_help { 1 }

#-######################################################################################
#- Steps Functions
#-######################################################################################
#------------------------------------------------------------------------------
sub selectLanguage {
    my ($o) = @_;
    lang::set($o->{lang}, !$o->isa('interactive::gtk'));
    $o->{langs} ||= { $o->{lang} => 1 };

    log::l("selectLanguage: pack_langs ", lang::pack_langs($o->{langs}));

    #- for auto_install compatibility with old $o->{keyboard} containing directly $o->{keyboard}{KEYBOARD}
    $o->{keyboard} = { KEYBOARD => $o->{keyboard} } if $o->{keyboard} && !ref($o->{keyboard});

    if (!$o->{keyboard} || $o->{keyboard}{unsafe}) {
	$o->{keyboard} = keyboard::from_usb() || keyboard::lang2keyboard($o->{lang});
	$o->{keyboard}{unsafe} = 1;
	keyboard::setup($o->{keyboard}) if !$::live;
    }

    addToBeDone {
	lang::write_langs($o->{prefix}, $o->{langs});
    } 'formatPartitions' unless $::g_auto_install;
    addToBeDone {
	lang::write($o->{prefix}, $o->{lang});
    } 'installPackages' unless $::g_auto_install;
}
#------------------------------------------------------------------------------
sub selectKeyboard {
    my ($o) = @_;
    $o->{keyboard}{KBCHARSET} = lang::lang2charset($o->{lang});
    keyboard::setup($o->{keyboard});

    addToBeDone {
	keyboard::write($o->{keyboard});
    } 'installPackages' if !$::g_auto_install && (!$o->{isUpgrade} || !$o->{keyboard}{unsafe});
}
#------------------------------------------------------------------------------
sub acceptLicence {}
sub selectPath {}
#------------------------------------------------------------------------------
sub selectInstallClass {}
#------------------------------------------------------------------------------
sub setupSCSI {
    my ($o) = @_;
    modules::configure_pcmcia($o->{pcmcia}) if $o->{pcmcia};
    modules::load_ide();
    modules::load_category('bus/firewire');
    modules::load_category('disk/scsi|hardware_raid');
}

#------------------------------------------------------------------------------
sub doPartitionDisksBefore {
    my ($o) = @_;
    eval { 
	close *pkgs::LOG;
	eval { fs::umount("$o->{prefix}/proc") };
	eval {          fs::umount_all($o->{fstab}, $o->{prefix}) };
	eval { sleep 1; fs::umount_all($o->{fstab}, $o->{prefix}) } if $@; #- HACK
    } if $o->{fstab} && !$::testing && !$::live;
}

#------------------------------------------------------------------------------
sub doPartitionDisksAfter {
    my ($o) = @_;

    if (!$::testing) {
	my $hds = $o->{all_hds}{hds};
	partition_table::write($_) foreach @$hds;
	$_->{rebootNeeded} and $o->rebootNeeded foreach @$hds;
    }

    fs::set_removable_mntpoints($o->{all_hds});
    fs::set_all_default_options($o->{all_hds}, $o->{useSupermount}, $o->{security}, lang::fs_options($o->{lang}))
	if !$o->{isUpgrade};

    $o->{fstab} = [ fsedit::get_all_fstab($o->{all_hds}) ];
    fsedit::get_root_($o->{fstab}) or die "Oops, no root partition";

    if (arch() =~ /ppc/ && detect_devices::get_mac_generation() =~ /NewWorld/) {
	die "Need bootstrap partition to boot system!" if !(defined $partition_table::mac::bootstrap_part);
    }
    
    if (arch() =~ /ia64/ && !fsedit::has_mntpoint("/boot/efi", $o->{all_hds})) {
	die _("You must have a FAT partition mounted in /boot/efi");
    }

    if ($o->{partitioning}{use_existing_root}) {
	#- ensure those partitions are mounted so that they are not proposed in choosePartitionsToFormat
	fs::mount_part($_, $o->{prefix}) foreach (sort { $a->{mntpoint} cmp $b->{mntpoint} }
						  grep { $_->{mntpoint} && maybeFormatted($_) } @{$o->{fstab}});
    }

    cat_("/proc/mounts") =~ m|(\S+)\s+/tmp/image nfs| &&
      !grep { $_->{mntpoint} eq "/mnt/nfs" } @{$o->{all_hds}{nfss}} and
	push @{$o->{all_hds}{nfss}}, { type => 'nfs', mntpoint => "/mnt/nfs", device => $1, options => "noauto,ro,nosuid,soft,rsize=8192,wsize=8192" };
}

#------------------------------------------------------------------------------
sub doPartitionDisks {
    my ($o) = @_;

    install_any::getHds($o);

    if ($o->{partitioning}{use_existing_root} || $o->{isUpgrade}) {
	# either one root is defined (and all is ok), or we take the first one we find
	my $p = fsedit::get_root_($o->{fstab}) || first(install_any::find_root_parts($o->{fstab}, $o->{prefix})) or die;
	install_any::use_root_part($o->{all_hds}, $p, $o->{prefix});
    } 
    if ($o->{partitioning}{auto_allocate}) {
	fsedit::auto_allocate($o->{all_hds}, $o->{partitions});
    }
}

#------------------------------------------------------------------------------

sub ask_mntpoint_s {
    my ($o, $fstab) = @_;

    #- TODO: set the mntpoints

    my %m; foreach (@$fstab) {
	my $m = $_->{mntpoint};

	next unless $m && $m ne 'swap'; #- there may be a lot of swap.

	$m{$m} and die _("Duplicate mount point %s", $m);
	$m{$m} = 1;

	#- in case the type does not correspond, force it to ext3
	$_->{type} = 0x483 if $m =~ m|^/| && !isTrueFS($_) && !isOtherAvailableFS($_);
    }
    1;
}


sub rebootNeeded($) {
    my ($o) = @_;
    log::l("Rebooting...");
    c::_exit(0);
}

sub choosePartitionsToFormat($$) {
    my ($o, $fstab) = @_;

    foreach (@$fstab) {
	$_->{mntpoint} = "swap" if isSwap($_);
	$_->{mntpoint} or next;
	
	add2hash_($_, { toFormat => $_->{notFormatted} });
        $_->{toFormatUnsure} = member($_->{mntpoint}, '/', '/usr');

	if (!$_->{toFormat}) {
	    my $t = fsedit::typeOfPart($_->{device});
	    $_->{toFormatUnsure} ||=
	      #- if detected dos/win, it's not precise enough to just compare the types (too many of them)
	      (!$t || isOtherAvailableFS({ type => $t }) ? !isOtherAvailableFS($_) : $t != $_->{type});
	}
    }
}

sub formatMountPartitions {
    my ($o) = @_;
    fs::formatMount_all($o->{all_hds}{raids}, $o->{fstab}, $o->{prefix});
}

#------------------------------------------------------------------------------
sub setPackages {
    my ($o, $rebuild_needed) = @_;

    install_any::setPackages($o, $rebuild_needed);
    pkgs::selectPackagesAlreadyInstalled($o->{packages}, $o->{prefix});
    $rebuild_needed and pkgs::selectPackagesToUpgrade($o->{packages}, $o->{prefix});
}

sub choosePackages {
    my ($o, $packages, $compssUsers, $first_time) = @_;

    #- now for upgrade, package that must be upgraded are
    #- selected first, after is used the same scheme as install.

    #- make sure we kept some space left for available else the system may
    #- not be able to start (xfs at least).
    my $available = install_any::getAvailableSpace($o);
    my $availableCorrected = pkgs::invCorrectSize($available / sqr(1024)) * sqr(1024);
    log::l(sprintf "available size %s (corrected %s)", formatXiB($available), formatXiB($availableCorrected));

    add2hash_($o, { compssListLevel => 5 }) if !$::auto_install;

    #- avoid destroying user selection of packages but only
    #- for expert, as they may have done individual selection before.
    if ($first_time || !$::expert) {
	exists $o->{compssListLevel}
	  and pkgs::setSelectedFromCompssList($packages, $o->{compssUsersChoice}, $o->{compssListLevel}, $availableCorrected);
    }
    $availableCorrected;
}

sub beforeInstallPackages {
    my ($o) = @_;

    #- save these files in case of upgrade failure.
    if ($o->{isUpgrade}) {
	foreach (@filesToSaveForUpgrade) {
	    unlink "$o->{prefix}/$_.mdkgisave";
	    if (-e "$o->{prefix}/$_") {
		eval { cp_af("$o->{prefix}/$_", "$o->{prefix}/$_.mdkgisave") };
	    }
	}
	foreach (@filesNewerToUseAfterUpgrade) {
	    unlink "$o->{prefix}/$_.rpmnew";
	}
    }

    #- some packages need such files for proper installation.
    install_any::write_fstab($o);

    require network;
    network::add2hosts("$o->{prefix}/etc/hosts", "localhost.localdomain", "127.0.0.1");

    log::l("setting excludedocs to $o->{excludedocs}");
    substInFile { s/%_excludedocs.*//; $_ .= "%_excludedocs yes\n" if eof && $o->{excludedocs} } "$o->{prefix}/etc/rpm/macros";

    #- add oem lilo theme and background if the files exists.
    mkdir "$o->{prefix}$_" foreach qw(/boot /usr /usr/share /usr/share/mdk);
    install_any::getAndSaveFile("Mandrake/base/oem-message-graphic", "$o->{prefix}/boot/oem-message-graphic");
    install_any::getAndSaveFile("Mandrake/base/oem-background.png", "$o->{prefix}/usr/share/mdk/oem-background.png");
}

sub pkg_install {
    my ($o, @l) = @_;
    log::l("selecting packages");
    require pkgs;
    if ($::testing) {
	log::l("selecting package \"$_\"") foreach @l;
    } else {
	$o->{packages}{rpmdb} ||= pkgs::rpmDbOpen($o->{prefix});
	pkgs::selectPackage($o->{packages}, pkgs::packageByName($o->{packages}, $_) || die "$_ rpm not found") foreach @l;
    }
    my @toInstall = pkgs::packagesToInstall($o->{packages});
    if (@toInstall) {
	log::l("installing packages");
	$o->installPackages;
    } else {
	log::l("all packages selected are already installed, nothing to do")
    }
}

sub pkg_install_if_requires_satisfied {
    my ($o, @l) = @_;
    require pkgs;
    $o->{packages}{rpmdb} ||= pkgs::rpmDbOpen($o->{prefix});
    foreach (@l) {
	my %newSelection;
	my $pkg = pkgs::packageByName($o->{packages}, $_) || die "$_ rpm not found";
	pkgs::selectPackage($o->{packages}, $pkg, 0, \%newSelection);
	if (scalar(keys %newSelection) == 1) {
	    pkgs::selectPackage($o->{packages}, $pkg);
	} else {
	    log::l("pkg_install_if_requires_satisfied: not selecting $_ because of ", join(", ", keys %newSelection));
	}
    }
    $o->installPackages;
}

sub installPackages($$) { #- complete REWORK, TODO and TOCHECK!
    my ($o) = @_;
    my $packages = $o->{packages};

    #- this method is always called, go here to close still opened rpm db.
    delete $packages->{rpmdb};

    if (%{$packages->{state}{ask_remove} || {}}) {
	log::l("removing : ", join ', ', keys %{$packages->{state}{ask_remove}});
	pkgs::remove($o->{prefix}, [ keys %{$packages->{state}{ask_remove}} ], $packages);
    }

    #- small transaction will be built based on this selection and depslist.
    my @toInstall = pkgs::packagesToInstall($packages);

    my $time = time;
    $ENV{DURING_INSTALL} = 1;
    pkgs::install($o->{prefix}, $o->{isUpgrade}, \@toInstall, $packages);
    delete $ENV{DURING_INSTALL};
    run_program::rooted_or_die($o->{prefix}, 'ldconfig') unless $::g_auto_install;
    log::l("Install took: ", formatTimeRaw(time - $time));
    install_any::log_sizes($o);
    scalar(@toInstall); #- return number of packages installed.
}

sub afterInstallPackages($) {
    my ($o) = @_;

    return if $::g_auto_install;

    die _("Some important packages didn't get installed properly.
Either your cdrom drive or your cdrom is defective.
Check the cdrom on an installed computer using \"rpm -qpl Mandrake/RPMS/*.rpm\"
") if grep { m|read failed: Input/output error| } cat_("$o->{prefix}/root/drakx/install.log");

    if (arch() !~ /^sparc/) { #- TODO restore it as may be needed for sparc
	-x "$o->{prefix}/usr/bin/dumpkeys" or $::testing or die 
"Some important packages didn't get installed properly.

Please switch to console 2 (using ctrl-alt-f2)
and look at the log file /tmp/ddebug.log

Consoles 1,3,4,7 may also contain interesting information";
    }

    #-  why not? cuz weather is nice today :-) [pixel]
    common::sync(); common::sync();

    my $have_devfsd = do {
	my $p = pkgs::packageByName($o->{packages}, 'devfsd');
	$p && $p->flag_installed
    };
    if ($have_devfsd) {
        require bootloader;
	bootloader::may_append($o->{bootloader}, devfs => 'mount');
    }

    #- generate /etc/lvmtab needed for rc.sysinit
    run_program::rooted($o->{prefix}, 'vgscan') if -e '/etc/lvmtab';

    #- configure PCMCIA services if needed.
    modules::write_pcmcia($o->{prefix}, $o->{pcmcia});

    #- for mandrake_firstime
    touch "$o->{prefix}/var/lock/TMP_1ST";

    any::config_dvd($o->{prefix}, $have_devfsd);
    any::config_mtools($o->{prefix});

    any::writeandclean_ldsoconf($o->{prefix});

    #- make sure wins is disabled in /etc/nsswitch.conf
    #- else if eth0 is not existing, glibc segfaults.
    substInFile { s/\s*wins// if /^\s*hosts\s*:/ } "$o->{prefix}/etc/nsswitch.conf";

    #- make sure some services have been enabled (or a catastrophic restart will occur).
    #- these are normally base package post install scripts or important services to start.
    run_program::rooted($o->{prefix}, "chkconfig", "--add", $_) foreach
			qw(random netfs network rawdevices sound kheader usb keytable syslog crond portmap);

    if ($o->{mouse}{device} =~ /ttyS/) {
	log::l("disabling gpm for serial mice (doesn't get along nicely with X)");
	run_program::rooted($o->{prefix}, "chkconfig", "--del", "gpm") 
    }

    #- call update-menus at the end of package installation
    run_program::rooted($o->{prefix}, "update-menus");

    if ($o->{pcmcia}) {
	substInFile { s/.*(TaskBarShowAPMStatus).*/$1=1/ } "$o->{prefix}/usr/lib/X11/icewm/preferences";
	eval { cp_af("$o->{prefix}/usr/share/applnk/System/kapm.kdelnk",
		     "$o->{prefix}/etc/skel/Desktop/Autostart/kapm.kdelnk") };
    }

    $o->install_urpmi;

    if ($o->{lang} =~ /^(zh_TW|th|vi|be|bg)/) {
	#- skip since we don't have the right font (it badly fails at least for zh_TW)
    } elsif (my $LANG = lang::lang2LANG($o->{lang})) {
	my $kdmrc = "$o->{prefix}/usr/share/config/kdm/kdmrc";

	my $kde_charset = lang::charset2kde_charset(lang::lang2charset($o->{lang}));
	my $welcome = c::to_utf8(_("Welcome to %s", '%n'));
	substInFile { 
	    s/^(GreetString)=.*/$1=$welcome/;
	    s/^(Language)=.*/$1=$LANG/;
	    if (!member($kde_charset, 'iso8859-1', 'iso8859-15')) { 
		#- don't keep the default for those
		s/^(StdFont)=.*/$1=*,12,5,$kde_charset,50,0/;
		s/^(FailFont)=.*/$1=*,12,5,$kde_charset,75,0/;
		s/^(GreetFont)=.*/$1=*,24,5,$kde_charset,50,0/;
	    }
	} "$o->{prefix}/usr/share/config/kdm/kdmrc";

    }
    install_any::disable_user_view($o->{prefix}) if $o->{security} >= 3 || $o->{authentication}{NIS};
    run_program::rooted($o->{prefix}, "kdeDesktopCleanup");

    foreach (list_skels($o->{prefix}, '.kde/share/config/kfmrc')) {
	my $found;
	substInFile {
	    $found ||= /KFM Misc Defaults/;
	    $_ .= 
"[KFM Misc Defaults]
GridWidth=85
GridHeight=70
" if eof && !$found;
	} $_ 
    }

    #- move some file after an upgrade that may be seriously annoying.
    #- and rename saved files to .mdkgiorig.
    if ($o->{isUpgrade}) {
	my $pkg = pkgs::packageByName($o->{packages}, 'rpm');
	$pkg && ($pkg->flag_selected || $pkg->flag_installed) && $pkg->compare(">= 4.0") and pkgs::cleanOldRpmDb($o->{prefix});

	log::l("moving previous desktop files that have been updated to Trash of each user");
	install_any::kdemove_desktop_file($o->{prefix});

	foreach (@filesToSaveForUpgrade) {
	    renamef("$o->{prefix}/$_.mdkgisave", "$o->{prefix}/$_.mdkgiorig")
	      if -e "$o->{prefix}$_.mdkgisave";
	}

	foreach (@filesNewerToUseAfterUpgrade) {
	    if (-e "$o->{prefix}/$_.rpmnew" && -e "$o->{prefix}/$_") {
		renamef("$o->{prefix}/$_", "$o->{prefix}/$_.mdkgiorig");
		renamef("$o->{prefix}/$_.rpmnew", "$o->{prefix}/$_");
	    }
	}
    }

    #- fix bad update-alternatives that may occurs after upgrade (but let them for install too).
    if (-d "$o->{prefix}/etc/alternatives") {
	local (*ALTERNATE_DIR, $_); opendir ALTERNATE_DIR, "$o->{prefix}/etc/alternatives";
	while (defined($_ = readdir ALTERNATE_DIR)) {
	    -e "$o->{prefix}/etc/alternatives/$_" and next;
	    log::l("fixing broken alternative $_");
	    run_program::rooted($o->{prefix}, "update-alternatives", "--auto", $_);
	}
	closedir ALTERNATE_DIR;
    }

    #- update oem lilo image if it exists.
    if (-s "$o->{prefix}/boot/oem-message-graphic") {
	rename "$o->{prefix}/boot/message-graphic", "$o->{prefix}/boot/message-graphic.mdkgiorig";
	rename "$o->{prefix}/boot/oem-message-graphic", "$o->{prefix}/boot/message-graphic";
    }

    #- update background image if it exists for common environment.
    if (-s "$o->{prefix}/usr/share/mdk/oem-background.png") {
	if (-e "$o->{prefix}/usr/share/mdk/backgrounds/default.png") {
	    rename "$o->{prefix}/usr/share/mdk/backgrounds/default.png",
	           "$o->{prefix}/usr/share/mdk/backgrounds/default.png.mdkgiorig";
	    rename "$o->{prefix}/usr/share/mdk/oem-background.png", "$o->{prefix}/usr/share/mdk/backgrounds/default.png";
	} else {
	    #- KDE desktop background.
	    if (-e "$o->{prefix}/usr/share/config/kdesktoprc") {
		update_gnomekderc("$o->{prefix}/usr/share/config/kdesktoprc", "Desktop0",
				  MultiWallpaperMode => "NoMulti",
				  Wallpaper => "/usr/share/mdk/oem-background.png",
				  WallpaperMode => "Scaled",
				 );
	    }
	    #- GNOME desktop background.
	    if (-e "$o->{prefix}/etc/gnome/config/Background") {
		update_gnomekderc("$o->{prefix}/etc/gnome/config/Background", "Default",
				  wallpaper => "/usr/share/mdk/oem-background.png",
				  wallpaperAlign => "3",
				 );
	    }
	}
    }

    if ($o->{blank} || $o->{updatemodules}) {
	my @l = detect_devices::floppies_dev();

	foreach (qw(blank updatemodules)) {
	    $o->{$_} eq "1" and $o->{$_} = $l[0] || die _("No floppy drive available");
	}

	$o->{blank} and $o->copyKernelFromFloppy();
	$o->{updatemodules} and $o->updateModulesFromFloppy();
    }
}

sub copyKernelFromFloppy {
    my ($o) = @_;
    return if $::testing || !$o->{blank};

    fs::mount($o->{blank}, "/floppy", "vfat", 0);
    eval { cp_af("/floppy/vmlinuz", "$o->{prefix}/boot/vmlinuz-default") };
    if ($@) {
	log::l("copying of /floppy/vmlinuz from blank modified disk failed: $@");
    }
    fs::umount("/floppy");
}

sub install_urpmi {
    my ($o) = @_;

    my $pkg = pkgs::packageByName($o->{packages}, 'urpmi');
    if ($pkg && ($pkg->flag_selected || $pkg->flag_installed)) {
	install_any::install_urpmi($o->{prefix}, 
				   $::oem ? 'cdrom' : $o->{method}, #- HACK
				   $o->{packages},
				   $o->{packages}{mediums});
	pkgs::saveCompssUsers($o->{prefix}, $o->{packages}, $o->{compssUsers}, $o->{compssUsersSorted});
    }
}

sub updateModulesFromFloppy {
    my ($o) = @_;
    return if $::testing || !$o->{updatemodules};

    fs::mount($o->{updatemodules}, "/floppy", "ext2", 0);
    foreach (glob_("$o->{prefix}/lib/modules/*")) {
	my ($kernelVersion) = m,lib/modules/(\S*),;
	log::l("examining updated modules for kernel $kernelVersion");
	if (-d "/floppy/$kernelVersion") {
	    my @src_files = glob_("/floppy/$kernelVersion/*");
	    my @dest_files = map { chomp_($_) } run_program::rooted_get_stdout($o->{prefix}, 'find', '/lib/modules');
	    foreach my $s (@src_files) {
		log::l("found updatable module $s");
		my ($sfile, $sext) = $s =~ /([^\/\.]*\.o)(?:\.gz|\.bz2)?$/;
		my $qsfile = quotemeta $sfile;
		my $qsext = quotemeta $sext;
		foreach my $target (@dest_files) {
		    $target =~ /$qsfile/ or next;
		    eval { cp_af($s, $target) };
		    if ($@) {
			log::l("updating module $target by $s failed: $@");
		    } else {
			log::l("updating module $target by $s");
		    }
		    if ($target !~ /$qsfile$qsext$/) {
			#- extension differ, first rename target file correctly,
			#- then uncompress source file, then compress it as expected.
			my ($basetarget, $text) = $target =~ /(.*?)(\.gz|\.bz2)$/;
			rename $target, "$basetarget$sext";
			$sext eq '.gz' and run_program::run("gzip", "-d", "$basetarget$sext");
			$sext eq '.bz2' and run_program::run("bzip2", "-d", "$basetarget$sext");
			$text eq '.gz' and run_program::run("gzip", $basetarget);
			$text eq '.bz2' and run_program::run("bzip2", $basetarget);
		    }
		}
	    }
	}
    }
    fs::umount("/floppy");
}

#------------------------------------------------------------------------------
sub selectMouse($) {
    my ($o) = @_;
}

#------------------------------------------------------------------------------
sub configureNetwork {
    my ($o) = @_;
    require network;
    network::configureNetwork2($o, $o->{prefix}, $o->{netc}, $o->{intf});
    if ($o->{method} =~ /ftp|http|nfs/) {
	$o->{netcnx}{type} = 'lan';
	foreach ("up", "down") {
	    my $f = "$o->{prefix}/etc/sysconfig/network-scripts/net_cnx_$_";
	    output $f, "\nif$_ eth0\n";
	    chmod 0755, $f;
	}
	output "$o->{prefix}/etc/sysconfig/network-scripts/net_cnx_pg", "\n/usr/sbin/drakconnet\n";
    }
}

#------------------------------------------------------------------------------
sub installCrypto {
    my ($o) = @_;
    my $u = $o->{crypto} or return; $u->{mirror} && $u->{packages} or return;

    upNetwork($o);
    require crypto;
    my @crypto_packages = crypto::getPackages($o->{prefix}, $o->{packages}, $u->{mirror});
    $o->pkg_install(@{$u->{packages}});
}

sub installUpdates {
    my ($o) = @_;
    my $u = $o->{updates} or return; $u->{updates} or return;

    upNetwork($o);
    require crypto;
    crypto::getPackages($o->{prefix}, $o->{packages}, $u->{mirror}) and
	$o->pkg_install(@{$u->{packages} || []});

    #- re-install urpmi with update security medium.
    $o->install_urpmi;
}

sub summary {
    my ($o) = @_;
    configureTimezone($o);
    configurePrinter($o) if $o->{printer};
}

#------------------------------------------------------------------------------
sub configureTimezone {
    my ($o) = @_;
    install_any::preConfigureTimezone($o);

    $o->pkg_install('ntp') if $o->{timezone}{ntp};

    require timezone;
    timezone::write($o->{prefix}, $o->{timezone});
}

#------------------------------------------------------------------------------
sub configureServices {
    my ($o) = @_;
    if ($o->{services}) {
	require services;
	services::doit($o, $o->{services}, $o->{prefix});
    }
}
#------------------------------------------------------------------------------
sub configurePrinter {
    my($o) = @_;
    $o->do_pkgs->install('foomatic', 'printer-utils','printer-testpages',
			 if_($o->do_pkgs->is_installed('gimp'), 'gimpprint'));
    
    require printer;
    eval { add2hash($o->{printer} ||= {}, printer::getinfo($o->{prefix})) }; #- get existing configuration.

    require printerdrake;
    printerdrake::install_spooler($o->{printer}, $o); #- not interactive...

    foreach (values %{$o->{printer}{configured} || {}}) {
	log::l("configuring printer queue " . $_->{queuedata}{queue} || $_->{QUEUE});
	#- when copy is so adulée (sorry french taste :-)
	#- and when there are some configuration in one place and in another place...
	$o->{printer}{currentqueue} = {};
	printer::copy_printer_params($_->{queuedata}, $o->{printer}{currentqueue});
	printer::copy_printer_params($_, $o->{printer});
	#- setup all configured queues, which is not the case interactively where
	#- only the working queue is setup on configuration.
	printer::configure_queue($o->{printer});
    }
}

#------------------------------------------------------------------------------
sub setRootPassword {
    my ($o) = @_;
    my $p = $o->{prefix};
    my $u = $o->{superuser} ||= {};
    $o->{superuser}{name} = 'root';
    any::write_passwd_user($o->{prefix}, $o->{superuser}, $o->{authentication}{md5});
    delete $o->{superuser}{name};
}

#------------------------------------------------------------------------------

sub addUser {
    my ($o) = @_;
    my $p = $o->{prefix};
    my $users = $o->{users} ||= [];

    my (%uids, %gids); 
    foreach (glob_("$p/home")) { my ($u, $g) = (stat($_))[4,5]; $uids{$u} = 1; $gids{$g} = 1 }

    foreach (@$users) {
	$_->{home} ||= "/home/$_->{name}";

	my $u = $_->{uid} || ($_->{oldu} = (stat("$p$_->{home}"))[4]) || int getpwnam($_->{name});
	my $g = $_->{gid} || ($_->{oldg} = (stat("$p$_->{home}"))[5]) || int getgrnam($_->{name});
	#- search for available uid above 501 else initscripts may fail to change language for KDE.
	if (!$u || getpwuid($u)) { for ($u = 501; getpwuid($u) || $uids{$u}; $u++) {} }
	if (!$g)                 { for ($g = 501; getgrgid($g) || $gids{$g}; $g++) {} }
	
	$_->{uid} = $u; $uids{$u} = 1;
	$_->{gid} = $g; $gids{$g} = 1;
    }

    any::write_passwd_user($p, $_, $o->{authentication}{md5}) foreach @$users;

    local *F;
    open F, ">> $p/etc/group" or die "can't append to group file: $!";
    print F "$_->{name}:x:$_->{gid}:\n" foreach grep { ! getgrgid($_->{gid}) } @$users;

    foreach my $u (@$users) {
	if (! -d "$p$u->{home}") {
	    my $mode = $o->{security} < 2 ? 0755 : 0750;
	    eval { cp_af("$p/etc/skel", "$p$u->{home}") };
	    if ($@) {
		log::l("copying of skel failed: $@"); mkdir("$p$u->{home}", $mode); 
	    } else {
		chmod $mode, "$p$u->{home}";
	    }
	}
	require commands;
	eval { commands::chown_("-r", "$u->{uid}.$u->{gid}", "$p$u->{home}") }
	    if $u->{uid} != $u->{oldu} || $u->{gid} != $u->{oldg};
    }
    any::addUsers($p, $users);

    $o->pkg_install("autologin") if $o->{autologin};
    any::set_autologin($p, $o->{autologin}, $o->{desktop});

    install_any::setAuthentication($o);

    install_any::disable_user_view($p) if @$users == ();
}

#------------------------------------------------------------------------------
sub createBootdisk($) {
    my ($o) = @_;
    my $dev = $o->{mkbootdisk} or return;

    my @l = detect_devices::floppies_dev();

    $dev = shift @l || die _("No floppy drive available")
      if $dev eq "1"; #- special case meaning autochoose

    return if $::testing;

    require bootloader;
    bootloader::mkbootdisk(install_any::kernelVersion($o), $dev, $o->{bootloader}{perImageAppend});
    $o->{mkbootdisk} = $dev;
}

#------------------------------------------------------------------------------
sub readBootloaderConfigBeforeInstall {
    my ($o) = @_;
    my ($image, $v);

    require bootloader;
    add2hash($o->{bootloader} ||= {}, bootloader::read());

    #- since kernel or kernel-smp may not be upgraded, it should be checked
    #- if there is a need to update existing lilo.conf entries by following
    #- symlinks before kernel or other packages get installed.
    #- update everything that could be a filename (for following symlink).
    foreach my $e (@{$o->{bootloader}{entries}}) {
	while (my $v = readlink "$o->{prefix}/$e->{kernel_or_dev}") {
	    $v = "/boot/$v" if $v !~ m|^/|; -e "$o->{prefix}$v" or last;
	    log::l("renaming $e->{kernel_or_dev} entry by $v");
	    $e->{kernel_or_dev} = $v;
	}
	while (my $v = readlink "$o->{prefix}/$e->{initrd}") {
	    $v = "/boot/$v" if $v !~ m|^/|; -e "$o->{prefix}$v" or last;
	    log::l("renaming $e->{initrd} entry by $v");
	    $e->{initrd} = $v;
	}
    }
}

sub setupBootloaderBefore {
    my ($o) = @_;

    require bootloader;
    if (my @l = (grep { $_->{bus} eq 'ide' } detect_devices::burners(), detect_devices::raw_zips())) {
	bootloader::add_append($o->{bootloader}, $_->{device}, 'ide-scsi') foreach @l;
    }
    if ($o->{miscellaneous}{HDPARM}) {
	bootloader::add_append($o->{bootloader}, $_, 'autotune') foreach grep { /ide.*/ } all("/proc/ide");
    }
    if (cat_("/proc/cmdline") =~ /mem=nopentium/) {