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
);
147 // check if we have to make an unattended install
148 if (strstr (line
, "unattended") != NULL
) {
150 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
154 mysystem("/sbin/modprobe ide-generic");
155 mysystem("/sbin/modprobe generic");
156 mysystem("/sbin/modprobe ide-cd");
157 mysystem("/sbin/modprobe ide-disk");
158 mysystem("/sbin/modprobe uhci_hcd");
159 mysystem("/sbin/modprobe ohci_hcd");
160 mysystem("/sbin/modprobe ehci_hcd");
161 mysystem("/sbin/modprobe ohci1394");
162 mysystem("/sbin/modprobe sd_mod");
163 mysystem("/sbin/modprobe sr_mod");
164 mysystem("/sbin/modprobe usb-storage");
165 mysystem("/sbin/modprobe usbhid");
167 mysystem("/sbin/modprobe iso9660"); // CDROM
168 mysystem("/sbin/modprobe ext2"); // Boot patition
169 mysystem("/sbin/modprobe vfat"); // USB key
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", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
182 langnames
, &choice
, "Ok", NULL
);
185 ctr
= langtrs
[choice
];
186 strcpy(shortlangname
, shortlangnames
[choice
]);
188 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
189 newtPushHelpLine(ctr
[TR_HELPLINE
]);
190 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
192 // Starting hardware detection
193 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
196 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
197 newtWinMessage(title
, ctr
[TR_OK
], message
);
199 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
200 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
201 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
202 ctr
[TR_CANCEL
], NULL
);
205 installtype
= CDROM_INSTALL
;
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
);
320 yesnoharddisk
[0] = ctr
[TR_NO
];
321 yesnoharddisk
[1] = ctr
[TR_YES
];
322 yesnoharddisk
[2] = NULL
;
326 rc
= newtWinMenu(title
, message
,
327 50, 5, 5, 6, yesnoharddisk
,
329 ctr
[TR_CANCEL
], NULL
);
337 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
338 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], 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 language und local settings */
536 write_lang_configs(shortlangname
);
538 /* touch the modules.dep files */
539 snprintf(commandstring
, STRING_SIZE
,
540 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
542 mysystem(commandstring
);
543 snprintf(commandstring
, STRING_SIZE
,
544 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
546 mysystem(commandstring
);
549 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
551 /* mount proc filesystem */
552 mysystem("mkdir /harddisk/proc");
553 mysystem("/bin/mount --bind /proc /harddisk/proc");
554 mysystem("/bin/mount --bind /dev /harddisk/dev");
555 mysystem("/bin/mount --bind /sys /harddisk/sys");
557 /* Build cache lang file */
558 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
559 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
561 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
565 /* Update /etc/fstab */
566 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
568 if (fstype
== REISER4
) {
569 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
570 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
571 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
572 } else if (fstype
== REISERFS
) {
573 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
574 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
575 } else if (fstype
== EXT3
) {
576 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
577 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
579 errorbox(ctr
[TR_JOURNAL_ERROR
]);
580 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
583 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
584 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
586 errorbox(ctr
[TR_JOURNAL_ERROR
]);
587 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
590 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
592 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"ext3 ");
593 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
596 /* Going to make our initrd... */
597 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
598 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
599 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
600 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
602 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
603 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
604 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
606 /* restore permissions */
607 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
609 snprintf(commandstring
, STRING_SIZE
,
610 "/sbin/chroot /harddisk /boot/grub/grubbatch");
611 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
612 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
616 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
618 mysystem("umount /cdrom");
619 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
620 mysystem(commandstring
);
623 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
625 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
631 fprintf(flog
, "Install program ended.\n");
634 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
636 freekeyvalues(ethernetkv
);
638 if (allok
&& !allok_fastexit
)
641 fprintf(flog
, "Entering unattended setup\n");
642 if (unattended_setup(unattendedkv
)) {
643 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
644 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
646 errorbox("Unattended setup failed.");
656 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
657 printf("Unable to run setup.\n");
660 if (system("/bin/umount /harddisk/proc"))
661 printf("Unable to umount /harddisk/proc.\n");
671 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
676 system("/bin/umount /harddisk/proc");
677 system("/bin/umount /harddisk/dev");
678 system("/bin/umount /harddisk/sys");
680 system("/bin/umount /harddisk/var");
681 system("/bin/umount /harddisk/boot");
682 system("/bin/umount /harddisk");