text
[RRG-proxmark3.git] / doc / cliparser.md
bloba837a5afcddd39a7a461bd946a9f8d7ba7891790
1 # Cliparser
3 The old style with mixed custom commandline parsing of user parameters or options was messy and confusing.  You can find all kinds in the Proxmark3 client.
4 Samples
5 ```
6 data xxxx h
7 script run x.lua -h
8 hf 14a raw -h
9 hf 14b raw -ss
10 lf search 1
11 lf config h H
12 ```
13 even the external tools which we collected into this repo,  under folder */tools/* folder uses their own argument parsing.
16 In order to counter this and unify it,  there was discussion over at the official repository a few years ago [link to issue](https://github.com/Proxmark/proxmark3/issues/467) and there it became clear a change is needed. Among the different solutions suggested @merlokk's idea of using the lib cliparser was agreed upon. The lib was adapted and implemented for commands like
18 ```
19 [usb] pm3 --> emv
20 [usb] pm3 --> hf fido
21 ```
23 And then it fell into silence since it wasn't well documented how to use the cliparser. Looking at source code wasn't very efficient. However the need of a better cli parsing was still there.
25 Fast forward today, where more commands has used the cliparser but it still wasn't the natural way when adding a new client command to the Proxmark3 client.
26 After more discussions among @doegox, @iceman1001 and @mrwalker the concept became more clear on how to use the cliparser lib in the _preferred_ way.
28 The aftermath was a design and layout specified which lead to a simpler implementation of the cliparser in the client source code while still unifying all helptexts with the new colours support and a defined layout. As seen below, the simplicity and clearness.
30 ![sample of new style helptext](http://www.icedev.se/proxmark3/helptext.png)
33 Furthermore @mrwalker offered to take notes and thus this document was created.
35 This is the _new_ and _preferred_ way to implement _helptext_ and _cli parsing_ for Proxmark3 client commands and it's external tools.
38 ## cliparser setup and use
40 The parser will format and color and layout as needed.
41 It will also add the `-h --help` option automatic.
43 ## design comments
45 * where possible all options should be lowercase.
46 * extended options preceded with -- should be short
47 * options provided directly (without an option identifier) should be avoided.
48 * -vv for extra verbose should be avoided; use of debug level is preferred.
49 * with --options the equal is not needed (will work with and without) so don't use '='
50   e.g. cmd --cn 12345
54 ## common options
55     -h --help       : help
56     --cn            : card number
57     --fn            : facility number
58     --q5            : target is LF T5555/Q5 card
59     --em            : target is LF EM4305/4469 card
60     --raw           : raw data
61     -d --data       : hex data supplied
62     -f --file       : filename supplied
63     -k --key        : key supplied
64     -n --keyno      : key number to use
65     -p --pwd        : password supplied
66     -v --verbose    : flag when output should provide more information, not considered debug.
67     -1 --buffer     : use the sample buffer
71 ## How to implement in source code
73 ### setup the parser data structure
74 Header file to include
76     #include "cliparser.h"
78 In the command function, setup the context
80     CLIParserContext *ctx;
83 ### define the context
84 `CLIParserInit (\<context\>, \<description\>, \<notes\n examples ... \>);`
86 use -> to separate example and example comment and \\n to separate examples.
87 e.g. lf indala clone -r a0000000a0002021 -> this uses .....
89     CLIParserInit(&ctx, "lf indala clone",
90                   "clone INDALA UID to T55x7 or Q5/T5555 tag",
91                   "lf indala clone --heden 888\n"
92                   "lf indala clone --fc 123 --cn 1337\n"
93                   "lf indala clone -r a0000000a0002021\n"
94                   "lf indala clone -l -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5");
96 ### define the options
98     void *argtable[] = {
99         arg_param_begin,
100         arg_lit0("l", "long", "optional - long UID 224 bits"),
101         arg_int0("c", "heden", "<decimal>", "Cardnumber for Heden 2L format"),
102         arg_strx0("r", "raw", "<hex>", "raw bytes"),
103         arg_lit0("q", "Q5", "optional - specify writing to Q5/T5555 tag"),
104         arg_int0(NULL, "fc", "<decimal>", "Facility Code (26 bit format)"),
105         arg_int0(NULL, "cn", "<decimal>", "Cardnumber (26 bit format)"),
106         arg_param_end
107     };
109 _All options has a parameter index,  since `-h --help` is added automatic, it will be assigned index 0.
110 Hence all options you add will start at index 1 and upwards. It added in the define "arg_param_begin_
112 ### Notes:
113 #### bool option.  true if supplied
114 `bool : arg_lit0 ("<short option>", "<long option>", <"description">)`
116 #### integer that is optional
117 `optional integer : arg_int0 ("<short option>", "<long option>", "<format>", <"description">)`
119 #### integer that is required
120 `required integer : arg_int1 ("<short option>", "<long option>", "<format>", <"description">)`
122 #### double that is optional
123 `optional double : arg_dbl0 ("<short option>", "<long option>", "<format>", <"description">)`
125 #### double that is required
126 `required double : arg_dbl1 ("<short option>", "<long option>", "<format>", <"description">)`
128 #### String option that is optional and only one instance can be provided
129 `optional string : arg_str0 ("<short option>", "<long option>", "<format>", <"description">)`
131 #### String option that is required and only one instance can be provided
132 `required string : arg_str1 ("<short option>", "<long option>", "<format>", <"description">)`
134 #### String option that is optional and can have up to 250 instances provided
135 `optional string : arg_strx0 ("<short option>", "<long option>", "<format>", <"description">)`
137 #### String option that is required/at least one instance and can have up to 250 instances
138 `required string : arg_strx1 ("<short option>", "<long option>", "<format>", <"description">)`
140 Unsigned values, like  u32 and u64 can be accomplished with
142 #### unsigned integer optional
143 `optional unsigned : arg_u64_0 ("<short option>", "<long option>", "<format>", <"description">)`
145 #### unsigned integer required
146 `required unsigned : arg_u64_1 ("<short option>", "<long option>", "<format>", <"description">)`
149 **if an option does not have a short or long option, use NULL in its place**
152 ### show the menu
153 `CLIExecWithReturn(\<context\>, \<command line to parse\>, \<arg/opt table\>, \<return on error\>);`
155     CLIExecWithReturn(ctx, Cmd, argtable, false);
157 ### clean up
158 Once you have extracted the options, cleanup the context.
160     CLIParserFree(ctx);
162 ### retrieving options
165 The parser will format and color and layout as needed.
166 It will also add the `-h --help` option automatic.
169 **bool option**
170 arg_get_lit(\<context\>, \<opt index\>);
172     is_long_uid = arg_get_lit(ctx, 1);
174 **int option**
175 arg_get_int_def(\<context\>, \<opt index\>, \<default value\>);
177     cardnumber = arg_get_int_def(ctx, 2, -1);
180 **uint32**
181 arg_get_u32_def(\<context\>, \<opt index\>, \<default value\>);
183     cardnumber = arg_get_u32_def(ctx, 2, 0);
185 **uint64**
186 arg_get_u64_def(\<context\>, \<opt index\>, \<default value\>);
188     cardnumber = arg_get_u64_def(ctx, 2, 0);
191 **hex option with return**
192 CLIGetHexWithReturn(\<context\>, \<opt index\>, \<store variable\>, \<ptr to stored length\>);
193     ?? as an array of uint_8 ??
194     If failed to retrieve hexbuff, it will exit fct
196     uint8_t aid[2] = {0};
197     int aidlen;
198     CLIGetHexWithReturn(ctx, 2, aid, &aidlen);
201 **hex option**
203     uint8_t key[24] = {0};
204     int keylen = 0;
205     int res_klen = CLIParamHexToBuf(arg_get_str(ctx, 3), key, 24, &keylen);
207     quick test : seems res_keylen == 0 when ok so not key len ???
209 **string option return**
210 CLIGetStrWithReturn(\<context\>,\<opt index\>, \<uint8_t \*\>, \<int \*\>);
211     If failed to retrieve string, it will exit fct
213     uint8_t buffer[100];
214     int slen = sizeof(buffer); // <- slen MUST be the maximum number of characters that you want returned. e.g. Buffer Size
215     CLIGetStrWithReturn(ctx, 1, buffer, &slen);
217 **string option**     
218 Getting a char array 
220     int slen = 0;
221     char format[16] = {0};
222     int res = CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)format, sizeof(format), &slen);
224     quick test : seem res == 0, then ok.  compare res == slen to see how many chars