GVariant * ostree_zlib_file_header_new (GFileInfo *file_info, GVariant *xattrs) { guint64 size; guint32 uid; guint32 gid; guint32 mode; guint32 rdev; const char *symlink_target; GVariant *ret; ot_lvariant GVariant *tmp_xattrs = NULL; size = g_file_info_get_size (file_info); uid = g_file_info_get_attribute_uint32 (file_info, "unix::uid"); gid = g_file_info_get_attribute_uint32 (file_info, "unix::gid"); mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); rdev = g_file_info_get_attribute_uint32 (file_info, "unix::rdev"); if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK) symlink_target = g_file_info_get_symlink_target (file_info); else symlink_target = ""; if (xattrs == NULL) tmp_xattrs = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); ret = g_variant_new ("(tuuuus@a(ayay))", GUINT64_TO_BE (size), GUINT32_TO_BE (uid), GUINT32_TO_BE (gid), GUINT32_TO_BE (mode), GUINT32_TO_BE (rdev), symlink_target, xattrs ? xattrs : tmp_xattrs); g_variant_ref_sink (ret); return ret; }
gboolean ot_gfile_get_symlink_target_from_info (GFile *path, GFileInfo *file_info, GFile **out_target, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const char *target; g_autoptr(GFile) path_parent = NULL; g_autoptr(GFile) ret_target = NULL; if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_SYMBOLIC_LINK) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not a symbolic link"); goto out; } path_parent = g_file_get_parent (path); target = g_file_info_get_symlink_target (file_info); g_assert (target); ret_target = g_file_resolve_relative_path (path_parent, target); ret = TRUE; out: ot_transfer_out_value (out_target, &ret_target); return ret; }
static gboolean file_is_loadable( GFile *file ) { static const gchar *thisfn = "na_core_utils_file_is_loadable"; GError *error; GFileInfo *info; guint64 size; GFileType type; gboolean isok; GFile *target_file; error = NULL; isok = FALSE; info = g_file_query_info( file, G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, &error ); if( !info ){ if( error ){ g_debug( "%s: %s", thisfn, error->message ); g_error_free( error ); } } else { size = g_file_info_get_attribute_uint64( info, G_FILE_ATTRIBUTE_STANDARD_SIZE ); g_debug( "%s: size=%lu", thisfn, ( unsigned long ) size ); isok = ( size >= SIZE_MIN && size <= SIZE_MAX ); } if( isok ){ type = g_file_info_get_file_type( info ); g_debug( "%s: type=%u", thisfn, ( unsigned ) type ); if( type != G_FILE_TYPE_REGULAR ){ isok = FALSE; if( type == G_FILE_TYPE_SYMBOLIC_LINK ){ const char *target = g_file_info_get_symlink_target( info ); if( target && strlen( target )){ target_file = g_file_resolve_relative_path( file, target ); if( target_file ){ isok = file_is_loadable( target_file ); g_object_unref( target_file ); } } } } } g_object_unref( info ); return( isok ); }
gchar * get_file_type_description (const gchar * file, GFileInfo * file_info) { const char * content_type = NULL; gchar * desc; if (file != NULL) { content_type = g_file_info_get_content_type (file_info); } if (content_type == NULL || g_content_type_is_unknown (content_type) == TRUE) { return g_strdup (g_content_type_get_description ("application/octet-stream")); } desc = g_strdup (g_content_type_get_description (content_type)); if (g_file_info_get_is_symlink (file_info) == TRUE) { const gchar * symlink_target; gchar * absolute_symlink = NULL; gchar * str = NULL; symlink_target = g_file_info_get_symlink_target (file_info); if (g_path_is_absolute (symlink_target) != TRUE) { gchar *dirname; dirname = g_path_get_dirname (file); absolute_symlink = g_strconcat (dirname, G_DIR_SEPARATOR_S, symlink_target, NULL); g_free (dirname); } else { absolute_symlink = g_strdup (symlink_target); } if (g_file_test (absolute_symlink, G_FILE_TEST_EXISTS) != TRUE) { if ((g_ascii_strcasecmp (content_type, "x-special/socket") != 0) && (g_ascii_strcasecmp (content_type, "x-special/fifo") != 0)) { g_free (absolute_symlink); g_free (desc); return g_strdup (_("link (broken)")); } } str = g_strdup_printf (_("link to %s"), (desc != NULL) ? desc : content_type); g_free (absolute_symlink); g_free (desc); return str; } return desc; }
static void migrate_web_app_links () { GList *apps, *p; apps = ephy_web_application_get_application_list (); for (p = apps; p; p = p->next) { char *desktop_file, *app_link; EphyWebApplication *app = (EphyWebApplication*)p->data; desktop_file = app->desktop_file; /* Update the link in applications. */ app_link = g_build_filename (g_get_user_data_dir (), "applications", desktop_file, NULL); if (g_file_test (app_link, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_SYMLINK)) { /* Change the link to point to the new profile dir. */ GFileInfo *info; const char *target; GFile *file = g_file_new_for_path (app_link); info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, 0, NULL, NULL); if (info) { char *new_target; target = g_file_info_get_symlink_target (info); new_target = fix_desktop_file_and_return_new_location (target); /* FIXME: Updating the file info and setting it again should * work, but it does not? Just delete and create the link * again. */ g_file_delete (file, 0, 0); g_object_unref (file); file = g_file_new_for_path (app_link); g_file_make_symbolic_link (file, new_target, NULL, NULL); g_object_unref (info); g_free (new_target); } g_object_unref (file); } g_free (app_link); } ephy_web_application_free_application_list (apps); }
static void run_file (GFile* file, GFile* _file_arg) { char* cmd_line = NULL; char* file_path = NULL; //here we should check the file type // if the src is symbolink we should set the file_path as the path for it's value GFileType type = g_file_query_file_type (file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL); if (type == G_FILE_TYPE_SYMBOLIC_LINK) { //TODO: symbolic links g_debug("the src file type is G_FILE_TYPE_SYMBOLIC_LINK"); GFileInfo* info = g_file_query_info(file, "standard::*", G_FILE_QUERY_INFO_NONE, NULL, NULL); if (info != NULL) { const char * link_target_path = g_file_info_get_symlink_target(info); g_debug("symbolic link target is :%s",link_target_path); file_path = g_strdup(link_target_path); } g_object_unref(info); } else{ file_path = g_file_get_path (file); } g_debug("run file_path :%s",file_path); if (_file_arg != NULL) { char* _file_arg_uri = g_file_get_uri (_file_arg); cmd_line = g_strdup_printf ("%s %s", file_path, _file_arg_uri); g_free (_file_arg_uri); } else { cmd_line = g_strdup (file_path); } g_free (file_path); if(cmd_line != NULL) { g_spawn_command_line_async (cmd_line, NULL); } else { g_warning("run file_path is null"); } g_free (cmd_line); }
/* http://stackoverflow.com/a/1024937 */ gchar * gs_get_executable_path () { gchar *path = NULL; #if defined (G_OS_WIN32) wchar_t buf[MAX_PATH]; if (!GetModuleFileNameW (NULL, buf, MAX_PATH)) return NULL; path = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL); #else GFile *link = g_file_new_for_path ("/proc/self/exe"); GFileInfo *info = g_file_query_info (link, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, G_FILE_QUERY_INFO_NONE, NULL, NULL); path = g_strdup (g_file_info_get_symlink_target (info)); g_object_unref (info); g_object_unref (link); #endif return path; }
PRIVATE void _add_monitor_directory(GFile* f) { g_assert(_inotify_fd != -1); GFileInfo* info = g_file_query_info(f, "standard::type", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL); if (info == NULL) return; //temp file may cause this like downloading file or compressing file GFileType type = g_file_info_get_attribute_uint32(info, G_FILE_ATTRIBUTE_STANDARD_TYPE); g_assert(info != NULL); if (g_file_info_get_is_symlink(info)) { GFile* maybe_real_target = g_file_new_for_uri(g_file_info_get_symlink_target(info)); _add_monitor_directory(maybe_real_target); g_object_unref(maybe_real_target); } else if (type == G_FILE_TYPE_DIRECTORY) { char* path = g_file_get_path(f); int watch = inotify_add_watch(_inotify_fd, path, IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO | IN_ATTRIB); g_free(path); g_hash_table_insert(_monitor_table, GINT_TO_POINTER(watch), g_object_ref(f)); } g_object_unref(info); }
/* * 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, OstreeRepoCheckoutOptions *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; } } else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { 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 (!gs_file_open_in_tmpdir_at (destination_dfd, file_mode, &temp_filename, &temp_out, cancellable, error)) goto out; if (!write_regular_file_content (repo, options, temp_out, file_info, xattrs, input, cancellable, error)) goto out; } else g_assert_not_reached (); if (G_UNLIKELY (renameat (destination_dfd, temp_filename, destination_dfd, destination_name) == -1)) { glnx_set_error_from_errno (error); goto out; } ret = TRUE; out: return ret; }
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; }
static void do_tree (GFile *f, int level, guint64 pattern) { GFileEnumerator *enumerator; GError *error = NULL; unsigned int n; GFileInfo *info; info = g_file_query_info (f, G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, 0, NULL, NULL); if (info != NULL) { if (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE) == G_FILE_TYPE_MOUNTABLE) { /* don't process mountables; we avoid these by getting the target_uri below */ g_object_unref (info); return; } g_object_unref (info); } enumerator = g_file_enumerate_children (f, G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "," G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, 0, NULL, &error); if (enumerator != NULL) { GList *l; GList *info_list; info_list = NULL; while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) { if (g_file_info_get_is_hidden (info) && !show_hidden) { g_object_unref (info); } else { info_list = g_list_prepend (info_list, info); } } g_file_enumerator_close (enumerator, NULL, NULL); info_list = g_list_sort (info_list, (GCompareFunc) sort_info_by_name); for (l = info_list; l != NULL; l = l->next) { const char *name; const char *target_uri; GFileType type; gboolean is_last_item; info = l->data; is_last_item = (l->next == NULL); name = g_file_info_get_name (info); type = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE); if (name != NULL) { for (n = 0; n < level; n++) { if (pattern & (1<<n)) { g_print ("| "); } else { g_print (" "); } } if (is_last_item) { g_print ("`-- %s", name); } else { g_print ("|-- %s", name); } target_uri = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI); if (target_uri != NULL) { g_print (" -> %s", target_uri); } else { if (g_file_info_get_is_symlink (info)) { const char *target; target = g_file_info_get_symlink_target (info); g_print (" -> %s", target); } } g_print ("\n"); if ((type & G_FILE_TYPE_DIRECTORY) && (follow_symlinks || !g_file_info_get_is_symlink (info))) { guint64 new_pattern; GFile *child; if (is_last_item) new_pattern = pattern; else new_pattern = pattern | (1<<level); child = NULL; if (target_uri != NULL) { if (follow_symlinks) child = g_file_new_for_uri (target_uri); } else { child = g_file_get_child (f, name); } if (child != NULL) { do_tree (child, level + 1, new_pattern); g_object_unref (child); } } } g_object_unref (info); } g_list_free (info_list); } else { for (n = 0; n < level; n++) { if (pattern & (1<<n)) { g_print ("| "); } else { g_print (" "); } } g_print (" [%s]\n", error->message); g_error_free (error); } }
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; }
gboolean ostree_builtin_show (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) { GOptionContext *context; gboolean ret = FALSE; const char *rev; gs_free char *resolved_rev = NULL; context = g_option_context_new ("OBJECT - Output a metadata object"); g_option_context_add_main_entries (context, options, NULL); if (!g_option_context_parse (context, &argc, &argv, error)) goto out; if (argc <= 1) { ot_util_usage_error (context, "An object argument is required", error); goto out; } rev = argv[1]; if (opt_print_metadata_key || opt_print_detached_metadata_key) { gboolean detached = opt_print_detached_metadata_key != NULL; const char *key = detached ? opt_print_detached_metadata_key : opt_print_metadata_key; if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error)) goto out; if (!do_print_metadata_key (repo, resolved_rev, detached, key, error)) goto out; } else if (opt_print_related) { if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error)) goto out; if (!do_print_related (repo, rev, resolved_rev, error)) goto out; } else if (opt_print_variant_type) { if (!do_print_variant_generic (G_VARIANT_TYPE (opt_print_variant_type), rev, error)) goto out; } else { gboolean found = FALSE; if (!ostree_validate_checksum_string (rev, NULL)) { if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error)) goto out; if (!print_object (repo, OSTREE_OBJECT_TYPE_COMMIT, resolved_rev, error)) goto out; } else { if (!print_if_found (repo, OSTREE_OBJECT_TYPE_COMMIT, rev, &found, cancellable, error)) goto out; if (!print_if_found (repo, OSTREE_OBJECT_TYPE_DIR_META, rev, &found, cancellable, error)) goto out; if (!print_if_found (repo, OSTREE_OBJECT_TYPE_DIR_TREE, rev, &found, cancellable, error)) goto out; if (!found) { gs_unref_object GFileInfo *finfo = NULL; gs_unref_variant GVariant *xattrs = NULL; GFileType filetype; if (!ostree_repo_load_file (repo, resolved_rev, NULL, &finfo, &xattrs, cancellable, error)) goto out; g_print ("Object: %s\nType: %s\n", rev, ostree_object_type_to_string (OSTREE_OBJECT_TYPE_FILE)); filetype = g_file_info_get_file_type (finfo); g_print ("File Type: "); switch (filetype) { case G_FILE_TYPE_REGULAR: g_print ("regular\n"); g_print ("Size: %" G_GUINT64_FORMAT "\n", g_file_info_get_size (finfo)); break; case G_FILE_TYPE_SYMBOLIC_LINK: g_print ("symlink\n"); g_print ("Target: %s\n", g_file_info_get_symlink_target (finfo)); break; default: g_printerr ("(unknown type %u)\n", (guint)filetype); } g_print ("Mode: 0%04o\n", g_file_info_get_attribute_uint32 (finfo, "unix::mode")); g_print ("Uid: %u\n", g_file_info_get_attribute_uint32 (finfo, "unix::uid")); g_print ("Gid: %u\n", g_file_info_get_attribute_uint32 (finfo, "unix::gid")); g_print ("Extended Attributes: "); if (xattrs) { gs_free char *xattr_string = g_variant_print (xattrs, TRUE); g_print ("{ %s }\n", xattr_string); } else { g_print ("(none)\n"); } } } } ret = TRUE; out: if (context) g_option_context_free (context); return ret; }
static GFileInfo * g_vfs_ftp_dir_cache_resolve_symlink (GVfsFtpDirCache * cache, GVfsFtpTask * task, const GVfsFtpFile *file, GFileInfo * original, guint stamp) { static const char *copy_attributes[] = { G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN, G_FILE_ATTRIBUTE_STANDARD_NAME, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET }; GFileInfo *info, *result; GVfsFtpFile *tmp, *link; guint i, lookups = 0; const char *target; if (!g_file_info_get_is_symlink (original) || g_vfs_ftp_task_is_in_error (task)) return original; info = g_object_ref (original); link = g_vfs_ftp_file_copy (file); do { target = g_file_info_get_symlink_target (info); if (target == NULL) { /* This happens when bad servers don't report a symlink target. * We now want to figure out if this is a directory or regular file, * so we can at least report something useful. */ g_object_unref (info); info = cache->funcs->lookup_uncached (task, file); break; } tmp = link; link = cache->funcs->resolve_symlink (task, tmp, g_file_info_get_symlink_target (info)); g_vfs_ftp_file_free (tmp); g_object_unref (info); if (link == NULL) { g_vfs_ftp_task_clear_error (task); return original; } info = g_vfs_ftp_dir_cache_lookup_file_internal (cache, task, link, stamp); if (info == NULL) { g_vfs_ftp_file_free (link); g_vfs_ftp_task_clear_error (task); return original; } } while (g_file_info_get_is_symlink (info) && lookups++ < 8); g_vfs_ftp_file_free (link); if (g_file_info_get_is_symlink (info)) { /* too many recursions */ g_object_unref (info); return original; } result = g_file_info_dup (info); g_object_unref (info); for (i = 0; i < G_N_ELEMENTS (copy_attributes); i++) { GFileAttributeType type; gpointer value; if (!g_file_info_get_attribute_data (original, copy_attributes[i], &type, &value, NULL)) continue; g_file_info_set_attribute (result, copy_attributes[i], type, value); } g_object_unref (original); return result; }