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; }
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); }
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; }
/** * 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, >ime); 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; }
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", ®ular_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; }
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; }
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), ×) == -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; }
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; }
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; }
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; }
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; }
/* * 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; }
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; }
/* * 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; }
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; }
/** * 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; }
/** * 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; }
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); }
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); } }
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); }
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); } } }
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); } }
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; }
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; }