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 CDROM_INSTALL 0
16 #define DISK_INSTALL 2
17 #define INST_FILECOUNT 6000
18 #define UNATTENDED_CONF "/cdrom/boot/unattended.conf"
29 extern char url
[STRING_SIZE
];
31 struct nic nics
[20] = { { "" , "" , "" } }; // only defined for compile
32 struct knic knics
[20] = { { "" , "" , "" , "" } }; // only defined for compile
39 char line
[STRING_SIZE
];
42 if ((fd
= fopen("/proc/cpuinfo", "r")) == NULL
) {
45 while (fgets(line
, STRING_SIZE
, fd
) != NULL
) {
46 if (strstr(line
, "processor") == line
) {
51 return (cpu_count
> 1);
54 long calc_swapsize(long memory
, long disk
) {
65 long calc_rootsize(long free
, long max
) {
78 int main(int argc
, char *argv
[])
80 char *langnames
[] = { "Deutsch", "English", NULL
};
81 char *shortlangnames
[] = { "de", "en", NULL
};
82 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
84 char harddrive
[11], sourcedrive
[5]; /* Device holder. */
85 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
86 int cdmounted
= 0; /* Loop flag for inserting a cd. */
88 char commandstring
[STRING_SIZE
];
89 char *installtypes
[] = { "CDROM/USB", "HTTP/FTP", NULL
};
90 int installtype
= CDROM_INSTALL
;
91 char mkfscommand
[STRING_SIZE
];
92 char *fstypes
[] = { "Reiser4", "ReiserFS", "ext3", NULL
};
98 char shortlangname
[10];
100 char title
[STRING_SIZE
];
102 int allok_fastexit
=0;
104 struct keyvalue
*ethernetkv
= initkeyvalues();
105 FILE *handle
, *cmdfile
;
106 char line
[STRING_SIZE
];
107 char string
[STRING_SIZE
];
108 long maximum_free
= 0, current_free
;
110 long system_partition
, boot_partition
, root_partition
, swap_file
;
112 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
115 struct keyvalue
*unattendedkv
= initkeyvalues();
118 setlocale (LC_ALL
, "");
119 sethostname( SNAME
, 10);
121 memset(&hdparams
, 0, sizeof(struct devparams
));
122 memset(&cdromparams
, 0, sizeof(struct devparams
));
124 /* Log file/terminal stuff. */
127 if (!(flog
= fopen(argv
[1], "w+")))
135 fprintf(flog
, "Install program started.\n");
140 /* Do usb detection first for usb keyboard */
141 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
143 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
145 fgets(line
, STRING_SIZE
, cmdfile
);
146 if (strstr (line
, "noide") == NULL
) {
147 fprintf(flog
, "Initializing IDE controllers.\n");
150 fprintf(flog
, "Skipping IDE detection.\n");
152 if (strstr (line
, "nousb") == NULL
) {
153 fprintf(flog
, "Initializing USB controllers.\n");
156 fprintf(flog
, "Skipping USB detection.\n");
158 // check if we have to make an unattended install
159 if (strstr (line
, "unattended") != NULL
) {
162 // Loading the cdrom-filesystem
163 mysystem("/sbin/modprobe iso9660");
167 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
170 /* German is the default */
171 for (choice
= 0; langnames
[choice
]; choice
++)
173 if (strcmp(langnames
[choice
], "Deutsch") == 0)
176 if (!langnames
[choice
])
180 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
181 langnames
, &choice
, "Ok", NULL
);
184 ctr
= langtrs
[choice
];
185 strcpy(shortlangname
, shortlangnames
[choice
]);
186 fprintf(flog
, "Selected language: %s\n", shortlangname
);
188 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
189 newtPushHelpLine(ctr
[TR_HELPLINE
]);
190 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
193 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
194 newtWinMessage(title
, ctr
[TR_OK
], message
);
196 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
197 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
198 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
199 ctr
[TR_CANCEL
], NULL
);
202 installtype
= CDROM_INSTALL
;
208 // Starting hardware detection
209 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
212 if (installtype
== CDROM_INSTALL
) {
213 switch (mysystem("/bin/mountsource.sh")) {
215 installtype
= CDROM_INSTALL
;
219 installtype
= DISK_INSTALL
;
222 errorbox(ctr
[TR_NO_CDROM
]);
226 /* read source drive letter */
227 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
228 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
231 fgets(sourcedrive
, 5, handle
);
232 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
236 /* Configure the network now! */
237 if (installtype
== URL_INSTALL
) {
238 /* Network driver and params. */
239 if (!(networkmenu(ethernetkv
))) {
240 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
244 /* Check for ipfire-<VERSION>.tbz2 */
245 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
246 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
254 fprintf(flog
, "Harddisk scan pass %i\n", i
);
256 switch (mysystem("/bin/mountdest.sh") % 255) {
257 case 0: // Found IDE disk
262 case 1: // Found SCSI disk
267 case 2: // Found RAID disk
272 case 10: // No harddisk found
274 errorbox(ctr
[TR_NO_HARDDISK
]);
277 // Do this if the kudzu-scan fails...
278 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
283 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
284 errorbox(ctr
[TR_NO_HARDDISK
]);
287 fgets(harddrive
, 11, handle
);
290 /* load unattended configuration */
292 fprintf(flog
, "unattended: Reading unattended.conf\n");
294 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
297 /* Make the hdparms struct and print the contents.
298 With USB-KEY install and SCSI disk, while installing, the disk
299 is named 'sdb,sdc,...' (following keys)
300 On reboot, it will become 'sda'
301 To avoid many test, all names are built in the struct.
303 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
304 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
305 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
306 /* Now the names after the machine is booted. Only scsi is affected
307 and we only install on the first scsi disk. */
309 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
310 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
311 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
314 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
316 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
321 yesnoharddisk
[0] = ctr
[TR_NO
];
322 yesnoharddisk
[1] = ctr
[TR_YES
];
323 yesnoharddisk
[2] = NULL
;
326 rc
= newtWinMenu(title
, message
,
327 50, 5, 5, 6, yesnoharddisk
,
329 ctr
[TR_CANCEL
], NULL
);
337 sprintf(message
, "(TR) Bitte waehlen Sie ihr Dateisystem aus:");
338 rc
= newtWinMenu("(TR) Dateisystemauswahl", message
,
339 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
340 ctr
[TR_CANCEL
], NULL
);
343 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
348 /* Calculate amount of memory in machine */
349 if ((handle
= fopen("/proc/meminfo", "r")))
351 while (fgets(line
, STRING_SIZE
-1, handle
)) {
352 if (sscanf (line
, "MemTotal: %s kB", string
)) {
353 memory
= atoi(string
) / 1024 ;
359 /* Partition, mkswp, mkfs.
360 * before partitioning, first determine the sizes of each
361 * partition. In order to do that we need to know the size of
364 /* Don't use mysystem here so we can redirect output */
365 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
366 system(commandstring
);
368 /* Calculate amount of disk space */
369 if ((handle
= fopen("/tmp/disksize", "r"))) {
370 fgets(line
, STRING_SIZE
-1, handle
);
371 if (sscanf (line
, "%s", string
)) {
372 maximum_free
= atoi(string
) / 1024;
377 fprintf(flog
, "maximum_free = %ld, memory = %ld", maximum_free
, memory
);
379 swap_file
= calc_swapsize(memory
, maximum_free
);
381 if (maximum_free
< 768 + swap_file
) {
382 if (maximum_free
< 768) {
383 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
388 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
399 boot_partition
= 20; /* in MB */
400 current_free
= maximum_free
- boot_partition
- swap_file
;
402 if (current_free
< 768) {
403 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
407 root_partition
= calc_rootsize(current_free
, maximum_free
);
409 if (root_partition
== 0) {
410 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
413 current_free
= current_free
- root_partition
;
416 if (current_free
< 256) {
417 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
421 system_partition
= current_free
;
423 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
424 boot_partition
, swap_file
, system_partition
, root_partition
);
426 handle
= fopen("/tmp/partitiontable", "w");
430 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
431 boot_partition
, swap_file
, root_partition
);
433 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
434 boot_partition
, root_partition
);
439 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
440 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
442 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
446 if (fstype
== REISER4
) {
447 mysystem("/sbin/modprobe reiser4");
448 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
449 } else if (fstype
== REISERFS
) {
450 mysystem("/sbin/modprobe reiserfs");
451 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
452 } else if (fstype
== EXT3
) {
453 mysystem("/sbin/modprobe ext3");
454 sprintf(mkfscommand
, "/bin/mke2fs -T ext3 -c");
457 snprintf(commandstring
, STRING_SIZE
, "/bin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
458 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
460 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
465 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
466 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
468 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
473 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
474 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
476 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
480 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
481 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
483 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
487 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
488 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
490 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
494 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
495 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
496 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
498 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
499 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
501 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
505 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
506 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
508 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
512 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
513 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
515 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
519 if (installtype
== URL_INSTALL
) {
520 snprintf(commandstring
, STRING_SIZE
,
521 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
524 if (installtype
== CDROM_INSTALL
) {
525 snprintf(commandstring
, STRING_SIZE
,
526 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
529 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
530 ctr
[TR_INSTALLING_FILES
]))
532 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
536 /* Save USB controller type to modules.conf */
537 write_usb_modules_conf();
539 /* Save language und local settings */
540 write_lang_configs(shortlangname
);
542 /* touch the modules.dep files */
543 snprintf(commandstring
, STRING_SIZE
,
544 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
546 mysystem(commandstring
);
547 snprintf(commandstring
, STRING_SIZE
,
548 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
550 mysystem(commandstring
);
553 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
555 /* mount proc filesystem */
556 mysystem("mkdir /harddisk/proc");
557 mysystem("/bin/mount --bind /proc /harddisk/proc");
558 mysystem("/bin/mount --bind /dev /harddisk/dev");
559 mysystem("/bin/mount --bind /sys /harddisk/sys");
561 /* Build cache lang file */
562 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
563 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
565 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
569 /* Update /etc/fstab */
570 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
572 if (fstype
== REISER4
) {
573 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
574 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
575 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
576 } else if (fstype
== REISERFS
) {
577 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
578 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
579 } else if (fstype
== EXT3
) {
580 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
581 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
584 /* Going to make our initrd... */
585 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -v -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
586 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
587 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -v -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
588 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
590 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
591 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
592 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
594 /* restore permissions */
595 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
597 snprintf(commandstring
, STRING_SIZE
,
598 "/sbin/chroot /harddisk /boot/grub/grubbatch");
599 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
600 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
604 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
606 mysystem("umount /cdrom");
607 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
608 mysystem(commandstring
);
611 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
613 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
619 fprintf(flog
, "Install program ended.\n");
622 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
624 freekeyvalues(ethernetkv
);
626 if (allok
&& !allok_fastexit
)
629 fprintf(flog
, "Entering unattended setup\n");
630 if (unattended_setup(unattendedkv
)) {
631 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
632 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
634 errorbox("Unattended setup failed.");
644 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
645 printf("Unable to run setup.\n");
648 if (system("/bin/umount /harddisk/proc"))
649 printf("Unable to umount /harddisk/proc.\n");
659 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
664 system("/bin/umount /harddisk/proc");
665 system("/bin/umount /harddisk/dev");
666 system("/bin/umount /harddisk/sys");
668 system("/bin/umount /harddisk/var");
669 system("/bin/umount /harddisk/boot");
670 system("/bin/umount /harddisk");