1
/* Copyright (c) 1993-2002
2
* Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4
* Copyright (c) 1987 Oliver Laumann
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2, or (at your option)
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program (see the file COPYING); if not, write to the
18
* Free Software Foundation, Inc.,
19
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21
****************************************************************
25
#include <sys/types.h>
28
#if !defined(NAMEDPIPE)
29
#include <sys/socket.h>
43
# define dirent direct
48
static int CheckPid __P((int));
49
static void ExecCreate __P((struct msg *));
50
static void DoCommandMsg __P((struct msg *));
51
#if defined(_SEQUENT_) && !defined(NAMEDPIPE)
52
# define connect sconnect /* _SEQUENT_ has braindamaged connect */
53
static int sconnect __P((int, struct sockaddr *, int));
55
static void FinishAttach __P((struct msg *));
56
static void AskPassword __P((struct msg *));
59
extern char *RcFileName, *extra_incap, *extra_outcap;
60
extern int ServerSocket, real_uid, real_gid, eff_uid, eff_gid;
61
extern int dflag, iflag, rflag, lsflag, quietflag, wipeflag, xflag;
62
extern char *attach_tty, *LoginName, HostName[];
63
extern struct display *display, *displays;
64
extern struct win *fore, *wtab[], *console_window, *windows;
65
extern struct layer *flayer;
66
extern struct NewWindow nwin_undef;
71
extern char *getenv();
73
extern char SockPath[];
74
extern struct event serv_read;
76
extern struct comm comms[];
79
# define SOCKMODE (S_IWRITE | S_IREAD | (displays ? S_IEXEC : 0) | (multi ? 1 : 0))
81
# define SOCKMODE (S_IWRITE | S_IREAD | (displays ? S_IEXEC : 0))
86
* Socket directory manager
88
* fdp: pointer to store the first good socket.
89
* nfoundp: pointer to store the number of sockets found matching.
90
* notherp: pointer to store the number of sockets not matching.
91
* match: string to match socket name.
93
* The socket directory must be in SockPath!
94
* The global variables LoginName, multi, rflag, xflag, dflag,
95
* quietflag, SockPath are used.
97
* The first good socket is stored in fdp and its name is
98
* appended to SockPath.
99
* If none exists or fdp is NULL SockPath is not changed.
101
* Returns: number of good sockets.
106
FindSocket(fdp, nfoundp, notherp, match)
108
int *nfoundp, *notherp;
118
int firsts = -1, sockfd;
120
int nfound = 0, ngood = 0, ndead = 0, nwipe = 0, npriv = 0;
126
} *slist, **slisttail, *sent, *nsent;
130
matchlen = strlen(match);
132
if (matchlen > NAME_MAX)
138
* SockPath contains the socket directory.
139
* At the end of FindSocket the socket name will be appended to it.
140
* Thus FindSocket() can only be called once!
142
sdirlen = strlen(SockPath);
149
if ((dirp = opendir(SockPath)) == 0)
150
Panic(errno, "Cannot opendir %s", SockPath);
154
while ((dp = readdir(dirp)))
157
debug1("- %s\n", name);
158
if (*name == 0 || *name == '.' || strlen(name) > 2*MAXSTR)
163
/* if we don't want to match digits. Skip them */
164
if ((*match <= '0' || *match > '9') && (*n > '0' && *n <= '9'))
166
while (*n >= '0' && *n <= '9')
171
/* the tty prefix is optional */
172
if (strncmp(match, "tty", 3) && strncmp(n, "tty", 3) == 0)
174
if (strncmp(match, n, matchlen))
176
debug1(" -> matched %s\n", match);
178
sprintf(SockPath + sdirlen, "/%s", name);
180
debug1("stat %s\n", SockPath);
182
debug2("uid = %d, gid = %d\n", getuid(), getgid());
183
debug2("euid = %d, egid = %d\n", geteuid(), getegid());
184
if (stat(SockPath, &st))
186
debug1("errno = %d\n", errno);
190
#ifndef SOCK_NOT_IN_FS
193
debug("S_ISFIFO?\n");
194
if (!S_ISFIFO(st.st_mode))
199
debug("S_ISSOCK?\n");
200
if (!S_ISSOCK(st.st_mode))
206
debug2("st.st_uid = %d, real_uid = %d\n", st.st_uid, real_uid);
207
if ((int)st.st_uid != real_uid)
209
mode = (int)st.st_mode & 0777;
210
debug1(" has mode 0%03o\n", mode);
212
if (multi && ((mode & 0677) != 0601))
214
debug(" is not a MULTI-USER session");
215
if (strcmp(multi, LoginName))
217
debug(" and we are in a foreign directory.\n");
222
debug(", but it is our own session.\n");
226
debug(" store it.\n");
227
if ((sent = (struct sent *)malloc(sizeof(struct sent))) == 0)
230
sent->name = SaveStr(name);
233
slisttail = &sent->next;
235
sockfd = MakeClientSocket(0);
237
/* MakeClientSocket sets ids back to eff */
243
debug2(" MakeClientSocket failed, unreachable? %d %d\n",
246
#ifndef SOCKDIR_IS_LOCAL_TO_HOST
247
/* Unreachable - it is dead if we detect that it's local
248
* or we specified a match
250
n = name + strlen(name) - 1;
251
while (n != name && *n != '.')
253
if (matchlen == 0 && !(*n == '.' && n[1] && strncmp(HostName, n + 1, strlen(n + 1)) == 0))
255
npriv++; /* a good socket that was not for us */
263
if (unlink(SockPath) == 0)
273
/* Shall we connect ? */
274
debug2(" connecting: mode=%03o, rflag=%d, ", mode, rflag);
275
debug2("xflag=%d, dflag=%d ?\n", xflag, dflag);
278
* mode 600: socket is detached.
279
* mode 700: socket is attached.
280
* xflag implies rflag here.
282
* fail, when socket mode mode is not 600 or 700
283
* fail, when we want to detach w/o reattach, but it already is detached.
284
* fail, when we only want to attach, but mode 700 and not xflag.
285
* fail, if none of dflag, rflag, xflag is set.
287
if ((mode != 0700 && mode != 0600) ||
288
(dflag && !rflag && !xflag && mode == 0600) ||
289
(!dflag && rflag && mode == 0700 && !xflag) ||
290
(!dflag && !rflag && !xflag))
294
npriv++; /* a good socket that was not for us */
298
if (fdp && firsts == -1)
306
debug(" discarded.\n");
310
(void)closedir(dirp);
311
if (nfound && (lsflag || ngood != 1) && !quietflag)
316
Msg(0, nfound > 1 ? "There are screens on:" : "There is a screen on:");
319
Msg(0, nfound > 1 ? "There are several screens on:" : "There is a suitable screen on:");
322
Msg(0, "There are several suitable screens on:");
325
for (sent = slist; sent; sent = sent->next)
330
printf("\t%s\t(Attached)\n", sent->name);
333
printf("\t%s\t(Detached)\n", sent->name);
337
printf("\t%s\t(Multi, attached)\n", sent->name);
340
printf("\t%s\t(Multi, detached)\n", sent->name);
344
/* No trigraphs here! */
345
printf("\t%s\t(Dead ?%c?)\n", sent->name, '?');
348
printf("\t%s\t(Removed)\n", sent->name);
351
printf("\t%s\t(Remote or dead)\n", sent->name);
354
printf("\t%s\t(Private)\n", sent->name);
359
if (ndead && !quietflag)
361
char *m = "Remove dead screens with 'screen -wipe'.";
363
Msg(0, "%d socket%s wiped out.", nwipe, nwipe > 1 ? "s" : "");
365
Msg(0, m, ndead > 1 ? "s" : "", ndead > 1 ? "" : "es"); /* other args for nethack */
369
sprintf(SockPath + sdirlen, "/%s", firstn);
373
SockPath[sdirlen] = 0;
374
for (sent = slist; sent; sent = nsent)
387
*nfoundp = nfound - nwipe;
394
** Socket/pipe create routines
410
if ((s = open(SockPath, O_WRONLY | O_NONBLOCK)) >= 0)
412
debug("huii, my fifo already exists??\n");
415
Kill(D_userpid, SIG_BYE);
418
Msg(0, "There is already a screen running on %s.", Filename(SockPath));
419
if (stat(SockPath, &st) == -1)
420
Panic(errno, "stat");
421
if ((int)st.st_uid != real_uid)
422
Panic(0, "Unfortunatelly you are not its owner.");
423
if ((st.st_mode & 0700) == 0600)
424
Panic(0, "To resume it, use \"screen -r\"");
426
Panic(0, "It is not detached.");
430
(void) unlink(SockPath);
431
if (mkfifo(SockPath, SOCKMODE))
432
Panic(0, "mkfifo %s failed", SockPath);
434
if ((s = open(SockPath, O_RDWR | O_NONBLOCK, 0)) < 0)
436
if ((s = open(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
438
Panic(errno, "open fifo %s", SockPath);
442
# else /* !USE_SETEUID */
443
if (UserContext() > 0)
445
(void) unlink(SockPath);
446
UserReturn(mkfifo(SockPath, SOCKMODE));
449
Panic(0, "mkfifo %s failed", SockPath);
451
if ((s = secopen(SockPath, O_RDWR | O_NONBLOCK, 0)) < 0)
453
if ((s = secopen(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
455
Panic(errno, "open fifo %s", SockPath);
457
# endif /* !USE_SETEUID */
462
MakeClientSocket(err)
467
if ((s = secopen(SockPath, O_WRONLY | O_NONBLOCK, 0)) >= 0)
469
(void) fcntl(s, F_SETFL, 0);
473
Msg(errno, "%s", SockPath);
474
debug2("MakeClientSocket() open %s failed (%d)\n", SockPath, errno);
479
#else /* NAMEDPIPE */
486
struct sockaddr_un a;
489
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
490
Panic(errno, "socket");
491
a.sun_family = AF_UNIX;
492
strncpy(a.sun_path, SockPath, sizeof(a.sun_path));
493
a.sun_path[sizeof(a.sun_path) - 1] = 0;
498
if (connect(s, (struct sockaddr *) &a, strlen(SockPath) + 2) != -1)
500
debug("oooooh! socket already is alive!\n");
503
Kill(D_userpid, SIG_BYE);
505
* oh, well. nobody receives that return code. papa
510
Msg(0, "There is already a screen running on %s.", Filename(SockPath));
511
if (stat(SockPath, &st) == -1)
512
Panic(errno, "stat");
513
if (st.st_uid != real_uid)
514
Panic(0, "Unfortunatelly you are not its owner.");
515
if ((st.st_mode & 0700) == 0600)
516
Panic(0, "To resume it, use \"screen -r\"");
518
Panic(0, "It is not detached.");
521
#if defined(m88k) || defined(sysV68)
522
close(s); /* we get bind: Invalid argument if this is not done */
523
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
524
Panic(errno, "reopen socket");
526
(void) unlink(SockPath);
527
if (bind(s, (struct sockaddr *) & a, strlen(SockPath) + 2) == -1)
528
Panic(errno, "bind (%s)", SockPath);
529
#ifdef SOCK_NOT_IN_FS
532
if ((f = secopen(SockPath, O_RDWR | O_CREAT, SOCKMODE)) < 0)
533
Panic(errno, "shadow socket open");
537
chmod(SockPath, SOCKMODE);
539
chown(SockPath, real_uid, real_gid);
541
#endif /* SOCK_NOT_IN_FS */
542
if (listen(s, 5) == -1)
543
Panic(errno, "listen");
545
fcntl(s, F_SETOWN, getpid());
546
debug1("Serversocket owned by %d\n", fcntl(s, F_GETOWN, 0));
547
# endif /* F_SETOWN */
556
MakeClientSocket(err)
560
struct sockaddr_un a;
562
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
563
Panic(errno, "socket");
564
a.sun_family = AF_UNIX;
565
strncpy(a.sun_path, SockPath, sizeof(a.sun_path));
566
a.sun_path[sizeof(a.sun_path) - 1] = 0;
571
if (access(SockPath, W_OK))
574
Msg(errno, "%s", SockPath);
575
debug2("MakeClientSocket: access(%s): %d.\n", SockPath, errno);
580
if (connect(s, (struct sockaddr *) &a, strlen(SockPath) + 2) == -1)
583
Msg(errno, "%s: connect", SockPath);
584
debug("MakeClientSocket: connect failed.\n");
594
#endif /* NAMEDPIPE */
599
** Message send and receive routines
604
SendCreateMsg(sty, nwin)
606
struct NewWindow *nwin;
612
char **av = nwin->args;
615
if (strlen(sty) > NAME_MAX)
618
if (strlen(sty) > 2 * MAXSTR - 1)
619
sty[2 * MAXSTR - 1] = 0;
620
sprintf(SockPath + strlen(SockPath), "/%s", sty);
621
if ((s = MakeClientSocket(1)) == -1)
623
debug1("SendCreateMsg() to '%s'\n", SockPath);
624
bzero((char *)&m, sizeof(m));
626
strncpy(m.m_tty, attach_tty, sizeof(m.m_tty) - 1);
627
m.m_tty[sizeof(m.m_tty) - 1] = 0;
630
if (nwin->args != nwin_undef.args)
631
for (av = nwin->args; *av && n < MAXARGS - 1; ++av, ++n)
633
len = strlen(*av) + 1;
634
if (p + len >= m.m.create.line + sizeof(m.m.create.line) - 1)
639
if (nwin->aka != nwin_undef.aka && p + strlen(nwin->aka) + 1 < m.m.create.line + sizeof(m.m.create.line))
640
strcpy(p, nwin->aka);
643
m.m.create.nargs = n;
644
m.m.create.aflag = nwin->aflag;
645
m.m.create.flowflag = nwin->flowflag;
646
m.m.create.lflag = nwin->lflag;
647
m.m.create.hheight = nwin->histheight;
648
if (getcwd(m.m.create.dir, sizeof(m.m.create.dir)) == 0)
650
Msg(errno, "getcwd");
653
if (nwin->term != nwin_undef.term)
654
strncpy(m.m.create.screenterm, nwin->term, 19);
655
m.m.create.screenterm[19] = '\0';
656
m.protocol_revision = MSG_REVISION;
657
debug1("SendCreateMsg writing '%s'\n", m.m.create.line);
658
if (write(s, (char *) &m, sizeof m) != sizeof m)
664
SendErrorMsg(tty, buf)
670
strncpy(m.m.message, buf, sizeof(m.m.message) - 1);
671
m.m.message[sizeof(m.m.message) - 1] = 0;
672
s = MakeClientSocket(0);
676
strncpy(m.m_tty, tty, sizeof(m.m_tty) - 1);
677
m.m_tty[sizeof(m.m_tty) - 1] = 0;
678
m.protocol_revision = MSG_REVISION;
679
debug1("SendErrorMsg(): writing to '%s'\n", SockPath);
680
(void) write(s, (char *) &m, sizeof m);
689
struct NewWindow nwin;
692
register char **pp = args, *p = mp->m.create.line;
695
n = mp->m.create.nargs;
698
/* ugly hack alert... should be done by the frontend! */
705
if (IsNumColon(p, 10, buf, sizeof(buf)))
710
if (num < 0 || num > MAXWIN - 1)
727
nwin.aflag = mp->m.create.aflag;
728
nwin.flowflag = mp->m.create.flowflag;
729
if (*mp->m.create.dir)
730
nwin.dir = mp->m.create.dir;
731
nwin.lflag = mp->m.create.lflag;
732
nwin.histheight = mp->m.create.hheight;
733
if (*mp->m.create.screenterm)
734
nwin.term = mp->m.create.screenterm;
742
debug1("Checking pid %d\n", pid);
745
if (eff_uid == real_uid)
747
if (UserContext() > 0)
748
UserReturn(kill(pid, 0));
754
* From: "F. K. Bruner" <napalm@ugcs.caltech.edu>
755
* From: "Dan Egnor" <egnor@oracorp.com> Tue Aug 10 06:56:45 1993
756
* The problem is that under HPUX (and possibly other systems too) there are
757
* two equivalent device files for each pty/tty device:
758
* /dev/ttyxx == /dev/pty/ttyxx
759
* /dev/ptyxx == /dev/ptym/ptyxx
760
* I didn't look into the exact specifics, but I've run across this problem
761
* before: Even if you open /dev/ttyxx as fds 0 1 & 2 for a process, if that
762
* process calls the system to determine its tty, it'll get /dev/pty/ttyxx.
764
* Earlier versions seemed to work -- wonder what they did.
770
if (strlen(s1) > 5) s1 += strlen(s1) - 5;
771
if (strlen(s2) > 5) s2 += strlen(s2) - 5;
772
return strcmp(s1, s2);
774
# define TTYCMP(a, b) ttycmp(a, b)
776
# define TTYCMP(a, b) strcmp(a, b)
785
int ns = ServerSocket;
789
struct display *next;
791
struct display *olddisplays = displays;
794
debug("Ha, there was someone knocking on my fifo??\n");
795
if (fcntl(ServerSocket, F_SETFL, 0) == -1)
796
Panic(errno, "BLOCK fcntl");
798
struct sockaddr_un a;
801
debug("Ha, there was someone knocking on my socket??\n");
802
if ((ns = accept(ns, (struct sockaddr *) &a, &len)) < 0)
804
Msg(errno, "accept");
807
#endif /* NAMEDPIPE */
813
len = read(ns, p, left);
814
if (len < 0 && errno == EINTR)
824
/* Reopen pipe to prevent EOFs at the select() call */
826
if ((ServerSocket = secopen(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
827
Panic(errno, "reopen fifo %s", SockPath);
829
serv_read.fd = ServerSocket;
843
if (left != sizeof(m))
844
Msg(0, "Message %d of %d bytes too small", left, (int)sizeof(m));
846
debug("No data on socket.\n");
849
if (m.protocol_revision != MSG_REVISION)
851
Msg(0, "Invalid message (magic 0x%08x).", m.protocol_revision);
855
debug2("*** RecMsg: type %d tty %s\n", m.type, m.m_tty);
856
for (display = displays; display; display = display->d_next)
857
if (TTYCMP(D_usertty, m.m_tty) == 0)
859
debug2("display: %s display %sfound\n", m.m_tty, display ? "" : "not ");
863
for (wi = windows; wi; wi = wi->w_next)
864
if (!TTYCMP(m.m_tty, wi->w_tty))
866
/* XXX: hmmm, rework this? */
867
display = wi->w_layer.l_cvlist ? wi->w_layer.l_cvlist->c_display : 0;
868
debug2("but window %s %sfound.\n", m.m_tty, display ? "" :
874
/* Remove the status to prevent garbage on the screen */
875
if (display && D_status)
878
if (display && !D_tcinited && m.type != MSG_HANGUP)
879
return; /* ignore messages for bad displays */
885
CheckScreenSize(1); /* Change fore */
889
* the window that issued the create message need not be an active
890
* window. Then we create the window without having a display.
891
* Resulting in another inactive window.
893
* Currently we enforce that at least one display exists. But why?
900
if (display && D_userpid != 0 && kill(D_userpid, 0) == 0)
901
break; /* Intruder Alert */
902
debug2("RecMsg: apid=%d,was %d\n", m.m.attach.apid, display ? D_userpid : 0);
906
if (CheckPid(m.m.attach.apid))
908
Msg(0, "Attach attempt with bad pid(%d)!", m.m.attach.apid);
911
if ((i = secopen(m.m_tty, O_RDWR | O_NONBLOCK, 0)) < 0)
913
Msg(errno, "Attach: Could not open %s!", m.m_tty);
914
Kill(m.m.attach.apid, SIG_BYE);
918
Kill(m.m.attach.apid, SIGCONT);
921
#if defined(ultrix) || defined(pyr) || defined(NeXT)
922
brktty(i); /* for some strange reason this must be done */
927
write(i, "Attaching from inside of screen?\n", 33);
929
Kill(m.m.attach.apid, SIG_BYE);
930
Msg(0, "Attach msg ignored: coming from inside.");
935
if (strcmp(m.m.attach.auser, LoginName))
936
if (*FindUserPtr(m.m.attach.auser) == 0)
938
write(i, "Access to session denied.\n", 26);
940
Kill(m.m.attach.apid, SIG_BYE);
941
Msg(0, "Attach: access denied for user %s.", m.m.attach.auser);
946
debug2("RecMsg: apid %d is o.k. and we just opened '%s'\n", m.m.attach.apid, m.m_tty);
950
write(i, "Screen session in use.\n", 23);
952
Kill(m.m.attach.apid, SIG_BYE);
957
/* create new display */
959
if (MakeDisplay(m.m.attach.auser, m.m_tty, m.m.attach.envterm, i, m.m.attach.apid, &Mode) == 0)
961
write(i, "Could not make display.\n", 24);
963
Msg(0, "Attach: could not make display for user %s", m.m.attach.auser);
964
Kill(m.m.attach.apid, SIG_BYE);
969
D_encoding = m.m.attach.encoding == 1 ? UTF8 : m.m.attach.encoding ? m.m.attach.encoding - 1 : 0;
971
D_encoding = m.m.attach.encoding ? m.m.attach.encoding - 1 : 0;
973
if (D_encoding < 0 || !EncodingName(D_encoding))
976
/* turn off iflag on a multi-attach... */
977
if (iflag && olddisplays)
980
#if defined(TERMIO) || defined(POSIX)
981
olddisplays->d_NewMode.tio.c_cc[VINTR] = VDISABLE;
982
olddisplays->d_NewMode.tio.c_lflag &= ~ISIG;
983
#else /* TERMIO || POSIX */
984
olddisplays->d_NewMode.m_tchars.t_intrc = -1;
985
#endif /* TERMIO || POSIX */
986
SetTTY(olddisplays->d_userfd, &olddisplays->d_NewMode);
988
SetMode(&D_OldMode, &D_NewMode, D_flow, iflag);
989
SetTTY(D_userfd, &D_NewMode);
990
if (fcntl(D_userfd, F_SETFL, FNBLOCK))
991
Msg(errno, "Warning: NBLOCK fcntl failed");
994
if (D_user->u_password && *D_user->u_password)
1001
Msg(0, "%s", m.m.message);
1004
if (!wi) /* ignore hangups from inside */
1007
#ifdef REMOTE_DETACH
1010
case MSG_POW_DETACH:
1011
# endif /* POW_DETACH */
1012
for (display = displays; display; display = next)
1014
next = display->d_next;
1016
if (m.type == MSG_POW_DETACH)
1017
Detach(D_REMOTE_POWER);
1019
# endif /* POW_DETACH */
1020
if (m.type == MSG_DETACH)
1029
Msg(0, "Invalid message (type %d).", m.type);
1033
#if defined(_SEQUENT_) && !defined(NAMEDPIPE)
1036
* sequent_ptx socket emulation must have mode 000 on the socket!
1039
sconnect(s, sapp, len)
1041
struct sockaddr *sapp;
1043
register struct sockaddr_un *sap;
1047
sap = (struct sockaddr_un *)sapp;
1048
if (stat(sap->sun_path, &st))
1050
chmod(sap->sun_path, 0);
1051
x = connect(s, (struct sockaddr *) sap, len);
1052
chmod(sap->sun_path, st.st_mode);
1059
* Set the mode bits of the socket to the current status
1064
int r, euid = geteuid();
1065
if (euid != real_uid)
1067
if (UserContext() <= 0)
1068
return UserStatus();
1070
r = chmod(SockPath, SOCKMODE);
1072
* Sockets usually reside in the /tmp/ area, where sysadmin scripts
1073
* may be happy to remove old files. We manually prevent the socket
1074
* from becoming old. (chmod does not touch mtime).
1076
(void)utimes(SockPath, NULL);
1078
if (euid != real_uid)
1084
* Try to recreate the socket/pipe
1089
close(ServerSocket);
1090
if ((int)geteuid() != real_uid)
1092
if (UserContext() > 0)
1093
UserReturn(unlink(SockPath));
1097
(void) unlink(SockPath);
1099
if ((ServerSocket = MakeServerSocket()) < 0)
1102
serv_read.fd = ServerSocket;
1120
#if defined(pyr) || defined(xelos) || defined(sequent)
1122
* Kludge for systems with braindamaged termcap routines,
1123
* which evaluate $TERMCAP, regardless weather it describes
1124
* the correct terminal type or not.
1126
debug("unsetenv(TERMCAP) in case of a different terminal");
1127
unsetenv("TERMCAP");
1131
* We reboot our Terminal Emulator. Forget all we knew about
1132
* the old terminal, reread the termcap entries in .screenrc
1133
* (and nothing more from .screenrc is read. Mainly because
1134
* I did not check, weather a full reinit is safe. jw)
1135
* and /etc/screenrc, and initialise anew.
1141
extra_incap = extra_outcap = 0;
1142
debug2("Message says size (%dx%d)\n", m->m.attach.columns, m->m.attach.lines);
1144
# ifdef ALLOW_SYSSCREENRC
1145
if ((p = getenv("SYSSCREENRC")))
1149
StartRc(ETCSCREENRC);
1151
StartRc(RcFileName);
1152
if (InitTermcap(m->m.attach.columns, m->m.attach.lines))
1158
MakeDefaultCanvas();
1159
InitTerm(m->m.attach.adaptflag); /* write init string on fd */
1160
if (displays->d_next == 0)
1162
signal(SIGHUP, SigHup);
1163
if (m->m.attach.esc != -1 && m->m.attach.meta_esc != -1)
1165
D_user->u_Esc = m->m.attach.esc;
1166
D_user->u_MetaEsc = m->m.attach.meta_esc;
1171
* we set the Utmp slots again, if we were detached normally
1172
* and if we were detached by ^Z.
1173
* don't log zomies back in!
1176
if (displays->d_next == 0)
1177
for (wi = windows; wi; wi = wi->w_next)
1178
if (wi->w_ptyfd >= 0 && wi->w_slot != (slot_t) -1)
1184
* there may be a window that we remember from last detach:
1186
debug1("D_user->u_detachwin = %d\n", D_user->u_detachwin);
1187
if (D_user->u_detachwin >= 0)
1188
fore = wtab[D_user->u_detachwin];
1192
/* Wayne wants us to restore the other window too. */
1193
if (D_user->u_detachotherwin >= 0)
1194
D_other = wtab[D_user->u_detachotherwin];
1197
if (*m->m.attach.preselect)
1199
if (!strcmp(m->m.attach.preselect, "="))
1201
else if (!strcmp(m->m.attach.preselect, "-"))
1207
fore = FindNiceWindow(fore, m->m.attach.preselect);
1210
fore = FindNiceWindow(fore, 0);
1212
SetForeWindow(fore);
1213
else if (!noshowwin)
1216
if (!AclCheckPermCmd(D_user, ACL_EXEC, &comms[RC_WINDOWLIST]))
1219
flayer = D_forecv->c_layer;
1220
display_wlist(1, WLIST_NUM);
1226
if (!D_fore && !noshowwin)
1228
if (displays->d_next == 0 && console_window)
1230
if (TtyGrabConsole(console_window->w_ptyfd, 1, "reattach") == 0)
1231
Msg(0, "console %s is on window %d", HostName, console_window->w_number);
1233
debug("activated...\n");
1235
# if defined(DEBUG) && defined(SIG_NODEBUG)
1239
debug1("Attacher %d must not debug, as we have debug off.\n", pid);
1240
kill(pid, SIG_NODEBUG);
1242
# endif /* SIG_NODEBUG */
1247
static void PasswordProcessInput __P((char *, int));
1259
struct pwdata *pwdata;
1261
pwdata = (struct pwdata *)malloc(sizeof(struct pwdata));
1266
D_processinputdata = (char *)pwdata;
1267
D_processinput = PasswordProcessInput;
1268
AddStr("Screen password: ");
1272
PasswordProcessInput(ibuf, ilen)
1276
struct pwdata *pwdata;
1279
int pid = D_userpid;
1281
pwdata = (struct pwdata *)D_processinputdata;
1285
c = *(unsigned char *)ibuf++;
1286
if (c == '\r' || c == '\n')
1288
up = D_user->u_password;
1290
if (strncmp(crypt(pwdata->buf, up), up, strlen(up)))
1292
/* uh oh, user failed */
1293
bzero(pwdata->buf, sizeof(pwdata->buf));
1294
AddStr("\r\nPassword incorrect.\r\n");
1295
D_processinputdata = 0; /* otherwise freed by FreeDis */
1297
Msg(0, "Illegal reattach attempt from terminal %s.", pwdata->m.m_tty);
1302
/* great, pw matched, all is fine */
1303
bzero(pwdata->buf, sizeof(pwdata->buf));
1305
D_processinputdata = 0;
1306
D_processinput = ProcessInput;
1307
FinishAttach(&pwdata->m);
1318
if (c == '\b' || c == 0177)
1329
if (l < (int)sizeof(pwdata->buf) - 1)
1330
pwdata->buf[l++] = c;
1340
char *args[MAXARGS];
1343
register char **pp = args, *p = mp->m.command.cmd;
1344
struct acluser *user;
1346
extern struct acluser *EffectiveAclUser; /* acls.c */
1348
extern struct acluser *users; /* acls.c */
1352
n = mp->m.command.nargs;
1353
if (n > MAXARGS - 1)
1363
user = *FindUserPtr(mp->m.attach.auser);
1366
Msg(0, "Unknown user %s tried to send a command!", mp->m.attach.auser);
1373
if (user->u_password && *user->u_password)
1375
Msg(0, "User %s has a password, cannot use -X option.", mp->m.attach.auser);
1380
for (display = displays; display; display = display->d_next)
1383
for (fore = windows; fore; fore = fore->w_next)
1384
if (!TTYCMP(mp->m_tty, fore->w_tty))
1387
display = fore->w_layer.l_cvlist ? fore->w_layer.l_cvlist->c_display : 0;
1391
display = displays; /* sigh */
1392
if (*mp->m.command.preselect)
1395
if (strcmp(mp->m.command.preselect, "-"))
1396
i = WindowByNoN(mp->m.command.preselect);
1397
fore = i >= 0 ? wtab[i] : 0;
1401
if (display && D_user == user)
1402
fore = Layer2Window(display->d_forecv->c_layer);
1405
fore = user->u_detachwin >= 0 ? wtab[user->u_detachwin] : 0;
1406
fore = FindNiceWindow(fore, 0);
1410
EffectiveAclUser = user;
1414
char *oldrcname = rc_name;
1416
debug3("Running command on display %x window %x (%d)\n", display, fore, fore ? fore->w_number : -1);
1417
flayer = fore ? &fore->w_layer : 0;
1418
if (fore && fore->w_savelayer && (fore->w_blocked || fore->w_savelayer->l_cvlist == 0))
1419
flayer = fore->w_savelayer;
1420
DoCommand(args, argl);
1421
rc_name = oldrcname;
1424
EffectiveAclUser = 0;