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
};
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();
70 setlocale (LC_ALL
, "");
71 sethostname( SNAME
, 10);
73 memset(&hdparams
, 0, sizeof(struct devparams
));
74 memset(&cdromparams
, 0, sizeof(struct devparams
));
76 /* Log file/terminal stuff. */
79 if (!(flog
= fopen(argv
[1], "w+")))
87 fprintf(flog
, "Install program started.\n");
92 /* Do usb detection first for usb keyboard */
93 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
95 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
97 fgets(line
, STRING_SIZE
, cmdfile
);
99 // check if we have to make an unattended install
100 if (strstr (line
, "unattended") != NULL
) {
102 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
106 mysystem("/sbin/modprobe ide-generic");
107 mysystem("/sbin/modprobe generic");
108 mysystem("/sbin/modprobe ide-cd");
109 mysystem("/sbin/modprobe ide-disk");
110 mysystem("/sbin/modprobe uhci-hcd");
111 mysystem("/sbin/modprobe ohci-hcd");
112 mysystem("/sbin/modprobe ehci-hcd");
113 mysystem("/sbin/modprobe ohci1394");
114 mysystem("/sbin/modprobe sd_mod");
115 mysystem("/sbin/modprobe sr_mod");
116 mysystem("/sbin/modprobe usb-storage");
117 mysystem("/sbin/modprobe usbhid");
119 mysystem("/bin/sleep 3");
120 mysystem("/sbin/modprobe ahci"); // SATA AHCI Host controller
122 mysystem("/sbin/modprobe iso9660"); // CDROM
123 mysystem("/sbin/modprobe ext2"); // Boot patition
124 mysystem("/sbin/modprobe vfat"); // USB key
126 /* German is the default */
127 for (choice
= 0; langnames
[choice
]; choice
++)
129 if (strcmp(langnames
[choice
], "Deutsch") == 0)
132 if (!langnames
[choice
])
136 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
137 langnames
, &choice
, "Ok", NULL
);
140 ctr
= langtrs
[choice
];
141 strcpy(shortlangname
, shortlangnames
[choice
]);
143 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
144 newtPushHelpLine(ctr
[TR_HELPLINE
]);
145 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
147 // Starting hardware detection
148 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
150 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
151 newtWinMessage(title
, ctr
[TR_OK
], message
);
153 switch (mysystem("/bin/mountsource.sh")) {
157 errorbox(ctr
[TR_NO_CDROM
]);
161 /* read source drive letter */
162 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
163 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
166 fgets(sourcedrive
, 5, handle
);
167 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
173 fprintf(flog
, "Harddisk scan pass %i\n", i
);
175 switch (mysystem("/bin/mountdest.sh") % 255) {
176 case 0: // Found IDE disk
181 case 1: // Found SCSI disk
186 case 2: // Found RAID disk
191 case 10: // No harddisk found
193 errorbox(ctr
[TR_NO_HARDDISK
]);
196 // Do this if the kudzu-scan fails...
197 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
202 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
203 errorbox(ctr
[TR_NO_HARDDISK
]);
206 fgets(harddrive
, 30, handle
);
209 /* load unattended configuration */
211 fprintf(flog
, "unattended: Reading unattended.conf\n");
213 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
216 /* Make the hdparms struct and print the contents.
217 With USB-KEY install and SCSI disk, while installing, the disk
218 is named 'sdb,sdc,...' (following keys)
219 On reboot, it will become 'sda'
220 To avoid many test, all names are built in the struct.
222 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
223 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
224 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
225 /* Now the names after the machine is booted. Only scsi is affected
226 and we only install on the first scsi disk. */
228 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
229 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
230 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
233 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
235 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
239 yesnoharddisk
[0] = ctr
[TR_NO
];
240 yesnoharddisk
[1] = ctr
[TR_YES
];
241 yesnoharddisk
[2] = NULL
;
245 rc
= newtWinMenu(title
, message
,
246 50, 5, 5, 6, yesnoharddisk
,
248 ctr
[TR_CANCEL
], NULL
);
256 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
257 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
258 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
259 ctr
[TR_CANCEL
], NULL
);
262 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
267 /* Calculate amount of memory in machine */
268 if ((handle
= fopen("/proc/meminfo", "r")))
270 while (fgets(line
, STRING_SIZE
-1, handle
)) {
271 if (sscanf (line
, "MemTotal: %s kB", string
)) {
272 memory
= atoi(string
) / 1024 ;
278 /* Partition, mkswp, mkfs.
279 * before partitioning, first determine the sizes of each
280 * partition. In order to do that we need to know the size of
283 /* Don't use mysystem here so we can redirect output */
284 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
285 system(commandstring
);
287 /* Calculate amount of disk space */
288 if ((handle
= fopen("/tmp/disksize", "r"))) {
289 fgets(line
, STRING_SIZE
-1, handle
);
290 if (sscanf (line
, "%s", string
)) {
291 disk
= atoi(string
) / 1024;
296 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
298 /* Calculating Swap-Size dependend of Ram Size */
301 else if (memory
>= 1024)
306 /* Calculating Root-Size dependend of Max Disk Space */
308 root_partition
= 200;
309 else if ( disk
>= 756 && disk
<= 3072 )
310 root_partition
= 512;
312 root_partition
= 2048;
315 /* Calculating the amount of free space */
316 boot_partition
= 20; /* in MB */
317 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
319 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
320 boot_partition
, swap_file
, system_partition
, root_partition
);
323 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
324 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
327 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
328 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
331 fprintf(flog
, "Disk is too small.\n");
332 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
335 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
339 fprintf(flog
, "Disk is too small.\n");
340 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
343 handle
= fopen("/tmp/partitiontable", "w");
347 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
348 boot_partition
, swap_file
, root_partition
);
350 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
351 boot_partition
, root_partition
);
356 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
357 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
359 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
363 if (fstype
== REISER4
) {
364 mysystem("/sbin/modprobe reiser4");
365 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
366 } else if (fstype
== REISERFS
) {
367 mysystem("/sbin/modprobe reiserfs");
368 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
369 } else if (fstype
== EXT3
) {
370 mysystem("/sbin/modprobe ext3");
371 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
374 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
375 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
377 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
382 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
383 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
385 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
390 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
391 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
393 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
397 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
398 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
400 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
404 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
405 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
407 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
411 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
412 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
413 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
415 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
416 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
418 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
422 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
423 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
425 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
429 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
430 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
432 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
436 snprintf(commandstring
, STRING_SIZE
,
437 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
439 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
440 ctr
[TR_INSTALLING_FILES
]))
442 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
446 /* Save language und local settings */
447 write_lang_configs(shortlangname
);
449 /* touch the modules.dep files */
450 snprintf(commandstring
, STRING_SIZE
,
451 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
453 mysystem(commandstring
);
454 snprintf(commandstring
, STRING_SIZE
,
455 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
457 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/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
482 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
483 } else if (fstype
== REISERFS
) {
484 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
485 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
486 } else if (fstype
== EXT3
) {
487 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
488 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
490 errorbox(ctr
[TR_JOURNAL_ERROR
]);
491 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
494 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
495 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
497 errorbox(ctr
[TR_JOURNAL_ERROR
]);
498 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
501 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
503 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"ext3 ");
504 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
507 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
509 /* mkinitcpio has a problem if ide and pata are included */
510 if ( scsi_disk
==1 ) {
511 /* Remove the ide hook if we install sda */
512 replace("/harddisk/etc/mkinitcpio.conf", " ide ", " ");
514 /* Remove the pata & sata hook if we install hda */
515 replace("/harddisk/etc/mkinitcpio.conf", " pata ", " ");
516 replace("/harddisk/etc/mkinitcpio.conf", " sata ", " ");
518 /* Going to make our initrd... */
519 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s.img -k %s-ipfire", KERNEL_VERSION
, KERNEL_VERSION
);
520 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
521 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-%s-smp.img -k %s-ipfire-smp", KERNEL_VERSION
, KERNEL_VERSION
);
522 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
524 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
525 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
526 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
528 system("sed -e 's#harddisk\\/##g' < /proc/mounts > /harddisk/etc/mtab");
530 snprintf(commandstring
, STRING_SIZE
,
531 "/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
532 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
533 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
537 mysystem("umount /cdrom");
538 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
539 mysystem(commandstring
);
542 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
544 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
550 fprintf(flog
, "Install program ended.\n");
553 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
555 freekeyvalues(ethernetkv
);
557 if (allok
&& !allok_fastexit
)
560 fprintf(flog
, "Entering unattended setup\n");
561 if (unattended_setup(unattendedkv
)) {
562 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
563 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
565 errorbox("Unattended setup failed.");
575 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
576 printf("Unable to run setup.\n");
579 if (system("/bin/umount /harddisk/proc"))
580 printf("Unable to umount /harddisk/proc.\n");
590 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
595 system("/bin/umount /harddisk/proc");
596 system("/bin/umount /harddisk/dev");
597 system("/bin/umount /harddisk/sys");
599 system("/bin/umount /harddisk/var");
600 system("/bin/umount /harddisk/boot");
601 system("/bin/umount /harddisk");