📄 driverdisk.c
字号:
/* * driverdisk.c - driver disk functionality * * Jeremy Katz <katzj@redhat.com> * * Copyright 2002-2003 Red Hat, Inc. * * This software may be freely redistributed under the terms of the GNU * General 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. */#include <errno.h>#include <fcntl.h>#include <kudzu/kudzu.h>#include <newt.h>#include <popt.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/stat.h>#include <unistd.h>#include "loader.h"#include "log.h"#include "loadermisc.h"#include "lang.h"#include "method.h"#include "modules.h"#include "moduledeps.h"#include "moduleinfo.h"#include "windows.h"#include "hardware.h"#include "driverdisk.h"#include "getparts.h"#include "dirbrowser.h"#include "nfsinstall.h"#include "urlinstall.h"#include "../isys/isys.h"#include "../isys/imount.h"#include "../isys/eddsupport.h"/* boot flags */extern int flags;static char * driverDiskFiles[] = { "modinfo", "modules.dep", "modules.cgz", "modules.alias", NULL };static char * optionalFiles[] = { "modules.pcimap", "pci.ids", "pcitable", NULL };static int verifyDriverDisk(char *mntpt) { char ** fnPtr; char file[200]; struct stat sb; for (fnPtr = driverDiskFiles; *fnPtr; fnPtr++) { sprintf(file, "%s/%s", mntpt, *fnPtr); if (access(file, R_OK)) { logMessage(ERROR, "cannot find %s, bad driver disk", file); return LOADER_BACK; } } /* check for both versions */ sprintf(file, "%s/rhdd", mntpt); if (access(file, R_OK)) { logMessage(DEBUGLVL, "not a new format driver disk, checking for old"); sprintf(file, "%s/rhdd-6.1", mntpt); if (access(file, R_OK)) { logMessage(ERROR, "can't find either driver disk identifier, bad " "driver disk"); } } /* side effect: file is still mntpt/ddident */ stat(file, &sb); if (!sb.st_size) return LOADER_BACK; return LOADER_OK;}/* 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(moduleInfoSet modInfo, moduleList modLoaded, moduleDeps * modDepsPtr, char *mntpt) { char file[200], dest[200]; char * title; char ** fnPtr; 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...")); } for (fnPtr = driverDiskFiles; *fnPtr; fnPtr++) { sprintf(file, "%s/%s", mntpt, *fnPtr); sprintf(dest, "/tmp/ramfs/DD-%d/%s", disknum, *fnPtr); copyFile(file, dest); } for (fnPtr = optionalFiles; *fnPtr; fnPtr++) { sprintf(file, "%s/%s", mntpt, *fnPtr); sprintf(dest, "/tmp/ramfs/DD-%d/%s", disknum, *fnPtr); copyFile(file, dest); } location = malloc(sizeof(struct moduleBallLocation)); location->title = strdup(title); location->path = sdupprintf("/tmp/ramfs/DD-%d/modules.cgz", disknum); location->version = version; 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;}/* Get the list of removable devices (floppy/cdrom) available. Used to * find suitable devices for update disk / driver disk source. * Returns the number of devices. ***devNames will be a NULL-terminated list * of device names */int getRemovableDevices(char *** devNames) { struct device **devices, **floppies, **cdroms, **disks; int numDevices = 0; int i = 0, j = 0; floppies = probeDevices(CLASS_FLOPPY, BUS_IDE | BUS_SCSI | BUS_MISC, PROBE_LOADED); cdroms = probeDevices(CLASS_CDROM, BUS_IDE | BUS_SCSI | BUS_MISC, PROBE_LOADED); disks = probeDevices(CLASS_HD, BUS_IDE | BUS_SCSI | BUS_MISC, PROBE_LOADED); /* we should probably take detached into account here, but it just * means we use a little bit more memory than we really need to */ if (floppies) for (i = 0; floppies[i]; i++) numDevices++; if (cdroms) for (i = 0; cdroms[i]; i++) numDevices++; if (disks) for (i = 0; disks[i]; i++) numDevices++; /* JKFIXME: better error handling */ if (!numDevices) { logMessage(ERROR, "no devices found to load drivers from"); return numDevices; } devices = malloc((numDevices + 1) * sizeof(**devices)); i = 0; if (floppies) for (j = 0; floppies[j]; j++) if ((floppies[j]->detached == 0) && (floppies[j]->device != NULL)) devices[i++] = floppies[j]; if (cdroms) for (j = 0; cdroms[j]; j++) if ((cdroms[j]->detached == 0) && (cdroms[j]->device != NULL)) devices[i++] = cdroms[j]; if (disks) for (j = 0; disks[j]; j++) if ((disks[j]->detached == 0) && (disks[j]->device != NULL)) devices[i++] = disks[j]; devices[i] = NULL; numDevices = i; for (i = 0; devices[i]; i++) { logMessage(DEBUGLVL, "devices[%d] is %s", i, devices[i]->device); } *devNames = malloc((numDevices + 1) * sizeof(*devNames)); for (i = 0; devices[i] && (i < numDevices); i++) (*devNames)[i] = strdup(devices[i]->device); free(devices); (*devNames)[i] = NULL; if (i != numDevices) logMessage(WARNING, "somehow numDevices != len(devices)"); return numDevices;}/* Prompt for loading a driver from "media" * * class: type of driver to load. * usecancel: if 1, use cancel instead of back */int loadDriverFromMedia(int class, moduleList modLoaded, moduleDeps * modDepsPtr, moduleInfoSet modInfo, int usecancel, int noprobe) { char * device = NULL, * part = NULL, * ddfile = NULL; char ** devNames = NULL; enum { DEV_DEVICE, DEV_PART, DEV_CHOOSEFILE, DEV_LOADFILE, DEV_INSERT, DEV_LOAD, DEV_PROBE, DEV_DONE } stage = DEV_DEVICE; int rc, num = 0; int dir = 1; int found = 0, before = 0; while (stage != DEV_DONE) { switch(stage) { case DEV_DEVICE: rc = getRemovableDevices(&devNames); if (rc == 0) return LOADER_BACK; /* we don't need to ask which to use if they only have one */ if (rc == 1) { device = strdup(devNames[0]); free(devNames); if (dir == -1) return LOADER_BACK; stage = DEV_PART; break; } dir = 1; startNewt(); rc = newtWinMenu(_("Driver Disk Source"), _("You have multiple devices which could serve " "as sources for a driver disk. Which would " "you like to use?"), 40, 10, 10, rc < 6 ? rc : 6, devNames, &num, _("OK"), (usecancel) ? _("Cancel") : _("Back"), NULL); if (rc == 2) { free(devNames); return LOADER_BACK; } device = strdup(devNames[num]); free(devNames); stage = DEV_PART; case DEV_PART: { char ** part_list = getPartitionsList(device); int nump = 0, num = 0; if (part != NULL) free(part); if ((nump = lenPartitionsList(part_list)) == 0) { if (dir == -1) stage = DEV_DEVICE; else stage = DEV_INSERT; break; } dir = 1; startNewt(); rc = newtWinMenu(_("Driver Disk Source"), _("There are multiple partitions on this device " "which could contain the driver disk image. " "Which would you like to use?"), 40, 10, 10, nump < 6 ? nump : 6, part_list, &num, _("OK"), _("Back"), NULL); if (rc == 2) { freePartitionsList(part_list); stage = DEV_DEVICE; dir = -1; break; } part = strdup(part_list[num]); stage = DEV_CHOOSEFILE; } case DEV_CHOOSEFILE: { if (part == NULL) { logMessage(ERROR, "somehow got to choosing file with a NULL part, going back"); stage = DEV_PART; break; } /* make sure nothing is mounted when we get here */ num = umount("/tmp/dpart"); if (num == -1) { logMessage(ERROR, "error unmounting: %s", strerror(errno)); if ((errno != EINVAL) && (errno != ENOENT)) exit(1); } logMessage(INFO, "trying to mount %s as partition", part); devMakeInode(part + 5, "/tmp/ddpart"); if (doPwMount("/tmp/ddpart", "/tmp/dpart", "vfat", IMOUNT_RDONLY, NULL)) { if (doPwMount("/tmp/ddpart", "/tmp/dpart", "ext2", IMOUNT_RDONLY, NULL)) { if (doPwMount("/tmp/ddpart", "/tmp/dpart", "iso9660", IMOUNT_RDONLY, NULL)) { newtWinMessage(_("Error"), _("OK"), _("Failed to mount partition.")); stage = DEV_PART;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -