opensc-explorer: extend do_cat()

Have do_cat() accept an optional second parameter indicating a record number.
If this is given and the file is a record-oriented file, only print the record
requested.
This commit is contained in:
Peter Marschall 2020-02-02 13:41:40 +01:00 committed by Jakub Jelen
parent f0b157b8e7
commit d345c65a5d
2 changed files with 23 additions and 9 deletions

View File

@ -182,12 +182,16 @@
<arg choice="plain"><replaceable>file-id</replaceable></arg> <arg choice="plain"><replaceable>file-id</replaceable></arg>
<arg choice="plain"><literal>sfi:</literal><replaceable>short-id</replaceable></arg> <arg choice="plain"><literal>sfi:</literal><replaceable>short-id</replaceable></arg>
</group> </group>
<arg choice="opt"><replaceable>rec-no</replaceable></arg>
</term> </term>
<listitem> <listitem>
<para> <para>
Print the contents of the working EF specified by Print the contents of the working EF specified by
<replaceable>file-id</replaceable> or the short file id <replaceable>file-id</replaceable> or the short file id
<replaceable>short-id</replaceable>. <replaceable>short-id</replaceable>.
If the optional second parameter
<replaceable>rec-no</replaceable> is given,
only print the record indicated by this parameter.
If no argument is given, print the the contents If no argument is given, print the the contents
of the currently selected EF. of the currently selected EF.
</para> </para>

View File

@ -145,8 +145,8 @@ static struct command cmds[] = {
"cd", "{.. | <file-id> | aid:<DF-name>}", "cd", "{.. | <file-id> | aid:<DF-name>}",
"change to another DF" }, "change to another DF" },
{ do_cat, { do_cat,
"cat", "[<file-id> | sfi:<sfi-id>]" "cat", "[{<file-id> | sfi:<sfi-id>} [<rec-no>]]"
, "print the contents of an EF" }, , "print the contents of [a record in] an EF" },
{ do_info, { do_info,
"info", "[<file-id>]", "info", "[<file-id>]",
"display attributes of card file" }, "display attributes of card file" },
@ -792,12 +792,13 @@ err:
return ret; return ret;
} }
static int read_and_print_record_file(sc_file_t *file, unsigned char sfi) static int read_and_print_record_file(sc_file_t *file, unsigned char sfi, unsigned int wanted)
{ {
u8 buf[SC_MAX_EXT_APDU_RESP_SIZE]; u8 buf[SC_MAX_EXT_APDU_RESP_SIZE];
int rec, r; int r;
unsigned int rec;
for (rec = 1; ; rec++) { for (rec = (wanted > 0) ? wanted : 1; wanted == 0 || wanted == rec; rec++) {
r = sc_lock(card); r = sc_lock(card);
if (r == SC_SUCCESS) if (r == SC_SUCCESS)
r = sc_read_record(card, rec, buf, sizeof(buf), r = sc_read_record(card, rec, buf, sizeof(buf),
@ -805,7 +806,7 @@ static int read_and_print_record_file(sc_file_t *file, unsigned char sfi)
else else
r = SC_ERROR_READER_LOCKED; r = SC_ERROR_READER_LOCKED;
sc_unlock(card); sc_unlock(card);
if (r == SC_ERROR_RECORD_NOT_FOUND) if (r == SC_ERROR_RECORD_NOT_FOUND && wanted == 0)
return 0; return 0;
if (r < 0) { if (r < 0) {
check_ret(r, SC_AC_OP_READ, "Read failed", file); check_ret(r, SC_AC_OP_READ, "Read failed", file);
@ -821,14 +822,18 @@ static int read_and_print_record_file(sc_file_t *file, unsigned char sfi)
static int do_cat(int argc, char **argv) static int do_cat(int argc, char **argv)
{ {
int r, err = 1; int r, err = 1;
unsigned int rec = 0;
sc_path_t path; sc_path_t path;
sc_file_t *file = NULL; sc_file_t *file = NULL;
int not_current = 1; int not_current = 1;
int sfi = 0; int sfi = 0;
if (argc > 1) if (argc > 2)
return usage(do_cat); return usage(do_cat);
if (argc > 1)
rec = (unsigned int) strtoul(argv[1], NULL, 10);
if (!argc) { if (!argc) {
path = current_path; path = current_path;
file = current_file; file = current_file;
@ -871,10 +876,15 @@ static int do_cat(int argc, char **argv)
fprintf(stderr, "only working EFs may be read\n"); fprintf(stderr, "only working EFs may be read\n");
goto err; goto err;
} }
if (file->ef_structure == SC_FILE_EF_TRANSPARENT && !sfi) if (file->ef_structure == SC_FILE_EF_TRANSPARENT && !sfi) {
if (argc > 1) {
fprintf(stderr, "Transparent files do not have records\n");
goto err;
}
read_and_print_binary_file(file); read_and_print_binary_file(file);
}
else else
read_and_print_record_file(file, sfi); read_and_print_record_file(file, sfi, rec);
err = 0; err = 0;
err: err: