예제 #1
0
int loop_free(char *loop_dev) {
    FILE *loop_fp;

    message(DEBUG, "Called loop_free(%s)\n", loop_dev);

    if ( is_blk(loop_dev) < 0 ) {
        message(ERROR, "Loop device is not a valid block device: %s\n", loop_dev);
        ABORT(255);
    }

    if ( ( loop_fp = fopen(loop_dev, "r") ) == NULL ) { // Flawfinder: ignore (only opening read only, and must be a block device)
        message(VERBOSE, "Could not open loop device %s: %s\n", loop_dev, strerror(errno));
        return(-1);
    }

    message(DEBUG, "Called disassociate_loop(loop_fp)\n");

    message(VERBOSE2, "Disassociating image from loop device\n");
    if ( ioctl(fileno(loop_fp), LOOP_CLR_FD, 0) < 0 ) {
        message(ERROR, "Could not clear loop device %s: (%d) %s\n", loop_dev, errno, strerror(errno));
        return(-1);
    }

    message(DEBUG, "Returning disassociate_loop(loop_fp) = 0\n");
    return(0);
}
예제 #2
0
파일: ls.c 프로젝트: DanLipsitt/libguestfs
/* This is the function which is called to display all files and
 * directories, and it's where the magic happens.  We are called with
 * full stat and extended attributes for each file, so there is no
 * penalty for displaying anything in those structures.  However if we
 * need other things (eg. checksum) we may have to go back to the
 * appliance and then there can be a very large penalty.
 */
