dparrish / libcli

Libcli provides a shared library for including a Cisco-like command-line interface into other software. It's a telnet interface which supports command-line editing, history, authentication and callbacks for a user-definable function tree.
https://dparrish.com/link/libcli
GNU Lesser General Public License v2.1
289 stars 143 forks source link

does libcli support concatinated command+arg? #56

Closed agva123 closed 4 years ago

agva123 commented 4 years ago

Say I have the following command under config term subtree:

interface eth0 ip 1.1.1.1 mask-len 24

where eth0, 1.1.1.1 and 24 are filtered results after I type the corresponding command.

Currently, if I create an "interface" command with an argument of interface name, then create an "ip" command with the "interface" command as its parent, when the cli runs it will skip the interface name parameter but goes directly to "ip", e.g.

"interface ?" will show "interface ip" as the only help string.

Thanks

RobSanders commented 4 years ago

Are you running the cli-test program for the above, or your own code?

agva123 commented 4 years ago

It is my own code. Thanks!

On Tue, Nov 19, 2019 at 9:54 PM Rob Sanders notifications@github.com wrote:

Are you running the cli-test program for the above, or your own code?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dparrish/libcli/issues/56?email_source=notifications&email_token=ABAMQUCXT7SJIN4LDJOBHPTQUPVXRA5CNFSM4JORM6M2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEOILYA#issuecomment-555517408, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABAMQUHLG74FFTXEKAXCA6TQUPVXRANCNFSM4JORM6MQ .

RobSanders commented 4 years ago

And which version are you running against? Anything before 1.10 doesn't support help or completion for anything except commands. As of 1.10 libcli does support named options and arguments, that may support help and tab completion if you write the appropriate helper routines. I updated clitest to demostrate this with the 'perimeter' command. Didn't update the others clitest commands however.

agva123 commented 4 years ago

Thanks. I read the perimeter example and it seems to only demonstrate the following types of commands: perimeter transparent, or perimeter verbose, or perimeter color (black | white | gray | ...)

whereas in my example it has a concatenation of command + parameters, e.g. interface eth0 ip 1.1.1.1 mask-len 24

I debugged the libcli code and do not feel that it is currently supported. Could you shed some light as to how one possibly change to support this scenario?

Thank you!

RobSanders commented 4 years ago

Think of it in this way in pseudo-code c=cli_register_comand ("interface",...) cli_register_optarg(CLI_CMD_ARGUMENT, "nic") cli_register_optarg(CLI_CMD_OPTIONAL_ARGUMENT, "ip") cli_register_optarg(CLI_CMD_OPTIONAL_ARGUMENT,"mask-len")

Then for the 'interface' command the first argument (required) will be the nic. Since it is required it positional. Then you have two optional arguments (ip and mask-len). Since they are optional, you must 'name' them on the command line to be recognized. You could then either register a CLI_CMD_SPOT_CHECK optarg to looks for both 'ip' and 'mask-len' settings (cli_optarg_get_value(...)) or have your callback require both of those fields to be set. I think clitest shows the spot check method for the perimeter command.

RobSanders commented 4 years ago

As a side note - our commercial application does things like this all the time. One example being almost exactly your use case above to configure a NIC.

RobSanders commented 4 years ago

Also, the 'perimeter' command would accept the following: perimeter color blue triangle 3 4 5

If you changed the cli_register_optarg() calls for side_1,side_2, and side_3 to be 'CLI_CMD_OPTIONAL_ARGUMENT' (total of 7 spots) and rebuild then the same command would be: perimeter color blue triangle side_1 3 side_2 4 side_3 5

agva123 commented 4 years ago

Very helpful comments. I was able to configure the command in the way you described and it works great! Thanks for the detailed explanation!