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