Disable nested execute. The execute protocol is flawed and cannot be
implemented correctly by asynchronous clients --- unless a client waits for a prompt after sending the execute command and its argument, it is prone to send more input before the C_EXECUTE arrives. That input overtakes the contents of the script file. This is almost certain to happen when the execute is in a script file. Disabling that is probably more useful and certainly less painful than documenting this mess. The client rejects nested execute since servcmd.c rev. 1.42. (EXEC): new. (player_coms): Require it for execute. (player_set_nstat): Set it in nstat. (execute): Clear it in nstat.
This commit is contained in:
parent
ed8e0cd552
commit
adfab4344e
4 changed files with 5 additions and 1 deletions
|
@ -46,6 +46,7 @@
|
||||||
#define SANCT (bit(1) | VIS)
|
#define SANCT (bit(1) | VIS)
|
||||||
#define NORM (bit(2) | VIS)
|
#define NORM (bit(2) | VIS)
|
||||||
#define GOD (bit(3) | NORM | VIS)
|
#define GOD (bit(3) | NORM | VIS)
|
||||||
|
#define EXEC bit(5)
|
||||||
#define CAP bit(6)
|
#define CAP bit(6)
|
||||||
#define MONEY bit(7)
|
#define MONEY bit(7)
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ struct cmndstr player_coms[] = {
|
||||||
0, edit, C_MOD, GOD},
|
0, edit, C_MOD, GOD},
|
||||||
{"enable", 0, enab, C_MOD, GOD},
|
{"enable", 0, enab, C_MOD, GOD},
|
||||||
{"enlist <SECTS> <NUM>", 2, enli, C_MOD, NORM + MONEY + CAP},
|
{"enlist <SECTS> <NUM>", 2, enli, C_MOD, NORM + MONEY + CAP},
|
||||||
{"execute <INPUT FILE>", 0, execute, 0, VIS},
|
{"execute <INPUT FILE>", 0, execute, 0, VIS + EXEC },
|
||||||
{"explore <c|m> <SECT> <NUM> <PATH|DESTINATION>",
|
{"explore <c|m> <SECT> <NUM> <PATH|DESTINATION>",
|
||||||
1, explore, C_MOD, NORM + MONEY + CAP},
|
1, explore, C_MOD, NORM + MONEY + CAP},
|
||||||
{"financial", 0, fina, 0, NORM},
|
{"financial", 0, fina, 0, NORM},
|
||||||
|
|
|
@ -82,5 +82,6 @@ player_set_nstat(struct player *pl, struct natstr *np)
|
||||||
pl->nstat |= MONEY;
|
pl->nstat |= MONEY;
|
||||||
if (np->nat_stat == STAT_ACTIVE && !influx(np))
|
if (np->nat_stat == STAT_ACTIVE && !influx(np))
|
||||||
pl->nstat |= CAP;
|
pl->nstat |= CAP;
|
||||||
|
pl->nstat |= EXEC;
|
||||||
return pl->nstat;
|
return pl->nstat;
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,6 +261,7 @@ execute(void)
|
||||||
prexec(p);
|
prexec(p);
|
||||||
|
|
||||||
while (!failed && status()) {
|
while (!failed && status()) {
|
||||||
|
player->nstat &= ~EXEC;
|
||||||
if (recvclient(buf, sizeof(buf)) < 0)
|
if (recvclient(buf, sizeof(buf)) < 0)
|
||||||
break;
|
break;
|
||||||
if (parse(buf, scanspace, player->argp, player->comtail,
|
if (parse(buf, scanspace, player->argp, player->comtail,
|
||||||
|
@ -278,6 +279,7 @@ execute(void)
|
||||||
if (failed) {
|
if (failed) {
|
||||||
while (recvclient(buf, sizeof(buf)) >= 0) ;
|
while (recvclient(buf, sizeof(buf)) >= 0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr("Execute : %s\n", failed ? "aborted" : "terminated");
|
pr("Execute : %s\n", failed ? "aborted" : "terminated");
|
||||||
player->eof = 0;
|
player->eof = 0;
|
||||||
return RET_OK;
|
return RET_OK;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue