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
) {
64 long calc_rootsize(long free
, long max
) {
77 int main(int argc
, char *argv
[])
79 char *langnames
[] = { "Deutsch", "English", NULL
};
80 char *shortlangnames
[] = { "de", "en", NULL
};
81 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
83 char harddrive
[11], sourcedrive
[5]; /* Device holder. */
84 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
85 int cdmounted
= 0; /* Loop flag for inserting a cd. */
87 char commandstring
[STRING_SIZE
];
88 char *installtypes
[] = { "CDROM/USB", "HTTP/FTP", NULL
};
89 int installtype
= CDROM_INSTALL
;
90 char mkfscommand
[STRING_SIZE
];
91 char *fstypes
[] = { "Reiser4", "ReiserFS", "ext3", NULL
};
97 char shortlangname
[10];
99 char title
[STRING_SIZE
];
101 int allok_fastexit
=0;
103 struct keyvalue
*ethernetkv
= initkeyvalues();
104 FILE *handle
, *cmdfile
;
105 char line
[STRING_SIZE
];
106 char string
[STRING_SIZE
];
107 long maximum_free
= 0, current_free
;
109 long system_partition
, boot_partition
, root_partition
, swap_file
;
111 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
114 struct keyvalue
*unattendedkv
= initkeyvalues();
117 setlocale (LC_ALL
, "");
118 sethostname( SNAME
, 10);
120 memset(&hdparams
, 0, sizeof(struct devparams
));
121 memset(&cdromparams
, 0, sizeof(struct devparams
));
123 /* Log file/terminal stuff. */
126 if (!(flog
= fopen(argv
[1], "w+")))
134 fprintf(flog
, "Install program started.\n");
139 /* Do usb detection first for usb keyboard */
140 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
142 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
144 fgets(line
, STRING_SIZE
, cmdfile
);
146 // check if we have to make an unattended install
147 if (strstr (line
, "unattended") != NULL
) {
149 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
153 mysystem("/sbin/modprobe ide-generic");
154 mysystem("/sbin/modprobe generic");
155 mysystem("/sbin/modprobe ide-cd");
156 mysystem("/sbin/modprobe ide-disk");
157 mysystem("/sbin/modprobe uhci-hcd");
158 mysystem("/sbin/modprobe ohci-hcd");
159 mysystem("/sbin/modprobe ehci-hcd");
160 mysystem("/sbin/modprobe ohci1394");
161 mysystem("/sbin/modprobe sd_mod");
162 mysystem("/sbin/modprobe sr_mod");
163 mysystem("/sbin/modprobe usb-storage");
164 mysystem("/sbin/modprobe usbhid");
166 mysystem("/sbin/modprobe iso9660"); // CDROM
167 mysystem("/sbin/modprobe ext2"); // Boot patition
168 mysystem("/sbin/modprobe vfat"); // USB key
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
]);
187 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
188 newtPushHelpLine(ctr
[TR_HELPLINE
]);
189 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
191 // Starting hardware detection
192 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
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
;
211 if (installtype
== CDROM_INSTALL
) {
212 switch (mysystem("/bin/mountsource.sh")) {
214 installtype
= CDROM_INSTALL
;
218 installtype
= DISK_INSTALL
;
221 errorbox(ctr
[TR_NO_CDROM
]);
225 /* read source drive letter */
226 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
227 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
230 fgets(sourcedrive
, 5, handle
);
231 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
235 /* Configure the network now! */
236 if (installtype
== URL_INSTALL
) {
237 /* Network driver and params. */
238 if (!(networkmenu(ethernetkv
))) {
239 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
243 /* Check for ipfire-<VERSION>.tbz2 */
244 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
245 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
253 fprintf(flog
, "Harddisk scan pass %i\n", i
);
255 switch (mysystem("/bin/mountdest.sh") % 255) {
256 case 0: // Found IDE disk
261 case 1: // Found SCSI disk
266 case 2: // Found RAID disk
271 case 10: // No harddisk found
273 errorbox(ctr
[TR_NO_HARDDISK
]);
276 // Do this if the kudzu-scan fails...
277 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
282 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
283 errorbox(ctr
[TR_NO_HARDDISK
]);
286 fgets(harddrive
, 11, handle
);
289 /* load unattended configuration */
291 fprintf(flog
, "unattended: Reading unattended.conf\n");
293 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
296 /* Make the hdparms struct and print the contents.
297 With USB-KEY install and SCSI disk, while installing, the disk
298 is named 'sdb,sdc,...' (following keys)
299 On reboot, it will become 'sda'
300 To avoid many test, all names are built in the struct.
302 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
303 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
304 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
305 /* Now the names after the machine is booted. Only scsi is affected
306 and we only install on the first scsi disk. */
308 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
309 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
310 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
313 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
315 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
319 yesnoharddisk
[0] = ctr
[TR_NO
];
320 yesnoharddisk
[1] = ctr
[TR_YES
];
321 yesnoharddisk
[2] = NULL
;
325 rc
= newtWinMenu(title
, message
,
326 50, 5, 5, 6, yesnoharddisk
,
328 ctr
[TR_CANCEL
], NULL
);
336 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
337 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
338 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
339 ctr
[TR_CANCEL
], NULL
);
342 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
347 /* Calculate amount of memory in machine */
348 if ((handle
= fopen("/proc/meminfo", "r")))
350 while (fgets(line
, STRING_SIZE
-1, handle
)) {
351 if (sscanf (line
, "MemTotal: %s kB", string
)) {
352 memory
= atoi(string
) / 1024 ;
358 /* Partition, mkswp, mkfs.
359 * before partitioning, first determine the sizes of each
360 * partition. In order to do that we need to know the size of
363 /* Don't use mysystem here so we can redirect output */
364 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
365 system(commandstring
);
367 /* Calculate amount of disk space */
368 if ((handle
= fopen("/tmp/disksize", "r"))) {
369 fgets(line
, STRING_SIZE
-1, handle
);
370 if (sscanf (line
, "%s", string
)) {
371 maximum_free
= atoi(string
) / 1024;
376 fprintf(flog
, "maximum_free = %ld, memory = %ld", maximum_free
, memory
);
378 swap_file
= calc_swapsize(memory
, maximum_free
);
380 if (maximum_free
< 512 + swap_file
) {
381 if (maximum_free
< 700) {
382 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
387 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
397 boot_partition
= 20; /* in MB */
398 current_free
= maximum_free
- boot_partition
- swap_file
;
400 if (current_free
< 700) {
401 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
405 root_partition
= calc_rootsize(current_free
, maximum_free
);
407 if (root_partition
== 0) {
408 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
411 current_free
= current_free
- root_partition
;
414 if (current_free
< 256) {
415 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
419 system_partition
= current_free
;
421 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
422 boot_partition
, swap_file
, system_partition
, root_partition
);
424 handle
= fopen("/tmp/partitiontable", "w");
428 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
429 boot_partition
, swap_file
, root_partition
);
431 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
432 boot_partition
, root_partition
);
437 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
438 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
440 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
444 if (fstype
== REISER4
) {
445 mysystem("/sbin/modprobe reiser4");
446 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
447 } else if (fstype
== REISERFS
) {
448 mysystem("/sbin/modprobe reiserfs");
449 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
450 } else if (fstype
== EXT3
) {
451 mysystem("/sbin/modprobe ext3");
452 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
455 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
456 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
458 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
463 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
464 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
466 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
471 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
472 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
474 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
478 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
479 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
481 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
485 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
486 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
488 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
492 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
493 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
494 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
496 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
497 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
499 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
503 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
504 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
506 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
510 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
511 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
513 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
517 if (installtype
== URL_INSTALL
) {
518 snprintf(commandstring
, STRING_SIZE
,
519 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
522 if (installtype
== CDROM_INSTALL
) {
523 snprintf(commandstring
, STRING_SIZE
,
524 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
527 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
528 ctr
[TR_INSTALLING_FILES
]))
530 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
534 /* Save language und local settings */
535 write_lang_configs(shortlangname
);
537 /* touch the modules.dep files */
538 snprintf(commandstring
, STRING_SIZE
,
539 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
541 mysystem(commandstring
);
542 snprintf(commandstring
, STRING_SIZE
,
543 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
545 mysystem(commandstring
);
548 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
550 /* mount proc filesystem */
551 mysystem("mkdir /harddisk/proc");
552 mysystem("/bin/mount --bind /proc /harddisk/proc");
553 mysystem("/bin/mount --bind /dev /harddisk/dev");
554 mysystem("/bin/mount --bind /sys /harddisk/sys");
556 /* Build cache lang file */
557 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
558 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
560 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
564 /* Update /etc/fstab */
565 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
567 if (fstype
== REISER4
) {
568 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
569 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
570 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
571 } else if (fstype
== REISERFS
) {
572 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
573 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
574 } else if (fstype
== EXT3
) {
575 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
576 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
578 errorbox(ctr
[TR_JOURNAL_ERROR
]);
579 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
582 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
583 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
585 errorbox(ctr
[TR_JOURNAL_ERROR
]);
586 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
589 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
591 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"ext3 ");
592 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
595 /* Going to make our initrd... */
596 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
597 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
598 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
599 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
601 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
602 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
603 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
605 /* restore permissions */
606 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
608 snprintf(commandstring
, STRING_SIZE
,
609 "/sbin/chroot /harddisk /boot/grub/grubbatch");
610 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
611 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
615 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
617 mysystem("umount /cdrom");
618 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
619 mysystem(commandstring
);
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 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
656 printf("Unable to run setup.\n");
659 if (system("/bin/umount /harddisk/proc"))
660 printf("Unable to umount /harddisk/proc.\n");
670 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
675 system("/bin/umount /harddisk/proc");
676 system("/bin/umount /harddisk/dev");
677 system("/bin/umount /harddisk/sys");
679 system("/bin/umount /harddisk/var");
680 system("/bin/umount /harddisk/boot");
681 system("/bin/umount /harddisk");