X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Finspect.c;h=f04668db23cd13e5d6f79cd23e3788290ec782a8;hb=a548c9668315844763456c15e89e35e9702b851a;hp=fc8d8df9a0faac4fc370d38578edce20e9daafa4;hpb=3336b5448f12c9eb25bf7a0cecda1315c4cf07ea;p=libguestfs.git diff --git a/src/inspect.c b/src/inspect.c index fc8d8df..f04668d 100644 --- a/src/inspect.c +++ b/src/inspect.c @@ -194,6 +194,7 @@ guestfs__inspect_get_distro (guestfs_h *g, const char *root) char *ret; switch (fs->distro) { case OS_DISTRO_ARCHLINUX: ret = safe_strdup (g, "archlinux"); break; + case OS_DISTRO_CENTOS: ret = safe_strdup (g, "centos"); break; case OS_DISTRO_DEBIAN: ret = safe_strdup (g, "debian"); break; case OS_DISTRO_FEDORA: ret = safe_strdup (g, "fedora"); break; case OS_DISTRO_GENTOO: ret = safe_strdup (g, "gentoo"); break; @@ -203,6 +204,7 @@ guestfs__inspect_get_distro (guestfs_h *g, const char *root) case OS_DISTRO_PARDUS: ret = safe_strdup (g, "pardus"); break; case OS_DISTRO_REDHAT_BASED: ret = safe_strdup (g, "redhat-based"); break; case OS_DISTRO_RHEL: ret = safe_strdup (g, "rhel"); break; + case OS_DISTRO_SCIENTIFIC_LINUX: ret = safe_strdup (g, "scientificlinux"); break; case OS_DISTRO_SLACKWARE: ret = safe_strdup (g, "slackware"); break; case OS_DISTRO_WINDOWS: ret = safe_strdup (g, "windows"); break; case OS_DISTRO_UBUNTU: ret = safe_strdup (g, "ubuntu"); break; @@ -498,69 +500,74 @@ guestfs__inspect_get_hostname (guestfs_h *g, const char *root) } /* Download a guest file to a local temporary file. The file is - * downloaded into g->tmpdir, unless it already exists in g->tmpdir. - * The final name will be g->tmpdir + "/" + basename. Refuse to - * download the guest file if it is larger than max_size. The caller - * does not need to delete the temporary file after use: it will be - * deleted when the handle is cleaned up. + * cached in the temporary directory, and is not downloaded again. + * + * The name of the temporary (downloaded) file is returned. The + * caller must free the pointer, but does *not* need to delete the + * temporary file. It will be deleted when the handle is closed. + * + * Refuse to download the guest file if it is larger than max_size. + * On this and other errors, NULL is returned. + * + * There is actually one cache per 'struct inspect_fs *' in order + * to handle the case of multiple roots. */ -int -guestfs___download_to_tmp (guestfs_h *g, const char *filename, +char * +guestfs___download_to_tmp (guestfs_h *g, struct inspect_fs *fs, + const char *filename, const char *basename, int64_t max_size) { - int tmpdirfd, fd, r = -1; - char buf[32]; + char *r; + int fd; + char devfd[32]; int64_t size; - tmpdirfd = open (g->tmpdir, O_RDONLY); - if (tmpdirfd == -1) { - perrorf (g, _("%s: temporary directory not found"), g->tmpdir); - return -1; + /* Make the basename unique by prefixing it with the fs number. */ + if (asprintf (&r, "%s/%ld-%s", g->tmpdir, fs - g->fses, basename) == -1) { + perrorf (g, "asprintf"); + return NULL; } /* If the file has already been downloaded, return. */ - if (faccessat (tmpdirfd, basename, R_OK, 0) == 0) { - r = 0; - goto out; - } + if (access (r, R_OK) == 0) + return r; /* Check size of remote file. */ size = guestfs_filesize (g, filename); if (size == -1) /* guestfs_filesize failed and has already set error in handle */ - goto out; + goto error; if (size > max_size) { error (g, _("size of %s is unreasonably large (%" PRIi64 " bytes)"), filename, size); - goto out; + goto error; } - fd = openat (tmpdirfd, basename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0600); + fd = open (r, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0600); if (fd == -1) { - perrorf (g, "openat: %s/%s", g->tmpdir, basename); - goto out; + perrorf (g, "open: %s", r); + goto error; } - snprintf (buf, sizeof buf, "/dev/fd/%d", fd); + snprintf (devfd, sizeof devfd, "/dev/fd/%d", fd); - if (guestfs_download (g, filename, buf) == -1) { - unlinkat (tmpdirfd, basename, 0); + if (guestfs_download (g, filename, devfd) == -1) { + unlink (r); close (fd); - goto out; + goto error; } if (close (fd) == -1) { - perrorf (g, "close: %s/%s", g->tmpdir, basename); - unlinkat (tmpdirfd, basename, 0); - goto out; + perrorf (g, "close: %s", r); + unlink (r); + goto error; } - r = 0; - out: - if (tmpdirfd >= 0) - close (tmpdirfd); - return r; + + error: + free (r); + return NULL; } struct inspect_fs *