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 sd_mod");
159 mysystem("/sbin/modprobe sr_mod");
160 mysystem("/sbin/modprobe usb-storage");
161 mysystem("/sbin/modprobe usbhid");
163 mysystem("/sbin/modprobe iso9660"); // CDROM
164 mysystem("/sbin/modprobe ext2"); // Boot patition
165 mysystem("/sbin/modprobe vfat"); // USB key
167 /* German is the default */
168 for (choice
= 0; langnames
[choice
]; choice
++)
170 if (strcmp(langnames
[choice
], "Deutsch") == 0)
173 if (!langnames
[choice
])
177 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
178 langnames
, &choice
, "Ok", NULL
);
181 ctr
= langtrs
[choice
];
182 strcpy(shortlangname
, shortlangnames
[choice
]);
184 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
185 newtPushHelpLine(ctr
[TR_HELPLINE
]);
186 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
189 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
190 newtWinMessage(title
, ctr
[TR_OK
], message
);
192 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
193 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
194 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
195 ctr
[TR_CANCEL
], NULL
);
198 installtype
= CDROM_INSTALL
;
204 // Starting hardware detection
205 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
208 if (installtype
== CDROM_INSTALL
) {
209 switch (mysystem("/bin/mountsource.sh")) {
211 installtype
= CDROM_INSTALL
;
215 installtype
= DISK_INSTALL
;
218 errorbox(ctr
[TR_NO_CDROM
]);
222 /* read source drive letter */
223 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
224 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
227 fgets(sourcedrive
, 5, handle
);
228 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
232 /* Configure the network now! */
233 if (installtype
== URL_INSTALL
) {
234 /* Network driver and params. */
235 if (!(networkmenu(ethernetkv
))) {
236 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
240 /* Check for ipfire-<VERSION>.tbz2 */
241 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
242 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
250 fprintf(flog
, "Harddisk scan pass %i\n", i
);
252 switch (mysystem("/bin/mountdest.sh") % 255) {
253 case 0: // Found IDE disk
258 case 1: // Found SCSI disk
263 case 2: // Found RAID disk
268 case 10: // No harddisk found
270 errorbox(ctr
[TR_NO_HARDDISK
]);
273 // Do this if the kudzu-scan fails...
274 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
279 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
280 errorbox(ctr
[TR_NO_HARDDISK
]);
283 fgets(harddrive
, 11, handle
);
286 /* load unattended configuration */
288 fprintf(flog
, "unattended: Reading unattended.conf\n");
290 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
293 /* Make the hdparms struct and print the contents.
294 With USB-KEY install and SCSI disk, while installing, the disk
295 is named 'sdb,sdc,...' (following keys)
296 On reboot, it will become 'sda'
297 To avoid many test, all names are built in the struct.
299 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
300 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
301 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
302 /* Now the names after the machine is booted. Only scsi is affected
303 and we only install on the first scsi disk. */
305 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
306 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
307 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
310 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
312 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
316 yesnoharddisk
[0] = ctr
[TR_NO
];
317 yesnoharddisk
[1] = ctr
[TR_YES
];
318 yesnoharddisk
[2] = NULL
;
322 rc
= newtWinMenu(title
, message
,
323 50, 5, 5, 6, yesnoharddisk
,
325 ctr
[TR_CANCEL
], NULL
);
333 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
334 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
335 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
336 ctr
[TR_CANCEL
], NULL
);
339 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
344 /* Calculate amount of memory in machine */
345 if ((handle
= fopen("/proc/meminfo", "r")))
347 while (fgets(line
, STRING_SIZE
-1, handle
)) {
348 if (sscanf (line
, "MemTotal: %s kB", string
)) {
349 memory
= atoi(string
) / 1024 ;
355 /* Partition, mkswp, mkfs.
356 * before partitioning, first determine the sizes of each
357 * partition. In order to do that we need to know the size of
360 /* Don't use mysystem here so we can redirect output */
361 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
362 system(commandstring
);
364 /* Calculate amount of disk space */
365 if ((handle
= fopen("/tmp/disksize", "r"))) {
366 fgets(line
, STRING_SIZE
-1, handle
);
367 if (sscanf (line
, "%s", string
)) {
368 maximum_free
= atoi(string
) / 1024;
373 fprintf(flog
, "maximum_free = %ld, memory = %ld", maximum_free
, memory
);
375 swap_file
= calc_swapsize(memory
, maximum_free
);
377 if (maximum_free
< 512 + swap_file
) {
378 if (maximum_free
< 700) {
379 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
384 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
394 boot_partition
= 20; /* in MB */
395 current_free
= maximum_free
- boot_partition
- swap_file
;
397 if (current_free
< 700) {
398 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
402 root_partition
= calc_rootsize(current_free
, maximum_free
);
404 if (root_partition
== 0) {
405 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
408 current_free
= current_free
- root_partition
;
411 if (current_free
< 256) {
412 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
416 system_partition
= current_free
;
418 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
419 boot_partition
, swap_file
, system_partition
, root_partition
);
421 handle
= fopen("/tmp/partitiontable", "w");
425 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
426 boot_partition
, swap_file
, root_partition
);
428 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
429 boot_partition
, root_partition
);
434 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
435 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
437 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
441 if (fstype
== REISER4
) {
442 mysystem("/sbin/modprobe reiser4");
443 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
444 } else if (fstype
== REISERFS
) {
445 mysystem("/sbin/modprobe reiserfs");
446 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
447 } else if (fstype
== EXT3
) {
448 mysystem("/sbin/modprobe ext3");
449 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
452 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
453 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
455 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
460 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
461 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
463 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
468 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
469 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
471 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
475 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
476 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
478 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
482 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
483 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
485 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
489 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
490 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
491 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
493 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
494 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
496 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
500 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
501 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
503 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
507 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
508 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
510 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
514 if (installtype
== URL_INSTALL
) {
515 snprintf(commandstring
, STRING_SIZE
,
516 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
519 if (installtype
== CDROM_INSTALL
) {
520 snprintf(commandstring
, STRING_SIZE
,
521 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
524 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
525 ctr
[TR_INSTALLING_FILES
]))
527 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
531 /* Save language und local settings */
532 write_lang_configs(shortlangname
);
534 /* touch the modules.dep files */
535 snprintf(commandstring
, STRING_SIZE
,
536 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
538 mysystem(commandstring
);
539 snprintf(commandstring
, STRING_SIZE
,
540 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
542 mysystem(commandstring
);
545 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
547 /* mount proc filesystem */
548 mysystem("mkdir /harddisk/proc");
549 mysystem("/bin/mount --bind /proc /harddisk/proc");
550 mysystem("/bin/mount --bind /dev /harddisk/dev");
551 mysystem("/bin/mount --bind /sys /harddisk/sys");
553 /* Build cache lang file */
554 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
555 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
557 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
561 /* Update /etc/fstab */
562 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
564 if (fstype
== REISER4
) {
565 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
566 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
567 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
568 } else if (fstype
== REISERFS
) {
569 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
570 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
571 } else if (fstype
== EXT3
) {
572 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
573 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
575 errorbox(ctr
[TR_JOURNAL_ERROR
]);
576 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
579 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
580 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
582 errorbox(ctr
[TR_JOURNAL_ERROR
]);
583 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
586 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
588 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"ext3 ");
589 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
592 /* Going to make our initrd... */
593 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
594 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
595 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
596 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
598 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
599 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
600 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
602 /* restore permissions */
603 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
605 snprintf(commandstring
, STRING_SIZE
,
606 "/sbin/chroot /harddisk /boot/grub/grubbatch");
607 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
608 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
612 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
614 mysystem("umount /cdrom");
615 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
616 mysystem(commandstring
);
619 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
621 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
627 fprintf(flog
, "Install program ended.\n");
630 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
632 freekeyvalues(ethernetkv
);
634 if (allok
&& !allok_fastexit
)
637 fprintf(flog
, "Entering unattended setup\n");
638 if (unattended_setup(unattendedkv
)) {
639 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
640 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
642 errorbox("Unattended setup failed.");
652 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
653 printf("Unable to run setup.\n");
656 if (system("/bin/umount /harddisk/proc"))
657 printf("Unable to umount /harddisk/proc.\n");
667 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
672 system("/bin/umount /harddisk/proc");
673 system("/bin/umount /harddisk/dev");
674 system("/bin/umount /harddisk/sys");
676 system("/bin/umount /harddisk/var");
677 system("/bin/umount /harddisk/boot");
678 system("/bin/umount /harddisk");