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 6000
18 #define UNATTENDED_CONF "/cdrom/boot/unattended.conf"
30 extern char url
[STRING_SIZE
];
32 struct nic nics
[20] = { { "" , "" , "" } }; // only defined for compile
33 struct knic knics
[20] = { { "" , "" , "" , "" } }; // only defined for compile
40 char line
[STRING_SIZE
];
43 if ((fd
= fopen("/proc/cpuinfo", "r")) == NULL
) {
46 while (fgets(line
, STRING_SIZE
, fd
) != NULL
) {
47 if (strstr(line
, "processor") == line
) {
52 return (cpu_count
> 1);
55 long calc_swapsize(long memory
, long disk
) {
66 long calc_rootsize(long free
, long max
) {
79 int main(int argc
, char *argv
[])
81 char *langnames
[] = { "Deutsch", "English", NULL
};
82 char *shortlangnames
[] = { "de", "en", NULL
};
83 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
85 char harddrive
[11], sourcedrive
[5]; /* Device holder. */
86 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
87 int cdmounted
= 0; /* Loop flag for inserting a cd. */
89 char commandstring
[STRING_SIZE
];
90 char *installtypes
[] = { "CDROM/USB", "HTTP/FTP", NULL
};
91 int installtype
= CDROM_INSTALL
;
92 char mkfscommand
[STRING_SIZE
];
93 char *fstypes
[] = { "Reiser4", "ReiserFS", "ext3", NULL
};
99 char shortlangname
[10];
101 char title
[STRING_SIZE
];
103 int allok_fastexit
=0;
105 struct keyvalue
*ethernetkv
= initkeyvalues();
106 FILE *handle
, *cmdfile
;
107 char line
[STRING_SIZE
];
108 char string
[STRING_SIZE
];
109 long maximum_free
= 0, current_free
;
111 long system_partition
, boot_partition
, root_partition
, swap_file
;
113 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
116 struct keyvalue
*unattendedkv
= initkeyvalues();
119 setlocale (LC_ALL
, "");
120 sethostname( SNAME
, 10);
122 memset(&hdparams
, 0, sizeof(struct devparams
));
123 memset(&cdromparams
, 0, sizeof(struct devparams
));
125 /* Log file/terminal stuff. */
128 if (!(flog
= fopen(argv
[1], "w+")))
136 fprintf(flog
, "Install program started.\n");
141 /* Do usb detection first for usb keyboard */
142 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
144 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
146 fgets(line
, STRING_SIZE
, cmdfile
);
147 if (strstr (line
, "noide") == NULL
) {
148 fprintf(flog
, "Initializing IDE controllers.\n");
151 fprintf(flog
, "Skipping IDE detection.\n");
153 if (strstr (line
, "nousb") == NULL
) {
154 fprintf(flog
, "Initializing USB controllers.\n");
157 fprintf(flog
, "Skipping USB detection.\n");
159 // check if we have to make an unattended install
160 if (strstr (line
, "unattended") != NULL
) {
163 // Loading the cdrom-filesystem
164 mysystem("/sbin/modprobe iso9660");
168 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
171 /* German is the default */
172 for (choice
= 0; langnames
[choice
]; choice
++)
174 if (strcmp(langnames
[choice
], "Deutsch") == 0)
177 if (!langnames
[choice
])
181 rc
= newtWinMenu("Language selection",
182 "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
183 langnames
, &choice
, "Ok", NULL
);
186 ctr
= langtrs
[choice
];
187 strcpy(shortlangname
, shortlangnames
[choice
]);
188 fprintf(flog
, "Selected language: %s\n", shortlangname
);
190 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
191 newtPushHelpLine(ctr
[TR_HELPLINE
]);
192 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
195 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
196 newtWinMessage(title
, ctr
[TR_OK
], message
);
198 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
199 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
200 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
201 ctr
[TR_CANCEL
], NULL
);
204 installtype
= CDROM_INSTALL
;
210 // Starting hardware detection
211 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
212 runcommandwithstatus("/bin/probenic.sh install", ctr
[TR_PROBING_HARDWARE
]);
215 if (installtype
== CDROM_INSTALL
) {
216 switch (mysystem("/bin/mountsource.sh")) {
218 installtype
= CDROM_INSTALL
;
222 installtype
= DISK_INSTALL
;
225 errorbox(ctr
[TR_NO_CDROM
]);
229 /* read source drive letter */
230 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
231 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
234 fgets(sourcedrive
, 5, handle
);
235 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
239 /* Configure the network now! */
240 if (installtype
== URL_INSTALL
) {
241 /* Network driver and params. */
242 if (!(networkmenu(ethernetkv
))) {
243 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
247 /* Check for ipfire-<VERSION>.tbz2 */
248 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
249 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
257 fprintf(flog
, "Harddisk scan pass %i\n", i
);
259 switch (mysystem("/bin/mountdest.sh") % 255) {
260 case 0: // Found IDE disk
265 case 1: // Found SCSI disk
270 case 2: // Found RAID disk
275 case 10: // No harddisk found
277 errorbox(ctr
[TR_NO_HARDDISK
]);
280 // Do this if the kudzu-scan fails...
281 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
287 // Need to clean this up at some point
288 // scsi disk is sdb/sdc when sda/sdb is used for usb-key
289 // if scsi-disk is sdd or more, it is not discovered
290 // Support only 2 usb keys, none could be unplugged
291 if (checkusb("sdb") && try_scsi("sdc")) {
293 sprintf(harddrive, "sdc");
294 goto FOUND_DESTINATION;
296 if (checkusb("sda") && try_scsi("sdb")) {
298 sprintf(harddrive, "sdb");
299 goto FOUND_DESTINATION;
301 if (try_scsi("sda")) {
303 sprintf(harddrive, "sda");
304 goto FOUND_DESTINATION;
306 if (try_scsi("ida/c0d0")) {
308 sprintf(harddrive, "ida/c0d0");
309 goto FOUND_DESTINATION;
311 if (try_scsi("cciss/c0d0")) {
313 sprintf(harddrive, "cciss/c0d0");
314 goto FOUND_DESTINATION;
316 if (try_scsi("rd/c0d0")) {
318 sprintf(harddrive, "rd/c0d0");
319 goto FOUND_DESTINATION;
321 if (try_scsi("ataraid/d0")) {
323 sprintf(harddrive, "ataraid/d0");
324 goto FOUND_DESTINATION;
328 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
329 errorbox(ctr
[TR_NO_HARDDISK
]);
332 fgets(harddrive
, 11, handle
);
335 /* load unattended configuration */
337 fprintf(flog
, "unattended: Reading unattended.conf\n");
339 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
342 /* Make the hdparms struct and print the contents.
343 With USB-KEY install and SCSI disk, while installing, the disk
344 is named 'sdb,sdc,...' (following keys)
345 On reboot, it will become 'sda'
346 To avoid many test, all names are built in the struct.
348 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
349 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
350 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
351 /* Now the names after the machine is booted. Only scsi is affected
352 and we only install on the first scsi disk. */
354 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
355 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
356 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
359 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
361 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
366 yesnoharddisk
[0] = ctr
[TR_NO
];
367 yesnoharddisk
[1] = ctr
[TR_YES
];
368 yesnoharddisk
[2] = NULL
;
371 rc
= newtWinMenu(title
, message
,
372 50, 5, 5, 6, yesnoharddisk
,
374 ctr
[TR_CANCEL
], NULL
);
382 sprintf(message
, "(TR) Bitte waehlen Sie ihr Dateisystem aus:");
383 rc
= newtWinMenu("(TR) Dateisystemauswahl", message
,
384 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
385 ctr
[TR_CANCEL
], NULL
);
388 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
393 /* Calculate amount of memory in machine */
394 if ((handle
= fopen("/proc/meminfo", "r")))
396 while (fgets(line
, STRING_SIZE
-1, handle
)) {
397 if (sscanf (line
, "MemTotal: %s kB", string
)) {
398 memory
= atoi(string
) / 1024 ;
404 /* Partition, mkswp, mkfs.
405 * before partitioning, first determine the sizes of each
406 * partition. In order to do that we need to know the size of
409 /* Don't use mysystem here so we can redirect output */
410 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
411 system(commandstring
);
413 /* Calculate amount of disk space */
414 if ((handle
= fopen("/tmp/disksize", "r"))) {
415 fgets(line
, STRING_SIZE
-1, handle
);
416 if (sscanf (line
, "%s", string
)) {
417 maximum_free
= atoi(string
) / 1024;
422 fprintf(flog
, "maximum_free = %ld, memory = %ld", maximum_free
, memory
);
424 swap_file
= calc_swapsize(memory
, maximum_free
);
426 if (maximum_free
< 768 + swap_file
) {
427 if (maximum_free
< 768) {
428 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
433 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
444 boot_partition
= 20; /* in MB */
445 current_free
= maximum_free
- boot_partition
- swap_file
;
447 if (current_free
< 768) {
448 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
452 root_partition
= calc_rootsize(current_free
, maximum_free
);
454 if (root_partition
== 0) {
455 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
458 current_free
= current_free
- root_partition
;
461 if (current_free
< 256) {
462 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
466 system_partition
= current_free
;
468 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
469 boot_partition
, swap_file
, system_partition
, root_partition
);
471 handle
= fopen("/tmp/partitiontable", "w");
475 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
476 boot_partition
, swap_file
, root_partition
);
478 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
479 boot_partition
, root_partition
);
484 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
485 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
487 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
491 if (fstype
== REISER4
) {
492 mysystem("/sbin/modprobe reiser4");
493 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
494 } else if (fstype
== REISERFS
) {
495 mysystem("/sbin/modprobe reiserfs");
496 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
497 } else if (fstype
== EXT3
) {
498 mysystem("/sbin/modprobe ext3");
499 sprintf(mkfscommand
, "/bin/mke2fs -T ext3 -c");
502 snprintf(commandstring
, STRING_SIZE
, "/bin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
503 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
505 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
510 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
511 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
513 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
518 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
519 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
521 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
525 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
526 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
528 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
532 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
533 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
535 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
539 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
540 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
541 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
543 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
544 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
546 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
550 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
551 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
553 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
557 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
558 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
560 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
564 if (installtype
== URL_INSTALL
) {
565 snprintf(commandstring
, STRING_SIZE
,
566 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
569 if (installtype
== CDROM_INSTALL
) {
570 snprintf(commandstring
, STRING_SIZE
,
571 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
574 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
575 ctr
[TR_INSTALLING_FILES
]))
577 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
581 /* Save USB controller type to modules.conf */
582 write_usb_modules_conf();
584 /* Save language und local settings */
585 write_lang_configs(shortlangname
);
587 /* touch the modules.dep files */
588 snprintf(commandstring
, STRING_SIZE
,
589 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
591 mysystem(commandstring
);
592 snprintf(commandstring
, STRING_SIZE
,
593 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
595 mysystem(commandstring
);
598 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
600 /* mount proc filesystem */
601 mysystem("mkdir /harddisk/proc");
602 mysystem("/bin/mount --bind /proc /harddisk/proc");
603 mysystem("/bin/mount --bind /dev /harddisk/dev");
604 mysystem("/bin/mount --bind /sys /harddisk/sys");
606 /* Build cache lang file */
607 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
608 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
610 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
614 /* Update /etc/fstab */
615 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
617 if (fstype
== REISER4
) {
618 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
619 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
620 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
621 } else if (fstype
== REISERFS
) {
622 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
623 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
624 } else if (fstype
== EXT3
) {
625 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
626 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
629 /* Going to make our initrd... */
630 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -v -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
631 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
632 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -v -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
633 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
635 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
636 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
637 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
639 /* restore permissions */
640 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
642 snprintf(commandstring
, STRING_SIZE
,
643 "/sbin/chroot /harddisk /boot/grub/grubbatch");
644 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
645 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
649 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
652 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
654 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
660 fprintf(flog
, "Install program ended.\n");
663 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
665 freekeyvalues(ethernetkv
);
667 if (allok
&& !allok_fastexit
)
670 fprintf(flog
, "Entering unattended setup\n");
671 if (unattended_setup(unattendedkv
)) {
672 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
673 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
675 errorbox("Unattended setup failed.");
685 // Copy our scanned nics to the disk and lock because scan doesn't work in chroot
686 system("touch /harddisk/var/ipfire/ethernet/scan_lock");
687 system("cp -f /tmp/scanned_nics /harddisk/var/ipfire/ethernet/scanned_nics");
688 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
689 printf("Unable to run setup.\n");
690 system("rm -f /harddisk/var/ipfire/ethernet/scan_lock");
693 if (system("/bin/umount /harddisk/proc"))
694 printf("Unable to umount /harddisk/proc.\n");
704 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
709 system("/bin/umount /harddisk/proc");
710 system("/bin/umount /harddisk/dev");
711 system("/bin/umount /harddisk/sys");
713 system("/bin/umount /harddisk/var");
714 system("/bin/umount /harddisk/boot");
715 system("/bin/umount /harddisk");