propagator/live.c
Anton Farygin 2c956f151a livecd mode and method added
rescue method must be rewrited !!!
2004-11-24 21:44:32 +00:00

258 lines
6.1 KiB
C

/*
* 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 <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/mount.h>
#include <linux/loop.h>
#include <fcntl.h>
#include <errno.h>
#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();
}