1 /* SmoothWall install program.
3 * This program is distributed under the terms of the GNU General Public
4 * Licence. See the file COPYING for details.
6 * (c) Lawrence Manning, 2001
7 * Contains main entry point, and misc functions.6
14 #define INST_FILECOUNT 6200
15 #define UNATTENDED_CONF "/cdrom/boot/unattended.conf"
26 extern char url
[STRING_SIZE
];
28 struct nic nics
[20] = { { "" , "" , "" } }; // only defined for compile
29 struct knic knics
[20] = { { "" , "" , "" , "" } }; // only defined for compile
34 int main(int argc
, char *argv
[])
36 char *langnames
[] = { "Deutsch", "English", NULL
};
37 char *shortlangnames
[] = { "de", "en", NULL
};
38 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
40 char harddrive
[30], sourcedrive
[5]; /* Device holder. */
41 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
43 char commandstring
[STRING_SIZE
];
44 char mkfscommand
[STRING_SIZE
];
45 char *fstypes
[] = { "Reiser4", "ReiserFS", "ext3", NULL
};
46 int fstype
= REISERFS
;
51 char shortlangname
[10];
53 char title
[STRING_SIZE
];
57 struct keyvalue
*ethernetkv
= initkeyvalues();
58 FILE *handle
, *cmdfile
;
59 char line
[STRING_SIZE
];
60 char string
[STRING_SIZE
];
61 long memory
= 0, disk
= 0, free
;
62 long system_partition
, boot_partition
, root_partition
, swap_file
;
64 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
67 struct keyvalue
*unattendedkv
= initkeyvalues();
70 setlocale (LC_ALL
, "");
71 sethostname( SNAME
, 10);
73 memset(&hdparams
, 0, sizeof(struct devparams
));
74 memset(&cdromparams
, 0, sizeof(struct devparams
));
76 /* Log file/terminal stuff. */
79 if (!(flog
= fopen(argv
[1], "w+")))
87 fprintf(flog
, "Install program started.\n");
92 /* Do usb detection first for usb keyboard */
93 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
95 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
97 fgets(line
, STRING_SIZE
, cmdfile
);
99 // check if we have to make an unattended install
100 if (strstr (line
, "unattended") != NULL
) {
102 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
106 mysystem("/sbin/modprobe ide-generic");
107 mysystem("/sbin/modprobe generic");
108 mysystem("/sbin/modprobe ide-cd");
109 mysystem("/sbin/modprobe ide-disk");
110 mysystem("/sbin/modprobe sata_via");
111 mysystem("/sbin/modprobe uhci-hcd");
112 mysystem("/sbin/modprobe ohci-hcd");
113 mysystem("/sbin/modprobe ehci-hcd");
114 mysystem("/sbin/modprobe ohci1394");
115 mysystem("/sbin/modprobe sd_mod");
116 mysystem("/sbin/modprobe sr_mod");
117 mysystem("/sbin/modprobe usb-storage");
118 mysystem("/sbin/modprobe usbhid");
120 mysystem("/sbin/modprobe iso9660"); // CDROM
121 mysystem("/sbin/modprobe ext2"); // Boot patition
122 mysystem("/sbin/modprobe vfat"); // USB key
124 /* German is the default */
125 for (choice
= 0; langnames
[choice
]; choice
++)
127 if (strcmp(langnames
[choice
], "Deutsch") == 0)
130 if (!langnames
[choice
])
134 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
135 langnames
, &choice
, "Ok", NULL
);
138 ctr
= langtrs
[choice
];
139 strcpy(shortlangname
, shortlangnames
[choice
]);
141 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
142 newtPushHelpLine(ctr
[TR_HELPLINE
]);
143 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
145 // Starting hardware detection
146 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
148 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
149 newtWinMessage(title
, ctr
[TR_OK
], message
);
151 switch (mysystem("/bin/mountsource.sh")) {
155 errorbox(ctr
[TR_NO_CDROM
]);
159 /* read source drive letter */
160 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
161 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
164 fgets(sourcedrive
, 5, handle
);
165 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
171 fprintf(flog
, "Harddisk scan pass %i\n", i
);
173 switch (mysystem("/bin/mountdest.sh") % 255) {
174 case 0: // Found IDE disk
179 case 1: // Found SCSI disk
184 case 2: // Found RAID disk
189 case 10: // No harddisk found
191 errorbox(ctr
[TR_NO_HARDDISK
]);
194 // Do this if the kudzu-scan fails...
195 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
200 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
201 errorbox(ctr
[TR_NO_HARDDISK
]);
204 fgets(harddrive
, 30, handle
);
207 /* load unattended configuration */
209 fprintf(flog
, "unattended: Reading unattended.conf\n");
211 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
214 /* Make the hdparms struct and print the contents.
215 With USB-KEY install and SCSI disk, while installing, the disk
216 is named 'sdb,sdc,...' (following keys)
217 On reboot, it will become 'sda'
218 To avoid many test, all names are built in the struct.
220 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
221 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
222 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
223 /* Now the names after the machine is booted. Only scsi is affected
224 and we only install on the first scsi disk. */
226 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
227 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
228 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
231 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
233 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
237 yesnoharddisk
[0] = ctr
[TR_NO
];
238 yesnoharddisk
[1] = ctr
[TR_YES
];
239 yesnoharddisk
[2] = NULL
;
243 rc
= newtWinMenu(title
, message
,
244 50, 5, 5, 6, yesnoharddisk
,
246 ctr
[TR_CANCEL
], NULL
);
254 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
255 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
256 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
257 ctr
[TR_CANCEL
], NULL
);
265 /* Calculate amount of memory in machine */
266 if ((handle
= fopen("/proc/meminfo", "r")))
268 while (fgets(line
, STRING_SIZE
-1, handle
)) {
269 if (sscanf (line
, "MemTotal: %s kB", string
)) {
270 memory
= atoi(string
) / 1024 ;
276 /* Partition, mkswp, mkfs.
277 * before partitioning, first determine the sizes of each
278 * partition. In order to do that we need to know the size of
281 /* Don't use mysystem here so we can redirect output */
282 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
283 system(commandstring
);
285 /* Calculate amount of disk space */
286 if ((handle
= fopen("/tmp/disksize", "r"))) {
287 fgets(line
, STRING_SIZE
-1, handle
);
288 if (sscanf (line
, "%s", string
)) {
289 disk
= atoi(string
) / 1024;
294 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
296 /* Calculating Swap-Size dependend of Ram Size */
299 else if (memory
>= 1024)
304 /* Calculating Root-Size dependend of Max Disk Space */
306 root_partition
= 200;
307 else if ( disk
>= 756 && disk
<= 3072 )
308 root_partition
= 512;
310 root_partition
= 2048;
313 /* Calculating the amount of free space */
314 boot_partition
= 20; /* in MB */
315 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
317 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
318 boot_partition
, swap_file
, system_partition
, root_partition
);
321 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
322 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
325 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
326 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
329 fprintf(flog
, "Disk is too small.\n");
330 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
333 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
337 fprintf(flog
, "Disk is too small.\n");
338 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
341 handle
= fopen("/tmp/partitiontable", "w");
345 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
346 boot_partition
, swap_file
, root_partition
);
348 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
349 boot_partition
, root_partition
);
354 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
355 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
357 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
361 if (fstype
== REISER4
) {
362 mysystem("/sbin/modprobe reiser4");
363 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
364 } else if (fstype
== REISERFS
) {
365 mysystem("/sbin/modprobe reiserfs");
366 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
367 } else if (fstype
== EXT3
) {
368 mysystem("/sbin/modprobe ext3");
369 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
372 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
373 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
375 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
380 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
381 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
383 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
388 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
389 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
391 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
395 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
396 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
398 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
402 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
403 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
405 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
409 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
410 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
411 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
413 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
414 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
416 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
420 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
421 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
423 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
427 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
428 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
430 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
434 snprintf(commandstring
, STRING_SIZE
,
435 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
437 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
438 ctr
[TR_INSTALLING_FILES
]))
440 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
444 /* Save language und local settings */
445 write_lang_configs(shortlangname
);
447 /* touch the modules.dep files */
448 snprintf(commandstring
, STRING_SIZE
,
449 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
451 mysystem(commandstring
);
452 /* snprintf(commandstring, STRING_SIZE,
453 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
455 mysystem(commandstring);
458 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
460 /* mount proc filesystem */
461 mysystem("mkdir /harddisk/proc");
462 mysystem("/bin/mount --bind /proc /harddisk/proc");
463 mysystem("/bin/mount --bind /dev /harddisk/dev");
464 mysystem("/bin/mount --bind /sys /harddisk/sys");
466 /* Build cache lang file */
467 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
468 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
470 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
474 /* Update /etc/fstab */
475 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
477 if (fstype
== REISER4
) {
478 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
479 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
480 } else if (fstype
== REISERFS
) {
481 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
482 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
483 } else if (fstype
== EXT3
) {
484 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
485 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
487 errorbox(ctr
[TR_JOURNAL_ERROR
]);
488 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
491 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
492 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
494 errorbox(ctr
[TR_JOURNAL_ERROR
]);
495 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
498 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
500 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
503 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
505 /* Build the emergency ramdisk with all drivers */
506 mysystem("cp -f /harddisk/etc/mkinitcpio.conf /harddisk/etc/mkinitcpio.conf.org");
508 replace("/harddisk/etc/mkinitcpio.conf", " autodetect ", " ");
509 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s-emergency.img -k %s-ipfire", KERNEL_VERSION
, KERNEL_VERSION
);
510 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
512 mysystem("cp -f /harddisk/etc/mkinitcpio.conf.org /harddisk/etc/mkinitcpio.conf");
514 /* mkinitcpio has a problem if ide and pata are included */
515 if ( scsi_disk
==1 ) {
516 /* Remove the ide hook if we install sda */
517 replace("/harddisk/etc/mkinitcpio.conf", " ide ", " ");
519 /* Remove the pata & sata hook if we install hda */
520 replace("/harddisk/etc/mkinitcpio.conf", " pata ", " ");
521 replace("/harddisk/etc/mkinitcpio.conf", " sata ", " ");
523 /* Going to make our initrd... */
524 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s.img -k %s-ipfire", KERNEL_VERSION
, KERNEL_VERSION
);
525 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
526 /* snprintf(commandstring, STRING_SIZE, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s-smp.img -k %s-ipfire-smp", KERNEL_VERSION, KERNEL_VERSION );
527 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
529 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
530 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
531 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
533 system("sed -e 's#harddisk\\/##g' < /proc/mounts > /harddisk/etc/mtab");
535 snprintf(commandstring
, STRING_SIZE
,
536 "/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
537 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
538 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
542 mysystem("umount /cdrom");
543 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
544 mysystem(commandstring
);
547 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
549 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
555 fprintf(flog
, "Install program ended.\n");
558 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
560 freekeyvalues(ethernetkv
);
562 if (allok
&& !allok_fastexit
)
565 fprintf(flog
, "Entering unattended setup\n");
566 if (unattended_setup(unattendedkv
)) {
567 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
568 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
570 errorbox("Unattended setup failed.");
580 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
581 printf("Unable to run setup.\n");
584 if (system("/bin/umount /harddisk/proc"))
585 printf("Unable to umount /harddisk/proc.\n");
595 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
600 system("/bin/umount /harddisk/proc");
601 system("/bin/umount /harddisk/dev");
602 system("/bin/umount /harddisk/sys");
604 system("/bin/umount /harddisk/var");
605 system("/bin/umount /harddisk/boot");
606 system("/bin/umount /harddisk");