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 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
237 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
241 yesnoharddisk
[0] = ctr
[TR_NO
];
242 yesnoharddisk
[1] = ctr
[TR_YES
];
243 yesnoharddisk
[2] = NULL
;
247 rc
= newtWinMenu(title
, message
,
248 50, 5, 5, 6, yesnoharddisk
,
250 ctr
[TR_CANCEL
], NULL
);
258 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
259 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
260 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
261 ctr
[TR_CANCEL
], NULL
);
269 /* Calculate amount of memory in machine */
270 if ((handle
= fopen("/proc/meminfo", "r")))
272 while (fgets(line
, STRING_SIZE
-1, handle
)) {
273 if (sscanf (line
, "MemTotal: %s kB", string
)) {
274 memory
= atoi(string
) / 1024 ;
280 /* Partition, mkswp, mkfs.
281 * before partitioning, first determine the sizes of each
282 * partition. In order to do that we need to know the size of
285 /* Don't use mysystem here so we can redirect output */
286 sprintf(commandstring
, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
287 system(commandstring
);
289 /* Calculate amount of disk space */
290 if ((handle
= fopen("/tmp/disksize", "r"))) {
291 fgets(line
, STRING_SIZE
-1, handle
);
292 if (sscanf (line
, "%s", string
)) {
293 disk
= atoi(string
) / 1024;
298 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
300 /* Calculating Swap-Size dependend of Ram Size */
303 else if (memory
<= 1024 && memory
> 256)
306 swap_file
= memory
/ 4;
308 /* Calculating Root-Size dependend of Max Disk Space */
310 root_partition
= 200;
311 else if ( disk
>= 756 && disk
<= 3072 )
312 root_partition
= 512;
314 root_partition
= 2048;
317 /* Calculating the amount of free space */
318 boot_partition
= 20; /* in MB */
319 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
321 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
322 boot_partition
, swap_file
, system_partition
, root_partition
);
325 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
326 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
329 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
330 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
333 fprintf(flog
, "Disk is too small.\n");
334 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
337 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
341 fprintf(flog
, "Disk is too small.\n");
342 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
345 handle
= fopen("/tmp/partitiontable", "w");
349 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
350 boot_partition
, swap_file
, root_partition
);
352 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
353 boot_partition
, root_partition
);
358 snprintf(commandstring
, STRING_SIZE
, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
359 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
361 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
365 if (fstype
== EXT2
) {
366 mysystem("/sbin/modprobe ext2");
367 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2");
368 } else if (fstype
== REISERFS
) {
369 mysystem("/sbin/modprobe reiserfs");
370 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
371 } else if (fstype
== EXT3
) {
372 mysystem("/sbin/modprobe ext3");
373 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3");
376 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams
.devnode_part
);
377 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
379 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
384 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
385 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
387 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
392 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
393 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
395 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
399 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
400 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
402 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
406 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
407 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
409 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
413 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
414 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
415 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
417 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
418 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
420 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
424 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
425 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
427 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
431 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
432 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
434 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
438 snprintf(commandstring
, STRING_SIZE
,
439 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma 2>/dev/null");
441 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
442 ctr
[TR_INSTALLING_FILES
]))
444 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
448 /* Save language und local settings */
449 write_lang_configs(shortlangname
);
451 // /* touch the modules.dep files */
452 // snprintf(commandstring, STRING_SIZE,
453 // "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
455 // mysystem(commandstring);
456 /* snprintf(commandstring, STRING_SIZE,
457 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
459 mysystem(commandstring);
463 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
465 /* mount proc filesystem */
466 mysystem("mkdir /harddisk/proc");
467 mysystem("/bin/mount --bind /proc /harddisk/proc");
468 mysystem("/bin/mount --bind /dev /harddisk/dev");
469 mysystem("/bin/mount --bind /sys /harddisk/sys");
471 /* Build cache lang file */
472 snprintf(commandstring
, STRING_SIZE
, "/usr/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
473 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
475 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
479 /* Update /etc/fstab */
480 snprintf(commandstring
, STRING_SIZE
, "/bin/sed -i -e \"s#DEVICE1#UUID=$(/sbin/blkid %s1 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams
.devnode_part
);
481 system(commandstring
);
482 snprintf(commandstring
, STRING_SIZE
, "/bin/sed -i -e \"s#DEVICE2#UUID=$(/sbin/blkid %s2 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams
.devnode_part
);
483 system(commandstring
);
484 snprintf(commandstring
, STRING_SIZE
, "/bin/sed -i -e \"s#DEVICE3#UUID=$(/sbin/blkid %s3 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams
.devnode_part
);
485 system(commandstring
);
486 snprintf(commandstring
, STRING_SIZE
, "/bin/sed -i -e \"s#DEVICE4#UUID=$(/sbin/blkid %s4 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams
.devnode_part
);
487 system(commandstring
);
489 if (fstype
== EXT2
) {
490 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
491 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
492 } else if (fstype
== REISERFS
) {
493 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
494 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
495 } else if (fstype
== EXT3
) {
496 //snprintf(commandstring, STRING_SIZE, "tune2fs -j %s3", hdparams.devnode_part);
497 //if (runcommandwithstatus(commandstring, ctr[TR_JOURNAL_EXT3]))
499 // errorbox(ctr[TR_JOURNAL_ERROR]);
500 // replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
503 //snprintf(commandstring, STRING_SIZE, "tune2fs -j %s4", hdparams.devnode_part);
504 //if (runcommandwithstatus(commandstring, ctr[TR_JOURNAL_EXT3]))
506 // errorbox(ctr[TR_JOURNAL_ERROR]);
507 // replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
510 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
512 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
515 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
517 /* Going to make our initrd... */
518 /* snprintf(commandstring, STRING_SIZE, "/usr/sbin/chroot /harddisk /usr/local/bin/rebuild-initrd");
519 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
521 snprintf(commandstring
, STRING_SIZE
, "/bin/sed -i -e \"s#root=ROOT#root=UUID=$(/sbin/blkid %s3 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/boot/grub/grub.conf", hdparams
.devnode_part
);
522 system(commandstring
);
524 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
526 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
528 snprintf(commandstring
, STRING_SIZE
,
529 "/usr/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
530 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
531 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
535 /* Copy restore file from cdrom */
536 if (unattended
&& (strlen(restore_file
) > 0)) {
537 fprintf(flog
, "unattended: Copy restore file\n");
538 snprintf(commandstring
, STRING_SIZE
,
539 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
540 mysystem(commandstring
);
543 mysystem("umount /cdrom");
544 snprintf(commandstring
, STRING_SIZE
, "/usr/bin/eject /dev/%s", sourcedrive
);
545 mysystem(commandstring
);
548 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
550 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
556 fprintf(flog
, "Install program ended.\n");
559 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
561 freekeyvalues(ethernetkv
);
563 if (allok
&& !allok_fastexit
)
566 fprintf(flog
, "Entering unattended setup\n");
567 if (unattended_setup(unattendedkv
)) {
568 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
569 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
571 errorbox("Unattended setup failed.");
580 // if (!unattended) {
581 // if (system("/usr/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
582 // printf("Unable to run setup.\n");
585 if (system("/bin/umount /harddisk/proc"))
586 printf("Unable to umount /harddisk/proc.\n");
596 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
601 system("/bin/umount /harddisk/proc");
602 system("/bin/umount /harddisk/dev");
603 system("/bin/umount /harddisk/sys");
605 system("/bin/umount /harddisk/var");
606 system("/bin/umount /harddisk/boot");
607 system("/bin/umount /harddisk");