[Date Prev] [Date Index] [Date Next] [Thread Prev] [Thread Index] [Thread Next]

[PATCH] Breaksequence list expansion from 9 to 35.

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