|
Subject: Patch for recent Cygwin Newsgroups: gmane.comp.gnu.screen Date: 2003-08-12 13:56:18 GMT (5 years, 46 weeks, 5 days, 5 hours and 15 minutes ago)
Recent versions of Cygwin does not save permissions to UNIX-domain
sockets. I wrote a workaround code. It also add support of FAT32
without CYGWIN=ntea.
diff -ru screen-3.9.15.orig/attacher.c screen-3.9.15/attacher.c
--- screen-3.9.15.orig/attacher.c 2002-08-23 04:21:53.000000000 +0900
+++ screen-3.9.15/attacher.c 2003-05-16 13:00:32.000000000 +0900
@@ -277,7 +277,7 @@
}
debug1("Attach decided, it is '%s'\n", SockPath);
debug1("Attach found MasterPid == %d\n", MasterPid);
- if (stat(SockPath, &st) == -1)
+ if (screen_stat(SockPath, &st) == -1)
Panic(errno, "stat %s", SockPath);
if ((st.st_mode & 0600) != 0600)
Panic(0, "Socket is in wrong mode (%03o)", (int)st.st_mode);
@@ -423,7 +423,7 @@
debug("AttacherFinit();\n");
signal(SIGHUP, SIG_IGN);
/* Check if signal comes from backend */
- if (stat(SockPath, &statb) == 0 && (statb.st_mode & 0777) != 0600)
+ if (screen_stat(SockPath, &statb) == 0 && (statb.st_mode & 0777) != 0600)
{
debug("Detaching backend!\n");
bzero((char *) &m, sizeof(m));
diff -ru screen-3.9.15.orig/config.h.in screen-3.9.15/config.h.in
--- screen-3.9.15.orig/config.h.in 2003-03-13 20:19:53.000000000 +0900
+++ screen-3.9.15/config.h.in 2003-05-16 13:01:24.000000000 +0900
@@ -180,6 +180,15 @@
#undef RXVT_OSC
#undef COLORS256
+#ifdef __CYGWIN__
+# define CYGWIN_FILEMODE
+#else
+# undef CYGWIN_FILEMODE
+#endif
+#ifdef CYGWIN_FILEMODE
+# undef MULTIUSER
+#endif
+
/*
* If you have a braille display you should define HAVE_BRAILLE.
diff -ru screen-3.9.15.orig/display.c screen-3.9.15/display.c
--- screen-3.9.15.orig/display.c 2003-02-24 20:53:35.000000000 +0900
+++ screen-3.9.15/display.c 2003-05-16 13:00:32.000000000 +0900
@@ -75,6 +75,9 @@
/*
* tputs needs this to calculate the padding
*/
+#if defined(__CYGWIN__) && !defined(NCURSES_STATIC)
+__declspec(dllimport)
+#endif
#ifndef NEED_OSPEED
extern
#endif /* NEED_OSPEED */
diff -ru screen-3.9.15.orig/extern.h screen-3.9.15/extern.h
--- screen-3.9.15.orig/extern.h 2003-02-25 02:01:17.000000000 +0900
+++ screen-3.9.15/extern.h 2003-05-16 13:02:33.000000000 +0900
@@ -479,3 +479,19 @@
# endif
#endif
extern int EncodeChar __P((char *, int, int, int *));
+
+#ifdef CYGWIN_FILEMODE
+extern int screen_stat __P((char *, struct stat *));
+extern int screen_chmod __P((char *, mode_t));
+# ifdef NAMEDPIPE
+extern int screen_mkfifo __P((char *, mode_t));
+# endif
+extern int screen_unlink __P((char *));
+#else /* CYGWIN_FILEMODE */
+# define screen_stat(path, st) stat(path, st)
+# define screen_chmod(path, mode) chmod(path, mode)
+# ifdef NAMEDPIPE
+# define screen_mkfifo(path, mode) mkfifo(path, mode)
+# endif
+# define screen_unlink(path) unlink(path)
+#endif /* CYGWIN_FILEMODE */
diff -ru screen-3.9.15.orig/misc.c screen-3.9.15/misc.c
--- screen-3.9.15.orig/misc.c 2003-02-22 05:30:57.000000000 +0900
+++ screen-3.9.15/misc.c 2003-05-16 13:00:32.000000000 +0900
@@ -642,7 +642,7 @@
*/
# endif /* NEEDSETENV */
#else /* USESETENV */
-# if defined(linux) || defined(__convex__) || (BSD >= 199103)
+# if defined(linux) || defined(__convex__) || (BSD >= 199103) || defined(__CYGWIN__)
setenv(var, value, 1);
# else
setenv(var, value);
@@ -811,6 +811,9 @@
int (*outc) __P((int));
{
int pad;
+#if defined(__CYGWIN__) && !defined(NCURSES_STATIC)
+__declspec(dllimport)
+#endif
extern short ospeed;
static short osp2pad[] = {
0,2000,1333,909,743,666,500,333,166,83,55,41,20,10,5,2,1,1
diff -ru screen-3.9.15.orig/pty.c screen-3.9.15/pty.c
--- screen-3.9.15.orig/pty.c 2003-02-14 22:44:20.000000000 +0900
+++ screen-3.9.15/pty.c 2003-04-25 16:55:13.000000000 +0900
@@ -37,7 +37,7 @@
#endif
/* for solaris 2.1, Unixware (SVR4.2) and possibly others */
-#ifdef HAVE_SVR4_PTYS
+#if defined(HAVE_SVR4_PTYS) && !defined(__CYGWIN__)
# include <sys/stropts.h>
#endif
diff -ru screen-3.9.15.orig/resize.c screen-3.9.15/resize.c
--- screen-3.9.15.orig/resize.c 2002-11-09 01:31:51.000000000 +0900
+++ screen-3.9.15/resize.c 2003-05-12 13:22:51.000000000 +0900
@@ -991,7 +991,11 @@
/* signal new size to window */
#ifdef TIOCSWINSZ
+#ifndef __CYGWIN__
if (wi && (p->w_width != wi || p->w_height != he) && p->w_ptyfd >= 0 && p->w_pid)
+#else
+ if (wi && (p->w_width != wi || p->w_height != he) && p->w_ptyfd >= 0)
+#endif
{
glwz.ws_col = wi;
glwz.ws_row = he;
diff -ru screen-3.9.15.orig/screen.c screen-3.9.15/screen.c
--- screen-3.9.15.orig/screen.c 2003-02-25 02:03:47.000000000 +0900
+++ screen-3.9.15/screen.c 2003-05-16 15:01:29.000000000 +0900
@@ -886,7 +886,7 @@
if (!detached && !lsflag && !cmdflag && !(dflag && !mflag && !rflag && !xflag))
{
/* ttyname implies isatty */
- if (!(attach_tty = ttyname(0)))
+ if (!(attach_tty = strdup(ttyname(0))))
Panic(0, "Must be connected to a terminal.");
if (strlen(attach_tty) >= MAXPATHLEN)
Panic(0, "TtyName too long - sorry.");
@@ -1019,8 +1019,10 @@
if (st.st_uid != real_uid)
Panic(0, "You are not the owner of %s.", SockPath);
}
+#ifndef CYGWIN_FILEMODE
if ((st.st_mode & 0777) != 0700)
Panic(0, "Directory %s must have mode 700.", SockPath);
+#endif
if (SockMatch && index(SockMatch, '/'))
Panic(0, "Bad session name '%s'", SockMatch);
SockName = SockPath + strlen(SockPath) + 1;
@@ -1066,7 +1068,7 @@
char *sty = 0;
/* attach_tty is not mandatory */
- if ((attach_tty = ttyname(0)) == 0)
+ if ((attach_tty = strdup(ttyname(0))) == 0)
attach_tty = "";
if (strlen(attach_tty) >= MAXPATHLEN)
Panic(0, "TtyName too long - sorry.");
@@ -1414,7 +1416,7 @@
signal(SIGCHLD, SigChld);
#endif
}
- if (stat(SockPath, &st) == -1)
+ if (screen_stat(SockPath, &st) == -1)
{
debug1("SigChldHandler: Yuck! cannot stat '%s'\n", SockPath);
if (!RecoverSocket())
@@ -1633,7 +1635,7 @@
xseteuid(real_uid);
xsetegid(real_gid);
#endif
- (void) unlink(SockPath);
+ (void) screen_unlink(SockPath);
#ifdef USE_SETEUID
xseteuid(eff_uid);
xsetegid(eff_gid);
@@ -1671,7 +1673,7 @@
debug1("we unlink(%s)\n", SockPath);
setgid(real_gid);
setuid(real_uid);
- (void) unlink(SockPath);
+ (void) screen_unlink(SockPath);
}
exit(e);
}
diff -ru screen-3.9.15.orig/socket.c screen-3.9.15/socket.c
--- screen-3.9.15.orig/socket.c 2003-02-25 02:08:34.000000000 +0900
+++ screen-3.9.15/socket.c 2003-05-16 13:00:36.000000000 +0900
@@ -184,7 +184,7 @@
errno = 0;
debug2("uid = %d, gid = %d\n", getuid(), getgid());
debug2("euid = %d, egid = %d\n", geteuid(), getegid());
- if (stat(SockPath, &st))
+ if (screen_stat(SockPath, &st))
{
debug1("errno = %d\n", errno);
continue;
@@ -263,7 +263,7 @@
sent->mode = -1;
if (wipeflag)
{
- if (unlink(SockPath) == 0)
+ if (screen_unlink(SockPath) == 0)
{
sent->mode = -2;
nwipe++;
@@ -419,7 +419,7 @@
eexit(11);
}
Msg(0, "There is already a screen running on %s.", Filename(SockPath));
- if (stat(SockPath, &st) == -1)
+ if (screen_stat(SockPath, &st) == -1)
Panic(errno, "stat");
if (st.st_uid != real_uid)
Panic(0, "Unfortunatelly you are not its owner.");
@@ -430,8 +430,8 @@
/* NOTREACHED */
}
# ifdef USE_SETEUID
- (void) unlink(SockPath);
- if (mkfifo(SockPath, SOCKMODE))
+ (void) screen_unlink(SockPath);
+ if (screen_mkfifo(SockPath, SOCKMODE))
Panic(0, "mkfifo %s failed", SockPath);
# ifdef BROKEN_PIPE
if ((s = open(SockPath, O_RDWR | O_NONBLOCK, 0)) < 0)
@@ -445,8 +445,8 @@
# else /* !USE_SETEUID */
if (UserContext() > 0)
{
- (void) unlink(SockPath);
- UserReturn(mkfifo(SockPath, SOCKMODE));
+ (void) screen_unlink(SockPath);
+ UserReturn(screen_mkfifo(SockPath, SOCKMODE));
}
if (UserStatus())
Panic(0, "mkfifo %s failed", SockPath);
@@ -511,7 +511,7 @@
eexit(11);
}
Msg(0, "There is already a screen running on %s.", Filename(SockPath));
- if (stat(SockPath, &st) == -1)
+ if (screen_stat(SockPath, &st) == -1)
Panic(errno, "stat");
if (st.st_uid != real_uid)
Panic(0, "Unfortunatelly you are not its owner.");
@@ -526,7 +526,7 @@
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
Panic(errno, "reopen socket");
#endif
- (void) unlink(SockPath);
+ (void) screen_unlink(SockPath);
if (bind(s, (struct sockaddr *) & a, strlen(SockPath) + 2) == -1)
Panic(errno, "bind (%s)", SockPath);
#ifdef SOCK_NOT_IN_FS
@@ -537,7 +537,7 @@
close(f);
}
#else
- chmod(SockPath, SOCKMODE);
+ screen_chmod(SockPath, SOCKMODE);
# ifndef USE_SETEUID
chown(SockPath, real_uid, real_gid);
# endif
@@ -911,7 +911,11 @@
Msg(0, "Attach attempt with bad pid(%d)!", m.m.attach.apid);
break;
}
+#ifndef O_NOCTTY
if ((i = secopen(m.m_tty, O_RDWR | O_NONBLOCK, 0)) < 0)
+#else /* O_NOCTTY */
+ if ((i = secopen(m.m_tty, O_RDWR | O_NONBLOCK | O_NOCTTY, 0)) < 0)
+#endif
{
Msg(errno, "Attach: Could not open %s!", m.m_tty);
Kill(m.m.attach.apid, SIG_BYE);
@@ -1070,7 +1074,7 @@
if (UserContext() <= 0)
return UserStatus();
}
- r = chmod(SockPath, SOCKMODE);
+ r = screen_chmod(SockPath, SOCKMODE);
/*
* Sockets usually reside in the /tmp/ area, where sysadmin scripts
* may be happy to remove old files. We manually prevent the socket
@@ -1093,11 +1097,11 @@
if (geteuid() != real_uid)
{
if (UserContext() > 0)
- UserReturn(unlink(SockPath));
+ UserReturn(screen_unlink(SockPath));
(void)UserStatus();
}
else
- (void) unlink(SockPath);
+ (void) screen_unlink(SockPath);
if ((ServerSocket = MakeServerSocket()) < 0)
return 0;
@@ -1423,3 +1427,160 @@
EffectiveAclUser = 0;
#endif
}
+
+#ifdef CYGWIN_FILEMODE
+/* On cygwin (without ntea/ntsec), the mode of the UNIX domain
+ * socket is always either 755 or 655. Unfortunately, screen
+ * saves the socket state as the file mode.
+ *
+ * Therefore, we emulate the file mode, creating a special
+ * key file. This is ugly and possibly unsecure hack, but not
+ * critical on single-user system.
+ *
+ * If you found any bug, mail me:
+ * AIDA Shinra <aida_s <at> mx12.freecom.ne.jp>
+ */
+
+static char *GetModeKeyPath __P((char *));
+static int CreateModeKeyFile __P((char *, mode_t));
+static int ReadModeKeyFile __P((char *, mode_t *));
+static char modekey_format[] = "$$ screen: socket mode=0%o $$\n";
+
+int
+screen_stat(path, st)
+char *path;
+struct stat *st;
+{
+ mode_t modetmp;
+
+ if (stat(SockPath, st))
+ return -1;
+ if (!ReadModeKeyFile(path, &modetmp))
+ st->st_mode = (st->st_mode & ~07777) | modetmp;
+ errno = 0;
+ return 0;
+}
+
+int
+screen_chmod(path, mode)
+char *path;
+mode_t mode;
+{
+ if (chmod(path, mode))
+ return -1;
+ CreateModeKeyFile(path, mode);
+ errno = 0;
+ return 0;
+}
+
+#ifdef NAMEDPIPE
+int
+screen_mkfifo(path, mode)
+char *path;
+mode_t mode;
+{
+ if (mkfifo(path, mode))
+ return -1;
+ CreateModeKeyFile(path, mode);
+ errno = 0;
+ return 0;
+}
+#endif
+
+int
+screen_unlink(path)
+char *path;
+{
+ char *modekey_path;
+
+ if (unlink(path))
+ return -1;
+ if ((modekey_path = GetModeKeyPath(path)) == NULL)
+ return -1;
+ unlink(modekey_path);
+ free(modekey_path);
+ errno = 0;
+ return 0;
+}
+
+static char *
+GetModeKeyPath(path)
+char *path;
+{
+ char *keypath;
+ char *base;
+
+ keypath = malloc(strlen(path) + 7);
+ if (keypath == NULL) {
+ Panic (0, strnomem);
+ return NULL;
+ }
+ base = strrchr(path, '/');
+ if (base == NULL)
+ base = path;
+ else
+ base++;
+ strncpy(keypath, path, base-path);
+ sprintf(keypath+(base-path), ".%s.mode", base);
+ return keypath;
+}
+
+static int
+CreateModeKeyFile(path, mode)
+char *path;
+mode_t mode;
+{
+ int err = 0;
+ char *modekey_path;
+ FILE *keyfile;
+
+ if ((modekey_path = GetModeKeyPath(path)) == NULL)
+ return -1;
+ if ((keyfile = fopen(modekey_path, "w")) == NULL) {
+ err = errno;
+ } else {
+ errno = 0;
+ fprintf(keyfile, modekey_format, (unsigned int)mode);
+ if (errno)
+ err = errno;
+ if (fclose(keyfile))
+ err = errno;
+# ifndef USE_SETEUID
+ if (chown(modekey_path, getuid(), getgid()))
+ err = errno;
+# endif
+ }
+ free(modekey_path);
+ errno = err;
+ return (err) ? -1 : 0;
+}
+
+static int
+ReadModeKeyFile(path, modep)
+char *path;
+mode_t *modep;
+{
+ int err = 0;
+ char *modekey_path;
+ FILE *keyfile;
+ unsigned int mode_u;
+
+ if ((modekey_path = GetModeKeyPath(path)) == NULL)
+ return -1;
+
+ if ((keyfile = fopen(modekey_path, "r")) == NULL) {
+ err = errno;
+ } else {
+ if (fscanf(keyfile, modekey_format, &mode_u) != 1)
+ err=errno;
+ if (fclose(keyfile))
+ err=errno;
+ }
+ free(modekey_path);
+ errno = err;
+ if (err)
+ return -1;
+ *modep = (mode_t)mode_u;
+ return 0;
+}
+#endif /* CYGWIN_FILEMODE */
diff -ru screen-3.9.15.orig/utmp.c screen-3.9.15/utmp.c
--- screen-3.9.15.orig/utmp.c 2002-09-06 18:45:32.000000000 +0900
+++ screen-3.9.15/utmp.c 2003-05-16 15:13:08.000000000 +0900
@@ -93,7 +93,7 @@
static int initutmp __P((void));
static void setutent __P((void));
#endif
-#if defined(linux) && defined(GETUTENT)
+#if (defined(linux) || defined(__CYGWIN__)) && defined(GETUTENT)
static struct utmp *xpututline __P((struct utmp *utmp));
# define pututline xpututline
#endif
@@ -593,7 +593,7 @@
struct utmp *u;
{
u->ut_type = DEAD_PROCESS;
-#if !defined(linux) || defined(EMPTY)
+#if !defined(__CYGWIN__) && (!defined(linux) || defined(EMPTY))
u->ut_exit.e_termination = 0;
u->ut_exit.e_exit = 0;
#endif
@@ -862,7 +862,7 @@
}
# endif /* BUGGYGETLOGIN */
-#if defined(linux) && defined(GETUTENT)
+#if (defined(linux) || defined(__CYGWIN__)) && defined(GETUTENT)
# undef pututline
/* aargh, linux' pututline returns void! */
|
|
|