[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[screen-devel] [PATCH 1/1] add compat layer to handle both fifos and soc
From: |
Christian Brauner |
Subject: |
[screen-devel] [PATCH 1/1] add compat layer to handle both fifos and sockets |
Date: |
Mon, 10 Apr 2017 21:33:15 +0200 |
So far screen could only support either sockets or fifos but not both. This
proved to be a blocker for any upgrade. This adds a compatibility layer to
screen v4 to support both sockets and fifos at the same time. The strategy here
is to only support fifos for legacy sessions that already exist. All new
sessions will use sockets by default.
Signed-off-by: Christian Brauner <address@hidden>
---
src/acconfig.h | 5 -
src/attacher.c | 30 +-
src/configure.ac | 26 --
src/extern.h | 9 +-
src/osdef.h.in | 3 -
src/osdef.sh | 2 -
src/screen.c | 34 +-
src/socket.c | 925 ++++++++++++++++++++++++++++---------------------------
8 files changed, 499 insertions(+), 535 deletions(-)
diff --git a/src/acconfig.h b/src/acconfig.h
index 2e46985..4e5cda0 100644
--- a/src/acconfig.h
+++ b/src/acconfig.h
@@ -504,11 +504,6 @@
#undef SELECT_BROKEN
/*
- * Define this if your system supports named pipes.
- */
-#undef NAMEDPIPE
-
-/*
* Define this if your system exits select() immediatly if a pipe is
* opened read-only and no writer has opened it.
*/
diff --git a/src/attacher.c b/src/attacher.c
index ed0d6ea..196993f 100644
--- a/src/attacher.c
+++ b/src/attacher.c
@@ -120,11 +120,11 @@ int s;
struct msg *m;
{
int r, l = sizeof(*m);
+ bool is_socket;
-#ifndef NAMEDPIPE
- if (m->type == MSG_ATTACH)
+ is_socket = IsSocket(SockPath);
+ if (is_socket && m->type == MSG_ATTACH)
return SendAttachMsg(s, m, attach_fd);
-#endif
while(l > 0)
{
@@ -147,6 +147,7 @@ int how;
struct msg m;
struct stat st;
char *s;
+ bool is_socket;
debug2("Attach: how=%d, tty=%s\n", how, attach_tty);
#ifdef MULTIUSER
@@ -234,9 +235,10 @@ int how;
strncpy(m.m_tty, attach_tty_is_in_new_ns ? attach_tty_name_in_ns :
attach_tty, sizeof(m.m_tty) - 1);
m.m_tty[sizeof(m.m_tty) - 1] = 0;
+ is_socket = IsSocket(SockPath);
if (how == MSG_WINCH)
{
- if ((lasts = MakeClientSocket(0)) >= 0)
+ if ((lasts = MakeClientSocket(0, is_socket)) >= 0)
{
WriteMessage(lasts, &m);
close(lasts);
@@ -246,7 +248,7 @@ int how;
if (how == MSG_CONT)
{
- if ((lasts = MakeClientSocket(0)) < 0)
+ if ((lasts = MakeClientSocket(0, is_socket)) < 0)
{
Panic(0, "Sorry, cannot contact session \"%s\" again.\r\n",
SockName);
@@ -254,7 +256,7 @@ int how;
}
else
{
- n = FindSocket(&lasts, (int *)0, (int *)0, SockMatch);
+ n = FindSocket(&lasts, (int *)0, (int *)0, SockMatch, &is_socket);
switch (n)
{
case 0:
@@ -363,7 +365,7 @@ int how;
if (how != MSG_ATTACH)
return 0; /* we detached it. jw. */
sleep(1); /* we dont want to overrun our poor backend. jw. */
- if ((lasts = MakeClientSocket(0)) == -1)
+ if ((lasts = MakeClientSocket(0, is_socket)) == -1)
Panic(0, "Cannot contact screen again. Sigh.");
m.type = how;
}
@@ -479,6 +481,7 @@ AttacherFinit SIGDEFARG
struct stat statb;
struct msg m;
int s;
+ bool is_socket;
debug("AttacherFinit();\n");
signal(SIGHUP, SIG_IGN);
@@ -493,7 +496,8 @@ AttacherFinit SIGDEFARG
m.m.detach.dpid = getpid();
m.type = MSG_HANGUP;
m.protocol_revision = MSG_REVISION;
- if ((s = MakeClientSocket(0)) >= 0)
+ is_socket = IsSocket(SockPath);
+ if ((s = MakeClientSocket(0, is_socket)) >= 0)
{
WriteMessage(s, &m);
close(s);
@@ -1002,10 +1006,11 @@ int query;
struct msg m;
char *p;
int len, n;
+ bool is_socket;
if (sty == 0)
{
- i = FindSocket(&s, (int *)0, (int *)0, match);
+ i = FindSocket(&s, (int *)0, (int *)0, match, &is_socket);
if (i == 0)
Panic(0, "No screen session found.");
if (i != 1)
@@ -1020,7 +1025,8 @@ int query;
if (strlen(sty) > 2 * MAXSTR - 1)
sty[2 * MAXSTR - 1] = 0;
sprintf(SockPath + strlen(SockPath), "/%s", sty);
- if ((s = MakeClientSocket(1)) == -1)
+ is_socket = IsSocket(SockPath);
+ if ((s = MakeClientSocket(1, is_socket)) == -1)
exit(1);
}
bzero((char *)&m, sizeof(m));
@@ -1060,7 +1066,7 @@ int query;
{
query[6] = c;
strcpy(sp, query); /* XXX: strncpy? */
- if ((r = MakeServerSocket()) >= 0)
+ if ((r = MakeServerSocket(is_socket)) >= 0)
break;
}
if (r < 0)
@@ -1069,7 +1075,7 @@ int query;
{
query[6] = c;
strcpy(sp, query);
- if ((r = MakeServerSocket()) >= 0)
+ if ((r = MakeServerSocket(is_socket)) >= 0)
break;
}
}
diff --git a/src/configure.ac b/src/configure.ac
index ffe2e37..28237f5 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -530,31 +530,9 @@ fi
dnl
dnl **** choose sockets or fifos ****
dnl
-if test -n "$fifo"; then
- if test -n "$sock"; then
- if test -n "$nore"; then
- AC_NOTE(- hmmm... better take the fifos)
- AC_DEFINE(NAMEDPIPE)
- elif test -n "$fifobr"; then
- AC_NOTE(- as your fifos are broken lets use the sockets.)
- else
- AC_NOTE(- both sockets and fifos usable. let's take sockets.)
- fi
- else
- AC_NOTE(- using named pipes, of course)
- AC_DEFINE(NAMEDPIPE)
- fi
-elif test -n "$sock"; then
- AC_NOTE(- using unix-domain sockets, of course)
-else
- AC_MSG_ERROR(you have neither usable sockets nor usable pipes -> no screen)
-fi
-
-dnl
dnl **** check the select implementation ****
dnl
-AC_CHECKING(select return value)
AC_TRY_RUN([
/* For select - According to POSIX 1003.1-2001 */
#include <sys/select.h>
@@ -569,14 +547,10 @@ AC_TRY_RUN([
char *nam = "/tmp/conftest$$";
-#ifdef NAMEDPIPE
-
#ifndef O_NONBLOCK
#define O_NONBLOCK O_NDELAY
-#endif
#ifndef S_IFIFO
#define S_IFIFO 0010000
-#endif
main()
diff --git a/src/extern.h b/src/extern.h
index bd22ebb..55e007d 100644
--- a/src/extern.h
+++ b/src/extern.h
@@ -32,6 +32,8 @@
#define __attribute__(x)
#endif
+#include <stdbool.h>
+
/* screen.c */
extern int main __P((int, char **));
extern sigret_t SigHup __P(SIGPROTOARG);
@@ -336,9 +338,9 @@ extern void SetTimeout __P((struct event *, int));
extern void sched __P((void));
/* socket.c */
-extern int FindSocket __P((int *, int *, int *, char *));
-extern int MakeClientSocket __P((int));
-extern int MakeServerSocket __P((void));
+extern int FindSocket __P((int *, int *, int *, char *, bool *));
+extern int MakeClientSocket __P((int, bool));
+extern int MakeServerSocket __P((bool));
extern int RecoverSocket __P((void));
extern int chsock __P((void));
extern void ReceiveMsg __P((void));
@@ -346,6 +348,7 @@ extern void SendCreateMsg __P((char *, struct NewWindow
*));
extern int SendErrorMsg __P((char *, char *));
extern int SendAttachMsg __P((int, struct msg *, int));
extern void ReceiveRaw __P((int));
+extern bool IsSocket __P((const char *));
/* misc.c */
extern char *SaveStr __P((const char *));
diff --git a/src/osdef.h.in b/src/osdef.h.in
index 3627154..0dd821e 100644
--- a/src/osdef.h.in
+++ b/src/osdef.h.in
@@ -147,9 +147,7 @@ extern char *malloc __P((int));
extern char *realloc __P((char *, int));
extern void free __P((char *));
-#ifdef NAMEDPIPE
extern int mknod __P((char *, int, int));
-#else
struct sockaddr; /* for connect __P */
extern int socket __P((int, int, int));
extern int connect __P((int, struct sockaddr *, int));
@@ -160,7 +158,6 @@ extern int accept __P((int, struct sockaddr *, socklen_t
*));
#else
extern int accept __P((int, struct sockaddr *, int *));
#endif
-#endif
#if defined(UTMPOK) && defined(GETUTENT)
extern void setutent __P((void));
diff --git a/src/osdef.sh b/src/osdef.sh
index b281175..1922229 100644
--- a/src/osdef.sh
+++ b/src/osdef.sh
@@ -28,9 +28,7 @@ cat << EOF > osdef0.c
#include <string.h>
#include <stdlib.h>
#endif
-#ifndef NAMEDPIPE
#include <sys/socket.h>
-#endif
#ifndef NOSYSLOG
#include <syslog.h>
#endif
diff --git a/src/screen.c b/src/screen.c
index 559f809..8f50d76 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -164,8 +164,8 @@ static char *runbacktick __P((struct backtick *, int *,
time_t));
static int IsSymbol __P((char *, char *));
static char *ParseChar __P((char *, char *));
static int ParseEscape __P((char *));
-static void SetTtyname(bool fatal, struct stat *st);
static char *pad_expand __P((char *, char *, int, int));
+static void SetTtyname __P((bool, struct stat *));
#ifdef DEBUG
static void fds __P((void));
#endif
@@ -422,9 +422,6 @@ int main(int ac, char** av)
#ifdef SYSVSIGS
debug("SYSVSIGS\n");
#endif
-#ifdef NAMEDPIPE
- debug("NAMEDPIPE\n");
-#endif
#if defined(SIGWINCH) && defined(TIOCGWINSZ)
debug("Window size changing enabled\n");
#endif
@@ -1001,9 +998,6 @@ int main(int ac, char** av)
attach_tty = "";
if (!detached && !lsflag && !cmdflag && !(dflag && !mflag && !rflag &&
!xflag) &&
!(sty && !SockMatch && !mflag && !rflag && !xflag)) {
-#ifndef NAMEDPIPE
- int fl;
-#endif
/* ttyname implies isatty */
SetTtyname(true, &st);
@@ -1011,25 +1005,11 @@ int main(int ac, char** av)
tty_mode = (int)st.st_mode & 0777;
#endif
-#ifndef NAMEDPIPE
- fl = fcntl(0, F_GETFL, 0);
- if (fl != -1 && (fl & (O_RDWR|O_RDONLY|O_WRONLY)) == O_RDWR)
- attach_fd = 0;
-#endif
-
if (attach_fd == -1) {
if ((n = secopen(attach_tty, O_RDWR | O_NONBLOCK, 0)) < 0)
Panic(0, "Cannot open your terminal '%s' - please check.", attach_tty);
- /* In case the pts device exists in another namespace we directly operate
- * on the symbolic link itself. However, this means that we need to keep
- * the fd open since we have no direct way of identifying the associated
- * pts device accross namespaces. This is ok though since keeping fds
open
- * is done in the codebase already.
- */
- if (attach_tty_is_in_new_ns)
- attach_fd = n;
- else
- close(n);
+ /* If the server uses a socket we need an open fd. */
+ attach_fd = n;
}
debug2("attach_tty is %s, attach_fd is %d\n", attach_tty, attach_fd);
@@ -1181,6 +1161,7 @@ int main(int ac, char** av)
if (lsflag) {
int i, fo, oth;
+ bool sock;
#ifdef MULTIUSER
if (multi)
@@ -1188,7 +1169,7 @@ int main(int ac, char** av)
#endif
SET_GUID();
- i = FindSocket((int *)NULL, &fo, &oth, SockMatch);
+ i = FindSocket((int *)NULL, &fo, &oth, SockMatch, &sock);
if (quietflag) {
if (rflag)
exit(10 + i);
@@ -1359,7 +1340,10 @@ int main(int ac, char** av)
#endif
sprintf(SockPath + strlen(SockPath), "/%s", socknamebuf);
- ServerSocket = MakeServerSocket();
+ /* Always create sockets. We only only allow attaching to fifos not creating
+ * new ones.
+ */
+ ServerSocket = MakeServerSocket(true);
InitKeytab();
#ifdef ETCSCREENRC
diff --git a/src/socket.c b/src/socket.c
index 81e0b4b..6d205b9 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -33,13 +33,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#if !defined(NAMEDPIPE)
# include <sys/socket.h>
# ifdef _OpenBSD_
# include <sys/uio.h>
# endif
# include <sys/un.h>
-#endif
#ifndef SIGINT
# include <signal.h>
@@ -67,7 +65,7 @@
static int CheckPid __P((int));
static void ExecCreate __P((struct msg *));
static void DoCommandMsg __P((struct msg *));
-#if defined(_SEQUENT_) && !defined(NAMEDPIPE)
+#if defined(_SEQUENT_)
# define connect sconnect /* _SEQUENT_ has braindamaged connect */
static int sconnect __P((int, struct sockaddr *, int));
#endif
@@ -122,14 +120,15 @@ extern struct comm comms[];
* If none exists or fdp is NULL SockPath is not changed.
*
* Returns: number of good sockets.
- *
+ *
*/
int
-FindSocket(fdp, nfoundp, notherp, match)
+FindSocket(fdp, nfoundp, notherp, match, is_sock)
int *fdp;
int *nfoundp, *notherp;
char *match;
+bool *is_sock;
{
DIR *dirp;
struct dirent *dp;
@@ -226,21 +225,9 @@ char *match;
continue;
}
-#ifndef SOCK_NOT_IN_FS
-# ifdef NAMEDPIPE
-# ifdef S_ISFIFO
- debug("S_ISFIFO?\n");
- if (!S_ISFIFO(st.st_mode))
- continue;
-# endif
-# else
-# ifdef S_ISSOCK
- debug("S_ISSOCK?\n");
- if (!S_ISSOCK(st.st_mode))
+ *is_sock = S_ISSOCK(st.st_mode);
+ if (!(*is_sock) && !S_ISFIFO(st.st_mode))
continue;
-# endif
-# endif
-#endif
debug2("st.st_uid = %d, real_uid = %d\n", st.st_uid, real_uid);
#ifdef SOCKDIR /* if SOCKDIR is not defined, the socket is in $HOME.
@@ -274,7 +261,7 @@ char *match;
*slisttail = sent;
slisttail = &sent->next;
nfound++;
- sockfd = MakeClientSocket(0);
+ sockfd = MakeClientSocket(0, *is_sock);
#ifdef USE_SETEUID
/* MakeClientSocket sets ids back to eff */
xseteuid(real_uid);
@@ -436,217 +423,228 @@ char *match;
return ngood;
}
+/* FIFO (legacy mode) */
+static int MakeServerFifo()
+{
+ register int s;
+ struct stat st;
-/*
-**
-** Socket/pipe create routines
-**
-*/
+#ifdef USE_SETEUID
+ xseteuid(real_uid);
+ xsetegid(real_gid);
+#endif
+ s = open(SockPath, O_WRONLY | O_NONBLOCK);
+ if (s >= 0) {
+ debug("huii, my fifo already exists??\n");
+ if (quietflag) {
+ Kill(D_userpid, SIG_BYE);
+ eexit(11);
+ }
-#ifdef NAMEDPIPE
+ Msg(0, "There is already a screen running on %s.",
+ Filename(SockPath));
-int
-MakeServerSocket()
-{
- register int s;
- struct stat st;
+ if (stat(SockPath, &st) < 0)
+ Panic(errno, "stat");
-# ifdef USE_SETEUID
- xseteuid(real_uid);
- xsetegid(real_gid);
-# endif
- if ((s = open(SockPath, O_WRONLY | O_NONBLOCK)) >= 0)
- {
- debug("huii, my fifo already exists??\n");
- if (quietflag)
- {
- Kill(D_userpid, SIG_BYE);
- eexit(11);
+#ifdef SOCKDIR /* if SOCKDIR is not defined, the socket is in $HOME.
\
+ in that case it does not make sense to compare uids. */
+ if ((int)st.st_uid != real_uid)
+ Panic(0, "Unfortunately you are not its owner.");
+#endif
+ if ((st.st_mode & 0700) == 0600)
+ Panic(0, "To resume it, use \"screen -r\"");
+ else
+ Panic(0, "It is not detached.");
+ /* NOTREACHED */
}
- Msg(0, "There is already a screen running on %s.", Filename(SockPath));
- if (stat(SockPath, &st) == -1)
- Panic(errno, "stat");
-#ifdef SOCKDIR /* if SOCKDIR is not defined, the socket is in $HOME.
- in that case it does not make sense to compare uids. */
- if ((int)st.st_uid != real_uid)
- Panic(0, "Unfortunately you are not its owner.");
+#ifdef USE_SETEUID
+ (void)unlink(SockPath);
+ if (mkfifo(SockPath, SOCKMODE) < 0)
+ Panic(0, "mkfifo %s failed", SockPath);
+#ifdef BROKEN_PIPE
+ s = open(SockPath, O_RDWR | O_NONBLOCK, 0);
+#else
+ s = open(SockPath, O_RDONLY | O_NONBLOCK, 0);
#endif
- if ((st.st_mode & 0700) == 0600)
- Panic(0, "To resume it, use \"screen -r\"");
- else
- Panic(0, "It is not detached.");
- /* NOTREACHED */
- }
-# ifdef USE_SETEUID
- (void) unlink(SockPath);
- if (mkfifo(SockPath, SOCKMODE))
- Panic(0, "mkfifo %s failed", SockPath);
-# ifdef BROKEN_PIPE
- if ((s = open(SockPath, O_RDWR | O_NONBLOCK, 0)) < 0)
-# else
- if ((s = open(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
-# endif
- Panic(errno, "open fifo %s", SockPath);
- xseteuid(eff_uid);
- xsetegid(eff_gid);
- return s;
-# else /* !USE_SETEUID */
- if (UserContext() > 0)
- {
- (void) unlink(SockPath);
- UserReturn(mkfifo(SockPath, SOCKMODE));
- }
- if (UserStatus())
- Panic(0, "mkfifo %s failed", SockPath);
-# ifdef BROKEN_PIPE
- if ((s = secopen(SockPath, O_RDWR | O_NONBLOCK, 0)) < 0)
-# else
- if ((s = secopen(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
-# endif
- Panic(errno, "open fifo %s", SockPath);
- return s;
-# endif /* !USE_SETEUID */
-}
+ if (s < 0)
+ Panic(errno, "open fifo %s", SockPath);
+ xseteuid(eff_uid);
+ xsetegid(eff_gid);
-int
-MakeClientSocket(err)
-int err;
-{
- register int s = 0;
+ return s;
- if ((s = secopen(SockPath, O_WRONLY | O_NONBLOCK, 0)) >= 0)
- {
- (void) fcntl(s, F_SETFL, 0);
- return s;
- }
- if (err)
- Msg(errno, "%s", SockPath);
- debug2("MakeClientSocket() open %s failed (%d)\n", SockPath, errno);
- return -1;
+#else /* !USE_SETEUID */
+ if (UserContext() > 0) {
+ (void)unlink(SockPath);
+ UserReturn(mkfifo(SockPath, SOCKMODE));
+ }
+ if (UserStatus())
+ Panic(0, "mkfifo %s failed", SockPath);
+#ifdef BROKEN_PIPE
+ s = secopen(SockPath, O_RDWR | O_NONBLOCK, 0);
+#else
+ s = secopen(SockPath, O_RDONLY | O_NONBLOCK, 0);
+#endif
+ if (s < 0)
+ Panic(errno, "open fifo %s", SockPath);
+
+ return s;
+#endif /* !USE_SETEUID */
}
+static int MakeClientFifo(int err)
+{
+ register int s = 0;
-#else /* NAMEDPIPE */
+ s = secopen(SockPath, O_WRONLY | O_NONBLOCK, 0);
+ if (s >= 0) {
+ (void)fcntl(s, F_SETFL, 0);
+ return s;
+ }
+ if (err)
+ Msg(errno, "%s", SockPath);
-int
-MakeServerSocket()
+ return -1;
+}
+
+/* Unix Domain Sockets */
+static int MakeServerUnixSocket()
{
- register int s;
- struct sockaddr_un a;
- struct stat st;
+ register int s;
+ struct sockaddr_un a;
+ struct stat st;
- if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- Panic(errno, "socket");
- a.sun_family = AF_UNIX;
- strncpy(a.sun_path, SockPath, sizeof(a.sun_path));
- a.sun_path[sizeof(a.sun_path) - 1] = 0;
-# ifdef USE_SETEUID
- xseteuid(real_uid);
- xsetegid(real_gid);
-# endif
- if (connect(s, (struct sockaddr *) &a, strlen(SockPath) + 2) != -1)
- {
- debug("oooooh! socket already is alive!\n");
- if (quietflag)
- {
- Kill(D_userpid, SIG_BYE);
- /*
- * oh, well. nobody receives that return code. papa
- * dies by signal.
- */
- eexit(11);
- }
- Msg(0, "There is already a screen running on %s.", Filename(SockPath));
- if (stat(SockPath, &st) == -1)
- Panic(errno, "stat");
-#ifdef SOCKDIR /* if SOCKDIR is not defined, the socket is in $HOME.
- in that case it does not make sense to compare uids. */
- if (st.st_uid != real_uid)
- Panic(0, "Unfortunately you are not its owner.");
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (s < 0)
+ Panic(errno, "socket");
+
+ a.sun_family = AF_UNIX;
+ strncpy(a.sun_path, SockPath, sizeof(a.sun_path));
+ a.sun_path[sizeof(a.sun_path) - 1] = 0;
+
+#ifdef USE_SETEUID
+ xseteuid(real_uid);
+ xsetegid(real_gid);
#endif
- if ((st.st_mode & 0700) == 0600)
- Panic(0, "To resume it, use \"screen -r\"");
- else
- Panic(0, "It is not detached.");
- /* NOTREACHED */
- }
+ if (connect(s, (struct sockaddr *)&a, strlen(SockPath) + 2) != -1) {
+ debug("oooooh! socket already is alive!\n");
+ if (quietflag) {
+ Kill(D_userpid, SIG_BYE);
+ /*
+ * oh, well. nobody receives that return code. papa
+ * dies by signal.
+ */
+ eexit(11);
+ }
+ Msg(0, "There is already a screen running on %s.",
+ Filename(SockPath));
+
+ if (stat(SockPath, &st) < 0)
+ Panic(errno, "stat");
+
+#ifdef SOCKDIR /* if SOCKDIR is not defined, the socket is in $HOME.
\
+ in that case it does not make sense to compare uids. */
+ if (st.st_uid != real_uid)
+ Panic(0, "Unfortunately you are not its owner.");
+#endif
+ if ((st.st_mode & 0700) == 0600)
+ Panic(0, "To resume it, use \"screen -r\"");
+ else
+ Panic(0, "It is not detached.");
+ /* NOTREACHED */
+ }
+
#if defined(m88k) || defined(sysV68)
- close(s); /* we get bind: Invalid argument if this is not done */
- if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- Panic(errno, "reopen socket");
+ close(s); /* we get bind: Invalid argument if this is not done */
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (s < 0)
+ Panic(errno, "reopen socket");
#endif
- (void) unlink(SockPath);
- if (bind(s, (struct sockaddr *) & a, strlen(SockPath) + 2) == -1)
- Panic(errno, "bind (%s)", SockPath);
+ (void)unlink(SockPath);
+ if (bind(s, (struct sockaddr *)&a, strlen(SockPath) + 2) == -1)
+ Panic(errno, "bind (%s)", SockPath);
#ifdef SOCK_NOT_IN_FS
- {
- int f;
- if ((f = secopen(SockPath, O_RDWR | O_CREAT, SOCKMODE)) < 0)
- Panic(errno, "shadow socket open");
- close(f);
- }
+ {
+ int f = secopen(SockPath, O_RDWR | O_CREAT, SOCKMODE);
+ if (f < 0)
+ Panic(errno, "shadow socket open");
+ close(f);
+ }
#else
- chmod(SockPath, SOCKMODE);
-# ifndef USE_SETEUID
- chown(SockPath, real_uid, real_gid);
-# endif
+ chmod(SockPath, SOCKMODE);
+#ifndef USE_SETEUID
+ chown(SockPath, real_uid, real_gid);
+#endif
#endif /* SOCK_NOT_IN_FS */
- if (listen(s, 5) == -1)
- Panic(errno, "listen");
-# ifdef F_SETOWN
- fcntl(s, F_SETOWN, getpid());
- debug1("Serversocket owned by %d\n", fcntl(s, F_GETOWN, 0));
-# endif /* F_SETOWN */
-# ifdef USE_SETEUID
- xseteuid(eff_uid);
- xsetegid(eff_gid);
-# endif
- return s;
+ if (listen(s, 5) == -1)
+ Panic(errno, "listen");
+#ifdef F_SETOWN
+ fcntl(s, F_SETOWN, getpid());
+ debug1("Serversocket owned by %d\n", fcntl(s, F_GETOWN, 0));
+#endif /* F_SETOWN */
+#ifdef USE_SETEUID
+ xseteuid(eff_uid);
+ xsetegid(eff_gid);
+#endif
+ return s;
}
-int
-MakeClientSocket(err)
-int err;
+static int MakeClientUnixSocket(int err)
{
- register int s;
- struct sockaddr_un a;
-
- if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- Panic(errno, "socket");
- a.sun_family = AF_UNIX;
- strncpy(a.sun_path, SockPath, sizeof(a.sun_path));
- a.sun_path[sizeof(a.sun_path) - 1] = 0;
-# ifdef USE_SETEUID
- xseteuid(real_uid);
- xsetegid(real_gid);
-# else
- if (access(SockPath, W_OK))
- {
- if (err)
- Msg(errno, "%s", SockPath);
- debug2("MakeClientSocket: access(%s): %d.\n", SockPath, errno);
- close(s);
- return -1;
- }
-# endif
- if (connect(s, (struct sockaddr *) &a, strlen(SockPath) + 2) == -1)
- {
- if (err)
- Msg(errno, "%s: connect", SockPath);
- debug("MakeClientSocket: connect failed.\n");
- close(s);
- s = -1;
- }
-# ifdef USE_SETEUID
- xseteuid(eff_uid);
- xsetegid(eff_gid);
-# endif
- return s;
+ register int s;
+ struct sockaddr_un a;
+
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (s < 0)
+ Panic(errno, "socket");
+
+ a.sun_family = AF_UNIX;
+ strncpy(a.sun_path, SockPath, sizeof(a.sun_path));
+ a.sun_path[sizeof(a.sun_path) - 1] = 0;
+#ifdef USE_SETEUID
+ xseteuid(real_uid);
+ xsetegid(real_gid);
+#else
+ if (access(SockPath, W_OK)) {
+ if (err)
+ Msg(errno, "%s", SockPath);
+ debug2("MakeClientSocket: access(%s): %d.\n", SockPath, errno);
+ close(s);
+ return -1;
+ }
+#endif
+ if (connect(s, (struct sockaddr *)&a, strlen(SockPath) + 2) == -1) {
+ if (err)
+ Msg(errno, "%s: connect", SockPath);
+ debug("MakeClientSocket: connect failed.\n");
+ close(s);
+ s = -1;
+ }
+#ifdef USE_SETEUID
+ xseteuid(eff_uid);
+ xsetegid(eff_gid);
+#endif
+ return s;
+}
+
+int MakeServerSocket(bool socket)
+{
+ if (socket)
+ return MakeServerUnixSocket();
+
+ return MakeServerFifo();
}
-#endif /* NAMEDPIPE */
+int MakeClientSocket(int err, bool socket)
+{
+ if (socket)
+ return MakeClientUnixSocket(err);
+
+ return MakeClientFifo(err);
+}
/*
**
@@ -664,6 +662,7 @@ struct NewWindow *nwin;
register char *p;
register int len, n;
char **av;
+ bool is_socket;
#ifdef NAME_MAX
if (strlen(sty) > NAME_MAX)
@@ -672,7 +671,8 @@ struct NewWindow *nwin;
if (strlen(sty) > 2 * MAXSTR - 1)
sty[2 * MAXSTR - 1] = 0;
sprintf(SockPath + strlen(SockPath), "/%s", sty);
- if ((s = MakeClientSocket(1)) == -1)
+ is_socket = IsSocket(SockPath);
+ if ((s = MakeClientSocket(1, is_socket)) == -1)
exit(1);
debug1("SendCreateMsg() to '%s'\n", SockPath);
bzero((char *)&m, sizeof(m));
@@ -720,10 +720,12 @@ char *tty, *buf;
{
int s;
struct msg m;
+ bool is_socket;
strncpy(m.m.message, buf, sizeof(m.m.message) - 1);
m.m.message[sizeof(m.m.message) - 1] = 0;
- s = MakeClientSocket(0);
+ is_socket = IsSocket(SockPath);
+ s = MakeClientSocket(0, is_socket);
if (s < 0)
return -1;
m.type = MSG_ERROR;
@@ -1007,280 +1009,276 @@ struct win *wi;
return 0;
}
-void
-ReceiveMsg()
+void ReceiveMsg()
{
- int left, len;
- static struct msg m;
- char *p;
- int ns = ServerSocket;
- struct win *wi;
- int recvfd = -1;
- struct acluser *user;
-
-#ifdef NAMEDPIPE
- debug("Ha, there was someone knocking on my fifo??\n");
- if (fcntl(ServerSocket, F_SETFL, 0) == -1)
- Panic(errno, "BLOCK fcntl");
- p = (char *) &m;
- left = sizeof(m);
-#else
- struct sockaddr_un a;
- struct msghdr msg;
- struct iovec iov;
- char control[1024];
-
- len = sizeof(a);
- debug("Ha, there was someone knocking on my socket??\n");
- if ((ns = accept(ns, (struct sockaddr *) &a, (void *)&len)) < 0)
- {
- Msg(errno, "accept");
- return;
- }
+ int left, len;
+ static struct msg m;
+ char *p;
+ int ns = ServerSocket;
+ struct win *wi;
+ int recvfd = -1;
+ struct acluser *user;
+ bool is_socket;
+
+ /* Socket specific variables. */
+ struct sockaddr_un a;
+ struct msghdr msg;
+ struct iovec iov;
+ char control[1024];
+
+ is_socket = IsSocket(SockPath);
+ if (!is_socket) {
+ debug("Ha, there was someone knocking on my fifo??\n");
+ if (fcntl(ServerSocket, F_SETFL, 0) == -1)
+ Panic(errno, "BLOCK fcntl");
+ p = (char *)&m;
+ left = sizeof(m);
+ } else {
+ len = sizeof(a);
+ debug("Ha, there was someone knocking on my socket??\n");
+ if ((ns = accept(ns, (struct sockaddr *)&a, (void *)&len)) <
+ 0) {
+ Msg(errno, "accept");
+ return;
+ }
- p = (char *) &m;
- left = sizeof(m);
- bzero(&msg, sizeof(msg));
- iov.iov_base = &m;
- iov.iov_len = left;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_controllen = sizeof(control);
- msg.msg_control = &control;
- while (left > 0)
- {
- len = recvmsg(ns, &msg, 0);
- if (len < 0 && errno == EINTR)
- continue;
- if (len < 0)
- {
- close(ns);
- Msg(errno, "read");
- return;
- }
- if (msg.msg_controllen)
- {
- struct cmsghdr *cmsg;
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
- {
- int cl;
- char *cp;
- if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type !=
SCM_RIGHTS)
- continue;
- cp = (char *)CMSG_DATA(cmsg);
- cl = cmsg->cmsg_len;
- while(cl >= CMSG_LEN(sizeof(int)))
- {
- int passedfd;
- bcopy(cp, &passedfd, sizeof(int));
- if (recvfd >= 0 && passedfd != recvfd)
- close(recvfd);
- recvfd = passedfd;
- cl -= CMSG_LEN(sizeof(int));
+ p = (char *)&m;
+ left = sizeof(m);
+ bzero(&msg, sizeof(msg));
+ iov.iov_base = &m;
+ iov.iov_len = left;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_controllen = sizeof(control);
+ msg.msg_control = &control;
+ while (left > 0) {
+ len = recvmsg(ns, &msg, 0);
+ if (len < 0 && errno == EINTR)
+ continue;
+ if (len < 0) {
+ close(ns);
+ Msg(errno, "read");
+ return;
+ }
+ if (msg.msg_controllen) {
+ struct cmsghdr *cmsg;
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ int cl;
+ char *cp;
+ if (cmsg->cmsg_level != SOL_SOCKET ||
+ cmsg->cmsg_type != SCM_RIGHTS)
+ continue;
+ cp = (char *)CMSG_DATA(cmsg);
+ cl = cmsg->cmsg_len;
+ while (cl >= CMSG_LEN(sizeof(int))) {
+ int passedfd;
+ bcopy(cp, &passedfd,
+ sizeof(int));
+ if (recvfd >= 0 &&
+ passedfd != recvfd)
+ close(recvfd);
+ recvfd = passedfd;
+ cl -= CMSG_LEN(sizeof(int));
+ }
+ }
+ }
+ p += len;
+ left -= len;
+ break;
}
- }
}
- p += len;
- left -= len;
- break;
- }
-#endif
-
- while (left > 0)
- {
- len = read(ns, p, left);
- if (len < 0 && errno == EINTR)
- continue;
- if (len <= 0)
- break;
- p += len;
- left -= len;
- }
+ while (left > 0) {
+ len = read(ns, p, left);
+ if (len < 0 && errno == EINTR)
+ continue;
+ if (len <= 0)
+ break;
+ p += len;
+ left -= len;
+ }
-#ifdef NAMEDPIPE
-# ifndef BROKEN_PIPE
- /* Reopen pipe to prevent EOFs at the select() call */
- close(ServerSocket);
- if ((ServerSocket = secopen(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
- Panic(errno, "reopen fifo %s", SockPath);
- evdeq(&serv_read);
- serv_read.fd = ServerSocket;
- evenq(&serv_read);
-# endif
-#else
- close(ns);
+ if (!is_socket) {
+#ifndef BROKEN_PIPE
+ /* Reopen pipe to prevent EOFs at the select() call */
+ close(ServerSocket);
+ if ((ServerSocket =
+ secopen(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
+ Panic(errno, "reopen fifo %s", SockPath);
+ evdeq(&serv_read);
+ serv_read.fd = ServerSocket;
+ evenq(&serv_read);
#endif
+ } else {
+ close(ns);
+ }
- if (len < 0)
- {
- Msg(errno, "read");
- if (recvfd != -1)
- close(recvfd);
- return;
- }
- if (left > 0)
- {
- if (left != sizeof(m))
- Msg(0, "Message %d of %d bytes too small", left, (int)sizeof(m));
- else
- debug("No data on socket.\n");
- return;
- }
- if (m.protocol_revision != MSG_REVISION)
- {
- if (recvfd != -1)
- close(recvfd);
- Msg(0, "Invalid message (magic 0x%08x).", m.protocol_revision);
- return;
- }
+ if (len < 0) {
+ Msg(errno, "read");
+ if (recvfd != -1)
+ close(recvfd);
+ return;
+ }
+ if (left > 0) {
+ if (left != sizeof(m))
+ Msg(0, "Message %d of %d bytes too small", left,
+ (int)sizeof(m));
+ else
+ debug("No data on socket.\n");
+ return;
+ }
+ if (m.protocol_revision != MSG_REVISION) {
+ if (recvfd != -1)
+ close(recvfd);
+ Msg(0, "Invalid message (magic 0x%08x).", m.protocol_revision);
+ return;
+ }
- debug2("*** RecMsg: type %d tty %s\n", m.type, m.m_tty);
- if (m.type != MSG_ATTACH && recvfd != -1)
- {
- close(recvfd);
- recvfd = -1;
- }
+ debug2("*** RecMsg: type %d tty %s\n", m.type, m.m_tty);
+ if (m.type != MSG_ATTACH && recvfd != -1) {
+ close(recvfd);
+ recvfd = -1;
+ }
- for (display = displays; display; display = display->d_next)
- if (TTYCMP(D_usertty, m.m_tty) == 0)
- break;
- debug2("display: %s display %sfound\n", m.m_tty, display ? "" : "not ");
- wi = 0;
- if (!display)
- {
- for (wi = windows; wi; wi = wi->w_next)
- if (!TTYCMP(m.m_tty, wi->w_tty))
- {
- /* XXX: hmmm, rework this? */
- display = wi->w_layer.l_cvlist ? wi->w_layer.l_cvlist->c_display :
0;
- debug2("but window %s %sfound.\n", m.m_tty, display ? "" :
- "(backfacing)");
- break;
- }
- }
+ for (display = displays; display; display = display->d_next)
+ if (TTYCMP(D_usertty, m.m_tty) == 0)
+ break;
+ debug2("display: %s display %sfound\n", m.m_tty, display ? "" : "not ");
+ wi = 0;
+ if (!display) {
+ for (wi = windows; wi; wi = wi->w_next)
+ if (!TTYCMP(m.m_tty, wi->w_tty)) {
+ /* XXX: hmmm, rework this? */
+ display = wi->w_layer.l_cvlist
+ ? wi->w_layer.l_cvlist->c_display
+ : 0;
+ debug2("but window %s %sfound.\n", m.m_tty,
+ display ? "" : "(backfacing)");
+ break;
+ }
+ }
- /* Remove the status to prevent garbage on the screen */
- if (display && D_status)
- RemoveStatus();
+ /* Remove the status to prevent garbage on the screen */
+ if (display && D_status)
+ RemoveStatus();
- if (display && !D_tcinited && m.type != MSG_HANGUP)
- {
- if (recvfd != -1)
- close(recvfd);
- return; /* ignore messages for bad displays */
- }
+ if (display && !D_tcinited && m.type != MSG_HANGUP) {
+ if (recvfd != -1)
+ close(recvfd);
+ return; /* ignore messages for bad displays */
+ }
- switch (m.type)
- {
- case MSG_WINCH:
- if (display)
- CheckScreenSize(1); /* Change fore */
- break;
- case MSG_CREATE:
- /*
- * the window that issued the create message need not be an active
- * window. Then we create the window without having a display.
- * Resulting in another inactive window.
- */
- ExecCreate(&m);
- break;
- case MSG_CONT:
- if (display && D_userpid != 0 && kill(D_userpid, 0) == 0)
- break; /* Intruder Alert */
- debug2("RecMsg: apid=%d,was %d\n", m.m.attach.apid, display ? D_userpid
: 0);
- /* FALLTHROUGH */
-
- case MSG_ATTACH:
- if (CreateTempDisplay(&m, recvfd, wi))
- break;
+ switch (m.type) {
+ case MSG_WINCH:
+ if (display)
+ CheckScreenSize(1); /* Change fore */
+ break;
+ case MSG_CREATE:
+ /*
+ * the window that issued the create message need not be an
+ * active
+ * window. Then we create the window without having a display.
+ * Resulting in another inactive window.
+ */
+ ExecCreate(&m);
+ break;
+ case MSG_CONT:
+ if (display && D_userpid != 0 && kill(D_userpid, 0) == 0)
+ break; /* Intruder Alert */
+ debug2("RecMsg: apid=%d,was %d\n", m.m.attach.apid,
+ display ? D_userpid : 0);
+ /* FALLTHROUGH */
+
+ case MSG_ATTACH:
+ if (CreateTempDisplay(&m, recvfd, wi))
+ break;
#ifdef PASSWORD
- if (D_user->u_password && *D_user->u_password)
- AskPassword(&m);
- else
+ if (D_user->u_password && *D_user->u_password)
+ AskPassword(&m);
+ else
#endif
- FinishAttach(&m);
- break;
- case MSG_ERROR:
- Msg(0, "%s", m.m.message);
- break;
- case MSG_HANGUP:
- if (!wi) /* ignore hangups from inside */
- Hangup();
- break;
+ FinishAttach(&m);
+ break;
+ case MSG_ERROR:
+ Msg(0, "%s", m.m.message);
+ break;
+ case MSG_HANGUP:
+ if (!wi) /* ignore hangups from inside */
+ Hangup();
+ break;
#ifdef REMOTE_DETACH
- case MSG_DETACH:
-# ifdef POW_DETACH
- case MSG_POW_DETACH:
-# endif /* POW_DETACH */
+ case MSG_DETACH:
+#ifdef POW_DETACH
+ case MSG_POW_DETACH:
+#endif /* POW_DETACH */
#ifdef PASSWORD
- user = *FindUserPtr(m.m.detach.duser);
- if (user && user->u_password && *user->u_password)
- {
- if (CreateTempDisplay(&m, recvfd, 0))
- break;
- AskPassword(&m);
- }
- else
+ user = *FindUserPtr(m.m.detach.duser);
+ if (user && user->u_password && *user->u_password) {
+ if (CreateTempDisplay(&m, recvfd, 0))
+ break;
+ AskPassword(&m);
+ } else
#endif /* PASSWORD */
- FinishDetach(&m);
- break;
+ FinishDetach(&m);
+ break;
#endif
- case MSG_QUERY:
- {
- char *oldSockPath = SaveStr(SockPath);
- strcpy(SockPath, m.m.command.writeback);
- int s = MakeClientSocket(0);
- strcpy(SockPath, oldSockPath);
- Free(oldSockPath);
- if (s >= 0)
- {
- queryflag = s;
- DoCommandMsg(&m);
- close(s);
- }
- else
- queryflag = -1;
-
- Kill(m.m.command.apid, (queryflag >= 0) ? SIGCONT : SIG_BYE); /* Send
SIG_BYE if an error happened */
- queryflag = -1;
+ case MSG_QUERY: {
+ char *oldSockPath = SaveStr(SockPath);
+ strcpy(SockPath, m.m.command.writeback);
+ bool is_socket = IsSocket(SockPath);
+ int s = MakeClientSocket(0, is_socket);
+ strcpy(SockPath, oldSockPath);
+ Free(oldSockPath);
+ if (s >= 0) {
+ queryflag = s;
+ DoCommandMsg(&m);
+ close(s);
+ } else
+ queryflag = -1;
+
+ Kill(m.m.command.apid,
+ (queryflag >= 0)
+ ? SIGCONT
+ : SIG_BYE); /* Send SIG_BYE if an error happened */
+ queryflag = -1;
+ } break;
+ case MSG_COMMAND:
+ DoCommandMsg(&m);
+ break;
+ default:
+ Msg(0, "Invalid message (type %d).", m.type);
}
- break;
- case MSG_COMMAND:
- DoCommandMsg(&m);
- break;
- default:
- Msg(0, "Invalid message (type %d).", m.type);
- }
}
-void
-ReceiveRaw(s)
-int s;
+void ReceiveRaw(int s)
{
- char rd[256];
- int len = 0;
-#ifdef NAMEDPIPE
- if (fcntl(s, F_SETFL, 0) == -1)
- Panic(errno, "BLOCK fcntl");
-#else
- struct sockaddr_un a;
- len = sizeof(a);
- if ((s = accept(s, (struct sockaddr *) &a, (void *)&len)) < 0)
- {
- Msg(errno, "accept");
- return;
- }
-#endif
- while ((len = read(s, rd, 255)) > 0)
- {
- rd[len] = 0;
- printf("%s", rd);
- }
- close(s);
+ char rd[256];
+ int len = 0;
+ struct sockaddr_un a;
+ bool is_socket;
+
+ is_socket = IsSocket(SockPath);
+ if (!is_socket) {
+ if (fcntl(s, F_SETFL, 0) < 0)
+ Panic(errno, "BLOCK fcntl");
+ } else {
+ len = sizeof(a);
+ s = accept(s, (struct sockaddr *)&a, (void *)&len);
+ if (s < 0) {
+ Msg(errno, "accept");
+ return;
+ }
+ }
+
+ while ((len = read(s, rd, 255)) > 0) {
+ rd[len] = 0;
+ printf("%s", rd);
+ }
+ close(s);
}
-#if defined(_SEQUENT_) && !defined(NAMEDPIPE)
+#if defined(_SEQUENT_)
#undef connect
/*
* sequent_ptx socket emulation must have mode 000 on the socket!
@@ -1336,6 +1334,8 @@ chsock()
int
RecoverSocket()
{
+ bool is_socket;
+
close(ServerSocket);
if ((int)geteuid() != real_uid)
{
@@ -1346,7 +1346,8 @@ RecoverSocket()
else
(void) unlink(SockPath);
- if ((ServerSocket = MakeServerSocket()) < 0)
+ is_socket = IsSocket(SockPath);
+ if ((ServerSocket = MakeServerSocket(is_socket)) < 0)
return 0;
evdeq(&serv_read);
serv_read.fd = ServerSocket;
@@ -1831,8 +1832,6 @@ struct msg *mp;
#endif
}
-#ifndef NAMEDPIPE
-
int
SendAttachMsg(s, m, fd)
int s;
@@ -1871,4 +1870,12 @@ int fd;
}
}
-#endif
+bool IsSocket(const char *path)
+{
+ struct stat st;
+
+ if (stat(SockPath, &st) < 0)
+ return false;
+
+ return S_ISSOCK(st.st_mode);
+}
--
2.11.0