summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2010-02-16 11:00:58 -0500
committerSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2010-02-16 11:00:58 -0500
commit929be520ad026011ac98420f4a56fa93dff06899 (patch)
treee3459df2901aa082c0431222b7c7f38cf78ebcea
parent8d3c168f49d1974180a01e09953702a78993179d (diff)
downloadscreen-929be520ad026011ac98420f4a56fa93dff06899.tar.gz
Complete the query-response system.
Some commands now can be queried from a remote session using the '-Q' flag, e.g. 'screen -Q windows'. The commands will send the response to the stdout of the querying process. If there was an error in the command, then the querying process will exit with a non-zero status. The commands that can be queried now are: echo info lastmsg time title windows
-rw-r--r--src/attacher.c11
-rw-r--r--src/comm.c8
-rw-r--r--src/process.c38
-rw-r--r--src/screen.c7
-rw-r--r--src/socket.c19
5 files changed, 57 insertions, 26 deletions
diff --git a/src/attacher.c b/src/attacher.c
index f8c3217..ef3ce8b 100644
--- a/src/attacher.c
+++ b/src/attacher.c
@@ -1009,6 +1009,16 @@ int query;
if ((r = MakeServerSocket()) >= 0)
break;
}
+ if (r < 0)
+ {
+ for (c = '0'; c <= '9'; c++)
+ {
+ query[6] = c;
+ strcpy(sp, query);
+ if ((r = MakeServerSocket()) >= 0)
+ break;
+ }
+ }
if (r < 0)
Panic(0, "Could not create a listening socket to read the results.");
@@ -1040,3 +1050,4 @@ int query;
close(s);
}
}
+
diff --git a/src/comm.c b/src/comm.c
index f7730cc..4843e10 100644
--- a/src/comm.c
+++ b/src/comm.c
@@ -180,7 +180,7 @@ struct comm comms[RC_LAST + 1] =
{ "dinfo", NEED_DISPLAY|ARGS_0 },
{ "displays", NEED_LAYER|ARGS_0 },
{ "dumptermcap", NEED_FORE|ARGS_0 },
- { "echo", ARGS_12 },
+ { "echo", CAN_QUERY|ARGS_12 },
#ifdef ENCODINGS
{ "encoding", ARGS_12 },
#endif
@@ -311,8 +311,8 @@ struct comm comms[RC_LAST + 1] =
{ "termcap", ARGS_23 },
{ "termcapinfo", ARGS_23 },
{ "terminfo", ARGS_23 },
- { "time", ARGS_01 },
- { "title", NEED_FORE|ARGS_01 },
+ { "time", CAN_QUERY|ARGS_01 },
+ { "title", CAN_QUERY|NEED_FORE|ARGS_01 },
{ "umask", ARGS_1|ARGS_ORMORE },
{ "unbindall", ARGS_0 },
{ "unsetenv", ARGS_1 },
@@ -327,7 +327,7 @@ struct comm comms[RC_LAST + 1] =
{ "wall", NEED_DISPLAY|ARGS_1},
{ "width", ARGS_0123 },
{ "windowlist", ARGS_012 },
- { "windows", NEED_DISPLAY|ARGS_0 },
+ { "windows", CAN_QUERY|ARGS_0 },
{ "wrap", NEED_FORE|ARGS_01 },
#ifdef COPY_PASTE
{ "writebuf", ARGS_0123 },
diff --git a/src/process.c b/src/process.c
index 923565a..5d6941d 100644
--- a/src/process.c
+++ b/src/process.c
@@ -59,6 +59,7 @@ extern char *BellString, *ActivityString, *ShellProg, *ShellArgs[];
extern char *hstatusstring, *captionstring, *timestring;
extern char *wliststr, *wlisttit;
extern int captionalways;
+extern int queryflag;
extern char *hardcopydir, *screenlogfile, *logtstamp_string;
extern int log_flush, logtstamp_on, logtstamp_after;
extern char *VisualBellString;
@@ -1147,31 +1148,35 @@ int key;
return;
}
n = comms[nr].flags;
- /* XXX: Commands will have a CAN_QUERY flag, depending on whether they have
- something to return on a query. For example, 'windows' can return a result,
- but 'other' cannot.
+ /* Commands will have a CAN_QUERY flag, depending on whether they have
+ * something to return on a query. For example, 'windows' can return a result,
+ * but 'other' cannot.
+ * If some command causes an error, then it should reset queryflag to -1, so that
+ * the process requesting the query can be notified that an error happened.
*/
-#if 0
- if (!(n & CAN_QUERY) && queryflag)
+ if (!(n & CAN_QUERY) && queryflag >= 0)
{
/* Query flag is set, but this command cannot be queried. */
Msg(0, "%s command cannot be queried.", comms[nr].name);
+ queryflag = -1;
return;
}
-#endif
if ((n & NEED_DISPLAY) && display == 0)
{
Msg(0, "%s: %s: display required", rc_name, comms[nr].name);
+ queryflag = -1;
return;
}
if ((n & NEED_FORE) && fore == 0)
{
Msg(0, "%s: %s: window required", rc_name, comms[nr].name);
+ queryflag = -1;
return;
}
if ((n & NEED_LAYER) && flayer == 0)
{
Msg(0, "%s: %s: display or window required", rc_name, comms[nr].name);
+ queryflag = -1;
return;
}
if ((argc = CheckArgNum(nr, args)) < 0)
@@ -1183,6 +1188,7 @@ int key;
{
Msg(0, "%s: %s: permission denied (user %s)",
rc_name, comms[nr].name, (EffectiveAclUser ? EffectiveAclUser : D_user)->u_name);
+ queryflag = -1;
return;
}
}
@@ -2038,6 +2044,13 @@ int key;
}
break;
case RC_TITLE:
+ if (queryflag >= 0)
+ {
+ if (fore)
+ Msg(0, "%s", fore->w_title);
+ else
+ queryflag = -1;
+ }
if (*args == 0)
InputAKA();
else
@@ -2647,7 +2660,10 @@ int key;
if (s)
Msg(0, "%s", s);
else
- Msg(0, "%s: 'echo [-n] [-p] \"string\"' expected.", rc_name);
+ {
+ Msg(0, "%s: 'echo [-n] [-p] \"string\"' expected.", rc_name);
+ queryflag = -1;
+ }
break;
case RC_BELL:
case RC_BELL_MSG:
@@ -5330,7 +5346,7 @@ int where;
continue;
if ((flags & 1) && display && p == D_fore)
continue;
- if (D_fore && D_fore->w_group != p->w_group)
+ if (display && D_fore && D_fore->w_group != p->w_group)
continue;
cmd = p->w_title;
@@ -5472,13 +5488,11 @@ int where;
char buf[1024];
char *s, *ss;
- if (!display)
- return;
- if (where == -1 && D_fore)
+ if (display && where == -1 && D_fore)
where = D_fore->w_number;
ss = AddWindows(buf, sizeof(buf), 0, where);
s = buf + strlen(buf);
- if (ss - buf > D_width / 2)
+ if (display && ss - buf > D_width / 2)
{
ss -= D_width / 2;
if (s - ss < D_width)
diff --git a/src/screen.c b/src/screen.c
index ce081ac..67cddbc 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -207,7 +207,7 @@ char *wlisttit;
int auto_detach = 1;
int iflag, rflag, dflag, lsflag, quietflag, wipeflag, xflag;
int cmdflag;
-int queryflag;
+int queryflag = -1;
int adaptflag;
#ifdef MULTIUSER
@@ -1181,7 +1181,7 @@ char **av;
if (!*av)
Panic(0, "Please specify a command.");
SET_GUID();
- SendCmdMessage(sty, SockMatch, av, queryflag);
+ SendCmdMessage(sty, SockMatch, av, queryflag >= 0);
exit(0);
}
else if (rflag || xflag)
@@ -2110,6 +2110,9 @@ VA_DECL
}
else
printf("%s\r\n", buf);
+
+ if (queryflag >= 0)
+ write(queryflag, buf, strlen(buf));
}
/*
diff --git a/src/socket.c b/src/socket.c
index 08b545f..70b57db 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -65,6 +65,7 @@ static void AskPassword __P((struct msg *));
extern char *RcFileName, *extra_incap, *extra_outcap;
extern int ServerSocket, real_uid, real_gid, eff_uid, eff_gid;
extern int dflag, iflag, rflag, lsflag, quietflag, wipeflag, xflag;
+extern int queryflag;
extern char *attach_tty, *LoginName, HostName[];
extern struct display *display, *displays;
extern struct win *fore, **wtab, *console_window, *windows;
@@ -1171,12 +1172,6 @@ ReceiveMsg()
break;
#endif
case MSG_QUERY:
- /* Reset error buffer */
- /* Reset output buffer */
- /* FALLTHROUGH */
- case MSG_COMMAND:
- DoCommandMsg(&m);
- if (m.type == MSG_QUERY)
{
char *oldSockPath = SaveStr(SockPath);
strcpy(SockPath, m.m.command.writeback);
@@ -1185,12 +1180,20 @@ ReceiveMsg()
Free(oldSockPath);
if (s >= 0)
{
- write(s, "So ...", 7);
+ queryflag = s;
+ DoCommandMsg(&m);
close(s);
}
- Kill(m.m.command.apid, SIGCONT); /* Send SIG_BYE if an error happened, instead */
+ 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);
}