<commit_before>/*
 * opensc-explorer.c: A shell for accessing smart cards with libopensc
 *
 * Copyright (C) 2001  <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef ENABLE_READLINE
#include <readline/readline.h>
#include <readline/history.h>
#endif
#if !defined(_WIN32)
#include <arpa/inet.h>  /* for htons() */
#endif

#include "libopensc/opensc.h"
#include "libopensc/asn1.h"
#include "libopensc/cardctl.h"
#include "libopensc/cards.h"
#include "util.h"

#define DIM(v) (sizeof(v)/sizeof((v)[0]))

/* type for associations of IDs to names */
typedef struct _id2str {
	unsigned int id;
	const char *str;
} id2str_t;

static const char *app_name = "opensc-explorer";

static int opt_wait = 0, verbose = 0;
static const char *opt_driver = NULL;
static const char *opt_reader = NULL;
static const char *opt_startfile = NULL;

static sc_file_t *current_file = NULL;
static sc_path_t current_path;
static sc_context_t *ctx = NULL;
static sc_card_t *card = NULL;

static const struct option options[] = {
	{ "reader",		1, NULL, 'r' },
	{ "card-driver",	1, NULL, 'c' },
	{ "mf",			1, NULL, 'm' },
	{ "wait",		0, NULL, 'w' },
	{ "verbose",		0, NULL, 'v' },
	{ NULL, 0, NULL, 0 }
};
static const char *option_help[] = {
	"Uses reader number <arg> [0]",
	"Forces the use of driver <arg> [auto-detect]",
	"Selects path <arg> on start-up, or none if empty [3F00]",
	"Wait for card insertion",
	"Verbose operation. Use several times to enable debug output.",
};


/* declare functions called by user commands */
static int do_echo(int argc, char **argv);
static int do_ls(int argc, char **argv);
static int do_find(int argc, char **argv);
static int do_cd(int argc, char **argv);
static int do_cat(int argc, char **argv);
static int do_info(int argc, char **argv);
static int do_create(int argc, char **argv);
static int do_mkdir(int argc, char **argv);
static int do_delete(int argc, char **argv);
static int do_verify(int argc, char **argv);
static int do_pace(int argc, char **argv);
static int do_change(int argc, char **argv);
static int do_unblock(int argc, char **argv);
static int do_get(int argc, char **argv);
static int do_update_binary(int argc, char **argv);
static int do_update_record(int argc, char **argv);
static int do_put(int argc, char **argv);
static int do_debug(int argc, char **argv);
static int do_erase(int argc, char **argv);
static int do_random(int argc, char **argv);
static int do_get_data(int argc, char **argv);
static int do_put_data(int argc, char **argv);
static int do_apdu(int argc, char **argv);
static int do_asn1(int argc, char **argv);
static int do_help(int argc, char **argv);
static int do_quit(int argc, char **argv);


struct command {
	int		(*func)(int, char **);
	const char *	name;
	const char *	args;
	const char *	help;
};

