/* Used by mountCdromStage2()                                      */
static void wrongCDMessage(void) {
    char *buf = sdupprintf(_("The %s CD was not found "
                             "in any of your CDROM drives. Please insert "
                             "the %s CD and press %s to retry."),
                           getProductName(), getProductName(), _("OK"));
    newtWinMessage(_("Error"), _("OK"), buf, _("OK"));
    free(buf);
}
Example #2
0
int nfsGetSetup(char ** hostptr, char ** dirptr, char ** optsptr) {
    struct newtWinEntry entries[4];
    char * buf;
    char * newServer = *hostptr ? strdup(*hostptr) : NULL;
    char * newDir = *dirptr ? strdup(*dirptr) : NULL;
    char * newMountOpts = *optsptr ? strdup(*optsptr) : NULL;
    int rc;

    entries[0].text = _("NFS server name:");
    entries[0].value = (const char **) &newServer;
    entries[0].flags = NEWT_FLAG_SCROLL;
    entries[1].text = sdupprintf(_("%s directory:"), getProductName());
    entries[1].value = (const char **) &newDir;
    entries[1].flags = NEWT_FLAG_SCROLL;
    entries[2].text = _("NFS mount options (optional):");
    entries[2].value = (const char **) &newMountOpts;
    entries[2].flags = NEWT_FLAG_SCROLL;
    entries[3].text = NULL;
    entries[3].value = NULL;
    buf = sdupprintf(_(nfsServerPrompt), getProductName());
    rc = newtWinEntries(_("NFS Setup"), buf, 60, 5, 15,
                        24, entries, _("OK"), _("Back"), NULL);
    free(buf);

    if (rc == 2) {
        if (newServer) free(newServer);
        if (newDir) free(newDir);
        if (newMountOpts) free(newMountOpts);
        return LOADER_BACK;
    }

    if (*hostptr) free(*hostptr);
    if (*dirptr) free(*dirptr);
    if (*optsptr) free(*optsptr);
    *hostptr = newServer;
    *dirptr = newDir;
    *optsptr = newMountOpts;

    return 0;
}
Example #3
0
int urlMainSetupPanel(struct iurlinfo * ui, urlprotocol protocol,
                      char * doSecondarySetup) {
    newtComponent form, okay, cancel, siteEntry, dirEntry;
    newtComponent answer, text;
    newtComponent cb = NULL;
    char * site, * dir;
    char * reflowedText = NULL;
    int width, height;
    newtGrid entryGrid, buttons, grid;
    char * chptr;
    char * buf = NULL;

    if (ui->address) {
        site = ui->address;
        dir = ui->prefix;
    } else {
        site = "";
        dir = "";
    }

    if (ui->login || ui->password || ui->proxy || ui->proxyPort)
        *doSecondarySetup = '*';
    else
        *doSecondarySetup = ' ';

    buttons = newtButtonBar(_("OK"), &okay, _("Back"), &cancel, NULL);
    
    switch (protocol) {
    case URL_METHOD_FTP:
        buf = sdupprintf(_(netServerPrompt), _("FTP"), getProductName());
        reflowedText = newtReflowText(buf, 47, 5, 5, &width, &height);
        free(buf);
        break;
    case URL_METHOD_HTTP:
        buf = sdupprintf(_(netServerPrompt), _("Web"), getProductName());
        reflowedText = newtReflowText(buf, 47, 5, 5, &width, &height);
        free(buf);
        break;

#ifdef ROCKS
    case URL_METHOD_HTTPS:
        buf = sdupprintf(_(netServerPrompt), "Secure Web", getProductName());
        reflowedText = newtReflowText(buf, 47, 5, 5, &width, &height);
        free(buf);
        break;
#endif /* ROCKS */
    }
    text = newtTextbox(-1, -1, width, height, NEWT_TEXTBOX_WRAP);
    newtTextboxSetText(text, reflowedText);
    free(reflowedText);

    siteEntry = newtEntry(22, 8, site, 24, (const char **) &site, 
                          NEWT_ENTRY_SCROLL);
    dirEntry = newtEntry(22, 9, dir, 24, (const char **) &dir, 
                         NEWT_ENTRY_SCROLL);

    entryGrid = newtCreateGrid(2, 2);
    newtGridSetField(entryGrid, 0, 0, NEWT_GRID_COMPONENT,
                     newtLabel(-1, -1, (protocol == URL_METHOD_FTP) ?
                                        _("FTP site name:") :
                                        _("Web site name:")),
                     0, 0, 1, 0, NEWT_ANCHOR_LEFT, 0);
    newtGridSetField(entryGrid, 0, 1, NEWT_GRID_COMPONENT,
                     newtLabel(-1, -1, 
                               sdupprintf(_("%s directory:"), 
                                          getProductName())),
                     0, 0, 1, 0, NEWT_ANCHOR_LEFT, 0);
    newtGridSetField(entryGrid, 1, 0, NEWT_GRID_COMPONENT, siteEntry,
                     0, 0, 0, 0, 0, 0);
    newtGridSetField(entryGrid, 1, 1, NEWT_GRID_COMPONENT, dirEntry,
                     0, 0, 0, 0, 0, 0);

    grid = newtCreateGrid(1, 4);
    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
                     0, 0, 0, 1, 0, 0);
    newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, entryGrid,
                     0, 0, 0, 1, 0, 0);

    if (protocol == URL_METHOD_FTP) {
        cb = newtCheckbox(3, 11, _("Use non-anonymous ftp"),
                          *doSecondarySetup, NULL, doSecondarySetup);
        newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, cb,
                         0, 0, 0, 1, NEWT_ANCHOR_LEFT, 0);
    }
        
    newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons,
                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);

    newtGridWrappedWindow(grid, (protocol == URL_METHOD_FTP) ? _("FTP Setup") :
                          _("HTTP Setup"));

    form = newtForm(NULL, NULL, 0);
    newtGridAddComponentsToForm(grid, form, 1);    

    do {
        answer = newtRunForm(form);
        if (answer != cancel) {
            if (!strlen(site)) {
                newtWinMessage(_("Error"), _("OK"),
                               _("You must enter a server name."));
                continue;
            }
            if (!strlen(dir)) {
                newtWinMessage(_("Error"), _("OK"),
                               _("You must enter a directory."));
                continue;
            }

            if (!addrToIp(site)) {
                newtWinMessage(_("Unknown Host"), _("OK"),
                        _("%s is not a valid hostname."), site);
                continue;
            }
        }

        break;
    } while (1);
    
    if (answer == cancel) {
        newtFormDestroy(form);
        newtPopWindow();
        
        return LOADER_BACK;
    }

    if (ui->address) free(ui->address);
    ui->address = strdup(site);

    if (ui->prefix) free(ui->prefix);

    /* add a slash at the start of the dir if it is missing */
    if (*dir != '/') {
        if (asprintf(&(ui->prefix), "/%s", dir) == -1)
            ui->prefix = strdup(dir);
    } else {
        ui->prefix = strdup(dir);
    }

    /* Get rid of trailing /'s */
    chptr = ui->prefix + strlen(ui->prefix) - 1;
    while (chptr > ui->prefix && *chptr == '/') chptr--;
    chptr++;
    *chptr = '\0';

    if (*doSecondarySetup != '*') {
        if (ui->login)
            free(ui->login);
        if (ui->password)
            free(ui->password);
        if (ui->proxy)
            free(ui->proxy);
        if (ui->proxyPort)
            free(ui->proxyPort);
        ui->login = ui->password = ui->proxy = ui->proxyPort = NULL;
    }

    ui->protocol = protocol;

    newtFormDestroy(form);
    newtPopWindow();

    return 0;
}
Example #4
0
char * mountNfsImage(struct installMethod * method,
                     char * location, struct loaderData_s * loaderData,
                     moduleInfoSet modInfo, moduleList modLoaded,
                     moduleDeps * modDepsPtr) {
    char * host = NULL;
    char * directory = NULL;
    char * mountOpts = NULL;
    char * fullPath = NULL;
    char * path;
    char * url = NULL;

    enum { NFS_STAGE_NFS, NFS_STAGE_MOUNT, 
           NFS_STAGE_DONE } stage = NFS_STAGE_NFS;

    int rc;
    int dir = 1;

    /* JKFIXME: ASSERT -- we have a network device setup when we get here */
    while (stage != NFS_STAGE_DONE) {
        switch (stage) {
        case NFS_STAGE_NFS:
            logMessage(INFO, "going to do nfsGetSetup");
            if (loaderData->method == METHOD_NFS && loaderData->methodData) {
                host = ((struct nfsInstallData *)loaderData->methodData)->host;
                directory = ((struct nfsInstallData *)loaderData->methodData)->directory;
                mountOpts = ((struct nfsInstallData *)loaderData->methodData)->mountOpts;

                logMessage(INFO, "host is %s, dir is %s, opts are '%s'", host, directory, mountOpts);

                if (!host || !directory) {
                    logMessage(ERROR, "missing host or directory specification");
                    loaderData->method = -1;
                    break;
                } else {
                    host = strdup(host);
                    directory = strdup(directory);
                    if (mountOpts) {
                        mountOpts = strdup(mountOpts);
                    }
                }
            } else if (nfsGetSetup(&host, &directory, &mountOpts) == LOADER_BACK) {
                return NULL;
            }
             
            stage = NFS_STAGE_MOUNT;
            dir = 1;
            break;

        case NFS_STAGE_MOUNT: {
            int foundinvalid = 0;
            char * buf;
            struct in_addr ip;

            if (loaderData->noDns && !(inet_pton(AF_INET, host, &ip))) {
                newtWinMessage(_("Error"), _("OK"),
                               _("Hostname specified with no DNS configured"));
                if (loaderData->method >= 0) {
                    loaderData->method = -1;
                }
                break;
            }

            fullPath = alloca(strlen(host) + strlen(directory) + 2);
            sprintf(fullPath, "%s:%s", host, directory);

            logMessage(INFO, "mounting nfs path %s, options '%s'", fullPath, mountOpts);

            if (FL_TESTING(flags)) {
                stage = NFS_STAGE_DONE;
                dir = 1;
                break;
            }

            stage = NFS_STAGE_NFS;

            if (!doPwMount(fullPath, "/mnt/source", "nfs", 
                           IMOUNT_RDONLY, mountOpts)) {
                if (!access("/mnt/source/images/stage2.img", R_OK)) {
                    logMessage(INFO, "can access /mnt/source/images/stage2.img");
                    rc = mountStage2("/mnt/source/images/stage2.img");
                    logMessage(DEBUGLVL, "after mountStage2, rc is %d", rc);
                    if (rc) {
                        if (rc == -1) { 
                            foundinvalid = 1; 
                            logMessage(WARNING, "not the right one"); 
                        }
                    } else {
                        stage = NFS_STAGE_DONE;
                        url = "nfs://mnt/source/.";
                        break;
                    }
                } else {
                    logMessage(WARNING, "unable to access /mnt/source/images/stage2.img");
                }

                if ((path = validIsoImages("/mnt/source", &foundinvalid))) {
		    foundinvalid = 0;
		    logMessage(INFO, "Path to valid iso is %s", path);
                    copyUpdatesImg("/mnt/source/updates.img");

                    if (mountLoopback(path, "/mnt/source2", "loop1")) 
                        logMessage(WARNING, "failed to mount iso %s loopback", path);
                    else {
                        rc = mountStage2("/mnt/source2/images/stage2.img");
                        if (rc) {
                            umountLoopback("/mnt/source2", "loop1");
                            if (rc == -1)
				foundinvalid = 1;
                        } else {
                            /* JKFIXME: hack because /mnt/source is hard-coded
                             * in mountStage2() */
                            copyUpdatesImg("/mnt/source2/images/updates.img");
                            copyProductImg("/mnt/source2/images/product.img");

                            queryIsoMediaCheck(path);

                            stage = NFS_STAGE_DONE;
                            url = "nfsiso:/mnt/source";
                            break;
                        }
                    }
                }

		/* if we fell through to here we did not find a valid NFS */
		/* source for installation.                               */
		umount("/mnt/source");
                if (foundinvalid) 
                    buf = sdupprintf(_("The %s installation tree in that "
                                       "directory does not seem to match "
                                       "your boot media."), getProductName());
                else
                    buf = sdupprintf(_("That directory does not seem to "
                                       "contain a %s installation tree."),
                                     getProductName());
                newtWinMessage(_("Error"), _("OK"), buf);
                if (loaderData->method >= 0) {
                    loaderData->method = -1;
                }

		
                break;
            } else {
                newtWinMessage(_("Error"), _("OK"),
                               _("That directory could not be mounted from "
                                 "the server."));
                if (loaderData->method >= 0) {
                    loaderData->method = -1;
                }
                break;
            }
        }

        case NFS_STAGE_DONE:
            break;
        }
    }

    free(host);
    free(directory);
    free(mountOpts);

    return url;
}
Example #5
0
int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) {
    char ret[47];
    char * host = NULL, *path = NULL, * file = NULL, * opts = NULL;
    int failed = 0;
    struct networkDeviceConfig netCfg;
    ip_addr_t *tip, *u;

    if (kickstartNetworkUp(loaderData, &netCfg)) {
        logMessage(ERROR, "unable to bring up network");
        return 1;
    }

    /* if they just did 'linux ks', they want us to figure it out from
     * the dhcp/bootp information
     */
    if (url == NULL) {
        if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_NEXTSERVER)) {
            logMessage(ERROR, "no bootserver was found");
            return 1;
        }

        tip = &(netCfg.dev.nextServer);
        if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE)) {
            inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip));
            url = sdupprintf("%s:%s", ret, "/kickstart/");
            logMessage(ERROR, "bootp: no bootfile received");
        } else {
            inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip));
            url = sdupprintf("%s:%s", ret, netCfg.dev.bootFile);
            logMessage(INFO, "bootp: bootfile is %s", netCfg.dev.bootFile);
        }
    } 

    /* get the IP of the target system */
    if (FL_HAVE_CMSCONF(flags)) {
        if (loaderData->ip == NULL) {
            logMessage(ERROR, "getFileFromNfs: no client IP information");
            return 1;
        } else {
            sprintf(ret, "%s", loaderData->ip);
        }
    } else {
        tip = &(netCfg.dev.ipv4);
        u = &(netCfg.dev.ip);
        if ((inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)) == NULL) && (inet_ntop(u->sa_family, IP_ADDR(u), ret, IP_STRLEN(u)) == NULL)) {
            logMessage(ERROR, "getFileFromNfs: no client IP information");
            return 1;
        }
    }

    logMessage(INFO, "url is %s", url);
    getHostandPath(url, &host, &path, ret);

    opts = strchr(host, ':');
    if (opts && (strlen(opts) > 1)) {
        char * c = opts;
        opts = host;
        host = c + 1;
        *c = '\0';
    } else {
        opts = NULL;
    }

    /* nfs has to be a little bit different... split off the last part as
     * the file and then concatenate host + dir path */
    file = strrchr(path, '/');
    if (!file) {
        file = path;
    } else {
        *file++ ='\0';
        host = sdupprintf("%s/%s", host, path);
    }

    logMessage(INFO, "file location: nfs://%s/%s", host, file);

    if (!doPwMount(host, "/tmp/mnt", "nfs", IMOUNT_RDONLY, opts)) {
        char * buf;

        buf = alloca(strlen(file) + 10);
        sprintf(buf, "/tmp/mnt/%s", file);
        if (copyFile(buf, dest)) {
            logMessage(ERROR, "failed to copy file to %s", dest);
            failed = 1;
        }
    } else {
        logMessage(ERROR, "failed to mount nfs source");
        failed = 1;
    }

    umount("/tmp/mnt");
    unlink("/tmp/mnt");

    return failed;
}
Example #6
0
/* this copies the contents of the driver disk to a ramdisk and loads
 * the moduleinfo, etc.  assumes a "valid" driver disk mounted at mntpt */
