diff options
author | Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> | 2010-02-16 11:00:58 -0500 |
---|---|---|
committer | Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> | 2010-02-16 11:00:58 -0500 |
commit | 929be520ad026011ac98420f4a56fa93dff06899 (patch) | |
tree | e3459df2901aa082c0431222b7c7f38cf78ebcea | |
parent | 8d3c168f49d1974180a01e09953702a78993179d (diff) | |
download | screen-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.c | 11 | ||||
-rw-r--r-- | src/comm.c | 8 | ||||
-rw-r--r-- | src/process.c | 38 | ||||
-rw-r--r-- | src/screen.c | 7 | ||||
-rw-r--r-- | src/socket.c | 19 |
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); } } + @@ -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); } |