static struct command	cmds[] = {
	{ do_echo,
		"echo",	"[<string> ..]",
		"display arguments"			},
	{ do_ls,
		"ls",	"",
		"list all files in the current DF"	},
	{ do_find,
		"find",	"[<start id> [<end id>]]",
		"find all files in the current DF"	},
	{ do_cd,
		"cd",	"{.. | <file id> | aid:<DF name>}",
		"change to another DF"			},
	{ do_cat,
		"cat",	"[<file id> | sfi:<sfi id>]"
	,	"print the contents of an EF"		},
	{ do_info,
		"info",	"[<file id>]",
		"display attributes of card file"	},
	{ do_create,
		"create",	"<file id> <size>",
		"create a new EF"			},
	{ do_mkdir,
		"mkdir",	"<file id> <size>",
		"create a new DF"			},
	{ do_delete,
		"delete",	"<file id>",
		"remove an EF/DF"			},
	{ do_delete,
		"rm",	"<file id>",
		"remove an EF/DF"			},
	{ do_verify,
		"verify",	"{CHV|KEY|AUT|PRO}<key ref> [<pin>]",
		"present a PIN or key to the card"	},
	{ do_pace,
		"pace",	"{pin|can|puk|mrz} [<secret>]",
		"Establish a PACE channel"	},
	{ do_change,
		"change",	"CHV<pin ref> [[<old pin>] <new pin>]",
		"change a PIN"                          },
	{ do_unblock,
		"unblock",	"CHV<pin ref> [<puk> [<new pin>]]",
		"unblock a PIN"                         },
	{ do_put,
		"put",	"<file id> [<input file>]",
		"copy a local file to the card"		},
	{ do_get,
		"get",	"<file id> [<output file>]",
		"copy an EF to a local file"		},
	{ do_get_data,
		"do_get",	"<hex tag> [<output file>]",
		"get a data object"			},
	{ do_put_data,
		"do_put",	"<hex tag> <data>",
		"put a data object"			},
	{ do_erase,
		"erase",	"",
		"erase card"				},
	{ do_random,
		"random",	"<count>",
		"obtain <count> random bytes from card"	},
	{ do_update_record,
		"update_record", "<file id> <rec no> <rec offs> <data>",
		"update record"				},
	{ do_update_binary,
		"update_binary", "<file id> <offs> <data>",
		"update binary"				},
	{ do_apdu,
		"apdu",	"<data>+",
		"send a custom apdu command"		},
	{ do_asn1,
		"asn1",	"[<file id>]",
		"decode an asn1 file"			},
	{ do_debug,
		"debug",	"[<value>]",
		"get/set the debug level"		},
	{ do_quit,
		"quit",	"",
		"quit this program"			},
	{ do_quit,
		"exit",	"",
		"quit this program"			},
	{ do_help,
		"help",	"",
		"show this help"			},
	{ NULL, NULL, NULL, NULL }
};


