Thread: terminal emulation?

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    89

    terminal emulation?

    When I am connecting to a telnet server using a socket I get all the garbage characters that you would not normally get using a telnet client. I was wondering how I can remove these characters from my final output. An example is:

    Code:
    ______________________________________________________________________________←[
    004;001H_←[004;080H_←[005;001H_←[005;080H_←[006;001H_←[006;080H_←[007;001H_←[007
    ;080H_←[008;001H_←[008;080H_←[009;001H_←[009;080H_←[010;001H_←[010;080H_←[011;00
    1H_←[011;080H_←[012;001H_←[012;020H←[0m←[7m←(B Reports .........................
    .... 1 ←[012;080H←[0m←(0_←[013;001H_←[013;021H←[0m←(BSetup←[013;027Hand←[013;031
    HDefinitions←[013;043H...............←[013;059H2←[013;080H←[0m←(0_←[014;001H_←[0
    14;021H←[0m←(BStatus←[014;028HMonitor←[014;036H......................←[014;059H3
    ←[014;080H←[0m←(0_←[015;001H_←[015;080H_←[016;001H_←[016;080H_←[017;001H_←[017;0
    80H_←[018;001H_←[018;080H_←[019;001H_←[019;080H_←[022;029H←[0m←(BPlease←[022;036
    HEnter←[022;042HChoice←[022;049H:←[022;051H←[0m←[1m←(B1←[022;080H←[0m←(0_←[023;0
    01H_____________________________________________________________________________
    I couldn't really find any concrete pattern to all those escape sequences (which I believe they are). I mean I know programmitically how to go about doing this but I just was wondering if there is an easier way to determine what is garbage and what is not.

    thanks

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    I think you should be able to set your TERM environment variable to something that termcap recognizes as non-ANSI. That should prevent it from sending those escape sequences in the first place.
    If you understand what you're doing, you're not learning anything.

  3. #3
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    What do you consider garbage? What does your program try to do? I'm confused as to how to determine "what is garbage": those escape code carry meaning to the normal telnet user: the majority of them are cursor movements. To a program doing automated work or displaying a custom interface, they probably just get in the way: I'd remove them. (That server also seems to send an excessive amount of escape sequences... like a full cursor move where a single ' ' would do it. (Perhaps a un-smart library...))

    Escape sequences generally follow the sequence of escape character, 0+ semi-colon-separated numbers, and the a letter. (I've never seen any that don't follow that, feel free to correct me.) If regex is available, then I believe this would work: \x1B[0-9;]*[a-zA-Z] (0x1B is the escape character.)

    itsme86: How would TERM/termcap affect anything here? He's reading a telnet server's output through a socket - Nothing need be outputted, but could be. (And we don't know if he has control over the server.) Telnet includes specs to negociate a terminal type: why not negociate one that doesn't include escape characters?
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    http://www.isthe.com/chongo/tech/comp/ansi_escapes.html
    For what they all mean.

    Filtering all of them out is pretty easy, as Cactus_Hugger suggests. What you should end up with is the raw text, but you'll probably lose some formatting along the way.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by Cactus_Hugger
    tsme86: How would TERM/termcap affect anything here? He's reading a telnet server's output through a socket - Nothing need be outputted, but could be. (And we don't know if he has control over the server.) Telnet includes specs to negociate a terminal type: why not negociate one that doesn't include escape characters?
    The latter is actually what I meant. Telling the server that you don't support ANSI saves bandwidth and CPU cycles. It's easier that way than having the server send you stuff that you're just going to filter out anyway.
    If you understand what you're doing, you're not learning anything.

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    89
    Okay to clarify some things:

    - I do not have control over the server
    - Formatting is not necessary because I am only interested in the raw text strings. I am using these strings to determine if I am at a specific screen or menu.
    - I have re-written what I had to use an outside program to handle the telnet and pipe info back and forth. The outside program is plink (command line version of putty) but I will have to look into whether or not I can choose which emulation it uses or how.
    - If it looks like the server is doing something stupid it probably is, which is the reason I am writing a frontend for it to handle the small stupid things the server requires or does.

    Okay here is the code I came up with once I figured out the rules for the escape chars. It's not perfect but I think it will get rid of 90% of the stuff but it keeps causing an Assertion error while running.

    Code:
    //ret is the string taken from the plink session
    string::iterator it1;
    string::iterator it2;
    for(it1 = ret.begin(); it1 != ret.end(); ++it1){
    	   if(*it1 == '0x1B'){
    		   for(it2 = it1+1; it2 != ret.end(); ++it2){
    			   if(isalpha(*it2)){
    				   ret.replace(it1, it2, "");
    				   it1 = it2+1;
    			   }
    		   }
    	   }
       }
    here is the error:
    Code:
    Debug Assertion Failed!
    
    Program: ...
    File: C:\Program Files\Microsoft Visual Studio 8\VC\include\xstring
    Line: 173
    thanks
    Last edited by ac251404; 08-03-2006 at 08:19 AM.

  7. #7
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Code:
    if(*it1 == '0x1B'){
    Take the 0x1B out of the single quotes.
    If you understand what you're doing, you're not learning anything.

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    89
    tried that and I also tried using "[" instead of 0x1B with no luck. Any other ideas?

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > for(it2 = it1+1;
    This doesn't cause the escape to be replaced

    > if(isalpha(*it2))
    This is also your loop exit condition.
    You're only deleteing the final letter at the moment.

    Not EVERYTHING between the escape and the letter (inclusive).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    May 2006
    Posts
    89
    I got it working, somewhat, with the following:

    Code:
    for(it1 = ret.begin(); it1 != ret.end(); ++it1){
    	   if(*it1 == 0x1B){
    		   for(it2 = it1; it2 != ret.end(); ++it2){
    			   if(isalpha(*it2)){
    				   ret.replace(it1, it2+1, "");
    				   break;
    			   }
    		   }
    	   }
       }
    I originally forgot my break statement. For some reason though it is missing some escapes and I'm not sure how that could be.

  11. #11
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    I'm shaky when it comes to iterators, but, are iterators valid after the string has changed? What if two escape sequences come in a row, you replace the first one. After the replacement, but before the break - it1 points to what? If it's the same place in the string, then it'll be the 0x1b of the next escape seqence, but when you break;, it1 is incremented, and misses that second 0x1b.
    Perhaps remove ++it1 from the for, and only increment it1 if the if(*it1 == 0x1B) fails. As:
    Code:
    	for(it1 = ret.begin(); it1 != ret.end();)
    	{
    		if(*it1 == 0x1B)
    		{
    			for(it2 = it1; it2 != ret.end(); ++it2)
    			{
    				if(isalpha(*it2))
    				{
    					ret.replace(it1, it2+1, "");
    					break;
    				}
    			}
    		}
    		else ++it1;
    	}
    Still, if you can get the server to not send these, that'd be best.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Redirect ouput to another instance terminal window.
    By johnlovestohate in forum C++ Programming
    Replies: 1
    Last Post: 04-18-2009, 03:27 PM
  2. Problem Clearing Terminal
    By mrginger in forum C Programming
    Replies: 3
    Last Post: 04-15-2009, 11:58 AM
  3. Console, Terminal and Terminal Emulator
    By lehe in forum C Programming
    Replies: 4
    Last Post: 02-15-2009, 09:59 PM
  4. using su with pseudo terminal
    By oncemyway in forum Linux Programming
    Replies: 2
    Last Post: 04-30-2007, 10:52 AM
  5. video game emulation
    By Shadow in forum A Brief History of Cprogramming.com
    Replies: 21
    Last Post: 04-26-2002, 09:19 AM