This is the same as has been previously done for NFS and URL install methods. While I'm at it, add a parseDeviceAndDir convenience function similar to what we've got in nfsinstall.c. --- loader/dirbrowser.c | 7 +- loader/dirbrowser.h | 6 +- loader/hdinstall.c | 258 +++++++++++++++++++++++---------------------------- loader/hdinstall.h | 4 +- loader/loader.c | 2 +- 5 files changed, 128 insertions(+), 149 deletions(-) diff --git a/loader/dirbrowser.c b/loader/dirbrowser.c index 3783ea3..ba0a6e8 100644 --- a/loader/dirbrowser.c +++ b/loader/dirbrowser.c @@ -30,6 +30,8 @@ #include <string.h> #include <sys/stat.h> +#include "dirbrowser.h" + #ifndef STANDALONE #include "../pyanaconda/isys/log.h" @@ -51,8 +53,7 @@ static int simpleStringCmp(const void * a, const void * b) { #define FSTEP 10 -static char ** get_file_list(char * dirname, - int (*filterfunc)(char *, struct dirent *)) { +char ** get_file_list(char * dirname, filterfunc_t filterfunc) { DIR * dir; struct dirent *entry; char ** files; @@ -100,7 +101,7 @@ static char ** get_file_list(char * dirname, * the dirent for the file. */ char * newt_select_file(char * title, char * text, char * dirname, - int (*filterfunc)(char *, struct dirent *)) { + filterfunc_t filterfunc) { char ** files; char * fn = NULL; int i, done = 0; diff --git a/loader/dirbrowser.h b/loader/dirbrowser.h index 7fb22f2..77f5681 100644 --- a/loader/dirbrowser.h +++ b/loader/dirbrowser.h @@ -22,7 +22,11 @@ #include <dirent.h> +typedef int (*filterfunc_t)(char *, struct dirent *); + +char **get_file_list(char *dirname, filterfunc_t filterfunc); + char * newt_select_file(char * title, char * text, char * dirname, - int (*filterfunc)(char *, struct dirent *)); + filterfunc_t filterfunc); #endif diff --git a/loader/hdinstall.c b/loader/hdinstall.c index e8c9873..453a594 100644 --- a/loader/hdinstall.c +++ b/loader/hdinstall.c @@ -25,6 +25,7 @@ #include <ctype.h> #include <errno.h> +#include <dirent.h> #include <fcntl.h> #include <newt.h> #include <stdlib.h> @@ -33,6 +34,7 @@ #include <unistd.h> #include <glib.h> +#include "dirbrowser.h" #include "driverdisk.h" #include "hdinstall.h" #include "getparts.h" @@ -54,76 +56,85 @@ /* boot flags */ extern uint64_t flags; -/* given a partition device and directory, tries to mount hd install image */ -static char * setupIsoImages(char * device, char * dirName, char * location) { - int rc = 0; - char *url = NULL, *dirspec, *updpath, *path; +/* format is hd:device:/path */ +static void parseDeviceAndDir(char *url, char **device, char **dir) { + char *token, *src = NULL; - logMessage(INFO, "mounting device %s for hard drive install", device); + if (!url) + return; - if (doPwMount(device, "/mnt/isodir", "auto", "ro", NULL)) - return NULL; + /* Skip over the leading hd: if present. */ + if (!strncmp(url, "hd:", 3)) + url += 3; - checked_asprintf(&dirspec, "/mnt/isodir/%.*s", - (int) (strrchr(dirName, '/') - dirName), dirName); - checked_asprintf(&path, "/mnt/isodir/%s", dirName); + logMessage(DEBUGLVL, "parseDeviceAndDir url: |%s|", url); - if (path) { - logMessage(INFO, "Path to stage2 image is %s", path); + src = strdup(url); + token = strtok(src, ":"); + if (!token) + return; - rc = copyFile(path, "/tmp/install.img"); - rc = mountStage2("/tmp/install.img"); + *device = strdup(token); - free(path); + token = strtok(NULL, ":"); + if (!token) + *dir = strdup("/"); + else + *dir = strdup(token); - if (rc) { - umount("/mnt/runtime"); - umount("/mnt/isodir"); - goto err; - } + logMessage(DEBUGLVL, "parseDeviceAndDir device: |%s|", *device); + logMessage(DEBUGLVL, "parseDeviceAndDir dir: |%s|", *dir); +} - checked_asprintf(&updpath, "%s/updates.img", dirspec); +static int ends_with_iso(char *dirname, struct dirent *ent) { + char *suffix; - logMessage(INFO, "Looking for updates for HD in %s", updpath); - copyUpdatesImg(updpath); - free(updpath); + if (ent->d_type != DT_REG) + return 0; - checked_asprintf(&updpath, "%s/product.img", dirspec); + suffix = rindex(ent->d_name, '.'); + return (!strcmp(suffix, "iso")); +} - logMessage(INFO, "Looking for product for HD in %s", updpath); - copyProductImg(updpath); +int loadHdImages(struct loaderData_s *loaderData) { + char *device = NULL, *dir = NULL, *path; - free(updpath); - free(dirspec); - umount("/mnt/isodir"); + if (!loaderData->instRepo) + return 0; - checked_asprintf(&url, "hd:%s:/%s", device, - dirName ? dirName : "."); + parseDeviceAndDir(loaderData->instRepo, &device, &dir); - return url; + if (doPwMount(device, "/mnt/isodir", "auto", "ro", NULL)) + return 0; + + if (dir[0] == '/') { + checked_asprintf(&path, "/mnt/isodir%s/updates.img", dir); } else { - free(dirspec); - free(path); + checked_asprintf(&path, "/mnt/isodir/%s/updates.img", dir); + } - if (rc) { - umount("/mnt/isodir"); - return NULL; - } + logMessage(INFO, "Looking for updates for HD in %s", path); + copyUpdatesImg(path); + free(path); + + if (dir[0] == '/') { + checked_asprintf(&path, "/mnt/isodir%s/product.img", dir); + } else { + checked_asprintf(&path, "/mnt/isodir/%s/product.img", dir); } -err: - newtWinMessage(_("Error"), _("OK"), - _("An error occured finding the installation image " - "on your hard drive. Please check your images and " - "try again.")); - return NULL; + logMessage(INFO, "Looking for product for HD in %s", path); + copyProductImg(path); + + free(device); + free(dir); + free(path); + umount("/mnt/isodir"); + + return 1; } -/* setup hard drive based install from a partition with a filesystem and - * ISO images on that filesystem - */ -char * mountHardDrive(struct installMethod * method, - char * location, struct loaderData_s * loaderData) { +int promptForHardDrive(struct loaderData_s *loaderData) { int rc; int i; @@ -131,75 +142,18 @@ char * mountHardDrive(struct installMethod * method, struct newtExitStruct es; newtGrid entryGrid, grid, buttons; - int done = 0; char * dir = g_strdup(""); char * tmpDir; - char * url = NULL; char * buf; int numPartitions; + char **files; char **partition_list; char *selpart; char *kspartition = NULL, *ksdirectory = NULL; - char *imgpath = "/images/install.img"; - - /* handle kickstart/stage2= data first if available */ - if (loaderData->method == METHOD_HD && loaderData->stage2Data) { - kspartition = ((struct hdInstallData *)loaderData->stage2Data)->partition; - if (kspartition) { - kspartition = g_strdup(kspartition); - } - - ksdirectory = ((struct hdInstallData *)loaderData->stage2Data)->directory; - if (ksdirectory) { - if (g_str_has_suffix(ksdirectory, ".img")) { - ksdirectory = g_strdup(ksdirectory); - } else { - ksdirectory = g_strconcat(ksdirectory, imgpath, NULL); - } - } else { - ksdirectory = g_strdup(imgpath); - } - - logMessage(INFO, "partition is %s, dir is %s", kspartition, ksdirectory); - - if (!kspartition || !ksdirectory) { - logMessage(ERROR, "missing partition or directory specification"); - loaderData->method = -1; - - if (loaderData->inferredStage2) - loaderData->invalidRepoParam = 1; - } else { - /* if we start with /dev, strip it (#121486) */ - char *kspart = kspartition; - if (!strncmp(kspart, "/dev/", 5)) - kspart = kspart + 5; - - url = setupIsoImages(kspart, ksdirectory, location); - if (!url) { - logMessage(ERROR, "unable to find %s installation images on hd", - getProductName()); - loaderData->method = -1; - - if (loaderData->inferredStage2) - loaderData->invalidRepoParam = 1; - } else { - g_free(kspartition); - g_free(ksdirectory); - return url; - } - } - } else { - kspartition = NULL; - ksdirectory = NULL; - } - - /* if we're here its either because this is interactive, or the */ - /* hd kickstart directive was faulty and we have to prompt for */ - /* location of harddrive image */ partition_list = NULL; - while (!done) { + while (1) { /* if we're doing another pass free this up first */ if (partition_list) freePartitionsList(partition_list); @@ -214,8 +168,8 @@ char * mountHardDrive(struct installMethod * method, "your system! Would you like to configure " "additional devices?")); if (rc == 2) { - loaderData->stage2Data = NULL; - return NULL; + loaderData->instRepo = NULL; + return LOADER_BACK; } rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0, NULL); @@ -300,8 +254,8 @@ char * mountHardDrive(struct installMethod * method, newtPopWindow(); if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) { - loaderData->stage2Data = NULL; - return NULL; + loaderData->instRepo = NULL; + return LOADER_BACK; } else if (es.reason == NEWT_EXIT_HOTKEY && es.u.key == NEWT_KEY_F2) { rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0, NULL); continue; @@ -309,37 +263,69 @@ char * mountHardDrive(struct installMethod * method, logMessage(INFO, "partition %s selected", selpart); - /* If the user-provided URL points at a repo instead of a stage2 - * image, fix that up now. - */ - if (!g_str_has_suffix(dir, ".img")) { - char *tmp = g_strconcat(dir, imgpath, NULL); - g_free(dir); - dir = tmp; + /* Now verify the ISO images pointed to contain an installation source. */ + if (doPwMount(selpart, "/mnt/isodir", "auto", "ro", NULL)) { + logMessage(ERROR, "couldn't mount %s to verify images", selpart); + continue; + } + + if (dir[0] == '/') { + checked_asprintf(&buf, "/mnt/isodir%s", dir); + } else { + checked_asprintf(&buf, "/mnt/isodir/%s", dir); + } + + files = get_file_list(buf, ends_with_iso); + if (!files) { + newtWinMessage(_("Error"), _("OK"), + _("That directory does not contain installation media.")); + umount("/mnt/isodir"); + free(buf); + continue; + } + + free(buf); + + /* mount the first image and check for a .treeinfo file */ + if (dir[0] == '/') { + checked_asprintf(&buf, "/mnt/isodir%s/%s", dir, files[0]); + } else { + checked_asprintf(&buf, "/mnt/isodir/%s/%s", dir, files[0]); } - loaderData->invalidRepoParam = 1; + if (doPwMount(buf, "/tmp/testmnt", "auto", "ro", NULL)) { + free(buf); + newtWinMessage(_("Error"), _("OK"), + _("That directory does not contain installation media.")); + umount("/mnt/isodir"); + continue; + } - url = setupIsoImages(selpart, dir, location); - if (!url) { - newtWinMessage(_("Error"), _("OK"), - _("Device %s does not appear to contain " - "an installation image."), selpart, getProductName()); + free(buf); + + if (access("/tmp/testmnt/.treeinfo", R_OK)) { + newtWinMessage(_("Error"), _("OK"), + _("That directory does not contain installation media.")); + umount("/tmp/testmnt"); + umount("/mnt/isodir"); continue; } - done = 1; + umount("/tmp/testmnt"); + umount("/mnt/isodir"); + break; } + checked_asprintf(&loaderData->instRepo, "hd:%s:/%s", selpart, dir); g_free(dir); + loaderData->method = METHOD_HD; - return url; + return LOADER_OK; } void setKickstartHD(struct loaderData_s * loaderData, int argc, char ** argv) { char *p; - char *substr = NULL; gchar *biospart = NULL, *partition = NULL, *dir = NULL; GOptionContext *optCon = g_option_context_new(NULL); GError *optErr = NULL; @@ -386,19 +372,7 @@ void setKickstartHD(struct loaderData_s * loaderData, int argc, } loaderData->method = METHOD_HD; - loaderData->stage2Data = calloc(sizeof(struct hdInstallData), 1); - if (partition) - ((struct hdInstallData *)loaderData->stage2Data)->partition = partition; - if (dir) - ((struct hdInstallData *)loaderData->stage2Data)->directory = dir; - - if (partition && dir) { - /* set repo only if location of stage 2 is not specified explicitly in --dir */ - substr = strstr(dir, ".img"); - if (!substr || (substr && *(substr+4) != '\0')) { - checked_asprintf(&(loaderData->instRepo), "hd:%s:%s", partition, dir); - } - } + checked_asprintf(&loaderData->instRepo, "hd:%s:%s", partition, dir); logMessage(INFO, "results of hd ks, partition is %s, dir is %s", partition, dir); diff --git a/loader/hdinstall.h b/loader/hdinstall.h index 44351a3..cee3e16 100644 --- a/loader/hdinstall.h +++ b/loader/hdinstall.h @@ -30,8 +30,8 @@ struct hdInstallData { void setKickstartHD(struct loaderData_s * loaderData, int argc, char ** argv); -char * mountHardDrive(struct installMethod * method, - char * location, struct loaderData_s * loaderData); +int promptForHardDrive(struct loaderData_s *loaderData); +int loadHdImages(struct loaderData_s *loaderData); int kickstartFromHD(char *kssrc); int kickstartFromBD(char *kssrc); diff --git a/loader/loader.c b/loader/loader.c index 942b5b5..044e84a 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -130,7 +130,7 @@ static const char *LANG_DEFAULT = "en_US.UTF-8"; static struct installMethod installMethods[] = { { N_("Local CD/DVD"), 0, DEVICE_CDROM, NULL, NULL }, - { N_("Hard drive"), 0, DEVICE_DISK, NULL, NULL }, + { N_("Hard drive"), 0, DEVICE_DISK, promptForHardDrive, loadHdImages }, { N_("NFS directory"), 1, DEVICE_NETWORK, promptForNfs, loadNfsImages }, { "URL", 1, DEVICE_NETWORK, promptForUrl, loadUrlImages}, }; -- 1.7.1.1 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list