Installer: remove USB wait and clean some comments.
[people/pmueller/ipfire-2.x.git] / src / install+setup / install / main.c
1 /* SmoothWall install program.
2 *
3 * This program is distributed under the terms of the GNU General Public
4 * Licence. See the file COPYING for details.
5 *
6 * (c) Lawrence Manning, 2001
7 * Contains main entry point, and misc functions.6
8 *
9 */
10
11 #include "install.h"
12 #define _GNU_SOURCE
13
14 #define INST_FILECOUNT 8400
15 #define UNATTENDED_CONF "/cdrom/boot/unattended.conf"
16
17 #define EXT2 0
18 #define REISERFS 2
19 #define EXT3 1
20
21 FILE *flog = NULL;
22 char *mylog;
23
24 char **ctr;
25
26 extern char url[STRING_SIZE];
27
28 struct nic nics[20] = { { "" , "" , "" } }; // only defined for compile
29 struct knic knics[20] = { { "" , "" , "" , "" } }; // only defined for compile
30
31 extern char *en_tr[];
32 extern char *es_tr[];
33 extern char *de_tr[];
34 extern char *fr_tr[];
35
36 int main(int argc, char *argv[])
37 {
38 char *langnames[] = { "Deutsch", "English", "Français", "Español", NULL };
39 char *shortlangnames[] = { "de", "en", "fr", "es", NULL };
40 char **langtrs[] = { de_tr, en_tr, fr_tr, es_tr, NULL };
41 char hdletter;
42 char harddrive[30], sourcedrive[5]; /* Device holder. */
43 struct devparams hdparams, cdromparams; /* Params for CDROM and HD */
44 int rc = 0;
45 char commandstring[STRING_SIZE];
46 char mkfscommand[STRING_SIZE];
47 char *fstypes[] = { "ext2", "ext3", "ReiserFS", NULL };
48 int fstype = REISERFS;
49 int choice;
50 int i;
51 int found = 0;
52 int firstrun = 0;
53 char shortlangname[10];
54 char message[1000];
55 char title[STRING_SIZE];
56 int allok = 0;
57 int allok_fastexit=0;
58 int raid_disk = 0;
59 struct keyvalue *ethernetkv = initkeyvalues();
60 FILE *handle, *cmdfile;
61 char line[STRING_SIZE];
62 char string[STRING_SIZE];
63 long memory = 0, disk = 0, free;
64 long system_partition, boot_partition, root_partition, swap_file;
65 int scsi_disk = 0;
66 char *yesnoharddisk[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
67
68 int unattended = 0;
69 struct keyvalue *unattendedkv = initkeyvalues();
70 int hardyn = 0;
71 char restore_file[STRING_SIZE] = "";
72
73 setlocale (LC_ALL, "");
74 sethostname( SNAME , 10);
75
76 memset(&hdparams, 0, sizeof(struct devparams));
77 memset(&cdromparams, 0, sizeof(struct devparams));
78
79 /* Log file/terminal stuff. */
80 if (argc >= 2)
81 {
82 if (!(flog = fopen(argv[1], "w+")))
83 return 0;
84 }
85 else
86 return 0;
87
88 mylog = argv[1];
89
90 fprintf(flog, "Install program started.\n");
91
92 newtInit();
93 newtCls();
94
95 newtDrawRootText(14, 0, NAME " " VERSION " - " SLOGAN );
96 sprintf (title, "%s %s - %s", NAME, VERSION, SLOGAN);
97
98 if (! (cmdfile = fopen("/proc/cmdline", "r")))
99 {
100 fprintf(flog, "Couldn't open commandline: /proc/cmdline\n");
101 } else {
102 fgets(line, STRING_SIZE, cmdfile);
103
104 // check if we have to make an unattended install
105 if (strstr (line, "unattended") != NULL) {
106 unattended = 1;
107 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
108 }
109 }
110
111 // Load common modules
112 mysystem("/sbin/modprobe iso9660"); // CDROM
113 mysystem("/sbin/modprobe ext2"); // Boot patition
114 mysystem("/sbin/modprobe vfat"); // USB key
115
116 /* German is the default */
117 for (choice = 0; langnames[choice]; choice++)
118 {
119 if (strcmp(langnames[choice], "Deutsch") == 0)
120 break;
121 }
122 if (!langnames[choice])
123 goto EXIT;
124
125 if (!unattended) {
126 rc = newtWinMenu("Language selection", "Select the language you wish to use for the " NAME ".", 50, 5, 5, 8,
127 langnames, &choice, "Ok", NULL);
128 }
129
130 ctr = langtrs[choice];
131 strcpy(shortlangname, shortlangnames[choice]);
132
133 newtPushHelpLine(ctr[TR_HELPLINE]);
134
135 sprintf(message, ctr[TR_WELCOME], NAME);
136 newtWinMessage(title, ctr[TR_OK], message);
137
138 switch (mysystem("/bin/mountsource.sh")) {
139 case 0:
140 break;
141 case 10:
142 errorbox(ctr[TR_NO_CDROM]);
143 goto EXIT;
144 }
145
146 /* read source drive letter */
147 if ((handle = fopen("/tmp/source_device", "r")) == NULL) {
148 errorbox(ctr[TR_ERROR_PROBING_CDROM]);
149 goto EXIT;
150 }
151 fgets(sourcedrive, 5, handle);
152 fprintf(flog, "Source drive: %s\n", sourcedrive);
153 fclose(handle);
154
155 i = 0;
156 while (found == 0) {
157 i++;
158 fprintf(flog, "Harddisk scan pass %i\n", i);
159
160 switch (mysystem("/bin/mountdest.sh") % 255) {
161 case 0: // Found IDE disk
162 scsi_disk = 0;
163 raid_disk = 0;
164 found = 1;
165 break;
166 case 1: // Found SCSI disk
167 scsi_disk = 1;
168 raid_disk = 0;
169 found = 1;
170 break;
171 case 2: // Found RAID disk
172 scsi_disk = 0;
173 raid_disk= 1;
174 found = 1;
175 break;
176 case 10: // No harddisk found
177 if (firstrun == 1) {
178 errorbox(ctr[TR_NO_HARDDISK]);
179 goto EXIT;
180 }
181 // Do this if the kudzu-scan fails...
182 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr[TR_PROBING_HARDWARE]);
183 firstrun = 1;
184 }
185 }
186
187 if ((handle = fopen("/tmp/dest_device", "r")) == NULL) {
188 errorbox(ctr[TR_NO_HARDDISK]);
189 goto EXIT;
190 }
191 fgets(harddrive, 30, handle);
192 fclose(handle);
193
194 /* load unattended configuration */
195 if (unattended) {
196 fprintf(flog, "unattended: Reading unattended.conf\n");
197
198 (void) readkeyvalues(unattendedkv, UNATTENDED_CONF);
199 findkey(unattendedkv, "RESTORE_FILE", restore_file);
200 }
201
202 /* Make the hdparms struct and print the contents.
203 With USB-KEY install and SCSI disk, while installing, the disk
204 is named 'sdb,sdc,...' (following keys)
205 On reboot, it will become 'sda'
206 To avoid many test, all names are built in the struct.
207 */
208 sprintf(hdparams.devnode_disk, "/dev/%s", harddrive);
209 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
210 sprintf(hdparams.devnode_part, "/dev/%s%s", harddrive,raid_disk ? "p" : "");
211 /* Now the names after the machine is booted. Only scsi is affected
212 and we only install on the first scsi disk. */
213
214 fprintf(flog, "Destination drive: %s\n", hdparams.devnode_disk);
215
216 sprintf(message, ctr[TR_PREPARE_HARDDISK], hdparams.devnode_disk);
217 if (unattended) {
218 hardyn = 1;
219 } else {
220 yesnoharddisk[0] = ctr[TR_NO];
221 yesnoharddisk[1] = ctr[TR_YES];
222 yesnoharddisk[2] = NULL;
223 }
224
225 while (! hardyn) {
226 rc = newtWinMenu(title, message,
227 50, 5, 5, 6, yesnoharddisk,
228 &hardyn, ctr[TR_OK],
229 ctr[TR_CANCEL], NULL);
230 if (rc == 2)
231 goto EXIT;
232 }
233 if (rc == 2)
234 goto EXIT;
235
236 if (!unattended) {
237 sprintf(message, ctr[TR_CHOOSE_FILESYSTEM]);
238 rc = newtWinMenu( ctr[TR_CHOOSE_FILESYSTEM], message,
239 50, 5, 5, 6, fstypes, &fstype, ctr[TR_OK],
240 ctr[TR_CANCEL], NULL);
241 } else {
242 rc = 1;
243 fstype = REISERFS;
244 }
245 if (rc == 2)
246 goto EXIT;
247
248 /* Calculate amount of memory in machine */
249 if ((handle = fopen("/proc/meminfo", "r")))
250 {
251 while (fgets(line, STRING_SIZE-1, handle)) {
252 if (sscanf (line, "MemTotal: %s kB", string)) {
253 memory = atoi(string) / 1024 ;
254 }
255 }
256 fclose(handle);
257 }
258
259 /* Partition, mkswp, mkfs.
260 * before partitioning, first determine the sizes of each
261 * partition. In order to do that we need to know the size of
262 * the disk.
263 */
264 /* Don't use mysystem here so we can redirect output */
265 sprintf(commandstring, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive);
266 system(commandstring);
267
268 /* Calculate amount of disk space */
269 if ((handle = fopen("/tmp/disksize", "r"))) {
270 fgets(line, STRING_SIZE-1, handle);
271 if (sscanf (line, "%s", string)) {
272 disk = atoi(string) / 1024;
273 }
274 fclose(handle);
275 }
276
277 fprintf(flog, "Disksize = %ld, memory = %ld", disk, memory);
278
279 /* Calculating Swap-Size dependend of Ram Size */
280 if (memory <= 256)
281 swap_file = 128;
282 else if (memory <= 1024 && memory > 256)
283 swap_file = 256;
284 else
285 swap_file = memory / 4;
286
287 /* Calculating Root-Size dependend of Max Disk Space */
288 if ( disk < 756 )
289 root_partition = 200;
290 else if ( disk >= 756 && disk <= 3072 )
291 root_partition = 512;
292 else
293 root_partition = 2048;
294
295
296 /* Calculating the amount of free space */
297 boot_partition = 20; /* in MB */
298 system_partition = disk - ( root_partition + swap_file + boot_partition );
299
300 fprintf(flog, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
301 boot_partition, swap_file, system_partition, root_partition);
302 rc = 0;
303
304 if ( (!unattended) && (((disk - (root_partition + swap_file + boot_partition)) < 256 ) && ((disk - (root_partition + boot_partition )) > 256)) ) {
305 rc = newtWinChoice(title, ctr[TR_OK], ctr[TR_CANCEL], ctr[TR_CONTINUE_NO_SWAP]);
306 if (rc == 1){
307 swap_file = 0;
308 system_partition = disk - ( root_partition + swap_file + boot_partition );
309 fprintf(flog, "Changing Swap Size to 0 MB.\n");
310 }
311 else if (rc == 2){
312 fprintf(flog, "Disk is too small.\n");
313 errorbox(ctr[TR_DISK_TOO_SMALL]);goto EXIT;
314 }
315 }
316 else if (disk - (root_partition + swap_file + boot_partition) >= 256) {
317
318 }
319 else {
320 fprintf(flog, "Disk is too small.\n");
321 errorbox(ctr[TR_DISK_TOO_SMALL]);goto EXIT;
322 }
323
324 handle = fopen("/tmp/partitiontable", "w");
325
326 /* Make swapfile */
327 if (swap_file) {
328 fprintf(handle, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
329 boot_partition, swap_file, root_partition);
330 } else {
331 fprintf(handle, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
332 boot_partition, root_partition);
333 }
334
335 fclose(handle);
336
337 snprintf(commandstring, STRING_SIZE, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams.devnode_disk);
338 if (runcommandwithstatus(commandstring, ctr[TR_PARTITIONING_DISK]))
339 {
340 errorbox(ctr[TR_UNABLE_TO_PARTITION]);
341 goto EXIT;
342 }
343
344 if (fstype == EXT2) {
345 mysystem("/sbin/modprobe ext2");
346 sprintf(mkfscommand, "/sbin/mke2fs -T ext2");
347 } else if (fstype == REISERFS) {
348 mysystem("/sbin/modprobe reiserfs");
349 sprintf(mkfscommand, "/sbin/mkreiserfs -f");
350 } else if (fstype == EXT3) {
351 mysystem("/sbin/modprobe ext3");
352 sprintf(mkfscommand, "/sbin/mke2fs -T ext3");
353 }
354
355 snprintf(commandstring, STRING_SIZE, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams.devnode_part);
356 if (runcommandwithstatus(commandstring, ctr[TR_MAKING_BOOT_FILESYSTEM]))
357 {
358 errorbox(ctr[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM]);
359 goto EXIT;
360 }
361
362 if (swap_file) {
363 snprintf(commandstring, STRING_SIZE, "/sbin/mkswap %s2", hdparams.devnode_part);
364 if (runcommandwithstatus(commandstring, ctr[TR_MAKING_SWAPSPACE]))
365 {
366 errorbox(ctr[TR_UNABLE_TO_MAKE_SWAPSPACE]);
367 goto EXIT;
368 }
369 }
370
371 snprintf(commandstring, STRING_SIZE, "%s %s3", mkfscommand, hdparams.devnode_part);
372 if (runcommandwithstatus(commandstring, ctr[TR_MAKING_ROOT_FILESYSTEM]))
373 {
374 errorbox(ctr[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM]);
375 goto EXIT;
376 }
377
378 snprintf(commandstring, STRING_SIZE, "%s %s4", mkfscommand, hdparams.devnode_part);
379 if (runcommandwithstatus(commandstring, ctr[TR_MAKING_LOG_FILESYSTEM]))
380 {
381 errorbox(ctr[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM]);
382 goto EXIT;
383 }
384
385 snprintf(commandstring, STRING_SIZE, "/bin/mount %s3 /harddisk", hdparams.devnode_part);
386 if (runcommandwithstatus(commandstring, ctr[TR_MOUNTING_ROOT_FILESYSTEM]))
387 {
388 errorbox(ctr[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM]);
389 goto EXIT;
390 }
391
392 mkdir("/harddisk/boot", S_IRWXU|S_IRWXG|S_IRWXO);
393 mkdir("/harddisk/var", S_IRWXU|S_IRWXG|S_IRWXO);
394 mkdir("/harddisk/var/log", S_IRWXU|S_IRWXG|S_IRWXO);
395
396 snprintf(commandstring, STRING_SIZE, "/bin/mount %s1 /harddisk/boot", hdparams.devnode_part);
397 if (runcommandwithstatus(commandstring, ctr[TR_MOUNTING_BOOT_FILESYSTEM]))
398 {
399 errorbox(ctr[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM]);
400 goto EXIT;
401 }
402 if (swap_file) {
403 snprintf(commandstring, STRING_SIZE, "/sbin/swapon %s2", hdparams.devnode_part);
404 if (runcommandwithstatus(commandstring, ctr[TR_MOUNTING_SWAP_PARTITION]))
405 {
406 errorbox(ctr[TR_UNABLE_TO_MOUNT_SWAP_PARTITION]);
407 goto EXIT;
408 }
409 }
410 snprintf(commandstring, STRING_SIZE, "/bin/mount %s4 /harddisk/var", hdparams.devnode_part);
411 if (runcommandwithstatus(commandstring, ctr[TR_MOUNTING_LOG_FILESYSTEM]))
412 {
413 errorbox(ctr[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM]);
414 goto EXIT;
415 }
416
417 snprintf(commandstring, STRING_SIZE,
418 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME "-" VERSION ".tlz --lzma 2>/dev/null");
419
420 if (runcommandwithprogress(60, 4, title, commandstring, INST_FILECOUNT,
421 ctr[TR_INSTALLING_FILES]))
422 {
423 errorbox(ctr[TR_UNABLE_TO_INSTALL_FILES]);
424 goto EXIT;
425 }
426
427 /* Save language und local settings */
428 write_lang_configs(shortlangname);
429
430 /* Rename uname */
431 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
432
433 /* mount proc filesystem */
434 mysystem("mkdir /harddisk/proc");
435 mysystem("/bin/mount --bind /proc /harddisk/proc");
436 mysystem("/bin/mount --bind /dev /harddisk/dev");
437 mysystem("/bin/mount --bind /sys /harddisk/sys");
438
439 /* Build cache lang file */
440 snprintf(commandstring, STRING_SIZE, "/usr/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT "/lang.pl'; &Lang::BuildCacheLang\"");
441 if (runcommandwithstatus(commandstring, ctr[TR_INSTALLING_LANG_CACHE]))
442 {
443 errorbox(ctr[TR_UNABLE_TO_INSTALL_LANG_CACHE]);
444 goto EXIT;
445 }
446
447 /* Update /etc/fstab */
448 snprintf(commandstring, STRING_SIZE, "/bin/sed -i -e \"s#DEVICE1#UUID=$(/sbin/blkid %s1 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams.devnode_part);
449 system(commandstring);
450 snprintf(commandstring, STRING_SIZE, "/bin/sed -i -e \"s#DEVICE2#UUID=$(/sbin/blkid %s2 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams.devnode_part);
451 system(commandstring);
452 snprintf(commandstring, STRING_SIZE, "/bin/sed -i -e \"s#DEVICE3#UUID=$(/sbin/blkid %s3 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams.devnode_part);
453 system(commandstring);
454 snprintf(commandstring, STRING_SIZE, "/bin/sed -i -e \"s#DEVICE4#UUID=$(/sbin/blkid %s4 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams.devnode_part);
455 system(commandstring);
456
457 if (fstype == EXT2) {
458 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
459 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
460 } else if (fstype == REISERFS) {
461 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
462 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
463 } else if (fstype == EXT3) {
464 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
465 NOJOURNAL:
466 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
467 }
468
469 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION);
470
471 snprintf(commandstring, STRING_SIZE, "/bin/sed -i -e \"s#root=ROOT#root=UUID=$(/sbin/blkid %s3 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/boot/grub/grub.conf", hdparams.devnode_part);
472 system(commandstring);
473
474 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
475
476 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
477
478 snprintf(commandstring, STRING_SIZE,
479 "/usr/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams.devnode_disk);
480 if (runcommandwithstatus(commandstring, ctr[TR_INSTALLING_GRUB])) {
481 errorbox(ctr[TR_UNABLE_TO_INSTALL_GRUB]);
482 goto EXIT;
483 }
484
485 /* Copy restore file from cdrom */
486 if (unattended && (strlen(restore_file) > 0)) {
487 fprintf(flog, "unattended: Copy restore file\n");
488 snprintf(commandstring, STRING_SIZE,
489 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file);
490 mysystem(commandstring);
491 }
492
493 mysystem("umount /cdrom");
494 snprintf(commandstring, STRING_SIZE, "/usr/bin/eject /dev/%s", sourcedrive);
495 mysystem(commandstring);
496
497 if (!unattended) {
498 sprintf(message, ctr[TR_CONGRATULATIONS_LONG],
499 NAME, SNAME, NAME);
500 newtWinMessage(ctr[TR_CONGRATULATIONS], ctr[TR_OK], message);
501 }
502
503 allok = 1;
504
505 EXIT:
506 fprintf(flog, "Install program ended.\n");
507
508 if (!(allok))
509 newtWinMessage(title, ctr[TR_OK], ctr[TR_PRESS_OK_TO_REBOOT]);
510
511 freekeyvalues(ethernetkv);
512
513 if (allok && !allok_fastexit)
514 {
515 if (unattended) {
516 fprintf(flog, "Entering unattended setup\n");
517 if (unattended_setup(unattendedkv)) {
518 snprintf(commandstring, STRING_SIZE, "/bin/sleep 10");
519 runcommandwithstatus(commandstring, "Unattended installation finished, system will reboot");
520 } else {
521 errorbox("Unattended setup failed.");
522 goto EXIT;
523 }
524 }
525
526 fflush(flog);
527 fclose(flog);
528 newtFinished();
529
530 // if (!unattended) {
531 // if (system("/usr/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
532 // printf("Unable to run setup.\n");
533 // }
534
535 if (system("/bin/umount /harddisk/proc"))
536 printf("Unable to umount /harddisk/proc.\n");
537 } else {
538 fflush(flog);
539 fclose(flog);
540 newtFinished();
541 }
542
543 fcloseall();
544
545 if (swap_file) {
546 snprintf(commandstring, STRING_SIZE, "/bin/swapoff %s2", hdparams.devnode_part);
547 }
548
549 newtFinished();
550
551 system("/bin/umount /harddisk/proc");
552 system("/bin/umount /harddisk/dev");
553 system("/bin/umount /harddisk/sys");
554
555 system("/bin/umount /harddisk/var");
556 system("/bin/umount /harddisk/boot");
557 system("/bin/umount /harddisk");
558
559 if (!(allok))
560 system("/etc/halt");
561
562 return 0;
563 }