📄 method.c
字号:
return; } /* Walk through the directories looking for a CD images. */ errno = 0; first = 0; while (1) { char *nextname; char *tdescr, *tstamp; if (first) { first = 1; nextname = isoFile; } else { ent = readdir(dir); if (!ent) break; nextname = ent->d_name; } /* synthesize name of iso from isoDir and file entry */ snprintf(isoImage, sizeof(isoImage), "%s/%s", isoDir, nextname); /* see if this is an iso image */ if (!fileIsIso(isoImage)) { errno = 0; continue; } /* see if its part of the current CD set */ readStampFileFromIso(isoImage, &tstamp, &tdescr); if (strcmp(tstamp, master_timestamp)) { errno = 0; continue; } /* found a valid candidate, proceed */ snprintf(tmpmessage, sizeof(tmpmessage), _("Would you like to perform a checksum " "test of the ISO image:\n\n %s?"), isoImage); rc = newtWinChoice(_("Checksum Test"), _("Test"), _("Skip"), tmpmessage); if (rc == 2) { logMessage(INFO, "mediacheck: skipped checking of %s", isoImage); if (tdescr) free(tdescr); continue; } else { mediaCheckFile(isoImage, tdescr); if (tdescr) free(tdescr); continue; } } free(isoDir); free(master_timestamp); closedir(dir); }/* Recursive */int copyDirectory(char * from, char * to) { DIR * dir; struct dirent * ent; int fd, outfd; char buf[4096]; int i; struct stat sb; char filespec[256]; char filespec2[256]; char link[1024]; mkdir(to, 0755); if (!(dir = opendir(from))) { newtWinMessage(_("Error"), _("OK"), _("Failed to read directory %s: %s"), from, strerror(errno)); return 1; } errno = 0; while ((ent = readdir(dir))) { /* we could lose .a this way, but at least, we lose less */ if ((ent->d_name[0] == '.') && (strlen(ent->d_name) <= 2)) continue; sprintf(filespec, "%s/%s", from, ent->d_name); sprintf(filespec2, "%s/%s", to, ent->d_name); lstat(filespec, &sb); if (S_ISDIR(sb.st_mode)) { logMessage(INFO, "recursively copying %s", filespec); if (copyDirectory(filespec, filespec2)) return 1; } else if (S_ISLNK(sb.st_mode)) { i = readlink(filespec, link, sizeof(link) - 1); link[i] = '\0'; if (symlink(link, filespec2)) { logMessage(WARNING, "failed to symlink %s to %s: %s", filespec2, link, strerror(errno)); } } else { fd = open(filespec, O_RDONLY); if (fd == -1) { logMessage(ERROR, "failed to open %s: %s", filespec, strerror(errno)); return 1; } outfd = open(filespec2, O_RDWR | O_TRUNC | O_CREAT, 0644); if (outfd == -1) { logMessage(WARNING, "failed to create %s: %s", filespec2, strerror(errno)); } else { fchmod(outfd, sb.st_mode & 07777); while ((i = read(fd, buf, sizeof(buf))) > 0) i = write(outfd, buf, i); close(outfd); } close(fd); } errno = 0; } closedir(dir); return 0;}/* * unpack a gzipped cpio ball into a tree rooted at rootDir * returns 0 on success, 1 on failure */int unpackCpioBall(char * ballPath, char * rootDir) { gzFile fd; char *buf, *cwd; int rc = 1; if (access(ballPath, R_OK)) return 1; if (access(rootDir, R_OK)) mkdirChain(rootDir); buf = (char *)malloc(PATH_MAX); cwd = getcwd(buf, PATH_MAX); if ((rc = chdir(rootDir)) == 0) { fd = gunzip_open(ballPath); if (fd) { if (!installCpioFile(fd, NULL, NULL, 0)) { logMessage(INFO, "copied contents of %s into %s", ballPath, rootDir); rc = chdir(cwd); return 0; } } rc = chdir(cwd); } return 1;}void copyUpdatesImg(char * path) { if (!access(path, R_OK)) { if (!mountLoopback(path, "/tmp/update-disk", "loop7")) { copyDirectory("/tmp/update-disk", "/tmp/updates"); umountLoopback("/tmp/update-disk", "loop7"); unlink("/tmp/update-disk"); } else { unpackCpioBall(path, "/tmp/updates"); } }}void copyProductImg(char * path) { if (!access(path, R_OK)) { if (!mountLoopback(path, "/tmp/product-disk", "loop7")) { copyDirectory("/tmp/product-disk", "/tmp/product"); umountLoopback("/tmp/product-disk", "loop7"); unlink("/tmp/product-disk"); } }}/* verify that the stamp files in / of the initrd and the stage2 match */int verifyStamp(char * path) { char *stamp1; char *stamp2; FILE *f; int fail = 0; char * p, *q; stamp1 = alloca(80); stamp2 = alloca(80); /* grab the one from the initrd */ f = fopen("/.buildstamp", "r"); if (!f) { fail = 1; } else { q = fgets(stamp1, 80, f); fclose(f); /* and the runtime */ p = sdupprintf("%s/.buildstamp", path); f = fopen(p, "r"); free(p); if (!f) { fail = 1; } else { q = fgets(stamp2, 80, f); fclose(f); if (strcmp(stamp1, stamp2) != 0) { fail = 1; } } } if (fail == 1) { return 0; } else { return 1; }}/* unmount a second stage, if mounted. Used for CDs and mediacheck mostly, so we can eject CDs. */void umountStage2(void) { umount("/mnt/runtime"); umountLoopback("/mnt/runtime", "loop0");}/* mount a second stage, verify the stamp file, copy updates * Returns 0 on success, 1 on failure to mount, -1 on bad stamp */int mountStage2(char * path) { if (access(path, R_OK)) { return 1; } if (mountLoopback(path, "/mnt/runtime", "loop0")) { return 1; } if (!verifyStamp("/mnt/runtime")) { umountLoopback("/mnt/runtime", "loop0"); return -1; } /* JKFIXME: this is kind of silly.. /mnt/source is hardcoded :/ */ copyUpdatesImg("/mnt/source/images/updates.img"); /* more hard coding */ copyProductImg("/mnt/source/images/product.img"); return 0;}/* copies a second stage from fd to dest and mounts on mntpoint */int copyFileAndLoopbackMount(int fd, char * dest, char * device, char * mntpoint) { int rc; struct stat sb; rc = copyFileFd(fd, dest); stat(dest, &sb); logMessage(DEBUGLVL, "copied %" PRId64 " bytes to %s (%s)", sb.st_size, dest, ((rc) ? " incomplete" : "complete")); if (rc) { /* just to make sure */ unlink(dest); return 1; } if (mountLoopback(dest, mntpoint, device)) { /* JKFIXME: this used to be fatal, but that seems unfriendly */ logMessage(ERROR, "Error mounting /dev/%s on %s (%s)", device, mntpoint, strerror(errno)); unlink(dest); return 1; } return 0;}/* given a device name (w/o '/dev' on it), try to get a file *//* Error codes: 1 - could not create device node 2 - could not mount device as ext2, vfat, or iso9660 3 - file named path not there*/int getFileFromBlockDevice(char *device, char *path, char * dest) { int rc; char file[4096]; logMessage(INFO, "getFileFromBlockDevice(%s, %s)", device, path); if (devMakeInode(device, "/tmp/srcdev")) { logMessage(ERROR, "failed to make device node for /dev/%s", device); return 1; } if (doPwMount("/tmp/srcdev", "/tmp/mnt", "vfat", IMOUNT_RDONLY, NULL) && doPwMount("/tmp/srcdev", "/tmp/mnt", "ext2", IMOUNT_RDONLY, NULL) && doPwMount("/tmp/srcdev", "/tmp/mnt", "iso9660", IMOUNT_RDONLY, NULL)) { logMessage(ERROR, "failed to mount /dev/%s: %s", device, strerror(errno)); return 2; } snprintf(file, sizeof(file), "/tmp/mnt/%s", path); logMessage(INFO, "Searching for file on path %s", file); if (access(file, R_OK)) { rc = 3; } else { copyFile(file, dest); rc = 0; logMessage(INFO, "file copied to %s", dest); } umount("/tmp/mnt"); unlink("/tmp/mnt"); unlink("/tmp/srcdev"); return rc;}void setMethodFromCmdline(char * arg, struct loaderData_s * ld) { char * c, * dup; dup = strdup(arg); c = dup; /* : will let us delimit real information on the method */ if ((c = strtok(c, ":"))) { c = strtok(NULL, ":"); if (!strncmp(arg, "nfs:", 4)) { ld->method = METHOD_NFS; ld->methodData = calloc(sizeof(struct nfsInstallData *), 1); ((struct nfsInstallData *)ld->methodData)->host = strdup(c); if ((c = strtok(NULL, ":"))) { ((struct nfsInstallData *)ld->methodData)->directory = strdup(c); } } else if (!strncmp(arg, "ftp:", 4) || !strncmp(arg, "http:", 5)) { ld->method = strncmp(arg, "ftp", 3) ? METHOD_HTTP : METHOD_FTP; ld->methodData = calloc(sizeof(struct urlInstallData *), 1); ((struct urlInstallData *)ld->methodData)->url = strdup(arg);#if !defined(__s390__) && !defined(__s390x__) } else if (!strncmp(arg, "cdrom:", 6)) { ld->method = METHOD_CDROM;#endif } else if (!strncmp(arg, "harddrive:", 10) || !strncmp(arg, "hd:", 3)) { ld->method = METHOD_HD; ld->methodData = calloc(sizeof(struct hdInstallData *), 1); ((struct hdInstallData *)ld->methodData)->partition = strdup(c); if ((c = strtok(NULL, ":"))) { ((struct hdInstallData *)ld->methodData)->directory = strdup(c); } } } free(dup);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -