Ejemplo n.º 1
0
static gboolean
_ostree_bootloader_grub2_query (OstreeBootloader *bootloader,
                                gboolean         *out_is_active,
                                GCancellable     *cancellable,
                                GError          **error)
{
  gboolean ret = FALSE;
  OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (bootloader);
  gs_unref_object GFile* efi_basedir = NULL;
  gs_unref_object GFileInfo *file_info = NULL;

  if (g_file_query_exists (self->config_path_bios, NULL))
    {
      *out_is_active = TRUE;
      ret = TRUE;
      goto out;
    }

  efi_basedir = g_file_resolve_relative_path (self->sysroot->path, "boot/efi/EFI");

  g_clear_object (&self->config_path_efi);

  if (g_file_query_exists (efi_basedir, NULL))
    {
      gs_unref_object GFileEnumerator *direnum = NULL;

      direnum = g_file_enumerate_children (efi_basedir, OSTREE_GIO_FAST_QUERYINFO,
                                           G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                           cancellable, error);
      if (!direnum)
        goto out;
  
      while (TRUE)
        {
          GFileInfo *file_info;
          const char *fname;
          gs_free char *subdir_grub_cfg = NULL;

          if (!gs_file_enumerator_iterate (direnum, &file_info, NULL,
                                           cancellable, error))
            goto out;
          if (file_info == NULL)
            break;

          fname = g_file_info_get_name (file_info);
          if (strcmp (fname, "BOOT") == 0)
            continue;

          if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
            continue;

          subdir_grub_cfg = g_build_filename (gs_file_get_path_cached (efi_basedir), fname, "grub.cfg", NULL); 
          
          if (g_file_test (subdir_grub_cfg, G_FILE_TEST_EXISTS))
            {
              self->config_path_efi = g_file_new_for_path (subdir_grub_cfg);
              break;
            }
        }

      if (self->config_path_efi)
        {
          self->is_efi = TRUE;
          *out_is_active = TRUE;
          ret = TRUE;
          goto out;
        }
    }
  else
    *out_is_active = FALSE;

  ret = TRUE;
 out:
  return ret;
}
Ejemplo n.º 2
0
static void
for_each_file_func (GFile     *file,
		    GFileInfo *info,
		    gpointer   user_data)
{
	GthOrganizeTask *self = user_data;
	GthFileData     *file_data;
	char            *key;
	GTimeVal         timeval;
	GthCatalog      *catalog;

	if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
		return;

	key = NULL;
	file_data = gth_file_data_new (file, info);
	switch (self->priv->group_policy) {
	case GTH_GROUP_POLICY_DIGITALIZED_DATE:
		{
			GObject *metadata;

			metadata = g_file_info_get_attribute_object (info, "Embedded::Photo::DateTimeOriginal");
			if (metadata != NULL) {
				if (_g_time_val_from_exif_date (gth_metadata_get_raw (GTH_METADATA (metadata)), &timeval))
					key = _g_time_val_strftime (&timeval, KEY_FORMAT);
			}
		}
		break;
	case GTH_GROUP_POLICY_MODIFIED_DATE:
		timeval = *gth_file_data_get_modification_time (file_data);
		key = _g_time_val_strftime (&timeval, KEY_FORMAT);
		break;
	}

	if (key == NULL)
		return;

	catalog = g_hash_table_lookup (self->priv->catalogs, key);
	if (catalog == NULL) {
		GthDateTime *date_time;
		GFile       *catalog_file;
		char        *name;
		GtkTreeIter  iter;

		date_time = gth_datetime_new ();
		gth_datetime_from_timeval (date_time, &timeval);

		catalog_file = gth_catalog_get_file_for_date (date_time);
		catalog = gth_catalog_load_from_file (catalog_file);
		if (catalog == NULL)
			catalog = gth_catalog_new ();
		gth_catalog_set_for_date (catalog, date_time);

		g_hash_table_insert (self->priv->catalogs, g_strdup (key), catalog);

		name = gth_datetime_strftime (date_time, "%x");
		gtk_list_store_append (self->priv->results_liststore, &iter);
		gtk_list_store_set (self->priv->results_liststore, &iter,
				    KEY_COLUMN, key,
				    NAME_COLUMN, name,
				    CARDINALITY_COLUMN, 0,
				    CREATE_CATALOG_COLUMN, TRUE,
				    ICON_COLUMN, self->priv->icon_pixbuf,
				    -1);
		self->priv->n_catalogs++;

		g_free (name);
		g_object_unref (catalog_file);
		gth_datetime_free (date_time);
	}

	if (catalog != NULL) {
		GtkTreeIter iter;
		int         n = 0;

		if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->priv->results_liststore), &iter)) {
			do {
				char *k;

				gtk_tree_model_get (GTK_TREE_MODEL (self->priv->results_liststore),
						    &iter,
						    KEY_COLUMN, &k,
						    CARDINALITY_COLUMN, &n,
						    -1);
				if (g_strcmp0 (k, key) == 0) {
					gtk_list_store_set (self->priv->results_liststore, &iter,
							    CARDINALITY_COLUMN, n + 1,
							    -1);
					self->priv->n_files++;

					g_free (k);
					break;
				}

				g_free (k);
			}
			while (gtk_tree_model_iter_next (GTK_TREE_MODEL (self->priv->results_liststore), &iter));
		}

		gth_catalog_insert_file (catalog, file_data->file, -1);
	}

	g_object_unref (file_data);
	g_free (key);
}
Ejemplo n.º 3
0
static gboolean
dir_contains_uid_or_gid (GFile         *root,
                         guint32        id,
                         const char    *attr,
                         gboolean      *out_found_match,
                         GCancellable  *cancellable,
                         GError       **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFileInfo) file_info = NULL;
  guint32 type;
  guint32 tid;
  gboolean found_match = FALSE;

  /* zero it out, just to be sure */
  *out_found_match = found_match;

  file_info = g_file_query_info (root, OSTREE_GIO_FAST_QUERYINFO,
                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                 cancellable, error);
  if (!file_info)
    goto out;

  type = g_file_info_get_file_type (file_info);

  switch (type)
    {
    case G_FILE_TYPE_DIRECTORY:
    case G_FILE_TYPE_SYMBOLIC_LINK:
    case G_FILE_TYPE_REGULAR:
    case G_FILE_TYPE_SPECIAL:
      tid = g_file_info_get_attribute_uint32 (file_info, attr);
      if (tid == id)
        found_match = TRUE;
      break;

    case G_FILE_TYPE_UNKNOWN:
    case G_FILE_TYPE_SHORTCUT:
    case G_FILE_TYPE_MOUNTABLE:
      g_assert_not_reached ();
      break;
    }

  /* Now recurse for dirs. */
  if (!found_match && type == G_FILE_TYPE_DIRECTORY)
    {
      g_autoptr(GFileEnumerator) dir_enum = NULL;
      g_autoptr(GFileInfo) child_info = NULL;

      dir_enum = g_file_enumerate_children (root, OSTREE_GIO_FAST_QUERYINFO, 
                                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                            NULL, 
                                            error);
      if (!dir_enum)
        goto out;
  
      while (TRUE)
        {
          GFileInfo *file_info;
          GFile *child;

          if (!gs_file_enumerator_iterate (dir_enum, &file_info, &child,
                                           cancellable, error))
            goto out;
          if (!file_info)
            break;

          if (!dir_contains_uid_or_gid (child, id, attr, &found_match,
                                        cancellable, error))
            goto out;

          if (found_match)
            break;
        }
    }
  
  ret = TRUE;
  *out_found_match = found_match;
 out:
  return ret;
}
static gboolean
visit_enumerator (FilesCtx *ctx, GFile *parent, GFileEnumerator *enumerator, GError **err)
{
    GFileEnumerator *children;
    gboolean ret = TRUE;
    GFileInfo *info;
    FileInfo *finfo;
    GFile *file = NULL;

    for (;;) {
	if (!seahorse_tool_progress_check ()) {
            ret = FALSE;
            break;
	}

	info = g_file_enumerator_next_file (enumerator, NULL, err);
        if (!info) {
            if (err && *err)
                ret = FALSE;
            break;
        }

        file = g_file_resolve_relative_path (parent, g_file_info_get_name (info));
        g_return_val_if_fail (file, FALSE);

        /* Enumerate child directories */
        if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
                children = g_file_enumerate_children (file, FILE_ATTRIBUTES,
                                                      G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                                      NULL, err);
                if (!enumerator) {
                    ret = FALSE;
                    break;
                }

                ret = visit_enumerator (ctx, file, children, err);
                if (!ret)
                    break;

        /* A file, add it */
        } else {

            finfo = g_new0 (FileInfo, 1);
            finfo->info = info;
            finfo->file = file;
            finfo->uri = g_file_get_uri (file);
            g_object_ref (info);
            g_object_ref (file);

            ctx->total += g_file_info_get_size (info);
            ctx->finfos = g_list_append (ctx->finfos, finfo);
        }

        g_object_unref (file);
        file = NULL;
    }

    if (file != NULL)
        g_object_unref (file);

    g_object_unref (enumerator);
    return ret;
}
Ejemplo n.º 5
0
/**
 * Read content of file or create file list from directory
 * @param aBuf read destination buffer
 * @param aCount length of destination buffer
 * @param aCountRead number of read characters
 * @return NS_OK when read successfully, NS_BASE_STREAM_CLOSED when end of file,
 *         error code otherwise
 */
nsresult
nsGIOInputStream::DoRead(char *aBuf, uint32_t aCount, uint32_t *aCountRead)
{
  nsresult rv = NS_ERROR_NOT_AVAILABLE;
  if (mStream) {
    // file read
    GError *error = nullptr;    
    uint32_t bytes_read = g_input_stream_read(G_INPUT_STREAM(mStream),
                                              aBuf,
                                              aCount,
                                              nullptr,
                                              &error);
    if (error) {
      rv = MapGIOResult(error);
      *aCountRead = 0;
      g_warning("Cannot read from file: %s", error->message);
      g_error_free(error);
      return rv;
    }
    *aCountRead = bytes_read;
    mBytesRemaining -= *aCountRead;
    return NS_OK;
  }
  else if (mDirOpen) {
    // directory read
    while (aCount && rv != NS_BASE_STREAM_CLOSED)
    {
      // Copy data out of our buffer
      uint32_t bufLen = mDirBuf.Length() - mDirBufCursor;
      if (bufLen)
      {
        uint32_t n = std::min(bufLen, aCount);
        memcpy(aBuf, mDirBuf.get() + mDirBufCursor, n);
        *aCountRead += n;
        aBuf += n;
        aCount -= n;
        mDirBufCursor += n;
      }

      if (!mDirListPtr)    // Are we at the end of the directory list?
      {
        rv = NS_BASE_STREAM_CLOSED;
      }
      else if (aCount)     // Do we need more data?
      {
        GFileInfo *info = (GFileInfo *) mDirListPtr->data;

        // Prune '.' and '..' from directory listing.
        const char * fname = g_file_info_get_name(info);
        if (fname && fname[0] == '.' && 
            (fname[1] == '\0' || (fname[1] == '.' && fname[2] == '\0')))
        {
          mDirListPtr = mDirListPtr->next;
          continue;
        }

        mDirBuf.AssignLiteral("201: ");

        // The "filename" field
        nsCString escName;
        nsCOMPtr<nsINetUtil> nu = do_GetService(NS_NETUTIL_CONTRACTID);
        if (nu && fname) {
          nu->EscapeString(nsDependentCString(fname),
                           nsINetUtil::ESCAPE_URL_PATH, escName);

          mDirBuf.Append(escName);
          mDirBuf.Append(' ');
        }

        // The "content-length" field
        // XXX truncates size from 64-bit to 32-bit
        mDirBuf.AppendInt(int32_t(g_file_info_get_size(info)));
        mDirBuf.Append(' ');

        // The "last-modified" field
        //
        // NSPR promises: PRTime is compatible with time_t
        // we just need to convert from seconds to microseconds
        GTimeVal gtime;
        g_file_info_get_modification_time(info, &gtime);

        PRExplodedTime tm;
        PRTime pt = ((PRTime) gtime.tv_sec) * 1000000;
        PR_ExplodeTime(pt, PR_GMTParameters, &tm);
        {
          char buf[64];
          PR_FormatTimeUSEnglish(buf, sizeof(buf),
              "%a,%%20%d%%20%b%%20%Y%%20%H:%M:%S%%20GMT ", &tm);
          mDirBuf.Append(buf);
        }

        // The "file-type" field
        switch (g_file_info_get_file_type(info))
        {
          case G_FILE_TYPE_REGULAR:
            mDirBuf.AppendLiteral("FILE ");
            break;
          case G_FILE_TYPE_DIRECTORY:
            mDirBuf.AppendLiteral("DIRECTORY ");
            break;
          case G_FILE_TYPE_SYMBOLIC_LINK:
            mDirBuf.AppendLiteral("SYMBOLIC-LINK ");
            break;
          default:
            break;
        }
        mDirBuf.Append('\n');

        mDirBufCursor = 0;
        mDirListPtr = mDirListPtr->next;
      }
    }
  }
  return rv;
}
Ejemplo n.º 6
0
static gboolean
checkout_one_file_at (OstreeRepo                        *repo,
                      OstreeRepoCheckoutAtOptions         *options,
                      GFile                             *source,
                      GFileInfo                         *source_info,
                      int                                destination_dfd,
                      const char                        *destination_name,
                      GCancellable                      *cancellable,
                      GError                           **error)
{
  gboolean ret = FALSE;
  const char *checksum;
  gboolean is_symlink;
  gboolean can_cache;
  gboolean need_copy = TRUE;
  char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
  g_autoptr(GInputStream) input = NULL;
  g_autoptr(GVariant) xattrs = NULL;
  gboolean is_whiteout;

  is_symlink = g_file_info_get_file_type (source_info) == G_FILE_TYPE_SYMBOLIC_LINK;

  checksum = ostree_repo_file_get_checksum ((OstreeRepoFile*)source);

  is_whiteout = !is_symlink && options->process_whiteouts &&
    g_str_has_prefix (destination_name, WHITEOUT_PREFIX);

  /* First, see if it's a Docker whiteout,
   * https://github.com/docker/docker/blob/1a714e76a2cb9008cd19609059e9988ff1660b78/pkg/archive/whiteouts.go
   */
  if (is_whiteout)
    {
      const char *name = destination_name + (sizeof (WHITEOUT_PREFIX) - 1);

      if (!name[0])
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Invalid empty whiteout '%s'", name);
          goto out;
        }

      g_assert (name[0] != '/'); /* Sanity */

      if (!glnx_shutil_rm_rf_at (destination_dfd, name, cancellable, error))
        goto out;

      need_copy = FALSE;
    }
  else
    {
      gboolean did_hardlink = FALSE;
      /* Try to do a hardlink first, if it's a regular file.  This also
       * traverses all parent repos.
       */
      OstreeRepo *current_repo = repo;

      while (current_repo)
        {
          gboolean is_bare = ((current_repo->mode == OSTREE_REPO_MODE_BARE
                               && options->mode == OSTREE_REPO_CHECKOUT_MODE_NONE) ||
                              (current_repo->mode == OSTREE_REPO_MODE_BARE_USER
                               && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER
                               /* NOTE: bare-user symlinks are not stored as symlinks */
                               && !is_symlink));
          gboolean current_can_cache = (options->enable_uncompressed_cache
                                        && current_repo->enable_uncompressed_cache);
          gboolean is_archive_z2_with_cache = (current_repo->mode == OSTREE_REPO_MODE_ARCHIVE_Z2
                                               && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER
                                               && current_can_cache);

          /* But only under these conditions */
          if (is_bare || is_archive_z2_with_cache)
            {
              /* Override repo mode; for archive-z2 we're looking in
                 the cache, which is in "bare" form */
              _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, OSTREE_REPO_MODE_BARE);
              if (!checkout_file_hardlink (current_repo,
                                           options,
                                           loose_path_buf,
                                           destination_dfd, destination_name,
                                           TRUE, &did_hardlink,
                                           cancellable, error))
                goto out;

              if (did_hardlink && options->devino_to_csum_cache)
                {
                  struct stat stbuf;
                  OstreeDevIno *key;
                  
                  if (TEMP_FAILURE_RETRY (fstatat (destination_dfd, destination_name, &stbuf, AT_SYMLINK_NOFOLLOW)) != 0)
                    {
                      glnx_set_error_from_errno (error);
                      goto out;
                    }
                  
                  key = g_new (OstreeDevIno, 1);
                  key->dev = stbuf.st_dev;
                  key->ino = stbuf.st_ino;
                  memcpy (key->checksum, checksum, OSTREE_SHA256_STRING_LEN+1);
                  
                  g_hash_table_add ((GHashTable*)options->devino_to_csum_cache, key);
                }

              if (did_hardlink)
                break;
            }
          current_repo = current_repo->parent_repo;
        }

      need_copy = !did_hardlink;
    }

  can_cache = (options->enable_uncompressed_cache
               && repo->enable_uncompressed_cache);

  /* Ok, if we're archive-z2 and we didn't find an object, uncompress
   * it now, stick it in the cache, and then hardlink to that.
   */
  if (can_cache
      && !is_whiteout
      && !is_symlink
      && need_copy
      && repo->mode == OSTREE_REPO_MODE_ARCHIVE_Z2
      && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER)
    {
      gboolean did_hardlink;
      
      if (!ostree_repo_load_file (repo, checksum, &input, NULL, NULL,
                                  cancellable, error))
        goto out;

      /* Overwrite any parent repo from earlier */
      _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, OSTREE_REPO_MODE_BARE);

      if (!checkout_object_for_uncompressed_cache (repo, loose_path_buf,
                                                   source_info, input,
                                                   cancellable, error))
        {
          g_prefix_error (error, "Unpacking loose object %s: ", checksum);
          goto out;
        }
      
      g_clear_object (&input);

      /* Store the 2-byte objdir prefix (e.g. e3) in a set.  The basic
       * idea here is that if we had to unpack an object, it's very
       * likely we're replacing some other object, so we may need a GC.
       *
       * This model ensures that we do work roughly proportional to
       * the size of the changes.  For example, we don't scan any
       * directories if we didn't modify anything, meaning you can
       * checkout the same tree multiple times very quickly.
       *
       * This is also scale independent; we don't hardcode e.g. looking
       * at 1000 objects.
       *
       * The downside is that if we're unlucky, we may not free
       * an object for quite some time.
       */
      g_mutex_lock (&repo->cache_lock);
      {
        gpointer key = GUINT_TO_POINTER ((g_ascii_xdigit_value (checksum[0]) << 4) + 
                                         g_ascii_xdigit_value (checksum[1]));
        if (repo->updated_uncompressed_dirs == NULL)
          repo->updated_uncompressed_dirs = g_hash_table_new (NULL, NULL);
        g_hash_table_add (repo->updated_uncompressed_dirs, key);
      }
      g_mutex_unlock (&repo->cache_lock);

      if (!checkout_file_hardlink (repo, options, loose_path_buf,
                                   destination_dfd, destination_name,
                                   FALSE, &did_hardlink,
                                   cancellable, error))
        {
          g_prefix_error (error, "Using new cached uncompressed hardlink of %s to %s: ", checksum, destination_name);
          goto out;
        }

      need_copy = !did_hardlink;
    }

  /* Fall back to copy if we couldn't hardlink */
  if (need_copy)
    {
      if (!ostree_repo_load_file (repo, checksum, &input, NULL, &xattrs,
                                  cancellable, error))
        goto out;

      if (options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES)
        {
          if (!checkout_file_unioning_from_input_at (repo, options, source_info, xattrs, input,
                                                     destination_dfd,
                                                     destination_name,
                                                     cancellable, error)) 
            {
              g_prefix_error (error, "Union checkout of %s to %s: ", checksum, destination_name);
              goto out;
            }
        }
      else
        {
          if (!checkout_file_from_input_at (repo, options, source_info, xattrs, input,
                                            destination_dfd,
                                            destination_name,
                                            cancellable, error))
            {
              g_prefix_error (error, "Checkout of %s to %s: ", checksum, destination_name);
              goto out;
            }
        }

      if (input)
        {
          if (!g_input_stream_close (input, cancellable, error))
            goto out;
        }
    }

  ret = TRUE;
 out:
  return ret;
}
static gboolean
step_check_uris (FilesCtx *ctx,
                 const gchar **uris,
                 GError **err)
{
    GFile *file, *base;
    GFileInfo *info;
    gchar *t, *path;
    gboolean ret = TRUE;
    FileInfo *finfo;
    const gchar **k;
    GFileType type;

    g_assert (err && !*err);

    t = g_get_current_dir ();
    base = g_file_new_for_path (t);
    g_free (t);

    for (k = uris; *k; k++) {
        if (!seahorse_tool_progress_check ()) {
            ret = FALSE;
            break;
        }

        t = g_uri_parse_scheme (*k);
        if (t)
            file = g_file_new_for_uri (*k);
        else
	        file = g_file_resolve_relative_path (base, *k);
        g_free (t);

        g_return_val_if_fail (file != NULL, FALSE);

        /* Find out if file can be accessed locally? */
        path = g_file_get_path (file);
        if (!path)
            ctx->remote = TRUE;
        g_free (path);

        info = g_file_query_info (file, FILE_ATTRIBUTES,
                                  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, err);

        if (!info) {
            ret = FALSE;
            g_object_unref (file);
            break;
        }

        type = g_file_info_get_file_type (info);

        /* Only handle simple types */
        if (type == G_FILE_TYPE_REGULAR || type == G_FILE_TYPE_UNKNOWN ||
            type == G_FILE_TYPE_DIRECTORY) {

            finfo = g_new0 (FileInfo, 1);
            finfo->file = file;
            g_object_ref (file);
            finfo->info = info;
            g_object_ref (info);
            finfo->uri = g_file_get_uri (file);

            ctx->total += g_file_info_get_size (info);
            ctx->finfos = g_list_prepend (ctx->finfos, finfo);
        }

        g_object_unref (file);
        g_object_unref (info);
    }

    g_object_unref (base);

    ctx->finfos = g_list_reverse (ctx->finfos);
    return ret;
}
XfdesktopRegularFileIcon *
xfdesktop_regular_file_icon_new(GFile *file,
                                GFileInfo *file_info,
                                GdkScreen *screen,
                                XfdesktopFileIconManager *fmanager)
{
    XfdesktopRegularFileIcon *regular_file_icon;

    g_return_val_if_fail(G_IS_FILE(file), NULL);
    g_return_val_if_fail(G_IS_FILE_INFO(file_info), NULL);
    g_return_val_if_fail(GDK_IS_SCREEN(screen), NULL);

    regular_file_icon = g_object_new(XFDESKTOP_TYPE_REGULAR_FILE_ICON, NULL);

    regular_file_icon->priv->file = g_object_ref(file);
    regular_file_icon->priv->file_info = g_object_ref(file_info);

    /* set the display name */
    regular_file_icon->priv->display_name = xfdesktop_file_utils_get_display_name(file, 
                                                                                  file_info);

    /* query file system information from GIO */
    regular_file_icon->priv->filesystem_info = g_file_query_filesystem_info(regular_file_icon->priv->file,
                                                                            XFDESKTOP_FILESYSTEM_INFO_NAMESPACE,
                                                                            NULL, NULL);

    /* query file information from GIO */
    regular_file_icon->priv->file_info = g_file_query_info(regular_file_icon->priv->file,
                                                           XFDESKTOP_FILE_INFO_NAMESPACE,
                                                           G_FILE_QUERY_INFO_NONE,
                                                           NULL, NULL);

    regular_file_icon->priv->gscreen = screen;

    regular_file_icon->priv->fmanager = fmanager;

    g_signal_connect_swapped(G_OBJECT(gtk_icon_theme_get_for_screen(screen)),
                             "changed",
                             G_CALLBACK(xfdesktop_icon_invalidate_pixbuf),
                             regular_file_icon);

    if(g_file_info_get_file_type(regular_file_icon->priv->file_info) == G_FILE_TYPE_DIRECTORY) {
        regular_file_icon->priv->monitor = g_file_monitor(regular_file_icon->priv->file,
                                                          G_FILE_MONITOR_NONE,
                                                          NULL,
                                                          NULL);

        g_signal_connect(regular_file_icon->priv->monitor, "changed",
                         G_CALLBACK(cb_folder_contents_changed),
                         regular_file_icon);

        g_object_get(regular_file_icon->priv->fmanager,
                     "show-thumbnails", &regular_file_icon->priv->show_thumbnails,
                     NULL);

        /* Keep an eye on the show-thumbnails property for folder thumbnails */
        g_signal_connect(G_OBJECT(fmanager), "notify::show-thumbnails",
                         G_CALLBACK(cb_show_thumbnails_notify), regular_file_icon);
    }
    return regular_file_icon;
}
Ejemplo n.º 9
0
static void
gb_vim_complete_edit_files (GtkWidget   *active_widget,
                            const gchar *command,
                            GPtrArray   *ar,
                            const gchar *prefix)
{
  g_autoptr(GFile) child = NULL;
  g_autoptr(GFile) parent = NULL;
  g_autoptr(GFile) workdir = NULL;

  IDE_ENTRY;

  g_assert (command);
  g_assert (ar);
  g_assert (prefix);

  if (!(workdir = find_workdir (active_widget)))
    IDE_EXIT;

  child = g_file_get_child (workdir, prefix);

  if (g_file_query_exists (child, NULL))
    {
      if (g_file_query_file_type (child, 0, NULL) == G_FILE_TYPE_DIRECTORY)
        {
          g_autoptr(GFileEnumerator) fe = NULL;
          GFileInfo *descendent;

          if (!g_str_has_suffix (prefix, "/"))
            {
              g_ptr_array_add (ar, g_strdup_printf ("%s %s/", command, prefix));
              IDE_EXIT;
            }

          fe = g_file_enumerate_children (child,
                                          G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
                                          G_FILE_QUERY_INFO_NONE,
                                          NULL, NULL);

          if (fe == NULL)
            IDE_EXIT;

          while ((descendent = g_file_enumerator_next_file (fe, NULL, NULL)))
            {
              const gchar *name;

              name = g_file_info_get_display_name (descendent);
              g_ptr_array_add (ar, g_strdup_printf ("%s %s%s", command, prefix, name));
              g_object_unref (descendent);
            }

          IDE_EXIT;
        }
    }

  parent = g_file_get_parent (child);

  if (parent != NULL)
    {
      g_autoptr(GFileEnumerator) fe = NULL;
      GFileInfo *descendent;
      const gchar *slash;
      const gchar *partial_name;
      g_autofree gchar *prefix_dir = NULL;

#ifdef IDE_ENABLE_TRACE
      {
        g_autofree gchar *parent_path = g_file_get_path (parent);
        IDE_TRACE_MSG ("parent_path: %s", parent_path);
      }
#endif

      if ((slash = strrchr (prefix, G_DIR_SEPARATOR)))
        {
          partial_name = slash + 1;
          prefix_dir = g_strndup (prefix, slash - prefix + 1);
        }
      else
        {
          partial_name = prefix;
        }

      fe = g_file_enumerate_children (parent,
                                      G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME","
                                      G_FILE_ATTRIBUTE_STANDARD_TYPE,
                                      G_FILE_QUERY_INFO_NONE,
                                      NULL, NULL);

      if (fe == NULL)
        IDE_EXIT;

      while ((descendent = g_file_enumerator_next_file (fe, NULL, NULL)))
        {
          const gchar *name;
          GFileType file_type;

          name = g_file_info_get_display_name (descendent);
          file_type = g_file_info_get_file_type (descendent);

          IDE_TRACE_MSG ("name=%s prefix=%s", name, prefix);

          if (name && g_str_has_prefix (name, partial_name))
            {
              gchar *completed_command;
              const gchar *descendent_name;
              g_autofree gchar *full_path = NULL;
              g_autofree gchar *parent_path = NULL;

              parent_path = g_file_get_path (parent);
              descendent_name = g_file_info_get_name (descendent);
              full_path = g_build_filename (parent_path, descendent_name, NULL);

              if (prefix[0] == G_DIR_SEPARATOR)
                completed_command = g_strdup_printf ("%s %s%s", command, full_path,
                                                     file_type == G_FILE_TYPE_DIRECTORY ? G_DIR_SEPARATOR_S : "");
              else if (strchr (prefix, G_DIR_SEPARATOR) == NULL)
                completed_command = g_strdup_printf ("%s %s%s", command, descendent_name,
                                                     file_type == G_FILE_TYPE_DIRECTORY ? G_DIR_SEPARATOR_S : "");
              else
                completed_command = g_strdup_printf ("%s %s%s%s", command, prefix_dir, descendent_name,
                                                     file_type == G_FILE_TYPE_DIRECTORY ? G_DIR_SEPARATOR_S : "");

              IDE_TRACE_MSG ("edit completion: %s", completed_command);

              g_ptr_array_add (ar, completed_command);
            }
          g_object_unref (descendent);
        }

      IDE_EXIT;
    }

  IDE_EXIT;
}
static GIcon *
xfdesktop_regular_file_icon_load_icon(XfdesktopIcon *icon)
{
    XfdesktopRegularFileIcon *regular_icon = XFDESKTOP_REGULAR_FILE_ICON(icon);
    XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(icon);
    GIcon *gicon = NULL;

    TRACE("entering");

    /* Try to load the icon referenced in the .desktop file */
    if(xfdesktop_file_utils_is_desktop_file(regular_icon->priv->file_info)) {
        gicon = xfdesktop_load_icon_from_desktop_file(regular_icon);

    } else if(g_file_info_get_file_type(regular_icon->priv->file_info) == G_FILE_TYPE_DIRECTORY) {
        /* Try to load a thumbnail from the standard folder image locations */
        gchar *thumbnail_file = NULL;

        if(regular_icon->priv->show_thumbnails)
            thumbnail_file = xfdesktop_load_icon_location_from_folder(file_icon);

        if(thumbnail_file) {
            /* If there's a folder thumbnail, use it */
            regular_icon->priv->thumbnail_file = g_file_new_for_path(thumbnail_file);
            gicon = g_file_icon_new(regular_icon->priv->thumbnail_file);
            g_free(thumbnail_file);
        }

    } else {
        /* If we have a thumbnail then they are enabled, use it. */
        if(regular_icon->priv->thumbnail_file) {
            gchar *file = g_file_get_path(regular_icon->priv->file);
            gchar *mimetype = xfdesktop_get_file_mimetype(file);

            /* Don't use thumbnails for svg, use the file itself */
            if(g_strcmp0(mimetype, "image/svg+xml") == 0)
                gicon = g_file_icon_new(regular_icon->priv->file);
            else
                gicon = g_file_icon_new(regular_icon->priv->thumbnail_file);

            g_free(mimetype);
            g_free(file);
        }
    }

    /* If we still don't have an icon, use the default */
    if(!G_IS_ICON(gicon)) {
        gicon = g_file_info_get_icon(regular_icon->priv->file_info);
        if(G_IS_ICON(gicon))
            g_object_ref(gicon);
    }

    g_object_set(file_icon, "gicon", gicon, NULL);

    /* Add any user set emblems */
    gicon = xfdesktop_file_icon_add_emblems(file_icon);

    /* load the read only emblem if necessary */
    if(!g_file_info_get_attribute_boolean(regular_icon->priv->file_info,
                                          G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
    {
        GIcon *themed_icon = g_themed_icon_new(EMBLEM_READONLY);
        GEmblem *emblem = g_emblem_new(themed_icon);

        g_emblemed_icon_add_emblem(G_EMBLEMED_ICON(gicon), emblem);

        g_object_unref(emblem);
        g_object_unref(themed_icon);
    }

    /* load the symlink emblem if necessary */
    if(g_file_info_get_attribute_boolean(regular_icon->priv->file_info,
                                         G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK))
    {
        GIcon *themed_icon = g_themed_icon_new(EMBLEM_SYMLINK);
        GEmblem *emblem = g_emblem_new(themed_icon);

        g_emblemed_icon_add_emblem(G_EMBLEMED_ICON(gicon), emblem);

        g_object_unref(emblem);
        g_object_unref(themed_icon);
    }

    return gicon;
}
gboolean
xfdesktop_regular_file_icon_do_drop_dest(XfdesktopIcon *icon,
                                         XfdesktopIcon *src_icon,
                                         GdkDragAction action)
{
    XfdesktopRegularFileIcon *regular_file_icon = XFDESKTOP_REGULAR_FILE_ICON(icon);
    XfdesktopFileIcon *src_file_icon = XFDESKTOP_FILE_ICON(src_icon);
    GFileInfo *src_info;
    GFile *src_file;
    gboolean result = FALSE;
    
    TRACE("entering");
    
    g_return_val_if_fail(regular_file_icon && src_file_icon, FALSE);
    g_return_val_if_fail(xfdesktop_regular_file_icon_get_allowed_drop_actions(icon, NULL) != 0,
                         FALSE);
    
    src_file = xfdesktop_file_icon_peek_file(src_file_icon);

    src_info = xfdesktop_file_icon_peek_file_info(src_file_icon);
    if(!src_info)
        return FALSE;
    
    if(g_file_info_get_file_type(regular_file_icon->priv->file_info) != G_FILE_TYPE_DIRECTORY
       && xfdesktop_file_utils_file_is_executable(regular_file_icon->priv->file_info))
    {
        GList files;

        files.data = src_file;
        files.prev = files.next = NULL;

        xfdesktop_file_utils_execute(NULL, regular_file_icon->priv->file, &files,
                                     regular_file_icon->priv->gscreen, NULL);

        result = TRUE;
    } else {
        GFile *parent, *dest_file = NULL;
        gchar *name;
        
        parent = g_file_get_parent(src_file);
        if(!parent)
            return FALSE;
        g_object_unref(parent);
        
        name = g_file_get_basename(src_file);
        if(!name)
            return FALSE;
        
        switch(action) {
            case GDK_ACTION_MOVE:
                dest_file = g_object_ref(regular_file_icon->priv->file);
                break;
            case GDK_ACTION_COPY:
                dest_file = g_file_get_child(regular_file_icon->priv->file, name);
                break;
            case GDK_ACTION_LINK:
                dest_file = g_object_ref(regular_file_icon->priv->file);
                break;
            default:
                g_warning("Unsupported drag action: %d", action);
        }

        if(dest_file) {
            xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
                                               regular_file_icon->priv->gscreen);

            g_object_unref(dest_file);

            result = TRUE;
        }

        g_free(name);
    }
    
    return result;
}
Ejemplo n.º 12
0
static gboolean
workaround_selinux_cross_labeling_recurse (GFile         *dir,
                                           GCancellable  *cancellable,
                                           GError       **error)
{
  gboolean ret = FALSE;
  gs_unref_object GFileEnumerator *direnum = NULL;

  direnum = g_file_enumerate_children (dir, "standard::name,standard::type,time::modified,time::access",
                                       G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                       cancellable, error);
  if (!direnum)
    goto out;

  while (TRUE)
    {
      GFileInfo *file_info;
      GFile *child;
      const char *name;

      if (!gs_file_enumerator_iterate (direnum, &file_info, &child,
                                       cancellable, error))
        goto out;
      if (!file_info)
        break;

      name = g_file_info_get_name (file_info);

      if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
        {
          if (!workaround_selinux_cross_labeling_recurse (child, cancellable, error))
            goto out;
        }
      else if (g_str_has_suffix (name, ".bin"))
        {
          const char *lastdot;
          gs_free char *nonbin_name = NULL;
          gs_unref_object GFile *nonbin_path = NULL;
          guint64 mtime = g_file_info_get_attribute_uint64 (file_info, "time::modified");
          guint64 atime = g_file_info_get_attribute_uint64 (file_info, "time::access");
          struct utimbuf times;

          lastdot = strrchr (name, '.');
          g_assert (lastdot);

          nonbin_name = g_strndup (name, lastdot - name);
          nonbin_path = g_file_get_child (dir, nonbin_name);

          times.actime = (time_t)atime;
          times.modtime = ((time_t)mtime) + 60;

          g_print ("Setting mtime of '%s' to newer than '%s'\n",
                   gs_file_get_path_cached (nonbin_path),
                   gs_file_get_path_cached (child));
          if (utime (gs_file_get_path_cached (nonbin_path), &times) == -1)
            {
              int errsv = errno;
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "utime(%s): %s", gs_file_get_path_cached (nonbin_path),
                           strerror (errsv));
              goto out;
            }
        }
    }

  ret = TRUE;
 out:
  return ret;
}
Ejemplo n.º 13
0
static gboolean
convert_var_to_tmpfiles_d (GOutputStream *tmpfiles_out,
                           GFile         *yumroot,
                           GFile         *dir,
                           GCancellable  *cancellable,
                           GError       **error)
{
  gboolean ret = FALSE;
  gs_unref_object GFileEnumerator *direnum = NULL;
  gsize bytes_written;

  direnum = g_file_enumerate_children (dir, "standard::name,standard::type,unix::mode,standard::symlink-target,unix::uid,unix::gid",
                                       G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                       cancellable, error);
  if (!direnum)
    {
      g_prefix_error (error, "Enumerating /var in '%s'", gs_file_get_path_cached (dir));
      goto out;
    }

  while (TRUE)
    {
      GFileInfo *file_info;
      GFile *child;
      GString *tmpfiles_d_buf;
      gs_free char *tmpfiles_d_line = NULL;
      char filetype_c;
      gs_free char *relpath = NULL;

      if (!gs_file_enumerator_iterate (direnum, &file_info, &child,
                                       cancellable, error))
        goto out;
      if (!file_info)
        break;

      switch (g_file_info_get_file_type (file_info))
        {
        case G_FILE_TYPE_DIRECTORY:
          filetype_c = 'd';
          break;
        case G_FILE_TYPE_SYMBOLIC_LINK:
          filetype_c = 'L';
          break;
        default:
          g_print ("Ignoring non-directory/non-symlink '%s'\n",
                   gs_file_get_path_cached (child));
          continue;
        }

      tmpfiles_d_buf = g_string_new ("");
      g_string_append_c (tmpfiles_d_buf, filetype_c);
      g_string_append_c (tmpfiles_d_buf, ' ');

      relpath = g_file_get_relative_path (yumroot, child);
      g_assert (relpath);
      
      g_string_append_c (tmpfiles_d_buf, '/');
      g_string_append (tmpfiles_d_buf, relpath);

      if (filetype_c == 'd')
        {
          guint mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
          mode &= ~S_IFMT;
          g_string_append_printf (tmpfiles_d_buf, " 0%02o", mode);
          g_string_append_printf (tmpfiles_d_buf, " %d %d - -",
                                  g_file_info_get_attribute_uint32 (file_info, "unix::uid"),
                                  g_file_info_get_attribute_uint32 (file_info, "unix::gid"));

          if (!convert_var_to_tmpfiles_d (tmpfiles_out, yumroot, child,
                                          cancellable, error))
            goto out;
        }
      else
        {
          g_string_append (tmpfiles_d_buf, " - - - - ");
          g_string_append (tmpfiles_d_buf, g_file_info_get_symlink_target (file_info));
        }

      g_string_append_c (tmpfiles_d_buf, '\n');

      tmpfiles_d_line = g_string_free (tmpfiles_d_buf, FALSE);

      if (!g_output_stream_write_all (tmpfiles_out, tmpfiles_d_line,
                                      strlen (tmpfiles_d_line), &bytes_written,
                                      cancellable, error))
        goto out;
    }

  ret = TRUE;
 out:
  return ret;
}
Ejemplo n.º 14
0
static gboolean
dump_files (GFile *dir,
            struct archive *archive,
            GCancellable *cancellable,
            char *parent,
            GError **error)
{
  g_autoptr(GFileEnumerator) fe = NULL;
  gboolean ret = TRUE;
  GFileType type;

  fe = g_file_enumerate_children (dir,
                                  "standard::name,standard::type,standard::is-symlink,standard::symlink-target,unix::mode,time::*",
                                  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error);
  if (fe == NULL)
    return FALSE;


  while (TRUE)
    {
      g_autoptr(GFileInfo) info = g_file_enumerator_next_file (fe, cancellable, error);
      g_autofree char *path = NULL;
      g_autoptr(GFile) child = NULL;
      guint32 mode;
      g_autoptr(archive_entry_t) entry = archive_entry_new2 (archive);

      if (!info)
        {
          if (error && *error != NULL)
            ret = FALSE;
          break;
        }

      type = g_file_info_get_file_type (info);
      mode = g_file_info_get_attribute_uint32 (info, "unix::mode");
      path = g_build_filename (parent, g_file_info_get_name (info), NULL);
      child = g_file_enumerator_get_child (fe, info);

      archive_entry_set_pathname (entry, path);
      archive_entry_set_uid(entry, 0);
      archive_entry_set_gid(entry, 0);
      archive_entry_set_perm(entry, mode & 0777);
      archive_entry_set_mtime(entry, 0, 0);

      switch (type)
        {
        case G_FILE_TYPE_SYMBOLIC_LINK:
          archive_entry_set_filetype (entry, AE_IFLNK);
          archive_entry_set_symlink (entry, g_file_info_get_symlink_target (info));
          break;

        case G_FILE_TYPE_REGULAR:
          archive_entry_set_filetype (entry, AE_IFREG);
          archive_entry_set_size(entry, g_file_info_get_size (info));
          break;

        case G_FILE_TYPE_DIRECTORY:
          archive_entry_set_filetype (entry, AE_IFDIR);
          break;

        default:
          g_error ("Unhandled type %d\n", type);
          break;
        }

      if (archive_write_header (archive, entry) < ARCHIVE_OK)
        return xdg_app_fail (error, "Can't write tar header");

      if (type == G_FILE_TYPE_REGULAR)
        {
          if (!dump_data (child, archive, cancellable, error))
            return FALSE;
        }

      if (archive_write_finish_entry (archive) < ARCHIVE_OK)
        return xdg_app_fail (error, "Can't finish tar entry");

      if (type == G_FILE_TYPE_DIRECTORY)
        {
          if (!dump_files (child, archive, cancellable, path, error))
            return FALSE;
        }
    }

  return ret;
}
Ejemplo n.º 15
0
static gboolean
exo_open_uri (const gchar  *uri,
              GError      **error)
{
  GFile               *file;
  gchar               *scheme;
  GFileInfo           *file_info;
  gboolean             succeed = FALSE;
  gboolean             retval = FALSE;
  GFileType            file_type;
  const gchar         *content_type;
  GAppInfo            *app_info;
  gchar               *path;
  const gchar         *executable;
  GList                fake_list;
  const gchar * const *schemes;
  GError              *err = NULL;
  guint                i;

  g_return_val_if_fail (uri != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

#ifndef NDEBUG
  schemes = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
  scheme = g_strjoinv (", ", (gchar **) schemes);
  g_debug ("vfs supported schemes: %s", scheme);
  g_free (scheme);
#endif

  file = g_file_new_for_uri (uri);
  scheme = g_file_get_uri_scheme (file);

  /* try to launch common schemes for know preferred applications */
  if (scheme != NULL && exo_open_uri_known_category (uri, scheme, &retval))
    {
      g_free (scheme);
      return retval;
    }

  /* handle the uri as a file, maybe we succeed... */
  file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                                 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
                                 G_FILE_QUERY_INFO_NONE, NULL, &err);
  if (file_info != NULL)
    {
      file_type = g_file_info_get_file_type (file_info);
      if (file_type == G_FILE_TYPE_DIRECTORY)
        {
#ifndef NDEBUG
          g_debug ("file is directory, use filemanager");
#endif
          /* directories should go fine with a file manager */
          retval = exo_open_launch_category ("FileManager", uri);
          succeed = TRUE;
        }
      else
        {
          content_type = g_file_info_get_content_type (file_info);
#ifndef NDEBUG
          g_debug ("content type=%s", content_type);
#endif
          if (G_LIKELY (content_type))
            {
              /* try to find a suitable application for this content type */
              path = g_file_get_path (file);
              app_info = g_app_info_get_default_for_type (content_type, path == NULL);
              g_free (path);

              if (app_info != NULL)
                {
                  /* make sure we don't loop somehow */
                  executable = g_app_info_get_executable (app_info);
#ifndef NDEBUG
                  g_debug ("default executable=%s", executable);
#endif
                  if (executable == NULL
                      || strcmp (executable, "exo-open") != 0)
                    {
                      fake_list.data = (gpointer) uri;
                      fake_list.prev = fake_list.next = NULL;

                      /* launch it */
                      retval = g_app_info_launch_uris (app_info, &fake_list, NULL, &err);
                      succeed = TRUE;
                    }

                  g_object_unref (G_OBJECT (app_info));
                }
            }
        }

      g_object_unref (G_OBJECT (file_info));
    }
  else if (err != NULL
           && scheme != NULL
           && err->code == G_IO_ERROR_NOT_MOUNTED)
    {
      /* check if the scheme is supported by gio */
      schemes = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
      if (G_LIKELY (schemes != NULL))
        {
          for (i = 0; schemes[i] != NULL; i++)
            {
              /* found scheme, open in file manager */
              if (strcmp (scheme, schemes[i]) == 0)
                {
                  retval = succeed = exo_open_launch_category ("FileManager", uri);
                  break;
                }
            }
        }
    }

  g_object_unref (G_OBJECT (file));

  /* our last try... */
  if (!succeed)
    {
#ifndef NDEBUG
          g_debug ("nothing worked, try ftp(s) or gtk_show_uri()");
#endif

      /* try ftp uris if the file manager/gio failed to recognize it */
      if (scheme != NULL
          && (strcmp (scheme, "ftp") == 0 || strcmp (scheme, "ftps") == 0))
        retval = exo_open_launch_category ("WebBrowser", uri);
      else
        retval = gtk_show_uri (NULL, uri, 0, error);
    }

  g_free (scheme);

  if (!retval && error != NULL)
    *error = err;
  else if (err != NULL)
    g_error_free (err);

  return retval;
}
Ejemplo n.º 16
0
static gboolean
cp_internal (GFile         *src,
             GFile         *dest,
             gboolean       use_hardlinks,
             GCancellable  *cancellable,
             GError       **error)
{
  gboolean ret = FALSE;
  ot_lobj GFileEnumerator *enumerator = NULL;
  ot_lobj GFileInfo *file_info = NULL;
  GError *temp_error = NULL;

  enumerator = g_file_enumerate_children (src, OSTREE_GIO_FAST_QUERYINFO,
                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                          cancellable, error);
  if (!enumerator)
    goto out;

  if (!ot_gfile_ensure_directory (dest, FALSE, error))
    goto out;

  while ((file_info = g_file_enumerator_next_file (enumerator, cancellable, &temp_error)) != NULL)
    {
      const char *name = g_file_info_get_name (file_info);
      ot_lobj GFile *src_child = g_file_get_child (src, name);
      ot_lobj GFile *dest_child = g_file_get_child (dest, name);

      if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
        {
          if (!ot_gfile_ensure_directory (dest_child, FALSE, error))
            goto out;

          /* Can't do this even though we'd like to; it fails with an error about
           * setting standard::type not being supported =/
           *
           if (!g_file_set_attributes_from_info (dest_child, file_info, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
           cancellable, error))
           goto out;
          */
          if (chmod (ot_gfile_get_path_cached (dest_child),
                     g_file_info_get_attribute_uint32 (file_info, "unix::mode")) == -1)
            {
              ot_util_set_error_from_errno (error, errno);
              goto out;
            }

          if (!cp_internal (src_child, dest_child, use_hardlinks, cancellable, error))
            goto out;
        }
      else
        {
          gboolean did_link = FALSE;
          (void) unlink (ot_gfile_get_path_cached (dest_child));
          if (use_hardlinks)
            {
              if (link (ot_gfile_get_path_cached (src_child), ot_gfile_get_path_cached (dest_child)) == -1)
                {
                  if (!(errno == EMLINK || errno == EXDEV))
                    {
                      ot_util_set_error_from_errno (error, errno);
                      goto out;
                    }
                  use_hardlinks = FALSE;
                }
              else
                did_link = TRUE;
            }
          if (!did_link)
            {
              if (!g_file_copy (src_child, dest_child,
                                G_FILE_COPY_OVERWRITE | G_FILE_COPY_ALL_METADATA | G_FILE_COPY_NOFOLLOW_SYMLINKS,
                                cancellable, NULL, NULL, error))
                goto out;
            }
        }
      g_clear_object (&file_info);
    }
  if (temp_error)
    {
      g_propagate_error (error, temp_error);
      goto out;
    }

  ret = TRUE;
 out:
  return ret;
}
Ejemplo n.º 17
0
/*
 * This function creates a file under a temporary name, then rename()s
 * it into place.  This implements union-like behavior.
 */
static gboolean
checkout_file_unioning_from_input_at (OstreeRepo     *repo,
                                      OstreeRepoCheckoutAtOptions  *options,
                                      GFileInfo      *file_info,
                                      GVariant       *xattrs,
                                      GInputStream   *input,
                                      int             destination_dfd,
                                      const char     *destination_name,
                                      GCancellable   *cancellable,
                                      GError        **error)
{
  gboolean ret = FALSE;
  g_autofree char *temp_filename = NULL;

  if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK)
    {
      if (!_ostree_make_temporary_symlink_at (destination_dfd,
                                              g_file_info_get_symlink_target (file_info),
                                              &temp_filename,
                                              cancellable, error))
        goto out;
          
      if (xattrs)
        {
          if (!glnx_dfd_name_set_all_xattrs (destination_dfd, temp_filename,
                                               xattrs, cancellable, error))
            goto out;
        }
      if (G_UNLIKELY (renameat (destination_dfd, temp_filename,
                                destination_dfd, destination_name) == -1))
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
    }
  else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
    {
      glnx_fd_close int temp_fd = -1;
      g_autoptr(GOutputStream) temp_out = NULL;
      guint32 file_mode;

      file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
      /* Don't make setuid files on checkout when we're doing --user */
      if (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER)
        file_mode &= ~(S_ISUID|S_ISGID);

      if (!glnx_open_tmpfile_linkable_at (destination_dfd, ".", O_WRONLY | O_CLOEXEC,
                                          &temp_fd, &temp_filename,
                                          error))
        goto out;
      temp_out = g_unix_output_stream_new (temp_fd, FALSE);

      if (!write_regular_file_content (repo, options, temp_out, file_info, xattrs, input,
                                       cancellable, error))
        goto out;

      if (!glnx_link_tmpfile_at (destination_dfd, GLNX_LINK_TMPFILE_REPLACE,
                                 temp_fd, temp_filename, destination_dfd,
                                 destination_name,
                                 error))
        goto out;
    }
  else
    g_assert_not_reached ();

  ret = TRUE;
 out:
  return ret;
}
Ejemplo n.º 18
0
static gboolean
list_all_boot_directories (OstreeSysroot       *self,
                           GPtrArray          **out_bootdirs,
                           GCancellable        *cancellable,
                           GError             **error)
{
    gboolean ret = FALSE;
    gs_unref_object GFileEnumerator *dir_enum = NULL;
    gs_unref_object GFile *boot_ostree = NULL;
    gs_unref_ptrarray GPtrArray *ret_bootdirs = NULL;
    GError *temp_error = NULL;

    boot_ostree = g_file_resolve_relative_path (self->path, "boot/ostree");

    ret_bootdirs = g_ptr_array_new_with_free_func (g_object_unref);

    dir_enum = g_file_enumerate_children (boot_ostree, OSTREE_GIO_FAST_QUERYINFO,
                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                          cancellable, &temp_error);
    if (!dir_enum)
    {
        if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
            g_clear_error (&temp_error);
            goto done;
        }
        else
        {
            g_propagate_error (error, temp_error);
            goto out;
        }
    }

    while (TRUE)
    {
        GFileInfo *file_info = NULL;
        GFile *child = NULL;
        const char *name;

        if (!gs_file_enumerator_iterate (dir_enum, &file_info, &child,
                                         NULL, error))
            goto out;
        if (file_info == NULL)
            break;

        if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
            continue;

        /* Only look at directories ending in -CHECKSUM; nothing else
         * should be in here, but let's be conservative.
         */
        name = g_file_info_get_name (file_info);
        if (!parse_bootdir_name (name, NULL, NULL))
            continue;

        g_ptr_array_add (ret_bootdirs, g_object_ref (child));
    }

done:
    ret = TRUE;
    ot_transfer_out_value (out_bootdirs, &ret_bootdirs);
out:
    return ret;
}
Ejemplo n.º 19
0
/*
 * checkout_tree_at:
 * @self: Repo
 * @mode: Options controlling all files
 * @overwrite_mode: Whether or not to overwrite files
 * @destination_parent_fd: Place tree here
 * @destination_name: Use this name for tree
 * @source: Source tree
 * @source_info: Source info
 * @cancellable: Cancellable
 * @error: Error
 *
 * Like ostree_repo_checkout_tree(), but check out @source into the
 * relative @destination_name, located by @destination_parent_fd.
 */
static gboolean
checkout_tree_at (OstreeRepo                        *self,
                  OstreeRepoCheckoutAtOptions       *options,
                  int                                destination_parent_fd,
                  const char                        *destination_name,
                  OstreeRepoFile                    *source,
                  GFileInfo                         *source_info,
                  GCancellable                      *cancellable,
                  GError                           **error)
{
  gboolean ret = FALSE;
  gboolean did_exist = FALSE;
  glnx_fd_close int destination_dfd = -1;
  int res;
  g_autoptr(GVariant) xattrs = NULL;
  g_autoptr(GFileEnumerator) dir_enum = NULL;

  /* Create initially with mode 0700, then chown/chmod only when we're
   * done.  This avoids anyone else being able to operate on partially
   * constructed dirs.
   */
  do
    res = mkdirat (destination_parent_fd, destination_name, 0700);
  while (G_UNLIKELY (res == -1 && errno == EINTR));
  if (res == -1)
    {
      if (errno == EEXIST && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES)
        did_exist = TRUE;
      else
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
    }

  if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE,
                       &destination_dfd, error))
    goto out;

  /* Set the xattrs now, so any derived labeling works */
  if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
    {
      if (!ostree_repo_file_get_xattrs (source, &xattrs, NULL, error))
        goto out;

      if (xattrs)
        {
          if (!glnx_fd_set_all_xattrs (destination_dfd, xattrs, cancellable, error))
            goto out;
        }
    }

  if (g_file_info_get_file_type (source_info) != G_FILE_TYPE_DIRECTORY)
    {
      ret = checkout_one_file_at (self, options,
                                  (GFile *) source,
                                  source_info,
                                  destination_dfd,
                                  g_file_info_get_name (source_info),
                                  cancellable, error);
      goto out;
    }
  dir_enum = g_file_enumerate_children ((GFile*)source,
                                        OSTREE_GIO_FAST_QUERYINFO, 
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        cancellable, 
                                        error);
  if (!dir_enum)
    goto out;

  while (TRUE)
    {
      GFileInfo *file_info;
      GFile *src_child;
      const char *name;

      if (!g_file_enumerator_iterate (dir_enum, &file_info, &src_child,
                                      cancellable, error))
        goto out;
      if (file_info == NULL)
        break;

      name = g_file_info_get_name (file_info);

      if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
        {
          if (!checkout_tree_at (self, options,
                                 destination_dfd, name,
                                 (OstreeRepoFile*)src_child, file_info,
                                 cancellable, error))
            goto out;
        }
      else
        {
          if (!checkout_one_file_at (self, options,
                                     src_child, file_info,
                                     destination_dfd, name,
                                     cancellable, error))
            goto out;
        }
    }

  /* We do fchmod/fchown last so that no one else could access the
   * partially created directory and change content we're laying out.
   */
  if (!did_exist)
    {
      do
        res = fchmod (destination_dfd,
                      g_file_info_get_attribute_uint32 (source_info, "unix::mode"));
      while (G_UNLIKELY (res == -1 && errno == EINTR));
      if (G_UNLIKELY (res == -1))
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
    }

  if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
    {
      do
        res = fchown (destination_dfd,
                      g_file_info_get_attribute_uint32 (source_info, "unix::uid"),
                      g_file_info_get_attribute_uint32 (source_info, "unix::gid"));
      while (G_UNLIKELY (res == -1 && errno == EINTR));
      if (G_UNLIKELY (res == -1))
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
    }

  /* Set directory mtime to OSTREE_TIMESTAMP, so that it is constant for all checkouts.
   * Must be done after setting permissions and creating all children.
   */
  if (!did_exist)
    {
      const struct timespec times[2] = { { OSTREE_TIMESTAMP, UTIME_OMIT }, { OSTREE_TIMESTAMP, 0} };
      do
        res = futimens (destination_dfd, times);
      while (G_UNLIKELY (res == -1 && errno == EINTR));
      if (G_UNLIKELY (res == -1))
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
    }

  if (fsync_is_enabled (self, options))
    {
      if (fsync (destination_dfd) == -1)
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
    }

  ret = TRUE;
 out:
  return ret;
}
Ejemplo n.º 20
0
gboolean
_ostree_sysroot_list_deployment_dirs_for_os (GFile               *osdir,
        GPtrArray           *inout_deployments,
        GCancellable        *cancellable,
        GError             **error)
{
    gboolean ret = FALSE;
    const char *osname = gs_file_get_basename_cached (osdir);
    gs_unref_object GFileEnumerator *dir_enum = NULL;
    gs_unref_object GFile *osdeploy_dir = NULL;
    GError *temp_error = NULL;

    osdeploy_dir = g_file_get_child (osdir, "deploy");

    dir_enum = g_file_enumerate_children (osdeploy_dir, OSTREE_GIO_FAST_QUERYINFO,
                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                          NULL, &temp_error);
    if (!dir_enum)
    {
        if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
            g_clear_error (&temp_error);
            goto done;
        }
        else
        {
            g_propagate_error (error, temp_error);
            goto out;
        }
    }

    while (TRUE)
    {
        const char *name;
        GFileInfo *file_info = NULL;
        GFile *child = NULL;
        gs_unref_object OstreeDeployment *deployment = NULL;
        gs_free char *csum = NULL;
        gint deployserial;

        if (!gs_file_enumerator_iterate (dir_enum, &file_info, &child,
                                         cancellable, error))
            goto out;
        if (file_info == NULL)
            break;

        name = g_file_info_get_name (file_info);

        if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
            continue;

        if (!_ostree_sysroot_parse_deploy_path_name (name, &csum, &deployserial, error))
            goto out;

        deployment = ostree_deployment_new (-1, osname, csum, deployserial, NULL, -1);
        g_ptr_array_add (inout_deployments, g_object_ref (deployment));
    }

done:
    ret = TRUE;
out:
    return ret;
}
static gboolean
step_process_multiple (FilesCtx *ctx,
                       const gchar **orig_uris,
                       GError **err)
{
    SeahorseWidget *swidget;
    gboolean done = FALSE;
    FileInfo *pkg_info = NULL;
    gchar *package = NULL;
    gchar *ext;
    GFile *file, *parent;
    gboolean ok = FALSE;
    GtkWidget *dlg;
    guint nfolders, nfiles;
    gchar *uris[2];
    gchar *uri;
    GList *l;

    g_assert (err && !*err);

    for (l = ctx->finfos, nfolders = nfiles = 0; l; l = g_list_next (l)) {
        FileInfo *finfo = (FileInfo*)l->data;
        if (g_file_info_get_file_type (finfo->info) == G_FILE_TYPE_DIRECTORY)
            ++nfolders;
        else
            ++nfiles;
    }

    /* In the case of one or less files, no dialog */
    if(nfolders == 0 && nfiles <= 1)
        return TRUE;

    /* The package extension */
    if ((ext = g_settings_get_string (seahorse_tool_settings, "package-extension")) == NULL)
        ext = g_strdup (".zip"); /* Yes this happens when the schema isn't installed */

    /* Figure out a good URI for our package */
    for (l = ctx->finfos; l; l = g_list_next (l)) {
        if (l->data) {
            pkg_info = (FileInfo*)(l->data);
            break;
        }
    }

    /* This sets up but doesn't run the dialog */
    swidget = prepare_dialog (ctx, nfolders, nfiles, pkg_info->info, ext);

    g_free (ext);

    dlg = seahorse_widget_get_toplevel (swidget);

    /* Inhibit popping up of progress dialog */
    seahorse_tool_progress_block (TRUE);

    while (!done) {
        switch (gtk_dialog_run (GTK_DIALOG (dlg)))
        {
        case GTK_RESPONSE_HELP:
            /* TODO: Implement help */
            break;

        case GTK_RESPONSE_OK:
            package = get_results (swidget);
            ok = TRUE;
            /* Fall through */

        default:
            done = TRUE;
            break;
        }
    }

    /* Let progress dialog pop up */
    seahorse_tool_progress_block (FALSE);

    seahorse_widget_destroy (swidget);

    /* Cancelled */
    if (!ok)
        return FALSE;

    /* No package was selected? */
    if (!package)
        return TRUE;

    /* A package was selected */

    /* Make a new path based on the first uri */
    parent = g_file_get_parent (pkg_info->file);
    if (!parent)
    	parent = pkg_info->file;
    file = g_file_get_child_for_display_name (parent, package, err);
    if (!file)
	    return FALSE;

    uri = g_file_get_uri (file);
    g_return_val_if_fail (uri, FALSE);
    g_object_unref (file);

    if (!seahorse_util_uris_package (uri, orig_uris)) {
        g_free (uri);
        return FALSE;
    }

    /* Free all file info */
    g_list_foreach (ctx->finfos, (GFunc)free_file_info, NULL);
    g_list_free (ctx->finfos);
    ctx->finfos = NULL;

    /* Reload up the new file, as what to encrypt */
    uris[0] = uri;
    uris[1] = NULL;
    ok = step_check_uris (ctx, (const gchar**)uris, err);
    g_free (uri);

    return ok;
}
Ejemplo n.º 22
0
/**
 * ostree_repo_list_refs:
 * @self: Repo
 * @refspec_prefix: (allow-none): Only list refs which match this prefix
 * @out_all_refs: (out) (element-type utf8 utf8): Mapping from ref to checksum
 * @cancellable: Cancellable
 * @error: Error
 *
 * If @refspec_prefix is %NULL, list all local and remote refspecs,
 * with their current values in @out_all_refs.  Otherwise, only list
 * refspecs which have @refspec_prefix as a prefix.
 */
gboolean
ostree_repo_list_refs (OstreeRepo       *self,
                       const char       *refspec_prefix,
                       GHashTable      **out_all_refs,
                       GCancellable     *cancellable,
                       GError          **error)
{
  gboolean ret = FALSE;
  gs_unref_hashtable GHashTable *ret_all_refs = NULL;
  gs_free char *remote = NULL;
  gs_free char *ref_prefix = NULL;

  ret_all_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  if (refspec_prefix)
    {
      gs_unref_object GFile *dir = NULL;
      gs_unref_object GFile *child = NULL;
      gs_unref_object GFileInfo *info = NULL;

      if (!ostree_parse_refspec (refspec_prefix, &remote, &ref_prefix, error))
        goto out;

      if (remote)
        dir = g_file_get_child (self->remote_heads_dir, remote);
      else
        dir = g_object_ref (self->local_heads_dir);

      child = g_file_resolve_relative_path (dir, ref_prefix);
      if (!ot_gfile_query_info_allow_noent (child, OSTREE_GIO_FAST_QUERYINFO, 0,
                                            &info, cancellable, error))
        goto out;

      if (info)
        {
          if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
            {
              if (!enumerate_refs_recurse (self, remote, child, child,
                                           ret_all_refs,
                                           cancellable, error))
                goto out;
            }
          else
            {
              if (!add_ref_to_set (remote, dir, child, ret_all_refs,
                                   cancellable, error))
                goto out;
            }
        }
    }
  else
    {
      gs_unref_object GFileEnumerator *remote_enumerator = NULL;

      if (!enumerate_refs_recurse (self, NULL, self->local_heads_dir, self->local_heads_dir,
                                   ret_all_refs,
                                   cancellable, error))
        goto out;

      remote_enumerator = g_file_enumerate_children (self->remote_heads_dir, OSTREE_GIO_FAST_QUERYINFO,
                                                     0,
                                                     cancellable, error);

      while (TRUE)
        {
          GFileInfo *info;
          GFile *child;
          const char *name;

          if (!gs_file_enumerator_iterate (remote_enumerator, &info, &child,
                                           cancellable, error))
            goto out;
          if (!info)
            break;

          name = g_file_info_get_name (info);
          if (!enumerate_refs_recurse (self, name, child, child,
                                       ret_all_refs,
                                       cancellable, error))
            goto out;
        }
    }

  ret = TRUE;
  ot_transfer_out_value (out_all_refs, &ret_all_refs);
 out:
  return ret;
}
Ejemplo n.º 23
0
/**
 * Start file open operation, mount volume when needed and according to file type
 * create file output stream or read directory content.
 * @return NS_OK when file or directory opened successfully, error code otherwise
 */
