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
42 int main(int argc
, char *argv
[])
45 char discl_msg
[40000] = "Disclaimer\n";
47 char *langnames
[] = { "Deutsch", "English", "Français", "Español", "Nederlands", "Polski", "Русский", NULL
};
48 char *shortlangnames
[] = { "de", "en", "fr", "es", "nl", "pl", "ru", NULL
};
49 char **langtrs
[] = { de_tr
, en_tr
, fr_tr
, es_tr
, nl_tr
, pl_tr
, ru_tr
, NULL
};
51 char harddrive
[30], sourcedrive
[5]; /* Device holder. */
52 char harddrive_info
[STRING_SIZE
]; /* Additional infos about target */
53 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
55 char commandstring
[STRING_SIZE
];
56 char mkfscommand
[STRING_SIZE
];
57 char *fstypes
[] = { "ext2", "ext3", "ext4", "ReiserFS", NULL
};
62 char shortlangname
[10];
64 char title
[STRING_SIZE
];
68 struct keyvalue
*ethernetkv
= initkeyvalues();
69 FILE *handle
, *cmdfile
, *copying
;
70 char line
[STRING_SIZE
];
71 char string
[STRING_SIZE
];
72 long memory
= 0, disk
= 0, free
;
73 long system_partition
, boot_partition
, root_partition
, swap_file
;
75 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
78 int serialconsole
= 0;
79 struct keyvalue
*unattendedkv
= initkeyvalues();
81 char restore_file
[STRING_SIZE
] = "";
83 setlocale (LC_ALL
, "");
84 sethostname( SNAME
, 10);
86 memset(&hdparams
, 0, sizeof(struct devparams
));
87 memset(&cdromparams
, 0, sizeof(struct devparams
));
89 /* Log file/terminal stuff. */
92 if (!(flog
= fopen(argv
[1], "w+")))
100 fprintf(flog
, "Install program started.\n");
105 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
106 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
108 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
110 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
112 fgets(line
, STRING_SIZE
, cmdfile
);
114 // check if we have to make an unattended install
115 if (strstr (line
, "unattended") != NULL
) {
117 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
119 // check if we have to patch for serial console
120 if (strstr (line
, "console=ttyS0") != NULL
) {
125 // Load common modules
126 mysystem("/sbin/modprobe iso9660"); // CDROM
127 // mysystem("/sbin/modprobe ext2"); // Boot patition
128 mysystem("/sbin/modprobe vfat"); // USB key
130 /* German is the default */
131 for (choice
= 0; langnames
[choice
]; choice
++)
133 if (strcmp(langnames
[choice
], "English") == 0)
136 if (!langnames
[choice
])
140 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
141 langnames
, &choice
, "Ok", NULL
);
144 ctr
= langtrs
[choice
];
145 strcpy(shortlangname
, shortlangnames
[choice
]);
147 newtPushHelpLine(ctr
[TR_HELPLINE
]);
150 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
151 newtWinMessage(title
, ctr
[TR_OK
], message
);
154 mysystem("/bin/mountsource.sh");
156 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
157 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_NO_LOCAL_SOURCE
]);
158 runcommandwithstatus("/bin/downloadsource.sh",ctr
[TR_DOWNLOADING_ISO
]);
159 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
160 errorbox(ctr
[TR_DOWNLOAD_ERROR
]);
165 fgets(sourcedrive
, 5, handle
);
166 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
170 // Read the license file.
171 if (!(copying
= fopen(LICENSE_FILE
, "r"))) {
172 sprintf(discl_msg
, "Could not open license file: %s\n", LICENSE_FILE
);
173 fprintf(flog
, discl_msg
);
175 fread(discl_msg
, 1, 40000, copying
);
178 if (disclaimerbox(discl_msg
)==0) {
179 errorbox(ctr
[TR_LICENSE_NOT_ACCEPTED
]);
188 fprintf(flog
, "Harddisk scan pass %i\n", i
);
190 switch (mysystem("/bin/mountdest.sh") % 255) {
191 case 0: // Found IDE disk
196 case 1: // Found SCSI disk
201 case 2: // Found RAID disk
206 case 10: // No harddisk found
207 errorbox(ctr
[TR_NO_HARDDISK
]);
212 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
213 errorbox(ctr
[TR_NO_HARDDISK
]);
216 fgets(harddrive
, 30, handle
);
218 if ((handle
= fopen("/tmp/dest_device_info", "r")) == NULL
) {
219 sprintf(harddrive_info
, "%s", harddrive
);
221 fgets(harddrive_info
, 70, handle
);
225 /* load unattended configuration */
227 fprintf(flog
, "unattended: Reading unattended.conf\n");
229 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
230 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
233 /* Make the hdparms struct and print the contents.
234 With USB-KEY install and SCSI disk, while installing, the disk
235 is named 'sdb,sdc,...' (following keys)
236 On reboot, it will become 'sda'
237 To avoid many test, all names are built in the struct.
239 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
240 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
241 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
242 /* Now the names after the machine is booted. Only scsi is affected
243 and we only install on the first scsi disk. */
245 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
247 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], harddrive_info
);
251 yesnoharddisk
[0] = ctr
[TR_NO
];
252 yesnoharddisk
[1] = ctr
[TR_YES
];
253 yesnoharddisk
[2] = NULL
;
257 rc
= newtWinMenu(title
, message
,
258 50, 5, 5, 6, yesnoharddisk
,
260 ctr
[TR_CANCEL
], NULL
);
267 fstypes
[0]=ctr
[TR_EXT2FS_DESCR
];
268 fstypes
[1]=ctr
[TR_EXT3FS_DESCR
];
269 fstypes
[2]=ctr
[TR_EXT4FS_DESCR
];
270 fstypes
[3]=ctr
[TR_REISERFS_DESCR
];
274 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
275 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
276 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
277 ctr
[TR_CANCEL
], NULL
);
285 /* Calculate amount of memory in machine */
286 if ((handle
= fopen("/proc/meminfo", "r")))
288 while (fgets(line
, STRING_SIZE
-1, handle
)) {
289 if (sscanf (line
, "MemTotal: %s kB", string
)) {
290 memory
= atoi(string
) / 1024 ;
296 /* Partition, mkswp, mkfs.
297 * before partitioning, first determine the sizes of each
298 * partition. In order to do that we need to know the size of
301 /* Don't use mysystem here so we can redirect output */
302 sprintf(commandstring
, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
303 system(commandstring
);
305 /* Calculate amount of disk space */
306 if ((handle
= fopen("/tmp/disksize", "r"))) {
307 fgets(line
, STRING_SIZE
-1, handle
);
308 if (sscanf (line
, "%s", string
)) {
309 disk
= atoi(string
) / 1024;
314 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
316 /* Calculating Swap-Size dependend of Ram Size */
319 else if (memory
<= 1024 && memory
> 256)
322 swap_file
= memory
/ 4;
324 /* Calculating Root-Size dependend of Max Disk Space */
326 root_partition
= 200;
327 else if ( disk
>= 756 && disk
<= 3072 )
328 root_partition
= 512;
330 root_partition
= 2048;
333 /* Calculating the amount of free space */
334 boot_partition
= 64; /* in MB */
335 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
337 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
338 boot_partition
, swap_file
, system_partition
, root_partition
);
341 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
342 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
345 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
346 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
349 fprintf(flog
, "Disk is too small.\n");
350 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
353 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
357 fprintf(flog
, "Disk is too small.\n");
358 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
361 handle
= fopen("/tmp/partitiontable", "w");
365 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
366 boot_partition
, swap_file
, root_partition
);
368 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
369 boot_partition
, root_partition
);
374 snprintf(commandstring
, STRING_SIZE
, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
375 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
377 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
381 if (fstype
== EXT2
) {
382 // mysystem("/sbin/modprobe ext2");
383 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2");
384 } else if (fstype
== REISERFS
) {
385 mysystem("/sbin/modprobe reiserfs");
386 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
387 } else if (fstype
== EXT3
) {
388 // mysystem("/sbin/modprobe ext3");
389 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3");
390 } else if (fstype
== EXT4
) {
391 // mysystem("/sbin/modprobe ext4");
392 sprintf(mkfscommand
, "/sbin/mke2fs -T ext4");
395 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams
.devnode_part
);
396 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
398 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
403 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
404 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
406 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
411 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
412 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
414 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
418 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
419 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
421 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
425 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
426 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
428 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
432 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
433 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
434 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
436 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
437 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
439 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
443 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
444 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
446 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
450 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
451 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
453 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
457 snprintf(commandstring
, STRING_SIZE
,
458 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma 2>/dev/null");
460 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
461 ctr
[TR_INSTALLING_FILES
]))
463 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
467 /* Save language und local settings */
468 write_lang_configs(shortlangname
);
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
, "/usr/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 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
);
486 system(commandstring
);
487 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
);
488 system(commandstring
);
489 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
);
490 system(commandstring
);
491 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
);
492 system(commandstring
);
494 if (fstype
== EXT2
) {
495 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
496 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
497 } else if (fstype
== REISERFS
) {
498 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
499 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
500 } else if (fstype
== EXT3
) {
501 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
502 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
503 } else if (fstype
== EXT4
) {
504 replace("/harddisk/etc/fstab", "FSTYPE", "ext4");
505 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
508 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
510 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
);
511 system(commandstring
);
513 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
515 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
518 * Generate device.map to help grub finding the device to install itself on.
521 if (f
= fopen("/harddisk/boot/grub/device.map", "w")) {
522 fprintf(f
, "(hd0) %s\n", hdparams
.devnode_disk
);
526 snprintf(commandstring
, STRING_SIZE
,
527 "/usr/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
528 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
529 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
533 /* Serial console ? */
536 replace("/harddisk/boot/grub/grub.conf", "splashimage", "#splashimage");
537 replace("/harddisk/boot/grub/grub.conf", "#serial", "serial");
538 replace("/harddisk/boot/grub/grub.conf", "#terminal", "terminal");
539 replace("/harddisk/boot/grub/grub.conf", " panic=10 ", " console=ttyS0,38400n8 panic=10 ");
542 replace("/harddisk/etc/inittab", "1:2345:respawn:", "#1:2345:respawn:");
543 replace("/harddisk/etc/inittab", "2:2345:respawn:", "#2:2345:respawn:");
544 replace("/harddisk/etc/inittab", "3:2345:respawn:", "#3:2345:respawn:");
545 replace("/harddisk/etc/inittab", "4:2345:respawn:", "#4:2345:respawn:");
546 replace("/harddisk/etc/inittab", "5:2345:respawn:", "#5:2345:respawn:");
547 replace("/harddisk/etc/inittab", "6:2345:respawn:", "#6:2345:respawn:");
548 replace("/harddisk/etc/inittab", "#7:2345:respawn:", "7:2345:respawn:");
551 /* Set marker that the user has already accepted the gpl */
552 mysystem("/usr/bin/touch /harddisk/var/ipfire/main/gpl_accepted");
554 /* Copy restore file from cdrom */
555 if (unattended
&& (strlen(restore_file
) > 0)) {
556 fprintf(flog
, "unattended: Copy restore file\n");
557 snprintf(commandstring
, STRING_SIZE
,
558 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
559 mysystem(commandstring
);
562 mysystem("umount /cdrom");
563 snprintf(commandstring
, STRING_SIZE
, "/usr/bin/eject /dev/%s", sourcedrive
);
564 mysystem(commandstring
);
567 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
569 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_PRESS_OK_TO_REBOOT
], message
);
575 fprintf(flog
, "Install program ended.\n");
578 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
580 freekeyvalues(ethernetkv
);
582 if (allok
&& !allok_fastexit
)
585 fprintf(flog
, "Entering unattended setup\n");
586 if (unattended_setup(unattendedkv
)) {
587 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
588 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
590 errorbox("Unattended setup failed.");
599 if (system("/bin/umount /harddisk/proc"))
600 printf("Unable to umount /harddisk/proc.\n");
610 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
615 system("/bin/umount /harddisk/proc >/dev/null 2>&1");
616 system("/bin/umount /harddisk/dev >/dev/null 2>&1");
617 system("/bin/umount /harddisk/sys >/dev/null 2>&1");
619 system("/bin/umount /harddisk/var >/dev/null 2>&1");
620 system("/bin/umount /harddisk/boot >/dev/null 2>&1");
621 system("/bin/umount /harddisk >/dev/null 2>&1");