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
);
146 if (strstr (line
, "noide") == NULL
) {
147 fprintf(flog
, "Initializing IDE controllers.\n");
150 fprintf(flog
, "Skipping IDE detection.\n");
152 if (strstr (line
, "nousb") == NULL
) {
153 fprintf(flog
, "Initializing USB controllers.\n");
156 fprintf(flog
, "Skipping USB detection.\n");
158 // check if we have to make an unattended install
159 if (strstr (line
, "unattended") != NULL
) {
162 // Loading the cdrom-filesystem
163 mysystem("/sbin/modprobe iso9660");
167 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
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
]);
186 fprintf(flog
, "Selected language: %s\n", shortlangname
);
188 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
189 newtPushHelpLine(ctr
[TR_HELPLINE
]);
190 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
193 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
194 newtWinMessage(title
, ctr
[TR_OK
], message
);
196 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
197 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
198 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
199 ctr
[TR_CANCEL
], NULL
);
202 installtype
= CDROM_INSTALL
;
208 // Starting hardware detection
209 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
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
);
321 yesnoharddisk
[0] = ctr
[TR_NO
];
322 yesnoharddisk
[1] = ctr
[TR_YES
];
323 yesnoharddisk
[2] = NULL
;
326 rc
= newtWinMenu(title
, message
,
327 50, 5, 5, 6, yesnoharddisk
,
329 ctr
[TR_CANCEL
], NULL
);
337 sprintf(message
, "(TR) Bitte waehlen Sie ihr Dateisystem aus:");
338 rc
= newtWinMenu("(TR) Dateisystemauswahl", 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
< 768 + swap_file
) {
382 if (maximum_free
< 768) {
383 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
388 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
399 boot_partition
= 20; /* in MB */
400 current_free
= maximum_free
- boot_partition
- swap_file
;
402 if (current_free
< 768) {
403 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
407 root_partition
= calc_rootsize(current_free
, maximum_free
);
409 if (root_partition
== 0) {
410 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
413 current_free
= current_free
- root_partition
;
416 if (current_free
< 256) {
417 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
421 system_partition
= current_free
;
423 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
424 boot_partition
, swap_file
, system_partition
, root_partition
);
426 handle
= fopen("/tmp/partitiontable", "w");
430 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
431 boot_partition
, swap_file
, root_partition
);
433 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
434 boot_partition
, root_partition
);
439 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
440 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
442 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
446 if (fstype
== REISER4
) {
447 mysystem("/sbin/modprobe reiser4");
448 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
449 } else if (fstype
== REISERFS
) {
450 mysystem("/sbin/modprobe reiserfs");
451 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
452 } else if (fstype
== EXT3
) {
453 mysystem("/sbin/modprobe ext3");
454 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
457 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
458 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
460 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
465 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
466 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
468 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
473 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
474 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
476 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
480 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
481 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
483 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
487 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
488 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
490 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
494 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
495 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
496 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
498 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
499 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
501 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
505 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
506 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
508 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
512 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
513 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
515 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
519 if (installtype
== URL_INSTALL
) {
520 snprintf(commandstring
, STRING_SIZE
,
521 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
524 if (installtype
== CDROM_INSTALL
) {
525 snprintf(commandstring
, STRING_SIZE
,
526 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
529 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
530 ctr
[TR_INSTALLING_FILES
]))
532 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
536 /* Save USB controller type to modules.conf */
537 write_usb_modules_conf();
539 /* Save language und local settings */
540 write_lang_configs(shortlangname
);
542 /* touch the modules.dep files */
543 snprintf(commandstring
, STRING_SIZE
,
544 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
546 mysystem(commandstring
);
547 snprintf(commandstring
, STRING_SIZE
,
548 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
550 mysystem(commandstring
);
553 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
555 /* mount proc filesystem */
556 mysystem("mkdir /harddisk/proc");
557 mysystem("/bin/mount --bind /proc /harddisk/proc");
558 mysystem("/bin/mount --bind /dev /harddisk/dev");
559 mysystem("/bin/mount --bind /sys /harddisk/sys");
561 /* Build cache lang file */
562 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
563 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
565 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
569 /* Update /etc/fstab */
570 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
572 if (fstype
== REISER4
) {
573 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
574 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
575 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
576 } else if (fstype
== REISERFS
) {
577 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
578 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
579 } else if (fstype
== EXT3
) {
580 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
581 if (runcommandwithstatus(commandstring
, "(TR) Creating journal for ext3..."))
583 errorbox("(TR) Unable to create journal. Going back to ext2.");
584 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
587 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
588 if (runcommandwithstatus(commandstring
, "(TR) Creating journal for ext3..."))
590 errorbox("(TR) Unable to create journal. Going back to ext2.");
591 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
594 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
596 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"ext3 ");
597 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
600 /* Going to make our initrd... */
601 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
602 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
603 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
604 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
606 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
607 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
608 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
610 /* restore permissions */
611 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
613 snprintf(commandstring
, STRING_SIZE
,
614 "/sbin/chroot /harddisk /boot/grub/grubbatch");
615 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
616 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
620 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
622 mysystem("umount /cdrom");
623 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
624 mysystem(commandstring
);
627 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
629 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
635 fprintf(flog
, "Install program ended.\n");
638 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
640 freekeyvalues(ethernetkv
);
642 if (allok
&& !allok_fastexit
)
645 fprintf(flog
, "Entering unattended setup\n");
646 if (unattended_setup(unattendedkv
)) {
647 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
648 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
650 errorbox("Unattended setup failed.");
660 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
661 printf("Unable to run setup.\n");
664 if (system("/bin/umount /harddisk/proc"))
665 printf("Unable to umount /harddisk/proc.\n");
675 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
680 system("/bin/umount /harddisk/proc");
681 system("/bin/umount /harddisk/dev");
682 system("/bin/umount /harddisk/sys");
684 system("/bin/umount /harddisk/var");
685 system("/bin/umount /harddisk/boot");
686 system("/bin/umount /harddisk");