Introduction
Introduction Statistics Contact Development Disclaimer Help
Rework how sam handles remote control sockets. - sam - An updated version of th…
git clone git://vernunftzentrum.de/sam.git
Log
Files
Refs
LICENSE
---
commit 8af7e5c04a842c0109e309b2a04c9140b7e3e9ac
parent 352fe7ddbeafce2db71b014625565a59b15c53c0
Author: Rob King <[email protected]>
Date: Wed, 4 Jan 2017 17:32:49 -0600
Rework how sam handles remote control sockets.
Originally, sam used a complex and buggy method for remote control,
requiring in-band messages and round-trips between the remote machine
and the terminal to accomplish anything.
Now, we take advantage of ssh(1)'s ability (present since 2014) to
forward UNIX domain sockets. The remote control mechanism has replaced
a FIFO with a UNIX domain socket. This simplifies the code in various places.
Diffstat:
Makefile | 7 +------
README.rst | 4 ++--
doc/B | 43 ------------------------------
doc/Makefile | 4 +---
doc/sam.1 | 103 +++++++++++++------------------
include/libg.h | 2 +-
libXg/xtbinit.c | 15 +++++++++++++--
rsam/Makefile | 16 ----------------
rsam/rsam.c | 122 -------------------------------
sam/Makefile | 9 +--------
sam/io.c | 131 ++++++++++++++++++++++++-------
sam/mesg.c | 1 -
sam/mesg.h | 1 -
sam/sam.c | 122 ++++++++++++++++++++++++++-----
sam/sam.h | 4 ++--
samterm/io.c | 7 +++++--
samterm/main.c | 21 +++++++++++++++------
samterm/mesg.c | 10 ----------
samterm/samterm.h | 1 -
samterm/unix.c | 62 ++-----------------------------
20 files changed, 291 insertions(+), 394 deletions(-)
---
diff --git a/Makefile b/Makefile
@@ -6,7 +6,7 @@
MODE?=user
-all: config.mk lXg lframe rsamdir samdir samtermdir docdir
+all: config.mk lXg lframe samdir samtermdir docdir
config.mk:
cp config.mk.def config.mk
@@ -20,9 +20,6 @@ lframe:
docdir:
cd doc; $(MAKE)
-rsamdir:
- cd rsam; $(MAKE)
-
samdir:
cd sam; $(MAKE)
@@ -36,14 +33,12 @@ install:
cd sam; $(MAKE) install
cd samterm; $(MAKE) install
cd doc; $(MAKE) install
- cd rsam; $(MAKE) install
clean:
cd libXg; $(MAKE) clean
cd libframe; $(MAKE) clean
cd sam; $(MAKE) clean
cd samterm; $(MAKE) clean
- cd rsam; $(MAKE) clean
nuke: clean
rm -f config.mk
diff --git a/README.rst b/README.rst
@@ -75,7 +75,7 @@ Both the `sam` and `B` commands accept an '-r' argument,
naming a remote machine or
(assuming you're using `ssh(1)`,
an SSH host entry).
-The remote machine needs to have both `sam` and `rsam` installed.
+The remote machine only needs to have the `sam` binary.
The remote machine may also have the `B` command installed.
If it is installed,
@@ -88,7 +88,7 @@ If you're using `ssh(1)` to run sam remotely, be sure to pass…
Installation Paths
-------------------
-By default, `sam`, `rsam`, `samterm`, and `B` all end up in '$(BINDIR)' as def…
+By default, `sam`, `samterm`, and `B` all end up in '$(BINDIR)' as defined in …
Compatibility
-------------
diff --git a/doc/B b/doc/B
@@ -1,43 +0,0 @@
-#!/bin/sh
-
-if [ $# = 0 ] ; then
- echo "usage: B [-r machine] files..." 1>&2
- exit 1
-fi
-
-machine=localhost
-if [ $1 = "-r" ] ; then
- shift
- machine=$1
- shift
-
- if [ "$machine" = "" ] ; then
- echo "usage: B [-r machine] files..." 1>&2
- exit 1
- fi
- echo "machine = $machine"
-fi
-
-pipe="${HOME}/.sam.${machine}"
-dir=`pwd`
-files=
-for i in $*
-do
- case "$i" in
- /*) files="$files $i"
- ;;
- *) files="$files $dir/$i"
- ;;
- esac
-done
-
-if [ ! -w "$pipe" ] ; then
- pipe="${HOME}/.sam.fifo" # created by rsam
-fi
-
-if [ ! -w "$pipe" ]; then
- sam $files & # start sam if it's not already running
-else
- echo "B $files" >> $pipe
-fi
-
diff --git a/doc/Makefile b/doc/Makefile
@@ -4,7 +4,7 @@ include ../config.mk
all:
-install: sam.1 B
+install: sam.1
mkdir -p "$(MANDIR)/man1"
cp sam.1 "$(MANDIR)/man1"
ln -sf "$(MANDIR)/man1/sam.1" "$(MANDIR)/man1/B.1"
@@ -14,5 +14,3 @@ install: sam.1 B
mkdir -p "$(MANDIR)/man5"
cp keyboard.5 "$(MANDIR)/man5"
cp samrc.5 "$(MANDIR)/man5"
- mkdir -p "$(BINDIR)"
- cp B "$(BINDIR)"
diff --git a/doc/sam.1 b/doc/sam.1
@@ -7,8 +7,6 @@
.Sh SYNOPSIS
.Nm
.Op Fl d
-.Op Fl e
-.Op Fl f
.Op Fl t Ar terminal
.Ar
.Nm
@@ -40,24 +38,6 @@ Do not download the terminal part of
.Nm "."
Editing will be done with the command language only, as in
.Xr ed 1 "."
-.It Fl e
-Expand tabs to spaces during editing.
-Literal tabs may still be inserted using the character composition functionali…
-.Sx "Composed Text Input" ","
-or by holding Control while pressing the Tab key.
-.It Fl f
-Do not create or take ownership of the external command FIFO
-.Po
-see
-.Sx "Controlling running instances of sam"
-.Pc "."
-The
-.Nm B
-command will not communicate with this instance of
-.Nm sam "."
-This flag is useful for running
-.Dq "one-off"
-instances of sam.
.It Fl r Ar machine
Run the host part remotely on the specified machine, the terminal part locally…
commands to be sent to an instance of
@@ -66,13 +46,6 @@ associated with
.Ar machine "."
.It Fl s Ar file
Start the host part from the indicated file on the remote host.
-By default, this is
-.Pa rsam ","
-which is a program that interposes itself between the host and terminal parts …
-.Nm
-and allows
-.Nm
-to be controlled via commands on the remote system.
.It Fl t Ar file
Start the terminal part from the indicated file.
Useful for debugging.
@@ -918,25 +891,11 @@ option, which is used to specify a remote machine name su…
.Ev RSH
environment variable.
.Pp
-By default,
+The only component of
.Nm sam
-will run a command called
-.Nm rsam
-as the host-part on the remote machine.
-.Nm rsam
-opens up an additional control channel on the remote machine, allowing
-.Nm sam
-to be controlled via the
-.Nm B
-command on the remote machine as well.
-.Pp
-The only components of
-.Nm sam
-that need to be on the remote machine are
-.Nm rsam
-and
+that needs to be on the remote machine is
.Nm sam ","
-and any command specified as the argument to the
+or whatever command specified as the argument to the
.Fl s
option.
Users may also like to have the
@@ -946,7 +905,7 @@ command present on the remote system; invoking this command…
if
.Nm sam
was invoked with its default remote host command, i.e.
-.Nm rsam
+.Nm sam
.Pc
open files in the local terminal.
This allows users to run the terminal part of
@@ -967,14 +926,6 @@ to load the named files; the default is the most-recently …
.Pp
.Nm B
may also be called on a remote machine, causing the downloaded instance of sam…
-.Pp
-Note that
-.Nm B
-will only communicate with the most-recently-run instance of
-.Nm sam ","
-but see the
-.Fl f
-option above.
.Ss Composed Text Input
.Nm sam
allows the input of arbitrary Unicode characters from the Basic Multilingual P…
@@ -1071,11 +1022,29 @@ The name of a command to be used to connect to a remote…
is invoked with the
.Fl r
option.
-It will be passed at least two arguments: the name of the machine to connect t…
+It will be passed arguments of the form:
+.Bd -literal
+
+ -R REMOTE:LOCAL MACHINE COMMAND
+
+.Ed
+where
+.Em REMOTE
+is the name of the remote UNIX domain socket for remote control,
+.Em LOCAL
+is the name of the local UNIX domain socket for remote control,
+.Em MACHINE
+is the hostname to connect to, and
+.Em COMMAND
+is the command
.Po
e.g.
-.Nm rsam
-.Pc "."
+.Nm sam
+.Pc
+to execute on that machine.
+.Pp
+Note that this works out-of-the-box with recent versions of
+.Xr ssh 1 "."
Any additional arguments should be passed to the command on the remote machine.
By default, this is the string
.Dq "ssh" "."
@@ -1087,6 +1056,23 @@ file to read at startup.
By default,
this is
.Pa ${HOME}/.samrc "."
+.It Ev SAMSOCKETPATH
+Names a directory in which
+.Nm
+remote control sockets should be placed.
+By default, the contents of
+.Ev HOME
+are used.
+.It Ev SAMSOCKETNAME
+Gives a full path name for a
+.Nm
+remote control socket; this will be used in preference to any file in the
+.Ev SAMSOCKETPATH
+directory.
+.It Ev RSAMSOCKETPATH
+Names a directory in which
+.Nm
+remote control sockets should be placed on remote systems.
.It Ev TABS
A number between 1 and 12, indicating the width of a tab character.
This number is treated as a multiplier of the width of the '0' character.
@@ -1095,11 +1081,6 @@ The default is 8.
If the number specified for
.Ev TABS
is negative, the absolute value of that number is used and automatic tab expan…
-.Po
-as for the
-.Fl e
-flag
-.Pc
is enabled.
Tab behavior can also be controlled using the
.Em tabs
diff --git a/include/libg.h b/include/libg.h
@@ -197,7 +197,7 @@ extern int scrpix(int*,int*);
extern uint64_t getbg(void);
extern void einit(uint64_t);
-extern uint64_t estart(uint64_t, int, int);
+extern uint64_t estart(uint64_t, int, size_t, bool);
extern uint64_t event(Event*);
extern uint64_t eread(uint64_t, Event*);
diff --git a/libXg/xtbinit.c b/libXg/xtbinit.c
@@ -4,6 +4,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include "libgint.h"
#define Font xFont
@@ -74,6 +76,7 @@ typedef struct Ebuf {
} Ebuf;
typedef struct Esrc {
+ bool issocket;
bool inuse;
int size;
int count;
@@ -387,7 +390,14 @@ gotinput(XtPointer cldata, int *pfd, XtInputId *id)
if (eb == 0)
return;
if(es->size){
- n = read(*pfd, (char *)eb->buf, es->size);
+ if (es->issocket){
+ struct sockaddr addr;
+ socklen_t len;
+ int fd = accept(*pfd, &addr, &len);
+ n = read(fd, (char *)eb->buf, es->size);
+ close(fd);
+ } else
+ n = read(*pfd, (char *)eb->buf, es->size);
if (n < 0)
n = 0;
if(n < es->size) {
@@ -519,7 +529,7 @@ einit(uint64_t keys)
}
uint64_t
-estart(uint64_t key, int fd, int n)
+estart(uint64_t key, int fd, size_t n, bool issocket)
{
int i;
@@ -532,6 +542,7 @@ estart(uint64_t key, int fd, int n)
if(nsrc <= i)
nsrc = i+1;
esrc[i].inuse = true;
+ esrc[i].issocket = issocket;
esrc[i].size = n;
esrc[i].count = 0;
XtAppAddInput(app, fd, (XtPointer)XtInputReadMask,
diff --git a/rsam/Makefile b/rsam/Makefile
@@ -1,16 +0,0 @@
-# Copyright (C) 2013-2015 Rob King <[email protected]>
-# This file may be redistributed and modified for any purpose.
-# No warranty is expressed or implied; use at your own risk.
-
-include ../config.mk
-
-all: rsam
-
-rsam: rsam.o
- $(CC) -o rsam rsam.o $(LDFLAGS)
-
-clean:
- rm -f *.o rsam
-
-install: rsam
- cp rsam $(BINDIR)
diff --git a/rsam/rsam.c b/rsam/rsam.c
@@ -1,122 +0,0 @@
-/* Copyright 2013-2015 Rob King <[email protected]>
- * This file may be freely redistributed in source or binary form with or with…
- * No warranty is expressed or implied; use at your own risk.
- */
-
-#define _POSIX_C_SOURCE 200809L
-#include <fcntl.h>
-#include <limits.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/select.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#define PARENT_READ readpipe[0]
-#define CHILD_WRITE readpipe[1]
-#define CHILD_READ writepipe[0]
-#define PARENT_WRITE writepipe[1]
-#define MAX(x, y) ((x) > (y) ? (x) : (y))
-#define CHECKEDWRITE(f, b, c) if (write(f, b, c) != c) exit(EXIT_FAILURE)
-
-char path[PATH_MAX + 1];
-
-void
-cleanup(void)
-{
- unlink(path);
-}
-
-int
-main(int argc, char **argv)
-{
- int fifo = -1;
- int nfd = 0;
- int writepipe[2] = {-1};
- int readpipe[2] = {-1};
- struct passwd *pwent = NULL;
- pid_t child = -1;
- fd_set rfds;
-
- pwent = getpwuid(getuid());
- if (!pwent || !pwent->pw_dir || !pwent->pw_dir[0])
- return perror("pwent"), EXIT_FAILURE;
-
- strncpy(path, pwent->pw_dir, PATH_MAX);
- strncat(path, "/.sam.fifo", PATH_MAX);
-
- if (pipe(writepipe) != 0 || pipe(readpipe) != 0)
- return perror("pipe"), EXIT_FAILURE;
-
- unlink(path);
- if (mkfifo(path, 0600) != 0)
- return perror("mkfifo"), EXIT_FAILURE;
-
- atexit(cleanup);
-
- fifo = open(path, O_RDWR);
- if (fifo < 0)
- return perror("open"), EXIT_FAILURE;
-
- child = fork();
- if (child == 0){
- close(PARENT_WRITE);
- close(PARENT_READ);
-
- dup2(CHILD_READ, STDIN_FILENO); close(CHILD_READ);
- dup2(CHILD_WRITE, STDOUT_FILENO); close(CHILD_WRITE);
-
- execlp("sam", "sam", "-R", NULL);
- return EXIT_FAILURE;
- } else if (child < 0){
- perror("fork");
- return EXIT_FAILURE;
- }
-
- close(CHILD_READ);
- close(CHILD_WRITE);
-
- FD_ZERO(&rfds);
- FD_SET(STDIN_FILENO, &rfds);
- FD_SET(fifo, &rfds);
- FD_SET(PARENT_READ, &rfds);
-
- nfd = MAX(STDIN_FILENO, MAX(PARENT_READ, fifo)) + 1;
- while (select(nfd, &rfds, NULL, NULL, NULL) >= 0){
- ssize_t count = 0;
- char buf[8192];
-
- if (FD_ISSET(STDIN_FILENO, &rfds)){
- count = read(STDIN_FILENO, buf, 8192);
- if (count <= 0)
- exit(EXIT_SUCCESS);
- CHECKEDWRITE(PARENT_WRITE, buf, count);
- }
-
- if (FD_ISSET(fifo, &rfds)){
- memset(buf, 0, 256);
- count = read(fifo, buf, 253);
- if (count <= 0)
- exit(EXIT_SUCCESS);
- CHECKEDWRITE(STDOUT_FILENO, "\x19\xff\x00", 3);
- CHECKEDWRITE(STDOUT_FILENO, buf, 255);
- }
-
- if (FD_ISSET(PARENT_READ, &rfds)){
- count = read(PARENT_READ, buf, 8192);
- if (count <= 0)
- exit(EXIT_SUCCESS);
- CHECKEDWRITE(STDOUT_FILENO, buf, count);
- }
-
- FD_ZERO(&rfds);
- FD_SET(STDIN_FILENO, &rfds);
- FD_SET(fifo, &rfds);
- FD_SET(PARENT_READ, &rfds);
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/sam/Makefile b/sam/Makefile
@@ -20,14 +20,6 @@ SAMDIR=$(BINDIR)
SHELLNAME=sh
SHELLPATH=/bin/sh
-# Set RXNAME and RXPATHNAME to the name of the remote execution command
-# and the pathname of its executable
-RXNAME=ssh
-RXPATHNAME=/usr/bin/ssh
-
-# Set RXSAMNAME to the name of the command to run on the remote host.
-RXSAMNAME=rsam
-
CFLAGS=$(STANDARDS) $(INCS) $(INCLUDES) -DRXPATH='"$(RXPATH)"'
CC?=c99
@@ -50,6 +42,7 @@ nuke: clean
install: sam
mkdir -p $(SAMDIR)
cp sam $(SAMDIR)/$(RSAMNAME)
+ ln -f $(SAMDIR)/$(RSAMNAME) $(SAMDIR)/B
$(OBJ): sam.h ../include/u.h errors.h mesg.h
diff --git a/sam/io.c b/sam/io.c
@@ -1,4 +1,10 @@
/* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <fcntl.h>
+
#include "sam.h"
#define NSYSFILE 3
@@ -151,45 +157,57 @@ closeio(Posn p)
dprint(L"#%lu\n", p);
}
+char exname[PATH_MAX + 1];
int remotefd0 = 0;
int remotefd1 = 1;
+int exfd = -1;
void
-bootterm(char *machine, char **argv, char **end)
+bootterm(char *machine)
{
+ char fd[100];
int ph2t[2], pt2h[2];
- if(machine){
+ snprintf(fd, sizeof(fd) - 1, "%d", exfd);
+
+ if (machine){
dup2(remotefd0, 0);
dup2(remotefd1, 1);
close(remotefd0);
close(remotefd1);
- argv[0] = "samterm";
- *end = 0;
- execvp(samterm, argv);
- fprintf(stderr, "can't exec: ");
- perror(samterm);
+ if (exfd >= 0)
+ execlp(samterm, samterm, "-r", machine, "-f", fd, "-n", exname, NU…
+ else
+ execlp(samterm, samterm, "-r", machine, NULL);
+ perror("couldn't exec samterm");
exit(EXIT_FAILURE);
}
- if(pipe(ph2t)==-1 || pipe(pt2h)==-1)
+
+ if (pipe(ph2t)==-1 || pipe(pt2h)==-1)
panic("pipe");
- switch(fork()){
- case 0:
- dup2(ph2t[0], 0);
- dup2(pt2h[1], 1);
- close(ph2t[0]);
- close(ph2t[1]);
- close(pt2h[0]);
- close(pt2h[1]);
- argv[0] = "samterm";
- *end = 0;
- execvp(samterm, argv);
- fprintf(stderr, "can't exec: ");
- perror(samterm);
- exit(EXIT_FAILURE);
- case -1:
- panic("can't fork samterm");
+
+ machine = machine? machine : "localhost";
+ switch (fork()){
+ case 0:
+ dup2(ph2t[0], 0);
+ dup2(pt2h[1], 1);
+ close(ph2t[0]);
+ close(ph2t[1]);
+ close(pt2h[0]);
+ close(pt2h[1]);
+ if (exfd >= 0)
+ execlp(samterm, samterm, "-r", machine, "-f", fd, "-n", exname…
+ else
+ execlp(samterm, samterm, "-r", machine, NULL);
+ perror("couldn't exec samterm");
+ exit(EXIT_FAILURE);
+ break;
+
+ case -1:
+ panic("can't fork samterm");
+ break;
}
+
dup2(pt2h[0], 0);
dup2(ph2t[1], 1);
close(ph2t[0]);
@@ -202,6 +220,14 @@ void
connectto(char *machine)
{
int p1[2], p2[2];
+ char sockname[FILENAME_MAX + 1] = {0};
+ char rarg[FILENAME_MAX + 1] = {0};
+
+ snprintf(sockname, FILENAME_MAX, "%s/sam.remote.%s",
+ getenv("RSAMSOCKETPATH")? getenv("RSAMSOCKETPATH") : "/tmp",
+ getenv("USER")? getenv("USER") : getenv("LOGNAME")? getenv("LOGNA…
+
+ snprintf(rarg, FILENAME_MAX, "%s:%s", sockname, exname);
if(pipe(p1)<0 || pipe(p2)<0){
dprint(L"can't pipe\n");
@@ -217,7 +243,11 @@ connectto(char *machine)
close(p1[1]);
close(p2[0]);
close(p2[1]);
- execlp(getenv("RSH") ? getenv("RSH") : RXPATH, getenv("RSH") ? getenv(…
+ execlp(getenv("RSH") ? getenv("RSH") : RXPATH,
+ getenv("RSH") ? getenv("RSH") : RXPATH,
+ "-R", rarg,
+ machine, rsamname, "-R", sockname,
+ NULL);
dprint(L"can't exec %s\n", RXPATH);
exit(EXIT_FAILURE);
@@ -230,12 +260,55 @@ connectto(char *machine)
}
void
-startup(char *machine, int Rflag, char **arg, char **end)
+removesocket(void)
+{
+ close(exfd);
+ unlink(exname);
+ exname[0] = 0;
+}
+
+void
+opensocket(const char *machine)
+{
+ struct sockaddr_un un = {0};
+ const char *path = getenv("SAMSOCKPATH")? getenv("SAMSOCKPATH") : getenv("…
+
+ if (!path){
+ fputs("could not determine command socket path\n", stderr);
+ return;
+ }
+
+ snprintf(exname, PATH_MAX, "%s/.sam.%s", path, machine? machine : "localho…
+ if (strlen(exname) >= sizeof(un.sun_path) - 1){
+ fputs("command socket path too long\n", stderr);
+ return;
+ }
+
+ un.sun_family = AF_UNIX;
+ strncpy(un.sun_path, exname, sizeof(un.sun_path) - 1);
+ if ((exfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0
+ || bind(exfd, (struct sockaddr *)&un, sizeof(un)) < 0
+ || listen(exfd, 10) < 0){
+ perror("could not open command socket");
+ exfd = -1;
+ return;
+ }
+
+ atexit(removesocket);
+}
+
+void
+startup(char *machine, bool rflag)
{
- if(machine)
+ if (!rflag)
+ opensocket(machine);
+
+ if (machine)
connectto(machine);
- if(!Rflag)
- bootterm(machine, arg, end);
+
+ if (!rflag)
+ bootterm(machine);
+
downloaded = true;
outTs(Hversion, VERSION);
}
diff --git a/sam/mesg.c b/sam/mesg.c
@@ -45,7 +45,6 @@ char *hname[] = {
[Hsetsnarf] = "Hsetsnarf",
[Hsnarflen] = "Hsnarflen",
[Hack] = "Hack",
- [Hextcmd] = "Hextcmd",
[Hexit] = "Hexit",
};
diff --git a/sam/mesg.h b/sam/mesg.h
@@ -65,7 +65,6 @@ typedef enum Hmesg
Hsnarflen, /* report length of implicit snarf */
Hack, /* request acknowledgement */
Hexit,
- Hextcmd, /* execute a external command */
HMAX
}Hmesg;
typedef struct Header{
diff --git a/sam/sam.c b/sam/sam.c
@@ -4,6 +4,9 @@
#include <libgen.h>
#include <signal.h>
#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#include <unistd.h>
wchar_t genbuf[BLOCKSIZE];
@@ -26,15 +29,15 @@ bool quitok = true;
bool downloaded;
bool expandtabs;
bool dflag;
-bool Rflag;
char *machine;
char *home;
bool bpipeok;
int termlocked;
char *samterm = "samterm";
-char *rsamname = "rsam";
+char *rsamname = "sam";
char *sh = "sh";
char *shpath = "/bin/sh";
+char *rmsocketname = NULL;
wchar_t baddir[] = { '<', 'b', 'a', 'd', 'd', 'i', 'r', '>', '\n'};
@@ -47,41 +50,121 @@ hup(int sig)
exit(EXIT_FAILURE);
}
+int sammain(int argc, char *argv[]);
+int bmain(int argc, char *argv[]);
+
int
main(int argc, char *argv[])
{
+ if (strcmp(basename(argv[0]), "B") == 0)
+ return bmain(argc, argv);
+ return sammain(argc, argv);
+}
+
+#define B_CMD_MAX 4095
+const char *
+getbsocketname(const char *machine)
+{
+ const char *user = getenv("USER")? getenv("USER") : getenv("LOGNAME")? get…
+ const char *path = getenv("SAMSOCKETPATH")? getenv("SAMSOCKETPATH") : gete…
+ static char name[FILENAME_MAX + 1] = {0};
+
+ if (getenv("SAMSOCKETNAME"))
+ return getenv("SAMSOCKETNAME");
+
+ if (name[0])
+ return name;
+
+ snprintf(name, FILENAME_MAX, "%s/.sam.%s", path, machine);
+ if (access(name, R_OK) == 0)
+ return name;
+
+ snprintf(name, FILENAME_MAX, "%s/.sam.remote.%s", path, user);
+ if (access(name, R_OK) == 0)
+ return name;
+
+ snprintf(name, FILENAME_MAX, "/tmp/sam.remote.%s", user);
+ if (access(name, R_OK) == 0)
+ return name;
+
+ return NULL;
+}
+
+int
+bmain(int argc, char *argv[])
+{
+ int fd, o;
+ struct sockaddr_un un = {0};
+ char cmd[B_CMD_MAX] = {0};
+
+ machine = "localhost";
+ while ((o = getopt(argc, argv, "r:")) != -1){
+ switch (o){
+ case 'r':
+ machine = optarg;
+ break;
+
+ default:
+ return fputs("usage: B [-r MACHINE] FILE...\n", stderr), EXIT_…
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (getbsocketname(machine) == NULL)
+ return fputs("could not determine controlling socket name\n", stderr),…
+
+ memset(&un, 0, sizeof(un));
+ un.sun_family = AF_UNIX;
+ strncpy(un.sun_path, getbsocketname(machine), sizeof(un.sun_path) - 1);
+ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 || connect(fd, (struct sock…
+ return perror("could not open socket"), EXIT_FAILURE;
+
+ strncat(cmd, "B ", B_CMD_MAX);
+ for (int i = 0; i < argc; i++){
+ strncat(cmd, " ", B_CMD_MAX);
+ strncat(cmd, argv[i], B_CMD_MAX);
+ }
+ strncat(cmd, "\n", B_CMD_MAX);
+
+ if (write(fd, cmd, strlen(cmd)) <= 0)
+ return perror("could not send command"), EXIT_FAILURE;
+
+ close(fd);
+ return EXIT_SUCCESS;
+}
+
+void
+rmsocket(void)
+{
+ if (rmsocketname)
+ unlink(rmsocketname);
+}
+
+int
+sammain(int argc, char *argv[])
+{
int i, o;
String *t;
char *arg[argc + 1], **ap;
- int targc = 1;
ap = &arg[argc];
arg[0] = "samterm";
setlocale(LC_ALL, "");
- while ((o = getopt(argc, argv, "efdRr:t:s:")) != -1){
+ while ((o = getopt(argc, argv, "edR:r:t:s:")) != -1){
switch (o){
- case 'e':
- arg[targc++] = "-e";
- break;
-
- case 'f':
- arg[targc++] = "-f";
- break;
-
case 'd':
dflag = true;
break;
case 'r':
machine = optarg;
- rsamname = "rsam";
- arg[targc++] = "-r";
- arg[targc++] = optarg;
break;
case 'R':
- Rflag = true;
+ rmsocketname = optarg;
+ atexit(rmsocket);
break;
case 't':
@@ -98,7 +181,6 @@ main(int argc, char *argv[])
}
argv += optind;
argc -= optind;
- arg[targc] = NULL;
Strinit(&cmdstr);
Strinit0(&lastpat);
@@ -113,7 +195,7 @@ main(int argc, char *argv[])
shpath = getenv("SHELL") ? getenv("SHELL") : shpath;
sh = basename(shpath);
if(!dflag)
- startup(machine, Rflag, arg, ap);
+ startup(machine, rmsocketname != NULL);
Fstart();
signal(SIGINT, SIG_IGN);
@@ -135,7 +217,7 @@ main(int argc, char *argv[])
if(file.nused)
current(file.filepptr[0]);
- atexit(shutdown);
+ atexit(scram);
setjmp(mainloop);
cmdloop();
@@ -145,7 +227,7 @@ main(int argc, char *argv[])
}
void
-shutdown(void)
+scram(void)
{
freecmd();
for (int i = 0; i < file.nused; i++)
diff --git a/sam/sam.h b/sam/sam.h
@@ -240,11 +240,11 @@ void resetxec(void);
void rgrow(List*, Posn, Posn);
void samerr(char*);
void settempfile(void);
-void shutdown(void);
+void scram(void);
int skipbl(void);
void snarf(File*, Posn, Posn, Buffer*, bool);
void sortname(File*);
-void startup(char*, int, char**, char**);
+void startup(char*, bool);
void state(File*, state_t);
int statfd(int, uint64_t*, uint64_t*, int64_t*, int64_t*, int64_t*);
int statfile(char*, uint64_t*, uint64_t*, int64_t*, int64_t*, int64_t*);
diff --git a/samterm/io.c b/samterm/io.c
@@ -20,9 +20,12 @@ void panic(char*);
void
initio(void){
+ extern int exfd;
+
einit(Emouse|Ekeyboard);
- estart(Ehost, 0, 0);
- extstart();
+ estart(Ehost, 0, 0, false);
+ if (exfd >= 0)
+ estart(Eextern, exfd, 8192, true);
}
void
diff --git a/samterm/main.c b/samterm/main.c
@@ -28,7 +28,15 @@ char lock = 1;
bool hasunlocked = false;
bool expandtabs = false;
char *machine = "localhost";
-int nofifo = 0;
+int exfd = -1;
+const char *exname;
+
+void
+removeext(void)
+{
+ if (exname)
+ unlink(exname);
+}
int
main(int argc, char *argv[])
@@ -49,18 +57,19 @@ main(int argc, char *argv[])
else
snprintf(rcpath, PATH_MAX, "%s/.samrc", getenv("HOME") ? getenv("HOME"…
- while ((opt = getopt(argc, argv, "efr:")) != -1){
+ while ((opt = getopt(argc, argv, "ef:n:r:")) != -1){
switch (opt){
case 'r':
machine = optarg;
break;
- case 'e':
- expandtabs = 1;
+ case 'f':
+ exfd = atoi(optarg);
break;
- case 'f':
- nofifo = 1;
+ case 'n':
+ exname = optarg;
+ atexit(removeext);
break;
}
}
diff --git a/samterm/mesg.c b/samterm/mesg.c
@@ -293,16 +293,6 @@ inmesg(Hmesg type, int count)
outT0(Tack);
break;
- case Hextcmd:
- if (exname[0]){
- int fifofd = open(exname, O_WRONLY);
- if (fifofd >= 0){
- dprintf(fifofd, "%511s", (char *)indata);
- close(fifofd);
- }
- }
- break;
-
case Hexit:
outT0(Texit);
mouseexit();
diff --git a/samterm/samterm.h b/samterm/samterm.h
@@ -108,7 +108,6 @@ void cursorset(Point);
void getmouse(void);
void mouseunblock(void);
void kbdblock(void);
-void extstart(void);
int button(int but);
int waitforio(void);
int rcvchar(void);
diff --git a/samterm/unix.c b/samterm/unix.c
@@ -5,19 +5,20 @@
#include "flayer.h"
#include "samterm.h"
+#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
#include <errno.h>
#include <signal.h>
-char exname[PATH_MAX + 1] = {0};
+char exname[FILENAME_MAX + 1] = {0};
static char *fallbacks[] = {
"*scrollForwardR: true",
"*geometry: 740x780",
NULL
};
-extern int nofifo;
-
void
getscreen(int argc, char **argv)
{
@@ -54,58 +55,3 @@ dumperrmsg(int count, int type, int count0, int c)
cp++;
}
}
-
-void
-removeextern(void)
-{
- unlink(exname);
- exname[0] = 0;
-}
-
-void
-extstart(void)
-{
- extern char *machine;
- int fd;
- int flags;
-
- if (nofifo || !getenv("HOME"))
- return;
-
- snprintf(exname, PATH_MAX, "%s/.sam.%s", getenv("HOME"), machine);
-
- /* Make the named pipe. */
- if (mkfifo(exname, 0600) == -1){
- struct stat statb;
-
- if (errno != EEXIST || stat(exname, &statb) == -1)
- return;
-
- if (!S_ISFIFO(statb.st_mode)){
- removeextern();
- if (mkfifo(exname, 0600) == -1)
- return;
- }
- }
-
- fd = open(exname, O_RDONLY | O_NONBLOCK);
- if (fd == -1) {
- removeextern();
- return;
- }
-
- /*
- * Turn off no-delay and provide ourselves as a lingering
- * writer so as not to get end of file on read.
- */
- flags = fcntl(fd, F_GETFL, 0);
- if (flags == -1 || fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == -1
- || open(exname, O_WRONLY) == -1){
- (void)close(fd);
- removeextern();
- return;
- }
-
- estart(Eextern, fd, 8192);
- atexit(removeextern);
-}
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.