diff --git a/BUILD b/BUILD new file mode 100644 index 0000000..4c807d5 --- /dev/null +++ b/BUILD @@ -0,0 +1,25 @@ + +COMPILATION +=========== + +* If no ./configure exists (i.e. raw svn export), use the dist command: + $ ./dist + +* Configure + $ ./configure + + Note that this being a nautilus extension, the --prefix is not really needed + as there's no real flexibility on where to install them. The appropiate place + will be checked on install time. + +* Compile + $ make + +* Install + $ make install + + +Of special interest: + Pass -D_DEBUG to the precompiler to enable the debugging/verbose + mode. + CPPFLAGS="-D_DEBUG" ./configure diff --git a/ChangeLog b/ChangeLog index 40cace0..61f6624 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,13 @@ -0.5.1: +Iterim milestones: + +0.5.2: + * INTERNAL: Corrected includes and function declarations + * INTERNAL: Switched to the autotools build system + * BUGFIX: Retrieve libnautilus-extension's directory for installation + * BUGFIX: Fixed mistakenly using relative paths for link resolution + * BUGFIX: Fixed incorrect memory allocation (crashed nautilus sometimes) + +0.5.1 (23 oct 2006): * BUGFIX: Correctly check error in realpath() call * INTERNAL: Rearrangement in multiple files, applied static where appropiate diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..1ba208c --- /dev/null +++ b/Makefile.am @@ -0,0 +1,5 @@ + +SUBDIRS = src + +# This doesn't work as expected +libdir = @libdir@/nautilus/extensions-1.0 diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..5d61a8a --- /dev/null +++ b/configure.in @@ -0,0 +1,38 @@ + +AC_INIT(src/follow-symlink.c) +AM_INIT_AUTOMAKE(libnautilus-follow-symlink, "0.5.2") +AC_CONFIG_HEADER(src/config.h) + +dnl default FLAGS +CPPFLAGS="$CPPFLAGS -std=gnu99 -pedantic-errors -Wall" +CFLAGS="$CFLAGS -O -Wall -Werror" +LDFLAGS="$LDFLAGS -Wl,--as-needed" + +# libtool +AM_PROG_LIBTOOL +AM_DISABLE_STATIC + +AC_PROG_INSTALL +AC_LANG_C +AC_PROG_CC + +# string.h and stdlib.h are used +dnl defines STDC_HEADERS if ANSI-compliant headers are present +AC_HEADER_STDC +dnl Xref: http://www.seul.org/docs/autotut/#libtool +AC_CHECK_HEADERS(sys/stat.h,,AC_MSG_ERROR([required header file missing])) + +# glib-2.0: ensure it's present +dnl and set GLIB_CFLAGS and GLIB_LIBS +AM_PATH_GLIB_2_0 + +# pkg-config: ensure libnautilus-extension is found by pkg-config +PKG_CHECK_MODULES(NAUTILUS_EXTENSION, [libnautilus-extension]) + +#AC_DEFINE(_GNU_SOURCE) + +dnl Incorporate the result of tests +CFLAGS="$CFLAGS $GLIB_CFLAGS $NAUTILUS_EXTENSION_CFLAGS" +LIBS="$LIBS $GLIB_LIBS $NAUTILUS_EXTENSION_LIBS" + +AC_OUTPUT(Makefile src/Makefile) diff --git a/debian/changelog b/debian/changelog index 0008aab..18ac32f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +nautilus-follow-symlink (0.5.2-out.1) unstable; urgency=low + + * New upstream release + + -- Toni Corvera Tue, 24 Oct 2006 18:24:52 +0200 + +nautilus-follow-symlink (0.5.1-out.1) experimental; urgency=low + + * New upstream release + + -- Toni Corvera Mon, 23 Oct 2006 01:20:15 +0200 + nautilus-follow-symlink (0.5-out.1) experimental; urgency=low * Initial release diff --git a/debian/rules b/debian/rules index 43fffd4..6fb09d4 100755 --- a/debian/rules +++ b/debian/rules @@ -24,6 +24,8 @@ configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. + test -f configure || ./dist clean gen + ./configure --prefix=/usr --disable-static touch configure-stamp @@ -34,7 +36,7 @@ build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. - cd src && $(MAKE) FINAL=1 + $(MAKE) FINAL=1 #docbook-to-man debian/nautilus-follow-symlink.sgml > nautilus-follow-symlink.1 touch build-stamp @@ -45,7 +47,7 @@ clean: rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. - -cd src && $(MAKE) clean + -$(MAKE) clean dh_clean @@ -56,7 +58,9 @@ install: build dh_installdirs # Add here commands to install the package into debian/nautilus-follow-symlink. - cd src && $(MAKE) install DESTDIR=$(CURDIR)/debian/nautilus-follow-symlink + $(MAKE) install DESTDIR=$(CURDIR)/debian/nautilus-follow-symlink + # There's really no need for the .la file + rm -f $(CURDIR)/debian/nautilus-follow-symlink/`pkg-config --variable=extensiondir libnautilus-extension`/*.la # Build architecture-independent files here. diff --git a/dist b/dist new file mode 100755 index 0000000..25eca32 --- /dev/null +++ b/dist @@ -0,0 +1,30 @@ +#!/usr/bin/make -f + + +dist: gen + +# aclocal won't find libtool's m4, at least in debian, unless an +# extra include path is given, with libtoolize it is "." while +# whitout it is /usr/share/libtool/m4, altough it will fail +# on finding ltmain.sh + +gen: + libtoolize + aclocal -I . + autoconf + autoheader + automake --add-missing --foreign + +regen: clean gen + +clean: + make distclean || true + make clean || true + cd src && make clean || true + # + rm -rf autom4te.cache + rm -f config.* depcomp install-sh missing src/config.h src/config.h.in + rm -f aclocal.m4 + rm -f configure Makefile Makefile.in src/Makefile src/Makefile.in + # Undo libtoolize + rm -f libtool.m4 lt*.m4 ltmain.sh libtool diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index 20086f1..0000000 --- a/src/Makefile +++ /dev/null @@ -1,57 +0,0 @@ - -# Note that building without FINAL=1 creates an uber-verbose version - -ifneq ($(FINAL),1) - VERSION:=\"0.5.1.interim.debug\" -else - VERSION:=\"0.5.1\" -endif - -CFLAGS=$$(pkg-config --cflags glib-2.0 libnautilus-extension) -LDFLAGS=$$(pkg-config --libs glib-2.0 libnautilus-extension) - -CFLAGS+=-DPIC -fPIC -g -O -DVERSION=$(VERSION) -LDFLAGS+=-Wl,--as-needed -g -O - -ifneq ($(FINAL),1) - CFLAGS+=-D_DEBUG -endif - -TARGET=libnautilus-follow-symlink - -# REQUIRED TO BUILD! -TARGET_DIR=/usr/lib/nautilus/extensions-1.0 -INSTALL_DIR=$(DESTDIR)$(TARGET_DIR) - -CC:=gcc - -all: $(TARGET).so - -$(TARGET).la: follow-symlink.o nautilus-ext-follow-symlink.o - libtool --mode=link $(CC) $(LDFLAGS) -o $(TARGET).la follow-symlink.lo nautilus-ext-follow-symlink.lo -rpath $(TARGET_DIR) - -$(TARGET).so: $(TARGET).la - ln -sf .libs/$(TARGET).so . - -follow-symlink.o: follow-symlink.c follow-symlink.h common.h - libtool --mode=compile $(CC) $(CFLAGS) -c follow-symlink.c - -nautilus-ext-follow-symlink.o: nautilus-ext-follow-symlink.c nautilus-ext-follow-symlink.h common.h - libtool --mode=compile $(CC) $(CFLAGS) -c nautilus-ext-follow-symlink.c - -install: strip - mkdir -p $(INSTALL_DIR) - install -m644 -oroot -groot $(TARGET).so $(INSTALL_DIR)/ - -uninstall: - rm -f $(INSTALL_DIR)/$(TARGET).so - rmdir -p $(INSTALL_DIR) || true - -strip: $(TARGET).so - strip $(TARGET).so - -distclean: clean - -clean: - rm -f *.la *.lo *.o *.so - rm -rf .libs diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..ae07a5d --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,15 @@ + +nautilus_extension_lib_LTLIBRARIES = libnautilus-follow-symlink.la + +# Must be installed in nautilus' extension dir +#nautilus_extension_libdir = $(libdir)/nautilus/extensions-1.0 +# Cleaner way: +nautilus_extension_libdir = `pkg-config --variable=extensiondir libnautilus-extension` + +libnautilus_follow_symlink_la_SOURCES = follow-symlink.c nautilus-ext-follow-symlink.c + +# There's really no need to have versioned file names +libnautilus_follow_symlink_la_LDFLAGS = -avoid-version +# See e.g. for version instructions +#libnautilus_follow_symlink_la_LDFLAGS = -version-info 0:0:0 + diff --git a/src/common.h b/src/common.h index 9dccb64..bc7b1ba 100644 --- a/src/common.h +++ b/src/common.h @@ -1,16 +1,52 @@ #ifndef FOLLOW_SYMLINK_COMMON_H #define FOLLOW_SYMLINK_COMMON_H -#include +/* + * This file defines common debug utilities. + * Also, includes config.h. + */ + +#include /* g_print() */ +#include /* g_printf() */ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif // HAVE_CONFIG_H #ifdef _DEBUG -#define TRACE() (g_printf("nautilus-follow-symlink trace: %s()\n", __FUNCTION__)); -#else -#define TRACE() -#endif +/* Debugging facilities */ + #include /* getenv() (3) */ + #include /* strcmp() (3) */ -#ifndef VERSION -#define VERSION "interim.debug" + /* Prefix for messages */ + #define FSL_ "nautilus-follow-symlink: " + /* Environment variable, set to 1 to enable verbosity */ + #define DBGENV_ (getenv("FSL_DBG")) + /* Check on runtime the environment variable's value */ + #define DEBUG_ON_() (DBGENV_ != NULL && 0 == strcmp(DBGENV_,"1")) + + /* Informational message shown on initialisation */ + #define FSL_DEBUG_INIT() { \ + const int ENABLED = DEBUG_ON_(); \ + g_print( FSL_ "DEBUG mode is available, and "); \ + g_print( (ENABLED) ? "enabled.\n" : "disabled.\n"); \ + g_print( FSL_ "set the environment variable FSL_DBG to \n" \ + FSL_ "1 to enable it or to any other value to disable it.\n"); \ + }; + + /* Display the name of the current function name */ + #define TRACE() if (DEBUG_ON_())\ + g_printf("nautilus-follow-symlink trace: %s()\n", __FUNCTION__); + /* Display a message */ + #define FSL_LOG(str) if (DEBUG_ON_()) g_printf("%s\n", (str)); + /* Display a formatted message with one string argument */ + #define FSL_LOG1(str1, str2) if (DEBUG_ON_()) g_printf("%s %s\n", (str1), (str2)); +#else + /* Debugging facilities disabled */ + #define TRACE() + #define FSL_LOG(a) + #define FSL_LOG1(a,b) + #define FSL_DEBUG_INIT() #endif #endif /* FOLLOW_SYMLINK_COMMON_H */ diff --git a/src/follow-symlink.c b/src/follow-symlink.c index 2d88473..efef0fd 100644 --- a/src/follow-symlink.c +++ b/src/follow-symlink.c @@ -1,5 +1,15 @@ #include "follow-symlink.h" +#include +#include +#include /* errno (3) */ +#include /* realpath() (3) */ +#include /* strlen(), strerror() (3) */ + +// Offset at char 7 to remove file:// +static const unsigned short URI_OFFSET = 7 * sizeof(gchar); +static const size_t PATH_LENGTH_BYTES = sizeof(gchar) * (PATH_MAX + 1); + /* Menu initialization */ void fsl_extension_menu_provider_iface_init(NautilusMenuProviderIface *iface) { @@ -22,7 +32,8 @@ fsl_get_file_items (NautilusMenuProvider * provider, // Number of files = g_list_length(files) // Directory = nautilus_file_info_is_directory(files->data) - if (files == NULL || g_list_length(files) != 1) { + if (NULL==files || g_list_length(files) != 1) { + FSL_LOG( (NULL==files) ? "No file" : "More than one file" ); return NULL; } @@ -30,6 +41,7 @@ fsl_get_file_items (NautilusMenuProvider * provider, { gchar * uri_scheme = nautilus_file_info_get_uri_scheme(files->data); if (strcmp(uri_scheme, "file") != 0) { + FSL_LOG( "Not file scheme" ); return NULL; } g_free(uri_scheme); @@ -45,15 +57,18 @@ fsl_get_file_items (NautilusMenuProvider * provider, */ /*if (gfi->type != GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK) {*/ if (gfi->type != GNOME_VFS_FILE_TYPE_DIRECTORY) { + FSL_LOG( "Not directory" ); return NULL; } // We know the file is either a directory or a symlink to a directory // TODO: Has glib/gnome any better/faster alternatives? { struct stat file_info; - const gchar * const file_name = nautilus_file_info_get_name(files->data); + // Note ..._get_name doesn't give the full path + const gchar * const file_name = nautilus_file_info_get_uri(files->data) + URI_OFFSET; lstat(file_name, &file_info); if (! S_ISLNK(file_info.st_mode)) { + FSL_LOG1( "Not S_ISLNK:", file_name ); return NULL; } } @@ -69,32 +84,33 @@ void fsl_callback (NautilusMenuItem * item, NautilusFileInfo * file_info) { TRACE(); - //g_print("fsl_callback\n"); - const size_t URI_OFFSET = 7 * sizeof(gchar); // Offset at char 7 to remove file:// - const size_t PATH_LENGTH_BYTES = sizeof(gchar) * (PATH_MAX + 1); gchar ** argv; - const gchar * link_name = nautilus_file_info_get_uri(file_info); + const gchar * link_name = nautilus_file_info_get_uri(file_info) + URI_OFFSET; gchar * target = g_malloc(PATH_LENGTH_BYTES); /* unlike readlink(man 2), realpath(man 3) resolves the symlink, while * readlink returns the pointed file, which might be a relative path + * Xref: */ - if (NULL == realpath(link_name + URI_OFFSET, target)) { + if (NULL == realpath(link_name, target)) { + g_printf("ERROR in realpath(): %s\n", strerror(errno)); g_assert( FALSE ); } - const gchar const * BASE_CMD = "nautilus --no-desktop --no-default-window "; - gchar * command_line = g_malloc( sizeof(gchar) * (strlen(BASE_CMD) + strlen(target) + URI_OFFSET + 1) ); + const gchar const * BASE_CMD = "nautilus --no-desktop --no-default-window \""; + gchar * command_line = g_malloc( sizeof(gchar) * ( strlen(BASE_CMD) + strlen(target) + 2 ) ); gchar * offset = g_stpcpy(command_line, BASE_CMD); - offset = g_stpcpy(offset, "file://"); - g_stpcpy(offset, target); + //offset = g_stpcpy(offset, "file://"); // unneeded; also makes nautilus think it may be incorrect + // if it contains spaces (instead of %20's) + offset = g_stpcpy(offset, target); + g_stpcpy(offset, "\""); if (FALSE == g_shell_parse_argv(command_line, NULL, &argv, NULL)) { g_assert( FALSE ); } - g_printf("nautilus-follow-symlink: Spawning nautilus with\n \"%s\"\n", command_line); + g_printf("nautilus-follow-symlink: Spawning nautilus with\n '%s'\n", command_line); g_spawn_async( nautilus_file_info_get_parent_uri(file_info) + URI_OFFSET, argv, diff --git a/src/follow-symlink.h b/src/follow-symlink.h index 5faeeb1..14dd750 100644 --- a/src/follow-symlink.h +++ b/src/follow-symlink.h @@ -7,18 +7,11 @@ */ #include -#include -#include /* realpath() */ -#include /* strlen() */ #include "common.h" /* Static Prototypes */ -static GType fsl_get_type(void); - -static void fsl_register_type(GTypeModule *); - static void fsl_callback(NautilusMenuItem *, NautilusFileInfo *); static GList *fsl_get_file_items(NautilusMenuProvider *, GtkWidget *, GList *); diff --git a/src/nautilus-ext-follow-symlink.c b/src/nautilus-ext-follow-symlink.c index 0713d63..16f70e8 100644 --- a/src/nautilus-ext-follow-symlink.c +++ b/src/nautilus-ext-follow-symlink.c @@ -1,5 +1,7 @@ #include "nautilus-ext-follow-symlink.h" +#include + /* Public interface */ static GType fsl_type; static GType provider_types[1]; @@ -7,6 +9,7 @@ static GType provider_types[1]; void nautilus_module_initialize (GTypeModule *module) { TRACE(); + FSL_DEBUG_INIT(); g_printf("Initializing nautilus-follow-symlink extension (v.%s)\n", VERSION); @@ -70,12 +73,12 @@ GType fsl_get_type(void) return fsl_type; } -static void fsl_instance_init(FsymlinkExtension *cvs) +void fsl_instance_init(FsymlinkExtension *cvs) { TRACE(); } -static void fsl_class_init(FsymlinkExtensionClass *class) +void fsl_class_init(FsymlinkExtensionClass *class) { TRACE(); }