static char *path_to_filename(const sc_path_t *path, const char sep)
{
	static char buf[2*SC_MAX_PATH_STRING_SIZE];
	size_t i, j;

	for (i = 0, j = 0; path != NULL && i < path->len; i++) {
		if (sep != '\0' && i > 0 && (i & 1) == 0)
			j += sprintf(buf+j, "%c", sep);
		j += sprintf(buf+j, "%02X", path->value[i]);<commit_msg>opensc-explorer: clean-up help text<commit_after>/*
 * opensc-explorer.c: A shell for accessing smart cards with libopensc
 *
 * Copyright (C) 2001  <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef ENABLE_READLINE
#include <readline/readline.h>
#include <readline/history.h>
#endif
#if !defined(_WIN32)
#include <arpa/inet.h>  /* for htons() */
#endif

#include "libopensc/opensc.h"
#include "libopensc/asn1.h"
#include "libopensc/cardctl.h"
#include "libopensc/cards.h"
#include "util.h"

#define DIM(v) (sizeof(v)/sizeof((v)[0]))

/* type for associations of IDs to names */
typedef struct _id2str {
	unsigned int id;
	const char *str;
} id2str_t;

static const char *app_name = "opensc-explorer";

static int opt_wait = 0, verbose = 0;
static const char *opt_driver = NULL;
static const char *opt_reader = NULL;
static const char *opt_startfile = NULL;

static sc_file_t *current_file = NULL;
static sc_path_t current_path;
static sc_context_t *ctx = NULL;
static sc_card_t *card = NULL;

static const struct option options[] = {
	{ "reader",		1, NULL, 'r' },
	{ "card-driver",	1, NULL, 'c' },
	{ "mf",			1, NULL, 'm' },
	{ "wait",		0, NULL, 'w' },
	{ "verbose",		0, NULL, 'v' },
	{ NULL, 0, NULL, 0 }
};
static const char *option_help[] = {
	"Uses reader number <arg> [0]",
	"Forces the use of driver <arg> [auto-detect]",
	"Selects path <arg> on start-up, or none if empty [3F00]",
	"Wait for card insertion",
	"Verbose operation. Use several times to enable debug output.",
};


/* declare functions called by user commands */
static int do_echo(int argc, char **argv);
static int do_ls(int argc, char **argv);
static int do_find(int argc, char **argv);
static int do_cd(int argc, char **argv);
static int do_cat(int argc, char **argv);
static int do_info(int argc, char **argv);
static int do_create(int argc, char **argv);
static int do_mkdir(int argc, char **argv);
static int do_delete(int argc, char **argv);
static int do_verify(int argc, char **argv);
static int do_pace(int argc, char **argv);
static int do_change(int argc, char **argv);
static int do_unblock(int argc, char **argv);
static int do_get(int argc, char **argv);
static int do_update_binary(int argc, char **argv);
static int do_update_record(int argc, char **argv);
static int do_put(int argc, char **argv);
static int do_debug(int argc, char **argv);
static int do_erase(int argc, char **argv);
static int do_random(int argc, char **argv);
static int do_get_data(int argc, char **argv);
static int do_put_data(int argc, char **argv);
static int do_apdu(int argc, char **argv);
static int do_asn1(int argc, char **argv);
static int do_help(int argc, char **argv);
static int do_quit(int argc, char **argv);


struct command {
	int		(*func)(int, char **);
	const char *	name;
	const char *	args;
	const char *	help;
};

static struct command	cmds[] = {
	{ do_echo,
		"echo",	"[<string> ..]",
		"display arguments"			},
	{ do_ls,
		"ls",	"",
		"list all files in the current DF"	},
	{ do_find,
		"find",	"[<start id> [<end id>]]",
		"find all files in the current DF"	},
	{ do_cd,
		"cd",	"{.. | <file id> | aid:<DF name>}",
		"change to another DF"			},
	{ do_cat,
		"cat",	"[<file id> | sfi:<sfi id>]"
	,	"print the contents of an EF"		},
	{ do_info,
		"info",	"[<file id>]",
		"display attributes of card file"	},
	{ do_create,
		"create",	"<file id> <size>",
		"create a new EF"			},
	{ do_mkdir,
		"mkdir",	"<file id> <size>",
		"create a new DF"			},
	{ do_delete,
		"delete",	"<file id>",
		"remove an EF/DF"			},
	{ do_delete,
		"rm",	"<file id>",
		"remove an EF/DF"			},
	{ do_verify,
		"verify",	"{CHV|KEY|AUT|PRO}<key ref> [<pin>]",
		"present a PIN or key to the card"	},
	{ do_pace,
		"pace",	"{pin|can|puk|mrz} [<secret>]",
		"Establish a PACE channel"	},
	{ do_change,
		"change",	"CHV<pin ref> [[<old pin>] <new pin>]",
		"change a PIN"                          },
	{ do_unblock,
		"unblock",	"CHV<pin ref> [<puk> [<new pin>]]",
		"unblock a PIN"                         },
	{ do_put,
		"put",	"<file id> [<input file>]",
		"copy a local file to the card"		},
	{ do_get,
		"get",	"<file id> [<output file>]",
		"copy an EF to a local file"		},
	{ do_get_data,
		"do_get",	"<hex tag> [<output file>]",
		"get a data object"			},
	{ do_put_data,
		"do_put",	"<hex tag> <data>",
		"put a data object"			},
	{ do_erase,
		"erase",	"",
		"erase card"				},
	{ do_random,
		"random",	"<count>",
		"obtain <count> random bytes from card"	},
	{ do_update_record,
		"update_record", "<file id> <rec no> <rec offs> <data>",
		"update record"				},
	{ do_update_binary,
		"update_binary", "<file id> <offs> <data>",
		"update binary"				},
	{ do_apdu,
		"apdu",	"<data>+",
		"send a custom apdu command"		},
	{ do_asn1,
		"asn1",	"[<file id>]",
		"decode an ASN.1 file"			},
	{ do_debug,
		"debug",	"[<value>]",
		"get/set the debug level"		},
	{ do_quit,
		"quit",	"",
		"quit this program"			},
	{ do_quit,
		"exit",	"",
		"quit this program"			},
	{ do_help,
		"help",	"",
		"show this help"			},
	{ NULL, NULL, NULL, NULL }
};


static char *path_to_filename(const sc_path_t *path, const char sep)
{
	static char buf[2*SC_MAX_PATH_STRING_SIZE];
	size_t i, j;

	for (i = 0, j = 0; path != NULL && i < path->len; i++) {
		if (sep != '\0' && i > 0 && (i & 1) == 0)
			j += sprintf(buf+j, "%c", sep);
		j += sprintf(buf+j, "%02X", path->value[i]);
{'fraction_non_alphanumeric': 0.166870365843722, 'fraction_numerical': 0.008473885765501508, 'mean_word_length': 3.8418145956607495, 'pattern_counts': {'":': 0, '<': 117, '<?xml version=': 0, '>': 121, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7220172', 'n_tokens_mistral': 4912, 'n_tokens_neox': 4625, 'n_words': 1532}