nsresult
nsGIOInputStream::DoOpen()
{
  nsresult rv;
  GError *error = nullptr;

  NS_ASSERTION(mHandle == nullptr, "already open");

  mHandle = g_file_new_for_uri( mSpec.get() );

  GFileInfo *info = g_file_query_info(mHandle,
                                      "standard::*",
                                      G_FILE_QUERY_INFO_NONE,
                                      nullptr,
                                      &error);

  if (error) {
    if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_MOUNTED) {
      // location is not yet mounted, try to mount
      g_error_free(error);
      if (NS_IsMainThread()) 
        return NS_ERROR_NOT_CONNECTED;
      error = nullptr;
      rv = MountVolume();
      if (rv != NS_OK) {
        return rv;
      }
      // get info again
      info = g_file_query_info(mHandle,
                               "standard::*",
                               G_FILE_QUERY_INFO_NONE,
                               nullptr,
                               &error);
      // second try to get file info from remote files after media mount
      if (!info) {
        g_warning("Unable to get file info: %s", error->message);
        rv = MapGIOResult(error);
        g_error_free(error);
        return rv;
      }
    } else {
      g_warning("Unable to get file info: %s", error->message);
      rv = MapGIOResult(error);
      g_error_free(error);
      return rv;
    }
  }
  // Get file type to handle directories and file differently
  GFileType f_type = g_file_info_get_file_type(info);
  if (f_type == G_FILE_TYPE_DIRECTORY) {
    // directory
    rv = DoOpenDirectory();
  } else if (f_type != G_FILE_TYPE_UNKNOWN) {
    // file
    rv = DoOpenFile(info);
  } else {
    g_warning("Unable to get file type.");
    rv = NS_ERROR_FILE_NOT_FOUND;
  }
  if (info)
    g_object_unref(info);
  return rv;
}
Ejemplo n.º 24
0
void
on_extensions_view_drag_data_received(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *selectiondata, guint info, guint time)
{
	GFile *file;
	GFileInfo *file_info;
	gchar *type_name = NULL;

	/* Check that we got data from source */
	if(selectiondata == NULL || gtk_selection_data_get_length(selectiondata) < 0)
		goto fail;

	/* Check that we got the format we can use */
	type_name = gdk_atom_name(gtk_selection_data_get_data_type(selectiondata));
	if(strcmp(type_name, "text/uri-list") != 0)
		goto fail;

	/* Do stuff with the data */
	char **extension_files = g_uri_list_extract_uris((char *)gtk_selection_data_get_data(selectiondata));
	int foo;
	/* Get a list of URIs to the dropped files */
	for(foo = 0; extension_files[foo] != NULL; foo++) {
		GError *err = NULL;
		file = g_file_new_for_uri(extension_files[foo]);
		file_info = g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, &err);
		if(!file_info) {
			IO_ERROR_DIALOG(NULL, file, err, _("accessing a URI"));
			goto fail2;
		}

		/* Check whether a directory was dropped. if so, install contents */
		/* NOTE: not recursive (that would be kind of silly anyway) */
		if(g_file_info_get_file_type(file_info) == G_FILE_TYPE_DIRECTORY) {

			GFileEnumerator *dir = g_file_enumerate_children(file, "standard::*", G_FILE_QUERY_INFO_NONE, NULL, &err);
			if(!dir) {
				IO_ERROR_DIALOG(NULL, file, err, _("opening a directory"));
				goto fail3;
			}

			GFileInfo *entry_info;
			while((entry_info = g_file_enumerator_next_file(dir, NULL, &err)) != NULL) {
				if(g_file_info_get_file_type(entry_info) != G_FILE_TYPE_DIRECTORY) {
					GFile *extension_file = g_file_get_child(file, g_file_info_get_name(entry_info));
					i7_app_install_extension(i7_app_get(), extension_file);
					g_object_unref(extension_file);
				}
				g_object_unref(entry_info);
			}
			g_file_enumerator_close(dir, NULL, &err);
			g_object_unref(dir);

			if(err) {
				IO_ERROR_DIALOG(NULL, file, err, _("reading a directory"));
				goto fail3;
			}

		} else {
			/* just install it */
			i7_app_install_extension(i7_app_get(), file);
		}

		g_object_unref(file_info);
		g_object_unref(file);
	}

	g_strfreev(extension_files);
	g_free(type_name);
	gtk_drag_finish(drag_context, TRUE, FALSE, time);
	return;

fail3:
	g_object_unref(file_info);
fail2:
	g_object_unref(file);
	g_strfreev(extension_files);
