/* * Anton Farygin (rider@altlinux.com) * * Copyright 2004 ALT Linux * * This software may be freely redistributed under the terms of the GNU * public license. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* * Portions from Guillaume Cottenceau (gc@mandrakesoft.com) * * Copyright 2000 MandrakeSoft * * Portions from Erik Troan (ewt@redhat.com) * * Copyright 1996 Red Hat Software * */ #include #include #include #include #include #include #include #include #include "stage1.h" #include "frontend.h" #include "modules.h" #include "probing.h" #include "log.h" #include "mount.h" #include "live.h" static int mount_that_cd_device(char * dev_name) { char device_fullname[50]; strcpy(device_fullname, "/dev/"); strcat(device_fullname, dev_name); return my_mount(device_fullname, IMAGE_LOCATION, "iso9660", 0); } int do_losetup(char * device, char * target) { int loopfd, targfd; struct loop_info loopInfo; loopfd = open( device, O_RDONLY ); if ( loopfd < 0 ) { log_message( "losetup: error opening %s: %s", device, strerror(errno) ); return -1; } targfd = open( target, O_RDONLY ); if ( targfd < 0 ) { log_message( "losetup: error opening %s: %s", target, strerror(errno) ); close( loopfd ); return -1; } if ( ioctl(loopfd, LOOP_SET_FD, targfd) < 0 ) { log_message( "losetup: error setting up loopback device: %s", strerror(errno) ); close( loopfd ); close( targfd ); return -1; } memset(&loopInfo, 0, sizeof(loopInfo)); strcpy(loopInfo.lo_name, target); if ( ioctl(loopfd, LOOP_SET_STATUS, &loopInfo) < 0 ) log_message( "losetup: error setting up loopback device: %s", strerror(errno) ); close( loopfd ); close( targfd ); return 0; } static int mount_image(char * dev_name) { char device_fullname[50]; strcpy(device_fullname, "/dev/"); strcat(device_fullname, dev_name); log_message("Setup %s for " IMAGE_LOCATION LIVECD_LOCATION, device_fullname); if (do_losetup(device_fullname, IMAGE_LOCATION LIVECD_LOCATION) == -1) fatal_error("could not setup loopback for live cd image"); mkdir(LIVEIMAGE_LOCATION,0755); return my_mount(device_fullname, LIVEIMAGE_LOCATION, "ext2", 0); } static int test_that_livecd() { return access(IMAGE_LOCATION LIVECD_LOCATION, R_OK); } static enum return_type try_with_live_device(char * dev_name, char * dev_model); static enum return_type do_with_live_device(char * dev_name, char * dev_model) { pid_t preparepid, childpid; int end_child; int wait_status; if (test_that_livecd()) { enum return_type results; umount(IMAGE_LOCATION); results = ask_yes_no("That CDROM disc does not seem to be a " DISTRIB_NAME " LIVE CD.\nRetry with another disc?"); if (results == RETURN_OK) return try_with_live_device(dev_name, dev_model); return results; } log_message("found a " DISTRIB_NAME " LIVE-CD, good news!"); mount_image("cloop"); #if 0 if (!(preparepid = fork())) { /* child */ char * child_argv[2]; char * args[3] = { "prepare_live.sh", NULL, }; char * envp[32] = { "HOME=/root", "TERM=linux", NULL, }; chroot("/tmp/live"); sleep(10); execve("/root/prepare_live.sh",args,envp); printf("error in exec of prepare_live.sh :-(\n"); return 0; } while (!end_child) { childpid = wait4(-1, &wait_status, 0, NULL); if (childpid == preparepid) end_child = 1; } #endif method_name = strdup("live"); return RETURN_OK; } static enum return_type try_with_live_device(char * dev_name, char * dev_model) { wait_message("Trying to access a CDROM disc (drive %s)", dev_model); if (mount_that_cd_device(dev_name) == -1) { enum return_type results; char msg[500]; unset_param(MODE_AUTOMATIC); /* we are in a fallback mode */ remove_wait_message(); snprintf(msg, sizeof(msg), "I can't access a " DISTRIB_NAME " liveCD disc in your CDROM drive (%s).\nRetry?", dev_model); results = ask_yes_no(msg); if (results == RETURN_OK) return try_with_live_device(dev_name, dev_model); return results; } remove_wait_message(); return do_with_live_device(dev_name, dev_model); } enum return_type live_prepare(void) { char ** medias, ** ptr, ** medias_models; char * choice; int i, count = 0; enum return_type results; my_insmod("ide-cd", ANY_DRIVER_TYPE, NULL); my_insmod("sr_mod", ANY_DRIVER_TYPE, NULL); my_insmod("zlib_inflate", ANY_DRIVER_TYPE, NULL); my_insmod("cloop", ANY_DRIVER_TYPE, NULL); get_medias(CDROM, &medias, &medias_models); ptr = medias; while (ptr && *ptr) { count++; ptr++; } if (count == 0) { stg1_error_message("No CDROM device found."); i = ask_insmod(SCSI_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return live_prepare(); } if (count == 1) { results = try_with_live_device(*medias, *medias_models); if (results == RETURN_OK) return RETURN_OK; i = ask_insmod(SCSI_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return live_prepare(); } if (IS_AUTOMATIC) { char ** model = medias_models; ptr = medias; while (ptr && *ptr) { wait_message("Trying to access " DISTRIB_NAME " LIVE CD disc (drive %s)", *model); if (mount_that_cd_device(*ptr) != -1) { if (!test_that_livecd()) { remove_wait_message(); return do_with_live_device(*ptr, *model); } else umount(IMAGE_LOCATION); } remove_wait_message(); ptr++; model++; } unset_param(MODE_AUTOMATIC); return live_prepare(); } else { results = ask_from_list_comments("Please choose the CDROM drive to use for the livecd.", medias, medias_models, &choice); if (results == RETURN_OK) { char ** model = medias_models; ptr = medias; while (ptr && *ptr && model && *model) { if (!strcmp(*ptr, choice)) break; ptr++; model++; } results = try_with_live_device(choice, *model); } else return results; } if (results == RETURN_OK) return RETURN_OK; if (results == RETURN_BACK) return live_prepare(); i = ask_insmod(SCSI_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return live_prepare(); }