[Date Prev] [Date Index] [Date Next] [Thread Prev] [Thread Index] [Thread Next]
Artem Savkov asavkov@redhat.com
Thu, 5 Mar 2015 11:53:34 GMT
This patch expands breaksequence list from 9 to 35 positions adding a-z range to possible bind characters. Signed-off-by: Artem Savkov <asavkov@redhat.com> --- conserver.cf/conserver.cf.man | 6 ++-- conserver/client.c | 64 +++++++++++++++++++++---------------------- conserver/consent.h | 2 +- conserver/convert.c | 12 ++++++-- conserver/group.c | 37 +++++++++++++++++-------- conserver/main.c | 2 +- conserver/readcfg.c | 33 ++++++++++++++++------ conserver/readcfg.h | 4 ++- 8 files changed, 100 insertions(+), 60 deletions(-) diff --git a/conserver.cf/conserver.cf.man b/conserver.cf/conserver.cf.man index 58cdc1a..70a6372 100644 --- a/conserver.cf/conserver.cf.man +++ b/conserver.cf/conserver.cf.man @@ -212,9 +212,11 @@ connections from the hosts without username authentication. .TP \f3break\fP \f2n\fP .br -Define a break sequence where 0 < +Define a break sequence where (0 < .I n -< 10. +< 10) or (a < +.I n +< z). Break sequences are accessed via the .RI ``^Ecl n '' client escape sequence. diff --git a/conserver/client.c b/conserver/client.c index 83c68f2..ae848e8 100644 --- a/conserver/client.c +++ b/conserver/client.c @@ -373,39 +373,39 @@ typedef struct HLnode { } HELP; static HELP aHLTable[] = { - {WHEN_ALWAYS, ". disconnect"}, + {WHEN_ALWAYS, ". disconnect"}, {WHEN_ALWAYS | IS_LIMITED, "; move to another console"}, - {WHEN_ALWAYS, "a attach read/write"}, - {WHEN_ALWAYS, "b send broadcast message"}, - {WHEN_ATTACH, "c toggle flow control"}, - {WHEN_ATTACH, "d down a console"}, - {WHEN_ALWAYS, "e change escape sequence"}, - {WHEN_ALWAYS, "f force attach read/write"}, - {WHEN_ALWAYS, "g group info"}, - {WHEN_ALWAYS, "i information dump"}, - {WHEN_ATTACH, "L toggle logging on/off"}, - {WHEN_ATTACH, "l? break sequence list"}, - {WHEN_ATTACH, "l0 send break per config file"}, - {WHEN_ATTACH, "l1-9 send specific break sequence"}, - {WHEN_ALWAYS, "m display the message of the day"}, - {WHEN_ALWAYS, "n write a note to the logfile"}, - {WHEN_ALWAYS, "o (re)open the tty and log file"}, - {WHEN_ALWAYS, "p playback the last %hu lines"}, - {WHEN_ALWAYS, "P set number of playback lines"}, - {WHEN_ALWAYS, "r replay the last %hu lines"}, - {WHEN_ALWAYS, "R set number of replay lines"}, - {WHEN_ATTACH, "s spy mode (read only)"}, - {WHEN_ALWAYS, "u show host status"}, - {WHEN_ALWAYS, "v show version info"}, - {WHEN_ALWAYS, "w who is on this console"}, - {WHEN_ALWAYS, "x show console baud info"}, - {WHEN_ALWAYS | IS_LIMITED, "z suspend the connection"}, - {WHEN_ATTACH, "! invoke task"}, - {WHEN_ATTACH | IS_LIMITED, "| attach local command"}, - {WHEN_ALWAYS, "? print this message"}, - {WHEN_ALWAYS, "<cr> ignore/abort command"}, - {WHEN_ALWAYS, "^R replay the last line"}, - {WHEN_ATTACH, "\\ooo send character by octal code"}, + {WHEN_ALWAYS, "a attach read/write"}, + {WHEN_ALWAYS, "b send broadcast message"}, + {WHEN_ATTACH, "c toggle flow control"}, + {WHEN_ATTACH, "d down a console"}, + {WHEN_ALWAYS, "e change escape sequence"}, + {WHEN_ALWAYS, "f force attach read/write"}, + {WHEN_ALWAYS, "g group info"}, + {WHEN_ALWAYS, "i information dump"}, + {WHEN_ATTACH, "L toggle logging on/off"}, + {WHEN_ATTACH, "l? break sequence list"}, + {WHEN_ATTACH, "l0 send break per config file"}, + {WHEN_ATTACH, "l1-9a-z send specific break sequence"}, + {WHEN_ALWAYS, "m display the message of the day"}, + {WHEN_ALWAYS, "n write a note to the logfile"}, + {WHEN_ALWAYS, "o (re)open the tty and log file"}, + {WHEN_ALWAYS, "p playback the last %hu lines"}, + {WHEN_ALWAYS, "P set number of playback lines"}, + {WHEN_ALWAYS, "r replay the last %hu lines"}, + {WHEN_ALWAYS, "R set number of replay lines"}, + {WHEN_ATTACH, "s spy mode (read only)"}, + {WHEN_ALWAYS, "u show host status"}, + {WHEN_ALWAYS, "v show version info"}, + {WHEN_ALWAYS, "w who is on this console"}, + {WHEN_ALWAYS, "x show console baud info"}, + {WHEN_ALWAYS | IS_LIMITED, "z suspend the connection"}, + {WHEN_ATTACH, "! invoke task"}, + {WHEN_ATTACH | IS_LIMITED, "| attach local command"}, + {WHEN_ALWAYS, "? print this message"}, + {WHEN_ALWAYS, "<cr> ignore/abort command"}, + {WHEN_ALWAYS, "^R replay the last line"}, + {WHEN_ATTACH, "\\ooo send character by octal code"}, }; /* list the commands we know for the user (ksb) diff --git a/conserver/consent.h b/conserver/consent.h index 8cb39e5..5eebb81 100644 --- a/conserver/consent.h +++ b/conserver/consent.h @@ -130,7 +130,7 @@ typedef struct consent { /* console information */ char *udssubst; /* socket file substitution pattern */ /* global stuff */ char *master; /* master hostname */ - unsigned short breakNum; /* break type [1-9] */ + unsigned short breakNum; /* break type [1-35] */ char *logfile; /* logfile */ off_t logfilemax; /* size limit for rolling logfile */ char *initcmd; /* initcmd command */ diff --git a/conserver/convert.c b/conserver/convert.c index 10dd6ef..fd6f223 100644 --- a/conserver/convert.c +++ b/conserver/convert.c @@ -222,7 +222,8 @@ ReadCfg(char *pcFile, FILE *fp) printf("\tinclude full;\n}\n"); } else if (0 == strcmp(acStart, "DOMAINHACK")) { } else if (0 == strncmp(acStart, "BREAK", 5) && - acStart[5] >= '1' && acStart[5] <= '9' && + ((acStart[5] >= '1' && acStart[5] <= '9') || + (acStart[5] >= 'a' && acStart[5] <= 'z')) && acStart[6] == '\000') { CONDDEBUG((1, "ReadCfg(): BREAK%c found with `%s'", acStart[5], pcLine)); @@ -342,10 +343,15 @@ ReadCfg(char *pcFile, FILE *fp) if (pcBreak) { int bt; bt = atoi(pcBreak); - if (bt > 9 || bt < 0) { + if (bt > BREAKLISTSIZE || bt < 0) { Error("%s(%d) bad break spec `%d'", pcFile, iLine, bt); } else { - printf("\tbreak %d;\n", bt); + char btc = 0; + if (bt < 10 ) + btc = bt + '0'; + else + btc = bt + 'a' - 10; + printf("\tbreak %c;\n", btc); } } diff --git a/conserver/group.c b/conserver/group.c index 99f0fcd..c0e66ff 100644 --- a/conserver/group.c +++ b/conserver/group.c @@ -1634,7 +1634,11 @@ ExpandString(char *str, CONSENT *pCE, short breaknum) continue; } else if (s == 'd') { PutConsole(pCE, IAC, 0); - PutConsole(pCE, '0' + breaknum, 0); + if (breaknum > 9) { + PutConsole(pCE, '0' + breaknum + ALPHAOFFSET, 0); + } else { + PutConsole(pCE, '0' + breaknum, 0); + } continue; } else if (s == 'z') { PutConsole(pCE, IAC, 0); @@ -1680,7 +1684,7 @@ SendBreak(CONSCLIENT *pCLServing, CONSENT *pCEServing, short bt) CONSCLIENT *pCL; short waszero = 0; - if (bt < 0 || bt > 9) { + if (bt < 0 || bt > BREAKLISTSIZE) { FileWrite(pCLServing->fd, FLAGFALSE, "aborted]\r\n", -1); return; } @@ -3522,7 +3526,8 @@ DoClientRead(GRPENT *pGE, CONSCLIENT *pCLServing) case S_HALT1: /* halt sequence? */ pCLServing->iState = S_NORMAL; if (acIn[i] != '?' && - (acIn[i] < '0' || acIn[i] > '9')) { + ((acIn[i] < '0' || acIn[i] > '9') && (acIn[i] < 'a' || + acIn[i] > 'z'))) { FileWrite(pCLServing->fd, FLAGFALSE, "aborted]\r\n", -1); continue; @@ -3530,13 +3535,14 @@ DoClientRead(GRPENT *pGE, CONSCLIENT *pCLServing) if (acIn[i] == '?') { int i; + int mod = i > 8 ? ALPHAOFFSET : 0; FileWrite(pCLServing->fd, FLAGFALSE, "list]\r\n", -1); i = pCEServing->breakNum; if (i == 0 || breakList[i - 1].seq->used <= 1 || pCEServing->breaklist == (char *)0 || ((char *)0 == - strchr(pCEServing->breaklist, '1' + i) + strchr(pCEServing->breaklist, '1' + i + mod) && (char *)0 == strchr(pCEServing->breaklist, '*'))) FileWrite(pCLServing->fd, FLAGTRUE, @@ -3552,20 +3558,26 @@ DoClientRead(GRPENT *pGE, CONSCLIENT *pCLServing) acA1->string); } if (pCEServing->breaklist != (char *)0) { - for (i = 0; i < 9; i++) { + for (i = 0; i < BREAKLISTSIZE; i++) { + int mod = i > 8 ? ALPHAOFFSET : 0; if ((char *)0 == strchr(pCEServing->breaklist, - '1' + i) + '1' + i + mod) && (char *)0 == strchr(pCEServing->breaklist, '*')) continue; if (breakList[i].seq->used > 1) { + char btc = 0; + if (i < 9) + btc = i + '0'; + else + btc = i + 'a' - 10; FmtCtlStr(breakList[i].seq->string, breakList[i].seq->used - 1, acA1); FilePrint(pCLServing->fd, FLAGTRUE, - " %d - %3dms, `%s'\r\n", - i + 1, + " %c - %3dms, `%s'\r\n", + btc + 1, breakList[i].delay, acA1->string); } @@ -3576,6 +3588,8 @@ DoClientRead(GRPENT *pGE, CONSCLIENT *pCLServing) } else { if (pCLServing->fwr) { int bt = acIn[i] - '0'; + if (bt > 48) + bt -= ALPHAOFFSET; SendBreak(pCLServing, pCEServing, bt); } else FileWrite(pCLServing->fd, FLAGFALSE, @@ -4139,7 +4153,7 @@ FlushConsole(CONSENT *pCEServing) } else { /* wbufIAC == 2 */ unsigned char next = (unsigned char)pCEServing->wbuf->string[offset + 1]; - if ((next >= '0' && next <= '9') || + if ((next >= '0' && next <= '9') || (next >= 'a' && next <= 'z') || (next == BREAK && pCEServing->type != HOST)) { CONDDEBUG((1, "Kiddie(): heavy IAC for [%s]", pCEServing->server)); @@ -4171,10 +4185,11 @@ FlushConsole(CONSENT *pCEServing) } /* Do the operation */ - if (next >= '0' && next <= '9') { + if ((next >= '0' && next <= '9') || (next >= 'a' && next <= 'z')) { int delay = BREAKDELAYDEFAULT; + int mod = next > '9' ? ALPHAOFFSET : 0; if (next != '0') - delay = breakList[next - '1'].delay; + delay = breakList[next - '1' - mod].delay; /* in theory this sets the break length to whatever * the "default" break sequence is for the console. * but, i think it would be better to just use the diff --git a/conserver/main.c b/conserver/main.c index 5c2ce5d..b814e4a 100644 --- a/conserver/main.c +++ b/conserver/main.c @@ -1076,7 +1076,7 @@ DumpDataStructures(void) } } } - for (i = 0; i < 9; i++) { + for (i = 0; i < BREAKLISTSIZE; i++) { CONDDEBUG((1, "DumpDataStructures(): break: string=%s, delay=%d, confirm=%s", EMPTYSTR(breakList[i].seq->string), breakList[i].delay, diff --git a/conserver/readcfg.c b/conserver/readcfg.c index 3d77e4a..cea0b4d 100644 --- a/conserver/readcfg.c +++ b/conserver/readcfg.c @@ -45,10 +45,19 @@ CONSENTUSERS *pADList = (CONSENTUSERS *)0; CONSENTUSERS *pLUList = (CONSENTUSERS *)0; REMOTE *pRCUniq = (REMOTE *)0; CONFIG *pConfig = (CONFIG *)0; -BREAKS breakList[9] = { +BREAKS breakList[BREAKLISTSIZE] = { {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, - {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0} + {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, + {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, + {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, + {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, + {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, + {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, + {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, + {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, + {(STRING *)0, 0}, {(STRING *)0, 0}, {(STRING *)0, 0}, + {(STRING *)0, 0}, {(STRING *)0, 0} }; TASKS *taskList = (TASKS *)0; @@ -116,7 +125,7 @@ DestroyBreakList(void) { int i; - for (i = 0; i < 9; i++) { + for (i = 0; i < BREAKLISTSIZE; i++) { if (breakList[i].seq != (STRING *)0) { DestroyString(breakList[i].seq); breakList[i].seq = (STRING *)0; @@ -207,13 +216,15 @@ void BreakBegin(char *id) { CONDDEBUG((1, "BreakBegin(%s) [%s:%d]", id, file, line)); - if ((id == (char *)0) || (*id == '\000') || id[0] < '1' || id[0] > '9' - || id[1] != '\000') { + if ((id == (char *)0) || (*id == '\000') || ((id[0] < '1' || id[0] > '9') + && (id[0] < 'a' || id[0] > 'z')) || id[1] != '\000') { if (isMaster) Error("invalid break number `%s' [%s:%d]", id, file, line); parserBreakNum = 0; } else { parserBreakNum = id[0] - '0'; + if (parserBreakNum > 48) + parserBreakNum -= ALPHAOFFSET; if (parserBreak == (STRING *)0) parserBreak = AllocString(); else @@ -256,7 +267,7 @@ BreakDestroy(void) #if DUMPDATA { int i; - for (i = 0; i < 9; i++) { + for (i = 0; i < BREAKLISTSIZE; i++) { Msg("Break[%d] = `%s', delay=%d", i, breakList[i].seq == (STRING *)0 ? "(null)" : (breakList[i].seq-> @@ -888,8 +899,11 @@ ProcessBreak(CONSENT *c, char *id) c->breakNum = 0; return; } - if ((id[0] >= '1') && (id[0] <= '9') && (id[1] == '\000')) { + if (((id[0] >= '1' && id[0] <= '9') || + (id[0] >= 'a' && id[0] <= 'z')) && (id[1] == '\000')) { c->breakNum = id[0] - '0'; + if (c->breakNum > 48) + c->breakNum -= ALPHAOFFSET; return; } if (isMaster) @@ -2083,7 +2097,8 @@ ProcessBreaklist(CONSENT *c, char *id) for (token = strtok(id, ALLWORDSEP); token != (char *)0; token = strtok(NULL, ALLWORDSEP)) { if (token[1] != '\000' || - ((token[0] < '0' || token[0] > '9') && token[0] != '*')) { + (((token[0] < '0' || token[0] > '9') && + (token[0] < 'a' || token[0] > 'z')) && token[0] != '*')) { if (isMaster) Error("invalid breaklist reference `%s' [%s:%d]", token, file, line); @@ -5006,7 +5021,7 @@ ReadCfg(char *filename, FILE *fp) isStartup = (pGroups == (GRPENT *)0 && pRCList == (REMOTE *)0); /* initialize the break lists */ - for (i = 0; i < 9; i++) { + for (i = 0; i < BREAKLISTSIZE; i++) { if (breakList[i].seq == (STRING *)0) { breakList[i].seq = AllocString(); } else { diff --git a/conserver/readcfg.h b/conserver/readcfg.h index fb8167a..bc5da6e 100644 --- a/conserver/readcfg.h +++ b/conserver/readcfg.h @@ -7,6 +7,8 @@ */ #define BREAKDELAYDEFAULT 250 +#define BREAKLISTSIZE 35 +#define ALPHAOFFSET 39 typedef struct config { STRING *name; @@ -57,7 +59,7 @@ extern REMOTE *pRCUniq; /* list of uniq console servers */ extern ACCESS *pACList; /* `who do you love' (or trust) */ extern CONSENTUSERS *pADList; /* list of admin users */ extern CONSENTUSERS *pLUList; /* list of limited users */ -extern BREAKS breakList[9]; /* list of break sequences */ +extern BREAKS breakList[BREAKLISTSIZE]; /* list of break sequences */ extern TASKS *taskList; /* list of tasks */ extern SUBST *taskSubst; /* substitution function data for tasks */ extern CONFIG *pConfig; /* settings seen by config parser */ -- 2.1.0