Merge pull request #1896 from marschap/explorer-card-drivers
opensc-explorer: make '--card-driver ?' list all available drivers
This commit is contained in:
commit
61c20cf83d
|
@ -33,13 +33,6 @@ smart cards and similar security tokens based on Siemens Card/OS M4.
|
|||
<title>Options</title>
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--card-driver</option> <replaceable>name</replaceable>,
|
||||
<option>-c</option> <replaceable>name</replaceable></term>
|
||||
<listitem><para>Use the card driver specified by <replaceable>name</replaceable>.
|
||||
The default is to auto-detect the correct card driver.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--format</option>,
|
||||
|
|
|
@ -95,14 +95,6 @@
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--driver</option> <replaceable>driver</replaceable>,
|
||||
<option>-c</option> <replaceable>driver</replaceable>
|
||||
</term>
|
||||
<listitem><para>Specify the card driver <replaceable>driver</replaceable> to use.
|
||||
Default is use driver from configuration file, or auto-detect if absent</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--wait</option>,
|
||||
|
|
|
@ -55,8 +55,11 @@
|
|||
<option>-c</option> <replaceable>driver</replaceable>
|
||||
</term>
|
||||
<listitem><para>
|
||||
Use the given card driver. The default is
|
||||
auto-detected.
|
||||
Use the given card driver.
|
||||
The default is to auto-detect the correct card driver.
|
||||
The literal value <literal>?</literal> lists
|
||||
all available card drivers and terminates
|
||||
<command>opensc-explorer</command>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
|
|
@ -52,8 +52,12 @@
|
|||
<option>--card-driver</option> <replaceable>driver</replaceable>,
|
||||
<option>-c</option> <replaceable>driver</replaceable>
|
||||
</term>
|
||||
<listitem><para>Use the given card driver.
|
||||
The default is auto-detected.</para></listitem>
|
||||
<listitem><para>
|
||||
Use the given card driver.
|
||||
The default is to auto-detect the correct card driver.
|
||||
The literal value <literal>?</literal> lists
|
||||
all available card drivers.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
|
|
|
@ -163,14 +163,6 @@
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--card-driver</option> <replaceable>driver</replaceable>,
|
||||
<option>-c</option> <replaceable>driver</replaceable>
|
||||
</term>
|
||||
<listitem><para>Use the given card driver.
|
||||
The default is auto-detected.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--wait</option>,
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#endif
|
||||
|
||||
#include "libopensc/opensc.h"
|
||||
#include "libopensc/cards.h"
|
||||
#include "util.h"
|
||||
|
||||
static const char *app_name = "cardos-tool";
|
||||
|
@ -54,7 +55,6 @@ static const struct option options[] = {
|
|||
{"startkey", 1, NULL, 's'},
|
||||
{"change-startkey", 1, NULL, 'S'},
|
||||
{"reader", 1, NULL, 'r'},
|
||||
{"card-driver", 1, NULL, 'c'},
|
||||
{"wait", 0, NULL, 'w'},
|
||||
{"verbose", 0, NULL, 'v'},
|
||||
{NULL, 0, NULL, 0}
|
||||
|
@ -67,7 +67,6 @@ static const char *option_help[] = {
|
|||
"Specify startkey for format",
|
||||
"Change Startkey with given APDU command",
|
||||
"Uses reader number <arg> [0]",
|
||||
"Forces the use of driver <arg> [auto-detect]",
|
||||
"Wait for a card to be inserted",
|
||||
"Verbose operation. Use several times to enable debug output.",
|
||||
};
|
||||
|
@ -1034,21 +1033,16 @@ static int cardos_change_startkey(const char *change_startkey_apdu) {
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int err = 0, r, c, long_optind = 0;
|
||||
int err = 0, r, c;
|
||||
int do_info = 0;
|
||||
int do_format = 0;
|
||||
int do_change_startkey = 0;
|
||||
int action_count = 0;
|
||||
const char *opt_driver = NULL;
|
||||
const char *opt_startkey = NULL;
|
||||
const char *opt_change_startkey = NULL;
|
||||
sc_context_param_t ctx_param;
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "hifs:r:vdc:wS:", options,
|
||||
&long_optind);
|
||||
if (c == -1)
|
||||
break;
|
||||
while ((c = getopt_long(argc, argv, "hifs:r:vdwS:", options, (int *) 0)) != -1) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
printf("NB! This tool is only for Siemens CardOS based cards!\n\n");
|
||||
|
@ -1075,12 +1069,11 @@ int main(int argc, char *argv[])
|
|||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'c':
|
||||
opt_driver = optarg;
|
||||
break;
|
||||
case 'w':
|
||||
opt_wait = 1;
|
||||
break;
|
||||
default:
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1095,20 +1088,25 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (opt_driver != NULL) {
|
||||
err = sc_set_card_driver(ctx, opt_driver);
|
||||
/* force CardOS card driver */
|
||||
err = sc_set_card_driver(ctx, "cardos");
|
||||
if (err) {
|
||||
fprintf(stderr, "Driver '%s' not found!\n",
|
||||
opt_driver);
|
||||
fprintf(stderr, "CardOS card driver not found!\n");
|
||||
err = 1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
|
||||
if (err)
|
||||
goto end;
|
||||
|
||||
/* fail if card is not a CardOS card */
|
||||
if (card->type < SC_CARD_TYPE_CARDOS_BASE || card->type >= SC_CARD_TYPE_CARDOS_BASE+1000) {
|
||||
fprintf(stderr, "Card type %X: not a CardOS card\n", card->type);
|
||||
err = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (do_info) {
|
||||
if ((err = cardos_info())) {
|
||||
goto end;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "libopensc/opensc.h"
|
||||
#include "libopensc/errors.h"
|
||||
#include "libopensc/cardctl.h"
|
||||
#include "libopensc/cards.h"
|
||||
#include "libopensc/pkcs15.h"
|
||||
#include "util.h"
|
||||
|
||||
|
@ -54,7 +55,6 @@ static const char *app_name = "dnie-tool";
|
|||
|
||||
static const struct option options[] = {
|
||||
{"reader", 1, NULL, 'r'},
|
||||
{"driver", 1, NULL, 'c'},
|
||||
{"wait", 0, NULL, 'w'},
|
||||
{"pin", 1, NULL, 'p'},
|
||||
{"idesp", 0, NULL, 'i'},
|
||||
|
@ -68,7 +68,6 @@ static const struct option options[] = {
|
|||
|
||||
static const char *option_help[] = {
|
||||
"Uses reader number <arg> [0]",
|
||||
"Uses card driver <arg> [auto-detect]",
|
||||
"Wait for a card to be inserted",
|
||||
"Specify PIN",
|
||||
"Retrieve IDESP",
|
||||
|
@ -86,7 +85,6 @@ int main(int argc, char* argv[])
|
|||
int opt_wait = 0;
|
||||
const char *opt_pin = NULL;
|
||||
const char *opt_reader = NULL;
|
||||
const char *opt_driver = NULL;
|
||||
int opt_operation = OP_NONE;
|
||||
int verbose = 0;
|
||||
|
||||
|
@ -94,25 +92,16 @@ int main(int argc, char* argv[])
|
|||
sc_context_t *ctx = NULL;
|
||||
sc_context_param_t ctx_param;
|
||||
sc_card_t *card = NULL;
|
||||
int c, long_optind, r, tries_left;
|
||||
int c, r;
|
||||
|
||||
char *data[] = { NULL, NULL, NULL, NULL, NULL };
|
||||
sc_serial_number_t serial;
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "r:c:wp:iVdsav",
|
||||
options, &long_optind);
|
||||
if (c == -1)
|
||||
break;
|
||||
while ((c = getopt_long(argc, argv, "r:wp:iVdsav", options, (int *) 0)) != -1) {
|
||||
switch (c) {
|
||||
case '?':
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
case 'r':
|
||||
opt_reader = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
opt_driver = optarg;
|
||||
break;
|
||||
case 'w':
|
||||
opt_wait = 1;
|
||||
break;
|
||||
|
@ -137,6 +126,8 @@ int main(int argc, char* argv[])
|
|||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
default:
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,17 +137,16 @@ int main(int argc, char* argv[])
|
|||
if (r) {
|
||||
fprintf(stderr, "Error: Failed to establish context: %s\n",
|
||||
sc_strerror(r));
|
||||
goto dnie_tool_end;
|
||||
}
|
||||
|
||||
if (opt_driver != NULL) {
|
||||
err = sc_set_card_driver(ctx, opt_driver);
|
||||
if (err) {
|
||||
fprintf(stderr, "Driver '%s' not found!\n",
|
||||
opt_driver);
|
||||
err = -1;
|
||||
goto dnie_tool_end;
|
||||
}
|
||||
|
||||
/* force DNIe card driver */
|
||||
err = sc_set_card_driver(ctx, "dnie");
|
||||
if (err) {
|
||||
fprintf(stderr, "DNIe card driver not found!\n");
|
||||
err = -1;
|
||||
goto dnie_tool_end;
|
||||
}
|
||||
|
||||
if (util_connect_card(ctx, &card, opt_reader, opt_wait, verbose) ) {
|
||||
|
@ -165,13 +155,16 @@ int main(int argc, char* argv[])
|
|||
goto dnie_tool_end;
|
||||
}
|
||||
|
||||
if ( strcmp(card->name,"dnie") ) {
|
||||
fprintf(stderr, "Error: Card seems not to be a DNIe\n");
|
||||
/* fail if card is not a DNIe card */
|
||||
if (card->type < SC_CARD_TYPE_DNIE_BASE || card->type >= SC_CARD_TYPE_DNIE_BASE+1000) {
|
||||
fprintf(stderr, "Card type %X: not a DNIe card\n", card->type);
|
||||
err = -1;
|
||||
goto dnie_tool_end;
|
||||
}
|
||||
|
||||
if ( opt_pin ) {
|
||||
int tries_left;
|
||||
|
||||
/* verify */
|
||||
r = sc_verify(card, SC_AC_CHV, 0,
|
||||
(u8*)opt_pin, strlen(opt_pin), &tries_left);
|
||||
|
@ -186,22 +179,17 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if (opt_operation==0) {
|
||||
fprintf(stderr,"Error: No operation specified");
|
||||
err = -1;
|
||||
goto dnie_tool_end;
|
||||
}
|
||||
if (opt_operation & 0x0f) {
|
||||
if (opt_operation & (OP_GET_DATA | OP_GET_IDESP | OP_GET_VERSION | OP_GET_SERIALNR)) {
|
||||
r = sc_card_ctl(card, SC_CARDCTL_DNIE_GET_INFO, data);
|
||||
if ( r != SC_SUCCESS ) {
|
||||
fprintf(stderr, "Error: Get info failed: %s\n", sc_strerror(r));
|
||||
err = -1;
|
||||
goto dnie_tool_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt_operation & OP_GET_DATA) {
|
||||
printf("DNIe Number: %s\n",data[0]);
|
||||
printf("SurName: %s\n",data[1]);
|
||||
printf("Surname: %s\n",data[1]);
|
||||
printf("Name: %s\n",data[2]);
|
||||
}
|
||||
if (opt_operation & OP_GET_IDESP) {
|
||||
|
@ -225,6 +213,11 @@ int main(int argc, char* argv[])
|
|||
util_hex_dump(stdout, serial.value, serial.len, NULL);
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"Error: No operation specified");
|
||||
err = -1;
|
||||
}
|
||||
|
||||
dnie_tool_end:
|
||||
if (card) {
|
||||
|
|
|
@ -105,7 +105,7 @@ static void decode_options(int argc, char **argv)
|
|||
{
|
||||
int c;
|
||||
|
||||
while ((c = getopt_long(argc, argv,"pwtr:x:hV", options, (int *) 0)) != EOF) {
|
||||
while ((c = getopt_long(argc, argv,"pwtr:x:hV", options, (int *) 0)) != -1) {
|
||||
|
||||
switch (c) {
|
||||
case 'r':
|
||||
|
|
|
@ -446,7 +446,8 @@ int main(
|
|||
int r, oerr=0, reader=0, debug=0, pin_nr=-1, cert_nr=-1;
|
||||
size_t i, newlen=0;
|
||||
|
||||
while((r=getopt_long(argc,argv,"hvr:p:u:0:1:",options,NULL))!=EOF) switch(r){
|
||||
while ((r = getopt_long(argc, argv, "hvr:p:u:0:1:", options, NULL)) != -1) {
|
||||
switch (r) {
|
||||
case 'h': ++do_help; break;
|
||||
case 'v': ++debug; break;
|
||||
case 'r': reader=atoi(optarg); break;
|
||||
|
@ -456,6 +457,7 @@ int main(
|
|||
case '1': set_pin(pinlist[3].value, &pinlist[3].len, optarg); break;
|
||||
default: ++oerr;
|
||||
}
|
||||
}
|
||||
if(do_help){
|
||||
fprintf(stderr,"This is netkey-tool V1.0, May 15 2005, Copyright Peter Koch <pk_opensc@web.de>\n");
|
||||
fprintf(stderr,"usage: %s <options> command\n", argv[0]);
|
||||
|
|
|
@ -461,7 +461,7 @@ static int decode_options(int argc, char **argv)
|
|||
char *endptr;
|
||||
unsigned long val;
|
||||
|
||||
while ((c = getopt_long(argc, argv,"r:x:CUG:KEht:wvVd:", options, (int *) 0)) != EOF) {
|
||||
while ((c = getopt_long(argc, argv,"r:x:CUG:KEht:wvVd:", options, (int *) 0)) != -1) {
|
||||
switch (c) {
|
||||
case 'r':
|
||||
opt_reader = optarg;
|
||||
|
|
|
@ -76,7 +76,7 @@ static const struct option options[] = {
|
|||
};
|
||||
static const char *option_help[] = {
|
||||
"Uses reader number <arg> [0]",
|
||||
"Forces the use of driver <arg> [auto-detect]",
|
||||
"Forces the use of driver <arg> [auto-detect; '?' for list]",
|
||||
"Selects path <arg> on start-up, or none if empty [3F00]",
|
||||
"Wait for card insertion",
|
||||
"Verbose operation. Use several times to enable debug output.",
|
||||
|
@ -2152,6 +2152,12 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (opt_driver != NULL) {
|
||||
/* special card driver value "?" means: list available drivers */
|
||||
if (strncmp("?", opt_driver, sizeof("?")) == 0) {
|
||||
err = util_list_card_drivers(ctx);
|
||||
goto end;
|
||||
}
|
||||
|
||||
err = sc_set_card_driver(ctx, opt_driver);
|
||||
if (err) {
|
||||
fprintf(stderr, "Driver '%s' not found!\n", opt_driver);
|
||||
|
|
|
@ -90,7 +90,7 @@ static const char *option_help[] = {
|
|||
"Sends an APDU in format AA:BB:CC:DD:EE:FF...",
|
||||
"Uses reader number <arg> [0]",
|
||||
"Does card reset of type <cold|warm> [cold]",
|
||||
"Forces the use of driver <arg> [auto-detect]",
|
||||
"Forces the use of driver <arg> [auto-detect; '?' for list]",
|
||||
"Lists algorithms supported by card",
|
||||
"Wait for a card to be inserted",
|
||||
"Verbose operation. Use several times to enable debug output.",
|
||||
|
@ -300,22 +300,6 @@ static int list_readers(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int list_drivers(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ctx->card_drivers[0] == NULL) {
|
||||
printf("No card drivers installed!\n");
|
||||
return 0;
|
||||
}
|
||||
printf("Configured card drivers:\n");
|
||||
for (i = 0; ctx->card_drivers[i] != NULL; i++) {
|
||||
printf(" %-16s %s\n", ctx->card_drivers[i]->short_name,
|
||||
ctx->card_drivers[i]->name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_file(sc_card_t *in_card, const sc_file_t *file,
|
||||
const sc_path_t *path, int depth)
|
||||
{
|
||||
|
@ -784,6 +768,13 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
case 'c':
|
||||
opt_driver = optarg;
|
||||
|
||||
/* treat argument "?" as request to list drivers */
|
||||
if (opt_driver && strncmp("?", opt_driver, sizeof("?")) == 0) {
|
||||
opt_driver = NULL;
|
||||
do_list_drivers = 1;
|
||||
action_count++;
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
opt_wait = 1;
|
||||
|
@ -844,7 +835,7 @@ int main(int argc, char *argv[])
|
|||
action_count--;
|
||||
}
|
||||
if (do_list_drivers) {
|
||||
if ((err = list_drivers()))
|
||||
if ((err = util_list_card_drivers(ctx)))
|
||||
goto end;
|
||||
action_count--;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
#include "libopensc/opensc.h"
|
||||
#include "libopensc/cardctl.h"
|
||||
#include "libopensc/cards.h"
|
||||
#include "libopensc/asn1.h"
|
||||
#include "util.h"
|
||||
#include "libopensc/sc-ossl-compat.h"
|
||||
|
@ -80,7 +81,6 @@ static const struct option options[] = {
|
|||
{ "in", 1, NULL, 'i' },
|
||||
{ "send-apdu", 1, NULL, 's' },
|
||||
{ "reader", 1, NULL, 'r' },
|
||||
{ "card-driver", 1, NULL, 'c' },
|
||||
{ "wait", 0, NULL, 'w' },
|
||||
{ "verbose", 0, NULL, 'v' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
|
@ -98,7 +98,6 @@ static const char *option_help[] = {
|
|||
"Input file for cert",
|
||||
"Sends an APDU in format AA:BB:CC:DD:EE:FF...",
|
||||
"Uses reader number <arg> [0]",
|
||||
"Forces the use of driver <arg> [auto-detect]",
|
||||
"Wait for a card to be inserted",
|
||||
"Verbose operation. Use several times to enable debug output.",
|
||||
};
|
||||
|
@ -469,7 +468,7 @@ static void print_serial(sc_card_t *in_card)
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int err = 0, r, c, long_optind = 0;
|
||||
int err = 0, r, c;
|
||||
int do_send_apdu = 0;
|
||||
int do_admin_mode = 0;
|
||||
int do_gen_key = 0;
|
||||
|
@ -479,7 +478,6 @@ int main(int argc, char *argv[])
|
|||
int do_print_serial = 0;
|
||||
int do_print_name = 0;
|
||||
int action_count = 0;
|
||||
const char *opt_driver = NULL;
|
||||
const char *out_file = NULL;
|
||||
const char *in_file = NULL;
|
||||
const char *cert_id = NULL;
|
||||
|
@ -489,12 +487,7 @@ int main(int argc, char *argv[])
|
|||
sc_context_param_t ctx_param;
|
||||
char **old_apdus = NULL;
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "nA:G:O:Z:C:i:o:fvs:c:w", options, &long_optind);
|
||||
if (c == -1)
|
||||
break;
|
||||
if (c == '?')
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
while ((c = getopt_long(argc, argv, "nA:G:O:Z:C:i:o:r:fvs:c:w", options, (int *) 0)) != -1) {
|
||||
switch (c) {
|
||||
case OPT_SERIAL:
|
||||
do_print_serial = 1;
|
||||
|
@ -554,14 +547,14 @@ int main(int argc, char *argv[])
|
|||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'c':
|
||||
opt_driver = optarg;
|
||||
break;
|
||||
case 'w':
|
||||
opt_wait = 1;
|
||||
break;
|
||||
default:
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (action_count == 0)
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
|
||||
|
@ -603,19 +596,25 @@ int main(int argc, char *argv[])
|
|||
if (action_count <= 0)
|
||||
goto end;
|
||||
|
||||
if (opt_driver != NULL) {
|
||||
err = sc_set_card_driver(ctx, opt_driver);
|
||||
/* force PIV card driver */
|
||||
err = sc_set_card_driver(ctx, "PIV-II");
|
||||
if (err) {
|
||||
fprintf(stderr, "Driver '%s' not found!\n", opt_driver);
|
||||
fprintf(stderr, "PIV card driver not found!\n");
|
||||
err = 1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
|
||||
if (err)
|
||||
goto end;
|
||||
|
||||
/* fail if card is not a PIV card */
|
||||
if (card->type < SC_CARD_TYPE_PIV_II_BASE || card->type >= SC_CARD_TYPE_PIV_II_BASE+1000) {
|
||||
fprintf(stderr, "Card type %X: not a PIV card\n", card->type);
|
||||
err = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (do_admin_mode) {
|
||||
if ((err = admin_mode(admin_info)))
|
||||
goto end;
|
||||
|
|
|
@ -305,6 +305,26 @@ util_print_usage_and_die(const char *app_name, const struct option options[],
|
|||
exit(2);
|
||||
}
|
||||
|
||||
int util_list_card_drivers(const sc_context_t *ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ctx == NULL) {
|
||||
fprintf(stderr, "Unable to get card drivers!\n");
|
||||
return 1;
|
||||
}
|
||||
if (ctx->card_drivers[0] == NULL) {
|
||||
fprintf(stderr, "No card drivers installed!\n");
|
||||
return 1;
|
||||
}
|
||||
printf("Available card drivers:\n");
|
||||
for (i = 0; ctx->card_drivers[i] != NULL; i++) {
|
||||
printf(" %-16s %s\n", ctx->card_drivers[i]->short_name,
|
||||
ctx->card_drivers[i]->name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * util_acl_to_str(const sc_acl_entry_t *e)
|
||||
{
|
||||
static char line[80], buf[20];
|
||||
|
|
|
@ -41,6 +41,7 @@ void util_hex_dump(FILE *f, const u8 *in, int len, const char *sep);
|
|||
void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr);
|
||||
NORETURN void util_print_usage_and_die(const char *app_name, const struct option options[],
|
||||
const char *option_help[], const char *args);
|
||||
int util_list_card_drivers(const sc_context_t *ctx);
|
||||
const char * util_acl_to_str(const struct sc_acl_entry *e);
|
||||
void util_warn(const char *fmt, ...);
|
||||
void util_error(const char *fmt, ...);
|
||||
|
|
Loading…
Reference in New Issue