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 14400
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
43 int main(int argc
, char *argv
[])
46 char discl_msg
[40000] = "Disclaimer\n";
48 char *langnames
[] = { "Deutsch", "English", "Français", "Español", "Nederlands", "Polski", "Русский", "Türkçe", NULL
};
49 char *shortlangnames
[] = { "de", "en", "fr", "es", "nl", "pl", "ru", "tr", NULL
};
50 char **langtrs
[] = { de_tr
, en_tr
, fr_tr
, es_tr
, nl_tr
, pl_tr
, ru_tr
, tr_tr
, NULL
};
52 char harddrive
[30], sourcedrive
[5]; /* Device holder. */
53 char harddrive_info
[STRING_SIZE
]; /* Additional infos about target */
54 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
56 char commandstring
[STRING_SIZE
];
57 char mkfscommand
[STRING_SIZE
];
58 char *fstypes
[] = { "ext2", "ext3", "ext4", "ReiserFS", NULL
};
63 char shortlangname
[10];
65 char title
[STRING_SIZE
];
69 struct keyvalue
*ethernetkv
= initkeyvalues();
70 FILE *handle
, *cmdfile
, *copying
;
71 char line
[STRING_SIZE
];
72 char string
[STRING_SIZE
];
73 long memory
= 0, disk
= 0, free
;
74 long system_partition
, boot_partition
, root_partition
, swap_file
;
76 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
79 int serialconsole
= 0;
80 struct keyvalue
*unattendedkv
= initkeyvalues();
82 char restore_file
[STRING_SIZE
] = "";
84 setlocale (LC_ALL
, "");
85 sethostname( SNAME
, 10);
87 memset(&hdparams
, 0, sizeof(struct devparams
));
88 memset(&cdromparams
, 0, sizeof(struct devparams
));
90 /* Log file/terminal stuff. */
93 if (!(flog
= fopen(argv
[1], "w+")))
101 fprintf(flog
, "Install program started.\n");
106 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
107 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
109 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
111 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
113 fgets(line
, STRING_SIZE
, cmdfile
);
115 // check if we have to make an unattended install
116 if (strstr (line
, "unattended") != NULL
) {
118 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
120 // check if we have to patch for serial console
121 if (strstr (line
, "console=ttyS0") != NULL
) {
126 // Load common modules
127 mysystem("/sbin/modprobe iso9660"); // CDROM
128 // mysystem("/sbin/modprobe ext2"); // Boot patition
129 mysystem("/sbin/modprobe vfat"); // USB key
131 /* German is the default */
132 for (choice
= 0; langnames
[choice
]; choice
++)
134 if (strcmp(langnames
[choice
], "English") == 0)
137 if (!langnames
[choice
])
141 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
142 langnames
, &choice
, "Ok", NULL
);
145 ctr
= langtrs
[choice
];
146 strcpy(shortlangname
, shortlangnames
[choice
]);
148 newtPushHelpLine(ctr
[TR_HELPLINE
]);
151 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
152 newtWinMessage(title
, ctr
[TR_OK
], message
);
155 mysystem("/bin/mountsource.sh");
157 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
158 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_NO_LOCAL_SOURCE
]);
159 runcommandwithstatus("/bin/downloadsource.sh",ctr
[TR_DOWNLOADING_ISO
]);
160 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
161 errorbox(ctr
[TR_DOWNLOAD_ERROR
]);
166 fgets(sourcedrive
, 5, handle
);
167 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
171 // Read the license file.
172 if (!(copying
= fopen(LICENSE_FILE
, "r"))) {
173 sprintf(discl_msg
, "Could not open license file: %s\n", LICENSE_FILE
);
174 fprintf(flog
, discl_msg
);
176 fread(discl_msg
, 1, 40000, copying
);
179 if (disclaimerbox(discl_msg
)==0) {
180 errorbox(ctr
[TR_LICENSE_NOT_ACCEPTED
]);
189 fprintf(flog
, "Harddisk scan pass %i\n", i
);
191 switch (mysystem("/bin/mountdest.sh") % 255) {
192 case 0: // Found IDE disk
197 case 1: // Found SCSI disk
202 case 2: // Found RAID disk
207 case 10: // No harddisk found
208 errorbox(ctr
[TR_NO_HARDDISK
]);
213 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
214 errorbox(ctr
[TR_NO_HARDDISK
]);
217 fgets(harddrive
, 30, handle
);
219 if ((handle
= fopen("/tmp/dest_device_info", "r")) == NULL
) {
220 sprintf(harddrive_info
, "%s", harddrive
);
222 fgets(harddrive_info
, 70, handle
);
226 /* load unattended configuration */
228 fprintf(flog
, "unattended: Reading unattended.conf\n");
230 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
231 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
234 /* Make the hdparms struct and print the contents.
235 With USB-KEY install and SCSI disk, while installing, the disk
236 is named 'sdb,sdc,...' (following keys)
237 On reboot, it will become 'sda'
238 To avoid many test, all names are built in the struct.
240 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
241 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
242 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
243 /* Now the names after the machine is booted. Only scsi is affected
244 and we only install on the first scsi disk. */
246 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
248 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], harddrive_info
);
252 yesnoharddisk
[0] = ctr
[TR_NO
];
253 yesnoharddisk
[1] = ctr
[TR_YES
];
254 yesnoharddisk
[2] = NULL
;
258 rc
= newtWinMenu(title
, message
,
259 50, 5, 5, 6, yesnoharddisk
,
261 ctr
[TR_CANCEL
], NULL
);
268 fstypes
[0]=ctr
[TR_EXT2FS_DESCR
];
269 fstypes
[1]=ctr
[TR_EXT3FS_DESCR
];
270 fstypes
[2]=ctr
[TR_EXT4FS_DESCR
];
271 fstypes
[3]=ctr
[TR_REISERFS_DESCR
];
275 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
276 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
277 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
278 ctr
[TR_CANCEL
], NULL
);
286 /* Calculate amount of memory in machine */
287 if ((handle
= fopen("/proc/meminfo", "r")))
289 while (fgets(line
, STRING_SIZE
-1, handle
)) {
290 if (sscanf (line
, "MemTotal: %s kB", string
)) {
291 memory
= atoi(string
) / 1024 ;
297 /* Partition, mkswp, mkfs.
298 * before partitioning, first determine the sizes of each
299 * partition. In order to do that we need to know the size of
302 /* Don't use mysystem here so we can redirect output */
303 sprintf(commandstring
, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
304 system(commandstring
);
306 /* Calculate amount of disk space */
307 if ((handle
= fopen("/tmp/disksize", "r"))) {
308 fgets(line
, STRING_SIZE
-1, handle
);
309 if (sscanf (line
, "%s", string
)) {
310 disk
= atoi(string
) / 1024;
315 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
317 /* Calculating Swap-Size dependend of Ram Size */
320 else if (memory
<= 1024 && memory
> 256)
323 swap_file
= memory
/ 4;
325 /* Calculating Root-Size dependend of Max Disk Space */
327 root_partition
= 200;
328 else if ( disk
>= 756 && disk
<= 3072 )
329 root_partition
= 512;
331 root_partition
= 2048;
334 /* Calculating the amount of free space */
335 boot_partition
= 64; /* in MB */
336 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
338 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
339 boot_partition
, swap_file
, system_partition
, root_partition
);
342 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
343 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
346 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
347 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
350 fprintf(flog
, "Disk is too small.\n");
351 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
354 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
358 fprintf(flog
, "Disk is too small.\n");
359 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
362 handle
= fopen("/tmp/partitiontable", "w");
366 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
367 boot_partition
, swap_file
, root_partition
);
369 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
370 boot_partition
, root_partition
);
375 snprintf(commandstring
, STRING_SIZE
, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
376 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
378 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
382 if (fstype
== EXT2
) {
383 // mysystem("/sbin/modprobe ext2");
384 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2");
385 } else if (fstype
== REISERFS
) {
386 mysystem("/sbin/modprobe reiserfs");
387 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
388 } else if (fstype
== EXT3
) {
389 // mysystem("/sbin/modprobe ext3");
390 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3");
391 } else if (fstype
== EXT4
) {
392 // mysystem("/sbin/modprobe ext4");
393 sprintf(mkfscommand
, "/sbin/mke2fs -T ext4");
396 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams
.devnode_part
);
397 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
399 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
404 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
405 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
407 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
412 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
413 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
415 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
419 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
420 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
422 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
426 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
427 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
429 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
433 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
434 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
435 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
436 mkdir("/harddisk/var/run", S_IRWXU
|S_IRWXG
|S_IRWXO
);
438 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
439 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
441 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
445 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
446 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
448 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
452 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
453 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
455 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
459 snprintf(commandstring
, STRING_SIZE
,
460 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma 2>/dev/null");
462 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
463 ctr
[TR_INSTALLING_FILES
]))
465 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
469 /* Save language und local settings */
470 write_lang_configs(shortlangname
);
472 /* mount proc filesystem */
473 mysystem("mkdir /harddisk/proc");
474 mysystem("/bin/mount --bind /proc /harddisk/proc");
475 mysystem("/bin/mount --bind /dev /harddisk/dev");
476 mysystem("/bin/mount --bind /sys /harddisk/sys");
478 /* Build cache lang file */
479 snprintf(commandstring
, STRING_SIZE
, "/usr/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
480 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
482 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
486 /* Update /etc/fstab */
487 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
);
488 system(commandstring
);
489 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
);
490 system(commandstring
);
491 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
);
492 system(commandstring
);
493 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
);
494 system(commandstring
);
496 if (fstype
== EXT2
) {
497 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
498 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
499 } else if (fstype
== REISERFS
) {
500 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
501 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
502 } else if (fstype
== EXT3
) {
503 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
504 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
505 } else if (fstype
== EXT4
) {
506 replace("/harddisk/etc/fstab", "FSTYPE", "ext4");
507 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
510 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
512 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
);
513 system(commandstring
);
515 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
517 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
520 * Generate device.map to help grub finding the device to install itself on.
523 if (f
= fopen("/harddisk/boot/grub/device.map", "w")) {
524 fprintf(f
, "(hd0) %s\n", hdparams
.devnode_disk
);
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 /* Serial console ? */
538 replace("/harddisk/boot/grub/grub.conf", "splashimage", "#splashimage");
539 replace("/harddisk/boot/grub/grub.conf", "#serial", "serial");
540 replace("/harddisk/boot/grub/grub.conf", "#terminal", "terminal");
541 replace("/harddisk/boot/grub/grub.conf", " panic=10 ", " console=ttyS0,38400n8 panic=10 ");
544 replace("/harddisk/etc/inittab", "1:2345:respawn:", "#1:2345:respawn:");
545 replace("/harddisk/etc/inittab", "2:2345:respawn:", "#2:2345:respawn:");
546 replace("/harddisk/etc/inittab", "3:2345:respawn:", "#3:2345:respawn:");
547 replace("/harddisk/etc/inittab", "4:2345:respawn:", "#4:2345:respawn:");
548 replace("/harddisk/etc/inittab", "5:2345:respawn:", "#5:2345:respawn:");
549 replace("/harddisk/etc/inittab", "6:2345:respawn:", "#6:2345:respawn:");
550 replace("/harddisk/etc/inittab", "#7:2345:respawn:", "7:2345:respawn:");
553 /* Set marker that the user has already accepted the gpl */
554 mysystem("/usr/bin/touch /harddisk/var/ipfire/main/gpl_accepted");
556 /* Copy restore file from cdrom */
557 if (unattended
&& (strlen(restore_file
) > 0)) {
558 fprintf(flog
, "unattended: Copy restore file\n");
559 snprintf(commandstring
, STRING_SIZE
,
560 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
561 mysystem(commandstring
);
564 mysystem("umount /cdrom");
565 snprintf(commandstring
, STRING_SIZE
, "/usr/bin/eject /dev/%s", sourcedrive
);
566 mysystem(commandstring
);
569 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
571 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_PRESS_OK_TO_REBOOT
], message
);
577 fprintf(flog
, "Install program ended.\n");
580 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
582 freekeyvalues(ethernetkv
);
584 if (allok
&& !allok_fastexit
)
587 fprintf(flog
, "Entering unattended setup\n");
588 if (unattended_setup(unattendedkv
)) {
589 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
590 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
592 errorbox("Unattended setup failed.");
601 if (system("/bin/umount /harddisk/proc"))
602 printf("Unable to umount /harddisk/proc.\n");
612 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
617 system("/bin/umount /harddisk/proc >/dev/null 2>&1");
618 system("/bin/umount /harddisk/dev >/dev/null 2>&1");
619 system("/bin/umount /harddisk/sys >/dev/null 2>&1");
621 system("/bin/umount /harddisk/var >/dev/null 2>&1");
622 system("/bin/umount /harddisk/boot >/dev/null 2>&1");
623 system("/bin/umount /harddisk >/dev/null 2>&1");