[Java] Commandline input autocompletion

Pagina: 1
Acties:

  • froggie
  • Registratie: November 2001
  • Laatst online: 20-11-2024
Ik ben een netwerk app aan het schrijven waarin ik een kleine management console wil inbouwen. Het idee is dat je dmv telnet kunt inloggen op de app en on the fly settings kunt wijzigen (zoals in de zebra/quagga routing software). De console werkt prima maar ik zou graag autocompletion (zoals je dat tegenkomt in bijv unix shells zoals bash/zsh of de shells van IOS/JunOS) willen toevoegen om het gebruikersgemak te vergroten.

Ik heb op Google gezocht naar mogelijke literatuur over dit onderwerp om een beginnetje te hebben maar ik heb weinig tot niets kunnen vinden (wat ik tegen ben gekomen ging over GUI autocompletion). Ik heb wat zitten greppen in de bash sourcecode, maar heb ook hier nog niets zinnigs uit kunnen halen (zou goed kunnen dat ik op de verkeerde plaats kijk).

Heeft iemand misschien wat informatie voor me over hoe je dit implementeerd? De meest lullige documentjes worden al op prijs gesteld.

Mocht het van invloed zijn op de implementatie: de app is geschreven in Java en ik heb daarbij gebruik gemaakt van de "nieuwe" nonblocking IO API (SocketChannels en Selector) om de "virtuele terminals" aan de app te knopen.

[ Voor 12% gewijzigd door froggie op 10-10-2005 20:04 ]


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Zodra er op tab geduwd wordt kun je kijken wat er al ingetikt is, dat parsen naar directories/files, en in het laatste niveau kijken welke bestanden er met die letters die over blijven bestaan? Je zal dus steeds door lijsten met bestanden/directories loopen en op basis daarvan kijken wat je doen moet.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • froggie
  • Registratie: November 2001
  • Laatst online: 20-11-2024
Mja, het gaat in dit geval niet om bestanden maar een lijst met commands. Maar is het niet zo dat telnet de input pas verstuurd wanneer op enter wordt gedrukt (of moet ik gebruik gaan maken van een soort raw input methode)?

[ Voor 17% gewijzigd door froggie op 10-10-2005 20:07 ]


  • JaWi
  • Registratie: Maart 2003
  • Laatst online: 14-01 21:58

JaWi

maak het maar stuk hoor...

Kijk bijvoorbeeld eens naar (GNU) ReadLine: http://java-readline.sourceforge.net/

Statistics are like bikinis. What they reveal is suggestive, but what they hide is vital.


  • Fl4sh3r
  • Registratie: Juni 2002
  • Laatst online: 26-03 21:19
Het probleem vond ik wel interessant klinken, ik heb er dus ook even naar gekeken. Ik heb me nooit eerder echt verdiept in Telnet en Java is ook alweer een tijdje geleden.

Met de RFC over de Telnet Protocol Specification ben ik een heel eind gekomen.

Verwacht er niet al te veel van, maar misschien helpt het je wat opweg.
http://download.bleq.nl/TelnetServer.zip

  • froggie
  • Registratie: November 2001
  • Laatst online: 20-11-2024
Bedankt voor de tip. Ik begrijp nog niet helemaal hoe ze van readLine() gebruik kunnen maken zonder dat er een linefeed of return gegeven wordt. Daarnaast is readLine() een blocking call terwijl ik graag gebruik zou willen maken van non blocking IO (minder threads en dus minder concurrency situaties etc) maar ik zal kijken of ik hier nog wat mee kan.

@ Fl4sh3r: ik heb je code even vluchtig bekeken en het ziet er interessant uit. Jou implementatie zou ook moeten werken met non blocking IO omdat je alleen gebruik maakt van read en write. Ik duik hier morgen zeker wat dieper in. Overigens weet ik niet precies hoe de uitvoer van je code eruit moet zien maar ik kon geen autocompletion ontdekken. Misschien kun je ook je class files eens posten.

Mijn omgeving: OS Linux 2.6, JVM Sun 1.5.0_05

[ Voor 29% gewijzigd door froggie op 10-10-2005 22:10 ]


  • Fl4sh3r
  • Registratie: Juni 2002
  • Laatst online: 26-03 21:19
Client.java, vanaf regel 65:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
...
                } else if(a == 9) {
                    if(completionStateCounter == 0)
                        completingCommand = cmd;
                    String foundCmd = completer.complete(completingCommand, completionStateCounter++);

                    if(foundCmd != null) {
                        cmd = foundCmd;
                        out.write(("\r>"+cmd).getBytes());
                    } else
                        out.write('\007');
                } ...


a is de gelezen byte, als die 9 is (tab) wordt de completer gebruikt. Deze is eerder gedefineerd en gedeclareerd als CommandCompleter.

Verder stelt het programma niet heel veel voor, maar ik vind het we een leuk begin voor een standaard command-line class. Voor wanneer je redelijk snel een telnet-server wil toevoegen aan je applicatie.

Waarom wil je overigens de .class files erbij? Krijg je deze niet gecompiled? Of heb je überhaupt geen Java 1.4 meer? Ik gebruik Java 1.4.2.

  • Kuhlie
  • Registratie: December 2002
  • Niet online