fail:
	g_free(type_name);
	gtk_drag_finish(drag_context, FALSE, FALSE, time);
}
Ejemplo n.º 25
0
static void
build_file (GbProjectTreeBuilder *self,
            IdeTreeNode          *node)
{
  g_autoptr(GFileEnumerator) enumerator = NULL;
  GbProjectFile *project_file;
  gpointer file_info_ptr;
  IdeVcs *vcs;
  GFile *file;
  IdeTree *tree;
  gint count = 0;
  gboolean show_ignored_files;

  g_return_if_fail (GB_IS_PROJECT_TREE_BUILDER (self));
  g_return_if_fail (IDE_IS_TREE_NODE (node));

  project_file = GB_PROJECT_FILE (ide_tree_node_get_item (node));

  tree = ide_tree_builder_get_tree (IDE_TREE_BUILDER (self));
  show_ignored_files = gb_project_tree_get_show_ignored_files (GB_PROJECT_TREE (tree));

  vcs = get_vcs (node);

  /*
   * TODO: Make this all async.
   */

  if (!gb_project_file_get_is_directory (project_file))
    return;

  file = gb_project_file_get_file (project_file);

  enumerator = g_file_enumerate_children (file,
                                          G_FILE_ATTRIBUTE_STANDARD_NAME","
                                          G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME","
                                          G_FILE_ATTRIBUTE_STANDARD_TYPE,
                                          G_FILE_QUERY_INFO_NONE,
                                          NULL,
                                          NULL);

  if (enumerator == NULL)
    return;

  while ((file_info_ptr = g_file_enumerator_next_file (enumerator, NULL, NULL)))
    {
      g_autoptr(GFileInfo) item_file_info = file_info_ptr;
      g_autoptr(GFile) item_file = NULL;
      g_autoptr(GbProjectFile) item = NULL;
      IdeTreeNode *child;
      const gchar *name;
      const gchar *display_name;
      const gchar *icon_name;
      gboolean ignored;

      name = g_file_info_get_name (item_file_info);
      item_file = g_file_get_child (file, name);

      ignored = ide_vcs_is_ignored (vcs, item_file, NULL);
      if (ignored && !show_ignored_files)
        continue;

      item = gb_project_file_new (item_file, item_file_info);

      display_name = gb_project_file_get_display_name (item);
      icon_name = gb_project_file_get_icon_name (item);

      child = g_object_new (IDE_TYPE_TREE_NODE,
                            "icon-name", icon_name,
                            "text", display_name,
                            "item", item,
                            "use-dim-label", ignored,
                            NULL);

      ide_tree_node_insert_sorted (node, child, compare_nodes_func, self);

      if (g_file_info_get_file_type (item_file_info) == G_FILE_TYPE_DIRECTORY)
        ide_tree_node_set_children_possible (child, TRUE);

      count++;
    }

  /*
   * If we didn't add any children to this node, insert an empty node to
   * notify the user that nothing was found.
   */
  if (count == 0)
    {
      IdeTreeNode *child;

      child = g_object_new (IDE_TYPE_TREE_NODE,
                            "icon-name", NULL,
                            "text", _("Empty"),
                            "use-dim-label", TRUE,
                            NULL);
      ide_tree_node_append (node, child);
    }
}
Ejemplo n.º 26
0
static void
enumerate_next_files_async_cb (GObject *source,
                               GAsyncResult *res,
                               gpointer user_data)
{
  EnumerateJob *job = user_data;
  GList *enumerated_files, *l;
  GFileInfo *info;
  GSList *logs;
  const char *content_type, *name;
  char *parse_string, *container_path;
  GFileType type;
  GFile *container;

  enumerated_files = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (source),
                                                          res, NULL);
  if (!enumerated_files) {
    enumerate_job_finish (job);
    return;
  }

  logs = job->logs;
  container = g_file_enumerator_get_container (G_FILE_ENUMERATOR (source));
  container_path = g_file_get_path (container);

  /* TODO: we don't support grouping rotated logs yet, skip gzipped files
   * and those which name contains a formatted date.
   */
  for (l = enumerated_files; l; l = l->next) {
    info = l->data;
    type = g_file_info_get_file_type (info);
    content_type = g_file_info_get_content_type (info);
    name = g_file_info_get_name (info);
    
    if (!g_file_info_get_attribute_boolean (info, "access::can-read")) {
      g_object_unref (info);
      continue;
    }

    if (type != (G_FILE_TYPE_REGULAR || G_FILE_TYPE_SYMBOLIC_LINK) ||
        !g_content_type_is_a (content_type, "text/plain"))
    {
      g_object_unref (info);
      continue;
    }

    if (g_content_type_is_a (content_type, "application/x-gzip")) {
      g_object_unref (info);
      continue;
    }

    if (g_regex_match_simple ("\\d{8}$", name, 0, 0)) {
      g_object_unref (info);
      continue;
    }

    parse_string = g_build_filename (container_path, name, NULL);

    if (g_slist_find_custom (logs, parse_string, (GCompareFunc) g_ascii_strcasecmp) == NULL) {
      logs = g_slist_append (logs, parse_string);
    } else {
      g_free (parse_string);
    }

    g_object_unref (info);
    parse_string = NULL;
  }

  g_list_free (enumerated_files);
  g_object_unref (container);
  g_free (container_path);

  job->logs = logs;

  enumerate_job_finish (job);
}
Ejemplo n.º 27
0
static void
xdg_cache_cache_copy_or_move (TumblerCache       *cache,
                              gboolean            do_copy,
                              const gchar *const *from_uris,
                              const gchar *const *to_uris)
{
  XDGCacheCache *xdg_cache = XDG_CACHE_CACHE (cache);
  GFileInfo     *info;
  guint64        mtime;
  GFile         *dest_source_file;
  GList         *iter;
  guint          n;
  GFile         *dummy_file;
  GFile         *parent;
  gchar         *dirname;
  GDir          *dir;
  const gchar   *file_basename;
  gchar         *filename;
  gchar         *uri;
  GFile         *original_file;
  GFile         *base_file;
  gchar         *to_uri;

  g_return_if_fail (XDG_CACHE_IS_CACHE (cache));
  g_return_if_fail (from_uris != NULL);
  g_return_if_fail (to_uris != NULL);

  for (iter = xdg_cache->flavors; iter != NULL; iter = iter->next)
    {
      for (n = 0; n < g_strv_length ((gchar **)from_uris); ++n)
        {
          dest_source_file = g_file_new_for_uri (to_uris[n]);
          info = g_file_query_info (dest_source_file,
                                    G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                                    G_FILE_ATTRIBUTE_TIME_MODIFIED,
                                    G_FILE_QUERY_INFO_NONE, NULL, NULL);

          if (info == NULL)
            {
              g_object_unref (dest_source_file);
              continue;
            }

          if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
            {
              /* compute the flavor directory filename */
              dummy_file = xdg_cache_cache_get_file ("foo", iter->data);
              parent = g_file_get_parent (dummy_file);
              dirname = g_file_get_path (parent);
              g_object_unref (parent);
              g_object_unref (dummy_file);

              /* the base path */
              base_file = g_file_new_for_uri (from_uris[n]);

              /* attempt to open the directory for reading */
              dir = g_dir_open (dirname, 0, NULL);
              if (dir != NULL)
                {
                  /* iterate over all files in the directory */
                  file_basename = g_dir_read_name (dir);
                  while (file_basename != NULL)
                    {
                      /* build the thumbnail filename */
                      filename = g_build_filename (dirname, file_basename, NULL);

                      /* read thumbnail information from the file */
                      if (xdg_cache_cache_read_thumbnail_info (filename, &uri, &mtime, NULL, NULL)
                          && uri != NULL)
                        {
                          /* create a GFile for the original URI. we need this for
                          * reliably checking the ancestor/descendant relationship */
                          original_file = g_file_new_for_uri (uri);

                          /* check if we have a thumbnail that is located in the moved/copied folder */
                          if (g_file_equal (original_file, base_file)
                              || g_file_has_prefix (original_file, base_file))
                            {
                              /* build the new target (replace old base with new base) */
                              to_uri = g_build_filename (to_uris[n], uri + strlen (from_uris[n]), NULL);

                              /* move or copy the thumbnail */
                              xdg_cache_cache_copy_or_move_file (cache, iter->data,
                                                                 do_copy,
                                                                 uri, to_uri,
                                                                 mtime);

                              g_free (to_uri);
                            }

                          g_object_unref (original_file);
                          g_free (uri);
                        }

                      g_free (filename);

                      /* try to determine the next filename in the directory */
                      file_basename = g_dir_read_name (dir);
                    }

                 g_dir_close (dir);
                }

              g_free (dirname);
              g_object_unref (base_file);
            }
          else
            {
              mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
              xdg_cache_cache_copy_or_move_file (cache, iter->data, do_copy,
                                                 from_uris[n], to_uris[n],
                                                 mtime);
            }

          g_object_unref (info);
          g_object_unref (dest_source_file);
        }
    }
}
Ejemplo n.º 28
0
static void
got_more_files (GObject *source_object,
		GAsyncResult *res,
		gpointer user_data)
{
  LoadBasenamesData *data = user_data;
  GList *infos, *l;
  GFileInfo *info;
  const char *name;
  gboolean append_slash;
  char *t;
  char *basename;

  if (data->completer == NULL)
    {
      /* Was cancelled */
      load_basenames_data_free (data);
      return;
    }

  infos = g_file_enumerator_next_files_finish (data->enumerator, res, NULL);

  for (l = infos; l != NULL; l = l->next)
    {
      info = l->data;

      if (data->dirs_only &&
	  g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY)
	{
	  g_object_unref (info);
	  continue;
	}
      
      append_slash = g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY;
      name = g_file_info_get_name (info);
      if (name == NULL)
	{
	  g_object_unref (info);
	  continue;
	}

      
      if (data->should_escape)
	basename = g_uri_escape_string (name,
					G_URI_RESERVED_CHARS_ALLOWED_IN_PATH,
					TRUE);
      else
	/* If not should_escape, must be a local filename, convert to utf8 */
	basename = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
      
      if (basename)
	{
	  if (append_slash)
	    {
	      t = basename;
	      basename = g_strconcat (basename, "/", NULL);
	      g_free (t);
	    }
	  
	  data->basenames = g_list_prepend (data->basenames, basename);
	}
      
      g_object_unref (info);
    }
  
  g_list_free (infos);
  
  if (infos)
    {
      /* Not last, get more files */
      g_file_enumerator_next_files_async (data->enumerator,
					  100,
					  0,
					  data->cancellable,
					  got_more_files, data);
    }
  else
    {
      data->completer->basename_loader = NULL;
      
      if (data->completer->basenames_dir)
	g_object_unref (data->completer->basenames_dir);
      g_list_foreach (data->completer->basenames, (GFunc)g_free, NULL);
      g_list_free (data->completer->basenames);
      
      data->completer->basenames_dir = g_object_ref (data->dir);
      data->completer->basenames = data->basenames;
      data->completer->basenames_are_escaped = data->should_escape;
      data->basenames = NULL;
      
      g_file_enumerator_close_async (data->enumerator, 0, NULL, NULL, NULL);

      g_signal_emit (data->completer, signals[GOT_COMPLETION_DATA], 0);
      load_basenames_data_free (data);
    }
}
Ejemplo n.º 29
0
static gboolean
checkout_file_from_input_at (OstreeRepo     *self,
                             OstreeRepoCheckoutOptions *options,
                             GFileInfo      *file_info,
                             GVariant       *xattrs,
                             GInputStream   *input,
                             int             destination_dfd,
                             const char     *destination_name,
                             GCancellable   *cancellable,
                             GError        **error)
{
  gboolean ret = FALSE;
  int res;

  if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK)
    {
      do
        res = symlinkat (g_file_info_get_symlink_target (file_info),
                         destination_dfd, destination_name);
      while (G_UNLIKELY (res == -1 && errno == EINTR));
      if (res == -1)
        {
          glnx_set_error_from_errno (error);
          goto out;
        }

      if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
        {
          if (G_UNLIKELY (fchownat (destination_dfd, destination_name,
                                    g_file_info_get_attribute_uint32 (file_info, "unix::uid"),
                                    g_file_info_get_attribute_uint32 (file_info, "unix::gid"),
                                    AT_SYMLINK_NOFOLLOW) == -1))
            {
              glnx_set_error_from_errno (error);
              goto out;
            }

          if (xattrs)
            {
              if (!glnx_dfd_name_set_all_xattrs (destination_dfd, destination_name,
                                                   xattrs, cancellable, error))
                goto out;
            }
        }
    }
  else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
    {
      g_autoptr(GOutputStream) temp_out = NULL;
      int fd;
      guint32 file_mode;

      file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
      /* Don't make setuid files on checkout when we're doing --user */
      if (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER)
        file_mode &= ~(S_ISUID|S_ISGID);

      do
        fd = openat (destination_dfd, destination_name, O_WRONLY | O_CREAT | O_EXCL, file_mode);
      while (G_UNLIKELY (fd == -1 && errno == EINTR));
      if (fd == -1)
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
      temp_out = g_unix_output_stream_new (fd, TRUE);
      fd = -1; /* Transfer ownership */

      if (!write_regular_file_content (self, options, temp_out, file_info, xattrs, input,
                                       cancellable, error))
        goto out;
    }
  else
    g_assert_not_reached ();
  
  ret = TRUE;
 out:
  return ret;
}
Ejemplo n.º 30
0
GimpPDBStatusType
file_save (Gimp                *gimp,
           GimpImage           *image,
           GimpProgress        *progress,
           GFile               *file,
           GimpPlugInProcedure *file_proc,
           GimpRunMode          run_mode,
           gboolean             change_saved_state,
           gboolean             export_backward,
           gboolean             export_forward,
           GError             **error)
{
  GimpDrawable      *drawable;
  GimpValueArray    *return_vals;
  GimpPDBStatusType  status     = GIMP_PDB_EXECUTION_ERROR;
  GFile             *local_file = NULL;
  gchar             *path       = NULL;
  gchar             *uri        = NULL;
  gint32             image_ID;
  gint32             drawable_ID;
  GError            *my_error   = NULL;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress),
                        GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (G_IS_FILE (file), GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc),
                        GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail ((export_backward && export_forward) == FALSE,
                        GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (error == NULL || *error == NULL,
                        GIMP_PDB_CALLING_ERROR);

  /*  ref image and file, so they can't get deleted during save  */
  g_object_ref (image);
  g_object_ref (file);

  drawable = gimp_image_get_active_drawable (image);

  if (! drawable)
    goto out;

  /* FIXME enable these tests for remote files again, needs testing */
  if (g_file_is_native (file) &&
      g_file_query_exists (file, NULL))
    {
      GFileInfo *info;

      info = g_file_query_info (file,
                                G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                                G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
                                G_FILE_QUERY_INFO_NONE,
                                NULL, error);
      if (! info)
        goto out;

      if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
        {
          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                               _("Not a regular file"));
          g_object_unref (info);
          goto out;
        }

      if (! g_file_info_get_attribute_boolean (info,
                                               G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
        {
          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                               _("Permission denied"));
          g_object_unref (info);
          goto out;
        }

      g_object_unref (info);
    }

  if (! g_file_is_native (file) &&
      ! file_remote_mount_file (gimp, file, progress, &my_error))
    {
      if (my_error)
        g_propagate_error (error, my_error);
      else
        status = GIMP_PDB_CANCEL;

      goto out;
    }

  if (! file_proc->handles_uri)
    {
      path = g_file_get_path (file);

      if (! path)
        {
          local_file = file_remote_upload_image_prepare (gimp, file, progress,
                                                         &my_error);

          if (! local_file)
            {
              if (my_error)
                g_propagate_error (error, my_error);
              else
                status = GIMP_PDB_CANCEL;

              goto out;
            }

          path = g_file_get_path (local_file);
        }
    }

  if (! path)
    path = g_file_get_uri (file);

  uri = g_file_get_uri (file);

  image_ID    = gimp_image_get_ID (image);
  drawable_ID = gimp_item_get_ID (GIMP_ITEM (drawable));

  return_vals =
    gimp_pdb_execute_procedure_by_name (image->gimp->pdb,
                                        gimp_get_user_context (gimp),
                                        progress, error,
                                        gimp_object_get_name (file_proc),
                                        GIMP_TYPE_INT32,       run_mode,
                                        GIMP_TYPE_IMAGE_ID,    image_ID,
                                        GIMP_TYPE_DRAWABLE_ID, drawable_ID,
                                        G_TYPE_STRING,         path,
                                        G_TYPE_STRING,         uri,
                                        G_TYPE_NONE);

  status = g_value_get_enum (gimp_value_array_index (return_vals, 0));

  gimp_value_array_unref (return_vals);

  if (local_file)
    {
      if (status == GIMP_PDB_SUCCESS)
        {
          GError *my_error = NULL;

          if (! file_remote_upload_image_finish (gimp, file, local_file,
                                                 progress, &my_error))
            {
              status = GIMP_PDB_EXECUTION_ERROR;

              if (my_error)
                g_propagate_error (error, my_error);
              else
                status = GIMP_PDB_CANCEL;
            }
        }

      g_file_delete (local_file, NULL, NULL);
      g_object_unref (local_file);
    }

  if (status == GIMP_PDB_SUCCESS)
    {
      GimpDocumentList *documents;
      GimpImagefile    *imagefile;

      if (change_saved_state)
        {
          gimp_image_set_file (image, file);
          gimp_image_set_save_proc (image, file_proc);

          /* Forget the import source when we save. We interpret a
           * save as that the user is not interested in being able
           * to quickly export back to the original any longer
           */
          gimp_image_set_imported_file (image, NULL);

          gimp_image_clean_all (image);
        }
      else if (export_backward)
        {
          /* We exported the image back to its imported source,
           * change nothing about export/import flags, only set
           * the export state to clean
           */
          gimp_image_export_clean_all (image);

          gimp_object_name_changed (GIMP_OBJECT (image));
        }
      else if (export_forward)
        {
          /* Remember the last entered Export URI for the image. We
           * only need to do this explicitly when exporting. It
           * happens implicitly when saving since the GimpObject name
           * of a GimpImage is the last-save URI
           */
          gimp_image_set_exported_file (image, file);
          gimp_image_set_export_proc (image, file_proc);

          /* An image can not be considered both exported and imported
           * at the same time, so stop consider it as imported now
           * that we consider it exported.
           */
          gimp_image_set_imported_file (image, NULL);

          gimp_image_export_clean_all (image);
        }

      if (export_backward || export_forward)
        gimp_image_exported (image, file);
      else
        gimp_image_saved (image, file);

      documents = GIMP_DOCUMENT_LIST (image->gimp->documents);

      imagefile = gimp_document_list_add_file (documents, file,
                                               file_proc->mime_type);

      /* only save a thumbnail if we are saving as XCF, see bug #25272 */
      if (GIMP_PROCEDURE (file_proc)->proc_type == GIMP_INTERNAL)
        gimp_imagefile_save_thumbnail (imagefile, file_proc->mime_type, image,
                                       NULL);
    }
  else if (status != GIMP_PDB_CANCEL)
    {
      if (error && *error == NULL)
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("%s plug-in could not save image"),
                       gimp_plug_in_procedure_get_label (file_proc));
        }
    }

  gimp_image_flush (image);

 out:
  g_object_unref (file);
  g_object_unref (image);

  g_free (path);
  g_free (uri);

  return status;
}