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 CDROM_INSTALL 0
16 #define DISK_INSTALL 2
17 #define INST_FILECOUNT 6200
18 #define UNATTENDED_CONF "/cdrom/boot/unattended.conf"
29 extern char url
[STRING_SIZE
];
31 struct nic nics
[20] = { { "" , "" , "" } }; // only defined for compile
32 struct knic knics
[20] = { { "" , "" , "" , "" } }; // only defined for compile
39 char line
[STRING_SIZE
];
42 if ((fd
= fopen("/proc/cpuinfo", "r")) == NULL
) {
45 while (fgets(line
, STRING_SIZE
, fd
) != NULL
) {
46 if (strstr(line
, "processor") == line
) {
51 return (cpu_count
> 1);
54 long calc_swapsize(long memory
, long disk
) {
65 long calc_rootsize(long free
, long max
) {
78 int main(int argc
, char *argv
[])
80 char *langnames
[] = { "Deutsch", "English", NULL
};
81 char *shortlangnames
[] = { "de", "en", NULL
};
82 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
84 char harddrive
[11], sourcedrive
[5]; /* Device holder. */
85 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
86 int cdmounted
= 0; /* Loop flag for inserting a cd. */
88 char commandstring
[STRING_SIZE
];
89 char *installtypes
[] = { "CDROM/USB", "HTTP/FTP", NULL
};
90 int installtype
= CDROM_INSTALL
;
91 char mkfscommand
[STRING_SIZE
];
92 char *fstypes
[] = { "Reiser4", "ReiserFS", "ext3", NULL
};
98 char shortlangname
[10];
100 char title
[STRING_SIZE
];
102 int allok_fastexit
=0;
104 struct keyvalue
*ethernetkv
= initkeyvalues();
105 FILE *handle
, *cmdfile
;
106 char line
[STRING_SIZE
];
107 char string
[STRING_SIZE
];
108 long maximum_free
= 0, current_free
;
110 long system_partition
, boot_partition
, root_partition
, swap_file
;
112 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
115 struct keyvalue
*unattendedkv
= initkeyvalues();
118 setlocale (LC_ALL
, "");
119 sethostname( SNAME
, 10);
121 memset(&hdparams
, 0, sizeof(struct devparams
));
122 memset(&cdromparams
, 0, sizeof(struct devparams
));
124 /* Log file/terminal stuff. */
127 if (!(flog
= fopen(argv
[1], "w+")))
135 fprintf(flog
, "Install program started.\n");
140 /* Do usb detection first for usb keyboard */
141 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
143 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
145 fgets(line
, STRING_SIZE
, cmdfile
);
146 if (strstr (line
, "noide") == NULL
) {
147 fprintf(flog
, "Initializing IDE controllers.\n");
150 fprintf(flog
, "Skipping IDE detection.\n");
152 if (strstr (line
, "nousb") == NULL
) {
153 fprintf(flog
, "Initializing USB controllers.\n");
156 fprintf(flog
, "Skipping USB detection.\n");
158 // check if we have to make an unattended install
159 if (strstr (line
, "unattended") != NULL
) {
162 // Loading the cdrom-filesystem
163 mysystem("/sbin/modprobe iso9660");
167 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
170 /* German is the default */
171 for (choice
= 0; langnames
[choice
]; choice
++)
173 if (strcmp(langnames
[choice
], "Deutsch") == 0)
176 if (!langnames
[choice
])
180 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
181 langnames
, &choice
, "Ok", NULL
);
184 ctr
= langtrs
[choice
];
185 strcpy(shortlangname
, shortlangnames
[choice
]);
186 fprintf(flog
, "Selected language: %s\n", shortlangname
);
188 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
189 newtPushHelpLine(ctr
[TR_HELPLINE
]);
190 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
193 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
194 newtWinMessage(title
, ctr
[TR_OK
], message
);
196 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
197 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
198 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
199 ctr
[TR_CANCEL
], NULL
);
202 installtype
= CDROM_INSTALL
;
208 // Starting hardware detection
209 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
212 if (installtype
== CDROM_INSTALL
) {
213 switch (mysystem("/bin/mountsource.sh")) {
215 installtype
= CDROM_INSTALL
;
219 installtype
= DISK_INSTALL
;
222 errorbox(ctr
[TR_NO_CDROM
]);
226 /* read source drive letter */
227 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
228 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
231 fgets(sourcedrive
, 5, handle
);
232 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
236 /* Configure the network now! */
237 if (installtype
== URL_INSTALL
) {
238 /* Network driver and params. */
239 if (!(networkmenu(ethernetkv
))) {
240 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
244 /* Check for ipfire-<VERSION>.tbz2 */
245 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
246 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
254 fprintf(flog
, "Harddisk scan pass %i\n", i
);
256 switch (mysystem("/bin/mountdest.sh") % 255) {
257 case 0: // Found IDE disk
262 case 1: // Found SCSI disk
267 case 2: // Found RAID disk
272 case 10: // No harddisk found
274 errorbox(ctr
[TR_NO_HARDDISK
]);
277 // Do this if the kudzu-scan fails...
278 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
283 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
284 errorbox(ctr
[TR_NO_HARDDISK
]);
287 fgets(harddrive
, 11, handle
);
290 /* load unattended configuration */
292 fprintf(flog
, "unattended: Reading unattended.conf\n");
294 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
297 /* Make the hdparms struct and print the contents.
298 With USB-KEY install and SCSI disk, while installing, the disk
299 is named 'sdb,sdc,...' (following keys)
300 On reboot, it will become 'sda'
301 To avoid many test, all names are built in the struct.
303 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
304 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
305 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
306 /* Now the names after the machine is booted. Only scsi is affected
307 and we only install on the first scsi disk. */
309 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
310 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
311 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
314 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
316 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
321 yesnoharddisk
[0] = ctr
[TR_NO
];
322 yesnoharddisk
[1] = ctr
[TR_YES
];
323 yesnoharddisk
[2] = NULL
;
326 rc
= newtWinMenu(title
, message
,
327 50, 5, 5, 6, yesnoharddisk
,
329 ctr
[TR_CANCEL
], NULL
);
337 sprintf(message
, "(TR) Bitte waehlen Sie ihr Dateisystem aus:");
338 rc
= newtWinMenu("(TR) Dateisystemauswahl", message
,
339 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
340 ctr
[TR_CANCEL
], NULL
);
343 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
348 /* Calculate amount of memory in machine */
349 if ((handle
= fopen("/proc/meminfo", "r")))
351 while (fgets(line
, STRING_SIZE
-1, handle
)) {
352 if (sscanf (line
, "MemTotal: %s kB", string
)) {
353 memory
= atoi(string
) / 1024 ;
359 /* Partition, mkswp, mkfs.
360 * before partitioning, first determine the sizes of each
361 * partition. In order to do that we need to know the size of
364 /* Don't use mysystem here so we can redirect output */
365 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
366 system(commandstring
);
368 /* Calculate amount of disk space */
369 if ((handle
= fopen("/tmp/disksize", "r"))) {
370 fgets(line
, STRING_SIZE
-1, handle
);
371 if (sscanf (line
, "%s", string
)) {
372 maximum_free
= atoi(string
) / 1024;
377 fprintf(flog
, "maximum_free = %ld, memory = %ld", maximum_free
, memory
);
379 swap_file
= calc_swapsize(memory
, maximum_free
);
381 if (maximum_free
< 512 + swap_file
) {
382 if (maximum_free
< 700) {
383 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
388 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
398 boot_partition
= 20; /* in MB */
399 current_free
= maximum_free
- boot_partition
- swap_file
;
401 if (current_free
< 700) {
402 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
406 root_partition
= calc_rootsize(current_free
, maximum_free
);
408 if (root_partition
== 0) {
409 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
412 current_free
= current_free
- root_partition
;
415 if (current_free
< 256) {
416 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
420 system_partition
= current_free
;
422 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
423 boot_partition
, swap_file
, system_partition
, root_partition
);
425 handle
= fopen("/tmp/partitiontable", "w");
429 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
430 boot_partition
, swap_file
, root_partition
);
432 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
433 boot_partition
, root_partition
);
438 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
439 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
441 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
445 if (fstype
== REISER4
) {
446 mysystem("/sbin/modprobe reiser4");
447 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
448 } else if (fstype
== REISERFS
) {
449 mysystem("/sbin/modprobe reiserfs");
450 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
451 } else if (fstype
== EXT3
) {
452 mysystem("/sbin/modprobe ext3");
453 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
456 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
457 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
459 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
464 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
465 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
467 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
472 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
473 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
475 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
479 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
480 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
482 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
486 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
487 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
489 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
493 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
494 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
495 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
497 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
498 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
500 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
504 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
505 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
507 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
511 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
512 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
514 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
518 if (installtype
== URL_INSTALL
) {
519 snprintf(commandstring
, STRING_SIZE
,
520 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
523 if (installtype
== CDROM_INSTALL
) {
524 snprintf(commandstring
, STRING_SIZE
,
525 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
528 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
529 ctr
[TR_INSTALLING_FILES
]))
531 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
535 /* Save USB controller type to modules.conf */
536 write_usb_modules_conf();
538 /* Save language und local settings */
539 write_lang_configs(shortlangname
);
541 /* touch the modules.dep files */
542 snprintf(commandstring
, STRING_SIZE
,
543 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
545 mysystem(commandstring
);
546 snprintf(commandstring
, STRING_SIZE
,
547 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
549 mysystem(commandstring
);
552 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
554 /* mount proc filesystem */
555 mysystem("mkdir /harddisk/proc");
556 mysystem("/bin/mount --bind /proc /harddisk/proc");
557 mysystem("/bin/mount --bind /dev /harddisk/dev");
558 mysystem("/bin/mount --bind /sys /harddisk/sys");
560 /* Build cache lang file */
561 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
562 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
564 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
568 /* Update /etc/fstab */
569 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
571 if (fstype
== REISER4
) {
572 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
573 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
574 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
575 } else if (fstype
== REISERFS
) {
576 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
577 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
578 } else if (fstype
== EXT3
) {
579 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
580 if (runcommandwithstatus(commandstring
, "(TR) Creating journal for ext3..."))
582 errorbox("(TR) Unable to create journal. Going back to ext2.");
583 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
586 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
587 if (runcommandwithstatus(commandstring
, "(TR) Creating journal for ext3..."))
589 errorbox("(TR) Unable to create journal. Going back to ext2.");
590 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
593 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
595 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"ext3 ");
596 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
599 /* Going to make our initrd... */
600 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
601 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
602 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
603 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
605 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
606 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
607 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
609 /* restore permissions */
610 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
612 snprintf(commandstring
, STRING_SIZE
,
613 "/sbin/chroot /harddisk /boot/grub/grubbatch");
614 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
615 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
619 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
621 mysystem("umount /cdrom");
622 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
623 mysystem(commandstring
);
626 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
628 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
634 fprintf(flog
, "Install program ended.\n");
637 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
639 freekeyvalues(ethernetkv
);
641 if (allok
&& !allok_fastexit
)
644 fprintf(flog
, "Entering unattended setup\n");
645 if (unattended_setup(unattendedkv
)) {
646 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
647 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
649 errorbox("Unattended setup failed.");
659 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
660 printf("Unable to run setup.\n");
663 if (system("/bin/umount /harddisk/proc"))
664 printf("Unable to umount /harddisk/proc.\n");
674 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
679 system("/bin/umount /harddisk/proc");
680 system("/bin/umount /harddisk/dev");
681 system("/bin/umount /harddisk/sys");
683 system("/bin/umount /harddisk/var");
684 system("/bin/umount /harddisk/boot");
685 system("/bin/umount /harddisk");