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 mysystem("/sbin/modprobe ide-generic");
146 mysystem("/sbin/modprobe generic");
147 mysystem("/sbin/modprobe ide-cd");
148 mysystem("/sbin/modprobe ide-disk");
149 mysystem("/sbin/modprobe sd_mod");
150 mysystem("/sbin/modprobe sr_mod");
151 mysystem("/sbin/modprobe usb-storage");
153 fgets(line
, STRING_SIZE
, cmdfile
);
155 // check if we have to make an unattended install
156 if (strstr (line
, "unattended") != NULL
) {
159 mysystem("/sbin/modprobe iso9660"); // CDROM
160 mysystem("/sbin/modprobe ext2"); // Boot patition
161 mysystem("/sbin/modprobe vfat"); // USB key
165 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
168 /* German is the default */
169 for (choice
= 0; langnames
[choice
]; choice
++)
171 if (strcmp(langnames
[choice
], "Deutsch") == 0)
174 if (!langnames
[choice
])
178 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
179 langnames
, &choice
, "Ok", NULL
);
182 ctr
= langtrs
[choice
];
183 strcpy(shortlangname
, shortlangnames
[choice
]);
184 fprintf(flog
, "Selected language: %s\n", shortlangname
);
186 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
187 newtPushHelpLine(ctr
[TR_HELPLINE
]);
188 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
191 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
192 newtWinMessage(title
, ctr
[TR_OK
], message
);
194 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
195 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
196 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
197 ctr
[TR_CANCEL
], NULL
);
200 installtype
= CDROM_INSTALL
;
206 // Starting hardware detection
207 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
210 if (installtype
== CDROM_INSTALL
) {
211 switch (mysystem("/bin/mountsource.sh")) {
213 installtype
= CDROM_INSTALL
;
217 installtype
= DISK_INSTALL
;
220 errorbox(ctr
[TR_NO_CDROM
]);
224 /* read source drive letter */
225 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
226 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
229 fgets(sourcedrive
, 5, handle
);
230 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
234 /* Configure the network now! */
235 if (installtype
== URL_INSTALL
) {
236 /* Network driver and params. */
237 if (!(networkmenu(ethernetkv
))) {
238 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
242 /* Check for ipfire-<VERSION>.tbz2 */
243 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
244 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
252 fprintf(flog
, "Harddisk scan pass %i\n", i
);
254 switch (mysystem("/bin/mountdest.sh") % 255) {
255 case 0: // Found IDE disk
260 case 1: // Found SCSI disk
265 case 2: // Found RAID disk
270 case 10: // No harddisk found
272 errorbox(ctr
[TR_NO_HARDDISK
]);
275 // Do this if the kudzu-scan fails...
276 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
281 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
282 errorbox(ctr
[TR_NO_HARDDISK
]);
285 fgets(harddrive
, 11, handle
);
288 /* load unattended configuration */
290 fprintf(flog
, "unattended: Reading unattended.conf\n");
292 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
295 /* Make the hdparms struct and print the contents.
296 With USB-KEY install and SCSI disk, while installing, the disk
297 is named 'sdb,sdc,...' (following keys)
298 On reboot, it will become 'sda'
299 To avoid many test, all names are built in the struct.
301 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
302 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
303 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
304 /* Now the names after the machine is booted. Only scsi is affected
305 and we only install on the first scsi disk. */
307 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
308 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
309 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
312 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
314 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
318 yesnoharddisk
[0] = ctr
[TR_NO
];
319 yesnoharddisk
[1] = ctr
[TR_YES
];
320 yesnoharddisk
[2] = NULL
;
324 rc
= newtWinMenu(title
, message
,
325 50, 5, 5, 6, yesnoharddisk
,
327 ctr
[TR_CANCEL
], NULL
);
335 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
336 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
337 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
338 ctr
[TR_CANCEL
], NULL
);
341 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
346 /* Calculate amount of memory in machine */
347 if ((handle
= fopen("/proc/meminfo", "r")))
349 while (fgets(line
, STRING_SIZE
-1, handle
)) {
350 if (sscanf (line
, "MemTotal: %s kB", string
)) {
351 memory
= atoi(string
) / 1024 ;
357 /* Partition, mkswp, mkfs.
358 * before partitioning, first determine the sizes of each
359 * partition. In order to do that we need to know the size of
362 /* Don't use mysystem here so we can redirect output */
363 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
364 system(commandstring
);
366 /* Calculate amount of disk space */
367 if ((handle
= fopen("/tmp/disksize", "r"))) {
368 fgets(line
, STRING_SIZE
-1, handle
);
369 if (sscanf (line
, "%s", string
)) {
370 maximum_free
= atoi(string
) / 1024;
375 fprintf(flog
, "maximum_free = %ld, memory = %ld", maximum_free
, memory
);
377 swap_file
= calc_swapsize(memory
, maximum_free
);
379 if (maximum_free
< 512 + swap_file
) {
380 if (maximum_free
< 700) {
381 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
386 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
396 boot_partition
= 20; /* in MB */
397 current_free
= maximum_free
- boot_partition
- swap_file
;
399 if (current_free
< 700) {
400 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
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");