static int loadDriverDisk(struct loaderData_s *loaderData, char *mntpt) {
    moduleDeps *modDepsPtr = loaderData->modDepsPtr;
    moduleInfoSet modInfo = loaderData->modInfo;
    char file[200], dest[200];
    char * title;
    struct moduleBallLocation * location;
    struct stat sb;
    static int disknum = 0;
    int version = 1;
    int fd, ret;

    /* check for both versions */
    sprintf(file, "%s/rhdd", mntpt);
    if (access(file, R_OK)) {
        version = 0;
        sprintf(file, "%s/rhdd-6.1", mntpt);
        if (access(file, R_OK)) {
            /* this can't happen, we already verified it! */
            return LOADER_BACK;
        } 
    }
    stat(file, &sb);
    title = malloc(sb.st_size + 1);

    fd = open(file, O_RDONLY);
    ret = read(fd, title, sb.st_size);
    if (title[sb.st_size - 1] == '\n')
        sb.st_size--;
    title[sb.st_size] = '\0';
    close(fd);

    sprintf(file, "/tmp/ramfs/DD-%d", disknum);
    mkdirChain(file);

    if (!FL_CMDLINE(flags)) {
        startNewt();
        winStatus(40, 3, _("Loading"), _("Reading driver disk..."));
    }

    sprintf(dest, "/tmp/ramfs/DD-%d", disknum);
    copyDirectory(mntpt, dest);

    location = malloc(sizeof(struct moduleBallLocation));
    location->title = strdup(title);
    location->path = sdupprintf("/tmp/ramfs/DD-%d/modules.cgz", disknum);
    location->version = version;

    char *fwdir = sdupprintf("/tmp/ramfs/DD-%d/firmware", disknum);
    if (!access(fwdir, R_OK|X_OK)) {
        add_fw_search_dir(loaderData, fwdir);
        stop_fw_loader(loaderData);
        start_fw_loader(loaderData);
    }
    free(fwdir);

    sprintf(file, "%s/modinfo", mntpt);
    readModuleInfo(file, modInfo, location, 1);

    sprintf(file, "%s/modules.dep", mntpt);
    mlLoadDeps(modDepsPtr, file);

    sprintf(file, "%s/modules.alias", mntpt);
    pciReadDrivers(file);

    if (!FL_CMDLINE(flags))
        newtPopWindow();

    disknum++;
    return 0;
}
Example #7
0
static int loadUrlImages(struct iurlinfo * ui) {
    char *stage2img;
    char tmpstr1[1024], tmpstr2[1024];
    int rc;

    /*    setupRamdisk();*/

    /* grab the updates.img before netstg1.img so that we minimize our
     * ramdisk usage */
    if (!loadSingleUrlImage(ui, "images/updates.img",
                            "/tmp/ramfs/updates-disk.img", "/tmp/update-disk",
                            "loop7", 1)) {
        copyDirectory("/tmp/update-disk", "/tmp/updates");
        umountLoopback("/tmp/update-disk", "loop7");
        unlink("/tmp/ramfs/updates-disk.img");
        unlink("/tmp/update-disk");
    }

    /* grab the product.img before netstg1.img so that we minimize our
     * ramdisk usage */
    if (!loadSingleUrlImage(ui, "images/product.img",
                            "/tmp/ramfs/product-disk.img", "/tmp/product-disk",
                            "loop7", 1)) {
        copyDirectory("/tmp/product-disk", "/tmp/product");
        umountLoopback("/tmp/product-disk", "loop7");
        unlink("/tmp/ramfs/product-disk.img");
        unlink("/tmp/product-disk");
    }

    /* require 128MB for use of graphical stage 2 due to size of image */
    if (totalMemory() < GUI_STAGE2_RAM) {
	stage2img = "minstg2.img";
	logMessage(WARNING, "URLINSTALL falling back to non-GUI stage2 "
                       "due to insufficient RAM");
    } else {
	stage2img = "stage2.img";
    }

    snprintf(tmpstr1, sizeof(tmpstr1), "images/%s", stage2img);
    snprintf(tmpstr2, sizeof(tmpstr2), "/tmp/ramfs/%s", stage2img);

#ifdef ROCKS
    rc = loadSingleUrlImage(ui, tmpstr1, tmpstr2, "/mnt/runtime", "loop2", 0);
#else
    rc = loadSingleUrlImage(ui, tmpstr1, tmpstr2,
                            "/mnt/runtime", "loop0", 0);
#endif /* ROCKS */

    if (rc) {
        if (rc != 2) 
            newtWinMessage(_("Error"), _("OK"),
                           _("Unable to retrieve the install image."));
        return 1;
    }

#ifndef ROCKS

    /*
     * ROCKS - we don't want to check the stamp since we routinely rebuild
     * the distribution.
     */

    /* now verify the stamp... */
    if (!verifyStamp("/mnt/runtime")) {
	char * buf;

	buf = sdupprintf(_("The %s installation tree in that directory does "
			   "not seem to match your boot media."), 
                         getProductName());

	newtWinMessage(_("Error"), _("OK"), buf);

	umountLoopback("/mnt/runtime", "loop0");
	return 1;
    }

#endif /* ROCKS */

    return 0;

}
/* set up a cdrom, nominally for installation 
 *
 * location: where to mount the cdrom at JKFIXME: ignored
 * interactive: whether or not to prompt about questions/errors (1 is yes)
 *
 * loaderData is the kickstart info, can be NULL meaning no info
 *
 * requirepkgs=1 means CD should have packages, otherwise we just find stage2
 *
 * side effect: found cdrom is mounted as /mnt/source.  stage2 mounted
 * as /mnt/runtime.
 */
