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"
28 extern char url
[STRING_SIZE
];
30 struct nic nics
[20] = { { "" , "" , "" } }; // only defined for compile
31 struct knic knics
[20] = { { "" , "" , "" , "" } }; // only defined for compile
40 int main(int argc
, char *argv
[])
43 char discl_msg
[40000] = "Disclaimer\n";
45 char *langnames
[] = { "Deutsch", "English", "Français", "Español", "Polski", "Русский", NULL
};
46 char *shortlangnames
[] = { "de", "en", "fr", "es", "pl", "ru", NULL
};
47 char **langtrs
[] = { de_tr
, en_tr
, fr_tr
, es_tr
, pl_tr
, ru_tr
, NULL
};
49 char harddrive
[30], sourcedrive
[5]; /* Device holder. */
50 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
52 char commandstring
[STRING_SIZE
];
53 char mkfscommand
[STRING_SIZE
];
54 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
) {
124 if (! (copying
= fopen("/COPYING", "r")))
126 fprintf(flog
, "Couldn't open gpl (/COPYING)\n");
127 sprintf(discl_msg
, "Couldn't open gpl (/COPYING)\n");
129 fread(discl_msg
, 1, 40000, copying
);
133 // Load common modules
134 mysystem("/sbin/modprobe iso9660"); // CDROM
135 // mysystem("/sbin/modprobe ext2"); // Boot patition
136 mysystem("/sbin/modprobe vfat"); // USB key
138 /* German is the default */
139 for (choice
= 0; langnames
[choice
]; choice
++)
141 if (strcmp(langnames
[choice
], "English") == 0)
144 if (!langnames
[choice
])
148 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
149 langnames
, &choice
, "Ok", NULL
);
152 ctr
= langtrs
[choice
];
153 strcpy(shortlangname
, shortlangnames
[choice
]);
155 newtPushHelpLine(ctr
[TR_HELPLINE
]);
158 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
159 newtWinMessage(title
, ctr
[TR_OK
], message
);
161 if (disclaimerbox(discl_msg
)==0) {
162 errorbox(ctr
[TR_LICENSE_NOT_ACCEPTED
]);
167 mysystem("/bin/mountsource.sh");
169 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
170 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_NO_LOCAL_SOURCE
]);
171 runcommandwithstatus("/bin/downloadsource.sh",ctr
[TR_DOWNLOADING_ISO
]);
172 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
173 errorbox(ctr
[TR_DOWNLOAD_ERROR
]);
178 fgets(sourcedrive
, 5, handle
);
179 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
185 fprintf(flog
, "Harddisk scan pass %i\n", i
);
187 switch (mysystem("/bin/mountdest.sh") % 255) {
188 case 0: // Found IDE disk
193 case 1: // Found SCSI disk
198 case 2: // Found RAID disk
203 case 10: // No harddisk found
205 errorbox(ctr
[TR_NO_HARDDISK
]);
208 // Do this if the kudzu-scan fails...
209 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
214 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
215 errorbox(ctr
[TR_NO_HARDDISK
]);
218 fgets(harddrive
, 30, handle
);
221 /* load unattended configuration */
223 fprintf(flog
, "unattended: Reading unattended.conf\n");
225 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
226 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
229 /* Make the hdparms struct and print the contents.
230 With USB-KEY install and SCSI disk, while installing, the disk
231 is named 'sdb,sdc,...' (following keys)
232 On reboot, it will become 'sda'
233 To avoid many test, all names are built in the struct.
235 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
236 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
237 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
238 /* Now the names after the machine is booted. Only scsi is affected
239 and we only install on the first scsi disk. */
241 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
243 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
247 yesnoharddisk
[0] = ctr
[TR_NO
];
248 yesnoharddisk
[1] = ctr
[TR_YES
];
249 yesnoharddisk
[2] = NULL
;
253 rc
= newtWinMenu(title
, message
,
254 50, 5, 5, 6, yesnoharddisk
,
256 ctr
[TR_CANCEL
], NULL
);
263 fstypes
[0]=ctr
[TR_EXT2FS_DESCR
];
264 fstypes
[1]=ctr
[TR_EXT3FS_DESCR
];
265 fstypes
[2]=ctr
[TR_EXT4FS_DESCR
];
266 fstypes
[3]=ctr
[TR_REISERFS_DESCR
];
270 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
271 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
272 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
273 ctr
[TR_CANCEL
], NULL
);
281 /* Calculate amount of memory in machine */
282 if ((handle
= fopen("/proc/meminfo", "r")))
284 while (fgets(line
, STRING_SIZE
-1, handle
)) {
285 if (sscanf (line
, "MemTotal: %s kB", string
)) {
286 memory
= atoi(string
) / 1024 ;
292 /* Partition, mkswp, mkfs.
293 * before partitioning, first determine the sizes of each
294 * partition. In order to do that we need to know the size of
297 /* Don't use mysystem here so we can redirect output */
298 sprintf(commandstring
, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
299 system(commandstring
);
301 /* Calculate amount of disk space */
302 if ((handle
= fopen("/tmp/disksize", "r"))) {
303 fgets(line
, STRING_SIZE
-1, handle
);
304 if (sscanf (line
, "%s", string
)) {
305 disk
= atoi(string
) / 1024;
310 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
312 /* Calculating Swap-Size dependend of Ram Size */
315 else if (memory
<= 1024 && memory
> 256)
318 swap_file
= memory
/ 4;
320 /* Calculating Root-Size dependend of Max Disk Space */
322 root_partition
= 200;
323 else if ( disk
>= 756 && disk
<= 3072 )
324 root_partition
= 512;
326 root_partition
= 2048;
329 /* Calculating the amount of free space */
330 boot_partition
= 20; /* in MB */
331 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
333 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
334 boot_partition
, swap_file
, system_partition
, root_partition
);
337 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
338 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
341 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
342 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
345 fprintf(flog
, "Disk is too small.\n");
346 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
349 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
353 fprintf(flog
, "Disk is too small.\n");
354 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
357 handle
= fopen("/tmp/partitiontable", "w");
361 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
362 boot_partition
, swap_file
, root_partition
);
364 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
365 boot_partition
, root_partition
);
370 snprintf(commandstring
, STRING_SIZE
, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
371 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
373 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
377 if (fstype
== EXT2
) {
378 // mysystem("/sbin/modprobe ext2");
379 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2");
380 } else if (fstype
== REISERFS
) {
381 mysystem("/sbin/modprobe reiserfs");
382 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
383 } else if (fstype
== EXT3
) {
384 // mysystem("/sbin/modprobe ext3");
385 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3");
386 } else if (fstype
== EXT4
) {
387 // mysystem("/sbin/modprobe ext4");
388 sprintf(mkfscommand
, "/sbin/mke2fs -T ext4");
391 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams
.devnode_part
);
392 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
394 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
399 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
400 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
402 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
407 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
408 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
410 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
414 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
415 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
417 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
421 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
422 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
424 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
428 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
429 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
430 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
432 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
433 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
435 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
439 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
440 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
442 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
446 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
447 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
449 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
453 snprintf(commandstring
, STRING_SIZE
,
454 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma 2>/dev/null");
456 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
457 ctr
[TR_INSTALLING_FILES
]))
459 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
463 /* Save language und local settings */
464 write_lang_configs(shortlangname
);
466 /* mount proc filesystem */
467 mysystem("mkdir /harddisk/proc");
468 mysystem("/bin/mount --bind /proc /harddisk/proc");
469 mysystem("/bin/mount --bind /dev /harddisk/dev");
470 mysystem("/bin/mount --bind /sys /harddisk/sys");
472 /* Build cache lang file */
473 snprintf(commandstring
, STRING_SIZE
, "/usr/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
474 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
476 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
480 /* Update /etc/fstab */
481 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
);
482 system(commandstring
);
483 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
);
484 system(commandstring
);
485 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
);
486 system(commandstring
);
487 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
);
488 system(commandstring
);
490 if (fstype
== EXT2
) {
491 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
492 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
493 } else if (fstype
== REISERFS
) {
494 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
495 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
496 } else if (fstype
== EXT3
) {
497 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
498 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
499 } else if (fstype
== EXT4
) {
500 replace("/harddisk/etc/fstab", "FSTYPE", "ext4");
501 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
504 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
506 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
);
507 system(commandstring
);
509 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
511 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
513 snprintf(commandstring
, STRING_SIZE
,
514 "/usr/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
515 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
516 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
520 /* Serial console ? */
523 replace("/harddisk/boot/grub/grub.conf", "splashimage", "#splashimage");
524 replace("/harddisk/boot/grub/grub.conf", "#serial", "serial");
525 replace("/harddisk/boot/grub/grub.conf", "#terminal", "terminal");
526 replace("/harddisk/boot/grub/grub.conf", " panic=10 ", " console=ttyS0,38400n8 panic=10 ");
529 replace("/harddisk/etc/inittab", "1:2345:respawn:", "#1:2345:respawn:");
530 replace("/harddisk/etc/inittab", "2:2345:respawn:", "#2:2345:respawn:");
531 replace("/harddisk/etc/inittab", "3:2345:respawn:", "#3:2345:respawn:");
532 replace("/harddisk/etc/inittab", "4:2345:respawn:", "#4:2345:respawn:");
533 replace("/harddisk/etc/inittab", "5:2345:respawn:", "#5:2345:respawn:");
534 replace("/harddisk/etc/inittab", "6:2345:respawn:", "#6:2345:respawn:");
535 replace("/harddisk/etc/inittab", "#7:2345:respawn:", "7:2345:respawn:");
538 /* Set marker that the user has already accepted the gpl */
539 mysystem("/usr/bin/touch /harddisk/var/ipfire/main/gpl_accepted");
541 /* Copy restore file from cdrom */
542 if (unattended
&& (strlen(restore_file
) > 0)) {
543 fprintf(flog
, "unattended: Copy restore file\n");
544 snprintf(commandstring
, STRING_SIZE
,
545 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
546 mysystem(commandstring
);
549 mysystem("umount /cdrom");
550 snprintf(commandstring
, STRING_SIZE
, "/usr/bin/eject /dev/%s", sourcedrive
);
551 mysystem(commandstring
);
554 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
556 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_PRESS_OK_TO_REBOOT
], message
);
562 fprintf(flog
, "Install program ended.\n");
565 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
567 freekeyvalues(ethernetkv
);
569 if (allok
&& !allok_fastexit
)
572 fprintf(flog
, "Entering unattended setup\n");
573 if (unattended_setup(unattendedkv
)) {
574 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
575 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
577 errorbox("Unattended setup failed.");
587 // Remove Setup autorun after boot
588 if (system("rm -f /harddisk/etc/rc.d/rcsysinit.d/S75firstsetup"))
589 printf("Unable to disable setup autorun.\n");
592 if (system("/bin/umount /harddisk/proc"))
593 printf("Unable to umount /harddisk/proc.\n");
603 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
608 system("/bin/umount /harddisk/proc >/dev/null 2>&1");
609 system("/bin/umount /harddisk/dev >/dev/null 2>&1");
610 system("/bin/umount /harddisk/sys >/dev/null 2>&1");
612 system("/bin/umount /harddisk/var >/dev/null 2>&1");
613 system("/bin/umount /harddisk/boot >/dev/null 2>&1");
614 system("/bin/umount /harddisk >/dev/null 2>&1");