コード例 #1
0
static OstreeRepoCommitFilterResult
commit_filter (OstreeRepo         *self,
               const char         *path,
               GFileInfo          *file_info,
               gpointer            user_data)
{
  GHashTable *mode_adds = user_data;
  gpointer value;

  if (opt_owner_uid >= 0)
    g_file_info_set_attribute_uint32 (file_info, "unix::uid", opt_owner_uid);
  if (opt_owner_gid >= 0)
    g_file_info_set_attribute_uint32 (file_info, "unix::gid", opt_owner_gid);

  if (mode_adds && g_hash_table_lookup_extended (mode_adds, path, NULL, &value))
    {
      guint current_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
      guint mode_add = GPOINTER_TO_UINT (value);
      g_file_info_set_attribute_uint32 (file_info, "unix::mode",
                                        current_mode | mode_add);
      g_hash_table_remove (mode_adds, path);
    }
  
  return OSTREE_REPO_COMMIT_FILTER_ALLOW;
}
コード例 #2
0
static OstreeRepoCommitFilterResult
commit_filter (OstreeRepo *repo,
               const char *path,
               GFileInfo *file_info,
               gpointer user_data)
{
  guint current_mode;

  /* No user info */
  g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0);

  /* No setuid */
  current_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
  g_file_info_set_attribute_uint32 (file_info, "unix::mode", current_mode & ~07000);

  if (g_str_equal (path, "/") ||
      g_str_equal (path, "/metadata") ||
      g_str_has_prefix (path, "/files") ||
      g_str_has_prefix (path, "/export"))
    {
      g_debug ("commit filter, allow: %s", path);
      return OSTREE_REPO_COMMIT_FILTER_ALLOW;
    }
  else
    {
      g_debug ("commit filter, skip: %s", path);
      return OSTREE_REPO_COMMIT_FILTER_SKIP;
    }
}
コード例 #3
0
ファイル: ostree-core.c プロジェクト: aperezdc/ostree
gboolean
ostree_zlib_file_header_parse (GVariant         *metadata,
                               GFileInfo       **out_file_info,
                               GVariant        **out_xattrs,
                               GError          **error)
{
  gboolean ret = FALSE;
  guint64 size;
  guint32 uid, gid, mode, rdev;
  const char *symlink_target;
  ot_lobj GFileInfo *ret_file_info = NULL;
  ot_lvariant GVariant *ret_xattrs = NULL;

  g_variant_get (metadata, "(tuuuu&s@a(ayay))", &size,
                 &uid, &gid, &mode, &rdev,
                 &symlink_target, &ret_xattrs);

  size = GUINT64_FROM_BE (size);
  uid = GUINT32_FROM_BE (uid);
  gid = GUINT32_FROM_BE (gid);
  mode = GUINT32_FROM_BE (mode);
  rdev = GUINT32_FROM_BE (rdev);

  ret_file_info = g_file_info_new ();
  g_file_info_set_size (ret_file_info, size);
  g_file_info_set_attribute_uint32 (ret_file_info, "standard::type", ot_gfile_type_for_mode (mode));
  g_file_info_set_attribute_boolean (ret_file_info, "standard::is-symlink", S_ISLNK (mode));
  g_file_info_set_attribute_uint32 (ret_file_info, "unix::uid", uid);
  g_file_info_set_attribute_uint32 (ret_file_info, "unix::gid", gid);
  g_file_info_set_attribute_uint32 (ret_file_info, "unix::mode", mode);

  if (S_ISREG (mode))
    {
      ;
    }
  else if (S_ISLNK (mode))
    {
      g_file_info_set_attribute_byte_string (ret_file_info, "standard::symlink-target", symlink_target);
    }
  else if (S_ISCHR (mode) || S_ISBLK (mode))
    {
      g_file_info_set_attribute_uint32 (ret_file_info, "unix::rdev", rdev);
    }
  else if (S_ISFIFO (mode))
    {
      ;
    }
  else
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Corrupted archive file; invalid mode %u", mode);
      goto out;
    }

  ret = TRUE;
  ot_transfer_out_value(out_file_info, &ret_file_info);
  ot_transfer_out_value(out_xattrs, &ret_xattrs);
 out:
  return ret;
}
コード例 #4
0
static OstreeRepoCommitFilterResult
commit_filter (OstreeRepo *repo,
               const char *path,
               GFileInfo  *file_info,
               CommitData *commit_data)
{
  guint mode;

  /* No user info */
  g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0);

  mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
  /* No setuid */
  mode = mode & ~07000;
  /* All files readable */
  mode = mode | 0444;
  g_file_info_set_attribute_uint32 (file_info, "unix::mode", mode);

  if (matches_patterns (commit_data->exclude, path) &&
      !matches_patterns (commit_data->include, path))
    {
      g_debug ("Excluding %s", path);
      return OSTREE_REPO_COMMIT_FILTER_SKIP;
    }

  return OSTREE_REPO_COMMIT_FILTER_ALLOW;
}
コード例 #5
0
ファイル: gvfsbackendtrash.c プロジェクト: gicmo/gvfs
static gboolean
trash_backend_query_fs_info (GVfsBackend           *vfs_backend,
                             GVfsJobQueryFsInfo    *job,
                             const char            *filename,
                             GFileInfo             *info,
                             GFileAttributeMatcher *matcher)
{
  g_file_info_set_attribute_string (info,
                                    G_FILE_ATTRIBUTE_FILESYSTEM_TYPE,
                                    "trash");
  g_file_info_set_attribute_boolean (info,
                                     G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE,
                                     FALSE);

  g_file_info_set_attribute_boolean (info,
                                     G_FILE_ATTRIBUTE_FILESYSTEM_READONLY,
                                     FALSE);

  g_file_info_set_attribute_uint32 (info,
                                    G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW,
                                    G_FILESYSTEM_PREVIEW_TYPE_IF_LOCAL);

  g_vfs_job_succeeded (G_VFS_JOB (job));

  return TRUE;
}
コード例 #6
0
ファイル: gvfsbackendtest.c プロジェクト: GNOME/gvfs
static void
do_query_info_on_read (GVfsBackend *backend,
		       GVfsJobQueryInfoRead *job,
		       GVfsBackendHandle handle,
		       GFileInfo *info,
		       GFileAttributeMatcher *attribute_matcher)
{
  int fd, res;
  struct stat statbuf;
    
  fd = GPOINTER_TO_INT (handle);

  res = fstat (fd, &statbuf);

  if (res == -1)
    {
      int errsv = errno;

      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR,
			g_io_error_from_errno (errsv),
			"Error querying info in file: %s",
			g_strerror (errsv));
    }
  else
    {
      g_file_info_set_size (info, statbuf.st_size);
      g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE,
					statbuf.st_dev);
      g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED, statbuf.st_mtime);
      g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS, statbuf.st_atime);
      g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CHANGED, statbuf.st_ctime);

      g_vfs_job_succeeded (G_VFS_JOB (job));
    }
}
コード例 #7
0
gboolean
add_file_to_mtree (GFile             *file,
                   const char        *name,
                   OstreeRepo        *repo,
                   OstreeMutableTree *mtree,
                   GCancellable      *cancellable,
                   GError           **error)
{
  g_autoptr(GFileInfo) file_info = NULL;
  g_autoptr(GInputStream) raw_input = NULL;
  g_autoptr(GInputStream) input = NULL;
  guint64 length;
  g_autofree guchar *child_file_csum = NULL;
  g_autofree char *tmp_checksum = NULL;

  file_info = g_file_query_info (file,
                                 "standard::size",
                                 0, cancellable, error);
  if (file_info == NULL)
    return FALSE;

  g_file_info_set_name (file_info, name);
  g_file_info_set_file_type (file_info, G_FILE_TYPE_REGULAR);
  g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::mode", 0100644);

  raw_input = (GInputStream *) g_file_read (file, cancellable, error);
  if (raw_input == NULL)
    return FALSE;

  if (!ostree_raw_file_to_content_stream (raw_input,
                                          file_info, NULL,
                                          &input, &length,
                                          cancellable, error))
    return FALSE;

  if (!ostree_repo_write_content (repo, NULL, input, length,
                                  &child_file_csum, cancellable, error))
    return FALSE;

  tmp_checksum = ostree_checksum_from_bytes (child_file_csum);
  if (!ostree_mutable_tree_replace_file (mtree, name, tmp_checksum, error))
    return FALSE;

  return TRUE;
}
コード例 #8
0
ファイル: files.c プロジェクト: DarkDare/sauvegarde
/**
 * Set unix mode of a file
 * @param fileinfo : a GFileInfo pointer obtained from an opened file
 *        (GFile *)
 * @param meta : meta_data_t * structure that contains all meta data for
 *        the corresponding file.
 */
