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 7000
18 #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
36 char line
[STRING_SIZE
];
39 if ((fd
= fopen("/proc/cpuinfo", "r")) == NULL
) {
42 while (fgets(line
, STRING_SIZE
, fd
) != NULL
) {
43 if (strstr(line
, "processor") == line
) {
48 return (cpu_count
> 1);
51 long calc_swapsize(long memory
, long disk
) {
62 int main(int argc
, char *argv
[])
64 char *langnames
[] = { "Deutsch", "English", NULL
};
65 char *shortlangnames
[] = { "de", "en", NULL
};
66 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
68 char harddrive
[5], sourcedrive
[5]; /* Device holder. */
69 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
70 int cdmounted
= 0; /* Loop flag for inserting a cd. */
72 char commandstring
[STRING_SIZE
];
73 char *installtypes
[] = { "CDROM/USB", "HTTP/FTP", NULL
};
74 int installtype
= CDROM_INSTALL
;
79 char shortlangname
[10];
81 char title
[STRING_SIZE
];
84 struct keyvalue
*ethernetkv
= initkeyvalues();
85 FILE *handle
, *cmdfile
;
86 char line
[STRING_SIZE
];
87 char string
[STRING_SIZE
];
88 long maximum_free
= 0, current_free
;
90 long system_partition
, boot_partition
, root_partition
, swap_file
;
92 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
95 struct keyvalue
*unattendedkv
= initkeyvalues();
98 setlocale (LC_ALL
, "");
99 sethostname( SNAME
, 10);
101 memset(&hdparams
, 0, sizeof(struct devparams
));
102 memset(&cdromparams
, 0, sizeof(struct devparams
));
104 /* Log file/terminal stuff. */
107 if (!(flog
= fopen(argv
[1], "w+")))
115 fprintf(flog
, "Install program started.\n");
120 /* Do usb detection first for usb keyboard */
121 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
123 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
125 fgets(line
, STRING_SIZE
, cmdfile
);
126 if (strstr (line
, "noide") == NULL
) {
127 fprintf(flog
, "Initializing IDE controllers.\n");
130 fprintf(flog
, "Skipping IDE detection.\n");
132 if (strstr (line
, "nousb") == NULL
) {
133 fprintf(flog
, "Initializing USB controllers.\n");
136 fprintf(flog
, "Skipping USB detection.\n");
138 // check if we have to make an unattended install
139 if (strstr (line
, "unattended") != NULL
) {
142 // Loading the cdrom-filesystem
143 mysystem("/sbin/modprobe iso9660");
147 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
150 /* German is the default */
151 for (choice
= 0; langnames
[choice
]; choice
++)
153 if (strcmp(langnames
[choice
], "Deutsch") == 0)
156 if (!langnames
[choice
])
160 rc
= newtWinMenu("Language selection",
161 "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
162 langnames
, &choice
, "Ok", NULL
);
165 ctr
= langtrs
[choice
];
166 strcpy(shortlangname
, shortlangnames
[choice
]);
167 fprintf(flog
, "Selected language: %s\n", shortlangname
);
169 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
170 newtPushHelpLine(ctr
[TR_HELPLINE
]);
171 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
174 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
175 newtWinMessage(title
, ctr
[TR_OK
], message
);
177 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
178 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
179 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
180 ctr
[TR_CANCEL
], NULL
);
183 installtype
= CDROM_INSTALL
;
189 // Starting hardware detection
190 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
191 runcommandwithstatus("/bin/probenic.sh install", ctr
[TR_PROBING_HARDWARE
]);
194 if (installtype
== CDROM_INSTALL
) {
195 switch (mysystem("/bin/mountsource.sh")) {
197 installtype
= CDROM_INSTALL
;
201 installtype
= DISK_INSTALL
;
204 errorbox(ctr
[TR_NO_CDROM
]);
208 /* read source drive letter */
209 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
210 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
213 fgets(sourcedrive
, 5, handle
);
214 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
218 /* Configure the network now! */
219 if (installtype
== URL_INSTALL
) {
220 /* Network driver and params. */
221 if (!(networkmenu(ethernetkv
))) {
222 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
226 /* Check for ipfire-<VERSION>.tbz2 */
227 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
228 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
236 fprintf(flog
, "Harddisk scan pass %i\n", i
);
238 switch (mysystem("/bin/mountdest.sh") % 255) {
239 case 0: // Found IDE disk
243 case 1: // Found SCSI disk
247 case 10: // No harddisk found
249 errorbox(ctr
[TR_NO_HARDDISK
]);
252 // Do this if the kudzu-scan fails...
253 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
259 // Need to clean this up at some point
260 // scsi disk is sdb/sdc when sda/sdb is used for usb-key
261 // if scsi-disk is sdd or more, it is not discovered
262 // Support only 2 usb keys, none could be unplugged
263 if (checkusb("sdb") && try_scsi("sdc")) {
265 sprintf(harddrive, "sdc");
266 goto FOUND_DESTINATION;
268 if (checkusb("sda") && try_scsi("sdb")) {
270 sprintf(harddrive, "sdb");
271 goto FOUND_DESTINATION;
273 if (try_scsi("sda")) {
275 sprintf(harddrive, "sda");
276 goto FOUND_DESTINATION;
278 if (try_scsi("ida/c0d0")) {
280 sprintf(harddrive, "ida/c0d0");
281 goto FOUND_DESTINATION;
283 if (try_scsi("cciss/c0d0")) {
285 sprintf(harddrive, "cciss/c0d0");
286 goto FOUND_DESTINATION;
288 if (try_scsi("rd/c0d0")) {
290 sprintf(harddrive, "rd/c0d0");
291 goto FOUND_DESTINATION;
293 if (try_scsi("ataraid/d0")) {
295 sprintf(harddrive, "ataraid/d0");
296 goto FOUND_DESTINATION;
300 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
301 errorbox(ctr
[TR_NO_HARDDISK
]);
304 fgets(harddrive
, 5, handle
);
307 /* load unattended configuration */
309 fprintf(flog
, "unattended: Reading unattended.conf\n");
311 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
314 /* Make the hdparms struct and print the contents.
315 With USB-KEY install and SCSI disk, while installing, the disk
316 is named 'sdb,sdc,...' (following keys)
317 On reboot, it will become 'sda'
318 To avoid many test, all names are built in the struct.
320 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
321 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
322 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
323 /* Now the names after the machine is booted. Only scsi is affected
324 and we only install on the first scsi disk. */
326 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
327 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
328 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
331 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
333 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
338 yesnoharddisk
[0] = ctr
[TR_NO
];
339 yesnoharddisk
[1] = ctr
[TR_YES
];
340 yesnoharddisk
[2] = NULL
;
343 rc
= newtWinMenu(title
, message
,
344 50, 5, 5, 6, yesnoharddisk
,
346 ctr
[TR_CANCEL
], NULL
);
353 /* Calculate amount of memory in machine */
354 if ((handle
= fopen("/proc/meminfo", "r")))
356 while (fgets(line
, STRING_SIZE
-1, handle
)) {
357 if (sscanf (line
, "MemTotal: %s kB", string
)) {
358 memory
= atoi(string
) / 1024 ;
364 /* Partition, mkswp, mkfs.
365 * before partitioning, first determine the sizes of each
366 * partition. In order to do that we need to know the size of
369 /* Don't use mysystem here so we can redirect output */
370 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
371 system(commandstring
);
373 /* Calculate amount of disk space */
374 if ((handle
= fopen("/tmp/disksize", "r")))
376 fgets(line
, STRING_SIZE
-1, handle
);
377 if (sscanf (line
, "%s", string
)) {
378 maximum_free
= atoi(string
) / 1024;
383 fprintf(flog
, "maximum_free = %ld, memory = %ld",
384 maximum_free
, memory
);
386 swap_file
= calc_swapsize(memory
, maximum_free
);
388 if (maximum_free
< 512 + swap_file
) {
389 if (maximum_free
< 512) {
390 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
395 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
406 boot_partition
= 20; /* in MB */
407 current_free
= maximum_free
- boot_partition
- swap_file
;
409 root_partition
= 2048 ;
410 if (current_free
< 512) {
411 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
415 current_free
= current_free
- root_partition
;
417 root_partition
= root_partition
+ swap_file
;
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 mysystem("/sbin/udevstart");
447 snprintf(commandstring
, STRING_SIZE
, "/bin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
448 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
450 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
455 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
456 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
458 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
463 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkreiserfs -f %s3", hdparams
.devnode_part
);
464 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
466 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
470 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkreiserfs -f %s4", hdparams
.devnode_part
);
471 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
473 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
477 /* Mount harddisk. */
478 mysystem("/sbin/modprobe reiserfs"); // to be banished...
480 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
481 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
483 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
487 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
488 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
489 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
491 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
492 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
494 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
498 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
499 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
501 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
505 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
506 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
508 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
512 if (installtype
== URL_INSTALL
) {
513 snprintf(commandstring
, STRING_SIZE
,
514 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
517 if (installtype
== CDROM_INSTALL
) {
518 snprintf(commandstring
, STRING_SIZE
,
519 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
522 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
523 ctr
[TR_INSTALLING_FILES
]))
525 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
529 /* Save USB controller type to modules.conf */
530 write_usb_modules_conf();
532 /* Save language und local settings */
533 write_lang_configs(shortlangname
);
535 /* touch the modules.dep files */
536 snprintf(commandstring
, STRING_SIZE
,
537 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
539 mysystem(commandstring
);
540 snprintf(commandstring
, STRING_SIZE
,
541 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
543 mysystem(commandstring
);
546 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
548 /* mount proc filesystem */
549 mysystem("mkdir /harddisk/proc");
550 mysystem("/bin/mount --bind /proc /harddisk/proc");
551 mysystem("/bin/mount --bind /dev /harddisk/dev");
552 mysystem("/bin/mount --bind /sys /harddisk/sys");
554 /* Build cache lang file */
555 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
556 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
558 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
562 /* Update /etc/fstab */
563 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
565 /* Going to make our initrd... */
566 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -v -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
567 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
568 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -v -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
569 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
571 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
572 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
573 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
575 /* restore permissions */
576 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
578 snprintf(commandstring
, STRING_SIZE
,
579 "/sbin/chroot /harddisk /boot/grub/grubbatch");
580 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
581 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
585 /* Install bootsplash */
586 // mysystem("/bin/installbootsplash.sh"); We cannot use this at the moment, it conflicts with our initrds...
588 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
591 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
593 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
599 fprintf(flog
, "Install program ended.\n");
602 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
604 freekeyvalues(ethernetkv
);
606 if (allok
&& !allok_fastexit
)
609 fprintf(flog
, "Entering unattended setup\n");
610 if (unattended_setup(unattendedkv
)) {
611 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
612 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
614 errorbox("Unattended setup failed.");
624 // Copy our scanned nics to the disk and lock because scan doesn't work in chroot
625 system("touch /harddisk/var/ipfire/ethernet/scan_lock");
626 system("cp -f /tmp/scanned_nics /harddisk/var/ipfire/ethernet/scanned_nics");
627 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
628 printf("Unable to run setup.\n");
629 system("rm -f /harddisk/var/ipfire/ethernet/scan_lock");
632 if (system("/bin/umount /harddisk/proc"))
633 printf("Unable to umount /harddisk/proc.\n");
643 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
648 system("/bin/umount /harddisk/proc");
649 system("/bin/umount /harddisk/dev");
650 system("/bin/umount /harddisk/sys");
652 system("/bin/umount /harddisk/var");
653 system("/bin/umount /harddisk/boot");
654 system("/bin/umount /harddisk");