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);
458 snprintf(commandstring
, STRING_SIZE
,
459 "/bin/touch /harddisk/lib/modules/2.6.25.17-ipfire/modules.dep");
460 mysystem(commandstring
);
464 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
466 /* mount proc filesystem */
467 mysystem("mkdir /harddisk/proc");
468 mysystem("/bin/mount --bind /proc /harddisk/proc");
469 mysystem("/bin/mount --bind /dev /harddisk/dev");
470 mysystem("/bin/mount --bind /sys /harddisk/sys");
472 /* Build cache lang file */
473 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
474 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
476 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
480 /* Update /etc/fstab */
481 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
483 if (fstype
== REISER4
) {
484 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
485 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
486 } else if (fstype
== REISERFS
) {
487 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
488 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
489 } else if (fstype
== EXT3
) {
490 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
491 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
493 errorbox(ctr
[TR_JOURNAL_ERROR
]);
494 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
497 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
498 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
500 errorbox(ctr
[TR_JOURNAL_ERROR
]);
501 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
504 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
506 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
509 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
511 /* Build the emergency ramdisk with all drivers */
512 mysystem("cp -f /harddisk/etc/mkinitcpio.conf /harddisk/etc/mkinitcpio.conf.org");
514 replace("/harddisk/etc/mkinitcpio.conf", " autodetect ", " ");
515 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s-emergency.img -k %s-ipfire", KERNEL_VERSION
, KERNEL_VERSION
);
516 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
518 mysystem("cp -f /harddisk/etc/mkinitcpio.conf.org /harddisk/etc/mkinitcpio.conf");
520 /* mkinitcpio has a problem if ide and pata are included */
521 if ( scsi_disk
==1 ) {
522 /* Remove the ide hook if we install sda */
523 replace("/harddisk/etc/mkinitcpio.conf", " ide ", " ");
525 /* Remove the pata & sata hook if we install hda */
526 replace("/harddisk/etc/mkinitcpio.conf", " pata ", " ");
527 replace("/harddisk/etc/mkinitcpio.conf", " sata ", " ");
529 /* Going to make our initrd... */
530 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s.img -k %s-ipfire", KERNEL_VERSION
, KERNEL_VERSION
);
531 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
532 /* snprintf(commandstring, STRING_SIZE, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s-smp.img -k %s-ipfire-smp", KERNEL_VERSION, KERNEL_VERSION );
533 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
535 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-2.6.25.17.img -k 2.6.25.17-ipfire");
536 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
540 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
541 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
542 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
544 system("sed -e 's#harddisk\\/##g' < /proc/mounts > /harddisk/etc/mtab");
546 snprintf(commandstring
, STRING_SIZE
,
547 "/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
548 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
549 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
553 /* Copy restore file from cdrom */
554 if (unattended
&& (strlen(restore_file
) > 0)) {
555 fprintf(flog
, "unattended: Copy restore file\n");
556 snprintf(commandstring
, STRING_SIZE
,
557 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
558 mysystem(commandstring
);
561 mysystem("umount /cdrom");
562 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
563 mysystem(commandstring
);
566 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
568 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
574 fprintf(flog
, "Install program ended.\n");
577 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
579 freekeyvalues(ethernetkv
);
581 if (allok
&& !allok_fastexit
)
584 fprintf(flog
, "Entering unattended setup\n");
585 if (unattended_setup(unattendedkv
)) {
586 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
587 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
589 errorbox("Unattended setup failed.");
599 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
600 printf("Unable to run setup.\n");
603 if (system("/bin/umount /harddisk/proc"))
604 printf("Unable to umount /harddisk/proc.\n");
614 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
619 system("/bin/umount /harddisk/proc");
620 system("/bin/umount /harddisk/dev");
621 system("/bin/umount /harddisk/sys");
623 system("/bin/umount /harddisk/var");
624 system("/bin/umount /harddisk/boot");
625 system("/bin/umount /harddisk");