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 8400
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
36 int main(int argc
, char *argv
[])
38 char *langnames
[] = { "Deutsch", "English", "Français", "Español", NULL
};
39 char *shortlangnames
[] = { "de", "en", "fr", "es", NULL
};
40 char **langtrs
[] = { de_tr
, en_tr
, fr_tr
, es_tr
, NULL
};
42 char harddrive
[30], sourcedrive
[5]; /* Device holder. */
43 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
45 char commandstring
[STRING_SIZE
];
46 char mkfscommand
[STRING_SIZE
];
47 char *fstypes
[] = { "ext2", "ext3", "ReiserFS", NULL
};
48 int fstype
= REISERFS
;
53 char shortlangname
[10];
55 char title
[STRING_SIZE
];
59 struct keyvalue
*ethernetkv
= initkeyvalues();
60 FILE *handle
, *cmdfile
;
61 char line
[STRING_SIZE
];
62 char string
[STRING_SIZE
];
63 long memory
= 0, disk
= 0, free
;
64 long system_partition
, boot_partition
, root_partition
, swap_file
;
66 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
69 struct keyvalue
*unattendedkv
= initkeyvalues();
71 char restore_file
[STRING_SIZE
] = "";
73 setlocale (LC_ALL
, "");
74 sethostname( SNAME
, 10);
76 memset(&hdparams
, 0, sizeof(struct devparams
));
77 memset(&cdromparams
, 0, sizeof(struct devparams
));
79 /* Log file/terminal stuff. */
82 if (!(flog
= fopen(argv
[1], "w+")))
90 fprintf(flog
, "Install program started.\n");
95 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
96 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
98 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
100 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
102 fgets(line
, STRING_SIZE
, cmdfile
);
104 // check if we have to make an unattended install
105 if (strstr (line
, "unattended") != NULL
) {
107 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
111 // Load ata-piix prior kudzu because kudzu use ata-generic for ich7
112 mysystem("/sbin/modprobe ata_piix");
114 // Starting hardware detection
115 runcommandwithstatus("/bin/probehw.sh", "Probing Hardware ...");
117 // Load common modules
118 mysystem("/sbin/modprobe ide-generic");
119 mysystem("/sbin/modprobe ide-cd");
120 mysystem("/sbin/modprobe ide-disk");
121 mysystem("/sbin/modprobe ehci-hcd");
122 mysystem("/sbin/modprobe uhci-hcd");
123 mysystem("/sbin/modprobe ohci-hcd");
124 mysystem("/sbin/modprobe ohci1394");
125 mysystem("/sbin/modprobe sd_mod");
126 mysystem("/sbin/modprobe sr_mod");
127 mysystem("/sbin/modprobe usb-storage");
128 mysystem("/sbin/modprobe usbhid");
129 mysystem("/sbin/modprobe ahci");
131 mysystem("/sbin/modprobe iso9660"); // CDROM
132 mysystem("/sbin/modprobe ext2"); // Boot patition
133 mysystem("/sbin/modprobe vfat"); // USB key
135 runcommandwithstatus("/bin/sleep 10", "Waiting for USB Hardware ...");
137 /* German is the default */
138 for (choice
= 0; langnames
[choice
]; choice
++)
140 if (strcmp(langnames
[choice
], "Deutsch") == 0)
143 if (!langnames
[choice
])
147 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
148 langnames
, &choice
, "Ok", NULL
);
151 ctr
= langtrs
[choice
];
152 strcpy(shortlangname
, shortlangnames
[choice
]);
154 newtPushHelpLine(ctr
[TR_HELPLINE
]);
156 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
157 newtWinMessage(title
, ctr
[TR_OK
], message
);
159 switch (mysystem("/bin/mountsource.sh")) {
163 errorbox(ctr
[TR_NO_CDROM
]);
167 /* read source drive letter */
168 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
169 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
172 fgets(sourcedrive
, 5, handle
);
173 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
179 fprintf(flog
, "Harddisk scan pass %i\n", i
);
181 switch (mysystem("/bin/mountdest.sh") % 255) {
182 case 0: // Found IDE disk
187 case 1: // Found SCSI disk
192 case 2: // Found RAID disk
197 case 10: // No harddisk found
199 errorbox(ctr
[TR_NO_HARDDISK
]);
202 // Do this if the kudzu-scan fails...
203 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
208 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
209 errorbox(ctr
[TR_NO_HARDDISK
]);
212 fgets(harddrive
, 30, handle
);
215 /* load unattended configuration */
217 fprintf(flog
, "unattended: Reading unattended.conf\n");
219 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
220 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
223 /* Make the hdparms struct and print the contents.
224 With USB-KEY install and SCSI disk, while installing, the disk
225 is named 'sdb,sdc,...' (following keys)
226 On reboot, it will become 'sda'
227 To avoid many test, all names are built in the struct.
229 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
230 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
231 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
232 /* Now the names after the machine is booted. Only scsi is affected
233 and we only install on the first scsi disk. */
235 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
236 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
237 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
240 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
242 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
246 yesnoharddisk
[0] = ctr
[TR_NO
];
247 yesnoharddisk
[1] = ctr
[TR_YES
];
248 yesnoharddisk
[2] = NULL
;
252 rc
= newtWinMenu(title
, message
,
253 50, 5, 5, 6, yesnoharddisk
,
255 ctr
[TR_CANCEL
], NULL
);
263 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
264 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
265 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
266 ctr
[TR_CANCEL
], NULL
);
274 /* Calculate amount of memory in machine */
275 if ((handle
= fopen("/proc/meminfo", "r")))
277 while (fgets(line
, STRING_SIZE
-1, handle
)) {
278 if (sscanf (line
, "MemTotal: %s kB", string
)) {
279 memory
= atoi(string
) / 1024 ;
285 /* Partition, mkswp, mkfs.
286 * before partitioning, first determine the sizes of each
287 * partition. In order to do that we need to know the size of
290 /* Don't use mysystem here so we can redirect output */
291 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
292 system(commandstring
);
294 /* Calculate amount of disk space */
295 if ((handle
= fopen("/tmp/disksize", "r"))) {
296 fgets(line
, STRING_SIZE
-1, handle
);
297 if (sscanf (line
, "%s", string
)) {
298 disk
= atoi(string
) / 1024;
303 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
305 /* Calculating Swap-Size dependend of Ram Size */
308 else if (memory
<= 1024 && memory
> 256)
311 swap_file
= memory
/ 4;
313 /* Calculating Root-Size dependend of Max Disk Space */
315 root_partition
= 200;
316 else if ( disk
>= 756 && disk
<= 3072 )
317 root_partition
= 512;
319 root_partition
= 2048;
322 /* Calculating the amount of free space */
323 boot_partition
= 20; /* in MB */
324 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
326 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
327 boot_partition
, swap_file
, system_partition
, root_partition
);
330 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
331 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
334 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
335 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
338 fprintf(flog
, "Disk is too small.\n");
339 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
342 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
346 fprintf(flog
, "Disk is too small.\n");
347 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
350 handle
= fopen("/tmp/partitiontable", "w");
354 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
355 boot_partition
, swap_file
, root_partition
);
357 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
358 boot_partition
, root_partition
);
363 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
364 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
366 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
370 if (fstype
== EXT2
) {
371 mysystem("/sbin/modprobe ext2");
372 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2 -c");
373 } else if (fstype
== REISERFS
) {
374 mysystem("/sbin/modprobe reiserfs");
375 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
376 } else if (fstype
== EXT3
) {
377 mysystem("/sbin/modprobe ext3");
378 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
381 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
382 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
384 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
389 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
390 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
392 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
397 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
398 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
400 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
404 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
405 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
407 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
411 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
412 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
414 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
418 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
419 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
420 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
422 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
423 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
425 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
429 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
430 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
432 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
436 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
437 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
439 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
443 snprintf(commandstring
, STRING_SIZE
,
444 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma");
446 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
447 ctr
[TR_INSTALLING_FILES
]))
449 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
453 /* Save language und local settings */
454 write_lang_configs(shortlangname
);
456 /* touch the modules.dep files */
457 snprintf(commandstring
, STRING_SIZE
,
458 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
460 mysystem(commandstring
);
461 /* snprintf(commandstring, STRING_SIZE,
462 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
464 mysystem(commandstring);
468 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
470 /* mount proc filesystem */
471 mysystem("mkdir /harddisk/proc");
472 mysystem("/bin/mount --bind /proc /harddisk/proc");
473 mysystem("/bin/mount --bind /dev /harddisk/dev");
474 mysystem("/bin/mount --bind /sys /harddisk/sys");
476 /* Build cache lang file */
477 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
478 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
480 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
484 /* Update /etc/fstab */
485 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
487 if (fstype
== EXT2
) {
488 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
489 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
490 } else if (fstype
== REISERFS
) {
491 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
492 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
493 } else if (fstype
== EXT3
) {
494 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", 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 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
502 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
504 errorbox(ctr
[TR_JOURNAL_ERROR
]);
505 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
508 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
510 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
513 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
515 /* Going to make our initrd... */
516 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/local/bin/rebuild-initrd");
517 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
519 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
520 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
521 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
523 system("sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
525 snprintf(commandstring
, STRING_SIZE
,
526 "/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
527 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
528 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
532 /* Copy restore file from cdrom */
533 if (unattended
&& (strlen(restore_file
) > 0)) {
534 fprintf(flog
, "unattended: Copy restore file\n");
535 snprintf(commandstring
, STRING_SIZE
,
536 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
537 mysystem(commandstring
);
540 mysystem("umount /cdrom");
541 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
542 mysystem(commandstring
);
545 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
547 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
553 fprintf(flog
, "Install program ended.\n");
556 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
558 freekeyvalues(ethernetkv
);
560 if (allok
&& !allok_fastexit
)
563 fprintf(flog
, "Entering unattended setup\n");
564 if (unattended_setup(unattendedkv
)) {
565 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
566 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
568 errorbox("Unattended setup failed.");
578 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
579 printf("Unable to run setup.\n");
582 if (system("/bin/umount /harddisk/proc"))
583 printf("Unable to umount /harddisk/proc.\n");
593 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
598 system("/bin/umount /harddisk/proc");
599 system("/bin/umount /harddisk/dev");
600 system("/bin/umount /harddisk/sys");
602 system("/bin/umount /harddisk/var");
603 system("/bin/umount /harddisk/boot");
604 system("/bin/umount /harddisk");