Wed Jun 26 16:58:14 2002 Michael Jennings (mej)
Latest Escreen stuff from Azundris, including work on twin support (twin.sourceforge.net). SVN revision: 6330
This commit is contained in:
parent
5cc41f7340
commit
ec34068f82
|
@ -4730,3 +4730,8 @@ Thu Jun 20 18:55:59 2002 Michael Jennings (mej)
|
|||
|
||||
Better fix from Azundris.
|
||||
----------------------------------------------------------------------
|
||||
Wed Jun 26 16:58:14 2002 Michael Jennings (mej)
|
||||
|
||||
Latest Escreen stuff from Azundris, including work on twin support
|
||||
(twin.sourceforge.net).
|
||||
----------------------------------------------------------------------
|
||||
|
|
33
configure.in
33
configure.in
|
@ -361,12 +361,40 @@ AC_MSG_CHECKING(for Escreen support)
|
|||
AC_ARG_ENABLE(escreen,
|
||||
[ --enable-escreen enable Eterm's built-in screen support], [
|
||||
if test "$enableval" = "yes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(ESCREEN)
|
||||
AC_CHECK_PROG(FOUND_SCREEN, screen, screen)
|
||||
if test ! -z "$FOUND_SCREEN"; then
|
||||
AC_DEFINE(NS_HAVE_SCREEN,1,[Support the GNU screen text windowing system?])
|
||||
else
|
||||
AC_WARN(*** screen support has been disabled because screen was not found ***)
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi], AC_MSG_RESULT(no)
|
||||
)
|
||||
AC_MSG_CHECKING(for Etwin support)
|
||||
AC_ARG_ENABLE(etwin,
|
||||
[ --enable-etwin enable Eterm's built-in twin support], [
|
||||
if test "$enableval" = "yes"; then
|
||||
AC_CHECK_LIB(Tw, Tw_Open, FOUND_LIBTWIN=1, FOUND_LIBTWIN=0, $GRLIBS)
|
||||
if test "$FOUND_LIBTWIN" -ne "1"; then
|
||||
AC_WARN(*** Twin support has been disabled because libTw was not found ***)
|
||||
else
|
||||
AC_DEFINE(NS_HAVE_TWIN,1,[Support the twin text windowing system?])
|
||||
LIBS="$LIBS -lTw"
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi], AC_MSG_RESULT(no)
|
||||
)
|
||||
|
||||
if test ! -z "FOUND_$SCREEN" || ! -z "$FOUND_LIBTWIN"; then
|
||||
AC_DEFINE(ESCREEN)
|
||||
fi
|
||||
|
||||
if test ! -z "FOUND_$SCREEN" || ! -z "$FOUND_LIBTWIN"; then
|
||||
AC_DEFINE(ESCREEN)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(if profiling macros should be included)
|
||||
AC_ARG_ENABLE(profile,
|
||||
[ --enable-profile compile with code profiling macros enabled], [
|
||||
|
@ -866,6 +894,7 @@ AC_ARG_WITH(sense-of-humor, [ --without-sense-of-humor Specify this if you ha
|
|||
if test -z "$HUMOR"; then
|
||||
AC_CHECK_LIB(Kenny, life_signs, , [
|
||||
echo " Oh my god, they killed Kenny! You bastards!"
|
||||
AC_DEFINE(HAVE_HUMOR,1,[Does user have a sense of humour?])
|
||||
])
|
||||
fi
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
| _/ ___ \ |_| | _ _ | |___\__ \ (__| | | __/ __/ | | |
|
||||
|_|/_/ \_\__\_\ (_|_) |_____|___/\___|_| \___|\___|_| |_|
|
||||
|
||||
Frequently Asked Questions about the Eterm "Escreen" extension
|
||||
Frequently Asked Questions about the "Escreen/Etwin" extension
|
||||
|
||||
|
||||
|
||||
|
@ -86,22 +86,21 @@ A An Eterm should open with a screen (without a status-line) running
|
|||
|
||||
Q What's new?
|
||||
|
||||
* Dialog boxes now longer block the entire GUI (only Eterm's).
|
||||
* libscream's functions are available through Eterm's scripting
|
||||
facility. See escreen.cfg for an example.
|
||||
|
||||
* Display-closing has a dialog-box now.
|
||||
* Preliminary Twin support. For now, Twin-URLs (Eterm -U twin://)
|
||||
and Twin's mouse-protocol are supported, allowing you start twin
|
||||
within Eterm (making it the only terminal emulator to support Twin,
|
||||
AFAIK). Next release should feature Twin support through libscream
|
||||
(thus exposing Twin to button- and key-bindings through Eterm's
|
||||
scripting interface).
|
||||
|
||||
* Code clean-up. It's actually understandable now.
|
||||
(You can also compile libscream w/o support for screen now. : )
|
||||
|
||||
* Logs debug info through libast now if it available
|
||||
|
||||
* Fix for scrollbar (reported by mej).
|
||||
|
||||
* Fix for remote sessions with no corresponding local user
|
||||
(reported by tfing).
|
||||
For more information on Twin see
|
||||
http://freshmeat.net/projects/twin/?topic_id=158
|
||||
|
||||
* Tear-off tabs. You can select the button-representation of a
|
||||
display and drag-and-drop it
|
||||
display and drag-and-drop it [currently under reconstruction]
|
||||
|
||||
- to another button:
|
||||
|
||||
|
@ -123,9 +122,6 @@ Q What should I expect in the future? (TODO)
|
|||
* Limited support for scrolling. screen doesn't give us all the info
|
||||
we'd need to make this really sexy.
|
||||
|
||||
* Possibly support for enhanced screen-clones (like the perchance
|
||||
forthcoming "scream").
|
||||
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
@ -142,7 +138,7 @@ A If you call it an Eterm, it will behave like one. Same for an Escreen.
|
|||
(you'd have to symlink from Escreen to Eterm first, of course).
|
||||
Additionally, when called with a command-line (-e "/some/program"), the
|
||||
suite will *always* behave like an Eterm, even if invoked as Escreen.
|
||||
Likewise, when called with an URL (-U "screen://user@some.host.gov/"),
|
||||
Likewise, when called with an URL (-U screen://user@some.host.gov/),
|
||||
it will behave like an Escreen, even if invoked under another name.
|
||||
|
||||
|
||||
|
@ -154,7 +150,7 @@ A Before you complain:
|
|||
* Take a deep breath, remember you didn't pay for this.
|
||||
|
||||
* Check whether you are using the latest version. Support for each
|
||||
version stops with the release of a new one!
|
||||
version ceases with the release of a new one!
|
||||
|
||||
* Read all of the FAQ, your question may be answered in there.
|
||||
Remember that the FAQ grows with almost each release, so re-reading
|
||||
|
@ -201,9 +197,10 @@ A Well, yes. ^A talks to the screen program. Put a line
|
|||
to press to send the escape (^A in the example) to the application
|
||||
instead); you'll want to put something else to move it around.
|
||||
See "man screen" for details.
|
||||
2002/05/13 note that ^A: opens a buffer where you can directly enter
|
||||
statements like "escape ^Uu"; trying things out will be
|
||||
easier that way. yes, it will be ^U: afterwards. ; )
|
||||
|
||||
Note that ^A: opens a buffer where you can directly enter
|
||||
statements like "escape ^Uu"; trying things out will be
|
||||
easier that way. Yes, it the magic key will be ^U: afterwards. ; )
|
||||
|
||||
|
||||
|
||||
|
@ -230,7 +227,7 @@ Q Escreen changes the escape on the remote box to the same thing as on
|
|||
|
||||
A You can always override the escapes like so:
|
||||
|
||||
Eterm -U user@host.com/-e^Xy
|
||||
Eterm -U screen://user@host.com/-e^Xy
|
||||
|
||||
Where ^X is the escape and y the literal (man screen).
|
||||
|
||||
|
|
|
@ -1090,10 +1090,19 @@ bbar_draw(buttonbar_t *bbar, unsigned char image_state, unsigned char force_mode
|
|||
GC gc; /* evil temporary hack */
|
||||
int f = button->flags & ~NS_SCREAM_BUTTON;
|
||||
|
||||
if (f & NS_SCREAM_CURR) {
|
||||
f = 1;
|
||||
} else if (f & NS_SCREAM_ACT) {
|
||||
f = 2;
|
||||
} else {
|
||||
f = 0;
|
||||
}
|
||||
|
||||
gc = LIBAST_X_CREATE_GC(0, NULL);
|
||||
XCopyGC(Xdisplay, bbar->gc, GCFont, gc);
|
||||
XSetForeground(Xdisplay, gc, PixColors[minBright + f + 2]);
|
||||
|
||||
D_BBAR(("bbar_draw: text \"%s\", colour %d.\n", button->text, f));
|
||||
if (f) {
|
||||
draw_string(bbar, bbar->bg, gc, button->text_x, button->text_y, button->text, button->len);
|
||||
LIBAST_X_FREE_GC(gc);
|
||||
|
|
|
@ -2471,6 +2471,7 @@ upd_disp(void *xd, int n, int flags, char *name)
|
|||
/* Update flags */
|
||||
if (flags >= 0) {
|
||||
button->flags = (flags | NS_SCREAM_BUTTON);
|
||||
D_ESCREEN(("upd_disp: new flags for \"%s\": %d\n", button->text, flags));
|
||||
}
|
||||
|
||||
/* Redraw buttonbar to reflect new information */
|
||||
|
@ -2571,6 +2572,7 @@ exe_prg(void *xd, char **argv)
|
|||
|
||||
/****** Azundris' playthings :-) ******/
|
||||
|
||||
#ifdef HAVE_HUMOR
|
||||
#define DIRECT_MASK (~(RS_Cursor|RS_Select|RS_fontMask))
|
||||
#define COLOUR_MASK (RS_fgMask|RS_bgMask)
|
||||
#define DIRECT_SET_SCREEN(x,y,fg,bg) (screen.text[ys+y])[x]=fg; (screen.rend[ys+y])[x]=bg&DIRECT_MASK;
|
||||
|
@ -2761,6 +2763,7 @@ waitstate(void *xd, int ms)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static _ns_efuns *
|
||||
escreen_reg_funcs(void)
|
||||
|
@ -2790,7 +2793,9 @@ escreen_reg_funcs(void)
|
|||
ns_register_inp(efuns, input_dialog);
|
||||
ns_register_tab(efuns, menu_tab);
|
||||
|
||||
#ifdef HAVE_HUMOR
|
||||
ns_register_fun(efuns, waitstate);
|
||||
#endif
|
||||
|
||||
return efuns;
|
||||
}
|
||||
|
@ -2798,15 +2803,22 @@ escreen_reg_funcs(void)
|
|||
static int
|
||||
make_escreen_menu(buttonbar_t *bbar)
|
||||
{
|
||||
static int been_here = 0;
|
||||
button_t *button;
|
||||
menu_t *m;
|
||||
menuitem_t *i;
|
||||
|
||||
if (been_here) { /* the start function may be called more than once */
|
||||
return 0; /* in later versions, but we only want one EScreen menu */
|
||||
}
|
||||
|
||||
been_here = 1;
|
||||
|
||||
if ((m = menu_create(NS_MENU_TITLE))) {
|
||||
char *sc[] = {
|
||||
/* display functions */
|
||||
"New", "es_display(new)", /* \x01:screen\r */
|
||||
"New (w/ name)...", "es_display(new,ask)",
|
||||
"New", "es_display(new)", /* \x01:screen\r */
|
||||
"New...", "es_display(new,ask)",
|
||||
"Rename...", "es_display(name,ask)",
|
||||
"Backlog...", "es_display(backlog)",
|
||||
"Monitor", "es_display(monitor)",
|
||||
|
@ -2815,7 +2827,7 @@ make_escreen_menu(buttonbar_t *bbar)
|
|||
/* region functions */
|
||||
"Split", "es_region(new)",
|
||||
"Unsplit", "es_region(full)",
|
||||
"Prev region", "es_region(prev)", /* NS_SCREEN_PRVS_REG */
|
||||
"Prev region", "es_region(prev)", /* NS_SCREEN_PRVS_REG */
|
||||
"Next region", "es_region(next)",
|
||||
"Kill region", "es_region(kill)",
|
||||
"-", "",
|
||||
|
@ -2883,7 +2895,7 @@ escreen_init(char **argv)
|
|||
_ns_efuns *efuns;
|
||||
buttonbar_t *bbar;
|
||||
|
||||
if (!TermWin.screen_mode) {
|
||||
if (TermWin.screen_mode == NS_MODE_NONE) {
|
||||
return run_command(argv);
|
||||
}
|
||||
|
||||
|
@ -2905,7 +2917,8 @@ escreen_init(char **argv)
|
|||
bbar_add(bbar);
|
||||
}
|
||||
|
||||
if ((TermWin.screen = ns_attach_by_URL(rs_url, rs_hop, &efuns, &ns_err, bbar)) == 0) {
|
||||
if ((TermWin.screen = ns_attach_by_URL(rs_url, rs_hop, &efuns, &ns_err, bbar)) == NULL) {
|
||||
D_CMD(("ns_attach_by_URL(%s,%s) failed\n", rs_url, rs_hop));
|
||||
return -1;
|
||||
}
|
||||
if (rs_delay >= 0) {
|
||||
|
@ -2920,6 +2933,7 @@ escreen_init(char **argv)
|
|||
parent_resize();
|
||||
|
||||
/* add_screen_ctl_button(bbar,"New",'c'); */
|
||||
D_CMD(("TermWin.screen->fd = %d\n", TermWin.screen->fd));
|
||||
return TermWin.screen->fd;
|
||||
}
|
||||
#endif
|
||||
|
@ -2963,7 +2977,7 @@ init_command(char **argv)
|
|||
AT_LEAST((int) num_fds, pipe_fd + 1);
|
||||
}
|
||||
if ((cmd_fd = command_func(argv)) < 0) {
|
||||
print_error("aborting\n");
|
||||
print_error("Unable to run sub-command.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
@ -3140,15 +3154,19 @@ cmd_getc(void)
|
|||
# ifdef NS_HAVE_TWIN
|
||||
case NS_MODE_TWIN:
|
||||
if (!TermWin.screen->twin) {
|
||||
if (!Tw_CheckMagic(libscream_magic)) {
|
||||
D_ESCREEN(("ns_attach_by_sess: Tw_CheckMagic failed\n"));
|
||||
TermWin.screen->backend = TermWin.screen_mode = NS_MODE_NONE;
|
||||
} else {
|
||||
if (!(TermWin.screen->twin = Tw_Open(TermWin.screen->twin_str))) {
|
||||
D_ESCREEN(("ns_attach_by_sess: Tw_Open(%s) failed\n", TermWin.screen->twin_str));
|
||||
if (!TermWin.screen->timestamp) {
|
||||
TermWin.screen->timestamp = time(NULL);
|
||||
} else if (TermWin.screen->timestamp < time(NULL)) {
|
||||
if (!Tw_CheckMagic(libscream_magic)) {
|
||||
D_ESCREEN(("ns_attach_by_sess: Tw_CheckMagic failed\n"));
|
||||
TermWin.screen->backend = TermWin.screen_mode = NS_MODE_NONE;
|
||||
} else {
|
||||
D_ESCREEN(("ns_attach_by_sess: Tw_Open(%s) succeeded\n", TermWin.screen->twin_str));
|
||||
if (!(TermWin.screen->twin = Tw_Open(TermWin.screen->twin_str))) {
|
||||
ns_desc_twin(TermWin.screen, "cmd_getc->Tw_Open");
|
||||
TermWin.screen->backend = TermWin.screen_mode = NS_MODE_NONE;
|
||||
} else {
|
||||
D_ESCREEN(("ns_attach_by_sess: Tw_Open(%s) succeeded: handle @ %p\n", TermWin.screen->twin_str, TermWin.screen->twin));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
419
src/libscream.c
419
src/libscream.c
|
@ -19,6 +19,7 @@
|
|||
* 2002/05/21 Azundris code restructuring, basic tab tear-off
|
||||
* 2002/06/04 Azundris advanced tab tear-off
|
||||
* 2002/06/05 Azundris basic twin support
|
||||
* 2002/06/11 Azundris more twin support
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
@ -61,6 +62,7 @@
|
|||
#ifdef NS_HAVE_TWIN
|
||||
# include <Tw/Tw.h>
|
||||
# include <Tw/Tw_1.h>
|
||||
# include <Tw/Twerrno.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
|
@ -387,6 +389,8 @@ ns_new_sess(void)
|
|||
s->dsbb = NS_SCREEN_DEFSBB;
|
||||
s->delay = NS_INIT_DELAY;
|
||||
s->fd = -1;
|
||||
s->disp = -1;
|
||||
s->port = -1;
|
||||
if (sa) { /* add to end of list */
|
||||
_ns_sess *r = sa;
|
||||
|
||||
|
@ -632,6 +636,28 @@ ns_sess_init(_ns_sess * sess)
|
|||
|
||||
|
||||
|
||||
/* return port number for service TWIN.
|
||||
<- a port number -- 7754 in all likelihood. */
|
||||
|
||||
int
|
||||
ns_get_twin_port(void)
|
||||
{
|
||||
#ifdef NS_HAVE_TWIN
|
||||
static int port = 0;
|
||||
struct servent *srv;
|
||||
|
||||
if (port)
|
||||
return port;
|
||||
/* (fixme) replace with getservbyname_r on systems that have it */
|
||||
srv = getservbyname("twin", "tcp");
|
||||
return (port = (srv ? ntohs(srv->s_port) : TW_INET_PORT));
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* return port number for service SSH (secure shell).
|
||||
<- a port number -- 22 in all likelihood. */
|
||||
|
||||
|
@ -755,6 +781,28 @@ ns_desc_string(char *c, char *doc)
|
|||
|
||||
|
||||
|
||||
/* ns_desc_twin
|
||||
print status of a twin session
|
||||
sess the session
|
||||
doc info about the context
|
||||
!stderr info about the twin session */
|
||||
|
||||
void
|
||||
ns_desc_twin(_ns_sess * sess, char *doc)
|
||||
{
|
||||
#ifdef HAVE_TWIN
|
||||
if (!sess) {
|
||||
D_ESCREEN(("%s: ns_desc_twin called with broken pointer!\n", doc ? doc : ""));
|
||||
return;
|
||||
}
|
||||
D_ESCREEN(("%s: twin status (%s) is %d-%s, %d-%s\n", doc, sess->twin_str,
|
||||
Tw_Errno(sess->twin),
|
||||
Tw_StrError(sess->twin, Tw_Errno(sess->twin)), Tw_ErrnoDetail(sess->twin), Tw_StrErrorDetail(sess->twin, Tw_Errno(sess->twin), Tw_ErrnoDetail(sess->twin))));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ns_desc_hop
|
||||
print basic info about a hop (tunnel, firewall). mostly for debugging.
|
||||
hop: a hop struct as generated by (eg) ns_attach_by_URL()
|
||||
|
@ -764,8 +812,8 @@ ns_desc_string(char *c, char *doc)
|
|||
static void
|
||||
ns_desc_hop(_ns_hop * h, char *doc)
|
||||
{
|
||||
if (!h && doc) {
|
||||
D_ESCREEN(("%s: ns_desc_hop called with broken pointer!\n", doc));
|
||||
if (!h) {
|
||||
D_ESCREEN(("%s: ns_desc_hop called with broken pointer!\n", doc ? doc : ""));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -788,16 +836,18 @@ static void
|
|||
ns_desc_sess(_ns_sess * sess, char *doc)
|
||||
{
|
||||
if (!sess) {
|
||||
D_ESCREEN(("%s: ns_desc_sess called with broken pointer!\n", doc));
|
||||
D_ESCREEN(("%s: ns_desc_sess called with broken pointer!\n", doc ? doc : ""));
|
||||
return;
|
||||
}
|
||||
if (sess->where == NS_LCL)
|
||||
D_ESCREEN(("%s: (efuns@%p)\t (user %s) local %s %s\n", doc, sess->efuns, sess->user, sess->proto, sess->rsrc));
|
||||
D_ESCREEN(("%s: (efuns@%p)\t (user %s) local %s", doc, sess->efuns, sess->user, sess->proto));
|
||||
else {
|
||||
D_ESCREEN(("%s: (efuns@%p)\t %s://%s%s%s@%s:%s/%s\n",
|
||||
doc, sess->efuns, sess->proto ? sess->proto : "???", sess->user, sess->pass ? ":" : "", sess->pass ? sess->pass : "", sess->host,
|
||||
sess->port, sess->rsrc));
|
||||
D_ESCREEN(("%s: (efuns@%p)\t %s://%s%s%s@%s",
|
||||
doc, sess->efuns, sess->proto ? sess->proto : "???", sess->user, sess->pass ? ":" : "", sess->pass ? sess->pass : "", sess->host));
|
||||
if (sess->port != NS_DFLT_SSH_PORT)
|
||||
D_ESCREEN((":%s", sess->port));
|
||||
}
|
||||
D_ESCREEN(("%c%s\n", sess->where == NS_LCL ? ' ' : '/', sess->rsrc));
|
||||
if (sess->hop)
|
||||
ns_desc_hop(sess->hop, NULL);
|
||||
if (sess->sysrc)
|
||||
|
@ -1088,23 +1138,6 @@ ns_attach_by_sess(_ns_sess ** sp, int *err)
|
|||
|
||||
D_ESCREEN(("ns_attach_by_sess: screen session-fd is %d, ^%c-%c\n", sess->fd, sess->escape + 'A' - 1, sess->literal));
|
||||
|
||||
#ifdef NS_HAVE_TWIN_
|
||||
if (sess->backend == NS_MODE_TWIN) {
|
||||
sleep(2);
|
||||
if (!Tw_CheckMagic(libscream_magic)) {
|
||||
D_ESCREEN(("ns_attach_by_sess: Tw_CheckMagic failed\n"));
|
||||
goto fail;
|
||||
} else {
|
||||
if (!(sess->twin = Tw_Open(sess->twin_str))) {
|
||||
D_ESCREEN(("ns_attach_by_sess: Tw_Open(%s) failed\n", sess->twin_str));
|
||||
goto fail;
|
||||
}
|
||||
D_ESCREEN(("ns_attach_by_sess: Tw_Open() succeeded\n"));
|
||||
ns_desc_sess(sess, "ns_sess_init");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return sess;
|
||||
|
||||
fail:
|
||||
|
@ -1145,18 +1178,22 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
|
|||
err = &err_dummy;
|
||||
*err = NS_OOM;
|
||||
|
||||
if (!sess)
|
||||
if (!sess) {
|
||||
D_ESCREEN(("ns_attach_by_URL: no session...\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
D_ESCREEN(("ns_attach_by_URL(%s,%s,%p,%p,%p)\n", url, hop, *ef, err, xd));
|
||||
|
||||
if (url && strlen(url)) {
|
||||
char *q;
|
||||
|
||||
if (!(d = STRDUP(url)))
|
||||
if (!(d = strdup(url)))
|
||||
goto fail;
|
||||
|
||||
if ((q = strstr(d, "://"))) { /* protocol, if any */
|
||||
*q = '\0';
|
||||
if (!(sess->proto = STRDUP(d)))
|
||||
if (!(sess->proto = strdup(d)))
|
||||
goto fail;
|
||||
q += 3;
|
||||
} else
|
||||
|
@ -1169,15 +1206,15 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
|
|||
*p = '\0';
|
||||
if ((r = strchr(q, ':'))) { /* password, if any */
|
||||
*(r++) = '\0';
|
||||
if (!(sess->pass = STRDUP(r))) /* password may be empty string! */
|
||||
if (!(sess->pass = strdup(r))) /* password may be empty string! */
|
||||
goto fail;
|
||||
}
|
||||
sess->user = STRDUP(q);
|
||||
sess->user = strdup(q);
|
||||
}
|
||||
q = p + 1;
|
||||
}
|
||||
|
||||
if ((p = strchr(q, '/'))) {
|
||||
if ((p = strchr(q, '/'))) { /* rsrc, possibly url-encoded */
|
||||
*(p++) = '\0';
|
||||
if (strlen(p)) {
|
||||
char *r = p;
|
||||
|
@ -1210,6 +1247,25 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
|
|||
r++;
|
||||
} else {
|
||||
if (*r == '-') {
|
||||
# ifdef NS_HAVE_TWIN
|
||||
if (!strncmp(NS_TWIN_PARA, &r[1], strlen(NS_TWIN_PARA))) {
|
||||
char *y = strchr(r, '@');
|
||||
|
||||
if (y && *++y) {
|
||||
char *z = strchr(y, ':');
|
||||
|
||||
if (z) {
|
||||
*z++ = '\0';
|
||||
if (*z)
|
||||
sess->disp = atoi(z);
|
||||
if (sess->disp < 0 || sess->disp > NS_MAX_PORT)
|
||||
sess->disp = 0;
|
||||
}
|
||||
if (strlen(y))
|
||||
sess->host = strdup(y);
|
||||
}
|
||||
} else
|
||||
# endif
|
||||
# ifdef NS_HAVE_SCREEN
|
||||
if (*(++r) == 'e') { /* set escape */
|
||||
char x = 0, y = 0;
|
||||
|
@ -1228,7 +1284,7 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
|
|||
*rx = '\0';
|
||||
if (*r != '/')
|
||||
D_ESCREEN(("URL: path for screen's option -c should be absolute (%s)\n", r));
|
||||
if ((rc = STRDUP(r))) {
|
||||
if ((rc = strdup(r))) {
|
||||
if (sess->home) /* this should never happen */
|
||||
FREE(sess->home);
|
||||
D_ESCREEN(("URL: searching for rc in %s\n", rc));
|
||||
|
@ -1238,8 +1294,9 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
|
|||
r = rx;
|
||||
*rx = ' ';
|
||||
}
|
||||
}
|
||||
} else
|
||||
# endif
|
||||
;
|
||||
while (*r && (f || *r != ' ')) {
|
||||
if (*r == '\"')
|
||||
f = 1 - f;
|
||||
|
@ -1251,7 +1308,7 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
|
|||
}
|
||||
}
|
||||
|
||||
if (!(sess->rsrc = STRDUP(p)))
|
||||
if (!(sess->rsrc = strdup(p)))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -1260,11 +1317,12 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
|
|||
*(p++) = '\0';
|
||||
if (!*p || !(sess->port = atoi(p)) || sess->port > NS_MAX_PORT) {
|
||||
*err = NS_MALFORMED_URL;
|
||||
D_ESCREEN(("malformed URL...\n"));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(q) && !(sess->host = STRDUP(q))) /* host, if any */
|
||||
if (strlen(q) && !(sess->host = strdup(q))) /* host, if any */
|
||||
goto fail;
|
||||
|
||||
FREE(d);
|
||||
|
@ -1275,27 +1333,30 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
|
|||
if (!sess->user) { /* default user (current user) */
|
||||
if (!pwe) {
|
||||
*err = NS_UNKNOWN_USER;
|
||||
D_ESCREEN(("unknown user...\n"));
|
||||
goto fail;
|
||||
}
|
||||
if (!(sess->user = STRDUP(pwe->pw_name)))
|
||||
if (!(sess->user = strdup(pwe->pw_name)))
|
||||
goto fail;
|
||||
} else if ((sess->host && strcmp(sess->host, "localhost") && strcmp(sess->host, "127.0.0.1")) || sess->port) {
|
||||
} else if ((sess->host && strcmp(sess->host, "localhost") && strcmp(sess->host, "127.0.0.1")) || (sess->port > 0)) {
|
||||
pwe = NULL;
|
||||
} else if (!pwe || strcmp(pwe->pw_name, sess->user)) { /* user!=current_user */
|
||||
sess->where = NS_SU;
|
||||
if (!(pwe = getpwnam(sess->user))) {
|
||||
*err = NS_UNKNOWN_USER;
|
||||
D_ESCREEN(("unknown user...\n"));
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
*err = NS_UNKNOWN_USER;
|
||||
D_ESCREEN(("unknown user...\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NS_HAVE_SCREEN
|
||||
if (getenv("SYSSCREENRC")) { /* $SYSSCREENRC */
|
||||
if (!(sess->sysrc = STRDUP(getenv("SCREENRC"))))
|
||||
if (!(sess->sysrc = strdup(getenv("SCREENRC"))))
|
||||
goto fail;
|
||||
} else {
|
||||
char *loc[] = { "/usr/local/etc/screenrc", /* official */
|
||||
|
@ -1307,56 +1368,96 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
|
|||
|
||||
for (n = 0; n < nloc; n++)
|
||||
if (!access(loc[n], R_OK)) {
|
||||
if (!(sess->sysrc = STRDUP(loc[n])))
|
||||
if (!(sess->sysrc = strdup(loc[n])))
|
||||
goto fail;
|
||||
n = nloc;
|
||||
}
|
||||
}
|
||||
|
||||
if (getenv("SCREENRC")) { /* $SCREENRC */
|
||||
sess->home = STRDUP(getenv("SCREENRC"));
|
||||
sess->home = strdup(getenv("SCREENRC"));
|
||||
} else if (pwe && !sess->home) { /* ~/.screenrc */
|
||||
if ((sess->home = MALLOC(strlen(pwe->pw_dir) + strlen(NS_SCREEN_RC) + 2)))
|
||||
sprintf(sess->home, "%s/%s", pwe->pw_dir, NS_SCREEN_RC);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!sess->host) { /* no host */
|
||||
if (!(sess->host = STRDUP("localhost")))
|
||||
goto fail;
|
||||
if (!sess->port) { /* no host/port */
|
||||
sess->where = NS_LCL;
|
||||
}
|
||||
} else if ((p = strchr(sess->host, '/'))) /* have host */
|
||||
*p = '\0';
|
||||
|
||||
if (!sess->port) /* no port -> default port (SSH) */
|
||||
sess->port = ns_get_ssh_port();
|
||||
|
||||
sess->backend = NS_MODE_NEGOTIATE;
|
||||
if (sess->proto) {
|
||||
#ifdef NS_HAVE_SCREEN
|
||||
if (!strcmp(sess->proto, "screen")) {
|
||||
sess->backend = NS_MODE_SCREEN;
|
||||
} else
|
||||
#warning compiling in support for GNU screen
|
||||
#endif
|
||||
#ifdef NS_HAVE_TWIN
|
||||
#warning compiling in support for twin
|
||||
if (!strcmp(sess->proto, "twin")) {
|
||||
char *twd = getenv("TWDISPLAY");
|
||||
|
||||
sess->backend = NS_MODE_TWIN;
|
||||
if (!sess->twin_str)
|
||||
sess->twin_str = STRDUP(twd ? twd : ":0");
|
||||
|
||||
/* fall back on TWDISPLAY env var only if host not set yet */
|
||||
if (twd && (!sess->host || !strlen(sess->host) || !strcmp(sess->host, "localhost"))) {
|
||||
char *twdisp = strrchr(twd, ':');
|
||||
|
||||
if (twdisp) {
|
||||
*twdisp++ = '\0';
|
||||
if (*twdisp && sess->disp < 0) /* fall back on TWDISPLAY display */
|
||||
sess->disp = atoi(twdisp);
|
||||
} /* fall back on TWDISPLAY host */
|
||||
if (((!sess->host) || (!strlen(sess->host))) && strlen(twd) && strcmp(twd, "localhost"))
|
||||
sess->host = strdup(twd);
|
||||
}
|
||||
/* this is ugly, but does the intuitive thing.
|
||||
* if you specifically want to connect a twin to a non-twin
|
||||
* port < 20, make it unambiguous by using the syntax
|
||||
* twin://host.dom:port/-twin@:disp or
|
||||
* twin://:port/-twin@host.dom:disp */
|
||||
else if (sess->host && sess->disp < 0 && sess->port >= 0 && sess->port < 20) {
|
||||
sess->disp = sess->port;
|
||||
sess->port = -1;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (!strcmp(sess->proto, "scream")) {
|
||||
sess->backend = NS_MODE_SCREAM;
|
||||
} else {
|
||||
*err = NS_UNKNOWN_PROTO;
|
||||
D_ESCREEN(("unknown protocol %s...\n", sess->proto));
|
||||
fprintf(stderr, "protocol \"%s\" not known...\n", sess->proto);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if ((sess->disp < 0) || (sess->disp > NS_MAX_PORT))
|
||||
sess->disp = 0;
|
||||
|
||||
#ifdef NS_HAVE_TWIN
|
||||
/* do this *before* host-fallback */
|
||||
if (sess->twin_str)
|
||||
FREE(sess->twin_str);
|
||||
|
||||
if (sess->twin_str = MALLOC((sess->host ? strlen(sess->host) : 0) + 7))
|
||||
sprintf(sess->twin_str, "%s:%d", (sess->host ? sess->host : ""), sess->disp);
|
||||
#endif
|
||||
|
||||
if (!sess->host) { /* no host */
|
||||
if (!(sess->host = strdup("localhost")))
|
||||
goto fail;
|
||||
if (sess->port <= 0) { /* no host/port */
|
||||
sess->where = NS_LCL;
|
||||
}
|
||||
} else if ((p = strchr(sess->host, '/'))) /* have host */
|
||||
*p = '\0';
|
||||
|
||||
if (sess->port <= 0) { /* no port -> default port (SSH) */
|
||||
if (sess->backend == NS_MODE_TWIN)
|
||||
sess->port = ns_get_twin_port();
|
||||
else
|
||||
sess->port = ns_get_ssh_port();
|
||||
}
|
||||
|
||||
if (!sess->efuns && ef && *ef) {
|
||||
sess->efuns = ns_ref_efuns(ef);
|
||||
}
|
||||
|
@ -1370,12 +1471,15 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
|
|||
}
|
||||
|
||||
*err = NS_SUCC;
|
||||
|
||||
return ns_attach_by_sess(&sess, err);
|
||||
|
||||
fail:
|
||||
if (d)
|
||||
FREE(d);
|
||||
|
||||
D_ESCREEN(("ns_attach_by_URL: fail...\n"));
|
||||
|
||||
return ns_dst_sess(&sess);
|
||||
}
|
||||
|
||||
|
@ -1457,7 +1561,7 @@ ns_go2_disp(_ns_sess * s, int d)
|
|||
return ns_screen_command(s, b);
|
||||
break;
|
||||
#endif
|
||||
#ifdef NS_HAVE_TWIN_
|
||||
#ifdef NS_HAVE_TWIN
|
||||
case NS_MODE_TWIN:
|
||||
{
|
||||
tscreen ts = Tw_FirstScreen(s->twin);
|
||||
|
@ -1477,23 +1581,27 @@ ns_go2_disp(_ns_sess * s, int d)
|
|||
}
|
||||
}
|
||||
|
||||
/* toggle monitor mode for disp (if possible) */
|
||||
/* toggle monitor mode for disp (if possible). -1 for current disp */
|
||||
int
|
||||
ns_mon_disp(_ns_sess * s, int no)
|
||||
ns_mon_disp(_ns_sess * s, int no, int quiet)
|
||||
{
|
||||
if (!s)
|
||||
return NS_FAIL;
|
||||
|
||||
D_ESCREEN(("toggling monitoring for display %d\n", no));
|
||||
|
||||
switch (s->backend) {
|
||||
#ifdef NS_HAVE_SCREEN
|
||||
case NS_MODE_SCREEN:
|
||||
ns_go2_disp(s, no);
|
||||
if (no >= 0)
|
||||
ns_go2_disp(s, no);
|
||||
if (quiet == NS_MON_TOGGLE_QUIET)
|
||||
s->flags |= NS_SESS_NO_MON_MSG;
|
||||
return ns_screen_command(s, "\x01M");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return NS_FAIL;
|
||||
}
|
||||
return NS_FAIL;
|
||||
}
|
||||
|
||||
/* scrollback buffer mode (if any) */
|
||||
|
@ -1553,7 +1661,13 @@ ns_rel_disp(_ns_sess * s, int d)
|
|||
ns_go2_disp(s, x->index);
|
||||
}
|
||||
|
||||
/* add a client display with the name "name" after display number #after */
|
||||
|
||||
|
||||
/* add a client display and a tab.
|
||||
s the session to add to
|
||||
after add after this display (0..n). -1 to add before disp 0.
|
||||
name NULL: ask. "": let backend choose name. else: set name. */
|
||||
|
||||
int
|
||||
ns_add_disp(_ns_sess * s, int after, char *name)
|
||||
{
|
||||
|
@ -1569,9 +1683,9 @@ ns_add_disp(_ns_sess * s, int after, char *name)
|
|||
if (after >= 0)
|
||||
ns_go2_disp(s, after);
|
||||
if (ns_screen_command(s, "\x01\x03") == NS_SUCC) {
|
||||
/* yes, -1 for "current_display" works even though we just made a new
|
||||
display that isn't in our list yet. faith will see you through. */
|
||||
ns_ren_disp(s, -1, name);
|
||||
if (!name || strlen(name))
|
||||
ns_ren_disp(s, -2, name);
|
||||
ns_mon_disp(s, -2, NS_MON_TOGGLE_QUIET);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -1585,6 +1699,7 @@ ns_add_disp(_ns_sess * s, int after, char *name)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* move client display #fm to display slot #to */
|
||||
int
|
||||
ns_mov_disp(_ns_sess * s, int fm, int to)
|
||||
|
@ -1679,7 +1794,15 @@ ns_rem_disp(_ns_sess * s, int d, int ask)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* rename display #d to "name". if d==-1, use current */
|
||||
/* rename display
|
||||
s session display is in
|
||||
d -1 current display
|
||||
-2 display was just created and is not in list yet
|
||||
>=0 index of the display
|
||||
name NULL ask for name
|
||||
!NULL the name
|
||||
<- error code */
|
||||
|
||||
int
|
||||
ns_ren_disp(_ns_sess * s, int d, char *name)
|
||||
{
|
||||
|
@ -1696,13 +1819,16 @@ ns_ren_disp(_ns_sess * s, int d, char *name)
|
|||
return NS_FAIL;
|
||||
}
|
||||
|
||||
if (d < 0) {
|
||||
if (d == -1)
|
||||
d = s->curr->index;
|
||||
}
|
||||
|
||||
if (!name || !*name) { /* ask */
|
||||
i = s->curr->name;
|
||||
l = strlen(i);
|
||||
if (d == -2)
|
||||
l = 32; /* dirty, but effective */
|
||||
else {
|
||||
i = s->curr->name;
|
||||
l = strlen(i);
|
||||
}
|
||||
(void) ns_inp_dial(s, "Enter a new name for the current display", 12, &i, NULL);
|
||||
if (!i || !*i)
|
||||
return NS_FAIL;
|
||||
|
@ -1712,7 +1838,8 @@ ns_ren_disp(_ns_sess * s, int d, char *name)
|
|||
#ifdef NS_HAVE_SCREEN
|
||||
case NS_MODE_SCREEN:
|
||||
if ((n = MALLOC(strlen(i ? i : name) + l + 1))) {
|
||||
ns_go2_disp(s, d);
|
||||
if (d >= 0)
|
||||
ns_go2_disp(s, d);
|
||||
strcpy(&n[l], i ? i : name); /* copy new name */
|
||||
while (l) /* prepend backspaces */
|
||||
n[--l] = '\x08';
|
||||
|
@ -2238,29 +2365,25 @@ ns_screen_command(_ns_sess * sess, char *cmd)
|
|||
char *c;
|
||||
int ret = NS_SUCC;
|
||||
|
||||
D_ESCREEN(("sess %8p, cmd %8p\n", sess, cmd));
|
||||
if (!cmd || !*cmd)
|
||||
return NS_FAIL;
|
||||
|
||||
D_ESCREEN(("Sending screen command %s\n", safe_print_string(cmd, strlen(cmd))));
|
||||
if (NS_EFUN_EXISTS(efuns, sess, NULL, inp_text)) {
|
||||
D_ESCREEN((" -> inp_text is set\n"));
|
||||
if ((c = STRDUP(cmd))) {
|
||||
char *p = c; /* replace default escape-char with that */
|
||||
if ((c = strdup(cmd))) {
|
||||
{
|
||||
char *p = c; /* replace default escape-char with that */
|
||||
|
||||
D_ESCREEN((" -> translating escapes\n"));
|
||||
while (*p) { /* actually used in this session */
|
||||
if (*p == NS_SCREEN_ESCAPE)
|
||||
*p = sess->escape;
|
||||
p++;
|
||||
while (*p) { /* actually used in this session */
|
||||
if (*p == NS_SCREEN_ESCAPE)
|
||||
*p = sess->escape;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
ns_desc_string(c, "ns_screen_command: xlated string");
|
||||
efuns->inp_text(NULL, sess->fd, c);
|
||||
FREE(c);
|
||||
} else {
|
||||
D_ESCREEN((" -> out of memory\n"));
|
||||
} else
|
||||
ret = NS_OOM;
|
||||
}
|
||||
} /* out of memory */
|
||||
else {
|
||||
ret = NS_EFUN_NOT_SET;
|
||||
|
@ -2549,7 +2672,7 @@ ns_parse_screen_interactive(_ns_sess * sess, char *c)
|
|||
if (!c || !*c)
|
||||
return NS_FAIL;
|
||||
#ifdef NS_PARANOID
|
||||
if (!(s = o = STRDUP(c)))
|
||||
if (!(s = o = strdup(c)))
|
||||
return NS_FAIL;
|
||||
#else
|
||||
s = c;
|
||||
|
@ -2576,6 +2699,32 @@ ns_parse_screen_interactive(_ns_sess * sess, char *c)
|
|||
|
||||
|
||||
|
||||
/* ns_weird_screen -- damage control
|
||||
screen the offending session
|
||||
doc string specifying the context
|
||||
!stderr a description of the problem
|
||||
!err_inhibit the problem-type is marked so we don't rewarn.
|
||||
<- error code (always NS_FAIL) */
|
||||
|
||||
static int
|
||||
ns_screen_weird(_ns_sess * screen, long type, char *doc)
|
||||
{
|
||||
if (!(err_inhibit & type)) {
|
||||
err_inhibit |= type;
|
||||
fprintf(stderr, "parse_screen: %s (%ld) screen sent weird stuff.\n"
|
||||
"This should never happen. It is assumed that you use a\n"
|
||||
"rather unusual configuration for \"screen\". Please\n"
|
||||
"send the result of 'screen --version' to <scream@azundris.com>\n"
|
||||
"(together with your ~/.screenrc and /etc/screenrc if present).\n"
|
||||
"If at all possible, please also run 'Eterm -e screen' and make\n"
|
||||
"a screenshot of the offending window (and the window only, the\n" "beauty of your desktop is not relevant to this investigation. : ).\n", doc, type);
|
||||
}
|
||||
(void) ns_upd_stat(screen);
|
||||
return NS_FAIL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ns_parse_screenrc -- read the user's screenrc (if we can find it),
|
||||
parse it (we need to know if she changes the escapes etc.), and
|
||||
send it to the actually screen
|
||||
|
@ -2663,6 +2812,7 @@ ns_parse_screenrc(_ns_sess * s, char *fn, int whence)
|
|||
as certain functionalities ("add a tab", "show status message")
|
||||
may be called from here.
|
||||
p the offending message-line
|
||||
! mode of operation may be modified using screen->flags
|
||||
<- returns an error code. */
|
||||
|
||||
static int
|
||||
|
@ -2670,8 +2820,9 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
|
|||
{
|
||||
_ns_efuns *efuns;
|
||||
char *p2;
|
||||
char vdate[33], vtype[3], vrem[17];
|
||||
int ma, mi, mu, ret = NS_SUCC, type;
|
||||
char vdate[33], vtype[3], vrem[17], win[64];
|
||||
int ma, mi, mu, ret = NS_SUCC, type, n;
|
||||
size_t l;
|
||||
|
||||
if (!p)
|
||||
return NS_FAIL;
|
||||
|
@ -2681,6 +2832,8 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
|
|||
while (isspace(*p))
|
||||
p++;
|
||||
|
||||
D_ESCREEN(("got \"%s\"\n", p));
|
||||
|
||||
type = (strlen(p) > 1) ? NS_SCREEN_STATUS : NS_SCREEN_ST_CLR;
|
||||
|
||||
if (type == NS_SCREEN_ST_CLR) {
|
||||
|
@ -2701,7 +2854,7 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
|
|||
if (screen->name) {
|
||||
FREE(screen->name);
|
||||
}
|
||||
if ((screen->name = STRDUP(&p[strlen(NS_SCREEN_SESS_T)]))) {
|
||||
if ((screen->name = strdup(&p[strlen(NS_SCREEN_SESS_T)]))) {
|
||||
size_t lsn = strlen(screen->name);
|
||||
|
||||
if (lsn) {
|
||||
|
@ -2715,7 +2868,30 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
|
|||
!strncmp(p, "msgminwait", strlen("msgminwait")) ||
|
||||
!strcmp(p, "Press ^@ to destroy or ^@ to resurrect window") || !strcmp(p, "Aborted because of window size change."))
|
||||
p = NULL;
|
||||
else if (sscanf(p, NS_SCREEN_VERSION_T, vtype, &ma, &mi, &mu, vrem, vdate) == 6) {
|
||||
else if ((screen->flags & NS_SESS_NO_MON_MSG) &&
|
||||
((sscanf(p, "Window %d (%s) is now being monitored for all activity.", &n, win) == 2) ||
|
||||
(sscanf(p, "Window %d (%s) is no longer being monitored for activity.", &n, win) == 2))) {
|
||||
D_ESCREEN(("activity toggled quietly for window %d-%s\n", n, win));
|
||||
p = NULL;
|
||||
screen->flags = (screen->flags & ~NS_SESS_NO_MON_MSG); /* reset mute flag */
|
||||
} else if (!strncmp(p, NS_SCREEN_ACT_T, l = strlen(NS_SCREEN_ACT_T))) {
|
||||
if (NS_EFUN_EXISTS(efuns, screen, NULL, upd_disp)) {
|
||||
int inx, button;
|
||||
_ns_disp *d;
|
||||
|
||||
p += l;
|
||||
inx = atoi(p);
|
||||
button = disp_get_real_by_screen(screen, inx);
|
||||
if ((d = disp_fetch(screen, inx))) {
|
||||
D_ESCREEN(("activity in window %d-%s (button %d)\n", inx, d->name, button));
|
||||
d->flags |= NS_SCREAM_ACT;
|
||||
efuns->upd_disp(screen->userdef, button, d->flags, NULL);
|
||||
} else {
|
||||
D_ESCREEN(("activity in unknown window %d (button %d)...\n", inx, button));
|
||||
}
|
||||
}
|
||||
p = NULL;
|
||||
} else if (sscanf(p, NS_SCREEN_VERSION_T, vtype, &ma, &mi, &mu, vrem, vdate) == 6) {
|
||||
if (!strcmp("en", vtype))
|
||||
screen->backend = NS_MODE_SCREEN;
|
||||
else if (!strcmp("am", vtype))
|
||||
|
@ -2779,7 +2955,7 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
|
|||
if (!force && screen->timestamp)
|
||||
return NS_SUCC;
|
||||
|
||||
if ((p = STRDUP(p))) {
|
||||
if ((p = strdup(p))) {
|
||||
_ns_parse pd[NS_MAX_DISPS];
|
||||
|
||||
p2 = &p[width - 1];
|
||||
|
@ -2788,13 +2964,19 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
|
|||
*(p2--) = '\0';
|
||||
} /* p2 now points behind last item */
|
||||
|
||||
D_ESCREEN(("parse_screen: screen sends ::%s::\n", p));
|
||||
D_ESCREEN(("parse_screen: screen sends (%d) ::%s::\n", strlen(p), p));
|
||||
|
||||
if (strlen(p) < 2) { /* special case: display 0 */
|
||||
disp = screen->dsps; /* might not get a status-line in d0! */
|
||||
if (disp && !(disp->flags & NS_SCREAM_CURR)) { /* flags need updating */
|
||||
disp->flags |= NS_SCREAM_CURR; /* set flag to avoid calling inp_text */
|
||||
disp->flags &= ~NS_SCREAM_ACT;
|
||||
while (disp->next) {
|
||||
disp->flags &= ~NS_SCREAM_CURR;
|
||||
disp = disp->next;
|
||||
}
|
||||
ret = ns_upd_stat(screen);
|
||||
D_ESCREEN(("parse_screen: qeueing update\n"));
|
||||
} /* more than once */
|
||||
else if (!screen->timestamp) {
|
||||
/* send init string the first time around, just to be on
|
||||
|
@ -2820,7 +3002,7 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
|
|||
screen->timestamp = 1;
|
||||
D_ESCREEN(("parse_screen: resetting screen...\n"));
|
||||
} else {
|
||||
D_ESCREEN(("parse_screen: error, we should never get here\n"));
|
||||
D_ESCREEN(("parse_screen: nothing to do in exception, updating anyways...\n"));
|
||||
ret = ns_upd_stat(screen);
|
||||
}
|
||||
FREE(p);
|
||||
|
@ -2880,28 +3062,42 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
|
|||
n = pd[r].screen;
|
||||
disp = disp_fetch(screen, n);
|
||||
|
||||
if (pd[r].flags & NS_SCREAM_CURR) {
|
||||
pd[r].flags &= ~NS_SCREAM_ACT;
|
||||
}
|
||||
|
||||
if (!disp) { /* new display */
|
||||
if (!(disp = disp_fetch_or_make(screen, n)) || !(disp->name = STRDUP(pd[r].name))) {
|
||||
if (!(disp = disp_fetch_or_make(screen, n)) || !(disp->name = strdup(pd[r].name))) {
|
||||
D_ESCREEN(("parse_screen: out of memory in new_display(%d)\n", n));
|
||||
ret = NS_FAIL;
|
||||
} else {
|
||||
if (NS_EFUN_EXISTS(efuns, screen, NULL, ins_disp))
|
||||
ret = efuns->ins_disp(screen->userdef, pd[r].real - 1, pd[r].screen, disp->name);
|
||||
}
|
||||
} else if ((tmp = strcmp(disp->name, pd[r].name)) || /* upd display */
|
||||
(disp->flags != pd[r].flags)) {
|
||||
if (tmp) {
|
||||
FREE(disp->name);
|
||||
if (!(disp->name = STRDUP(pd[r].name))) {
|
||||
FREE(p);
|
||||
return NS_FAIL;
|
||||
} else {
|
||||
int fl = (disp->flags & ~NS_SCREAM_CURR) | (pd[r].flags & NS_SCREAM_MASK);
|
||||
|
||||
if ((fl & (NS_SCREAM_CURR | NS_SCREAM_ACT)) == (NS_SCREAM_CURR | NS_SCREAM_ACT))
|
||||
fl &= ~NS_SCREAM_ACT;
|
||||
|
||||
if ((tmp = strcmp(disp->name, pd[r].name)) || /* upd display */
|
||||
(disp->flags != fl)) {
|
||||
if (tmp) {
|
||||
FREE(disp->name);
|
||||
if (!(disp->name = strdup(pd[r].name))) {
|
||||
FREE(p);
|
||||
return NS_FAIL;
|
||||
}
|
||||
}
|
||||
if (disp->flags != fl) {
|
||||
if (pd[r].flags & NS_SCREAM_CURR)
|
||||
disp->sess->curr = disp;
|
||||
disp->flags = fl;
|
||||
} else
|
||||
fl = -1;
|
||||
if (NS_EFUN_EXISTS(efuns, screen, NULL, upd_disp))
|
||||
ret = efuns->upd_disp(screen->userdef, r, fl, (!tmp) ? NULL : disp->name);
|
||||
}
|
||||
if (pd[r].flags & NS_SCREAM_CURR)
|
||||
disp->sess->curr = disp;
|
||||
disp->flags = pd[r].flags & NS_SCREAM_MASK;
|
||||
if (NS_EFUN_EXISTS(efuns, screen, NULL, upd_disp))
|
||||
ret = efuns->upd_disp(screen->userdef, r, disp->flags, disp->name);
|
||||
}
|
||||
|
||||
/* remove any displays from list that have disappeared
|
||||
|
@ -2925,19 +3121,9 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
|
|||
|
||||
#ifdef NS_PARANOID
|
||||
if (!r) {
|
||||
if (!(err_inhibit & NS_ERR_WEIRDSCREEN)) {
|
||||
err_inhibit |= NS_ERR_WEIRDSCREEN;
|
||||
fprintf(stderr, "parse_screen: !r\n"
|
||||
"This should never happen. It is assumed that you use a\n"
|
||||
"rather unusual configuration for \"screen\". Please\n"
|
||||
"send the result of 'screen --version' to <scream@azundris.com>\n"
|
||||
"(together with your ~/.screenrc and /etc/screenrc if present).\n"
|
||||
"If at all possible, please also run 'Eterm -e screen' and make\n"
|
||||
"a screenshot of the offending window (and the window only, the\n" "beauty of your desktop is not relevant to this investigation. : ).\n");
|
||||
}
|
||||
ret = ns_upd_stat(screen);
|
||||
D_ESCREEN(("parse_screen: no elements parsed (!r)...\n"));
|
||||
FREE(p);
|
||||
return NS_FAIL;
|
||||
return ns_screen_weird(screen, NS_ERR_WEIRDSCREEN, "no elements parsed (!r)...");
|
||||
} else
|
||||
#endif
|
||||
/* kill overhang (o/t right) if status-line isn't side-scrolling
|
||||
|
@ -3024,6 +3210,7 @@ ns_register_red(_ns_efuns * efuns, int (*redraw) (void *))
|
|||
efuns->redraw = redraw;
|
||||
}
|
||||
|
||||
|
||||
/* function that redraw part of the terminal */
|
||||
void
|
||||
ns_register_rda(_ns_efuns * efuns, int (*redraw_xywh) (void *, int, int, int, int))
|
||||
|
@ -3031,7 +3218,7 @@ ns_register_rda(_ns_efuns * efuns, int (*redraw_xywh) (void *, int, int, int, in
|
|||
efuns->redraw_xywh = redraw_xywh;
|
||||
}
|
||||
|
||||
/* function that redraw part of the terminal */
|
||||
/* function that expires buttons */
|
||||
void
|
||||
ns_register_exb(_ns_efuns * efuns, int (*expire_buttons) (void *, int))
|
||||
{
|
||||
|
|
22
src/menus.c
22
src/menus.c
|
@ -302,7 +302,9 @@ menu_handle_button_release(event_t *ev)
|
|||
menu_display_submenu(current_menu, item);
|
||||
} else {
|
||||
menu_action(item);
|
||||
menuitem_deselect(current_menu);
|
||||
if (current_menu) {
|
||||
menuitem_deselect(current_menu);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Reset the state of the menu system. */
|
||||
|
@ -413,8 +415,7 @@ menu_dispatch_event(event_t *ev)
|
|||
return (0);
|
||||
}
|
||||
|
||||
menulist_t *
|
||||
menulist_add_menu(menulist_t *list, menu_t *menu)
|
||||
menulist_t *menulist_add_menu(menulist_t *list, menu_t *menu)
|
||||
{
|
||||
ASSERT_RVAL(menu != NULL, list);
|
||||
|
||||
|
@ -446,8 +447,7 @@ menulist_clear(menulist_t *list)
|
|||
FREE(list);
|
||||
}
|
||||
|
||||
menu_t *
|
||||
menu_create(char *title)
|
||||
menu_t *menu_create(char *title)
|
||||
{
|
||||
menu_t *menu;
|
||||
static Cursor cursor;
|
||||
|
@ -599,8 +599,7 @@ menu_is_child(menu_t *menu, menu_t *submenu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
menu_t *
|
||||
find_menu_by_title(menulist_t *list, char *title)
|
||||
menu_t *find_menu_by_title(menulist_t *list, char *title)
|
||||
{
|
||||
register unsigned char i;
|
||||
|
||||
|
@ -614,8 +613,7 @@ find_menu_by_title(menulist_t *list, char *title)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
menu_t *
|
||||
find_menu_by_window(menulist_t *list, Window win)
|
||||
menu_t *find_menu_by_window(menulist_t *list, Window win)
|
||||
{
|
||||
register unsigned char i;
|
||||
|
||||
|
@ -629,8 +627,7 @@ find_menu_by_window(menulist_t *list, Window win)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
menuitem_t *
|
||||
find_item_by_coords(menu_t *menu, int x, int y)
|
||||
menuitem_t *find_item_by_coords(menu_t *menu, int x, int y)
|
||||
{
|
||||
register unsigned char i;
|
||||
register menuitem_t *item;
|
||||
|
@ -700,8 +697,7 @@ menuitem_change_current(menuitem_t *item)
|
|||
}
|
||||
}
|
||||
|
||||
menuitem_t *
|
||||
menuitem_create(char *text)
|
||||
menuitem_t *menuitem_create(char *text)
|
||||
{
|
||||
menuitem_t *menuitem;
|
||||
|
||||
|
|
|
@ -323,8 +323,7 @@ static const struct {
|
|||
OPT_LONG("finished-text", "text to output after program termination", &rs_finished_text),
|
||||
OPT_LONG("term-name", "value to use for setting $TERM", &rs_term_name),
|
||||
OPT_LONG("pipe-name", "filename of console pipe to emulate -C", &rs_pipe_name),
|
||||
OPT_STR('a', "attribute", "parse an attribute in the specified context", NULL),
|
||||
OPT_BOOL('C', "console", "grab console messages", &Options, Opt_console),
|
||||
OPT_STR('a', "attribute", "parse an attribute in the specified context", NULL), OPT_BOOL('C', "console", "grab console messages", &Options, Opt_console),
|
||||
#ifdef ESCREEN
|
||||
OPT_STR('U', "URL", "an URL pointing at a screen-session to pick up", &rs_url),
|
||||
OPT_STR('Z', "[lclport:]fw[:fwport]", "the destination machine -U can only be seen by the firewall fw. tunnel.", &rs_hop),
|
||||
|
|
46
src/scream.h
46
src/scream.h
|
@ -58,7 +58,7 @@
|
|||
#define NS_SCREAM_FILE 32
|
||||
#define NS_SCREAM_SHARED 64
|
||||
#define NS_SCREAM_ZOMBIE 128
|
||||
#define NS_SCREAM_BUTTON 0xf0
|
||||
#define NS_SCREAM_BUTTON 0xf00
|
||||
|
||||
#define NS_SCREAM_MASK (~(NS_SCREAM_UTMP|NS_SCREAM_PRVS))
|
||||
|
||||
|
@ -70,6 +70,11 @@
|
|||
#define NS_ESC_SCREENRC 3
|
||||
#define NS_ESC_INTERACTIVE 4
|
||||
|
||||
#define NS_SESS_NO_MON_MSG 1
|
||||
|
||||
#define NS_MON_TOGGLE_QUIET 0
|
||||
#define NS_MON_TOGGLE_NOISY 1
|
||||
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -90,35 +95,43 @@ typedef struct __ns_hop {
|
|||
|
||||
|
||||
typedef struct __ns_sess { /* a whole screen-session with many clients */
|
||||
char *name; /* session name */
|
||||
int where; /* local/remote */
|
||||
int backend; /* screen/scream */
|
||||
int backend; /* screen/scream/twin */
|
||||
int nesting; /* 0=topLevel, 1=screen within a screen etc */
|
||||
time_t timestamp; /* last updated when? see NS_SCREEN_UPD_FREQ */
|
||||
time_t timestamp; /* last updated when? */
|
||||
int delay; /* initialization delay */
|
||||
|
||||
int flags; /* miracle flags, see NS_SESS_* */
|
||||
int fd; /* fd for communication */
|
||||
int dsbb; /* default length of scroll-back buffer */
|
||||
|
||||
char *proto; /* protocol. usually "screen" */
|
||||
char *host; /* host. numeric or symbolic. ("localhost") */
|
||||
int port; /* port. usually TCP22: SSH */
|
||||
int disp; /* display (used by twin etc., not screen) */
|
||||
char *user; /* user. often current local user */
|
||||
char *pass; /* password. used for su. for remote sessions, a
|
||||
ssh-key should be on the remote machine. */
|
||||
char *rsrc; /* add'l parameter to screen/scream. URL-enc */
|
||||
char *home; /* user's home dir. so we can find .screenrc */
|
||||
char *sysrc; /* global screen config */
|
||||
|
||||
void *userdef; /* the term-app can store a pointer here */
|
||||
char *name; /* session name */
|
||||
int fd; /* fd for communication */
|
||||
char escape,literal; /* talking to screen: defaults to ^A, a */
|
||||
int escdef; /* where was the escape sequence defined? */
|
||||
int delay; /* initialization delay */
|
||||
int dsbb; /* default length of scroll-back buffer */
|
||||
|
||||
struct __ns_efuns *efuns; /* callbacks into the terminal program. */
|
||||
struct __ns_hop *hop; /* tunnel, if any */
|
||||
struct __ns_disp *dsps; /* first display (that with the lowest index) */
|
||||
struct __ns_disp *curr; /* current display (NULL for none) */
|
||||
struct __ns_sess *prvs; /* previous session in session list */
|
||||
struct __ns_sess *next; /* next session in session list */
|
||||
|
||||
char *home; /* user's home dir. so we can find .screenrc */
|
||||
char *sysrc; /* global screen config */
|
||||
char escape,literal; /* talking to screen: defaults to ^A, a */
|
||||
int escdef; /* where was the escape sequence defined? */
|
||||
|
||||
#ifdef NS_HAVE_TWIN
|
||||
tdisplay twin;
|
||||
char *twin_str;
|
||||
tdisplay twin; /* twin-display */
|
||||
char *twin_str; /* twin-display (string specifier) */
|
||||
#endif
|
||||
} _ns_sess;
|
||||
|
||||
|
@ -190,9 +203,14 @@ _ns_sess *ns_attach_by_sess(_ns_sess **,int *);
|
|||
_ns_sess *ns_attach_by_URL(char *,char *,_ns_efuns **,int *,void *);
|
||||
int ns_detach(_ns_sess **);
|
||||
|
||||
/* debug */
|
||||
void ns_desc_twin(_ns_sess *,char *);
|
||||
|
||||
/* convenience */
|
||||
int ns_run(_ns_efuns *, char *);
|
||||
int ns_get_ssh_port(void);
|
||||
int ns_get_twin_port(void);
|
||||
|
||||
|
||||
int disp_get_real_by_screen(_ns_sess *,int);
|
||||
int disp_get_screen_by_real(_ns_sess *,int);
|
||||
|
@ -236,7 +254,7 @@ int ns_rsz_disp(_ns_sess *,int,int,int);
|
|||
int ns_rem_disp(_ns_sess *,int,int);
|
||||
int ns_ren_disp(_ns_sess *,int,char *);
|
||||
int ns_log_disp(_ns_sess *,int,char *);
|
||||
int ns_mon_disp(_ns_sess *,int);
|
||||
int ns_mon_disp(_ns_sess *,int,int);
|
||||
int ns_sbb_disp(_ns_sess *,int);
|
||||
|
||||
int ns_tog_region(_ns_sess *,_ns_disp *);
|
||||
|
|
|
@ -15,12 +15,6 @@
|
|||
undef it, you're on your own. */
|
||||
#define NS_PARANOID
|
||||
|
||||
/* compile in support for the GNU "screen" program as a backend */
|
||||
#define NS_HAVE_SCREEN 1
|
||||
|
||||
/* compile in support for the "twin" program as a backend */
|
||||
#undef NS_HAVE_TWIN
|
||||
|
||||
|
||||
|
||||
#define NS_MAXCMD 512
|
||||
|
@ -38,6 +32,8 @@
|
|||
#define NS_SCREEN_RC ".screenrc"
|
||||
#define NS_TWIN_CALL "export TERM=xterm; twin %s"
|
||||
#define NS_TWIN_OPTS "-hw=tty"
|
||||
#define NS_TWIN_PARA "twin@"
|
||||
#define NS_TWDISPLAY_OPTS "-" NS_TWIN_PARA "%s"
|
||||
|
||||
/* this should never change. the escape-char for an out-of-the-box "screen".
|
||||
don't change this just because you set something else in your .screenrc */
|
||||
|
@ -69,6 +65,7 @@
|
|||
#define NS_SCREEN_SESS_T "This session is named '"
|
||||
#define NS_SCREEN_VERSION_T "scre%2s %d.%d.%d %16s %32s"
|
||||
#define NS_SCREEN_NO_DEBUG "Sorry, screen was compiled without -DDEBUG option."
|
||||
#define NS_SCREEN_ACT_T "Activity in window "
|
||||
|
||||
/* should be 1s */
|
||||
#define NS_INIT_DELAY 1
|
||||
|
|
|
@ -484,12 +484,15 @@ script_handler_es_display(char **params)
|
|||
D_ESCREEN(("Toggle display\n"));
|
||||
ns_tog_disp(sess);
|
||||
} else if (!strcmp(p, "new")) {
|
||||
if (!a || !*a || !strcasecmp(a, "ask")) {
|
||||
if (!a || !*a) {
|
||||
D_ESCREEN(("disp new\n"));
|
||||
ns_add_disp(sess, no, "");
|
||||
} else if (!a || !*a || !strcasecmp(a, "ask")) {
|
||||
D_ESCREEN(("disp new ask\n"));
|
||||
ns_add_disp(sess, no, NULL);
|
||||
} else {
|
||||
D_ESCREEN(("disp new \"%s\"\n", a));
|
||||
ns_ren_disp(sess, no, a);
|
||||
ns_add_disp(sess, no, a);
|
||||
}
|
||||
} else if (!strcmp(p, "title") || !strcmp(p, "name") || !strcmp(p, "rename")) {
|
||||
if (!a || !*a || !strcasecmp(a, "ask")) {
|
||||
|
@ -509,7 +512,7 @@ script_handler_es_display(char **params)
|
|||
}
|
||||
} else if (!strcmp(p, "watch") || !strcmp(p, "monitor")) {
|
||||
D_ESCREEN(("Monitor display %d\n", no));
|
||||
ns_mon_disp(sess, no);
|
||||
ns_mon_disp(sess, no, NS_MON_TOGGLE_NOISY);
|
||||
} else if (!strcmp(p, "back") || !strcmp(p, "backlog") || !strcmp(p, "scrollback")) {
|
||||
D_ESCREEN(("View scrollback on display %d\n", no));
|
||||
ns_sbb_disp(sess, no);
|
||||
|
|
Loading…
Reference in New Issue