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
};
60 char shortlangname
[10];
62 char title
[STRING_SIZE
];
66 struct keyvalue
*ethernetkv
= initkeyvalues();
67 FILE *handle
, *cmdfile
, *copying
;
68 char line
[STRING_SIZE
];
69 char string
[STRING_SIZE
];
70 long memory
= 0, disk
= 0, free
;
71 long system_partition
, boot_partition
, root_partition
, swap_file
;
73 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
76 int serialconsole
= 0;
77 struct keyvalue
*unattendedkv
= initkeyvalues();
79 char restore_file
[STRING_SIZE
] = "";
81 setlocale (LC_ALL
, "");
82 sethostname( SNAME
, 10);
84 memset(&hdparams
, 0, sizeof(struct devparams
));
85 memset(&cdromparams
, 0, sizeof(struct devparams
));
87 /* Log file/terminal stuff. */
90 if (!(flog
= fopen(argv
[1], "w+")))
98 fprintf(flog
, "Install program started.\n");
103 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
104 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
106 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
108 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
110 fgets(line
, STRING_SIZE
, cmdfile
);
112 // check if we have to make an unattended install
113 if (strstr (line
, "unattended") != NULL
) {
115 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
117 // check if we have to patch for serial console
118 if (strstr (line
, "console=ttyS0") != NULL
) {
123 // Load common modules
124 mysystem("/sbin/modprobe iso9660"); // CDROM
125 // mysystem("/sbin/modprobe ext2"); // Boot patition
126 mysystem("/sbin/modprobe vfat"); // USB key
128 /* German is the default */
129 for (choice
= 0; langnames
[choice
]; choice
++)
131 if (strcmp(langnames
[choice
], "English") == 0)
134 if (!langnames
[choice
])
138 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
139 langnames
, &choice
, "Ok", NULL
);
142 ctr
= langtrs
[choice
];
143 strcpy(shortlangname
, shortlangnames
[choice
]);
145 newtPushHelpLine(ctr
[TR_HELPLINE
]);
148 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
149 newtWinMessage(title
, ctr
[TR_OK
], message
);
152 mysystem("/bin/mountsource.sh");
154 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
155 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_NO_LOCAL_SOURCE
]);
156 runcommandwithstatus("/bin/downloadsource.sh",ctr
[TR_DOWNLOADING_ISO
]);
157 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
158 errorbox(ctr
[TR_DOWNLOAD_ERROR
]);
163 fgets(sourcedrive
, 5, handle
);
164 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
168 // Read the license file.
169 if (!(copying
= fopen(LICENSE_FILE
, "r"))) {
170 sprintf(discl_msg
, "Could not open license file: %s\n", LICENSE_FILE
);
171 fprintf(flog
, discl_msg
);
173 fread(discl_msg
, 1, 40000, copying
);
176 if (disclaimerbox(discl_msg
)==0) {
177 errorbox(ctr
[TR_LICENSE_NOT_ACCEPTED
]);
186 fprintf(flog
, "Harddisk scan pass %i\n", i
);
188 switch (mysystem("/bin/mountdest.sh") % 255) {
189 case 0: // Found IDE disk
194 case 1: // Found SCSI disk
199 case 2: // Found RAID disk
204 case 10: // No harddisk found
205 errorbox(ctr
[TR_NO_HARDDISK
]);
210 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
211 errorbox(ctr
[TR_NO_HARDDISK
]);
214 fgets(harddrive
, 30, handle
);
217 /* load unattended configuration */
219 fprintf(flog
, "unattended: Reading unattended.conf\n");
221 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
222 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
225 /* Make the hdparms struct and print the contents.
226 With USB-KEY install and SCSI disk, while installing, the disk
227 is named 'sdb,sdc,...' (following keys)
228 On reboot, it will become 'sda'
229 To avoid many test, all names are built in the struct.
231 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
232 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
233 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
234 /* Now the names after the machine is booted. Only scsi is affected
235 and we only install on the first scsi disk. */
237 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
239 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
243 yesnoharddisk
[0] = ctr
[TR_NO
];
244 yesnoharddisk
[1] = ctr
[TR_YES
];
245 yesnoharddisk
[2] = NULL
;
249 rc
= newtWinMenu(title
, message
,
250 50, 5, 5, 6, yesnoharddisk
,
252 ctr
[TR_CANCEL
], NULL
);
259 fstypes
[0]=ctr
[TR_EXT2FS_DESCR
];
260 fstypes
[1]=ctr
[TR_EXT3FS_DESCR
];
261 fstypes
[2]=ctr
[TR_EXT4FS_DESCR
];
262 fstypes
[3]=ctr
[TR_REISERFS_DESCR
];
266 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
267 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
268 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
269 ctr
[TR_CANCEL
], NULL
);
277 /* Calculate amount of memory in machine */
278 if ((handle
= fopen("/proc/meminfo", "r")))
280 while (fgets(line
, STRING_SIZE
-1, handle
)) {
281 if (sscanf (line
, "MemTotal: %s kB", string
)) {
282 memory
= atoi(string
) / 1024 ;
288 /* Partition, mkswp, mkfs.
289 * before partitioning, first determine the sizes of each
290 * partition. In order to do that we need to know the size of
293 /* Don't use mysystem here so we can redirect output */
294 sprintf(commandstring
, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
295 system(commandstring
);
297 /* Calculate amount of disk space */
298 if ((handle
= fopen("/tmp/disksize", "r"))) {
299 fgets(line
, STRING_SIZE
-1, handle
);
300 if (sscanf (line
, "%s", string
)) {
301 disk
= atoi(string
) / 1024;
306 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
308 /* Calculating Swap-Size dependend of Ram Size */
311 else if (memory
<= 1024 && memory
> 256)
314 swap_file
= memory
/ 4;
316 /* Calculating Root-Size dependend of Max Disk Space */
318 root_partition
= 200;
319 else if ( disk
>= 756 && disk
<= 3072 )
320 root_partition
= 512;
322 root_partition
= 2048;
325 /* Calculating the amount of free space */
326 boot_partition
= 20; /* in MB */
327 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
329 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
330 boot_partition
, swap_file
, system_partition
, root_partition
);
333 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
334 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
337 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
338 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
341 fprintf(flog
, "Disk is too small.\n");
342 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
345 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
349 fprintf(flog
, "Disk is too small.\n");
350 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
353 handle
= fopen("/tmp/partitiontable", "w");
357 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
358 boot_partition
, swap_file
, root_partition
);
360 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
361 boot_partition
, root_partition
);
366 snprintf(commandstring
, STRING_SIZE
, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
367 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
369 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
373 if (fstype
== EXT2
) {
374 // mysystem("/sbin/modprobe ext2");
375 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2");
376 } else if (fstype
== REISERFS
) {
377 mysystem("/sbin/modprobe reiserfs");
378 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
379 } else if (fstype
== EXT3
) {
380 // mysystem("/sbin/modprobe ext3");
381 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3");
382 } else if (fstype
== EXT4
) {
383 // mysystem("/sbin/modprobe ext4");
384 sprintf(mkfscommand
, "/sbin/mke2fs -T ext4");
387 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams
.devnode_part
);
388 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
390 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
395 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
396 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
398 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
403 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
404 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
406 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
410 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
411 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
413 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
417 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
418 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
420 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
424 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
425 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
426 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
428 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
429 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
431 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
435 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
436 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
438 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
442 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
443 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
445 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
449 snprintf(commandstring
, STRING_SIZE
,
450 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma 2>/dev/null");
452 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
453 ctr
[TR_INSTALLING_FILES
]))
455 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
459 /* Save language und local settings */
460 write_lang_configs(shortlangname
);
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
, "/usr/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 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
);
478 system(commandstring
);
479 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
);
480 system(commandstring
);
481 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
);
482 system(commandstring
);
483 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
);
484 system(commandstring
);
486 if (fstype
== EXT2
) {
487 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
488 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
489 } else if (fstype
== REISERFS
) {
490 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
491 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
492 } else if (fstype
== EXT3
) {
493 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
494 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
495 } else if (fstype
== EXT4
) {
496 replace("/harddisk/etc/fstab", "FSTYPE", "ext4");
497 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
500 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
502 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
);
503 system(commandstring
);
505 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
507 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
510 * Generate device.map to help grub finding the device to install itself on.
513 if (f
= fopen("/harddisk/boot/grub/device.map", "w")) {
514 fprintf(f
, "(hd0) %s\n", hdparams
.devnode_disk
);
518 snprintf(commandstring
, STRING_SIZE
,
519 "/usr/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
520 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
521 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
525 /* Serial console ? */
528 replace("/harddisk/boot/grub/grub.conf", "splashimage", "#splashimage");
529 replace("/harddisk/boot/grub/grub.conf", "#serial", "serial");
530 replace("/harddisk/boot/grub/grub.conf", "#terminal", "terminal");
531 replace("/harddisk/boot/grub/grub.conf", " panic=10 ", " console=ttyS0,38400n8 panic=10 ");
534 replace("/harddisk/etc/inittab", "1:2345:respawn:", "#1:2345:respawn:");
535 replace("/harddisk/etc/inittab", "2:2345:respawn:", "#2:2345:respawn:");
536 replace("/harddisk/etc/inittab", "3:2345:respawn:", "#3:2345:respawn:");
537 replace("/harddisk/etc/inittab", "4:2345:respawn:", "#4:2345:respawn:");
538 replace("/harddisk/etc/inittab", "5:2345:respawn:", "#5:2345:respawn:");
539 replace("/harddisk/etc/inittab", "6:2345:respawn:", "#6:2345:respawn:");
540 replace("/harddisk/etc/inittab", "#7:2345:respawn:", "7:2345:respawn:");
543 /* Set marker that the user has already accepted the gpl */
544 mysystem("/usr/bin/touch /harddisk/var/ipfire/main/gpl_accepted");
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
, "/usr/bin/eject /dev/%s", sourcedrive
);
556 mysystem(commandstring
);
559 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
561 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_PRESS_OK_TO_REBOOT
], 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 // Remove Setup autorun after boot
593 if (system("rm -f /harddisk/etc/rc.d/rcsysinit.d/S75firstsetup"))
594 printf("Unable to disable setup autorun.\n");
597 if (system("/bin/umount /harddisk/proc"))
598 printf("Unable to umount /harddisk/proc.\n");
608 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
613 system("/bin/umount /harddisk/proc >/dev/null 2>&1");
614 system("/bin/umount /harddisk/dev >/dev/null 2>&1");
615 system("/bin/umount /harddisk/sys >/dev/null 2>&1");
617 system("/bin/umount /harddisk/var >/dev/null 2>&1");
618 system("/bin/umount /harddisk/boot >/dev/null 2>&1");
619 system("/bin/umount /harddisk >/dev/null 2>&1");