2 /* SmoothWall install program.
4 * This program is distributed under the terms of the GNU General Public
5 * Licence. See the file COPYING for details.
7 * (c) Lawrence Manning, 2001
8 * Contains main entry point, and misc functions.6
15 #define INST_FILECOUNT 10700
16 #define UNATTENDED_CONF "/cdrom/boot/unattended.conf"
17 #define LICENSE_FILE "/cdrom/COPYING"
29 extern char url
[STRING_SIZE
];
31 struct nic nics
[20] = { { "" , "" , "" } }; // only defined for compile
32 struct knic knics
[20] = { { "" , "" , "" , "" } }; // only defined for compile
41 int main(int argc
, char *argv
[])
44 char discl_msg
[40000] = "Disclaimer\n";
46 char *langnames
[] = { "Deutsch", "English", "Français", "Español", "Polski", "Русский", NULL
};
47 char *shortlangnames
[] = { "de", "en", "fr", "es", "pl", "ru", NULL
};
48 char **langtrs
[] = { de_tr
, en_tr
, fr_tr
, es_tr
, pl_tr
, ru_tr
, NULL
};
50 char harddrive
[30], sourcedrive
[5]; /* Device holder. */
51 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
53 char commandstring
[STRING_SIZE
];
54 char mkfscommand
[STRING_SIZE
];
55 char *fstypes
[] = { "ext2", "ext3", "ext4", "ReiserFS", NULL
};
61 char shortlangname
[10];
63 char title
[STRING_SIZE
];
67 struct keyvalue
*ethernetkv
= initkeyvalues();
68 FILE *handle
, *cmdfile
, *copying
;
69 char line
[STRING_SIZE
];
70 char string
[STRING_SIZE
];
71 long memory
= 0, disk
= 0, free
;
72 long system_partition
, boot_partition
, root_partition
, swap_file
;
74 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
77 int serialconsole
= 0;
78 struct keyvalue
*unattendedkv
= initkeyvalues();
80 char restore_file
[STRING_SIZE
] = "";
82 setlocale (LC_ALL
, "");
83 sethostname( SNAME
, 10);
85 memset(&hdparams
, 0, sizeof(struct devparams
));
86 memset(&cdromparams
, 0, sizeof(struct devparams
));
88 /* Log file/terminal stuff. */
91 if (!(flog
= fopen(argv
[1], "w+")))
99 fprintf(flog
, "Install program started.\n");
104 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
105 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
107 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
109 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
111 fgets(line
, STRING_SIZE
, cmdfile
);
113 // check if we have to make an unattended install
114 if (strstr (line
, "unattended") != NULL
) {
116 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
118 // check if we have to patch for serial console
119 if (strstr (line
, "console=ttyS0") != NULL
) {
124 // Load common modules
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
], "English") == 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
]);
149 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
150 newtWinMessage(title
, ctr
[TR_OK
], message
);
153 mysystem("/bin/mountsource.sh");
155 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
156 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_NO_LOCAL_SOURCE
]);
157 runcommandwithstatus("/bin/downloadsource.sh",ctr
[TR_DOWNLOADING_ISO
]);
158 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
159 errorbox(ctr
[TR_DOWNLOAD_ERROR
]);
164 fgets(sourcedrive
, 5, handle
);
165 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
169 // Read the license file.
170 if (!(copying
= fopen(LICENSE_FILE
, "r"))) {
171 sprintf(discl_msg
, "Could not open license file: %s\n", LICENSE_FILE
);
172 fprintf(flog
, discl_msg
);
174 fread(discl_msg
, 1, 40000, copying
);
177 if (disclaimerbox(discl_msg
)==0) {
178 errorbox(ctr
[TR_LICENSE_NOT_ACCEPTED
]);
187 fprintf(flog
, "Harddisk scan pass %i\n", i
);
189 switch (mysystem("/bin/mountdest.sh") % 255) {
190 case 0: // Found IDE disk
195 case 1: // Found SCSI disk
200 case 2: // Found RAID disk
205 case 10: // No harddisk found
207 errorbox(ctr
[TR_NO_HARDDISK
]);
210 // Do this if the kudzu-scan fails...
211 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
216 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
217 errorbox(ctr
[TR_NO_HARDDISK
]);
220 fgets(harddrive
, 30, handle
);
223 /* load unattended configuration */
225 fprintf(flog
, "unattended: Reading unattended.conf\n");
227 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
228 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
231 /* Make the hdparms struct and print the contents.
232 With USB-KEY install and SCSI disk, while installing, the disk
233 is named 'sdb,sdc,...' (following keys)
234 On reboot, it will become 'sda'
235 To avoid many test, all names are built in the struct.
237 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
238 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
239 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
240 /* Now the names after the machine is booted. Only scsi is affected
241 and we only install on the first scsi disk. */
243 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
245 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
249 yesnoharddisk
[0] = ctr
[TR_NO
];
250 yesnoharddisk
[1] = ctr
[TR_YES
];
251 yesnoharddisk
[2] = NULL
;
255 rc
= newtWinMenu(title
, message
,
256 50, 5, 5, 6, yesnoharddisk
,
258 ctr
[TR_CANCEL
], NULL
);
265 fstypes
[0]=ctr
[TR_EXT2FS_DESCR
];
266 fstypes
[1]=ctr
[TR_EXT3FS_DESCR
];
267 fstypes
[2]=ctr
[TR_EXT4FS_DESCR
];
268 fstypes
[3]=ctr
[TR_REISERFS_DESCR
];
272 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
273 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
274 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
275 ctr
[TR_CANCEL
], NULL
);
283 /* Calculate amount of memory in machine */
284 if ((handle
= fopen("/proc/meminfo", "r")))
286 while (fgets(line
, STRING_SIZE
-1, handle
)) {
287 if (sscanf (line
, "MemTotal: %s kB", string
)) {
288 memory
= atoi(string
) / 1024 ;
294 /* Partition, mkswp, mkfs.
295 * before partitioning, first determine the sizes of each
296 * partition. In order to do that we need to know the size of
299 /* Don't use mysystem here so we can redirect output */
300 sprintf(commandstring
, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
301 system(commandstring
);
303 /* Calculate amount of disk space */
304 if ((handle
= fopen("/tmp/disksize", "r"))) {
305 fgets(line
, STRING_SIZE
-1, handle
);
306 if (sscanf (line
, "%s", string
)) {
307 disk
= atoi(string
) / 1024;
312 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
314 /* Calculating Swap-Size dependend of Ram Size */
317 else if (memory
<= 1024 && memory
> 256)
320 swap_file
= memory
/ 4;
322 /* Calculating Root-Size dependend of Max Disk Space */
324 root_partition
= 200;
325 else if ( disk
>= 756 && disk
<= 3072 )
326 root_partition
= 512;
328 root_partition
= 2048;
331 /* Calculating the amount of free space */
332 boot_partition
= 20; /* in MB */
333 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
335 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
336 boot_partition
, swap_file
, system_partition
, root_partition
);
339 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
340 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
343 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
344 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
347 fprintf(flog
, "Disk is too small.\n");
348 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
351 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
355 fprintf(flog
, "Disk is too small.\n");
356 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
359 handle
= fopen("/tmp/partitiontable", "w");
363 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
364 boot_partition
, swap_file
, root_partition
);
366 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
367 boot_partition
, root_partition
);
372 snprintf(commandstring
, STRING_SIZE
, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
373 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
375 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
379 if (fstype
== EXT2
) {
380 // mysystem("/sbin/modprobe ext2");
381 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2");
382 } else if (fstype
== REISERFS
) {
383 mysystem("/sbin/modprobe reiserfs");
384 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
385 } else if (fstype
== EXT3
) {
386 // mysystem("/sbin/modprobe ext3");
387 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3");
388 } else if (fstype
== EXT4
) {
389 // mysystem("/sbin/modprobe ext4");
390 sprintf(mkfscommand
, "/sbin/mke2fs -T ext4");
393 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams
.devnode_part
);
394 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
396 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
401 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
402 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
404 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
409 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
410 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
412 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
416 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
417 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
419 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
423 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
424 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
426 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
430 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
431 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
432 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
434 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
435 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
437 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
441 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
442 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
444 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
448 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
449 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
451 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
455 snprintf(commandstring
, STRING_SIZE
,
456 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma 2>/dev/null");
458 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
459 ctr
[TR_INSTALLING_FILES
]))
461 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
465 /* Save language und local settings */
466 write_lang_configs(shortlangname
);
468 /* mount proc filesystem */
469 mysystem("mkdir /harddisk/proc");
470 mysystem("/bin/mount --bind /proc /harddisk/proc");
471 mysystem("/bin/mount --bind /dev /harddisk/dev");
472 mysystem("/bin/mount --bind /sys /harddisk/sys");
474 /* Build cache lang file */
475 snprintf(commandstring
, STRING_SIZE
, "/usr/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
476 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
478 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
482 /* Update /etc/fstab */
483 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
);
484 system(commandstring
);
485 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
);
486 system(commandstring
);
487 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
);
488 system(commandstring
);
489 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
);
490 system(commandstring
);
492 if (fstype
== EXT2
) {
493 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
494 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
495 } else if (fstype
== REISERFS
) {
496 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
497 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
498 } else if (fstype
== EXT3
) {
499 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
500 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
501 } else if (fstype
== EXT4
) {
502 replace("/harddisk/etc/fstab", "FSTYPE", "ext4");
503 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
506 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
508 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
);
509 system(commandstring
);
511 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
513 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
516 * Generate device.map to help grub finding the device to install itself on.
519 if (f
= fopen("/harddisk/boot/grub/device.map", "w")) {
520 fprintf(f
, "(hd0) %s\n", hdparams
.devnode_disk
);
524 snprintf(commandstring
, STRING_SIZE
,
525 "/usr/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
526 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
527 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
531 /* Serial console ? */
534 replace("/harddisk/boot/grub/grub.conf", "splashimage", "#splashimage");
535 replace("/harddisk/boot/grub/grub.conf", "#serial", "serial");
536 replace("/harddisk/boot/grub/grub.conf", "#terminal", "terminal");
537 replace("/harddisk/boot/grub/grub.conf", " panic=10 ", " console=ttyS0,38400n8 panic=10 ");
540 replace("/harddisk/etc/inittab", "1:2345:respawn:", "#1:2345:respawn:");
541 replace("/harddisk/etc/inittab", "2:2345:respawn:", "#2:2345:respawn:");
542 replace("/harddisk/etc/inittab", "3:2345:respawn:", "#3:2345:respawn:");
543 replace("/harddisk/etc/inittab", "4:2345:respawn:", "#4:2345:respawn:");
544 replace("/harddisk/etc/inittab", "5:2345:respawn:", "#5:2345:respawn:");
545 replace("/harddisk/etc/inittab", "6:2345:respawn:", "#6:2345:respawn:");
546 replace("/harddisk/etc/inittab", "#7:2345:respawn:", "7:2345:respawn:");
549 /* Set marker that the user has already accepted the gpl */
550 mysystem("/usr/bin/touch /harddisk/var/ipfire/main/gpl_accepted");
552 /* Copy restore file from cdrom */
553 if (unattended
&& (strlen(restore_file
) > 0)) {
554 fprintf(flog
, "unattended: Copy restore file\n");
555 snprintf(commandstring
, STRING_SIZE
,
556 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
557 mysystem(commandstring
);
560 mysystem("umount /cdrom");
561 snprintf(commandstring
, STRING_SIZE
, "/usr/bin/eject /dev/%s", sourcedrive
);
562 mysystem(commandstring
);
565 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
567 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_PRESS_OK_TO_REBOOT
], message
);
573 fprintf(flog
, "Install program ended.\n");
576 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
578 freekeyvalues(ethernetkv
);
580 if (allok
&& !allok_fastexit
)
583 fprintf(flog
, "Entering unattended setup\n");
584 if (unattended_setup(unattendedkv
)) {
585 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
586 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
588 errorbox("Unattended setup failed.");
598 // Remove Setup autorun after boot
599 if (system("rm -f /harddisk/etc/rc.d/rcsysinit.d/S75firstsetup"))
600 printf("Unable to disable setup autorun.\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 >/dev/null 2>&1");
620 system("/bin/umount /harddisk/dev >/dev/null 2>&1");
621 system("/bin/umount /harddisk/sys >/dev/null 2>&1");
623 system("/bin/umount /harddisk/var >/dev/null 2>&1");
624 system("/bin/umount /harddisk/boot >/dev/null 2>&1");
625 system("/bin/umount /harddisk >/dev/null 2>&1");