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
) {
58 else if (memory
> 1024) {
66 long calc_rootsize(long free
, long max
) {
73 else if (root
> 2048) {
81 int main(int argc
, char *argv
[])
83 char *langnames
[] = { "Deutsch", "English", NULL
};
84 char *shortlangnames
[] = { "de", "en", NULL
};
85 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
87 char harddrive
[11], sourcedrive
[5]; /* Device holder. */
88 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
89 int cdmounted
= 0; /* Loop flag for inserting a cd. */
91 char commandstring
[STRING_SIZE
];
92 char *installtypes
[] = { "CDROM/USB", "HTTP/FTP", NULL
};
93 int installtype
= CDROM_INSTALL
;
94 char mkfscommand
[STRING_SIZE
];
95 char *fstypes
[] = { "Reiser4", "ReiserFS", "ext3", NULL
};
101 char shortlangname
[10];
103 char title
[STRING_SIZE
];
105 int allok_fastexit
=0;
107 struct keyvalue
*ethernetkv
= initkeyvalues();
108 FILE *handle
, *cmdfile
;
109 char line
[STRING_SIZE
];
110 char string
[STRING_SIZE
];
111 long maximum_free
= 0, current_free
;
113 long system_partition
, boot_partition
, root_partition
, swap_file
;
115 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
118 struct keyvalue
*unattendedkv
= initkeyvalues();
121 setlocale (LC_ALL
, "");
122 sethostname( SNAME
, 10);
124 memset(&hdparams
, 0, sizeof(struct devparams
));
125 memset(&cdromparams
, 0, sizeof(struct devparams
));
127 /* Log file/terminal stuff. */
130 if (!(flog
= fopen(argv
[1], "w+")))
138 fprintf(flog
, "Install program started.\n");
143 /* Do usb detection first for usb keyboard */
144 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
146 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
148 fgets(line
, STRING_SIZE
, cmdfile
);
150 // check if we have to make an unattended install
151 if (strstr (line
, "unattended") != NULL
) {
153 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
157 mysystem("/sbin/modprobe ide-generic");
158 mysystem("/sbin/modprobe generic");
159 mysystem("/sbin/modprobe ide-cd");
160 mysystem("/sbin/modprobe ide-disk");
161 mysystem("/sbin/modprobe uhci-hcd");
162 mysystem("/sbin/modprobe ohci-hcd");
163 mysystem("/sbin/modprobe ehci-hcd");
164 mysystem("/sbin/modprobe ohci1394");
165 mysystem("/sbin/modprobe sd_mod");
166 mysystem("/sbin/modprobe sr_mod");
167 mysystem("/sbin/modprobe usb-storage");
168 mysystem("/sbin/modprobe usbhid");
170 mysystem("/sbin/modprobe iso9660"); // CDROM
171 mysystem("/sbin/modprobe ext2"); // Boot patition
172 mysystem("/sbin/modprobe vfat"); // USB key
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
]);
191 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
192 newtPushHelpLine(ctr
[TR_HELPLINE
]);
193 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
195 // Starting hardware detection
196 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
199 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
200 newtWinMessage(title
, ctr
[TR_OK
], message
);
202 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
203 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
204 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
205 ctr
[TR_CANCEL
], NULL
);
208 installtype
= CDROM_INSTALL
;
215 if (installtype
== CDROM_INSTALL
) {
216 switch (mysystem("/bin/mountsource.sh")) {
218 installtype
= CDROM_INSTALL
;
222 installtype
= DISK_INSTALL
;
225 errorbox(ctr
[TR_NO_CDROM
]);
229 /* read source drive letter */
230 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
231 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
234 fgets(sourcedrive
, 5, handle
);
235 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
239 /* Configure the network now! */
240 if (installtype
== URL_INSTALL
) {
241 /* Network driver and params. */
242 if (!(networkmenu(ethernetkv
))) {
243 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
247 /* Check for ipfire-<VERSION>.tbz2 */
248 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
249 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
257 fprintf(flog
, "Harddisk scan pass %i\n", i
);
259 switch (mysystem("/bin/mountdest.sh") % 255) {
260 case 0: // Found IDE disk
265 case 1: // Found SCSI disk
270 case 2: // Found RAID disk
275 case 10: // No harddisk found
277 errorbox(ctr
[TR_NO_HARDDISK
]);
280 // Do this if the kudzu-scan fails...
281 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
286 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
287 errorbox(ctr
[TR_NO_HARDDISK
]);
290 fgets(harddrive
, 11, handle
);
293 /* load unattended configuration */
295 fprintf(flog
, "unattended: Reading unattended.conf\n");
297 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
300 /* Make the hdparms struct and print the contents.
301 With USB-KEY install and SCSI disk, while installing, the disk
302 is named 'sdb,sdc,...' (following keys)
303 On reboot, it will become 'sda'
304 To avoid many test, all names are built in the struct.
306 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
307 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
308 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
309 /* Now the names after the machine is booted. Only scsi is affected
310 and we only install on the first scsi disk. */
312 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
313 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
314 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
317 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
319 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
323 yesnoharddisk
[0] = ctr
[TR_NO
];
324 yesnoharddisk
[1] = ctr
[TR_YES
];
325 yesnoharddisk
[2] = NULL
;
329 rc
= newtWinMenu(title
, message
,
330 50, 5, 5, 6, yesnoharddisk
,
332 ctr
[TR_CANCEL
], NULL
);
340 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
341 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
342 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
343 ctr
[TR_CANCEL
], NULL
);
346 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
351 /* Calculate amount of memory in machine */
352 if ((handle
= fopen("/proc/meminfo", "r")))
354 while (fgets(line
, STRING_SIZE
-1, handle
)) {
355 if (sscanf (line
, "MemTotal: %s kB", string
)) {
356 memory
= atoi(string
) / 1024 ;
362 /* Partition, mkswp, mkfs.
363 * before partitioning, first determine the sizes of each
364 * partition. In order to do that we need to know the size of
367 /* Don't use mysystem here so we can redirect output */
368 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
369 system(commandstring
);
371 /* Calculate amount of disk space */
372 if ((handle
= fopen("/tmp/disksize", "r"))) {
373 fgets(line
, STRING_SIZE
-1, handle
);
374 if (sscanf (line
, "%s", string
)) {
375 maximum_free
= atoi(string
) / 1024;
380 fprintf(flog
, "maximum_free = %ld, memory = %ld", maximum_free
, memory
);
382 swap_file
= calc_swapsize(memory
, maximum_free
);
384 if (maximum_free
< 512 + swap_file
) {
385 if (maximum_free
< 700) {
386 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
391 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
401 boot_partition
= 20; /* in MB */
402 current_free
= maximum_free
- boot_partition
- swap_file
;
404 root_partition
= calc_rootsize(current_free
, maximum_free
);
406 if (root_partition
== 0) {
407 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
410 current_free
= current_free
- root_partition
;
413 if (current_free
< 256) {
414 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
418 system_partition
= current_free
;
420 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
421 boot_partition
, swap_file
, system_partition
, root_partition
);
423 handle
= fopen("/tmp/partitiontable", "w");
427 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
428 boot_partition
, swap_file
, root_partition
);
430 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
431 boot_partition
, root_partition
);
436 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
437 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
439 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
443 if (fstype
== REISER4
) {
444 mysystem("/sbin/modprobe reiser4");
445 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
446 } else if (fstype
== REISERFS
) {
447 mysystem("/sbin/modprobe reiserfs");
448 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
449 } else if (fstype
== EXT3
) {
450 mysystem("/sbin/modprobe ext3");
451 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
454 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
455 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
457 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
462 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
463 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
465 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
470 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
471 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
473 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
477 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
478 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
480 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
484 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
485 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
487 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
491 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
492 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
493 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
495 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
496 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
498 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
502 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
503 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
505 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
509 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
510 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
512 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
516 if (installtype
== URL_INSTALL
) {
517 snprintf(commandstring
, STRING_SIZE
,
518 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
521 if (installtype
== CDROM_INSTALL
) {
522 snprintf(commandstring
, STRING_SIZE
,
523 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
526 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
527 ctr
[TR_INSTALLING_FILES
]))
529 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
533 /* Save language und local settings */
534 write_lang_configs(shortlangname
);
536 /* touch the modules.dep files */
537 snprintf(commandstring
, STRING_SIZE
,
538 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
540 mysystem(commandstring
);
541 snprintf(commandstring
, STRING_SIZE
,
542 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
544 mysystem(commandstring
);
547 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
549 /* mount proc filesystem */
550 mysystem("mkdir /harddisk/proc");
551 mysystem("/bin/mount --bind /proc /harddisk/proc");
552 mysystem("/bin/mount --bind /dev /harddisk/dev");
553 mysystem("/bin/mount --bind /sys /harddisk/sys");
555 /* Build cache lang file */
556 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
557 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
559 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
563 /* Update /etc/fstab */
564 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
566 if (fstype
== REISER4
) {
567 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
568 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
569 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
570 } else if (fstype
== REISERFS
) {
571 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
572 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
573 } else if (fstype
== EXT3
) {
574 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
575 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
577 errorbox(ctr
[TR_JOURNAL_ERROR
]);
578 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
581 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
582 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
584 errorbox(ctr
[TR_JOURNAL_ERROR
]);
585 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
588 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
590 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"ext3 ");
591 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
594 /* Going to make our initrd... */
595 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
596 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
597 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
598 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
600 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
601 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
602 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
604 /* restore permissions */
605 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
607 snprintf(commandstring
, STRING_SIZE
,
608 "/sbin/chroot /harddisk /boot/grub/grubbatch");
609 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
610 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
614 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
616 mysystem("umount /cdrom");
617 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
618 mysystem(commandstring
);
621 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
623 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
629 fprintf(flog
, "Install program ended.\n");
632 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
634 freekeyvalues(ethernetkv
);
636 if (allok
&& !allok_fastexit
)
639 fprintf(flog
, "Entering unattended setup\n");
640 if (unattended_setup(unattendedkv
)) {
641 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
642 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
644 errorbox("Unattended setup failed.");
654 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
655 printf("Unable to run setup.\n");
658 if (system("/bin/umount /harddisk/proc"))
659 printf("Unable to umount /harddisk/proc.\n");
669 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
674 system("/bin/umount /harddisk/proc");
675 system("/bin/umount /harddisk/dev");
676 system("/bin/umount /harddisk/sys");
678 system("/bin/umount /harddisk/var");
679 system("/bin/umount /harddisk/boot");
680 system("/bin/umount /harddisk");