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