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 mysystem("/bin/mountsource.sh");
161 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
162 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_NO_LOCAL_SOURCE
]);
163 runcommandwithstatus("/bin/downloadsource.sh",ctr
[TR_DOWNLOADING_ISO
]);
164 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
165 errorbox(ctr
[TR_DOWNLOAD_ERROR
]);
170 fgets(sourcedrive
, 5, handle
);
171 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
177 fprintf(flog
, "Harddisk scan pass %i\n", i
);
179 switch (mysystem("/bin/mountdest.sh") % 255) {
180 case 0: // Found IDE disk
185 case 1: // Found SCSI disk
190 case 2: // Found RAID disk
195 case 10: // No harddisk found
197 errorbox(ctr
[TR_NO_HARDDISK
]);
200 // Do this if the kudzu-scan fails...
201 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
206 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
207 errorbox(ctr
[TR_NO_HARDDISK
]);
210 fgets(harddrive
, 30, handle
);
213 /* load unattended configuration */
215 fprintf(flog
, "unattended: Reading unattended.conf\n");
217 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
218 findkey(unattendedkv
, "RESTORE_FILE", restore_file
);
221 /* Make the hdparms struct and print the contents.
222 With USB-KEY install and SCSI disk, while installing, the disk
223 is named 'sdb,sdc,...' (following keys)
224 On reboot, it will become 'sda'
225 To avoid many test, all names are built in the struct.
227 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
228 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
229 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
230 /* Now the names after the machine is booted. Only scsi is affected
231 and we only install on the first scsi disk. */
233 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
235 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
239 yesnoharddisk
[0] = ctr
[TR_NO
];
240 yesnoharddisk
[1] = ctr
[TR_YES
];
241 yesnoharddisk
[2] = NULL
;
245 rc
= newtWinMenu(title
, message
,
246 50, 5, 5, 6, yesnoharddisk
,
248 ctr
[TR_CANCEL
], NULL
);
255 fstypes
[0]=ctr
[TR_EXT2FS_DESCR
];
256 fstypes
[1]=ctr
[TR_EXT3FS_DESCR
];
257 fstypes
[2]=ctr
[TR_EXT4FS_DESCR
];
258 fstypes
[3]=ctr
[TR_REISERFS_DESCR
];
262 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
263 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
264 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
265 ctr
[TR_CANCEL
], NULL
);
273 /* Calculate amount of memory in machine */
274 if ((handle
= fopen("/proc/meminfo", "r")))
276 while (fgets(line
, STRING_SIZE
-1, handle
)) {
277 if (sscanf (line
, "MemTotal: %s kB", string
)) {
278 memory
= atoi(string
) / 1024 ;
284 /* Partition, mkswp, mkfs.
285 * before partitioning, first determine the sizes of each
286 * partition. In order to do that we need to know the size of
289 /* Don't use mysystem here so we can redirect output */
290 sprintf(commandstring
, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
291 system(commandstring
);
293 /* Calculate amount of disk space */
294 if ((handle
= fopen("/tmp/disksize", "r"))) {
295 fgets(line
, STRING_SIZE
-1, handle
);
296 if (sscanf (line
, "%s", string
)) {
297 disk
= atoi(string
) / 1024;
302 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
304 /* Calculating Swap-Size dependend of Ram Size */
307 else if (memory
<= 1024 && memory
> 256)
310 swap_file
= memory
/ 4;
312 /* Calculating Root-Size dependend of Max Disk Space */
314 root_partition
= 200;
315 else if ( disk
>= 756 && disk
<= 3072 )
316 root_partition
= 512;
318 root_partition
= 2048;
321 /* Calculating the amount of free space */
322 boot_partition
= 20; /* in MB */
323 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
325 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
326 boot_partition
, swap_file
, system_partition
, root_partition
);
329 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
)) > 256)) ) {
330 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
333 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
334 fprintf(flog
, "Changing Swap Size to 0 MB.\n");
337 fprintf(flog
, "Disk is too small.\n");
338 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
341 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
345 fprintf(flog
, "Disk is too small.\n");
346 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
349 handle
= fopen("/tmp/partitiontable", "w");
353 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
354 boot_partition
, swap_file
, root_partition
);
356 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
357 boot_partition
, root_partition
);
362 snprintf(commandstring
, STRING_SIZE
, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
363 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
365 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
369 if (fstype
== EXT2
) {
370 mysystem("/sbin/modprobe ext2");
371 sprintf(mkfscommand
, "/sbin/mke2fs -T ext2");
372 } else if (fstype
== REISERFS
) {
373 mysystem("/sbin/modprobe reiserfs");
374 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
375 } else if (fstype
== EXT3
) {
376 mysystem("/sbin/modprobe ext3");
377 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3");
378 } else if (fstype
== EXT4
) {
379 mysystem("/sbin/modprobe ext4");
380 sprintf(mkfscommand
, "/sbin/mke2fs -T ext4");
383 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams
.devnode_part
);
384 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
386 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
391 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
392 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
394 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
399 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
400 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
402 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
406 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
407 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
409 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
413 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
414 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
416 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
420 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
421 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
422 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
424 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
425 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
427 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
431 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
432 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
434 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
438 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
439 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
441 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
445 snprintf(commandstring
, STRING_SIZE
,
446 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME
"-" VERSION
".tlz --lzma 2>/dev/null");
448 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
449 ctr
[TR_INSTALLING_FILES
]))
451 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
455 /* Save language und local settings */
456 write_lang_configs(shortlangname
);
459 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
461 /* mount proc filesystem */
462 mysystem("mkdir /harddisk/proc");
463 mysystem("/bin/mount --bind /proc /harddisk/proc");
464 mysystem("/bin/mount --bind /dev /harddisk/dev");
465 mysystem("/bin/mount --bind /sys /harddisk/sys");
467 /* Build cache lang file */
468 snprintf(commandstring
, STRING_SIZE
, "/usr/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
469 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
471 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
475 /* Update /etc/fstab */
476 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
);
477 system(commandstring
);
478 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
);
479 system(commandstring
);
480 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
);
481 system(commandstring
);
482 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
);
483 system(commandstring
);
485 if (fstype
== EXT2
) {
486 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
487 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
488 } else if (fstype
== REISERFS
) {
489 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
490 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
491 } else if (fstype
== EXT3
) {
492 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
493 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
494 } else if (fstype
== EXT4
) {
495 replace("/harddisk/etc/fstab", "FSTYPE", "ext4");
496 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
499 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION
);
501 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
);
502 system(commandstring
);
504 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
506 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
508 snprintf(commandstring
, STRING_SIZE
,
509 "/usr/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams
.devnode_disk
);
510 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
511 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
515 /* Copy restore file from cdrom */
516 if (unattended
&& (strlen(restore_file
) > 0)) {
517 fprintf(flog
, "unattended: Copy restore file\n");
518 snprintf(commandstring
, STRING_SIZE
,
519 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file
);
520 mysystem(commandstring
);
523 mysystem("umount /cdrom");
524 snprintf(commandstring
, STRING_SIZE
, "/usr/bin/eject /dev/%s", sourcedrive
);
525 mysystem(commandstring
);
528 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
530 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
536 fprintf(flog
, "Install program ended.\n");
539 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
541 freekeyvalues(ethernetkv
);
543 if (allok
&& !allok_fastexit
)
546 fprintf(flog
, "Entering unattended setup\n");
547 if (unattended_setup(unattendedkv
)) {
548 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
549 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
551 errorbox("Unattended setup failed.");
560 // if (!unattended) {
561 // if (system("/usr/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
562 // printf("Unable to run setup.\n");
565 if (system("/bin/umount /harddisk/proc"))
566 printf("Unable to umount /harddisk/proc.\n");
576 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
581 system("/bin/umount /harddisk/proc");
582 system("/bin/umount /harddisk/dev");
583 system("/bin/umount /harddisk/sys");
585 system("/bin/umount /harddisk/var");
586 system("/bin/umount /harddisk/boot");
587 system("/bin/umount /harddisk");