[w3m-dev 04151] Re: w3m -remote
Hiroyuki Ito <[email protected]> Tue, 28 Jun 2005 23:17:10 +0900 (JST)
| Newsgroups | gmane.comp.web.w3m.devel |
|---|---|
| Message-ID | <[email protected]> |
w3m -remote
-enable_remote
-remote COMMAND ... w3m COMMAND
COMMAND
-remote_id PID w3m id
w3m
-enabel_remote ~/.w3m w3msock* (* pid)
-remote COMMAND
w3m w3m
~/.w3m 700
UID
Linux (2.2 ) getsockopt() SO_PEERCRED
FreeBSD getpeereid()
LOCAL_CREDS
linux
getpeereid(), SO_PEERCRED
stat UID
Index: acinclude.m4
===================================================================
RCS file: /cvsroot/w3m/w3m/acinclude.m4,v
retrieving revision 1.40
diff -u -r1.40 acinclude.m4
--- acinclude.m4 14 Feb 2005 16:36:30 -0000 1.40
+++ acinclude.m4 28 Jun 2005 13:27:54 -0000
@@ -70,6 +70,18 @@
AC_MSG_RESULT($enable_mouse)])
#
# ----------------------------------------------------------------
+# AC_W3M_REMOTE
+# ----------------------------------------------------------------
+AC_DEFUN([AC_W3M_REMOTE],
+[AC_SUBST(USE_MOUSE)
+AC_MSG_CHECKING(if remote operation enabled)
+AC_ARG_ENABLE(remote,
+ [ --disable-remote disable remote operation],,
+ [enable_remote="yes"])
+test x"$enable_remote" = xyes && AC_DEFINE(USE_REMOTE)
+AC_MSG_RESULT($enable_remote)])
+#
+# ----------------------------------------------------------------
# AC_W3M_COOKIE
# ----------------------------------------------------------------
AC_DEFUN([AC_W3M_COOKIE],
@@ -877,3 +889,27 @@
else
AC_DEFINE(SIGNAL_RETURN,return 0)
fi])
+#
+# ----------------------------------------------------------------
+# AC_W3M_SO_PEERCRED
+# ----------------------------------------------------------------
+AC_DEFUN([AC_W3M_SO_PEERCRED],
+[AC_SUBST(HAVE_SO_PEERCRED)
+AC_MSG_CHECKING(for SO_PEERCRED)
+AC_TRY_COMPILE(
+[#include <sys/socket.h>],
+[ int sopt = SO_PEERCRED;
+ exit(sopt);],
+[have_so_peercred="yes"; AC_DEFINE(HAVE_SO_PEERCRED)],
+[have_so_peercred="no"])
+AC_MSG_RESULT($have_so_peercred)])
+#
+# ----------------------------------------------------------------
+# AC_W3M_GETPEEREID
+# ----------------------------------------------------------------
+AC_DEFUN([AC_W3M_GETPEEREID],
+[AC_SUBST(HAVE_GETPEEREID)
+AC_MSG_CHECKING(for getpeereid)
+AC_CHECK_FUNC(getpeereid,
+[have_getpeereid="yes"; AC_DEFINE(HAVE_GETPEEREID)],
+[have_getpeereid="no"])])
Index: aclocal.m4
===================================================================
RCS file: /cvsroot/w3m/w3m/aclocal.m4,v
retrieving revision 1.41
diff -u -r1.41 aclocal.m4
--- aclocal.m4 14 Feb 2005 16:36:30 -0000 1.41
+++ aclocal.m4 28 Jun 2005 13:27:55 -0000
@@ -82,6 +82,18 @@
AC_MSG_RESULT($enable_mouse)])
#
# ----------------------------------------------------------------
+# AC_W3M_REMOTE
+# ----------------------------------------------------------------
+AC_DEFUN([AC_W3M_REMOTE],
+[AC_SUBST(USE_MOUSE)
+AC_MSG_CHECKING(if remote operation enabled)
+AC_ARG_ENABLE(remote,
+ [ --disable-remote disable remote operation],,
+ [enable_remote="yes"])
+test x"$enable_remote" = xyes && AC_DEFINE(USE_REMOTE)
+AC_MSG_RESULT($enable_remote)])
+#
+# ----------------------------------------------------------------
# AC_W3M_COOKIE
# ----------------------------------------------------------------
AC_DEFUN([AC_W3M_COOKIE],
@@ -890,6 +902,31 @@
AC_DEFINE(SIGNAL_RETURN,return 0)
fi])
+#
+# ----------------------------------------------------------------
+# AC_W3M_SO_PEERCRED
+# ----------------------------------------------------------------
+AC_DEFUN([AC_W3M_SO_PEERCRED],
+[AC_SUBST(HAVE_SO_PEERCRED)
+AC_MSG_CHECKING(for SO_PEERCRED)
+AC_TRY_COMPILE(
+[#include <sys/socket.h>],
+[ int sopt = SO_PEERCRED;
+ exit(sopt);],
+[have_so_peercred="yes"; AC_DEFINE(HAVE_SO_PEERCRED)],
+[have_so_peercred="no"])
+AC_MSG_RESULT($have_so_peercred)])
+#
+# ----------------------------------------------------------------
+# AC_W3M_GETPEEREID
+# ----------------------------------------------------------------
+AC_DEFUN([AC_W3M_GETPEEREID],
+[AC_SUBST(HAVE_GETPEEREID)
+AC_MSG_CHECKING(for getpeereid)
+AC_CHECK_FUNC(getpeereid,
+[have_getpeereid="yes"; AC_DEFINE(HAVE_GETPEEREID)],
+[have_getpeereid="no"])])
+
# lib-prefix.m4 serial 3 (gettext-0.13)
dnl Copyright (C) 2001-2003 Free Software Foundation, Inc.
dnl This file is free software, distributed under the terms of the GNU
Index: config.h.in
===================================================================
RCS file: /cvsroot/w3m/w3m/config.h.in,v
retrieving revision 1.16
diff -u -r1.16 config.h.in
--- config.h.in 26 Feb 2005 17:06:44 -0000 1.16
+++ config.h.in 28 Jun 2005 13:27:56 -0000
@@ -53,6 +53,7 @@
#undef USE_MIGEMO
#define USE_MARK
#undef USE_MOUSE
+#undef USE_REMOTE
#undef USE_GPM
#undef USE_SYSMOUSE
#undef USE_MENU
@@ -143,6 +144,8 @@
#undef HAVE_SETPGRP
#undef HAVE_SETLOCALE
#undef HAVE_LANGINFO_CODESET
+#undef HAVE_SO_PEERCRED
+#undef HAVE_GETPEEREID
#undef SETPGRP_VOID
#ifdef HAVE_SETPGRP
Index: configure
===================================================================
RCS file: /cvsroot/w3m/w3m/configure,v
retrieving revision 1.153
diff -u -r1.153 configure
--- configure 26 Feb 2005 17:13:58 -0000 1.153
+++ configure 28 Jun 2005 13:27:59 -0000
@@ -310,7 +310,7 @@
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS PACKAGE VERSION W3M W3M_LANG AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB PERL NKF MAN build build_cpu build_vendor build_os host host_cpu host_vendor host_os W3M_TARGET W3M_LIBS USE_M17N USE_UNICODE WCTARGET WCCFLAGS DISPLAY_CHARSET SYSTEM_CHARSET DOCUMENT_CHARSET POSUBST POLANG MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE LIBICONV LTLIBICONV INTLLIBS LIBINTL LTLIBINTL POSUB INTLTARGET NLSTARGET USE_COLOR USE_ANSI_COLOR USE_BG_COLOR USE_IMAGE USE_W3
MIMG_X11 USE_W3MIMG_FB W3MIMGDISPLAY_SETUID INSTALL_W3MIMGDISPLAY USE_GDKPIXBUF USE_GTK2 !
USE_IMLIB USE_IMLIB2 IMGTARGETS IMGOBJS IMGX11CFLAGS IMGX11LDFLAGS IMGFBCFLAGS IMGFBLDFLAGS USE_XFACE uncompface KEYMAP_FILE HELP_FILE KEYBIND USE_MENU USE_MOUSE USE_HISTORY USE_ALARM USE_COOKIE USE_DIGEST_AUTH USE_NNTP USE_GOPHER USE_DICT USE_HELP_CGI USE_EXTERNAL_URI_LOADER USE_W3MMAILER USE_MIGEMO DEF_MIGEMO_COMMAND DEF_EDITOR DEF_MAILER DEF_EXT_BROWSER INET6 HAVE_OLD_SS_FAMILY USE_SSL USE_SSL_VERIFY PKG_CONFIG SSL_CFLAGS SSL_LIBS USE_W3M USE_SYSMOUSE AUXBIN_TARGETS EGREP USE_BINMODE_STREAM HAVE_SYS_ERRLIST HAVE_SIGSETJMP RETSIGTYPE SIGNAL_RETURN HELP_DIR RC_DIR DOCDIRS CURRENT_VERSION LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS PACKAGE VERSION W3M W3M_LANG AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB PERL NKF MAN build build_cpu build_vendor build_os host host_cpu host_vendor host_os W3M_TARGET W3M_LIBS USE_M17N USE_UNICODE WCTARGET WCCFLAGS DISPLAY_CHARSET SYSTEM_CHARSET DOCUMENT_CHARSET POSUBST POLANG MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE LIBICONV LTLIBICONV INTLLIBS LIBINTL LTLIBINTL POSUB INTLTARGET NLSTARGET USE_COLOR USE_ANSI_COLOR USE_BG_COLOR USE_IMAGE USE_W3
MIMG_X11 USE_W3MIMG_FB W3MIMGDISPLAY_SETUID INSTALL_W3MIMGDISPLAY USE_GDKPIXBUF USE_GTK2 !
USE_IMLIB USE_IMLIB2 IMGTARGETS IMGOBJS IMGX11CFLAGS IMGX11LDFLAGS IMGFBCFLAGS IMGFBLDFLAGS USE_XFACE uncompface KEYMAP_FILE HELP_FILE KEYBIND USE_MENU USE_MOUSE USE_HISTORY USE_ALARM USE_COOKIE USE_DIGEST_AUTH USE_NNTP USE_GOPHER USE_DICT USE_HELP_CGI USE_EXTERNAL_URI_LOADER USE_W3MMAILER USE_MIGEMO DEF_MIGEMO_COMMAND DEF_EDITOR DEF_MAILER DEF_EXT_BROWSER INET6 HAVE_OLD_SS_FAMILY USE_SSL USE_SSL_VERIFY PKG_CONFIG SSL_CFLAGS SSL_LIBS USE_W3M USE_SYSMOUSE AUXBIN_TARGETS EGREP USE_BINMODE_STREAM HAVE_SYS_ERRLIST HAVE_SIGSETJMP RETSIGTYPE SIGNAL_RETURN HAVE_SO_PEERCRED HAVE_GETPEEREID HELP_DIR RC_DIR DOCDIRS CURRENT_VERSION LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -866,6 +866,7 @@
--disable-mouse disable mouse operation
--disable-history disable URL history
--disable-alarm disable alarm
+ --disable-remote disable remote operation
--disable-cookie disable cookie
--disable-digest-auth disable digest auth
--disable-nntp disable NNTP
@@ -5502,6 +5503,22 @@
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
+echo "$as_me:$LINENO: checking if remote operation enabled" >&5
+echo $ECHO_N "checking if remote operation enabled... $ECHO_C" >&6
+# Check whether --enable-remote or --disable-remote was given.
+if test "${enable_remote+set}" = set; then
+ enableval="$enable_remote"
+
+else
+ enable_remote="yes"
+fi;
+test x"$enable_remote" = xyes && cat >>confdefs.h <<\_ACEOF
+#define USE_REMOTE 1
+_ACEOF
+
+echo "$as_me:$LINENO: result: $enable_remote" >&5
+echo "${ECHO_T}$enable_remote" >&6
+
echo "$as_me:$LINENO: checking if cookie is enabled" >&5
echo $ECHO_N "checking if cookie is enabled... $ECHO_C" >&6
@@ -10256,6 +10273,160 @@
fi
+echo "$as_me:$LINENO: checking for SO_PEERCRED" >&5
+echo $ECHO_N "checking for SO_PEERCRED... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/socket.h>
+int
+main ()
+{
+ int sopt = SO_PEERCRED;
+ exit(sopt);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ have_so_peercred="yes"; cat >>confdefs.h <<\_ACEOF
+#define HAVE_SO_PEERCRED 1
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+have_so_peercred="no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $have_so_peercred" >&5
+echo "${ECHO_T}$have_so_peercred" >&6
+
+echo "$as_me:$LINENO: checking for getpeereid" >&5
+echo $ECHO_N "checking for getpeereid... $ECHO_C" >&6
+echo "$as_me:$LINENO: checking for getpeereid" >&5
+echo $ECHO_N "checking for getpeereid... $ECHO_C" >&6
+if test "${ac_cv_func_getpeereid+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define getpeereid to an innocuous variant, in case <limits.h> declares getpeereid.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define getpeereid innocuous_getpeereid
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getpeereid (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef getpeereid
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getpeereid ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_getpeereid) || defined (__stub___getpeereid)
+choke me
+#else
+char (*f) () = getpeereid;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != getpeereid;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_getpeereid=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_getpeereid=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_getpeereid" >&5
+echo "${ECHO_T}$ac_cv_func_getpeereid" >&6
+if test $ac_cv_func_getpeereid = yes; then
+ have_getpeereid="yes"; cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETPEEREID 1
+_ACEOF
+
+else
+ have_getpeereid="no"
+fi
+
+
HELP_DIR="$datadir/$PACKAGE"
cat >>confdefs.h <<\_ACEOF
@@ -11042,6 +11213,8 @@
s,@HAVE_SIGSETJMP@,$HAVE_SIGSETJMP,;t t
s,@RETSIGTYPE@,$RETSIGTYPE,;t t
s,@SIGNAL_RETURN@,$SIGNAL_RETURN,;t t
+s,@HAVE_SO_PEERCRED@,$HAVE_SO_PEERCRED,;t t
+s,@HAVE_GETPEEREID@,$HAVE_GETPEEREID,;t t
s,@HELP_DIR@,$HELP_DIR,;t t
s,@RC_DIR@,$RC_DIR,;t t
s,@DOCDIRS@,$DOCDIRS,;t t
Index: configure.ac
===================================================================
RCS file: /cvsroot/w3m/w3m/configure.ac,v
retrieving revision 1.1
diff -u -r1.1 configure.ac
--- configure.ac 26 Feb 2005 17:13:59 -0000 1.1
+++ configure.ac 28 Jun 2005 13:27:59 -0000
@@ -67,6 +67,7 @@
AC_W3M_MOUSE
AC_W3M_HISTORY
AC_W3M_ALARM
+AC_W3M_REMOTE
AC_W3M_COOKIE
AC_W3M_DIGEST_AUTH
@@ -152,6 +153,8 @@
AC_W3M_SYS_ERRLIST
AC_W3M_SIGSETJMP
AC_W3M_SIGNAL
+AC_W3M_SO_PEERCRED
+AC_W3M_GETPEEREID
AC_SUBST(HELP_DIR)
HELP_DIR="$datadir/$PACKAGE"
Index: main.c
===================================================================
RCS file: /cvsroot/w3m/w3m/main.c,v
retrieving revision 1.247
diff -u -r1.247 main.c
--- main.c 26 Feb 2005 17:06:44 -0000 1.247
+++ main.c 28 Jun 2005 13:28:01 -0000
@@ -14,6 +14,13 @@
#include "terms.h"
#include "myctype.h"
#include "regex.h"
+
+#ifdef USE_REMOTE
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <dirent.h>
+#endif
+
#ifdef USE_MOUSE
#ifdef USE_GPM
#include <gpm.h>
@@ -104,6 +111,19 @@
#define help() fusage(stdout, 0)
#define usage() fusage(stderr, 1)
+#ifdef USE_REMOTE
+static int open_remote(int id);
+static void execute_remote(int sock, char *arg);
+static Str find_sock(int pid);
+static int init_serv(void);
+static int init_remote(char *prefix);
+static void parse_sock_data(void);
+static Str SockName;
+static int SockFd = -1, UseRemote = FALSE, ExecuteRemote = FALSE, RemoteId = -1;
+struct sockaddr_un SockAddr;
+socklen_t SockLength;
+#endif
+
static void
fversion(FILE * f)
{
@@ -134,6 +154,9 @@
",sysmouse"
#endif
#endif
+#ifdef USE_REMOTE
+ ",remote"
+#endif
#ifdef USE_MENU
",menu"
#endif
@@ -229,6 +252,11 @@
#ifdef USE_MOUSE
fprintf(f, " -no-mouse don't use mouse\n");
#endif /* USE_MOUSE */
+#ifdef USE_REMOTE
+ fprintf(f, " -enable_remote accept remote operation\n");
+ fprintf(f, " -remote command execute command in an already running w3m process\n");
+ fprintf(f, " -remote_id pid select a w3m to control with -remote option\n");
+#endif /* USE_MOUSE */
#ifdef USE_COOKIE
fprintf(f,
" -cookie use cookie (-no-cookie: don't use cookie)\n");
@@ -727,6 +755,33 @@
else if (!strcmp("-dummy", argv[i])) {
/* do nothing */
}
+#ifdef USE_REMOTE
+ else if (!strcmp("-enable_remote", argv[i])) {
+ UseRemote = TRUE;
+ }
+ else if (!strcmp("-remote_id", argv[i])) {
+ if (++i >= argc)
+ usage();
+ RemoteId = atoi(argv[i]);
+ }
+ else if (!strcmp("-remote", argv[i])) {
+ ExecuteRemote = TRUE;
+
+ SockFd = open_remote(RemoteId);
+ if (SockFd < 0) {
+ fprintf(stderr, "Can't find w3m process.\n");
+ exit(1);
+ }
+ while (++i < argc) {
+ if ((*argv[i] == '+') || (*argv[i] == '-')) {
+ i--;
+ break;
+ }
+ execute_remote(SockFd, argv[i]);
+ }
+ close(SockFd);
+ }
+#endif
else if (!strcmp("-debug", argv[i]))
w3m_debug = TRUE;
else {
@@ -741,7 +796,11 @@
}
i++;
}
-
+#ifdef USE_REMOTE
+ if (ExecuteRemote) {
+ exit(0);
+ }
+#endif
#ifdef __WATT32__
if (w3m_debug)
dbug_init();
@@ -1028,6 +1087,13 @@
if (line_str) {
_goLine(line_str);
}
+
+#ifdef USE_REMOTE
+ if (UseRemote) {
+ init_serv();
+ }
+#endif
+
for (;;) {
if (add_download_list) {
add_download_list = FALSE;
@@ -1098,7 +1164,20 @@
} while (sleep_till_anykey(1, 0) <= 0);
}
#endif
+#ifdef USE_REMOTE
+ if (UseRemote) {
+ int n;
+ c = getch_select(SockFd, &n);
+ if (n == 1) {
+ parse_sock_data();
+ continue;
+ }
+ } else {
+ c = getch();
+ }
+#else
c = getch();
+#endif
#ifdef SIGWINCH
mySignal(SIGWINCH, resize_hook);
#endif
@@ -1130,6 +1209,237 @@
}
}
+#ifdef USE_REMOTE
+#ifndef HAVE_GETPEEREID
+#ifdef HAVE_SO_PEERCRED
+int
+getpeereid(int s, uid_t *euid, gid_t *egid)
+{
+ struct ucred cr;
+ int cl = sizeof(cr), r;
+
+ r = getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cl);
+ if (r)
+ return r;
+
+ *euid = cr.uid;
+ *egid = cr.gid;
+ return 0;
+}
+#endif /* HAVE_SO_PEERCRED */
+#endif /* ! HAVE_GETPEEREID */
+
+static int
+open_remote(int id)
+{
+#if defined(HAVE_SO_PEERCRED) || defined(HAVE_GETPEEREID)
+ uid_t euid;
+ gid_t egid;
+#endif
+ Str sock_name = find_sock(id);
+
+ if (! sock_name)
+ return -1;
+
+ if (sizeof(SockAddr.sun_path) <= sock_name->length)
+ return -1;
+
+ if (init_remote("w3mclis"))
+ return -1;
+
+ SockAddr.sun_family = AF_UNIX;
+ strcpy(SockAddr.sun_path, sock_name->ptr);
+ SockLength = sizeof(SockAddr.sun_family) + strlen(SockAddr.sun_path);
+
+ if (connect(SockFd, (struct sockaddr *) &SockAddr, SockLength)) {
+ close(SockFd);
+ unlink(SockName->ptr);
+ return -1;
+ }
+
+#if defined(HAVE_SO_PEERCRED) || defined(HAVE_GETPEEREID)
+ if (getpeereid(SockFd, &euid, &egid) != 0 || euid != getuid()) {
+ close(SockFd);
+ unlink(SockName->ptr);
+ return -1;
+ }
+#endif
+
+ return SockFd;
+}
+
+static void
+execute_remote(int sock, char *arg)
+{
+ write(sock, arg, strlen(arg));
+ write(sock, "\n", 1);
+}
+
+static Str
+find_sock(int pid)
+{
+ DIR *dot_w3m;
+ Str sock_name;
+ struct dirent *file = NULL;
+ struct stat sbuf;
+
+ if (pid > 0) {
+ sock_name = Sprintf("w3msock%d", pid);
+ } else {
+ sock_name = Strnew_charp("w3msock");
+ }
+
+ dot_w3m = opendir(rc_dir);
+ if (! dot_w3m)
+ return NULL;
+
+ while ((file = readdir(dot_w3m))) {
+ if ((pid > 0 && (Strcmp_charp(sock_name, file->d_name) == 0)) ||
+ (pid <= 0 && Strncmp_charp(sock_name, file->d_name, sock_name->length) == 0)) {
+ sock_name = Sprintf("%s/%s", rc_dir, file->d_name);
+ if ((stat(sock_name->ptr, &sbuf) == 0) &&
+ (sbuf.st_mode & S_IFSOCK) &&
+ !(sbuf.st_mode & (S_IRWXO | S_IRWXG)) &&
+ (sbuf.st_uid == getuid()))
+ goto SockFound;
+ }
+ }
+ closedir(dot_w3m);
+ return NULL;
+
+ SockFound:
+ closedir(dot_w3m);
+ return sock_name;
+}
+
+static int
+init_serv(void)
+{
+ if (init_remote("w3msock")) {
+ return 1;
+ }
+
+ if (listen(SockFd, 5)) {
+ unlink(SockName->ptr);
+ close(SockFd);
+ SockFd = -1;
+ UseRemote = FALSE;
+ return 1;
+ }
+
+ fcntl(SockFd, F_SETFL, O_NONBLOCK);
+ return 0;
+}
+
+
+static int
+init_remote(char *prefix)
+{
+ SockName = Sprintf("%s/%s%d", rc_dir, prefix, CurrentPid);
+ if (sizeof(SockAddr.sun_path) <= SockName->length)
+ goto SockErr;
+
+ SockAddr.sun_family = AF_UNIX;
+ strcpy(SockAddr.sun_path, SockName->ptr);
+ SockLength = sizeof(SockAddr.sun_family) + strlen(SockAddr.sun_path);
+
+ if ((SockFd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
+ goto SockErr;
+
+ unlink(SockName->ptr);
+ if (bind(SockFd, (struct sockaddr *) &SockAddr, SockLength))
+ goto SockErr;
+
+ chmod(SockName->ptr, S_IRUSR | S_IWUSR);
+ return 0;
+
+ SockErr:
+ unlink(SockName->ptr);
+ if (SockFd >= 0) {
+ close(SockFd);
+ }
+ SockFd = -1;
+ UseRemote = FALSE;
+ return 1;
+}
+
+static void
+parse_sock_data(void)
+{
+ Str data = NULL;
+ char buf[64];
+ char *p, *q, *s;
+ int l, f, conn;
+ struct sockaddr_un sock_addr = SockAddr;
+ socklen_t sock_length = SockLength;
+#if defined(HAVE_SO_PEERCRED) || defined(HAVE_GETPEEREID)
+ uid_t euid;
+ gid_t egid;
+#else
+ struct stat sbuf;
+ time_t staletime;
+#endif
+
+ if (!UseRemote || SockFd < 0) {
+ return;
+ }
+
+ if (!data)
+ data = Strnew();
+
+ conn = accept(SockFd, (struct sockaddr *) &sock_addr, &sock_length);
+
+ if (conn < 0)
+ return;
+
+
+ sock_length -= sizeof(sock_addr.sun_family);
+ sock_addr.sun_path[sock_length] = '\0';
+#if defined(HAVE_SO_PEERCRED) || defined(HAVE_GETPEEREID)
+ if (getpeereid(conn, &euid, &egid) != 0 || euid != getuid()) {
+#else
+#define STALE_LIMIT 60
+ staletime = time(NULL) - STALE_LIMIT;
+ if ((stat(sock_addr.sun_path, &sbuf) < 0) ||
+ !(sbuf.st_mode & S_IFSOCK) ||
+ (sbuf.st_mode & (S_IRWXO | S_IRWXG)) ||
+ (sbuf.st_uid != getuid()) ||
+ (sbuf.st_atime < staletime) ||
+ (sbuf.st_ctime < staletime) ||
+ (sbuf.st_mtime < staletime)) {
+#endif
+ close(conn);
+ return;
+ }
+ unlink(sock_addr.sun_path);
+ while ((l = read(conn, buf, sizeof(buf))) > 0) {
+ Strcat_charp_n(data, buf, l);
+ }
+ close(conn);
+
+ p = data->ptr;
+
+ while ((q = strchr(p, '\n'))) {
+ Str funcname = Strnew();
+ Str cmd = Strnew_charp_n(p, q - p);
+
+ s = cmd->ptr;
+ SKIP_BLANKS(s);
+ while (*s && !IS_SPACE(*s))
+ Strcat_char(funcname, *(s++));
+
+ SKIP_BLANKS(s);
+ f = getFuncList(funcname->ptr);
+ if (f >= 0) {
+ Str tmp = Strnew_charp(s);
+ Strchop(tmp);
+ pushEvent(f, tmp->ptr);
+ }
+ p = q + 1;
+ }
+}
+#endif /* USE_REMOTE */
+
static void
keyPressEventProc(int c)
{
@@ -5714,6 +6024,11 @@
#ifdef USE_NNTP
disconnectNews();
#endif
+#ifdef USE_REMOTE
+ if (UseRemote) {
+ unlink(SockName->ptr);
+ }
+#endif
exit(i);
}
Index: proto.h
===================================================================
RCS file: /cvsroot/w3m/w3m/proto.h,v
retrieving revision 1.99
diff -u -r1.99 proto.h
--- proto.h 16 Apr 2004 18:47:19 -0000 1.99
+++ proto.h 28 Jun 2005 13:28:01 -0000
@@ -492,6 +492,9 @@
extern void flush_tty(void);
extern void toggle_stand(void);
extern char getch(void);
+#ifdef USE_REMOTE
+char getch_select(int fd, int *num);
+#endif
extern void bell(void);
extern int sleep_till_anykey(int sec, int purge);
#ifdef USE_IMAGE
Index: terms.c
===================================================================
RCS file: /cvsroot/w3m/w3m/terms.c,v
retrieving revision 1.53
diff -u -r1.53 terms.c
--- terms.c 18 Jan 2005 16:38:01 -0000 1.53
+++ terms.c 28 Jun 2005 13:28:02 -0000
@@ -1830,6 +1830,44 @@
return c;
}
+#ifdef USE_REMOTE
+char
+getch_select(int fd, int *fdn)
+{
+ int maxfd = tty;
+ fd_set rset;
+
+ if (fd < 0 || fd == tty) {
+ *fdn = 0;
+ return getch();
+ }
+
+ if (maxfd < fd)
+ maxfd = fd;
+
+ maxfd++;
+
+ FD_ZERO(&rset);
+ FD_SET(tty, &rset);
+ FD_SET(fd, &rset);
+
+ while (select(maxfd, &rset, NULL, NULL, NULL) < 1) {
+ FD_ZERO(&rset);
+ FD_SET(tty, &rset);
+ FD_SET(fd, &rset);
+ }
+
+ if (FD_ISSET(tty, &rset)) {
+ *fdn = 0;
+ return getch();
+ } else if (FD_ISSET(fd, &rset)) {
+ *fdn = 1;
+ }
+ return 0;
+}
+#endif
+
+
#ifdef USE_MOUSE
#ifdef USE_GPM
char