char * setupCdrom(char * location, struct loaderData_s * loaderData,
                  moduleInfoSet modInfo, moduleList modLoaded, 
                  moduleDeps modDeps, int interactive, int requirepkgs) {
    int i, r, rc;
    int foundinvalid = 0;
    int stage2inram = 0;
    char * buf;
    char *stage2img;
    struct device ** devices;

    devices = probeDevices(CLASS_CDROM, BUS_UNSPEC, 0);
    if (!devices) {
        logMessage(ERROR, "got to setupCdrom without a CD device");
        return NULL;
    }

    /* JKFIXME: ASSERT -- we have a cdrom device when we get here */
    do {
        for (i = 0; devices[i]; i++) {
            if (!devices[i]->device)
                continue;

            logMessage(INFO,"trying to mount CD device %s", devices[i]->device);

            if (devMakeInode(devices[i]->device, "/tmp/cdrom") != 0) {
                logMessage(ERROR, "unable to create device node for %s",
                           devices[i]->device);
                continue;
            }

            if (!doPwMount("/tmp/cdrom", "/mnt/source", "iso9660", 
                           IMOUNT_RDONLY, NULL)) {
                if (!access("/mnt/source/images/stage2.img", R_OK) &&
                    (!requirepkgs || !access("/mnt/source/.discinfo", R_OK))) {

                    /* if in rescue mode lets copy stage 2 into RAM so we can */
                    /* free up the CD drive and user can have it avaiable to  */
                    /* aid system recovery.                                   */
                    if (FL_RESCUE(flags) && !FL_TEXT(flags) &&
                        totalMemory() > 128000) {
                        rc = copyFile("/mnt/source/images/stage2.img", 
                                      "/tmp/ramfs/stage2.img");
                        stage2img = "/tmp/ramfs/stage2.img";
                        stage2inram = 1;
                    } else {
                        stage2img = strdup("/mnt/source/images/stage2.img");
                        stage2inram = 0;
                    }
	
                    rc = mountStage2(stage2img);

                    /* if we failed, umount /mnt/source and keep going */
                    if (rc) {
                        logMessage(INFO, "mounting stage2 failed");

                        umount("/mnt/source");
                        if (rc == -1)
                            foundinvalid = 1;
                        continue;
                    }

                    /* do the media check */
                    queryCDMediaCheck(devices[i]->device);

                    /* if in rescue mode and we copied stage2 to RAM */
                    /* we can now unmount the CD                     */
                    if (FL_RESCUE(flags) && stage2inram) {
                        umount("/mnt/source");
                        unlink("/tmp/cdrom");
                    }

                    r = asprintf(&buf, "cdrom://%s:/mnt/source",
                                 devices[i]->device);
                    if (r == -1)
                        return NULL;
                    else
                        return buf;

                }

                /* this wasnt the CD we were looking for, clean up and */
                /* try the next CD drive                               */
                umount("/mnt/source");
            }
        }

        if (interactive) {
            char * buf;
            if (foundinvalid)
                buf = sdupprintf(_("No %s CD was found which matches your "
                                   "boot media.  Please insert the %s CD "
                                   "and press %s to retry."), getProductName(),
                                 getProductName(), _("OK"));
            else
                buf = sdupprintf(_("The %s CD was not found in any of your "
                                   "CDROM drives. Please insert the %s CD "
                                   "and press %s to retry."), getProductName(),
                                 getProductName(), _("OK"));

            if (!FL_NOEJECT(flags)) {
                ejectCdrom();
                unlink("/tmp/cdrom");
            } else {
                logMessage(INFO, "noeject in effect, not ejecting cdrom");
            }
            rc = newtWinChoice(_("CD Not Found"),
                               _("OK"), _("Back"), buf, _("OK"));
            free(buf);
            if (rc == 2)
                return NULL;
        } else {
            /* we can't ask them about it, so just return not found */
            return NULL;
        }
    } while (1);

    return NULL;
}