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.
14 #define CDROM_INSTALL 0
16 #define DISK_INSTALL 2
17 #define INST_FILECOUNT 7000
18 #define UNATTENDED_CONF "/cdrom/boot/unattended.conf"
26 extern char url
[STRING_SIZE
];
33 char line
[STRING_SIZE
];
36 if ((fd
= fopen("/proc/cpuinfo", "r")) == NULL
) {
39 while (fgets(line
, STRING_SIZE
, fd
) != NULL
) {
40 if (strstr(line
, "processor") == line
) {
45 return (cpu_count
> 1);
48 long calc_swapsize(long memory
, long disk
) {
59 int main(int argc
, char *argv
[])
61 char *langnames
[] = { "Deutsch", "English", NULL
};
62 char *shortlangnames
[] = { "de", "en", NULL
};
63 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
65 char harddrive
[5], sourcedrive
[5]; /* Device holder. */
66 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
67 int cdmounted
= 0; /* Loop flag for inserting a cd. */
69 char commandstring
[STRING_SIZE
];
70 char *installtypes
[] = { "CDROM/USB", "HTTP/FTP", NULL
};
71 int installtype
= CDROM_INSTALL
;
73 char shortlangname
[10];
75 char title
[STRING_SIZE
];
78 struct keyvalue
*ethernetkv
= initkeyvalues();
79 FILE *handle
, *cmdfile
;
80 char line
[STRING_SIZE
];
81 char string
[STRING_SIZE
];
82 long maximum_free
= 0, current_free
;
84 long system_partition
, boot_partition
, root_partition
, swap_file
;
86 char *yesnoharddisk
[] = { "NO", "YES", NULL
};
88 struct keyvalue
*unattendedkv
= initkeyvalues();
91 setlocale (LC_ALL
, "");
92 sethostname( SNAME
, 10);
94 memset(&hdparams
, 0, sizeof(struct devparams
));
95 memset(&cdromparams
, 0, sizeof(struct devparams
));
97 /* Log file/terminal stuff. */
100 if (!(flog
= fopen(argv
[1], "w+")))
108 fprintf(flog
, "Install program started.\n");
113 /* Do usb detection first for usb keyboard */
114 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
116 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
118 fgets(line
, STRING_SIZE
, cmdfile
);
119 if (strstr (line
, "nousb") == NULL
) {
120 fprintf(flog
, "Initializing USB controllers.\n");
123 fprintf(flog
, "Skipping USB detection.\n");
125 // check if we have to make an unattended install
126 if (strstr (line
, "unattended") != NULL
) {
131 // make some beeps before wiping the system :)
133 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
136 /* German is the default */
137 for (choice
= 0; langnames
[choice
]; choice
++)
139 if (strcmp(langnames
[choice
], "Deutsch") == 0)
142 if (!langnames
[choice
])
146 rc
= newtWinMenu("Language selection",
147 "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
148 langnames
, &choice
, "Ok", NULL
);
151 ctr
= langtrs
[choice
];
152 strcpy(shortlangname
, shortlangnames
[choice
]);
154 mysystem("/bin/setfont lat0-16");
156 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
157 newtPushHelpLine(ctr
[TR_HELPLINE
]);
158 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
161 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
162 newtWinMessage(title
, ctr
[TR_OK
], message
);
164 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
165 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
166 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
167 ctr
[TR_CANCEL
], NULL
);
171 installtype
= CDROM_INSTALL
;
177 // Starting hardware detection
178 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
181 if (installtype
== CDROM_INSTALL
) {
183 switch (mysystem("/bin/mountsource.sh")) {
185 installtype
= CDROM_INSTALL
;
189 installtype
= DISK_INSTALL
;
192 errorbox(ctr
[TR_NO_CDROM
]);
196 /* read source drive letter */
197 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
198 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
201 fgets(sourcedrive
, 5, handle
);
202 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
205 snprintf(cdromparams
.devnode
, STRING_SIZE
, "/dev/%s", sourcedrive
);
206 cdromparams
.module
= 0;
207 fprintf(flog
, "Source device: %s\n", cdromparams
.devnode
);
210 /* Configure the network now! */
211 if (installtype
== URL_INSTALL
) {
212 /* Network driver and params. */
213 if (!(networkmenu(ethernetkv
))) {
214 errorbox(ctr
[TR_NETWORK_SETUP_FAILED
]);
218 /* Check for ipcop-<VERSION>.tbz2 */
219 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
220 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
225 /* Get device for the HD. This has to succeed. */
226 if (!(hdletter
= findidetype(IDE_HD
)))
228 /* Need to clean this up at some point */
229 if (!try_scsi("sda") || strstr(sourcedrive
, "sda") != NULL
) {
230 if (!try_scsi("ida/c0d0")) {
231 if (!try_scsi("cciss/c0d0")) {
232 if (!try_scsi("rd/c0d0")) {
233 if (!try_scsi("ataraid/d0")) {
234 errorbox(ctr
[TR_NO_HARDDISK
]);
238 sprintf(harddrive
, "ataraid/d0");
242 sprintf(harddrive
, "rd/c0d0");
246 sprintf(harddrive
, "cciss/c0d0");
250 sprintf(harddrive
, "ida/c0d0");
253 if (strstr(sourcedrive
, "sda") != NULL
) {
254 // probably installing from usb stick, try sdb
255 if (try_scsi("sdb")) {
256 sprintf(harddrive
, "sdb");
259 errorbox(ctr
[TR_NO_HARDDISK
]);
264 sprintf(harddrive
, "sda");
269 sprintf(harddrive
, "hd%c", hdletter
);
271 fprintf(flog
, "Destination drive: %s\n", harddrive
);
273 /* load unattended configuration */
275 fprintf(flog
, "unattended: Reading unattended.conf\n");
277 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
280 /* Make the hdparms struct and print the contents. */
281 snprintf(hdparams
.devnode
, STRING_SIZE
, "/dev/%s", harddrive
);
284 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode
);
291 rc
= newtWinMenu(title
, message
,
292 50, 5, 5, 6, yesnoharddisk
,
294 ctr
[TR_CANCEL
], NULL
);
302 /* Calculate amount of memory in machine */
303 if ((handle
= fopen("/proc/meminfo", "r")))
305 while (fgets(line
, STRING_SIZE
-1, handle
)) {
306 if (sscanf (line
, "MemTotal: %s kB", string
)) {
307 memory
= atoi(string
) / 1024 ;
313 /* Partition, mkswp, mkfs.
314 * before partitioning, first determine the sizes of each
315 * partition. In order to do that we need to know the size of
318 /* Don't use mysystem here so we can redirect output */
319 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
320 system(commandstring
);
322 /* Calculate amount of disk space */
323 if ((handle
= fopen("/tmp/disksize", "r")))
325 fgets(line
, STRING_SIZE
-1, handle
);
326 if (sscanf (line
, "%s", string
)) {
327 maximum_free
= atoi(string
) / 1024;
332 fprintf(flog
, "maximum_free = %ld, memory = %ld",
333 maximum_free
, memory
);
335 swap_file
= calc_swapsize(memory
, maximum_free
);
337 if (maximum_free
< 512 + swap_file
) {
338 if (maximum_free
< 512) {
339 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
344 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
355 boot_partition
= 20; /* in MB */
356 current_free
= maximum_free
- boot_partition
- swap_file
;
358 root_partition
= 2048 ;
359 if (current_free
< 512) {
360 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
364 current_free
= current_free
- root_partition
;
366 root_partition
= root_partition
+ swap_file
;
369 system_partition
= current_free
;
371 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
372 boot_partition
, swap_file
, system_partition
, root_partition
);
374 handle
= fopen("/tmp/partitiontable", "w");
378 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
379 boot_partition
, swap_file
, root_partition
);
381 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
382 boot_partition
, root_partition
);
387 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode
);
388 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
390 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
394 mysystem("/sbin/udevstart");
397 snprintf(commandstring
, STRING_SIZE
, "/bin/mke2fs -T ext2 -c %sp1", hdparams
.devnode
);
399 snprintf(commandstring
, STRING_SIZE
, "/bin/mke2fs -T ext2 -c %s1", hdparams
.devnode
);
400 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
402 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
408 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %sp2", hdparams
.devnode
);
410 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode
);
411 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
413 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
419 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkreiserfs -f %sp3", hdparams
.devnode
);
421 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkreiserfs -f %s3", hdparams
.devnode
);
423 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
425 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
430 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkreiserfs -f %sp4", hdparams
.devnode
);
432 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkreiserfs -f %s4", hdparams
.devnode
);
434 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
436 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
440 /* Mount harddisk. */
442 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %sp3 /harddisk", hdparams
.devnode
);
444 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode
);
445 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
447 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
451 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
452 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
453 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
456 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %sp1 /harddisk/boot", hdparams
.devnode
);
458 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode
);
460 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
462 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
467 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %sp2", hdparams
.devnode
);
469 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode
);
470 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
472 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
477 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %sp4 /harddisk/var", hdparams
.devnode
);
479 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode
);
480 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
482 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
486 if (installtype
== URL_INSTALL
) {
487 snprintf(commandstring
, STRING_SIZE
,
488 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
491 if (installtype
== CDROM_INSTALL
) {
492 snprintf(commandstring
, STRING_SIZE
,
493 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
496 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
497 ctr
[TR_INSTALLING_FILES
]))
499 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
503 /* Save USB controller type to modules.conf */
504 write_usb_modules_conf();
506 /* touch the modules.dep files */
507 snprintf(commandstring
, STRING_SIZE
,
508 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
510 mysystem(commandstring
);
511 snprintf(commandstring
, STRING_SIZE
,
512 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
514 mysystem(commandstring
);
517 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
519 /* *always* write disk configuration */
520 if (!(write_disk_configs(&hdparams
))){
521 errorbox(ctr
[TR_ERROR_WRITING_CONFIG
]);
525 /* mount proc filesystem */
526 mysystem("mkdir /harddisk/proc");
527 mysystem("/bin/mount -t proc none /harddisk/proc");
528 mysystem("/bin/mount --bind /dev /harddisk/dev");
531 /* if we detected SCSI then fixup */
532 /* doesn't really work cause it sometimes creates a ramdisk on ide systems */
533 /* mysystem("/bin/probecntrl.sh");
534 if ((handle = fopen("/cntrldriver", "r")))
537 fgets(line, STRING_SIZE-1, handle);
539 line[strlen(line) - 1] = 0;
540 driver = strtok(line, ".");
541 fprintf(flog, "Detected SCSI driver %s\n",driver);
542 if (strlen(driver) > 1) {
543 fprintf(flog, "Fixing up ipfirerd.img\n");
544 mysystem("/sbin/chroot /harddisk /sbin/modprobe loop");
545 mkdir("/harddisk/initrd", S_IRWXU|S_IRWXG|S_IRWXO);
546 snprintf(commandstring, STRING_SIZE, "/sbin/chroot /harddisk /sbin/mkinitrd --with=scsi_mod --with=%s --with=sd_mod --with=sr_mod --with=libata /boot/ipfirerd.img %s", driver, KERNEL_VERSION);
547 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
548 snprintf(commandstring, STRING_SIZE, "/sbin/chroot /harddisk /sbin/mkinitrd --with=scsi_mod --with=%s --with=sd_mod --with=sr_mod --with=libata /boot/ipfirerd-smp.img %s-smp", driver, KERNEL_VERSION);
549 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
550 mysystem("/sbin/chroot /harddisk /bin/mv /boot/grub/scsigrub.conf /boot/grub/grub.conf");
554 /* Build cache lang file */
555 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
556 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
558 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
563 sprintf(string
, "root=%sp3", hdparams
.devnode
);
565 sprintf(string
, "root=%s3", hdparams
.devnode
);
566 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
567 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode
);
569 /* restore permissions */
570 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
572 snprintf(commandstring
, STRING_SIZE
,
573 "/sbin/chroot /harddisk /boot/grub/grubbatch");
574 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
575 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
579 /* Update /etc/fstab */
580 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode
);
582 /* Install bootsplash */
583 mysystem("/bin/installbootsplash.sh");
585 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
586 mysystem("umount /harddisk/proc");
587 mysystem("umount /harddisk/dev");
590 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
591 NAME
, SNAME
, SNAME
, NAME
, NAME
, NAME
);
592 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
598 fprintf(flog
, "Install program ended.\n");
601 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
603 freekeyvalues(ethernetkv
);
605 if (allok
&& !allok_fastexit
)
607 /* /proc is needed by the module checker. We have to mount it
608 * so it can be seen by setup, which is run chrooted. */
609 if (system("/bin/mount proc -t proc /harddisk/proc"))
610 printf("Unable to mount proc in /harddisk.");
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");
641 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %sp2", hdparams
.devnode
);
643 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode
);
648 system("/bin/umount /harddisk/var");
649 system("/bin/umount /harddisk/boot");
650 system("/bin/umount /harddisk");