Example #1
0
struct guestfs_stat_list *
guestfs_impl_lstatlist (guestfs_h *g, const char *dir, char * const*names)
{
  CLEANUP_FREE_STATNS_LIST struct guestfs_statns_list *r;
  struct guestfs_stat_list *ret;
  size_t i;

  r = guestfs_lstatnslist (g, dir, names);
  if (r == NULL)
    return NULL;

  ret = safe_malloc (g, sizeof *ret);
  ret->len = r->len;
  ret->val = safe_calloc (g, r->len, sizeof (struct guestfs_stat));

  for (i = 0; i < r->len; ++i)
    statns_to_old_stat (&r->val[i], &ret->val[i]);

  return ret;
}
Example #2
0
static int
mount_local_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
                     off_t offset, struct fuse_file_info *fi)
{
  time_t now;
  size_t i;
  char **names;
  CLEANUP_FREE_DIRENT_LIST struct guestfs_dirent_list *ents = NULL;
  DECL_G ();
  DEBUG_CALL ("%s, %p, %ld", path, buf, (long) offset);

  time (&now);

  dir_cache_remove_all_expired (g, now);

  ents = guestfs_readdir (g, path);
  if (ents == NULL)
    RETURN_ERRNO;

  for (i = 0; i < ents->len; ++i) {
    struct stat stat;
    memset (&stat, 0, sizeof stat);

    stat.st_ino = ents->val[i].ino;
    switch (ents->val[i].ftyp) {
    case 'b': stat.st_mode = S_IFBLK; break;
    case 'c': stat.st_mode = S_IFCHR; break;
    case 'd': stat.st_mode = S_IFDIR; break;
    case 'f': stat.st_mode = S_IFIFO; break;
    case 'l': stat.st_mode = S_IFLNK; break;
    case 'r': stat.st_mode = S_IFREG; break;
    case 's': stat.st_mode = S_IFSOCK; break;
    case 'u':
    case '?':
    default:  stat.st_mode = 0;
    }

    /* Copied from the example, which also ignores 'offset'.  I'm
     * not quite sure how this is ever supposed to work on large
     * directories. XXX
     */
    if (filler (buf, ents->val[i].name, &stat, 0))
      break;
  }

  /* Now prepopulate the directory caches.  This step is just an
   * optimization, don't worry if it fails.
   */
  names = malloc ((ents->len + 1) * sizeof (char *));
  if (names) {
    CLEANUP_FREE_STATNS_LIST struct guestfs_statns_list *ss = NULL;
    CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
    char **links;

    for (i = 0; i < ents->len; ++i)
      names[i] = ents->val[i].name;
    names[i] = NULL;

    ss = guestfs_lstatnslist (g, path, names);
    if (ss) {
      for (i = 0; i < ss->len; ++i) {
        if (ss->val[i].st_ino >= 0) {
          struct stat statbuf;

          memset (&statbuf, 0, sizeof statbuf);
          statbuf.st_dev = ss->val[i].st_dev;
          statbuf.st_ino = ss->val[i].st_ino;
          statbuf.st_mode = ss->val[i].st_mode;
          statbuf.st_nlink = ss->val[i].st_nlink;
          statbuf.st_uid = ss->val[i].st_uid;
          statbuf.st_gid = ss->val[i].st_gid;
          statbuf.st_rdev = ss->val[i].st_rdev;
          statbuf.st_size = ss->val[i].st_size;
          statbuf.st_blksize = ss->val[i].st_blksize;
          statbuf.st_blocks = ss->val[i].st_blocks;
          statbuf.st_atime = ss->val[i].st_atime_sec;
#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
          statbuf.st_atim.tv_nsec = ss->val[i].st_atime_nsec;
#endif
          statbuf.st_mtime = ss->val[i].st_mtime_sec;
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
          statbuf.st_mtim.tv_nsec = ss->val[i].st_mtime_nsec;
#endif
          statbuf.st_ctime = ss->val[i].st_ctime_sec;
#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
          statbuf.st_ctim.tv_nsec = ss->val[i].st_ctime_nsec;
#endif

          lsc_insert (g, path, names[i], now, &statbuf);
        }
      }
    }

    xattrs = guestfs_lxattrlist (g, path, names);
    if (xattrs) {
      size_t ni, num;
      struct guestfs_xattr *first;
      struct guestfs_xattr_list *copy;

      for (i = 0, ni = 0; i < xattrs->len; ++i, ++ni) {
        /* assert (strlen (xattrs->val[i].attrname) == 0); */
        if (xattrs->val[i].attrval_len > 0) {
          ++i;
          first = &xattrs->val[i];
          num = 0;
          for (; i < xattrs->len && strlen (xattrs->val[i].attrname) > 0; ++i)
            num++;

          copy = copy_xattr_list (g, first, num);
          if (copy)
            xac_insert (g, path, names[ni], now, copy);

          i--;
        }
      }
    }

    links = guestfs_readlinklist (g, path, names);
    if (links) {
      for (i = 0; names[i] != NULL; ++i) {
        if (links[i][0])
          /* Note that rlc_insert owns the string links[i] after this, */
          rlc_insert (g, path, names[i], now, links[i]);
        else
          /* which is why we have to free links[i] here. */
          free (links[i]);
      }
      free (links);             /* free the array, not the strings */
    }

    free (names);
  }

  return 0;
}