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 struct keyvalue
*unattendedkv
= initkeyvalues();
75 char restore_file
[STRING_SIZE
] = "";
77 setlocale (LC_ALL
, "");
78 sethostname( SNAME
, 10);
80 memset(&hdparams
, 0, sizeof(struct devparams
));
81 memset(&cdromparams
, 0, sizeof(struct devparams
));
83 /* Log file/terminal stuff. */
86 if (!(flog
= fopen(argv
[1], "w+")))
94 fprintf(flog
, "Install program started.\n");
99 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
100 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
102 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
104 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
106 fgets(line
, STRING_SIZE
, cmdfile
);
108 // check if we have to make an unattended install
109 if (strstr (line
, "unattended") != NULL
) {
111 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
116 if (! (copying
= fopen("/COPYING", "r")))
118 fprintf(flog
, "Couldn't open gpl (/COPYING)\n");
119 sprintf(discl_msg
, "Couldn't open gpl (/COPYING)\n");
121 fread(discl_msg
, 1, 40000, copying
);
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
], "Deutsch") == 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
]);
149 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
150 newtWinMessage(title
, ctr
[TR_OK
], message
);
153 if (disclaimerbox(discl_msg
)==0) {
154 errorbox(ctr
[TR_LICENSE_NOT_ACCEPTED
]);
159 switch (mysystem("/bin/mountsource.sh")) {
163 errorbox(ctr
[TR_NO_CDROM
]);
167 /* read source drive letter */
168 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
169 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
172 fgets(sourcedrive
, 5, handle
);
173 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
179 fprintf(flog
, "Harddisk scan pass %i\n", i
);
181 switch (mysystem("/bin/mountdest.sh") % 255) {
182 case 0: // Found IDE disk
187 case 1: // Found SCSI disk
192 case 2: // Found RAID disk
197 case 10: // No harddisk found
199 errorbox(ctr
[TR_NO_HARDDISK
]);
202 // Do this if the kudzu-scan fails...
203 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
208 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
209 errorbox(ctr
[TR_NO_HARDDISK
]);
212 fgets(harddrive
, 30, handle
);
215 /* load unattended configuration */
217 fprintf(flog
, "unattended: Reading unattended.conf\n");
219 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
220 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
223 /* Make the hdparms struct and print the contents.
224 With USB-KEY install and SCSI disk, while installing, the disk
225 is named 'sdb,sdc,...' (following keys)
226 On reboot, it will become 'sda'
227 To avoid many test, all names are built in the struct.
229 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
230 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
231 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
232 /* Now the names after the machine is booted. Only scsi is affected
233 and we only install on the first scsi disk. */
235 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
237 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
241 yesnoharddisk
[0] = ctr
[TR_NO
];
242 yesnoharddisk
[1] = ctr
[TR_YES
];
243 yesnoharddisk
[2] = NULL
;
247 rc
= newtWinMenu(title
, message
,
248 50, 5, 5, 6, yesnoharddisk
,
250 ctr
[TR_CANCEL
], NULL
);
257 fstypes
[0]=ctr
[TR_EXT2FS_DESCR
];
258 fstypes
[1]=ctr
[TR_EXT3FS_DESCR
];
259 fstypes
[2]=ctr
[TR_EXT4FS_DESCR
];
260 fstypes
[3]=ctr
[TR_REISERFS_DESCR
];
264 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
265 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
266 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
267 ctr
[TR_CANCEL
], NULL
);
275 /* Calculate amount of memory in machine */
276 if ((handle
= fopen("/proc/meminfo", "r")))
278 while (fgets(line
, STRING_SIZE
-1, handle
)) {
279 if (sscanf (line
, "MemTotal: %s kB", string
)) {
280 memory
= atoi(string
) / 1024 ;
286 /* Partition, mkswp, mkfs.
287 * before partitioning, first determine the sizes of each
288 * partition. In order to do that we need to know the size of
291 /* Don't use mysystem here so we can redirect output */
292 sprintf(commandstring
, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
293 system(commandstring
);
295 /* Calculate amount of disk space */
296 if ((handle
= fopen("/tmp/disksize", "r"))) {
297 fgets(line
, STRING_SIZE
-1, handle
);
298 if (sscanf (line
, "%s", string
)) {
299 disk
= atoi(string
) / 1024;
304 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
306 /* Calculating Swap-Size dependend of Ram Size */
309 else if (memory
<= 1024 && memory
> 256)
312 swap_file
= memory
/ 4;
314 /* Calculating Root-Size dependend of Max Disk Space */
316 root_partition
= 200;
317 else if ( disk
>= 756 && disk
<= 3072 )
318 root_partition
= 512;
320 root_partition
= 2048;
323 /* Calculating the amount of free space */
324 boot_partition
= 20; /* in MB */
325 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
327 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
328 boot_partition
, swap_file
, system_partition
, root_partition
);
331 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
332 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
335 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
336 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
339 fprintf(flog
, "Disk is too small.\n");
340 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
343 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
347 fprintf(flog
, "Disk is too small.\n");
348 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
351 handle
= fopen("/tmp/partitiontable", "w");
355 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
356 boot_partition
, swap_file
, root_partition
);
358 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
359 boot_partition
, root_partition
);
364 snprintf(commandstring
, STRING_SIZE
, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
365 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
367 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
371 if (fstype
== EXT2
) {
372 mysystem("/sbin/modprobe ext2");
373 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2");
374 } else if (fstype
== REISERFS
) {
375 mysystem("/sbin/modprobe reiserfs");
376 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
377 } else if (fstype
== EXT3
) {
378 mysystem("/sbin/modprobe ext3");
379 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3");
380 } else if (fstype
== EXT4
) {
381 mysystem("/sbin/modprobe ext4");
382 sprintf(mkfscommand
, "/sbin/mke2fs -T ext4");
385 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams
.devnode_part
);
386 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
388 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
393 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
394 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
396 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
401 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
402 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
404 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
408 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
409 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
411 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
415 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
416 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
418 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
422 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
423 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
424 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
426 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
427 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
429 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
433 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
434 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
436 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
440 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
441 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
443 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
447 snprintf(commandstring
, STRING_SIZE
,
448 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma 2>/dev/null");
450 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
451 ctr
[TR_INSTALLING_FILES
]))
453 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
457 /* Save language und local settings */
458 write_lang_configs(shortlangname
);
461 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
463 /* mount proc filesystem */
464 mysystem("mkdir /harddisk/proc");
465 mysystem("/bin/mount --bind /proc /harddisk/proc");
466 mysystem("/bin/mount --bind /dev /harddisk/dev");
467 mysystem("/bin/mount --bind /sys /harddisk/sys");
469 /* Build cache lang file */
470 snprintf(commandstring
, STRING_SIZE
, "/usr/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
471 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
473 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
477 /* Update /etc/fstab */
478 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
);
479 system(commandstring
);
480 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
);
481 system(commandstring
);
482 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
);
483 system(commandstring
);
484 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
);
485 system(commandstring
);
487 if (fstype
== EXT2
) {
488 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
489 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
490 } else if (fstype
== REISERFS
) {
491 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
492 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
493 } else if (fstype
== EXT3
) {
494 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
495 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
496 } else if (fstype
== EXT4
) {
497 replace("/harddisk/etc/fstab", "FSTYPE", "ext4");
498 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
501 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
503 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
);
504 system(commandstring
);
506 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
508 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
510 snprintf(commandstring
, STRING_SIZE
,
511 "/usr/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
512 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
513 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
517 /* Copy restore file from cdrom */
518 if (unattended
&& (strlen(restore_file
) > 0)) {
519 fprintf(flog
, "unattended: Copy restore file\n");
520 snprintf(commandstring
, STRING_SIZE
,
521 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
522 mysystem(commandstring
);
525 mysystem("umount /cdrom");
526 snprintf(commandstring
, STRING_SIZE
, "/usr/bin/eject /dev/%s", sourcedrive
);
527 mysystem(commandstring
);
530 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
532 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
538 fprintf(flog
, "Install program ended.\n");
541 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
543 freekeyvalues(ethernetkv
);
545 if (allok
&& !allok_fastexit
)
548 fprintf(flog
, "Entering unattended setup\n");
549 if (unattended_setup(unattendedkv
)) {
550 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
551 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
553 errorbox("Unattended setup failed.");
562 // if (!unattended) {
563 // if (system("/usr/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
564 // printf("Unable to run setup.\n");
567 if (system("/bin/umount /harddisk/proc"))
568 printf("Unable to umount /harddisk/proc.\n");
578 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
583 system("/bin/umount /harddisk/proc");
584 system("/bin/umount /harddisk/dev");
585 system("/bin/umount /harddisk/sys");
587 system("/bin/umount /harddisk/var");
588 system("/bin/umount /harddisk/boot");
589 system("/bin/umount /harddisk");