void set_file_mode_to_gfile(GFileInfo *fileinfo, meta_data_t *meta)
{
    if (fileinfo != NULL && meta != NULL)
        {
            print_debug(_("Setting mode: %d\n"), meta->mode);
            g_file_info_set_attribute_uint32(fileinfo, G_FILE_ATTRIBUTE_UNIX_MODE, meta->mode);
        }
}
コード例 #9
0
static OstreeRepoCommitFilterResult
commit_filter (OstreeRepo *repo,
               const char *path,
               GFileInfo  *file_info,
               CommitData *commit_data)
{
  guint mode;

  /* No user info */
  g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0);
  g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0);

  /* In flatpak, there is no real reason for files to have different
   * permissions based on the group or user really, everything is
   * always used readonly for everyone. Having things be writeable
   * for anyone but the user just causes risks for the system-installed
   * case. So, we canonicalize the mode to writable only by the user,
   * readable to all, and executable for all for directories and
   * files that the user can execute.
   */
  mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
  if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
    mode = 0755 | S_IFDIR;
  else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
    {
      /* If use can execute, make executable by all */
      if (mode & S_IXUSR)
        mode = 0755 | S_IFREG;
      else /* otherwise executable by none */
        mode = 0644 | S_IFREG;
    }
  g_file_info_set_attribute_uint32 (file_info, "unix::mode", mode);

  if (matches_patterns (commit_data->exclude, path) &&
      !matches_patterns (commit_data->include, path))
    {
      g_debug ("Excluding %s", path);
      return OSTREE_REPO_COMMIT_FILTER_SKIP;
    }

  return OSTREE_REPO_COMMIT_FILTER_ALLOW;
}
コード例 #10
0
ファイル: gzlibdecompressor.c プロジェクト: Andais/glib
static GConverterResult
g_zlib_decompressor_convert (GConverter *converter,
			     const void *inbuf,
			     gsize       inbuf_size,
			     void       *outbuf,
			     gsize       outbuf_size,
			     GConverterFlags flags,
			     gsize      *bytes_read,
			     gsize      *bytes_written,
			     GError    **error)
{
  GZlibDecompressor *decompressor;
  int res;

  decompressor = G_ZLIB_DECOMPRESSOR (converter);

  decompressor->zstream.next_in = (void *)inbuf;
  decompressor->zstream.avail_in = inbuf_size;

  decompressor->zstream.next_out = outbuf;
  decompressor->zstream.avail_out = outbuf_size;

  res = inflate (&decompressor->zstream, Z_NO_FLUSH);

  if (res == Z_DATA_ERROR || res == Z_NEED_DICT)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
			   _("Invalid compressed data"));
      return G_CONVERTER_ERROR;
    }

  if (res == Z_MEM_ERROR)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
			   _("Not enough memory"));
      return G_CONVERTER_ERROR;
    }

    if (res == Z_STREAM_ERROR)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
		   _("Internal error: %s"), decompressor->zstream.msg);
      return G_CONVERTER_ERROR;
    }

    if (res == Z_BUF_ERROR)
      {
	if (flags & G_CONVERTER_FLUSH)
	  return G_CONVERTER_FLUSHED;

	/* Z_FINISH not set, so this means no progress could be made */
	/* We do have output space, so this should only happen if we
	   have no input but need some */

	g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT,
			     _("Need more input"));
	return G_CONVERTER_ERROR;
      }

  g_assert (res == Z_OK || res == Z_STREAM_END);

  *bytes_read = inbuf_size - decompressor->zstream.avail_in;
  *bytes_written = outbuf_size - decompressor->zstream.avail_out;