Het probleem is misschien ook dat een aantal telnetclients pas data gaan versturen na een ram op de entertoets. Lees: voor zover ik weet doet de standaard unix/linux-telnet-client dat. Misschien kan je ze met een bepaalde escape-code ervan overtuigen dat ze dat niet moeten doen, maar zeker weten doe ik dat niet. Ik zou daar eerst eens naar kijken (of aannemen dat men Windows gebruikt, de daarbijbehorende telnetclient stuurt gewoon elk teken direct).

  • Fl4sh3r
  • Registratie: Juni 2002
  • Laatst online: 26-03 21:19
Inderdaad... als ik vanaf Linux telnet naar mijn Java telnet servertje werkt het niet zo goed meer.

Misschien vanavond wel even tijd om ernaar te kijken. Mocht iemand in de tussentijd al iets vinden dan lees ik het hier wel.

  • froggie
  • Registratie: November 2001
  • Laatst online: 20-11-2024
Wat prutsen (en het lezen van de manpage van telnet) leert mij dat de unix telnet client standaard in linemode staat. Wanneer je character mode gebruikt stuurt je client alles meteen door naar de server. Je server moet dan wel de input terug sturen (echo) anders zie je niets in je terminal.
Nu alleen nog even uitvogelen welke codes de terminal client moet krijgen om hem in character mode te krijgen, dan is het daarna alleen nog maar een kwestie om de input op te vangen en hier iets nuttigs mee te doen.

[ Voor 3% gewijzigd door froggie op 11-10-2005 10:49 ]


  • Fl4sh3r
  • Registratie: Juni 2002
  • Laatst online: 26-03 21:19
Handig tabelletje gevonden, of eigenlijk twee:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
+--------------+--------------+--------------+
| command naam | nummer (dec) | nummer (hex) |
+--------------+--------------+--------------+
| WILL         |   251        |   0xfb       |
| WONT         |   252        |   0xfc       |
| DO           |   253        |   0xfd       |
| DONT         |   254        |   0xfe       |
| IAC          |   255        |   0xff       | 
+--------------+--------------+--------------+

+-----------+--------------+--------------+ 
| arg. naam | nummer (dec) | nummer (hex) |
+-----------+--------------+--------------+
| echo      |     1        |   0x01       |
| linemode  |    34        |   0x22       |
| env. var. |    36        |   0x23       |
+-----------+--------------+--------------+


Wat meer info: http://hackers4hackers.org/reader.php?h4h=12&page=06

  • froggie
  • Registratie: November 2001
  • Laatst online: 20-11-2024
In RFC 1116 staat linemode gespecificeerd. Vooral paragraaf 5.10 is wel interessant.
Ik ben nu m'n server aan het aanpassen zodat ik wat sessie informatie kan opslaan (linemode aan|uit, echo aan|uit etc).

  • Fl4sh3r
  • Registratie: Juni 2002
  • Laatst online: 26-03 21:19
Ik zit nu al een aantal uurtjes te worstelen met subcommands completen. Zoals Cisco IOS doet.

Stel je hebt als commands:
aaa, aab en aac

aac heeft als subcommands
test1, test2, test3

Als je dan in een leeg scherm "a<tab><tab><tab>" drukt zit je bij "aac". Als je vervolgens drukt " <tab>" moet er dus komen te staan "aac test1", als er weer een <tab> volgt dient dit "aab test2" te worden.

Als iemand hier nou al een elegante oplossing voor heeft ben ik wel benieuwd.

Mijn TelnetServer werkt nu overigens zowel met de Windows als de Linux telnet.

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Voor de duidelijkheid, telnet is character-based. Elke character die je stuurt wordt apart over de lijn gestuurd. Mits je aan een telnet-server hangt. Als je telnet naar een willekeurige poort waar een niet-telnet daemon aanhangt gaat het inderdaad per regel. (Per line zou bijzonder kut zijn bij ncurses-achtige dingen enzo ;))

All my posts are provided as-is. They come with NO WARRANTY at all.


  • froggie
  • Registratie: November 2001
  • Laatst online: 20-11-2024
Fl4sh3r, zou je zo vriendelijk willen zijn de code te posten die je gebruikt om de client in te stellen (line mode en echo setten), voor zover je dat doet. Je zou mij daar bijzonder mee helpen.

[ Voor 3% gewijzigd door froggie op 11-10-2005 23:41 ]


  • Fl4sh3r
  • Registratie: Juni 2002
  • Laatst online: 26-03 21:19
De code is er niet veel netter op geworden. Alles dat ik getest heb qua linemode lijkt te werken, ook als je naar een andere poort dan telnet connect vanuit Linux.

http://download.bleq.nl/TelnetServer2.zip

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

De bash autocompletion is een los programma. Zie hier. En /etc/bash_completion op een linuxbak :).

Wie trösten wir uns, die Mörder aller Mörder?


  • Fl4sh3r
  • Registratie: Juni 2002
  • Laatst online: 26-03 21:19
Froggie nog een beetje voortgang geboekt? Ik heb zelf geen tijd meer gehad om ermee bezig te zijn, maar ben wel nieuwsgierig naar jouw nieuwe bevindingen.
Pagina: 1