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 10700
15 #define UNATTENDED_CONF "/cdrom/boot/unattended.conf"
27 extern char url
[STRING_SIZE
];
29 struct nic nics
[20] = { { "" , "" , "" } }; // only defined for compile
30 struct knic knics
[20] = { { "" , "" , "" , "" } }; // only defined for compile
38 int main(int argc
, char *argv
[])
41 char discl_msg
[40000] = "Disclaimer\n";
43 char *langnames
[] = { "Deutsch", "English", "Français", "Español", "Polski", NULL
};
44 char *shortlangnames
[] = { "de", "en", "fr", "es", "pl", NULL
};
45 char **langtrs
[] = { de_tr
, en_tr
, fr_tr
, es_tr
, pl_tr
, NULL
};
47 char harddrive
[30], sourcedrive
[5]; /* Device holder. */
48 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
50 char commandstring
[STRING_SIZE
];
51 char mkfscommand
[STRING_SIZE
];
52 char *fstypes
[] = { "ext2", "ext3", "ext4", "ReiserFS", NULL
};
58 char shortlangname
[10];
60 char title
[STRING_SIZE
];
64 struct keyvalue
*ethernetkv
= initkeyvalues();
65 FILE *handle
, *cmdfile
, *copying
;
66 char line
[STRING_SIZE
];
67 char string
[STRING_SIZE
];
68 long memory
= 0, disk
= 0, free
;
69 long system_partition
, boot_partition
, root_partition
, swap_file
;
71 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
74 int serialconsole
= 0;
75 struct keyvalue
*unattendedkv
= initkeyvalues();
77 char restore_file
[STRING_SIZE
] = "";
79 setlocale (LC_ALL
, "");
80 sethostname( SNAME
, 10);
82 memset(&hdparams
, 0, sizeof(struct devparams
));
83 memset(&cdromparams
, 0, sizeof(struct devparams
));
85 /* Log file/terminal stuff. */
88 if (!(flog
= fopen(argv
[1], "w+")))
96 fprintf(flog
, "Install program started.\n");
101 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
102 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
104 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
106 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
108 fgets(line
, STRING_SIZE
, cmdfile
);
110 // check if we have to make an unattended install
111 if (strstr (line
, "unattended") != NULL
) {
113 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
115 // check if we have to patch for serial console
116 if (strstr (line
, "console=ttyS0") != NULL
) {
122 if (! (copying
= fopen("/COPYING", "r")))
124 fprintf(flog
, "Couldn't open gpl (/COPYING)\n");
125 sprintf(discl_msg
, "Couldn't open gpl (/COPYING)\n");
127 fread(discl_msg
, 1, 40000, copying
);
131 // Load common modules
132 mysystem("/sbin/modprobe iso9660"); // CDROM
133 mysystem("/sbin/modprobe ext2"); // Boot patition
134 mysystem("/sbin/modprobe vfat"); // USB key
136 /* German is the default */
137 for (choice
= 0; langnames
[choice
]; choice
++)
139 if (strcmp(langnames
[choice
], "English") == 0)
142 if (!langnames
[choice
])
146 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
147 langnames
, &choice
, "Ok", NULL
);
150 ctr
= langtrs
[choice
];
151 strcpy(shortlangname
, shortlangnames
[choice
]);
153 newtPushHelpLine(ctr
[TR_HELPLINE
]);
156 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
157 newtWinMessage(title
, ctr
[TR_OK
], message
);
159 if (disclaimerbox(discl_msg
)==0) {
160 errorbox(ctr
[TR_LICENSE_NOT_ACCEPTED
]);
165 mysystem("/bin/mountsource.sh");
167 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
168 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_NO_LOCAL_SOURCE
]);
169 runcommandwithstatus("/bin/downloadsource.sh",ctr
[TR_DOWNLOADING_ISO
]);
170 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
171 errorbox(ctr
[TR_DOWNLOAD_ERROR
]);
176 fgets(sourcedrive
, 5, handle
);
177 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
183 fprintf(flog
, "Harddisk scan pass %i\n", i
);
185 switch (mysystem("/bin/mountdest.sh") % 255) {
186 case 0: // Found IDE disk
191 case 1: // Found SCSI disk
196 case 2: // Found RAID disk
201 case 10: // No harddisk found
203 errorbox(ctr
[TR_NO_HARDDISK
]);
206 // Do this if the kudzu-scan fails...
207 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
212 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
213 errorbox(ctr
[TR_NO_HARDDISK
]);
216 fgets(harddrive
, 30, handle
);
219 /* load unattended configuration */
221 fprintf(flog
, "unattended: Reading unattended.conf\n");
223 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
224 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
227 /* Make the hdparms struct and print the contents.
228 With USB-KEY install and SCSI disk, while installing, the disk
229 is named 'sdb,sdc,...' (following keys)
230 On reboot, it will become 'sda'
231 To avoid many test, all names are built in the struct.
233 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
234 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
235 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
236 /* Now the names after the machine is booted. Only scsi is affected
237 and we only install on the first scsi disk. */
239 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
241 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
245 yesnoharddisk
[0] = ctr
[TR_NO
];
246 yesnoharddisk
[1] = ctr
[TR_YES
];
247 yesnoharddisk
[2] = NULL
;
251 rc
= newtWinMenu(title
, message
,
252 50, 5, 5, 6, yesnoharddisk
,
254 ctr
[TR_CANCEL
], NULL
);
261 fstypes
[0]=ctr
[TR_EXT2FS_DESCR
];
262 fstypes
[1]=ctr
[TR_EXT3FS_DESCR
];
263 fstypes
[2]=ctr
[TR_EXT4FS_DESCR
];
264 fstypes
[3]=ctr
[TR_REISERFS_DESCR
];
268 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
269 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
270 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
271 ctr
[TR_CANCEL
], NULL
);
279 /* Calculate amount of memory in machine */
280 if ((handle
= fopen("/proc/meminfo", "r")))
282 while (fgets(line
, STRING_SIZE
-1, handle
)) {
283 if (sscanf (line
, "MemTotal: %s kB", string
)) {
284 memory
= atoi(string
) / 1024 ;
290 /* Partition, mkswp, mkfs.
291 * before partitioning, first determine the sizes of each
292 * partition. In order to do that we need to know the size of
295 /* Don't use mysystem here so we can redirect output */
296 sprintf(commandstring
, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
297 system(commandstring
);
299 /* Calculate amount of disk space */
300 if ((handle
= fopen("/tmp/disksize", "r"))) {
301 fgets(line
, STRING_SIZE
-1, handle
);
302 if (sscanf (line
, "%s", string
)) {
303 disk
= atoi(string
) / 1024;
308 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
310 /* Calculating Swap-Size dependend of Ram Size */
313 else if (memory
<= 1024 && memory
> 256)
316 swap_file
= memory
/ 4;
318 /* Calculating Root-Size dependend of Max Disk Space */
320 root_partition
= 200;
321 else if ( disk
>= 756 && disk
<= 3072 )
322 root_partition
= 512;
324 root_partition
= 2048;
327 /* Calculating the amount of free space */
328 boot_partition
= 20; /* in MB */
329 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
331 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
332 boot_partition
, swap_file
, system_partition
, root_partition
);
335 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
336 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
339 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
340 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
343 fprintf(flog
, "Disk is too small.\n");
344 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
347 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
351 fprintf(flog
, "Disk is too small.\n");
352 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
355 handle
= fopen("/tmp/partitiontable", "w");
359 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
360 boot_partition
, swap_file
, root_partition
);
362 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
363 boot_partition
, root_partition
);
368 snprintf(commandstring
, STRING_SIZE
, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
369 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
371 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
375 if (fstype
== EXT2
) {
376 mysystem("/sbin/modprobe ext2");
377 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2");
378 } else if (fstype
== REISERFS
) {
379 mysystem("/sbin/modprobe reiserfs");
380 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
381 } else if (fstype
== EXT3
) {
382 mysystem("/sbin/modprobe ext3");
383 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3");
384 } else if (fstype
== EXT4
) {
385 mysystem("/sbin/modprobe ext4");
386 sprintf(mkfscommand
, "/sbin/mke2fs -T ext4");
389 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams
.devnode_part
);
390 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
392 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
397 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
398 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
400 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
405 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
406 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
408 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
412 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
413 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
415 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
419 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
420 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
422 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
426 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
427 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
428 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
430 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
431 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
433 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
437 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
438 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
440 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
444 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
445 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
447 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
451 snprintf(commandstring
, STRING_SIZE
,
452 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma 2>/dev/null");
454 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
455 ctr
[TR_INSTALLING_FILES
]))
457 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
461 /* Save language und local settings */
462 write_lang_configs(shortlangname
);
465 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
467 /* mount proc filesystem */
468 mysystem("mkdir /harddisk/proc");
469 mysystem("/bin/mount --bind /proc /harddisk/proc");
470 mysystem("/bin/mount --bind /dev /harddisk/dev");
471 mysystem("/bin/mount --bind /sys /harddisk/sys");
473 /* Build cache lang file */
474 snprintf(commandstring
, STRING_SIZE
, "/usr/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
475 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
477 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
481 /* Update /etc/fstab */
482 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
);
483 system(commandstring
);
484 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
);
485 system(commandstring
);
486 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
);
487 system(commandstring
);
488 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
);
489 system(commandstring
);
491 if (fstype
== EXT2
) {
492 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
493 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
494 } else if (fstype
== REISERFS
) {
495 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
496 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
497 } else if (fstype
== EXT3
) {
498 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
499 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
500 } else if (fstype
== EXT4
) {
501 replace("/harddisk/etc/fstab", "FSTYPE", "ext4");
502 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
505 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
507 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
);
508 system(commandstring
);
510 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
512 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
514 snprintf(commandstring
, STRING_SIZE
,
515 "/usr/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
516 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
517 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
521 /* Serial console ? */
524 replace("/harddisk/boot/grub/grub.conf", "splashimage", "#splashimage");
525 replace("/harddisk/boot/grub/grub.conf", "#serial", "serial");
526 replace("/harddisk/boot/grub/grub.conf", "#terminal", "terminal");
527 replace("/harddisk/boot/grub/grub.conf", " panic=10 ", " console=ttyS0,38400n8 panic=10 ");
530 replace("/harddisk/etc/inittab", "1:2345:respawn:", "#1:2345:respawn:");
531 replace("/harddisk/etc/inittab", "2:2345:respawn:", "#2:2345:respawn:");
532 replace("/harddisk/etc/inittab", "3:2345:respawn:", "#3:2345:respawn:");
533 replace("/harddisk/etc/inittab", "4:2345:respawn:", "#4:2345:respawn:");
534 replace("/harddisk/etc/inittab", "5:2345:respawn:", "#5:2345:respawn:");
535 replace("/harddisk/etc/inittab", "6:2345:respawn:", "#6:2345:respawn:");
536 replace("/harddisk/etc/inittab", "#7:2345:respawn:", "7:2345:respawn:");
539 /* Set marker that the user has already accepted the gpl */
540 mysystem("/usr/bin/touch /harddisk/var/ipfire/main/gpl_accepted");
542 /* Copy restore file from cdrom */
543 if (unattended
&& (strlen(restore_file
) > 0)) {
544 fprintf(flog
, "unattended: Copy restore file\n");
545 snprintf(commandstring
, STRING_SIZE
,
546 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
547 mysystem(commandstring
);
550 mysystem("umount /cdrom");
551 snprintf(commandstring
, STRING_SIZE
, "/usr/bin/eject /dev/%s", sourcedrive
);
552 mysystem(commandstring
);
555 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
557 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_PRESS_OK_TO_REBOOT
], message
);
563 fprintf(flog
, "Install program ended.\n");
566 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
568 freekeyvalues(ethernetkv
);
570 if (allok
&& !allok_fastexit
)
573 fprintf(flog
, "Entering unattended setup\n");
574 if (unattended_setup(unattendedkv
)) {
575 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
576 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
578 errorbox("Unattended setup failed.");
588 // Remove Setup autorun after boot
589 if (system("rm -f /harddisk/etc/rc.d/rcsysinit.d/S75firstsetup"))
590 printf("Unable to disable setup autorun.\n");
593 if (system("/bin/umount /harddisk/proc"))
594 printf("Unable to umount /harddisk/proc.\n");
604 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
609 system("/bin/umount /harddisk/proc >/dev/null 2>&1");
610 system("/bin/umount /harddisk/dev >/dev/null 2>&1");
611 system("/bin/umount /harddisk/sys >/dev/null 2>&1");
613 system("/bin/umount /harddisk/var >/dev/null 2>&1");
614 system("/bin/umount /harddisk/boot >/dev/null 2>&1");
615 system("/bin/umount /harddisk >/dev/null 2>&1");