#if !defined (G_OS_WIN32) || ZLIB_VERNUM >= 0x1240
  if (decompressor->header_data != NULL &&
      decompressor->header_data->gzheader.done == 1)
    {
      HeaderData *data = decompressor->header_data;

      /* So we don't notify again */
      data->gzheader.done = 2;

      data->file_info = g_file_info_new ();
      g_file_info_set_attribute_uint64 (data->file_info,
                                        G_FILE_ATTRIBUTE_TIME_MODIFIED,
                                        data->gzheader.time);
      g_file_info_set_attribute_uint32 (data->file_info,
                                        G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
                                        0);

      if (data->filename[0] != '\0')
        g_file_info_set_attribute_byte_string (data->file_info,
                                               G_FILE_ATTRIBUTE_STANDARD_NAME,
                                               data->filename);

      g_object_notify (G_OBJECT (decompressor), "file-info");
    }
#endif /* !G_OS_WIN32 || ZLIB >= 1.2.4 */

  if (res == Z_STREAM_END)
    return G_CONVERTER_FINISHED;
  return G_CONVERTER_CONVERTED;
}
コード例 #11
0
ファイル: gvfsbackendtrash.c プロジェクト: UIKit0/gvfs
static gboolean
trash_backend_query_info (GVfsBackend           *vfs_backend,
                          GVfsJobQueryInfo      *job,
                          const char            *filename,
                          GFileQueryInfoFlags    flags,
                          GFileInfo             *info,
                          GFileAttributeMatcher *matcher)
{
  GVfsBackendTrash *backend = G_VFS_BACKEND_TRASH (vfs_backend);

  g_assert (filename[0] == '/');

  if (filename[1])
    {
      GError *error = NULL;
      gboolean is_toplevel;
      TrashItem *item;
      GFile *real;

      real = trash_backend_get_file (backend, filename,
                                     &item, &is_toplevel, &error);

      if (real)
        {
          GFileInfo *real_info;

          real_info = g_file_query_info (real, 
                                         job->attributes,
                                         flags,
                                         G_VFS_JOB (job)->cancellable,
                                         &error);
          g_object_unref (real);

          if (real_info)
            {
              g_file_info_copy_into (real_info, info);
              trash_backend_add_info (item, info, is_toplevel);
              g_vfs_job_succeeded (G_VFS_JOB (job));
              trash_item_unref (item);
              g_object_unref (real_info);

              return TRUE;
            }

          trash_item_unref (item);
        }

      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
      g_error_free (error);
    }
  else
    {
      GIcon *icon;
      int n_items;

      n_items = trash_root_get_n_items (backend->root);

      g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
      g_file_info_set_name (info, "/");
      /* Translators: this is the display name of the backend */
      g_file_info_set_display_name (info, _("Trash"));
      g_file_info_set_content_type (info, "inode/directory");

      icon = g_themed_icon_new (n_items ? "user-trash-full" : "user-trash");
      g_file_info_set_icon (info, icon);
      g_object_unref (icon);

      icon = g_themed_icon_new (n_items ? "user-trash-full-symbolic" : "user-trash-symbolic");
      g_file_info_set_symbolic_icon (info, icon);
      g_object_unref (icon);

      g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT, n_items);

      g_vfs_job_succeeded (G_VFS_JOB (job));
    }

  return TRUE;
}
コード例 #12
0
ファイル: ostree-diff.c プロジェクト: alexlarsson/ostree
/**
 * ostree_diff_dirs_with_options:
 * @flags: Flags
 * @a: First directory path, or %NULL
 * @b: First directory path
 * @modified: (element-type OstreeDiffItem): Modified files
 * @removed: (element-type Gio.File): Removed files
 * @added: (element-type Gio.File): Added files
 * @cancellable: Cancellable
 * @options: (allow-none): Options
 * @error: Error
 *
 * Compute the difference between directory @a and @b as 3 separate
 * sets of #OstreeDiffItem in @modified, @removed, and @added.
 */
