4,7 → 4,7 |
* nautilus-follow-symlink: Nautilus extension which allows opening the real |
* path of symbolic links |
* |
* Copyright (C) 2006-2008 Toni Corvera |
* Copyright (C) 2006, 2008, 2009 Toni Corvera |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
26,7 → 26,11 |
#include "follow-symlink.h" |
|
#include <gio/gio.h> |
#include <gtk/gtkicontheme.h> |
|
// Symbolic name of the icon, use to be in /usr/share/icons/gnome/[16x16]/emblems/ |
#define FSL_ICON_NAME "emblem-symbolic-link" |
|
extern int errno; |
|
// References for gio and the newer nautilus-extension: (required to support GNOME 2.22) |
67,41 → 71,25 |
g_free(uri_scheme); |
} |
|
// TODO: Once the older code is deprecated, some nautilus_* function can be |
// translated to their g_file_* counterparts. |
|
#ifndef NX_1_0 |
// TODO: Once the older code is deprecated, some nautilus_* function can be |
// translated to their g_file_* counterparts. |
|
// Only process symlinks to directories, we know already the file is a |
// direcoty or a symlink to one |
GFile * gf = nautilus_file_info_get_location(file_info); // Get the pointed GFile |
// FIXME: Can NULL be passed as last argument??? |
GFileInfo* gfi = g_file_query_info(gf, |
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, |
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, // <== Important :P |
NULL, |
NULL); // Retrieve the symlink attribute |
|
if (!g_file_info_get_is_symlink(gfi)) { |
FSL_LOG("No " G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK " attribute in %s", |
nautilus_file_info_get_uri(file_info)); |
return NULL; |
} |
#else |
// We know the file is either a directory or a symlink to a directory |
// TODO: Has glib/gnome any better/faster alternatives? |
GnomeVFSFileInfo * gfi = nautilus_file_info_get_vfs_file_info(file_info); |
// Only process symlinks to directories, we know already the file is a |
// direcoty or a symlink to one |
GFile * gf = nautilus_file_info_get_location(file_info); // Get the pointed GFile |
// FIXME: Can NULL be passed as last argument??? |
GFileInfo* gfi = g_file_query_info(gf, |
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, |
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, // <== Important :P |
NULL, |
NULL); // Retrieve the symlink attribute |
|
/* TODO: In which situations might the flags field be invalid? |
* Hence, can the older stat version be dumped safely? |
*/ |
g_assert( (gfi->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_FLAGS) > 0 ); |
|
if ( (gfi->flags & GNOME_VFS_FILE_FLAGS_SYMLINK) == 0 ) { |
FSL_LOG("GnomeVFS Flags: ! SYMLINK in %s", nautilus_file_info_get_uri(file_info)); |
if (!g_file_info_get_is_symlink(gfi)) { |
FSL_LOG("No " G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK " attribute in %s", |
nautilus_file_info_get_uri(file_info)); |
return NULL; |
} |
#endif |
|
item = fsl_menu_item_new(gtk_widget_get_screen(window), |
is_file_item, |
nautilus_file_info_get_name(file_info)); |
127,20 → 115,11 |
gboolean file_is_directory (const gpointer const file_data) |
{ |
TRACE(); |
|
#ifndef NX_1_0 // Nautilus extension v1.0, deprected |
/* |
* The "effective" type is returned, a symlink to a directory is a directory |
*/ |
return G_FILE_TYPE_DIRECTORY == nautilus_file_info_get_file_type(file_data); |
#else |
|
/* |
* Apparently type is never GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK and symlinks |
* are resolved to the target type |
* The "effective" type is returned, a symlink to a directory is a directory |
*/ |
const GnomeVFSFileInfo * const gfi = nautilus_file_info_get_vfs_file_info(file_data); |
return gfi->type == GNOME_VFS_FILE_TYPE_DIRECTORY; |
#endif |
return G_FILE_TYPE_DIRECTORY == nautilus_file_info_get_file_type(file_data); |
} |
|
/* |
194,60 → 173,21 |
{ |
TRACE(); |
|
#ifndef NX_1_0 |
gchar ** argv; |
|
GFile * gf = nautilus_file_info_get_location(file_info); // Get the pointed GFile |
// FIXME: Can NULL be passed as last argument??? |
GFileInfo* gfi = g_file_query_info(gf, |
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, |
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, // <== Important :P |
NULL, |
NULL); // Retrieve the symlink attribute |
|
// The result will relative if the symlink is, must use the correct CWD |
const char * target = g_file_info_get_symlink_target(gfi); |
|
GFile * parent = nautilus_file_info_get_parent_location(file_info); |
gchar ** argv; |
|
const gchar const * BASE_CMD = "nautilus --no-desktop --no-default-window '%s'"; |
const gsize mem_block_size = printf_string_upper_bound(BASE_CMD, target); |
gchar * command_line = g_try_malloc( mem_block_size ); |
GFile * gf = nautilus_file_info_get_location(file_info); // Get the pointed GFile |
// FIXME: Can NULL be passed as last argument??? |
GFileInfo* gfi = g_file_query_info(gf, |
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, |
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, // <== Important :P |
NULL, |
NULL); // Retrieve the symlink attribute |
|
if (NULL == command_line) { |
g_printerr(__FILE__ ":%d: Failed to allocate enough memory " |
"for command line, can't spawn new nautilus.\n", __LINE__); |
// Redundant, but issues a CRITICAL message |
g_return_if_fail( NULL != command_line ); |
} |
// The result will relative if the symlink is, must use the correct CWD |
const char * target = g_file_info_get_symlink_target(gfi); |
|
g_sprintf(command_line, BASE_CMD, target); |
GFile * parent = nautilus_file_info_get_parent_location(file_info); |
|
if (FALSE == g_shell_parse_argv(command_line, NULL, &argv, NULL)) { |
g_free(command_line); |
|
g_printerr("Failed in creating the arguments for the child nautilus.\n"); |
//g_return_if_fail( FALSE ); |
g_return_if_reached(); |
} |
|
g_printf("nautilus-follow-symlink: Spawning nautilus with\n '%s'\n", command_line); |
|
g_spawn_async( g_file_get_path(parent), // Inherit CWD |
argv, |
NULL, |
G_SPAWN_SEARCH_PATH, //| G_SPAWN_DO_NOT_REAP_CHILD, |
NULL, NULL, NULL, NULL); |
|
g_free(command_line); |
g_strfreev(argv); |
#else |
gchar ** argv; |
const GnomeVFSFileInfo * gfi = nautilus_file_info_get_vfs_file_info(file_info); |
// See /usr/include/gnome-vfs-2.0/libgnomevfs/gnome-vfs-file-info.h, |
// this one is the "realpath()" (3), also it isn't urlencoded |
const gchar const * target = gfi->symlink_name; |
|
const gchar const * BASE_CMD = "nautilus --no-desktop --no-default-window '%s'"; |
const gsize mem_block_size = printf_string_upper_bound(BASE_CMD, target); |
gchar * command_line = g_try_malloc( mem_block_size ); |
271,7 → 211,7 |
|
g_printf("nautilus-follow-symlink: Spawning nautilus with\n '%s'\n", command_line); |
|
g_spawn_async( NULL, // Inherit CWD |
g_spawn_async( g_file_get_path(parent), // Inherit CWD |
argv, |
NULL, |
G_SPAWN_SEARCH_PATH, //| G_SPAWN_DO_NOT_REAP_CHILD, |
279,7 → 219,6 |
|
g_free(command_line); |
g_strfreev(argv); |
#endif |
} |
|
/* |
367,7 → 306,7 |
ret = nautilus_menu_item_new("Fsymlink::allocation_error", |
_("Follow symbolic _link"), |
_("Open the symbolic link"), |
FSL_ICON); |
FSL_ICON_NAME); |
g_return_val_if_fail(NULL!=name && NULL!=tooltip && NULL!=unique_name, |
ret); |
} |
377,7 → 316,7 |
g_sprintf(unique_name, ITEM_NAME_FMT, a_base_name); |
|
// (name, label, tip, icon) |
ret = nautilus_menu_item_new(unique_name, name, tooltip, FSL_ICON); |
ret = nautilus_menu_item_new(unique_name, name, tooltip, FSL_ICON_NAME); |
|
if (base_name != a_base_name) { |
g_free(base_name); |