Author: colossus
Date: 2006-11-22 12:36:03 +0000 (Wed, 22 Nov 2006)
New Revision: 23930

Added:
   xarchiver/trunk/src/socket.c
   xarchiver/trunk/src/socket.h
Modified:
   xarchiver/trunk/configure.in.in
   xarchiver/trunk/src/Makefile.am
   xarchiver/trunk/src/callbacks.c
   xarchiver/trunk/src/main.c
   xarchiver/trunk/src/main.h
Log:
Xarchiver reuses the running instance if called from the cmd-line with 
parameters.


Modified: xarchiver/trunk/configure.in.in
===================================================================
--- xarchiver/trunk/configure.in.in     2006-11-22 08:16:37 UTC (rev 23929)
+++ xarchiver/trunk/configure.in.in     2006-11-22 12:36:03 UTC (rev 23930)
@@ -70,7 +70,7 @@
 dnl ************************************
 dnl *** Check for standard functions ***
 dnl ************************************
-AC_CHECK_FUNCS([strcasestr mkdtemp])
+AC_CHECK_FUNCS([strcasestr mkdtemp socket])
 
 dnl ******************************
 dnl *** Check for i18n support ***

Modified: xarchiver/trunk/src/Makefile.am
===================================================================
--- xarchiver/trunk/src/Makefile.am     2006-11-22 08:16:37 UTC (rev 23929)
+++ xarchiver/trunk/src/Makefile.am     2006-11-22 12:36:03 UTC (rev 23930)
@@ -1,6 +1,7 @@
 bin_PROGRAMS = xarchiver
 
 xarchiver_SOURCES = \
+       socket.c socket.h \
        main.c main.h \
        string_utils.c string_utils.h \
        support.c support.h \

Modified: xarchiver/trunk/src/callbacks.c
===================================================================
--- xarchiver/trunk/src/callbacks.c     2006-11-22 08:16:37 UTC (rev 23929)
+++ xarchiver/trunk/src/callbacks.c     2006-11-22 12:36:03 UTC (rev 23930)
@@ -2122,8 +2122,8 @@
        idx = xa_find_archive_index (current_page);
 
     selection = gtk_tree_view_get_selection (GTK_TREE_VIEW 
(archive[idx]->treeview));
+       row_list = gtk_tree_selection_get_selected_rows (selection, NULL);
 
-       row_list = gtk_tree_selection_get_selected_rows (selection, NULL);
        if ( row_list == NULL)
                return;
        if ( archive[idx]->status == XA_ARCHIVESTATUS_EXTRACT )

Modified: xarchiver/trunk/src/main.c
===================================================================
--- xarchiver/trunk/src/main.c  2006-11-22 08:16:37 UTC (rev 23929)
+++ xarchiver/trunk/src/main.c  2006-11-22 12:36:03 UTC (rev 23930)
@@ -20,6 +20,10 @@
 #include "main.h"
 #include "string_utils.h"
 
+#ifdef HAVE_SOCKET
+#include "socket.h"
+#endif
+
 gint exit_status;
 gchar *cli_command = NULL;
 gchar *absolute_path = NULL;
@@ -60,6 +64,19 @@
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
        textdomain (GETTEXT_PACKAGE);
        #endif
+
+#ifdef HAVE_SOCKET
+       socket_info.lock_socket = -1;
+       socket_info.lock_socket_tag = 0;
+       socket_info.lock_socket = socket_init(argc, argv);
+
+       if (socket_info.lock_socket < 0)
+       {
+               // Socket exists
+               if (argc > 1)   // filenames were sent to first instance, so 
quit
+                       return 0;
+       }
+#endif
        gtk_init_with_args(&argc, &argv, _("[archive name]"), entries, PACKAGE, 
&cli_error);
        g_get_charset (&locale);
        if ( cli_error != NULL )
@@ -217,6 +234,13 @@
                        current_open_directory = g_path_get_dirname (dummy);
                        xa_open_archive ( NULL , dummy );
                }
+               #ifdef HAVE_SOCKET
+               if (! socket_info.ignore_socket && socket_info.lock_socket > 0)
+               {
+                       socket_info.read_ioc = 
g_io_channel_unix_new(socket_info.lock_socket);
+                       socket_info.lock_socket_tag = 
g_io_add_watch(socket_info.read_ioc,      G_IO_IN|G_IO_PRI|G_IO_ERR, 
socket_lock_input_cb, MainWindow);
+               }
+               #endif
                gtk_main ();
                g_list_free ( ArchiveSuffix);
                g_list_free ( ArchiveType);
@@ -224,6 +248,23 @@
        }
 }
 