gboolean
ostree_diff_dirs_with_options (OstreeDiffFlags        flags,
                               GFile                 *a,
                               GFile                 *b,
                               GPtrArray             *modified,
                               GPtrArray             *removed,
                               GPtrArray             *added,
                               OstreeDiffDirsOptions *options,
                               GCancellable          *cancellable,
                               GError               **error)
{
  gboolean ret = FALSE;
  GError *temp_error = NULL;
  g_autoptr(GFileEnumerator) dir_enum = NULL;
  g_autoptr(GFile) child_a = NULL;
  g_autoptr(GFile) child_b = NULL;
  g_autoptr(GFileInfo) child_a_info = NULL;
  g_autoptr(GFileInfo) child_b_info = NULL;
  OstreeDiffDirsOptions default_opts = OSTREE_DIFF_DIRS_OPTIONS_INIT;

  if (!options)
    options = &default_opts;

  /* If we're diffing versus a repo, and either of them have xattrs disabled,
   * then disable for both.
   */
  OstreeRepo *repo;
  if (OSTREE_IS_REPO_FILE (a))
    repo = ostree_repo_file_get_repo ((OstreeRepoFile*)a);
  else if (OSTREE_IS_REPO_FILE (b))
    repo = ostree_repo_file_get_repo ((OstreeRepoFile*)b);
  else
    repo = NULL;
  if (repo != NULL && repo->disable_xattrs)
    flags |= OSTREE_DIFF_FLAGS_IGNORE_XATTRS;

  if (a == NULL)
    {
      if (!diff_add_dir_recurse (b, added, cancellable, error))
        goto out;

      ret = TRUE;
      goto out;
    }

  child_a_info = g_file_query_info (a, OSTREE_GIO_FAST_QUERYINFO,
                                    G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                    cancellable, error);
  if (!child_a_info)
    goto out;

  child_b_info = g_file_query_info (b, OSTREE_GIO_FAST_QUERYINFO,
                                    G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                    cancellable, error);
  if (!child_b_info)
    goto out;

  /* Fast path test for unmodified directories */
  if (g_file_info_get_file_type (child_a_info) == G_FILE_TYPE_DIRECTORY
      && g_file_info_get_file_type (child_b_info) == G_FILE_TYPE_DIRECTORY
      && OSTREE_IS_REPO_FILE (a)
      && OSTREE_IS_REPO_FILE (b))
    {
      OstreeRepoFile *a_repof = (OstreeRepoFile*) a;
      OstreeRepoFile *b_repof = (OstreeRepoFile*) b;
      
      if (strcmp (ostree_repo_file_tree_get_contents_checksum (a_repof),
                  ostree_repo_file_tree_get_contents_checksum (b_repof)) == 0)
        {
          ret = TRUE;
          goto out;
        }
    }

  g_clear_object (&child_a_info);
  g_clear_object (&child_b_info);

  dir_enum = g_file_enumerate_children (a, OSTREE_GIO_FAST_QUERYINFO, 
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        cancellable, error);
  if (!dir_enum)
    goto out;

  while ((child_a_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)) != NULL)
    {
      const char *name;
      GFileType child_a_type;
      GFileType child_b_type;

      name = g_file_info_get_name (child_a_info);

      g_clear_object (&child_a);
      child_a = g_file_get_child (a, name);
      child_a_type = g_file_info_get_file_type (child_a_info);

      g_clear_object (&child_b);
      child_b = g_file_get_child (b, name);

      g_clear_object (&child_b_info);
      child_b_info = g_file_query_info (child_b, OSTREE_GIO_FAST_QUERYINFO,
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        cancellable,
                                        &temp_error);
      if (!child_b_info)
        {
          if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
            {
              g_clear_error (&temp_error);
              g_ptr_array_add (removed, g_object_ref (child_a));
            }
          else
            {
              g_propagate_error (error, temp_error);
              goto out;
            }
        }
      else
        {
          if (options->owner_uid >= 0)
            g_file_info_set_attribute_uint32 (child_b_info, "unix::uid", options->owner_uid);
          if (options->owner_gid >= 0)
            g_file_info_set_attribute_uint32 (child_b_info, "unix::gid", options->owner_gid);

          child_b_type = g_file_info_get_file_type (child_b_info);
          if (child_a_type != child_b_type)
            {
              OstreeDiffItem *diff_item = diff_item_new (child_a, child_a_info,
                                                   child_b, child_b_info, NULL, NULL);
              
              g_ptr_array_add (modified, diff_item);
            }
          else
            {
              OstreeDiffItem *diff_item = NULL;

              if (!diff_files (flags, child_a, child_a_info, child_b, child_b_info, &diff_item,
                               cancellable, error))
                goto out;
              
              if (diff_item)
                g_ptr_array_add (modified, diff_item); /* Transfer ownership */

              if (child_a_type == G_FILE_TYPE_DIRECTORY)
                {
                  if (!ostree_diff_dirs_with_options (flags, child_a, child_b, modified,
                                                      removed, added, options,
                                                      cancellable, error))
                    goto out;
                }
            }
        }
      
      g_clear_object (&child_a_info);
    }
  if (temp_error != NULL)
    {
      g_propagate_error (error, temp_error);
      goto out;
    }

  g_clear_object (&dir_enum);
  dir_enum = g_file_enumerate_children (b, OSTREE_GIO_FAST_QUERYINFO, 
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        cancellable, error);
  if (!dir_enum)
    goto out;

  g_clear_object (&child_b_info);
  while ((child_b_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)) != NULL)
    {
      const char *name;

      name = g_file_info_get_name (child_b_info);

      g_clear_object (&child_a);
      child_a = g_file_get_child (a, name);

      g_clear_object (&child_b);
      child_b = g_file_get_child (b, name);

      g_clear_object (&child_a_info);
      child_a_info = g_file_query_info (child_a, OSTREE_GIO_FAST_QUERYINFO,
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        cancellable,
                                        &temp_error);
      if (!child_a_info)
        {
          if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
            {
              g_clear_error (&temp_error);
              g_ptr_array_add (added, g_object_ref (child_b));
              if (g_file_info_get_file_type (child_b_info) == G_FILE_TYPE_DIRECTORY)
                {
                  if (!diff_add_dir_recurse (child_b, added, cancellable, error))
                    goto out;
                }
            }
          else
            {
              g_propagate_error (error, temp_error);
              goto out;
            }
        }
      g_clear_object (&child_b_info);
    }
  if (temp_error != NULL)
    {
      g_propagate_error (error, temp_error);
      goto out;
    }

  ret = TRUE;
 out:
  return ret;
}
コード例 #13
0
ファイル: gvfsfileinfo.c プロジェクト: Amerekanets/gvfs
GFileInfo *
gvfs_file_info_demarshal (char      *data,
			  gsize      size)
{
  guint32 num_attrs, i;
  GInputStream *memstream;
  GDataInputStream *in;
  GFileInfo *info;
  char *attr, *str, **strv;
  GFileAttributeType type;
  GFileAttributeStatus status;
  GObject *obj;
  int objtype;

  memstream = g_memory_input_stream_new_from_data (data, size, NULL);
  in = g_data_input_stream_new (memstream);
  g_object_unref (memstream);

  info = g_file_info_new ();
  num_attrs = g_data_input_stream_read_uint32 (in, NULL, NULL);

  for (i = 0; i < num_attrs; i++)
    {
      attr = read_string (in);
      type = g_data_input_stream_read_byte (in, NULL, NULL);
      status = g_data_input_stream_read_byte (in, NULL, NULL);

      switch (type)
	{
	case G_FILE_ATTRIBUTE_TYPE_STRING:
	  str = read_string (in);
	  g_file_info_set_attribute_string (info, attr, str);
	  g_free (str);
	  break;
	case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
	  str = read_string (in);
	  g_file_info_set_attribute_byte_string (info, attr, str);
	  g_free (str);
	  break;
	case G_FILE_ATTRIBUTE_TYPE_STRINGV:
	  strv = read_stringv (in);
	  g_file_info_set_attribute_stringv (info, attr, strv);
	  g_strfreev (strv);
	  break;
	case G_FILE_ATTRIBUTE_TYPE_BOOLEAN:
	  g_file_info_set_attribute_boolean (info, attr,
					     g_data_input_stream_read_byte (in,
									    NULL,
									    NULL));
	  break;
	case G_FILE_ATTRIBUTE_TYPE_UINT32:
	  g_file_info_set_attribute_uint32 (info, attr,
					    g_data_input_stream_read_uint32 (in,
									     NULL,
									     NULL));
	  break;
	case G_FILE_ATTRIBUTE_TYPE_INT32:
	  g_file_info_set_attribute_int32 (info, attr,
					   g_data_input_stream_read_int32 (in,
									   NULL,
									   NULL));
	  break;
	case G_FILE_ATTRIBUTE_TYPE_UINT64:
	  g_file_info_set_attribute_uint64 (info, attr,
					    g_data_input_stream_read_uint64 (in,
									     NULL,
									     NULL));
	  break;
	case G_FILE_ATTRIBUTE_TYPE_INT64:
	  g_file_info_set_attribute_int64 (info, attr,
					   g_data_input_stream_read_int64 (in,
									   NULL,
									   NULL));
	  break;
	case G_FILE_ATTRIBUTE_TYPE_OBJECT:
	  objtype = g_data_input_stream_read_byte (in, NULL, NULL);
	  obj = NULL;

	  if (objtype == 1)
	    {
	      char *icon_str;

	      icon_str = read_string (in);
	      obj = (GObject *)g_icon_new_for_string  (icon_str, NULL);
	      g_free (icon_str);
	    }
	  else
	    {
	      g_warning ("Unsupported GFileInfo object type %d\n", objtype);
	      g_free (attr);
	      goto out;
	    }
	  g_file_info_set_attribute_object (info, attr, obj);
	  if (obj)
	    g_object_unref (obj);
	  break;
	case G_FILE_ATTRIBUTE_TYPE_INVALID:
	  break;
	default:
	  g_warning ("Unsupported GFileInfo attribute type %d\n", type);
	  g_free (attr);
	  goto out;
	  break;
	}
      g_file_info_set_attribute_status (info, attr, status);
      g_free (attr);
    }
  
 out:
  g_object_unref (in);
  return info;
}
コード例 #14
0
static gboolean
fl_parser_fill_file_info (GFileInfo *info, const char **attr)
{
	gint i;
	
	for (i = 0; attr[i]; ++i) {
		const gchar *name;
		const gchar *value;

		name  = attr[i];
		value = attr[++i];
		
		if (strcmp (name, "name") == 0) {
			char *display_name;
			/* Apparently someone decided it was a good idea
			 * to send name="" mem-type="MMC" 
			 */
			if (!value || strcmp (value, "") == 0) {
				return FALSE;
			}

			g_file_info_set_name (info, value);
			display_name = g_filename_display_name (value);
			g_file_info_set_display_name (info, display_name);
			d(g_print ("Name: '%s'\n", display_name));
			g_free (display_name);
		}
		else if (strcmp (name, "size") == 0) {
			g_file_info_set_size (info, strtoll (value, NULL, 10));
			d(g_print ("Size: '%"G_GINT64_FORMAT"'\n", g_file_info_get_size (info)));
		}
		else if (strcmp (name, "modified") == 0) {
			GTimeVal time;

			if (g_time_val_from_iso8601 (value, &time) == FALSE)
				continue;
			g_file_info_set_modification_time (info, &time);
			d(g_print ("Modified: '%s' = '%d'\n", 
				   value, (int)time.tv_sec));
		}
		else if (strcmp (name, "created") == 0) {
			GTimeVal time;

			if (g_time_val_from_iso8601 (value, &time) == FALSE)
				continue;
			g_file_info_set_attribute_uint64 (info,
							  G_FILE_ATTRIBUTE_TIME_CREATED,
							  time.tv_sec);
			g_file_info_set_attribute_uint32 (info,
							  G_FILE_ATTRIBUTE_TIME_CREATED_USEC,
							  time.tv_usec);
			d(g_print ("Created: '%s' = '%d'\n", 
				   value, (int)time.tv_sec));
		}
		else if (strcmp (name, "accessed") == 0) {
			GTimeVal time;

			if (g_time_val_from_iso8601 (value, &time) == FALSE)
				continue;
			g_file_info_set_attribute_uint64 (info,
							  G_FILE_ATTRIBUTE_TIME_ACCESS,
							  time.tv_sec);
			g_file_info_set_attribute_uint32 (info,
							  G_FILE_ATTRIBUTE_TIME_ACCESS_USEC,
							  time.tv_usec);
			d(g_print ("Accessed: '%s' = '%d'\n", 
				   value, (int)time.tv_sec));
		}
		else if (strcmp (name, "user-perm") == 0) {
			/* The permissions don't map well to unix semantics,
			 * since the user is most likely not the same on both
			 * sides. We map the user permissions to "other" on the
			 * local side. D is treated as write, otherwise files
			 * can't be deleted through the module, even if it
			 * should be possible.
			 */
			if (strstr (value, "R")) {
				g_file_info_set_attribute_boolean (info,
								   G_FILE_ATTRIBUTE_ACCESS_CAN_READ,
								   TRUE);
			}
			if (strstr (value, "W") || strstr (value, "D")) {
				g_file_info_set_attribute_boolean (info,
								   G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
								   TRUE);
			}
		}
		else if (strcmp (name, "group-perm") == 0) {
			/* Ignore for now */
			d(g_print ("Group permissions: '%s'\n", value));
		}
		else if (strcmp (name, "other-perm") == 0) {
			/* Ignore for now */
			d(g_print ("Other permissions: '%s'\n", value));
		}
		else if (strcmp (name, "owner") == 0) {
			/* Ignore for now */
			d(g_print ("Owner: '%s'\n", value));
		}
		else if (strcmp (name, "group") == 0) {
			/* Ignore for now */
			d(g_print ("Group: '%s'\n", value));
		}
		else if (strcmp (name, "type") == 0) {
			g_file_info_set_content_type (info, value);
			d(g_print ("Mime-Type: '%s'\n", value));
		}
		else if (strcmp (name, "xml:lang") == 0) {
			d(g_print ("Lang: '%s'\n", value));
		}
		else if (strcmp (name, "mem-type") == 0) {
			guint device;

			if (value == NULL || value[0] == '\0')
				continue;

			device = om_mem_type_id_from_string (value);
			g_file_info_set_attribute_uint32 (info,
							 G_FILE_ATTRIBUTE_UNIX_RDEV,
							 device);
			d(g_print ("Mem-Type: '%s' (%d)\n",
				   value, device));
		}
		else {
			d(g_print ("Unknown Attribute: %s = %s\n",
				   name, value));
		}
	}

	if (g_file_info_get_name (info) == NULL) { /* Required attribute */
		/* Set error */
		return FALSE;
	}
	
	return TRUE;
}
コード例 #15
0
ファイル: gvfsftpdircache.c プロジェクト: BATYakhkhkh/gvfs
static gboolean
g_vfs_ftp_dir_cache_funcs_process (GInputStream *        stream,
                                   int                   debug_id,
                                   const GVfsFtpFile *   dir,
                                   GVfsFtpDirCacheEntry *entry,
                                   gboolean              is_unix,
                                   GCancellable *        cancellable,
                                   GError **             error)
{
  struct list_state state = { NULL, };
  GDataInputStream *data;
  GFileInfo *info;
  int type;
  GVfsFtpFile *file;
  char *line, *s;
  gsize length;

  /* protect against code reorg - in current code, error never is NULL */
  g_assert (error != NULL);
  g_assert (*error == NULL);

  data = g_data_input_stream_new (stream);
  /* we use LF only, because the mozilla code can handle lines ending in CR */
  g_data_input_stream_set_newline_type (data, G_DATA_STREAM_NEWLINE_TYPE_LF);
  while ((line = g_data_input_stream_read_line (data, &length, cancellable, error)))
    {
      struct list_result result = { 0, };
      GFileType file_type = G_FILE_TYPE_UNKNOWN;
      GTimeVal tv = { 0, 0 };

      /* strip trailing \r - ParseFTPList only removes it if the line ends in \r\n,
       * but we stripped the \n already.
       */
      if (length > 0 && line[length - 1] == '\r')
        line[--length] = '\0';

      g_debug ("<<%2d <<  %s\n", debug_id, line);
      type = ParseFTPList (line, &state, &result);
      if (type != 'd' && type != 'f' && type != 'l')
        {
          g_free (line);
          continue;
        }

      /* don't list . and .. directories
       * Let's hope they're not important files on some ftp servers
       */
      if (result.fe_fnlen == 1 &&
          result.fe_fname[0] == '.')
        {
          g_free (line);
          continue;
        }
      if (result.fe_fnlen == 2 &&
          result.fe_fname[0] == '.' &&
          result.fe_fname[1] == '.')
        {
          g_free (line);
          continue;
        }

      s = g_strndup (result.fe_fname, result.fe_fnlen);
      file = g_vfs_ftp_file_new_child  (dir, s, NULL);
      g_free (s);
      if (file == NULL)
        {
          g_debug ("# invalid filename, skipping");
          g_free (line);
          continue;
        }

      info = g_file_info_new ();

      s = g_path_get_basename (g_vfs_ftp_file_get_gvfs_path (file));
      g_file_info_set_name (info, s);
      g_free (s);

      if (type == 'l')
        {
          char *link;

          link = g_strndup (result.fe_lname, result.fe_lnlen);
          g_file_info_set_symlink_target (info, link);
          g_file_info_set_is_symlink (info, TRUE);
          g_free (link);
        }

      g_file_info_set_size (info, g_ascii_strtoull (result.fe_size, NULL, 10));

      /* If unix format then parse the attributes */
      if (state.lstyle == 'U')
        {
          char file_mode[10], uid[64], gid[64];
          guint32 mode;

          /* POSIX ls -l form: mode, links, owner, group */
          if (sscanf(line, "%10c %*u %63s %63s", file_mode, uid, gid) == 3)
            {
              if (g_vfs_ftp_parse_mode (file_mode, &mode, &file_type))
                {
                  g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, mode);
                  g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_USER, uid);
                  g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP, gid);
                }
            }
          else
            g_debug ("# unknown listing format\n");
        }

      if (file_type == G_FILE_TYPE_UNKNOWN)
        {
          file_type = type == 'f' ? G_FILE_TYPE_REGULAR :
                      type == 'l' ? G_FILE_TYPE_SYMBOLIC_LINK :
                      G_FILE_TYPE_DIRECTORY;
        }

      gvfs_file_info_populate_default (info,
                                       g_vfs_ftp_file_get_gvfs_path (file),
                                       file_type);

      if (is_unix)
        g_file_info_set_is_hidden (info, result.fe_fnlen > 0 &&
                                         result.fe_fname[0] == '.');

      /* Workaround:
       * result.fetime.tm_year contains actual year instead of offset-from-1900,
       * which mktime expects.
       */
      if (result.fe_time.tm_year >= 1900)
              result.fe_time.tm_year -= 1900;

      tv.tv_sec = mktime (&result.fe_time);
      if (tv.tv_sec != -1)
        g_file_info_set_modification_time (info, &tv);

      g_vfs_ftp_dir_cache_entry_add (entry, file, info);
      g_free (line);
    }

  g_object_unref (data);
  return *error != NULL;
}