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 and ext2
163 mysystem("/sbin/modprobe iso9660");
164 mysystem("/sbin/modprobe ext2");
166 // Loading the via_rhine driver because it isn't detected correctly (sometimes)
167 mysystem("/sbin/modprobe via-rhine");
171 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
174 /* German is the default */
175 for (choice
= 0; langnames
[choice
]; choice
++)
177 if (strcmp(langnames
[choice
], "Deutsch") == 0)
180 if (!langnames
[choice
])
184 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
185 langnames
, &choice
, "Ok", NULL
);
188 ctr
= langtrs
[choice
];
189 strcpy(shortlangname
, shortlangnames
[choice
]);
190 fprintf(flog
, "Selected language: %s\n", shortlangname
);
192 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
193 newtPushHelpLine(ctr
[TR_HELPLINE
]);
194 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
197 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
198 newtWinMessage(title
, ctr
[TR_OK
], message
);
200 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
201 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
202 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
203 ctr
[TR_CANCEL
], NULL
);
206 installtype
= CDROM_INSTALL
;
212 // Starting hardware detection
213 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
216 if (installtype
== CDROM_INSTALL
) {
217 switch (mysystem("/bin/mountsource.sh")) {
219 installtype
= CDROM_INSTALL
;
223 installtype
= DISK_INSTALL
;
226 errorbox(ctr
[TR_NO_CDROM
]);
230 /* read source drive letter */
231 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
232 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
235 fgets(sourcedrive
, 5, handle
);
236 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
240 /* Configure the network now! */
241 if (installtype
== URL_INSTALL
) {
242 /* Network driver and params. */
243 if (!(networkmenu(ethernetkv
))) {
244 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
248 /* Check for ipfire-<VERSION>.tbz2 */
249 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
250 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
258 fprintf(flog
, "Harddisk scan pass %i\n", i
);
260 switch (mysystem("/bin/mountdest.sh") % 255) {
261 case 0: // Found IDE disk
266 case 1: // Found SCSI disk
271 case 2: // Found RAID disk
276 case 10: // No harddisk found
278 errorbox(ctr
[TR_NO_HARDDISK
]);
281 // Do this if the kudzu-scan fails...
282 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
287 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
288 errorbox(ctr
[TR_NO_HARDDISK
]);
291 fgets(harddrive
, 11, handle
);
294 /* load unattended configuration */
296 fprintf(flog
, "unattended: Reading unattended.conf\n");
298 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
301 /* Make the hdparms struct and print the contents.
302 With USB-KEY install and SCSI disk, while installing, the disk
303 is named 'sdb,sdc,...' (following keys)
304 On reboot, it will become 'sda'
305 To avoid many test, all names are built in the struct.
307 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
308 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
309 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
310 /* Now the names after the machine is booted. Only scsi is affected
311 and we only install on the first scsi disk. */
313 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
314 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
315 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
318 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
320 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
325 yesnoharddisk
[0] = ctr
[TR_NO
];
326 yesnoharddisk
[1] = ctr
[TR_YES
];
327 yesnoharddisk
[2] = NULL
;
330 rc
= newtWinMenu(title
, message
,
331 50, 5, 5, 6, yesnoharddisk
,
333 ctr
[TR_CANCEL
], NULL
);
341 sprintf(message
, "(TR) Bitte waehlen Sie ihr Dateisystem aus:");
342 rc
= newtWinMenu("(TR) Dateisystemauswahl", message
,
343 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
344 ctr
[TR_CANCEL
], NULL
);
347 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
352 /* Calculate amount of memory in machine */
353 if ((handle
= fopen("/proc/meminfo", "r")))
355 while (fgets(line
, STRING_SIZE
-1, handle
)) {
356 if (sscanf (line
, "MemTotal: %s kB", string
)) {
357 memory
= atoi(string
) / 1024 ;
363 /* Partition, mkswp, mkfs.
364 * before partitioning, first determine the sizes of each
365 * partition. In order to do that we need to know the size of
368 /* Don't use mysystem here so we can redirect output */
369 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
370 system(commandstring
);
372 /* Calculate amount of disk space */
373 if ((handle
= fopen("/tmp/disksize", "r"))) {
374 fgets(line
, STRING_SIZE
-1, handle
);
375 if (sscanf (line
, "%s", string
)) {
376 maximum_free
= atoi(string
) / 1024;
381 fprintf(flog
, "maximum_free = %ld, memory = %ld", maximum_free
, memory
);
383 swap_file
= calc_swapsize(memory
, maximum_free
);
385 if (maximum_free
< 512 + swap_file
) {
386 if (maximum_free
< 700) {
387 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
392 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
402 boot_partition
= 20; /* in MB */
403 current_free
= maximum_free
- boot_partition
- swap_file
;
405 if (current_free
< 700) {
406 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
410 root_partition
= calc_rootsize(current_free
, maximum_free
);
412 if (root_partition
== 0) {
413 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
416 current_free
= current_free
- root_partition
;
419 if (current_free
< 256) {
420 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
424 system_partition
= current_free
;
426 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
427 boot_partition
, swap_file
, system_partition
, root_partition
);
429 handle
= fopen("/tmp/partitiontable", "w");
433 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
434 boot_partition
, swap_file
, root_partition
);
436 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
437 boot_partition
, root_partition
);
442 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
443 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
445 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
449 if (fstype
== REISER4
) {
450 mysystem("/sbin/modprobe reiser4");
451 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
452 } else if (fstype
== REISERFS
) {
453 mysystem("/sbin/modprobe reiserfs");
454 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
455 } else if (fstype
== EXT3
) {
456 mysystem("/sbin/modprobe ext3");
457 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
460 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
461 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
463 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
468 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
469 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
471 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
476 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
477 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
479 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
483 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
484 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
486 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
490 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
491 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
493 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
497 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
498 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
499 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
501 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
502 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
504 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
508 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
509 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
511 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
515 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
516 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
518 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
522 if (installtype
== URL_INSTALL
) {
523 snprintf(commandstring
, STRING_SIZE
,
524 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
527 if (installtype
== CDROM_INSTALL
) {
528 snprintf(commandstring
, STRING_SIZE
,
529 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
532 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
533 ctr
[TR_INSTALLING_FILES
]))
535 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
539 /* Save USB controller type to modules.conf */
540 write_usb_modules_conf();
542 /* Save language und local settings */
543 write_lang_configs(shortlangname
);
545 /* touch the modules.dep files */
546 snprintf(commandstring
, STRING_SIZE
,
547 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
549 mysystem(commandstring
);
550 snprintf(commandstring
, STRING_SIZE
,
551 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
553 mysystem(commandstring
);
556 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
558 /* mount proc filesystem */
559 mysystem("mkdir /harddisk/proc");
560 mysystem("/bin/mount --bind /proc /harddisk/proc");
561 mysystem("/bin/mount --bind /dev /harddisk/dev");
562 mysystem("/bin/mount --bind /sys /harddisk/sys");
564 /* Build cache lang file */
565 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
566 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
568 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
572 /* Update /etc/fstab */
573 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
575 if (fstype
== REISER4
) {
576 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
577 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
578 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
579 } else if (fstype
== REISERFS
) {
580 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
581 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
582 } else if (fstype
== EXT3
) {
583 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
584 if (runcommandwithstatus(commandstring
, "(TR) Creating journal for ext3..."))
586 errorbox("(TR) Unable to create journal. Going back to ext2.");
587 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
590 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
591 if (runcommandwithstatus(commandstring
, "(TR) Creating journal for ext3..."))
593 errorbox("(TR) Unable to create journal. Going back to ext2.");
594 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
597 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
599 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"ext3 ");
600 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
603 /* Going to make our initrd... */
604 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
605 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
606 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
607 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
609 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
610 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
611 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
613 /* restore permissions */
614 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
616 snprintf(commandstring
, STRING_SIZE
,
617 "/sbin/chroot /harddisk /boot/grub/grubbatch");
618 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
619 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
623 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
625 mysystem("umount /cdrom");
626 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
627 mysystem(commandstring
);
630 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
632 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
638 fprintf(flog
, "Install program ended.\n");
641 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
643 freekeyvalues(ethernetkv
);
645 if (allok
&& !allok_fastexit
)
648 fprintf(flog
, "Entering unattended setup\n");
649 if (unattended_setup(unattendedkv
)) {
650 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
651 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
653 errorbox("Unattended setup failed.");
663 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
664 printf("Unable to run setup.\n");
667 if (system("/bin/umount /harddisk/proc"))
668 printf("Unable to umount /harddisk/proc.\n");
678 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
683 system("/bin/umount /harddisk/proc");
684 system("/bin/umount /harddisk/dev");
685 system("/bin/umount /harddisk/sys");
687 system("/bin/umount /harddisk/var");
688 system("/bin/umount /harddisk/boot");
689 system("/bin/umount /harddisk");