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 INST_FILECOUNT 6200
15 #define UNATTENDED_CONF "/cdrom/boot/unattended.conf"
26 extern char url
[STRING_SIZE
];
28 struct nic nics
[20] = { { "" , "" , "" } }; // only defined for compile
29 struct knic knics
[20] = { { "" , "" , "" , "" } }; // only defined for compile
34 int main(int argc
, char *argv
[])
36 char *langnames
[] = { "Deutsch", "English", NULL
};
37 char *shortlangnames
[] = { "de", "en", NULL
};
38 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
40 char harddrive
[30], sourcedrive
[5]; /* Device holder. */
41 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
43 char commandstring
[STRING_SIZE
];
44 char mkfscommand
[STRING_SIZE
];
45 char *fstypes
[] = { "Reiser4", "ReiserFS", "ext3", NULL
};
46 int fstype
= REISERFS
;
51 char shortlangname
[10];
53 char title
[STRING_SIZE
];
57 struct keyvalue
*ethernetkv
= initkeyvalues();
58 FILE *handle
, *cmdfile
;
59 char line
[STRING_SIZE
];
60 char string
[STRING_SIZE
];
61 long memory
= 0, disk
= 0, free
;
62 long system_partition
, boot_partition
, root_partition
, swap_file
;
64 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
67 struct keyvalue
*unattendedkv
= initkeyvalues();
69 char restore_file
[STRING_SIZE
] = "";
71 setlocale (LC_ALL
, "");
72 sethostname( SNAME
, 10);
74 memset(&hdparams
, 0, sizeof(struct devparams
));
75 memset(&cdromparams
, 0, sizeof(struct devparams
));
77 /* Log file/terminal stuff. */
80 if (!(flog
= fopen(argv
[1], "w+")))
88 fprintf(flog
, "Install program started.\n");
93 /* Do usb detection first for usb keyboard */
94 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
96 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
98 fgets(line
, STRING_SIZE
, cmdfile
);
100 // check if we have to make an unattended install
101 if (strstr (line
, "unattended") != NULL
) {
103 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
107 mysystem("/sbin/modprobe ide-generic");
108 mysystem("/sbin/modprobe generic");
109 mysystem("/sbin/modprobe ide-cd");
110 mysystem("/sbin/modprobe ide-disk");
111 mysystem("/sbin/modprobe uhci-hcd");
112 mysystem("/sbin/modprobe ohci-hcd");
113 mysystem("/sbin/modprobe ehci-hcd");
114 mysystem("/sbin/modprobe ohci1394");
115 mysystem("/sbin/modprobe sd_mod");
116 mysystem("/sbin/modprobe sr_mod");
117 mysystem("/sbin/modprobe usb-storage");
118 mysystem("/sbin/modprobe usbhid");
120 mysystem("/sbin/modprobe iso9660"); // CDROM
121 mysystem("/sbin/modprobe ext2"); // Boot patition
122 mysystem("/sbin/modprobe vfat"); // USB key
124 /* German is the default */
125 for (choice
= 0; langnames
[choice
]; choice
++)
127 if (strcmp(langnames
[choice
], "Deutsch") == 0)
130 if (!langnames
[choice
])
134 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
135 langnames
, &choice
, "Ok", NULL
);
138 ctr
= langtrs
[choice
];
139 strcpy(shortlangname
, shortlangnames
[choice
]);
141 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
142 newtPushHelpLine(ctr
[TR_HELPLINE
]);
143 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
145 // Starting hardware detection
146 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
148 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
149 newtWinMessage(title
, ctr
[TR_OK
], message
);
151 switch (mysystem("/bin/mountsource.sh")) {
155 errorbox(ctr
[TR_NO_CDROM
]);
159 /* read source drive letter */
160 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
161 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
164 fgets(sourcedrive
, 5, handle
);
165 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
171 fprintf(flog
, "Harddisk scan pass %i\n", i
);
173 switch (mysystem("/bin/mountdest.sh") % 255) {
174 case 0: // Found IDE disk
179 case 1: // Found SCSI disk
184 case 2: // Found RAID disk
189 case 10: // No harddisk found
191 errorbox(ctr
[TR_NO_HARDDISK
]);
194 // Do this if the kudzu-scan fails...
195 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
200 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
201 errorbox(ctr
[TR_NO_HARDDISK
]);
204 fgets(harddrive
, 30, handle
);
207 /* load unattended configuration */
209 fprintf(flog
, "unattended: Reading unattended.conf\n");
211 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
212 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
215 /* Make the hdparms struct and print the contents.
216 With USB-KEY install and SCSI disk, while installing, the disk
217 is named 'sdb,sdc,...' (following keys)
218 On reboot, it will become 'sda'
219 To avoid many test, all names are built in the struct.
221 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
222 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
223 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
224 /* Now the names after the machine is booted. Only scsi is affected
225 and we only install on the first scsi disk. */
227 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
228 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
229 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
232 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
234 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
238 yesnoharddisk
[0] = ctr
[TR_NO
];
239 yesnoharddisk
[1] = ctr
[TR_YES
];
240 yesnoharddisk
[2] = NULL
;
244 rc
= newtWinMenu(title
, message
,
245 50, 5, 5, 6, yesnoharddisk
,
247 ctr
[TR_CANCEL
], NULL
);
255 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
256 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
257 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
258 ctr
[TR_CANCEL
], NULL
);
266 /* Calculate amount of memory in machine */
267 if ((handle
= fopen("/proc/meminfo", "r")))
269 while (fgets(line
, STRING_SIZE
-1, handle
)) {
270 if (sscanf (line
, "MemTotal: %s kB", string
)) {
271 memory
= atoi(string
) / 1024 ;
277 /* Partition, mkswp, mkfs.
278 * before partitioning, first determine the sizes of each
279 * partition. In order to do that we need to know the size of
282 /* Don't use mysystem here so we can redirect output */
283 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
284 system(commandstring
);
286 /* Calculate amount of disk space */
287 if ((handle
= fopen("/tmp/disksize", "r"))) {
288 fgets(line
, STRING_SIZE
-1, handle
);
289 if (sscanf (line
, "%s", string
)) {
290 disk
= atoi(string
) / 1024;
295 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
297 /* Calculating Swap-Size dependend of Ram Size */
300 else if (memory
>= 1024)
305 /* Calculating Root-Size dependend of Max Disk Space */
307 root_partition
= 200;
308 else if ( disk
>= 756 && disk
<= 3072 )
309 root_partition
= 512;
311 root_partition
= 2048;
314 /* Calculating the amount of free space */
315 boot_partition
= 20; /* in MB */
316 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
318 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
319 boot_partition
, swap_file
, system_partition
, root_partition
);
322 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
323 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
326 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
327 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
330 fprintf(flog
, "Disk is too small.\n");
331 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
334 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
338 fprintf(flog
, "Disk is too small.\n");
339 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
342 handle
= fopen("/tmp/partitiontable", "w");
346 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
347 boot_partition
, swap_file
, root_partition
);
349 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
350 boot_partition
, root_partition
);
355 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
356 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
358 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
362 if (fstype
== REISER4
) {
363 mysystem("/sbin/modprobe reiser4");
364 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
365 } else if (fstype
== REISERFS
) {
366 mysystem("/sbin/modprobe reiserfs");
367 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
368 } else if (fstype
== EXT3
) {
369 mysystem("/sbin/modprobe ext3");
370 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
373 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
374 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
376 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
381 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
382 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
384 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
389 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
390 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
392 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
396 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
397 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
399 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
403 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
404 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
406 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
410 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
411 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
412 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
414 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
415 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
417 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
421 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
422 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
424 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
428 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
429 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
431 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
435 snprintf(commandstring
, STRING_SIZE
,
436 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
438 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
439 ctr
[TR_INSTALLING_FILES
]))
441 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
445 /* Save language und local settings */
446 write_lang_configs(shortlangname
);
448 /* touch the modules.dep files */
449 snprintf(commandstring
, STRING_SIZE
,
450 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
452 mysystem(commandstring
);
453 /* snprintf(commandstring, STRING_SIZE,
454 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
456 mysystem(commandstring);
459 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
461 /* mount proc filesystem */
462 mysystem("mkdir /harddisk/proc");
463 mysystem("/bin/mount --bind /proc /harddisk/proc");
464 mysystem("/bin/mount --bind /dev /harddisk/dev");
465 mysystem("/bin/mount --bind /sys /harddisk/sys");
467 /* Build cache lang file */
468 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
469 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
471 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
475 /* Update /etc/fstab */
476 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
478 if (fstype
== REISER4
) {
479 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
480 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
481 } else if (fstype
== REISERFS
) {
482 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
483 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
484 } else if (fstype
== EXT3
) {
485 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
486 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
488 errorbox(ctr
[TR_JOURNAL_ERROR
]);
489 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
492 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
493 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
495 errorbox(ctr
[TR_JOURNAL_ERROR
]);
496 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
499 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
501 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
504 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
506 /* Build the emergency ramdisk with all drivers */
507 mysystem("cp -f /harddisk/etc/mkinitcpio.conf /harddisk/etc/mkinitcpio.conf.org");
509 replace("/harddisk/etc/mkinitcpio.conf", " autodetect ", " ");
510 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s-emergency.img -k %s-ipfire", KERNEL_VERSION
, KERNEL_VERSION
);
511 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
513 mysystem("cp -f /harddisk/etc/mkinitcpio.conf.org /harddisk/etc/mkinitcpio.conf");
515 /* mkinitcpio has a problem if ide and pata are included */
516 if ( scsi_disk
==1 ) {
517 /* Remove the ide hook if we install sda */
518 replace("/harddisk/etc/mkinitcpio.conf", " ide ", " ");
520 /* Remove the pata & sata hook if we install hda */
521 replace("/harddisk/etc/mkinitcpio.conf", " pata ", " ");
522 replace("/harddisk/etc/mkinitcpio.conf", " sata ", " ");
524 /* Going to make our initrd... */
525 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s.img -k %s-ipfire", KERNEL_VERSION
, KERNEL_VERSION
);
526 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
527 /* snprintf(commandstring, STRING_SIZE, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s-smp.img -k %s-ipfire-smp", KERNEL_VERSION, KERNEL_VERSION );
528 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
530 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
531 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
532 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
534 system("sed -e 's#harddisk\\/##g' < /proc/mounts > /harddisk/etc/mtab");
536 snprintf(commandstring
, STRING_SIZE
,
537 "/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
538 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
539 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
543 /* Copy restore file from cdrom */
544 if (unattended
&& (strlen(restore_file
) > 0)) {
545 fprintf(flog
, "unattended: Copy restore file\n");
546 snprintf(commandstring
, STRING_SIZE
,
547 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
550 mysystem("umount /cdrom");
551 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
552 mysystem(commandstring
);
555 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
557 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
563 fprintf(flog
, "Install program ended.\n");
566 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
568 freekeyvalues(ethernetkv
);
570 if (allok
&& !allok_fastexit
)
573 fprintf(flog
, "Entering unattended setup\n");
574 if (unattended_setup(unattendedkv
)) {
575 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
576 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
578 errorbox("Unattended setup failed.");
588 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
589 printf("Unable to run setup.\n");
592 if (system("/bin/umount /harddisk/proc"))
593 printf("Unable to umount /harddisk/proc.\n");
603 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
608 system("/bin/umount /harddisk/proc");
609 system("/bin/umount /harddisk/dev");
610 system("/bin/umount /harddisk/sys");
612 system("/bin/umount /harddisk/var");
613 system("/bin/umount /harddisk/boot");
614 system("/bin/umount /harddisk");