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 6200
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 int main(int argc
, char *argv
[])
56 char *langnames
[] = { "Deutsch", "English", NULL
};
57 char *shortlangnames
[] = { "de", "en", NULL
};
58 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
60 char harddrive
[11], sourcedrive
[5]; /* Device holder. */
61 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
62 int cdmounted
= 0; /* Loop flag for inserting a cd. */
64 char commandstring
[STRING_SIZE
];
65 char *installtypes
[] = { "CDROM/USB", "HTTP/FTP", NULL
};
66 int installtype
= CDROM_INSTALL
;
67 char mkfscommand
[STRING_SIZE
];
68 char *fstypes
[] = { "Reiser4", "ReiserFS", "ext3", NULL
};
74 char shortlangname
[10];
76 char title
[STRING_SIZE
];
80 struct keyvalue
*ethernetkv
= initkeyvalues();
81 FILE *handle
, *cmdfile
;
82 char line
[STRING_SIZE
];
83 char string
[STRING_SIZE
];
84 long memory
= 0, disk
= 0, free
;
85 long system_partition
, boot_partition
, root_partition
, swap_file
;
87 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
90 struct keyvalue
*unattendedkv
= initkeyvalues();
93 setlocale (LC_ALL
, "");
94 sethostname( SNAME
, 10);
96 memset(&hdparams
, 0, sizeof(struct devparams
));
97 memset(&cdromparams
, 0, sizeof(struct devparams
));
99 /* Log file/terminal stuff. */
102 if (!(flog
= fopen(argv
[1], "w+")))
110 fprintf(flog
, "Install program started.\n");
115 /* Do usb detection first for usb keyboard */
116 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
118 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
120 fgets(line
, STRING_SIZE
, cmdfile
);
122 // check if we have to make an unattended install
123 if (strstr (line
, "unattended") != NULL
) {
125 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
129 mysystem("/sbin/modprobe ide-generic");
130 mysystem("/sbin/modprobe generic");
131 mysystem("/sbin/modprobe ide-cd");
132 mysystem("/sbin/modprobe ide-disk");
133 mysystem("/sbin/modprobe uhci-hcd");
134 mysystem("/sbin/modprobe ohci-hcd");
135 mysystem("/sbin/modprobe ehci-hcd");
136 mysystem("/sbin/modprobe ohci1394");
137 mysystem("/sbin/modprobe sd_mod");
138 mysystem("/sbin/modprobe sr_mod");
139 mysystem("/sbin/modprobe usb-storage");
140 mysystem("/sbin/modprobe usbhid");
142 mysystem("/sbin/modprobe iso9660"); // CDROM
143 mysystem("/sbin/modprobe ext2"); // Boot patition
144 mysystem("/sbin/modprobe vfat"); // USB key
146 /* German is the default */
147 for (choice
= 0; langnames
[choice
]; choice
++)
149 if (strcmp(langnames
[choice
], "Deutsch") == 0)
152 if (!langnames
[choice
])
156 rc
= newtWinMenu("Language selection", "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
157 langnames
, &choice
, "Ok", NULL
);
160 ctr
= langtrs
[choice
];
161 strcpy(shortlangname
, shortlangnames
[choice
]);
163 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
164 newtPushHelpLine(ctr
[TR_HELPLINE
]);
165 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
167 // Starting hardware detection
168 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
171 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
172 newtWinMessage(title
, ctr
[TR_OK
], message
);
174 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
175 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
176 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
177 ctr
[TR_CANCEL
], NULL
);
180 installtype
= CDROM_INSTALL
;
187 if (installtype
== CDROM_INSTALL
) {
188 switch (mysystem("/bin/mountsource.sh")) {
190 installtype
= CDROM_INSTALL
;
194 installtype
= DISK_INSTALL
;
197 errorbox(ctr
[TR_NO_CDROM
]);
201 /* read source drive letter */
202 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
203 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
206 fgets(sourcedrive
, 5, handle
);
207 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
211 /* Configure the network now! */
212 if (installtype
== URL_INSTALL
) {
213 /* Network driver and params. */
214 if (!(networkmenu(ethernetkv
))) {
215 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
219 /* Check for ipfire-<VERSION>.tbz2 */
220 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
221 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
229 fprintf(flog
, "Harddisk scan pass %i\n", i
);
231 switch (mysystem("/bin/mountdest.sh") % 255) {
232 case 0: // Found IDE disk
237 case 1: // Found SCSI disk
242 case 2: // Found RAID disk
247 case 10: // No harddisk found
249 errorbox(ctr
[TR_NO_HARDDISK
]);
252 // Do this if the kudzu-scan fails...
253 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr
[TR_PROBING_HARDWARE
]);
258 if ((handle
= fopen("/tmp/dest_device", "r")) == NULL
) {
259 errorbox(ctr
[TR_NO_HARDDISK
]);
262 fgets(harddrive
, 11, handle
);
265 /* load unattended configuration */
267 fprintf(flog
, "unattended: Reading unattended.conf\n");
269 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
272 /* Make the hdparms struct and print the contents.
273 With USB-KEY install and SCSI disk, while installing, the disk
274 is named 'sdb,sdc,...' (following keys)
275 On reboot, it will become 'sda'
276 To avoid many test, all names are built in the struct.
278 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
279 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
280 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
281 /* Now the names after the machine is booted. Only scsi is affected
282 and we only install on the first scsi disk. */
284 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
285 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
286 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
289 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
291 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
295 yesnoharddisk
[0] = ctr
[TR_NO
];
296 yesnoharddisk
[1] = ctr
[TR_YES
];
297 yesnoharddisk
[2] = NULL
;
301 rc
= newtWinMenu(title
, message
,
302 50, 5, 5, 6, yesnoharddisk
,
304 ctr
[TR_CANCEL
], NULL
);
312 sprintf(message
, ctr
[TR_CHOOSE_FILESYSTEM
]);
313 rc
= newtWinMenu( ctr
[TR_CHOOSE_FILESYSTEM
], message
,
314 50, 5, 5, 6, fstypes
, &fstype
, ctr
[TR_OK
],
315 ctr
[TR_CANCEL
], NULL
);
318 fstype
= REISER4
; // Reiser4 is our standard filesystem. Love it or shut up!
323 /* Calculate amount of memory in machine */
324 if ((handle
= fopen("/proc/meminfo", "r")))
326 while (fgets(line
, STRING_SIZE
-1, handle
)) {
327 if (sscanf (line
, "MemTotal: %s kB", string
)) {
328 memory
= atoi(string
) / 1024 ;
334 /* Partition, mkswp, mkfs.
335 * before partitioning, first determine the sizes of each
336 * partition. In order to do that we need to know the size of
339 /* Don't use mysystem here so we can redirect output */
340 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
341 system(commandstring
);
343 /* Calculate amount of disk space */
344 if ((handle
= fopen("/tmp/disksize", "r"))) {
345 fgets(line
, STRING_SIZE
-1, handle
);
346 if (sscanf (line
, "%s", string
)) {
347 disk
= atoi(string
) / 1024;
352 fprintf(flog
, "Disksize = %ld, memory = %ld", disk
, memory
);
354 /* Calculating Swap-Size dependend of Ram Size */
357 else if (memory
>= 1024)
362 /* Calculating Root-Size dependend of Max Disk Space */
364 root_partition
= 256;
365 else if ( disk
>= 1024 && disk
<= 3072 )
366 root_partition
= 512;
368 root_partition
= 2048;
371 /* Calculating the amount of free space */
372 boot_partition
= 20; /* in MB */
373 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
375 fprintf(flog
, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
376 boot_partition
, swap_file
, system_partition
, root_partition
);
378 if ( (!unattended
) && (((disk
- (root_partition
+ swap_file
+ boot_partition
)) < 256 ) && ((disk
- (root_partition
+ boot_partition
+ 32 )) > 256)) ) {
379 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
382 system_partition
= disk
- ( root_partition
+ swap_file
+ boot_partition
);
383 fprintf(flog
, "Changing Swap Size to 32 MB.\n");
386 fprintf(flog
, "Disk is too small.\n");
387 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
390 else if (disk
- (root_partition
+ swap_file
+ boot_partition
) >= 256) {
394 fprintf(flog
, "Disk is too small.\n");
395 errorbox(ctr
[TR_DISK_TOO_SMALL
]);goto EXIT
;
398 handle
= fopen("/tmp/partitiontable", "w");
402 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
403 boot_partition
, swap_file
, root_partition
);
405 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
406 boot_partition
, root_partition
);
411 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
412 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
414 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
418 if (fstype
== REISER4
) {
419 mysystem("/sbin/modprobe reiser4");
420 sprintf(mkfscommand
, "/sbin/mkfs.reiser4 -y");
421 } else if (fstype
== REISERFS
) {
422 mysystem("/sbin/modprobe reiserfs");
423 sprintf(mkfscommand
, "/sbin/mkreiserfs -f");
424 } else if (fstype
== EXT3
) {
425 mysystem("/sbin/modprobe ext3");
426 sprintf(mkfscommand
, "/sbin/mke2fs -T ext3 -c");
429 snprintf(commandstring
, STRING_SIZE
, "/sbin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
430 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
432 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
437 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
438 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
440 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
445 snprintf(commandstring
, STRING_SIZE
, "%s %s3", mkfscommand
, hdparams
.devnode_part
);
446 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
448 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
452 snprintf(commandstring
, STRING_SIZE
, "%s %s4", mkfscommand
, hdparams
.devnode_part
);
453 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
455 errorbox(ctr
[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM
]);
459 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
460 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
462 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
466 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
467 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
468 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
470 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
471 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
473 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
477 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
478 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
480 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
484 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
485 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
487 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
491 if (installtype
== URL_INSTALL
) {
492 snprintf(commandstring
, STRING_SIZE
,
493 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
496 if (installtype
== CDROM_INSTALL
) {
497 snprintf(commandstring
, STRING_SIZE
,
498 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
501 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
502 ctr
[TR_INSTALLING_FILES
]))
504 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
508 /* Save language und local settings */
509 write_lang_configs(shortlangname
);
511 /* touch the modules.dep files */
512 snprintf(commandstring
, STRING_SIZE
,
513 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
515 mysystem(commandstring
);
516 snprintf(commandstring
, STRING_SIZE
,
517 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
519 mysystem(commandstring
);
522 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
524 /* mount proc filesystem */
525 mysystem("mkdir /harddisk/proc");
526 mysystem("/bin/mount --bind /proc /harddisk/proc");
527 mysystem("/bin/mount --bind /dev /harddisk/dev");
528 mysystem("/bin/mount --bind /sys /harddisk/sys");
530 /* Build cache lang file */
531 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
532 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
534 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
538 /* Update /etc/fstab */
539 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
541 if (fstype
== REISER4
) {
542 replace("/harddisk/etc/fstab", "FSTYPE", "reiser4");
543 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"reiser4 ");
544 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "rw");
545 } else if (fstype
== REISERFS
) {
546 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
547 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
548 } else if (fstype
== EXT3
) {
549 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s3", hdparams
.devnode_part
);
550 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
552 errorbox(ctr
[TR_JOURNAL_ERROR
]);
553 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
556 snprintf(commandstring
, STRING_SIZE
, "tune2fs -j %s4", hdparams
.devnode_part
);
557 if (runcommandwithstatus(commandstring
, ctr
[TR_JOURNAL_EXT3
]))
559 errorbox(ctr
[TR_JOURNAL_ERROR
]);
560 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
563 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
565 replace("/harddisk/etc/mkinitcpio.conf", "MODULES=\"", "MODULES=\"ext3 ");
566 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
569 /* Going to make our initrd... */
570 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd.img -k %s-ipfire", KERNEL_VERSION
);
571 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
572 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /sbin/mkinitcpio -g /boot/ipfirerd-smp.img -k %s-ipfire-smp", KERNEL_VERSION
);
573 runcommandwithstatus(commandstring
, ctr
[TR_BUILDING_INITRD
]);
575 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
576 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
577 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
579 /* restore permissions */
580 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
582 snprintf(commandstring
, STRING_SIZE
,
583 "/sbin/chroot /harddisk /boot/grub/grubbatch");
584 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
585 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
589 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
591 mysystem("umount /cdrom");
592 snprintf(commandstring
, STRING_SIZE
, "eject /dev/%s", sourcedrive
);
593 mysystem(commandstring
);
596 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
598 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
604 fprintf(flog
, "Install program ended.\n");
607 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
609 freekeyvalues(ethernetkv
);
611 if (allok
&& !allok_fastexit
)
614 fprintf(flog
, "Entering unattended setup\n");
615 if (unattended_setup(unattendedkv
)) {
616 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
617 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
619 errorbox("Unattended setup failed.");
629 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
630 printf("Unable to run setup.\n");
633 if (system("/bin/umount /harddisk/proc"))
634 printf("Unable to umount /harddisk/proc.\n");
644 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
649 system("/bin/umount /harddisk/proc");
650 system("/bin/umount /harddisk/dev");
651 system("/bin/umount /harddisk/sys");
653 system("/bin/umount /harddisk/var");
654 system("/bin/umount /harddisk/boot");
655 system("/bin/umount /harddisk");