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 8400
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
37 int main(int argc
, char *argv
[])
40 char discl_msg
[40000] = "Disclaimer\n";
42 char *langnames
[] = { "Deutsch", "English", "Français", "Español", NULL
};
43 char *shortlangnames
[] = { "de", "en", "fr", "es", NULL
};
44 char **langtrs
[] = { de_tr
, en_tr
, fr_tr
, es_tr
, NULL
};
46 char harddrive
[30], sourcedrive
[5]; /* Device holder. */
47 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
49 char commandstring
[STRING_SIZE
];
50 char mkfscommand
[STRING_SIZE
];
51 char *fstypes
[] = { "ext2", "ext3", "ext4", "ReiserFS", NULL
};
57 char shortlangname
[10];
59 char title
[STRING_SIZE
];
63 struct keyvalue
*ethernetkv
= initkeyvalues();
64 FILE *handle
, *cmdfile
, *copying
;
65 char line
[STRING_SIZE
];
66 char string
[STRING_SIZE
];
67 long memory
= 0, disk
= 0, free
;
68 long system_partition
, boot_partition
, root_partition
, swap_file
;
70 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
73 int serialconsole
= 0;
74 struct keyvalue
*unattendedkv
= initkeyvalues();
76 char restore_file
[STRING_SIZE
] = "";
78 setlocale (LC_ALL
, "");
79 sethostname( SNAME
, 10);
81 memset(&hdparams
, 0, sizeof(struct devparams
));
82 memset(&cdromparams
, 0, sizeof(struct devparams
));
84 /* Log file/terminal stuff. */
87 if (!(flog
= fopen(argv
[1], "w+")))
95 fprintf(flog
, "Install program started.\n");
100 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
101 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
103 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
105 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
107 fgets(line
, STRING_SIZE
, cmdfile
);
109 // check if we have to make an unattended install
110 if (strstr (line
, "unattended") != NULL
) {
112 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
114 // check if we have to patch for serial console
115 if (strstr (line
, "console=ttyS0") != NULL
) {
121 if (! (copying
= fopen("/COPYING", "r")))
123 fprintf(flog
, "Couldn't open gpl (/COPYING)\n");
124 sprintf(discl_msg
, "Couldn't open gpl (/COPYING)\n");
126 fread(discl_msg
, 1, 40000, copying
);
130 // Load common modules
131 mysystem("/sbin/modprobe iso9660"); // CDROM
132 mysystem("/sbin/modprobe ext2"); // Boot patition
133 mysystem("/sbin/modprobe vfat"); // USB key
135 /* German is the default */
136 for (choice
= 0; langnames
[choice
]; choice
++)
138 if (strcmp(langnames
[choice
], "Deutsch") == 0)
141 if (!langnames
[choice
])
145 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
146 langnames
, &choice
, "Ok", NULL
);
149 ctr
= langtrs
[choice
];
150 strcpy(shortlangname
, shortlangnames
[choice
]);
152 newtPushHelpLine(ctr
[TR_HELPLINE
]);
154 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
155 newtWinMessage(title
, ctr
[TR_OK
], message
);
158 if (disclaimerbox(discl_msg
)==0) {
159 errorbox(ctr
[TR_LICENSE_NOT_ACCEPTED
]);
164 mysystem("/bin/mountsource.sh");
166 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
167 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_NO_LOCAL_SOURCE
]);
168 runcommandwithstatus("/bin/downloadsource.sh",ctr
[TR_DOWNLOADING_ISO
]);
169 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
170 errorbox(ctr
[TR_DOWNLOAD_ERROR
]);
175 fgets(sourcedrive
, 5, handle
);
176 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
182 fprintf(flog
, "Harddisk scan pass %i\n", i
);
184 switch (mysystem("/bin/mountdest.sh") % 255) {
185 case 0: // Found IDE disk
190 case 1: // Found SCSI disk
195 case 2: // Found RAID disk
200 case 10: // No harddisk found
202 errorbox(ctr
[TR_NO_HARDDISK
]);
205 // Do this if the kudzu-scan fails...
206 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
211 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
212 errorbox(ctr
[TR_NO_HARDDISK
]);
215 fgets(harddrive
, 30, handle
);
218 /* load unattended configuration */
220 fprintf(flog
, "unattended: Reading unattended.conf\n");
222 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
223 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
226 /* Make the hdparms struct and print the contents.
227 With USB-KEY install and SCSI disk, while installing, the disk
228 is named 'sdb,sdc,...' (following keys)
229 On reboot, it will become 'sda'
230 To avoid many test, all names are built in the struct.
232 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
233 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
234 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
235 /* Now the names after the machine is booted. Only scsi is affected
236 and we only install on the first scsi disk. */
238 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
240 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
244 yesnoharddisk
[0] = ctr
[TR_NO
];
245 yesnoharddisk
[1] = ctr
[TR_YES
];
246 yesnoharddisk
[2] = NULL
;
250 rc
= newtWinMenu(title
, message
,
251 50, 5, 5, 6, yesnoharddisk
,
253 ctr
[TR_CANCEL
], NULL
);
260 fstypes
[0]=ctr
[TR_EXT2FS_DESCR
];
261 fstypes
[1]=ctr
[TR_EXT3FS_DESCR
];
262 fstypes
[2]=ctr
[TR_EXT4FS_DESCR
];
263 fstypes
[3]=ctr
[TR_REISERFS_DESCR
];
267 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
268 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
269 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
270 ctr
[TR_CANCEL
], NULL
);
278 /* Calculate amount of memory in machine */
279 if ((handle
= fopen("/proc/meminfo", "r")))
281 while (fgets(line
, STRING_SIZE
-1, handle
)) {
282 if (sscanf (line
, "MemTotal: %s kB", string
)) {
283 memory
= atoi(string
) / 1024 ;
289 /* Partition, mkswp, mkfs.
290 * before partitioning, first determine the sizes of each
291 * partition. In order to do that we need to know the size of
294 /* Don't use mysystem here so we can redirect output */
295 sprintf(commandstring
, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
296 system(commandstring
);
298 /* Calculate amount of disk space */
299 if ((handle
= fopen("/tmp/disksize", "r"))) {
300 fgets(line
, STRING_SIZE
-1, handle
);
301 if (sscanf (line
, "%s", string
)) {
302 disk
= atoi(string
) / 1024;
307 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
309 /* Calculating Swap-Size dependend of Ram Size */
312 else if (memory
<= 1024 && memory
> 256)
315 swap_file
= memory
/ 4;
317 /* Calculating Root-Size dependend of Max Disk Space */
319 root_partition
= 200;
320 else if ( disk
>= 756 && disk
<= 3072 )
321 root_partition
= 512;
323 root_partition
= 2048;
326 /* Calculating the amount of free space */
327 boot_partition
= 20; /* in MB */
328 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
330 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
331 boot_partition
, swap_file
, system_partition
, root_partition
);
334 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
335 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
338 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
339 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
342 fprintf(flog
, "Disk is too small.\n");
343 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
346 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
350 fprintf(flog
, "Disk is too small.\n");
351 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
354 handle
= fopen("/tmp/partitiontable", "w");
358 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
359 boot_partition
, swap_file
, root_partition
);
361 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
362 boot_partition
, root_partition
);
367 snprintf(commandstring
, STRING_SIZE
, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
368 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
370 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
374 if (fstype
== EXT2
) {
375 mysystem("/sbin/modprobe ext2");
376 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2");
377 } else if (fstype
== REISERFS
) {
378 mysystem("/sbin/modprobe reiserfs");
379 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
380 } else if (fstype
== EXT3
) {
381 mysystem("/sbin/modprobe ext3");
382 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3");
383 } else if (fstype
== EXT4
) {
384 mysystem("/sbin/modprobe ext4");
385 sprintf(mkfscommand
, "/sbin/mke2fs -T ext4");
388 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams
.devnode_part
);
389 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
391 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
396 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
397 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
399 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
404 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
405 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
407 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
411 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
412 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
414 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
418 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
419 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
421 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
425 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
426 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
427 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
429 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
430 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
432 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
436 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
437 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
439 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
443 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
444 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
446 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
450 snprintf(commandstring
, STRING_SIZE
,
451 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma 2>/dev/null");
453 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
454 ctr
[TR_INSTALLING_FILES
]))
456 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
460 /* Save language und local settings */
461 write_lang_configs(shortlangname
);
464 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
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");