📄 method.c
字号:
/* * method.c - generic install method setup functions * * Erik Troan <ewt@redhat.com> * Matt Wilson <msw@redhat.com> * Michael Fulbright <msf@redhat.com> * Jeremy Katz <katzj@redhat.com> * * Copyright 2002 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 <ctype.h>#include <dirent.h>#include <errno.h>#include <fcntl.h>#include <inttypes.h>#include <libgen.h>#include <newt.h>#include <stdlib.h>#include <string.h>#include <sys/ioctl.h>#include <sys/mount.h>#include <sys/types.h>#include <unistd.h>#include <libgen.h>#include "loader.h"#include "loadermisc.h"#include "log.h"#include "lang.h"#include "mediacheck.h"#include "method.h"#include "../isys/imount.h"#include "../isys/isys.h"#include "../isys/cpio.h"#include "devt.h"#include "nfsinstall.h"#include "hdinstall.h"#include "urlinstall.h"/* boot flags */extern int flags;int umountLoopback(char * mntpoint, char * device) { int loopfd; umount(mntpoint); logMessage(INFO, "umounting loopback %s %s", mntpoint, device); devMakeInode(device, "/tmp/loop"); loopfd = open("/tmp/loop", O_RDONLY); if (ioctl(loopfd, LOOP_CLR_FD, 0) == -1) logMessage(ERROR, "LOOP_CLR_FD failed for %s %s (%s)", mntpoint, device, strerror(errno)); close(loopfd); return 0;}int mountLoopback(char * fsystem, char * mntpoint, char * device) { struct loop_info loopInfo; int targfd, loopfd; char *filename; mkdirChain(mntpoint); filename = alloca(15 + strlen(device)); sprintf(filename, "/tmp/%s", device); mkdirChain(mntpoint);#ifdef O_DIRECT targfd = open(fsystem, O_RDONLY | O_DIRECT); if (targfd == -1) {#endif targfd = open(fsystem, O_RDONLY); if (targfd == -1) { logMessage(ERROR, "open file to loop mount %s failed", fsystem); return LOADER_ERROR; }#ifdef O_DIRECT }#endif devMakeInode(device, filename); loopfd = open(filename, O_RDONLY); if (loopfd == -1) { logMessage(ERROR, "unable to open loop device %s", filename); return LOADER_ERROR; } logMessage(INFO, "mntloop %s on %s as %s fd is %d", device, mntpoint, fsystem, loopfd); if (ioctl(loopfd, LOOP_SET_FD, targfd)) { logMessage(ERROR, "LOOP_SET_FD failed: %s", strerror(errno)); ioctl(loopfd, LOOP_CLR_FD, 0); close(targfd); close(loopfd); return LOADER_ERROR; } close(targfd); memset(&loopInfo, 0, sizeof(loopInfo)); strncpy(loopInfo.lo_name, basename(fsystem), 63); if (ioctl(loopfd, LOOP_SET_STATUS, &loopInfo)) { logMessage(ERROR, "LOOP_SET_STATUS failed: %s", strerror(errno)); close(loopfd); return LOADER_ERROR; } close(loopfd); /* FIXME: really, mountLoopback() should take a list of "valid" * filesystems for the specific type of image being mounted */ if (doPwMount(filename, mntpoint, "iso9660", IMOUNT_RDONLY, NULL)) { if (doPwMount(filename, mntpoint, "ext2", IMOUNT_RDONLY, NULL)) { if (doPwMount(filename, mntpoint, "squashfs", IMOUNT_RDONLY, NULL)) { if (doPwMount(filename, mntpoint, "cramfs", IMOUNT_RDONLY, NULL)) { if (doPwMount(filename, mntpoint, "vfat", IMOUNT_RDONLY, NULL)) { logMessage(ERROR, "failed to mount loop: %s", strerror(errno)); loopfd = open(filename, O_RDONLY); ioctl(loopfd, LOOP_CLR_FD, 0); close(loopfd); return LOADER_ERROR; } } } } } return 0;}/* returns the *absolute* path (malloced) to the #1 iso image */char * validIsoImages(char * dirName, int *foundinvalid) { DIR * dir; struct dirent * ent; char isoImage[1024]; if (!(dir = opendir(dirName))) { newtWinMessage(_("Error"), _("OK"), _("Failed to read directory %s: %s"), dirName, strerror(errno)); return 0; } /* Walk through the directories looking for a CD image. */ errno = 0; while ((ent = readdir(dir))) { snprintf(isoImage, sizeof(isoImage), "%s/%s", dirName, ent->d_name); if (!fileIsIso(isoImage)) { errno = 0; continue; } if (mountLoopback(isoImage, "/tmp/loopimage", "loop7")) { logMessage(WARNING, "failed to mount %s", isoImage); errno = 0; continue; } if (mountLoopback("/tmp/loopimage/images/stage2.img", "/mnt/runtime", "loop0")) { umountLoopback("/mnt/runtime", "loop0"); } else { if (verifyStamp("/mnt/runtime")) { umountLoopback("/mnt/runtime", "loop0"); umountLoopback("/tmp/loopimage", "loop7"); break; } logMessage(ERROR, "disc %s is not the right image", isoImage); umountLoopback("/mnt/runtime", "loop0"); if (foundinvalid) *foundinvalid = 1; } umountLoopback("/tmp/loopimage", "loop7"); errno = 0; } closedir(dir); if (!ent) return NULL; return strdup(isoImage);}/* get timestamp and description of ISO image from stamp file *//* returns 0 on success, -1 otherwise */int readStampFileFromIso(char *file, char **timestamp, char **releasedescr) { DIR * dir; FILE *f; struct dirent * ent; struct stat sb; char *stampfile; char *descr, *tstamp; char tmpstr[1024]; int filetype; int rc; lstat(file, &sb); if (S_ISBLK(sb.st_mode)) { filetype = 1; if (doPwMount(file, "/tmp/testmnt", "iso9660", IMOUNT_RDONLY, NULL)) { logMessage(ERROR, "Failed to mount device %s to get description", file); return -1; } } else if (S_ISREG(sb.st_mode)) { filetype = 2; if (mountLoopback(file, "/tmp/testmnt", "loop6")) { logMessage(ERROR, "Failed to mount iso %s to get description", file); return -1; } } else { logMessage(ERROR, "Unknown type of file %s to get description", file); return -1; } if (!(dir = opendir("/tmp/testmnt"))) { umount("/tmp/testmnt"); if (filetype == 2) umountLoopback("/tmp/testmnt", "loop6"); return -1; } errno = 0; stampfile = NULL; while ((ent = readdir(dir))) { if (!strncmp(ent->d_name, ".discinfo", 9)) { stampfile = strdup(".discinfo"); break; } } closedir(dir); descr = NULL; tstamp = NULL; if (stampfile) { snprintf(tmpstr, sizeof(tmpstr), "/tmp/testmnt/%s", stampfile); f = fopen(tmpstr, "r"); if (f) { char *tmpptr; /* readtime stamp line */ tmpptr = fgets(tmpstr, sizeof(tmpstr), f); if (tmpptr) tstamp = strdup(tmpstr); /* now read OS description line */ if (tmpptr) tmpptr = fgets(tmpstr, sizeof(tmpstr), f); if (tmpptr) descr = strdup(tmpstr); /* skip over arch */ if (tmpptr) tmpptr = fgets(tmpstr, sizeof(tmpstr), f); /* now get the CD number */ if (tmpptr) { unsigned int len; char *p, *newstr; tmpptr = fgets(tmpstr, sizeof(tmpstr), f); /* nuke newline from end of descr, stick number on end*/ for (p=descr+strlen(descr); p != descr && !isspace(*p); p--); *p = '\0'; len = strlen(descr) + strlen(tmpstr) + 10; newstr = malloc(len); strncpy(newstr, descr, len-1); strncat(newstr, " ", len-1); /* is this a DVD or not? If disc id has commas, like */ /* "1,2,3", its a DVD */ if (strchr(tmpstr, ',')) strncat(newstr, "DVD\n", len-1); else { strncat(newstr, "disc ", len-1); strncat(newstr, tmpstr, len-1); } free(descr); descr = newstr; } fclose(f); } } free(stampfile); umount("/tmp/testmnt"); if (filetype == 2) umountLoopback("/tmp/testmnt", "loop6"); if (descr != NULL && tstamp != NULL) { descr[strlen(descr)-1] = '\0'; *releasedescr = descr; tstamp[strlen(tstamp)-1] = '\0'; *timestamp = tstamp; rc = 0; } else { rc = 1; } return rc;}/* XXX this ignores "location", which should be fixed * * Given a starting isoFile, will offer choice to mediacheck it and * all other ISO images in the same directory with the same stamp */void queryIsoMediaCheck(char *isoFile) { DIR * dir; struct dirent * ent; char *isoDir; char isoImage[1024]; char tmpmessage[1024]; char *master_timestamp; char *tmpstr; int rc, first; /* dont bother to test in automated installs */ if (FL_KICKSTART(flags) && !FL_MEDIACHECK(flags)) return; /* if they did not specify to mediacheck explicitely then return */ if (!FL_MEDIACHECK(flags)) return; /* check that file is actually an iso */ if (!fileIsIso(isoFile)) return; /* get stamp of isoFile, free descr since we dont care */ readStampFileFromIso(isoFile, &master_timestamp, &tmpstr); free(tmpstr); /* get base path from isoFile */ tmpstr = strdup(isoFile); isoDir = strdup(dirname(tmpstr)); free(tmpstr); logMessage(DEBUGLVL, "isoFile = %s", isoFile); logMessage(DEBUGLVL, "isoDir = %s", isoDir); logMessage(DEBUGLVL, "Master Timestemp = %s", master_timestamp); if (!(dir = opendir(isoDir))) { newtWinMessage(_("Error"), _("OK"), _("Failed to read directory %s: %s"), isoDir, strerror(errno)); free(isoDir); free(master_timestamp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -