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 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
94 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
96 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
98 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
100 fgets(line
, STRING_SIZE
, cmdfile
);
102 // check if we have to make an unattended install
103 if (strstr (line
, "unattended") != NULL
) {
105 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
109 // Starting hardware detection
110 runcommandwithstatus("/bin/probehw.sh", "Probing Hardware ...");
112 // Load common modules
113 mysystem("/sbin/modprobe ide-generic");
114 mysystem("/sbin/modprobe ide-cd");
115 mysystem("/sbin/modprobe ide-disk");
116 mysystem("/sbin/modprobe uhci-hcd");
117 mysystem("/sbin/modprobe ohci-hcd");
118 mysystem("/sbin/modprobe ehci-hcd");
119 mysystem("/sbin/modprobe ohci1394");
120 mysystem("/sbin/modprobe sd_mod");
121 mysystem("/sbin/modprobe sr_mod");
122 mysystem("/sbin/modprobe usb-storage");
123 mysystem("/sbin/modprobe usbhid");
125 mysystem("/sbin/modprobe iso9660"); // CDROM
126 mysystem("/sbin/modprobe ext2"); // Boot patition
127 mysystem("/sbin/modprobe vfat"); // USB key
129 /* German is the default */
130 for (choice
= 0; langnames
[choice
]; choice
++)
132 if (strcmp(langnames
[choice
], "Deutsch") == 0)
135 if (!langnames
[choice
])
139 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
140 langnames
, &choice
, "Ok", NULL
);
143 ctr
= langtrs
[choice
];
144 strcpy(shortlangname
, shortlangnames
[choice
]);
146 newtPushHelpLine(ctr
[TR_HELPLINE
]);
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);
460 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
462 /* mount proc filesystem */
463 mysystem("mkdir /harddisk/proc");
464 mysystem("/bin/mount --bind /proc /harddisk/proc");
465 mysystem("/bin/mount --bind /dev /harddisk/dev");
466 mysystem("/bin/mount --bind /sys /harddisk/sys");
468 /* Build cache lang file */
469 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
470 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
472 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
476 /* Update /etc/fstab */
477 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
479 if (fstype
== REISER4
) {
480 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
481 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
482 } else if (fstype
== REISERFS
) {
483 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
484 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
485 } else if (fstype
== EXT3
) {
486 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
487 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
489 errorbox(ctr
[TR_JOURNAL_ERROR
]);
490 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
493 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
494 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
496 errorbox(ctr
[TR_JOURNAL_ERROR
]);
497 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
500 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
502 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
505 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
507 /* Build the emergency ramdisk with all drivers */
508 mysystem("cp -f /harddisk/etc/mkinitcpio.conf /harddisk/etc/mkinitcpio.conf.org");
510 replace("/harddisk/etc/mkinitcpio.conf", " autodetect ", " ");
511 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s-emergency.img -k %s-ipfire", KERNEL_VERSION
, KERNEL_VERSION
);
512 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
514 mysystem("cp -f /harddisk/etc/mkinitcpio.conf.org /harddisk/etc/mkinitcpio.conf");
516 /* mkinitcpio has a problem if ide and pata are included */
517 if ( scsi_disk
==1 ) {
518 /* Remove the ide hook if we install sda */
519 replace("/harddisk/etc/mkinitcpio.conf", " ide ", " ");
521 /* Remove the pata & sata hook if we install hda */
522 replace("/harddisk/etc/mkinitcpio.conf", " pata ", " ");
523 replace("/harddisk/etc/mkinitcpio.conf", " sata ", " ");
525 /* Going to make our initrd... */
526 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s.img -k %s-ipfire", KERNEL_VERSION
, KERNEL_VERSION
);
527 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
528 /* snprintf(commandstring, STRING_SIZE, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s-smp.img -k %s-ipfire-smp", KERNEL_VERSION, KERNEL_VERSION );
529 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
533 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
534 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
535 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
537 system("sed -e 's#harddisk\\/##g' < /proc/mounts > /harddisk/etc/mtab");
539 snprintf(commandstring
, STRING_SIZE
,
540 "/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
541 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
542 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
546 /* Copy restore file from cdrom */
547 if (unattended
&& (strlen(restore_file
) > 0)) {
548 fprintf(flog
, "unattended: Copy restore file\n");
549 snprintf(commandstring
, STRING_SIZE
,
550 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
551 mysystem(commandstring
);
554 mysystem("umount /cdrom");
555 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
556 mysystem(commandstring
);
559 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
561 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
567 fprintf(flog
, "Install program ended.\n");
570 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
572 freekeyvalues(ethernetkv
);
574 if (allok
&& !allok_fastexit
)
577 fprintf(flog
, "Entering unattended setup\n");
578 if (unattended_setup(unattendedkv
)) {
579 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
580 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
582 errorbox("Unattended setup failed.");
592 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
593 printf("Unable to run setup.\n");
596 if (system("/bin/umount /harddisk/proc"))
597 printf("Unable to umount /harddisk/proc.\n");
607 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
612 system("/bin/umount /harddisk/proc");
613 system("/bin/umount /harddisk/dev");
614 system("/bin/umount /harddisk/sys");
616 system("/bin/umount /harddisk/var");
617 system("/bin/umount /harddisk/boot");
618 system("/bin/umount /harddisk");