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
};
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 uhci-hcd");
111 mysystem("/sbin/modprobe ohci-hcd");
112 mysystem("/sbin/modprobe ehci-hcd");
113 mysystem("/sbin/modprobe ohci1394");
114 mysystem("/sbin/modprobe sd_mod");
115 mysystem("/sbin/modprobe sr_mod");
116 mysystem("/sbin/modprobe usb-storage");
117 mysystem("/sbin/modprobe usbhid");
119 mysystem("/sbin/modprobe iso9660"); // CDROM
120 mysystem("/sbin/modprobe ext2"); // Boot patition
121 mysystem("/sbin/modprobe vfat"); // USB key
123 // AHCI must be loaded after the filesystems
124 // or it find no partitions
125 mysystem("/sbin/modprobe ahci"); // SATA AHCI Host controller
128 /* German is the default */
129 for (choice
= 0; langnames
[choice
]; choice
++)
131 if (strcmp(langnames
[choice
], "Deutsch") == 0)
134 if (!langnames
[choice
])
138 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
139 langnames
, &choice
, "Ok", NULL
);
142 ctr
= langtrs
[choice
];
143 strcpy(shortlangname
, shortlangnames
[choice
]);
145 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
146 newtPushHelpLine(ctr
[TR_HELPLINE
]);
147 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
149 // Starting hardware detection
150 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
152 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
153 newtWinMessage(title
, ctr
[TR_OK
], message
);
155 switch (mysystem("/bin/mountsource.sh")) {
159 errorbox(ctr
[TR_NO_CDROM
]);
163 /* read source drive letter */
164 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
165 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
168 fgets(sourcedrive
, 5, handle
);
169 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
175 fprintf(flog
, "Harddisk scan pass %i\n", i
);
177 switch (mysystem("/bin/mountdest.sh") % 255) {
178 case 0: // Found IDE disk
183 case 1: // Found SCSI disk
188 case 2: // Found RAID disk
193 case 10: // No harddisk found
195 errorbox(ctr
[TR_NO_HARDDISK
]);
198 // Do this if the kudzu-scan fails...
199 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
204 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
205 errorbox(ctr
[TR_NO_HARDDISK
]);
208 fgets(harddrive
, 30, handle
);
211 /* load unattended configuration */
213 fprintf(flog
, "unattended: Reading unattended.conf\n");
215 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
218 /* Make the hdparms struct and print the contents.
219 With USB-KEY install and SCSI disk, while installing, the disk
220 is named 'sdb,sdc,...' (following keys)
221 On reboot, it will become 'sda'
222 To avoid many test, all names are built in the struct.
224 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
225 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
226 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
227 /* Now the names after the machine is booted. Only scsi is affected
228 and we only install on the first scsi disk. */
230 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
231 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
232 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
235 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
237 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
241 yesnoharddisk
[0] = ctr
[TR_NO
];
242 yesnoharddisk
[1] = ctr
[TR_YES
];
243 yesnoharddisk
[2] = NULL
;
247 rc
= newtWinMenu(title
, message
,
248 50, 5, 5, 6, yesnoharddisk
,
250 ctr
[TR_CANCEL
], NULL
);
258 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
259 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
260 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
261 ctr
[TR_CANCEL
], NULL
);
264 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
269 /* Calculate amount of memory in machine */
270 if ((handle
= fopen("/proc/meminfo", "r")))
272 while (fgets(line
, STRING_SIZE
-1, handle
)) {
273 if (sscanf (line
, "MemTotal: %s kB", string
)) {
274 memory
= atoi(string
) / 1024 ;
280 /* Partition, mkswp, mkfs.
281 * before partitioning, first determine the sizes of each
282 * partition. In order to do that we need to know the size of
285 /* Don't use mysystem here so we can redirect output */
286 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
287 system(commandstring
);
289 /* Calculate amount of disk space */
290 if ((handle
= fopen("/tmp/disksize", "r"))) {
291 fgets(line
, STRING_SIZE
-1, handle
);
292 if (sscanf (line
, "%s", string
)) {
293 disk
= atoi(string
) / 1024;
298 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
300 /* Calculating Swap-Size dependend of Ram Size */
303 else if (memory
>= 1024)
308 /* Calculating Root-Size dependend of Max Disk Space */
310 root_partition
= 200;
311 else if ( disk
>= 756 && disk
<= 3072 )
312 root_partition
= 512;
314 root_partition
= 2048;
317 /* Calculating the amount of free space */
318 boot_partition
= 20; /* in MB */
319 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
321 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
322 boot_partition
, swap_file
, system_partition
, root_partition
);
325 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
326 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
329 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
330 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
333 fprintf(flog
, "Disk is too small.\n");
334 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
337 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
341 fprintf(flog
, "Disk is too small.\n");
342 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
345 handle
= fopen("/tmp/partitiontable", "w");
349 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
350 boot_partition
, swap_file
, root_partition
);
352 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
353 boot_partition
, root_partition
);
358 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
359 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
361 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
365 if (fstype
== REISER4
) {
366 mysystem("/sbin/modprobe reiser4");
367 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
368 } else if (fstype
== REISERFS
) {
369 mysystem("/sbin/modprobe reiserfs");
370 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
371 } else if (fstype
== EXT3
) {
372 mysystem("/sbin/modprobe ext3");
373 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
376 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
377 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
379 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
384 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
385 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
387 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
392 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
393 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
395 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
399 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
400 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
402 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
406 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
407 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
409 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
413 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
414 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
415 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
417 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
418 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
420 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
424 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
425 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
427 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
431 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
432 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
434 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
438 snprintf(commandstring
, STRING_SIZE
,
439 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
441 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
442 ctr
[TR_INSTALLING_FILES
]))
444 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
448 /* Save language und local settings */
449 write_lang_configs(shortlangname
);
451 /* touch the modules.dep files */
452 snprintf(commandstring
, STRING_SIZE
,
453 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
455 mysystem(commandstring
);
456 snprintf(commandstring
, STRING_SIZE
,
457 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
459 mysystem(commandstring
);
462 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
464 /* mount proc filesystem */
465 mysystem("mkdir /harddisk/proc");
466 mysystem("/bin/mount --bind /proc /harddisk/proc");
467 mysystem("/bin/mount --bind /dev /harddisk/dev");
468 mysystem("/bin/mount --bind /sys /harddisk/sys");
470 /* Build cache lang file */
471 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
472 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
474 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
478 /* Update /etc/fstab */
479 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
481 if (fstype
== REISER4
) {
482 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
483 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
484 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
485 } else if (fstype
== REISERFS
) {
486 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
487 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
488 } else if (fstype
== EXT3
) {
489 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
490 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
492 errorbox(ctr
[TR_JOURNAL_ERROR
]);
493 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
496 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
497 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
499 errorbox(ctr
[TR_JOURNAL_ERROR
]);
500 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
503 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
505 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"ext3 ");
506 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
509 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
511 /* mkinitcpio has a problem if ide and pata are included */
512 if ( scsi_disk
==1 ) {
513 /* Remove the ide hook if we install sda */
514 replace("/harddisk/etc/mkinitcpio.conf", " ide ", " ");
516 /* Remove the pata & sata hook if we install hda */
517 replace("/harddisk/etc/mkinitcpio.conf", " pata ", " ");
518 replace("/harddisk/etc/mkinitcpio.conf", " sata ", " ");
520 /* Going to make our initrd... */
521 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s.img -k %s-ipfire", KERNEL_VERSION
, KERNEL_VERSION
);
522 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
523 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s-smp.img -k %s-ipfire-smp", KERNEL_VERSION
, KERNEL_VERSION
);
524 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
526 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
527 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
528 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
530 system("sed -e 's#harddisk\\/##g' < /proc/mounts > /harddisk/etc/mtab");
532 snprintf(commandstring
, STRING_SIZE
,
533 "/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
534 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
535 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
539 mysystem("umount /cdrom");
540 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
541 mysystem(commandstring
);
544 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
546 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
552 fprintf(flog
, "Install program ended.\n");
555 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
557 freekeyvalues(ethernetkv
);
559 if (allok
&& !allok_fastexit
)
562 fprintf(flog
, "Entering unattended setup\n");
563 if (unattended_setup(unattendedkv
)) {
564 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
565 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
567 errorbox("Unattended setup failed.");
577 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
578 printf("Unable to run setup.\n");
581 if (system("/bin/umount /harddisk/proc"))
582 printf("Unable to umount /harddisk/proc.\n");
592 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
597 system("/bin/umount /harddisk/proc");
598 system("/bin/umount /harddisk/dev");
599 system("/bin/umount /harddisk/sys");
601 system("/bin/umount /harddisk/var");
602 system("/bin/umount /harddisk/boot");
603 system("/bin/umount /harddisk");