+gchar *get_argv_filename(const gchar *filename)
+{
+       gchar *result;
+
+       if (g_path_is_absolute(filename))
+               result = g_strdup(filename);
+       else
+       {
+               //use current dir
+               gchar *cur_dir = g_get_current_dir();
+               result = g_strjoin(
+                       G_DIR_SEPARATOR_S, cur_dir, filename, NULL);
+               g_free(cur_dir);
+       }
+       return result;
+}
+
 void GetAvailableCompressors()
 {
        absolute_path = g_find_program_in_path("arj");

Modified: xarchiver/trunk/src/main.h
===================================================================
--- xarchiver/trunk/src/main.h  2006-11-22 08:16:37 UTC (rev 23929)
+++ xarchiver/trunk/src/main.h  2006-11-22 12:36:03 UTC (rev 23930)
@@ -33,6 +33,7 @@
 
 void GetAvailableCompressors();
 void xa_set_button_state ( gboolean, gboolean,gboolean,gboolean, gboolean, 
gboolean );
+gchar *get_argv_filename(const gchar *filename);
 gboolean SpawnSyncCommand ( gchar *command );
 XArchive *xa_init_structure_from_cmd_line (char *filename);
 #endif /* MAIN_H */

Added: xarchiver/trunk/src/socket.c
===================================================================
--- xarchiver/trunk/src/socket.c                                (rev 0)
+++ xarchiver/trunk/src/socket.c        2006-11-22 12:36:03 UTC (rev 23930)
@@ -0,0 +1,304 @@
+/*
+ *  Copyright (C) 2006 Giuseppe Torelli - <[EMAIL PROTECTED]>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#ifdef HAVE_SOCKET
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "socket.h"
+
+static gint socket_fd_connect_unix     (const gchar *path);
+static gint socket_fd_open_unix                (const gchar *path);
+static gint socket_fd_write                    (gint sock, const gchar *buf, 
gint len);
+static gint socket_fd_write_all                (gint sock, const gchar *buf, 
gint len);
+static gint socket_fd_gets                     (gint sock, gchar *buf, gint 
len);
+static gint socket_fd_check_io         (gint fd, GIOCondition cond);
+static gint socket_fd_read                     (gint sock, gchar *buf, gint 
len);
+static gint socket_fd_recv                     (gint fd, gchar *buf, gint len, 
gint flags);
+static gint socket_fd_close                    (gint sock);
+
+/* (Unix domain) socket support to replace the old FIFO code
+ * (taken from Sylpheed, thanks) */
+gint socket_init(gint argc, gchar **argv)
+{
+       gint sock;
+
+       if (socket_info.file_name == NULL)
+               socket_info.file_name = g_strdup ("/tmp/xarchiver_socket");
+
+       sock = socket_fd_connect_unix(socket_info.file_name);
+       if (sock < 0)
+       {
+               unlink(socket_info.file_name);
+               return socket_fd_open_unix(socket_info.file_name);
+       }
+       // remote command mode, here we have another running instance and want 
to use it
+       if (argc > 1)
+       {
+               gint i;
+               gchar *filename;
+
+               socket_fd_write_all(sock, "open\n", 5);
+
+               for(i = 1; i < argc && argv[i] != NULL; i++)
+               {
+                       filename = argv[i];
+
+                       if (filename != NULL)
+                       {
+                               socket_fd_write_all(sock, filename, 
strlen(filename));
+                               socket_fd_write_all(sock, "\n", 1);
+                               g_free(filename);
+                       }
+               }
+               socket_fd_write_all(sock, ".\n", 2);
+       }
+
+       socket_fd_close(sock);
+       return -1;
+}
+
+gint socket_finalize(void)
+{
+       if (socket_info.lock_socket < 0) return -1;
+
+       if (socket_info.lock_socket_tag > 0)
+               g_source_remove(socket_info.lock_socket_tag);
+       if (socket_info.read_ioc)
+       {
+               g_io_channel_shutdown(socket_info.read_ioc, FALSE, NULL);
+               g_io_channel_unref(socket_info.read_ioc);
+               socket_info.read_ioc = NULL;
+       }
+
+       unlink(socket_info.file_name);
+       g_free(socket_info.file_name);
+       return 0;
+}
+
+static gint socket_fd_connect_unix(const gchar *path)
+{
+       gint sock;
+       struct sockaddr_un addr;
+
+       sock = socket(PF_UNIX, SOCK_STREAM, 0);
+       if (sock < 0)
+       {
+               perror("fd_connect_unix(): socket");
+               return -1;
+       }
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
+
+       if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+       {
+               socket_fd_close(sock);
+               return -1;
+       }
+       return sock;
+}
+
+static gint socket_fd_open_unix(const gchar *path)
+{
+       gint sock;
+       struct sockaddr_un addr;
+       gint val;
+
+       sock = socket(PF_UNIX, SOCK_STREAM, 0);
+
+       if (sock < 0)
+       {
+               perror("sock_open_unix(): socket");
+               return -1;
+       }
+
+       val = 1;
+       if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0)
+       {
+               perror("setsockopt");
+               socket_fd_close(sock);
+               return -1;
+       }
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
+
+       if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+       {
+               perror("bind");
+               socket_fd_close(sock);
+               return -1;
+       }
+
+       if (listen(sock, 1) < 0)
+       {
+               perror("listen");
+               socket_fd_close(sock);
+               return -1;
+       }
+
+       return sock;
+}
+
+static gint socket_fd_close(gint fd)
+{
+       return close(fd);
+}
+
+gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, 
gpointer data)
+{
+       gint fd, sock;
+       gchar buf[4096];
+       gchar *buf_to_free;
+       struct sockaddr_in caddr;
+       guint caddr_len;
+       GtkWidget *window = data;
+       caddr_len = sizeof(caddr);
+
+       fd = g_io_channel_unix_get_fd(source);
+       sock = accept(fd, (struct sockaddr *)&caddr, &caddr_len);
+       // first get the command
+       if (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && strncmp(buf, 
"open", 4) == 0)
+       {
+               while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != 
'.')
+               {
+                       g_strstrip(buf); // remove \n char
+                       buf_to_free = g_strdup (buf);
+                       if (g_file_test(buf, G_FILE_TEST_IS_REGULAR | 
G_FILE_TEST_IS_SYMLINK))
+                               xa_open_archive (NULL,buf_to_free);
+               }
+               gtk_window_deiconify (GTK_WINDOW(window));
+       }
+       socket_fd_close(sock);
+       return TRUE;
+}
+
+static gint socket_fd_gets(gint fd, gchar *buf, gint len)
+{
+       gchar *newline, *bp = buf;
+       gint n;
+
+       if (--len < 1)
+               return -1;
+       do
+       {
+               if ((n = socket_fd_recv(fd, bp, len, MSG_PEEK)) <= 0)
+                       return -1;
+               if ((newline = memchr(bp, '\n', n)) != NULL)
+                       n = newline - bp + 1;
+               if ((n = socket_fd_read(fd, bp, n)) < 0)
+                       return -1;
+               bp += n;
+               len -= n;
+       } while (! newline && len);
+
+       *bp = '\0';
+       return bp - buf;
+}
+
+static gint socket_fd_recv(gint fd, gchar *buf, gint len, gint flags)
+{
+       if (socket_fd_check_io(fd, G_IO_IN) < 0)
+               return -1;
+
+       return recv(fd, buf, len, flags);
+}
+
+
+static gint socket_fd_read(gint fd, gchar *buf, gint len)
+{
+       if (socket_fd_check_io(fd, G_IO_IN) < 0)
+               return -1;
+       return read(fd, buf, len);
+}
+
+static gint socket_fd_check_io(gint fd, GIOCondition cond)
+{
+       struct timeval timeout;
+       fd_set fds;
+       gint flags;
+       timeout.tv_sec  = 60;
+       timeout.tv_usec = 0;
+
+       // checking for non-blocking mode
+       flags = fcntl(fd, F_GETFL, 0);
+       if (flags < 0)
+       {
+               perror("fcntl");
+               return 0;
+       }
+
+       if ((flags & O_NONBLOCK) != 0)
+               return 0;
+
+       FD_ZERO(&fds);
+       FD_SET(fd, &fds);
+
+       if (cond == G_IO_IN)
+       {
+               select(fd + 1, &fds, NULL, NULL, &timeout);
+       }
+       else
+       {
+               select(fd + 1, NULL, &fds, NULL, &timeout);
+       }
+
+       if (FD_ISSET(fd, &fds))
+       {
+               return 0;
+       }
+       else
+               return -1;
+}
+
+static gint socket_fd_write_all(gint fd, const gchar *buf, gint len)
+{
+       gint n, wrlen = 0;
+
+       while (len)
+       {
+               n = socket_fd_write(fd, buf, len);
+               if (n <= 0)
+                       return -1;
+               len -= n;
+               wrlen += n;
+               buf += n;
+       }
+
+       return wrlen;
+}
+
+gint socket_fd_write(gint fd, const gchar *buf, gint len)
+{
+       if (socket_fd_check_io(fd, G_IO_OUT) < 0)
+               return -1;
+       return write(fd, buf, len);
+}
+
+#endif
+
+

Added: xarchiver/trunk/src/socket.h
===================================================================
--- xarchiver/trunk/src/socket.h                                (rev 0)
+++ xarchiver/trunk/src/socket.h        2006-11-22 12:36:03 UTC (rev 23930)
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (C) 2006 Giuseppe Torelli - <[EMAIL PROTECTED]>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef XARCHIVER_SOCKET_H
+#define XARCHIVER_SOCKET_H
+
+struct
+{
+       gboolean         ignore_socket;
+       gchar           *file_name;
+       GIOChannel      *read_ioc;
+       gint             lock_socket;
+       gint             lock_socket_tag;
+} socket_info;
+
+gint socket_init (gint argc, gchar **argv);
+gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, 
gpointer data);
+gint socket_finalize();
+
+#endif

_______________________________________________
Xfce4-commits mailing list
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to