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
];
28 struct nic nics
[20] = { { "" , "" } }; // only defined for compile
29 struct knic knics
[20] = { { "" , "" , "" } }; // only defined for compile
36 char line
[STRING_SIZE
];
39 if ((fd
= fopen("/proc/cpuinfo", "r")) == NULL
) {
42 while (fgets(line
, STRING_SIZE
, fd
) != NULL
) {
43 if (strstr(line
, "processor") == line
) {
48 return (cpu_count
> 1);
51 long calc_swapsize(long memory
, long disk
) {
62 int main(int argc
, char *argv
[])
64 char *langnames
[] = { "Deutsch", "English", NULL
};
65 char *shortlangnames
[] = { "de", "en", NULL
};
66 char **langtrs
[] = { de_tr
, en_tr
, NULL
};
68 char harddrive
[5], sourcedrive
[5]; /* Device holder. */
69 struct devparams hdparams
, cdromparams
; /* Params for CDROM and HD */
70 int cdmounted
= 0; /* Loop flag for inserting a cd. */
72 char commandstring
[STRING_SIZE
];
73 char *installtypes
[] = { "CDROM/USB", "HTTP/FTP", NULL
};
74 int installtype
= CDROM_INSTALL
;
76 char shortlangname
[10];
78 char title
[STRING_SIZE
];
81 struct keyvalue
*ethernetkv
= initkeyvalues();
82 FILE *handle
, *cmdfile
;
83 char line
[STRING_SIZE
];
84 char string
[STRING_SIZE
];
85 long maximum_free
= 0, current_free
;
87 long system_partition
, boot_partition
, root_partition
, swap_file
;
89 char *yesnoharddisk
[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
92 struct keyvalue
*unattendedkv
= initkeyvalues();
95 setlocale (LC_ALL
, "");
96 sethostname( SNAME
, 10);
98 memset(&hdparams
, 0, sizeof(struct devparams
));
99 memset(&cdromparams
, 0, sizeof(struct devparams
));
101 /* Log file/terminal stuff. */
104 if (!(flog
= fopen(argv
[1], "w+")))
112 fprintf(flog
, "Install program started.\n");
117 /* Do usb detection first for usb keyboard */
118 if (! (cmdfile
= fopen("/proc/cmdline", "r")))
120 fprintf(flog
, "Couldn't open commandline: /proc/cmdline\n");
122 fgets(line
, STRING_SIZE
, cmdfile
);
123 if (strstr (line
, "nousb") == NULL
) {
124 fprintf(flog
, "Initializing USB controllers.\n");
127 fprintf(flog
, "Skipping USB detection.\n");
129 // check if we have to make an unattended install
130 if (strstr (line
, "unattended") != NULL
) {
136 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
139 /* German is the default */
140 for (choice
= 0; langnames
[choice
]; choice
++)
142 if (strcmp(langnames
[choice
], "Deutsch") == 0)
145 if (!langnames
[choice
])
149 rc
= newtWinMenu("Language selection",
150 "Select the language you wish to use for the " NAME
".", 50, 5, 5, 8,
151 langnames
, &choice
, "Ok", NULL
);
154 ctr
= langtrs
[choice
];
155 strcpy(shortlangname
, shortlangnames
[choice
]);
156 fprintf(flog
, "Selected language: %s\n", shortlangname
);
158 newtDrawRootText(14, 0, NAME
" " VERSION
" - " SLOGAN
);
159 newtPushHelpLine(ctr
[TR_HELPLINE
]);
160 sprintf (title
, "%s %s - %s", NAME
, VERSION
, SLOGAN
);
163 sprintf(message
, ctr
[TR_WELCOME
], NAME
);
164 newtWinMessage(title
, ctr
[TR_OK
], message
);
166 sprintf(message
, ctr
[TR_SELECT_INSTALLATION_MEDIA_LONG
], NAME
);
167 rc
= newtWinMenu(ctr
[TR_SELECT_INSTALLATION_MEDIA
], message
,
168 50, 5, 5, 6, installtypes
, &installtype
, ctr
[TR_OK
],
169 ctr
[TR_CANCEL
], NULL
);
172 installtype
= CDROM_INSTALL
;
178 // Starting hardware detection
179 runcommandwithstatus("/bin/probehw.sh", ctr
[TR_PROBING_HARDWARE
]);
180 runcommandwithstatus("/bin/probenic.sh install", ctr
[TR_PROBING_HARDWARE
]);
183 if (installtype
== CDROM_INSTALL
) {
184 switch (mysystem("/bin/mountsource.sh")) {
186 installtype
= CDROM_INSTALL
;
190 installtype
= DISK_INSTALL
;
193 errorbox(ctr
[TR_NO_CDROM
]);
197 /* read source drive letter */
198 if ((handle
= fopen("/tmp/source_device", "r")) == NULL
) {
199 errorbox(ctr
[TR_ERROR_PROBING_CDROM
]);
202 fgets(sourcedrive
, 5, handle
);
203 fprintf(flog
, "Source drive: %s\n", sourcedrive
);
206 //snprintf(cdromparams.devnode_disk, STRING_SIZE, "/dev/%s", sourcedrive);
207 fprintf(flog
, "Source device: %s\n", sourcedrive
);
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 ipfire-<VERSION>.tbz2 */
219 if (checktarball(SNAME
"-" VERSION
".tbz2", ctr
[TR_ENTER_URL
])) {
220 errorbox(ctr
[TR_NO_IPCOP_TARBALL_FOUND
]);
225 // Now try to find destination device...
226 if ((hdletter
= findidetype(IDE_HD
))) {
227 sprintf(harddrive
, "hd%c", hdletter
);
228 goto FOUND_DESTINATION
;
231 /* Need to clean this up at some point
232 scsi disk is sdb/sdc when sda/sdb is used for usb-key
233 if scsi-disk is sdd or more, it is not discovered
234 Support only 2 usb keys, none could be unplugged */
235 if (checkusb("sdb") && try_scsi("sdc")) {
237 sprintf(harddrive
, "sdc");
238 goto FOUND_DESTINATION
;
240 if (checkusb("sda") && try_scsi("sdb")) {
242 sprintf(harddrive
, "sdb");
243 goto FOUND_DESTINATION
;
245 if (try_scsi("sda")) {
247 sprintf(harddrive
, "sda");
248 goto FOUND_DESTINATION
;
250 if (try_scsi("ida/c0d0")) {
252 sprintf(harddrive
, "ida/c0d0");
253 goto FOUND_DESTINATION
;
255 if (try_scsi("cciss/c0d0")) {
257 sprintf(harddrive
, "cciss/c0d0");
258 goto FOUND_DESTINATION
;
260 if (try_scsi("rd/c0d0")) {
262 sprintf(harddrive
, "rd/c0d0");
263 goto FOUND_DESTINATION
;
265 if (try_scsi("ataraid/d0")) {
267 sprintf(harddrive
, "ataraid/d0");
268 goto FOUND_DESTINATION
;
270 /* nothing worked, give up */
271 errorbox(ctr
[TR_NO_HARDDISK
]);
275 /* load unattended configuration */
277 fprintf(flog
, "unattended: Reading unattended.conf\n");
279 (void) readkeyvalues(unattendedkv
, UNATTENDED_CONF
);
282 /* Make the hdparms struct and print the contents.
283 With USB-KEY install and SCSI disk, while installing, the disk
284 is named 'sdb,sdc,...' (following keys)
285 On reboot, it will become 'sda'
286 To avoid many test, all names are built in the struct.
288 sprintf(hdparams
.devnode_disk
, "/dev/%s", harddrive
);
289 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
290 sprintf(hdparams
.devnode_part
, "/dev/%s%s", harddrive
,raid_disk
? "p" : "");
291 /* Now the names after the machine is booted. Only scsi is affected
292 and we only install on the first scsi disk. */
294 strcpy(tmp
, scsi_disk
? "sda" : harddrive
);
295 sprintf(hdparams
.devnode_disk_run
, "/dev/%s", tmp
);
296 sprintf(hdparams
.devnode_part_run
, "/dev/%s%s", tmp
, raid_disk
? "p" : "");
299 fprintf(flog
, "Destination drive: %s\n", hdparams
.devnode_disk
);
301 sprintf(message
, ctr
[TR_PREPARE_HARDDISK
], hdparams
.devnode_disk
);
306 yesnoharddisk
[0] = ctr
[TR_NO
];
307 yesnoharddisk
[1] = ctr
[TR_YES
];
308 yesnoharddisk
[2] = NULL
;
311 rc
= newtWinMenu(title
, message
,
312 50, 5, 5, 6, yesnoharddisk
,
314 ctr
[TR_CANCEL
], NULL
);
321 /* Calculate amount of memory in machine */
322 if ((handle
= fopen("/proc/meminfo", "r")))
324 while (fgets(line
, STRING_SIZE
-1, handle
)) {
325 if (sscanf (line
, "MemTotal: %s kB", string
)) {
326 memory
= atoi(string
) / 1024 ;
332 /* Partition, mkswp, mkfs.
333 * before partitioning, first determine the sizes of each
334 * partition. In order to do that we need to know the size of
337 /* Don't use mysystem here so we can redirect output */
338 sprintf(commandstring
, "/bin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive
);
339 system(commandstring
);
341 /* Calculate amount of disk space */
342 if ((handle
= fopen("/tmp/disksize", "r")))
344 fgets(line
, STRING_SIZE
-1, handle
);
345 if (sscanf (line
, "%s", string
)) {
346 maximum_free
= atoi(string
) / 1024;
351 fprintf(flog
, "maximum_free = %ld, memory = %ld",
352 maximum_free
, memory
);
354 swap_file
= calc_swapsize(memory
, maximum_free
);
356 if (maximum_free
< 512 + swap_file
) {
357 if (maximum_free
< 512) {
358 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
363 rc
= newtWinChoice(title
, ctr
[TR_OK
], ctr
[TR_CANCEL
], ctr
[TR_CONTINUE_NO_SWAP
]);
374 boot_partition
= 20; /* in MB */
375 current_free
= maximum_free
- boot_partition
- swap_file
;
377 root_partition
= 2048 ;
378 if (current_free
< 512) {
379 errorbox(ctr
[TR_DISK_TOO_SMALL
]);
383 current_free
= current_free
- root_partition
;
385 root_partition
= root_partition
+ swap_file
;
388 system_partition
= current_free
;
390 fprintf(flog
, "boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
391 boot_partition
, swap_file
, system_partition
, root_partition
);
393 handle
= fopen("/tmp/partitiontable", "w");
397 fprintf(handle
, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
398 boot_partition
, swap_file
, root_partition
);
400 fprintf(handle
, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
401 boot_partition
, root_partition
);
406 snprintf(commandstring
, STRING_SIZE
, "/bin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams
.devnode_disk
);
407 if (runcommandwithstatus(commandstring
, ctr
[TR_PARTITIONING_DISK
]))
409 errorbox(ctr
[TR_UNABLE_TO_PARTITION
]);
413 mysystem("/sbin/udevstart");
415 snprintf(commandstring
, STRING_SIZE
, "/bin/mke2fs -T ext2 -c %s1", hdparams
.devnode_part
);
416 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_BOOT_FILESYSTEM
]))
418 errorbox(ctr
[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM
]);
423 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkswap %s2", hdparams
.devnode_part
);
424 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_SWAPSPACE
]))
426 errorbox(ctr
[TR_UNABLE_TO_MAKE_SWAPSPACE
]);
431 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkreiserfs -f %s3", hdparams
.devnode_part
);
432 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_ROOT_FILESYSTEM
]))
434 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
438 snprintf(commandstring
, STRING_SIZE
, "/sbin/mkreiserfs -f %s4", hdparams
.devnode_part
);
439 if (runcommandwithstatus(commandstring
, ctr
[TR_MAKING_LOG_FILESYSTEM
]))
441 errorbox(ctr
[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM
]);
445 /* Mount harddisk. */
447 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s3 /harddisk", hdparams
.devnode_part
);
448 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_ROOT_FILESYSTEM
]))
450 errorbox(ctr
[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM
]);
454 mkdir("/harddisk/boot", S_IRWXU
|S_IRWXG
|S_IRWXO
);
455 mkdir("/harddisk/var", S_IRWXU
|S_IRWXG
|S_IRWXO
);
456 mkdir("/harddisk/var/log", S_IRWXU
|S_IRWXG
|S_IRWXO
);
458 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s1 /harddisk/boot", hdparams
.devnode_part
);
459 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_BOOT_FILESYSTEM
]))
461 errorbox(ctr
[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM
]);
465 snprintf(commandstring
, STRING_SIZE
, "/sbin/swapon %s2", hdparams
.devnode_part
);
466 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_SWAP_PARTITION
]))
468 errorbox(ctr
[TR_UNABLE_TO_MOUNT_SWAP_PARTITION
]);
472 snprintf(commandstring
, STRING_SIZE
, "/bin/mount %s4 /harddisk/var", hdparams
.devnode_part
);
473 if (runcommandwithstatus(commandstring
, ctr
[TR_MOUNTING_LOG_FILESYSTEM
]))
475 errorbox(ctr
[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM
]);
479 if (installtype
== URL_INSTALL
) {
480 snprintf(commandstring
, STRING_SIZE
,
481 "/bin/wget -q -O - %s/" SNAME
"-" VERSION
".tbz2 | /bin/tar -C /harddisk -xvjf -", url
);
484 if (installtype
== CDROM_INSTALL
) {
485 snprintf(commandstring
, STRING_SIZE
,
486 "/bin/tar -C /harddisk -xvjf /cdrom/" SNAME
"-" VERSION
".tbz2");
489 if (runcommandwithprogress(60, 4, title
, commandstring
, INST_FILECOUNT
,
490 ctr
[TR_INSTALLING_FILES
]))
492 errorbox(ctr
[TR_UNABLE_TO_INSTALL_FILES
]);
496 /* Save USB controller type to modules.conf */
497 write_usb_modules_conf();
499 /* Save language und local settings */
500 write_lang_configs(shortlangname
);
502 /* touch the modules.dep files */
503 snprintf(commandstring
, STRING_SIZE
,
504 "/bin/touch /harddisk/lib/modules/%s-ipfire/modules.dep",
506 mysystem(commandstring
);
507 snprintf(commandstring
, STRING_SIZE
,
508 "/bin/touch /harddisk/lib/modules/%s-ipfire-smp/modules.dep",
510 mysystem(commandstring
);
513 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
515 /* mount proc filesystem */
516 mysystem("mkdir /harddisk/proc");
517 mysystem("/bin/mount -t proc none /harddisk/proc");
518 mysystem("/bin/mount --bind /dev /harddisk/dev");
520 /* Build cache lang file */
521 snprintf(commandstring
, STRING_SIZE
, "/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT
"/lang.pl'; &Lang::BuildCacheLang\"");
522 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_LANG_CACHE
]))
524 errorbox(ctr
[TR_UNABLE_TO_INSTALL_LANG_CACHE
]);
528 /* Update /etc/fstab */
529 replace("/harddisk/etc/fstab", "DEVICE", hdparams
.devnode_part_run
);
531 /* if we detected SCSI/USB then fixup */
532 /* mysystem("/bin/probecntrl.sh");
533 if ((handle = fopen("/tmp/cntrldriver", "r")))
536 fgets(line, STRING_SIZE-1, handle);
538 line[strlen(line) - 1] = 0;
539 driver = strtok(line, ".");
540 if (strlen(driver) > 1) {
541 fprintf(flog, "Fixing up ipfirerd.img\n");
542 mkdir("/harddisk/initrd", S_IRWXU|S_IRWXG|S_IRWXO);
543 snprintf(commandstring, STRING_SIZE, "/sbin/chroot /harddisk /sbin/mkinitrd --with=scsi_mod %s --with=sd_mod --with=sr_mod /boot/ipfirerd.img %s-ipfire", driver, KERNEL_VERSION);
544 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
545 snprintf(commandstring, STRING_SIZE, "/sbin/chroot /harddisk /sbin/mkinitrd --with=scsi_mod %s --with=sd_mod --with=sr_mod /boot/ipfirerd-smp.img %s-ipfire-smp", driver, KERNEL_VERSION);
546 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
547 mysystem("/sbin/chroot /harddisk /bin/mv /boot/grub/scsigrub.conf /boot/grub/grub.conf");
551 sprintf(string
, "root=%s3", hdparams
.devnode_part_run
);
552 replace( "/harddisk/boot/grub/grub.conf", "root=ROOT", string
);
553 replace( "/harddisk/boot/grub/grubbatch", "DEVICE", hdparams
.devnode_disk
);
555 /* restore permissions */
556 chmod("/harddisk/boot/grub/grubbatch", S_IXUSR
| S_IRUSR
| S_IXGRP
| S_IRGRP
| S_IXOTH
| S_IROTH
);
558 snprintf(commandstring
, STRING_SIZE
,
559 "/sbin/chroot /harddisk /boot/grub/grubbatch");
560 if (runcommandwithstatus(commandstring
, ctr
[TR_INSTALLING_GRUB
])) {
561 errorbox(ctr
[TR_UNABLE_TO_INSTALL_GRUB
]);
565 /* Install bootsplash */
566 mysystem("/bin/installbootsplash.sh");
568 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
569 // mysystem("umount /harddisk/proc");
570 // mysystem("umount /harddisk/dev");
573 sprintf(message
, ctr
[TR_CONGRATULATIONS_LONG
],
575 newtWinMessage(ctr
[TR_CONGRATULATIONS
], ctr
[TR_OK
], message
);
581 fprintf(flog
, "Install program ended.\n");
586 newtWinMessage(title
, ctr
[TR_OK
], ctr
[TR_PRESS_OK_TO_REBOOT
]);
588 freekeyvalues(ethernetkv
);
590 if (allok
&& !allok_fastexit
)
592 /* /proc is needed by the module checker. We have to mount it
593 * so it can be seen by setup, which is run chrooted. */
594 // if (system("/bin/mount proc -t proc /harddisk/proc"))
595 // printf("Unable to mount proc in /harddisk.");
599 fprintf(flog
, "Entering unattended setup\n");
600 if (unattended_setup(unattendedkv
)) {
601 snprintf(commandstring
, STRING_SIZE
, "/bin/sleep 10");
602 runcommandwithstatus(commandstring
, "Unattended installation finished, system will reboot");
604 errorbox("Unattended setup failed.");
614 // Copy our scanned nics to the disk and lock because scan doesn't work in chroot
615 system("touch /harddisk/var/ipfire/ethernet/scan_lock");
616 system("cp -f /tmp/scanned_nics /harddisk/var/ipfire/ethernet/scanned_nics");
617 if (system("/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
618 printf("Unable to run setup.\n");
619 system("rm -f /harddisk/var/ipfire/ethernet/scan_lock");
622 if (system("/bin/umount /harddisk/proc"))
623 printf("Unable to umount /harddisk/proc.\n");
634 snprintf(commandstring
, STRING_SIZE
, "/bin/swapoff %s2", hdparams
.devnode_part
);
639 system("/bin/umount /harddisk/proc");
640 system("/bin/umount /harddisk/dev");
642 system("/bin/umount /harddisk/var");
643 system("/bin/umount /harddisk/boot");
644 system("/bin/umount /harddisk");