The code that makes up `sdsi2sh' isn't the prettiest. This is
because sdsi2sh was originally conceived more as a tool for
testing, and not as a prime-time program. Its command parsing, type
checking, and symbol table management are all very quick-and-dirty. For
these reasons, its actual design is not documented very much here.(7)
However, one goal of sdsi2sh was to make it very easy to add new
commands to it. The file sdsi2sh-commands.c contains all of the
functions that implement the various shell commands. Every function
that implements a command has the same prototype: something * function-name(something *);
A something is the data structure used to pass values of many
types within the shell. A something can represent
a SDSI S-expression, bytestring, or an integer.
somethings can made into a linked list; this
is how multiple arguments are passed into a command function.
Command functions optionally return a single something containing the
result of the command. A something indicates what type of
thing it actually represents, and includes
the value of that thing.
Adding a new command to the shell involves the following tasks:
FUNC macro to the top of
sdsi2sh-commands.c using the name of the new function.
commands array.
commands is an initialized array of elements of type
command - a data structure that holds a command declaration.
An example element of the commands array is for the sign
command:
/* sign: */
{ "sign", do_sign, "oI",
"signs an object",
"usage: sign <object> [<include-key-as-hash-flag>] - returns your \n" \
" signature on <object>. if <include-key-as-hash-flag> is given,\n" \
" includes the verification key as a hash instead of outright.\n" }
The fields of a command structure are, in order:
somethings
passed in, hand them to a library function, and package the return
value back into a something. The function implementing
the shell's sign command is a good example of this:
/* the "sign" command: */
something * do_sign(args)
something *args;
{
something *ret;
ret = new_thing(NULL);
ret->what = AN_SEXP;
sdsi2_signature_compute(&args->the_sexp, &ret->the_sexp.signature,
&speaker_private_key, &speaker_public_key, args->next->the_int);
return(ret);
}
A command's argument list description (given in the third element of its commands element)
is a string where each
character represents an argument, and indicates the type of something
that argument must be. The valid characters are:
o
s
i
The case of an o, s, or i is significant. If a
letter is capitalized, this causes an empty object (or, in the case of
an integer, the value zero) to be passed in as the corresponding
argument if none is specified on the command line - in other words, a
capitalized argument type specifies that an argument is optional,
and defaults to a suitable "empty" value.
In an argument list description, the first optional argument must be followed by all optional arguments. It is impossible to follow an optional argument with any mandatory arguments.
Go to the first, previous, next, last section, table of contents.