static int
show_file (const char *dir, const char *name,
           const struct guestfs_stat *stat,
           const struct guestfs_xattr_list *xattrs,
           void *unused)
{
  const char *filetype;
  CLEANUP_FREE char *path = NULL, *csum = NULL, *link = NULL;

  /* Display the basic fields. */
  output_start_line ();

  if (is_reg (stat->mode))
    filetype = "-";
  else if (is_dir (stat->mode))
    filetype = "d";
  else if (is_chr (stat->mode))
    filetype = "c";
  else if (is_blk (stat->mode))
    filetype = "b";
  else if (is_fifo (stat->mode))
    filetype = "p";
  else if (is_lnk (stat->mode))
    filetype = "l";
  else if (is_sock (stat->mode))
    filetype = "s";
  else
    filetype = "u";
  output_string (filetype);
  output_int64_perms (stat->mode & 07777);

  output_int64_size (stat->size);

  /* Display extra fields when enabled. */
  if (enable_uids) {
    output_int64_uid (stat->uid);
    output_int64_uid (stat->gid);
  }

  if (enable_times) {
    output_int64_time (stat->atime);
    output_int64_time (stat->mtime);
    output_int64_time (stat->ctime);
  }

  if (enable_extra_stats) {
    output_int64_dev (stat->dev);
    output_int64 (stat->ino);
    output_int64 (stat->nlink);
    output_int64_dev (stat->rdev);
    output_int64 (stat->blocks);
  }

  /* Disabled for now -- user would definitely want these to be interpreted.
  if (enable_xattrs)
    output_xattrs (xattrs);
  */

  path = full_path (dir, name);

  if (checksum && is_reg (stat->mode)) {
    csum = guestfs_checksum (g, checksum, path);
    if (!csum)
      exit (EXIT_FAILURE);

    output_string (csum);
  }

  output_string (path);

  if (is_lnk (stat->mode))
    /* XXX Fix this for NTFS. */
    link = guestfs_readlink (g, path);
  if (link)
    output_string_link (link);

  output_end_line ();

  return 0;
}
예제 #3
0
int loop_bind(FILE *image_fp, char **loop_dev, int autoclear) {
    struct loop_info64 lo64 = {0};
    int i;

    message(DEBUG, "Called loop_bind(image_fp, **{loop_dev)\n");

    if ( autoclear > 0 ) {
        lo64.lo_flags = LO_FLAGS_AUTOCLEAR;
    }
    lo64.lo_offset = image_offset(image_fp);

    for( i=0; i < MAX_LOOP_DEVS; i++ ) {
        char *test_loopdev = strjoin("/dev/loop", int2str(i));
        FILE *loop_fp;

        if ( is_blk(test_loopdev) < 0 ) {
            message(VERBOSE, "Creating loop device: %s\n", test_loopdev);
            if ( mknod(test_loopdev, S_IFBLK | 0644, makedev(7, i)) < 0 ) {
                message(ERROR, "Could not create %s: %s\n", test_loopdev, strerror(errno));
                ABORT(255);
            }
        }

        if ( ( loop_fp = fopen(test_loopdev, "r+") ) == NULL ) { // Flawfinder: ignore (not user modifyable)
            message(VERBOSE, "Could not open loop device %s: %s\n", test_loopdev, strerror(errno));
            continue;
        }

        message(VERBOSE2, "Attempting to associate image pointer to loop device\n");
        if ( ioctl(fileno(loop_fp), LOOP_SET_FD, fileno(image_fp)) < 0 ) {
            if ( errno == 16 ) {
                message(VERBOSE3, "Loop device is in use: %s\n", test_loopdev);
                fclose(loop_fp);
                continue;
            } else {
                message(WARNING, "Could not associate image to loop %s: %s\n", test_loopdev, strerror(errno));
                fclose(loop_fp);
                continue;
            }
        }

        message(VERBOSE, "Found valid loop device: %s\n", test_loopdev);

        message(VERBOSE2, "Setting loop device flags\n");
        if ( ioctl(fileno(loop_fp), LOOP_SET_STATUS64, &lo64) < 0 ) {
            fprintf(stderr, "ERROR: Failed to set loop flags on loop device: %s\n", strerror(errno));
            (void)ioctl(fileno(loop_fp), LOOP_CLR_FD, 0);
            (void)loop_free(*loop_dev);
            ABORT(255);
        }
        *loop_dev = strdup(test_loopdev);

        message(VERBOSE, "Using loop device: %s\n", *loop_dev);

        message(DEBUG, "Returning loop_bind(image_fp) = 0\n");

        return(0);
    }

    message(ERROR, "No valid loop devices available\n");
    ABORT(255);

    return(-1);
}
예제 #4
0
파일: diff.c 프로젝트: kelledge/libguestfs
static void
output_file (guestfs_h *g, struct file *file)
{
    const char *filetype;
    size_t i;
    CLEANUP_FREE char *link = NULL;

    if (is_reg (file->stat->st_mode))
        filetype = "-";
    else if (is_dir (file->stat->st_mode))
        filetype = "d";
    else if (is_chr (file->stat->st_mode))
        filetype = "c";
    else if (is_blk (file->stat->st_mode))
        filetype = "b";
    else if (is_fifo (file->stat->st_mode))
        filetype = "p";
    else if (is_lnk (file->stat->st_mode))
        filetype = "l";
    else if (is_sock (file->stat->st_mode))
        filetype = "s";
    else
        filetype = "u";

    output_string (filetype);
    output_int64_perms (file->stat->st_mode & 07777);

    output_int64_size (file->stat->st_size);

    /* Display extra fields when enabled. */
    if (enable_uids) {
        output_int64_uid (file->stat->st_uid);
        output_int64_uid (file->stat->st_gid);
    }

    if (enable_times) {
        if (atime)
            output_int64_time (file->stat->st_atime_sec, file->stat->st_atime_nsec);
        output_int64_time (file->stat->st_mtime_sec, file->stat->st_mtime_nsec);
        output_int64_time (file->stat->st_ctime_sec, file->stat->st_ctime_nsec);
    }

    if (enable_extra_stats) {
        output_int64_dev (file->stat->st_dev);
        output_int64 (file->stat->st_ino);
        output_int64 (file->stat->st_nlink);
        output_int64_dev (file->stat->st_rdev);
        output_int64 (file->stat->st_blocks);
    }

    if (file->csum)
        output_string (file->csum);

    output_string (file->path);

    if (is_lnk (file->stat->st_mode)) {
        /* XXX Fix this for NTFS. */
        link = guestfs_readlink (g, file->path);
        if (link)
            output_string_link (link);
    }

    if (enable_xattrs) {
        for (i = 0; i < file->xattrs->len; ++i) {
            output_string (file->xattrs->val[i].attrname);
            output_binary (file->xattrs->val[i].attrval,
                           file->xattrs->val[i].attrval_len);
        }
    }
}
예제 #5
0
int main(int argc, char ** argv) {
    uid_t uid = geteuid();

    if ( argv[1] == NULL || argv[2] == NULL ) {
        fprintf(stderr, "USAGE: %s [attach/detach] [image/loop]\n", argv[0]);
        return(1);
    }

    message(VERBOSE, "Checking calling user\n");
    if ( uid != 0 ) {
        message(ERROR, "Calling user must be root\n");
        ABORT(1);
    }

    message(VERBOSE, "Checking command: %s\n", argv[1]);
    if ( strcmp(argv[1], "attach") == 0 ) {
        FILE *containerimage_fp;
        char *containerimage;
        char *loop_dev;

        message(VERBOSE, "Preparing to attach container to loop\n");

        containerimage = xstrdup(argv[2]);

        message(VERBOSE, "Evaluating image: %s\n", containerimage);
    
        message(VERBOSE, "Checking if container image exists\n");
        if ( is_file(containerimage) < 0 ) {
            message(ERROR, "Container image not found: %s\n", containerimage);
            ABORT(1);
        }

        message(VERBOSE, "Checking if container can be opened read/write\n");
        if ( !( containerimage_fp = fopen(containerimage, "r+") ) ) { // Flawfinder: ignore
            message(ERROR, "Could not open image %s: %s\n", containerimage, strerror(errno));
            ABORT(255);
        }

        message(DEBUG, "Binding container to loop interface\n");
        if ( loop_bind(containerimage_fp, &loop_dev, 0) < 0 ) {
            message(ERROR, "Could not bind image to loop!\n");
            ABORT(255);
        }

        printf("%s\n", loop_dev);
    } else if (strcmp(argv[1], "detach") == 0 ) {
        char *loop_dev;

        loop_dev = xstrdup(argv[2]);

        message(VERBOSE, "Preparing to detach loop: %s\n", loop_dev);

        message(VERBOSE, "Checking loop device\n");
        if ( is_blk(loop_dev) < 0 ) {
            message(ERROR, "Block device not found: %s\n", loop_dev);
            ABORT(255);
        }

        message(VERBOSE, "Unbinding container image from loop\n");
        if ( loop_free(loop_dev) < 0 ) {
            message(ERROR, "Failed to detach loop device: %s\n", loop_dev);
            ABORT(255);
        }

    }

    return(0);
}