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 int main(int argc
, char *argv
[])
68 char *langnames
[] = { "Deutsch", "English", NULL
};
69 char *shortlangnames
[] = { "de", "en", NULL
};
70 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
72 char harddrive
[5], sourcedrive
[5]; /* Device holder. */
73 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
74 int cdmounted
= 0; /* Loop flag for inserting a cd. */
76 char commandstring
[STRING_SIZE
];
77 char *installtypes
[] = { "CDROM/USB", "HTTP/FTP", NULL
};
78 int installtype
= CDROM_INSTALL
;
79 char mkfscommand
[STRING_SIZE
];
80 char *fstypes
[] = { "Reiser4", "ReiserFS", "ext3", NULL
};
86 char shortlangname
[10];
88 char title
[STRING_SIZE
];
91 struct keyvalue
*ethernetkv
= initkeyvalues();
92 FILE *handle
, *cmdfile
;
93 char line
[STRING_SIZE
];
94 char string
[STRING_SIZE
];
95 long maximum_free
= 0, current_free
;
97 long system_partition
, boot_partition
, root_partition
, swap_file
;
99 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
102 struct keyvalue
*unattendedkv
= initkeyvalues();
105 setlocale (LC_ALL
, "");
106 sethostname( SNAME
, 10);
108 memset(&hdparams
, 0, sizeof(struct devparams
));
109 memset(&cdromparams
, 0, sizeof(struct devparams
));
111 /* Log file/terminal stuff. */
114 if (!(flog
= fopen(argv
[1], "w+")))
122 fprintf(flog
, "Install program started.\n");
127 /* Do usb detection first for usb keyboard */
128 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
130 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
132 fgets(line
, STRING_SIZE
, cmdfile
);
133 if (strstr (line
, "noide") == NULL
) {
134 fprintf(flog
, "Initializing IDE controllers.\n");
137 fprintf(flog
, "Skipping IDE detection.\n");
139 if (strstr (line
, "nousb") == NULL
) {
140 fprintf(flog
, "Initializing USB controllers.\n");
143 fprintf(flog
, "Skipping USB detection.\n");
145 // check if we have to make an unattended install
146 if (strstr (line
, "unattended") != NULL
) {
149 // Loading the cdrom-filesystem
150 mysystem("/sbin/modprobe iso9660");
154 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
157 /* German is the default */
158 for (choice
= 0; langnames
[choice
]; choice
++)
160 if (strcmp(langnames
[choice
], "Deutsch") == 0)
163 if (!langnames
[choice
])
167 rc
= newtWinMenu("Language selection",
168 "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
169 langnames
, &choice
, "Ok", NULL
);
172 ctr
= langtrs
[choice
];
173 strcpy(shortlangname
, shortlangnames
[choice
]);
174 fprintf(flog
, "Selected language: %s\n", shortlangname
);
176 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
177 newtPushHelpLine(ctr
[TR_HELPLINE
]);
178 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
181 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
182 newtWinMessage(title
, ctr
[TR_OK
], message
);
184 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
185 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
186 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
187 ctr
[TR_CANCEL
], NULL
);
190 installtype
= CDROM_INSTALL
;
196 // Starting hardware detection
197 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
198 runcommandwithstatus("/bin/probenic.sh install", ctr
[TR_PROBING_HARDWARE
]);
201 if (installtype
== CDROM_INSTALL
) {
202 switch (mysystem("/bin/mountsource.sh")) {
204 installtype
= CDROM_INSTALL
;
208 installtype
= DISK_INSTALL
;
211 errorbox(ctr
[TR_NO_CDROM
]);
215 /* read source drive letter */
216 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
217 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
220 fgets(sourcedrive
, 5, handle
);
221 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
225 /* Configure the network now! */
226 if (installtype
== URL_INSTALL
) {
227 /* Network driver and params. */
228 if (!(networkmenu(ethernetkv
))) {
229 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
233 /* Check for ipfire-<VERSION>.tbz2 */
234 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
235 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
243 fprintf(flog
, "Harddisk scan pass %i\n", i
);
245 switch (mysystem("/bin/mountdest.sh") % 255) {
246 case 0: // Found IDE disk
250 case 1: // Found SCSI disk
254 case 10: // No harddisk found
256 errorbox(ctr
[TR_NO_HARDDISK
]);
259 // Do this if the kudzu-scan fails...
260 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
266 // Need to clean this up at some point
267 // scsi disk is sdb/sdc when sda/sdb is used for usb-key
268 // if scsi-disk is sdd or more, it is not discovered
269 // Support only 2 usb keys, none could be unplugged
270 if (checkusb("sdb") && try_scsi("sdc")) {
272 sprintf(harddrive, "sdc");
273 goto FOUND_DESTINATION;
275 if (checkusb("sda") && try_scsi("sdb")) {
277 sprintf(harddrive, "sdb");
278 goto FOUND_DESTINATION;
280 if (try_scsi("sda")) {
282 sprintf(harddrive, "sda");
283 goto FOUND_DESTINATION;
285 if (try_scsi("ida/c0d0")) {
287 sprintf(harddrive, "ida/c0d0");
288 goto FOUND_DESTINATION;
290 if (try_scsi("cciss/c0d0")) {
292 sprintf(harddrive, "cciss/c0d0");
293 goto FOUND_DESTINATION;
295 if (try_scsi("rd/c0d0")) {
297 sprintf(harddrive, "rd/c0d0");
298 goto FOUND_DESTINATION;
300 if (try_scsi("ataraid/d0")) {
302 sprintf(harddrive, "ataraid/d0");
303 goto FOUND_DESTINATION;
307 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
308 errorbox(ctr
[TR_NO_HARDDISK
]);
311 fgets(harddrive
, 5, handle
);
314 /* load unattended configuration */
316 fprintf(flog
, "unattended: Reading unattended.conf\n");
318 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
321 /* Make the hdparms struct and print the contents.
322 With USB-KEY install and SCSI disk, while installing, the disk
323 is named 'sdb,sdc,...' (following keys)
324 On reboot, it will become 'sda'
325 To avoid many test, all names are built in the struct.
327 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
328 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
329 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
330 /* Now the names after the machine is booted. Only scsi is affected
331 and we only install on the first scsi disk. */
333 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
334 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
335 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
338 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
340 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
345 yesnoharddisk
[0] = ctr
[TR_NO
];
346 yesnoharddisk
[1] = ctr
[TR_YES
];
347 yesnoharddisk
[2] = NULL
;
350 rc
= newtWinMenu(title
, message
,
351 50, 5, 5, 6, yesnoharddisk
,
353 ctr
[TR_CANCEL
], NULL
);
361 sprintf(message
, "(TR) Bitte waehlen Sie ihr Dateisystem aus:");
362 rc
= newtWinMenu("(TR) Dateisystemauswahl", message
,
363 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
364 ctr
[TR_CANCEL
], NULL
);
367 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
372 /* Calculate amount of memory in machine */
373 if ((handle
= fopen("/proc/meminfo", "r")))
375 while (fgets(line
, STRING_SIZE
-1, handle
)) {
376 if (sscanf (line
, "MemTotal: %s kB", string
)) {
377 memory
= atoi(string
) / 1024 ;
383 /* Partition, mkswp, mkfs.
384 * before partitioning, first determine the sizes of each
385 * partition. In order to do that we need to know the size of
388 /* Don't use mysystem here so we can redirect output */
389 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
390 system(commandstring
);
392 /* Calculate amount of disk space */
393 if ((handle
= fopen("/tmp/disksize", "r")))
395 fgets(line
, STRING_SIZE
-1, handle
);
396 if (sscanf (line
, "%s", string
)) {
397 maximum_free
= atoi(string
) / 1024;
402 fprintf(flog
, "maximum_free = %ld, memory = %ld",
403 maximum_free
, memory
);
405 swap_file
= calc_swapsize(memory
, maximum_free
);
407 if (maximum_free
< 512 + swap_file
) {
408 if (maximum_free
< 512) {
409 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
414 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
425 boot_partition
= 20; /* in MB */
426 current_free
= maximum_free
- boot_partition
- swap_file
;
428 root_partition
= 1024 ;
429 if (current_free
< 512) {
430 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
434 current_free
= current_free
- root_partition
;
436 root_partition
= root_partition
+ swap_file
;
439 system_partition
= current_free
;
441 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
442 boot_partition
, swap_file
, system_partition
, root_partition
);
444 handle
= fopen("/tmp/partitiontable", "w");
448 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
449 boot_partition
, swap_file
, root_partition
);
451 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
452 boot_partition
, root_partition
);
457 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
458 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
460 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
464 if (fstype
== REISER4
) {
465 mysystem("/sbin/modprobe reiser4");
466 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
467 } else if (fstype
== REISERFS
) {
468 mysystem("/sbin/modprobe reiserfs");
469 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
470 } else if (fstype
== EXT3
) {
471 mysystem("/sbin/modprobe ext3");
472 sprintf(mkfscommand
, "/bin/mke2fs -T ext2 -c");
475 snprintf(commandstring
, STRING_SIZE
, "/bin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
476 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
478 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
483 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
484 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
486 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
491 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
492 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
494 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
498 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
499 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
501 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
505 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
506 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
508 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
512 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
513 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
514 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
516 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
517 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
519 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
523 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
524 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
526 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
530 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
531 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
533 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
537 if (installtype
== URL_INSTALL
) {
538 snprintf(commandstring
, STRING_SIZE
,
539 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
542 if (installtype
== CDROM_INSTALL
) {
543 snprintf(commandstring
, STRING_SIZE
,
544 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
547 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
548 ctr
[TR_INSTALLING_FILES
]))
550 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
554 /* Save USB controller type to modules.conf */
555 write_usb_modules_conf();
557 /* Save language und local settings */
558 write_lang_configs(shortlangname
);
560 /* touch the modules.dep files */
561 snprintf(commandstring
, STRING_SIZE
,
562 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
564 mysystem(commandstring
);
565 snprintf(commandstring
, STRING_SIZE
,
566 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
568 mysystem(commandstring
);
571 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
573 /* mount proc filesystem */
574 mysystem("mkdir /harddisk/proc");
575 mysystem("/bin/mount --bind /proc /harddisk/proc");
576 mysystem("/bin/mount --bind /dev /harddisk/dev");
577 mysystem("/bin/mount --bind /sys /harddisk/sys");
579 /* Build cache lang file */
580 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
581 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
583 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
587 /* Update /etc/fstab */
588 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
590 if (fstype
== REISER4
) {
591 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
592 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
593 } else if (fstype
== REISERFS
) {
594 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
595 } else if (fstype
== EXT3
) {
596 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
599 /* Going to make our initrd... */
600 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -v -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 -v -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");
622 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
624 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
630 fprintf(flog
, "Install program ended.\n");
633 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
635 freekeyvalues(ethernetkv
);
637 if (allok
&& !allok_fastexit
)
640 fprintf(flog
, "Entering unattended setup\n");
641 if (unattended_setup(unattendedkv
)) {
642 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
643 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
645 errorbox("Unattended setup failed.");
655 // Copy our scanned nics to the disk and lock because scan doesn't work in chroot
656 system("touch /harddisk/var/ipfire/ethernet/scan_lock");
657 system("cp -f /tmp/scanned_nics /harddisk/var/ipfire/ethernet/scanned_nics");
658 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
659 printf("Unable to run setup.\n");
660 system("rm -f /harddisk/var/ipfire/ethernet/scan_lock");
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");