updated ccid for new version of libnpa
This commit is contained in:
@@ -40,33 +40,24 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
|||||||
|
|
||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
|
|
||||||
# --disable-ccid
|
AC_CHECK_HEADERS(linux/usb/gadgetfs.h,,
|
||||||
AC_ARG_ENABLE(ccid,
|
[ AC_MSG_ERROR([linux/usb/gadgetfs.h not found, maybe you want to disable ccid]) ])
|
||||||
AS_HELP_STRING([--disable-ccid], [Disable USB CCID emulator]),
|
|
||||||
[enable_ccid="${enableval}"], [enable_ccid=yes])
|
|
||||||
if test "x$enable_ccid" != xno ; then
|
|
||||||
AC_CHECK_HEADERS(linux/usb/gadgetfs.h,,
|
|
||||||
[ AC_MSG_ERROR([linux/usb/gadgetfs.h not found, maybe you want to disable ccid]) ])
|
|
||||||
|
|
||||||
ACX_PTHREAD
|
ACX_PTHREAD
|
||||||
|
|
||||||
saved_CPPFLAGS="$CPPFLAGS"
|
saved_CPPFLAGS="$CPPFLAGS"
|
||||||
saved_LIBS="$LIBS"
|
saved_LIBS="$LIBS"
|
||||||
CPPFLAGS="$CPPFLAGS $PTHREAD_CFLAGS"
|
CPPFLAGS="$CPPFLAGS $PTHREAD_CFLAGS"
|
||||||
LIBS="$LDFLAGS $PTHREAD_LIBS"
|
LIBS="$LDFLAGS $PTHREAD_LIBS"
|
||||||
|
|
||||||
AC_CHECK_HEADERS(pthread.h, [],
|
AC_CHECK_HEADERS(pthread.h, [],
|
||||||
[ AC_MSG_ERROR([pthread.h not found, use ./configure PTHREAD_CFLAGS=... or disable ccid]) ])
|
[ AC_MSG_ERROR([pthread.h not found, use ./configure PTHREAD_CFLAGS=... or disable ccid]) ])
|
||||||
AC_MSG_CHECKING([for pthread_create])
|
AC_MSG_CHECKING([for pthread_create])
|
||||||
AC_TRY_LINK_FUNC(pthread_create, [ AC_MSG_RESULT([yes]) ],
|
AC_TRY_LINK_FUNC(pthread_create, [ AC_MSG_RESULT([yes]) ],
|
||||||
[ AC_MSG_ERROR([pthread not found, use ./configure PTHREAD_LIBS=... or disable ccid]) ])
|
[ AC_MSG_ERROR([pthread not found, use ./configure PTHREAD_LIBS=... or disable ccid]) ])
|
||||||
|
|
||||||
CPPFLAGS="$saved_CPPFLAGS"
|
CPPFLAGS="$saved_CPPFLAGS"
|
||||||
LIBS="$saved_LIBS"
|
LIBS="$saved_LIBS"
|
||||||
|
|
||||||
enable_ccid=yes
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL(WITH_CCID, test "${enable_ccid}" != "no")
|
|
||||||
|
|
||||||
|
|
||||||
PKG_CHECK_EXISTS([libssl],
|
PKG_CHECK_EXISTS([libssl],
|
||||||
@@ -96,8 +87,8 @@ if test "x$enable_pace" != xno ; then
|
|||||||
CPPFLAGS="$CPPFLAGS $LIBNPA_CFLAGS -I$(pwd)/src/opensc/src $OPENSSL_CFLAGS"
|
CPPFLAGS="$CPPFLAGS $LIBNPA_CFLAGS -I$(pwd)/src/opensc/src $OPENSSL_CFLAGS"
|
||||||
LIBS="$LDFLAGS $LIBNPA_LIBS $OPENSSL_LIBS"
|
LIBS="$LDFLAGS $LIBNPA_LIBS $OPENSSL_LIBS"
|
||||||
AC_CHECK_HEADERS(npa/npa.h, [], [ AC_MSG_ERROR([npa/npa.h not found, install libnpa or use ./configure LIBNPA_CFLAGS=...]) ])
|
AC_CHECK_HEADERS(npa/npa.h, [], [ AC_MSG_ERROR([npa/npa.h not found, install libnpa or use ./configure LIBNPA_CFLAGS=...]) ])
|
||||||
AC_MSG_CHECKING([for EstablishPACEChannel])
|
AC_MSG_CHECKING([for perform_pace])
|
||||||
AC_TRY_LINK_FUNC(EstablishPACEChannel, [ AC_MSG_RESULT([yes]) ], [ AC_MSG_ERROR([libnpa not found, use ./configure LIBNPA_LIBS=...]) ])
|
AC_TRY_LINK_FUNC(perform_pace, [ AC_MSG_RESULT([yes]) ], [ AC_MSG_ERROR([libnpa not found, use ./configure LIBNPA_LIBS=...]) ])
|
||||||
|
|
||||||
enable_pace=yes
|
enable_pace=yes
|
||||||
else
|
else
|
||||||
@@ -159,7 +150,6 @@ OPENSSL_LIBS: ${OPENSSL_LIBS}
|
|||||||
LIBNPA_CFLAGS: ${LIBNPA_CFLAGS}
|
LIBNPA_CFLAGS: ${LIBNPA_CFLAGS}
|
||||||
LIBNPA_LIBS: ${LIBNPA_LIBS}
|
LIBNPA_LIBS: ${LIBNPA_LIBS}
|
||||||
|
|
||||||
CCID emulator: ${enable_ccid}
|
|
||||||
PACE support: ${enable_pace}
|
PACE support: ${enable_pace}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ tools.
|
|||||||
.. [#f1] Note that the heavily outdated `Windows USB CCID driver <http://msdn.microsoft.com/en-us/windows/hardware/gg487509>`_ does not support secure PIN entry or PIN modification. USB CCID Emulator comes with a patch for libccid_ to support |PACE|, because it is not yet standardised in USB CCID. However, the traditional commands can be used without restriction.
|
.. [#f1] Note that the heavily outdated `Windows USB CCID driver <http://msdn.microsoft.com/en-us/windows/hardware/gg487509>`_ does not support secure PIN entry or PIN modification. USB CCID Emulator comes with a patch for libccid_ to support |PACE|, because it is not yet standardised in USB CCID. However, the traditional commands can be used without restriction.
|
||||||
|
|
||||||
|
|
||||||
|
.. include:: download.rst
|
||||||
|
|
||||||
|
|
||||||
.. include:: autotools.rst
|
.. include:: autotools.rst
|
||||||
|
|
||||||
Running the USB CCID Emulator has the following dependencies:
|
Running the USB CCID Emulator has the following dependencies:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
.. highlight:: sh
|
.. highlight:: sh
|
||||||
|
|
||||||
=============
|
============
|
||||||
Installation
|
Installation
|
||||||
=============
|
============
|
||||||
|
|
||||||
The USB CCID Emulator uses the GNU Build System to compile and install. If you are
|
The USB CCID Emulator uses the GNU Build System to compile and install. If you are
|
||||||
unfamiliar with it, please have a look at :file:`INSTALL`. If you have a look
|
unfamiliar with it, please have a look at :file:`INSTALL`. If you have a look
|
||||||
@@ -10,7 +10,7 @@ around and can not find it, you are probably working bleeding edge in the
|
|||||||
repository. Run the following command in :file:`ccid-emulator` to
|
repository. Run the following command in :file:`ccid-emulator` to
|
||||||
get the missing standard auxiliary files::
|
get the missing standard auxiliary files::
|
||||||
|
|
||||||
autoreconf -i
|
autoreconf --verbose --install
|
||||||
|
|
||||||
To configure (:command:`configure --help` lists possible options), build and
|
To configure (:command:`configure --help` lists possible options), build and
|
||||||
install the USB CCID Emulator now do the following::
|
install the USB CCID Emulator now do the following::
|
||||||
|
|||||||
@@ -9,15 +9,14 @@ do_subst = $(SED) \
|
|||||||
BUILT_SOURCES = cmdline.h cmdline.c
|
BUILT_SOURCES = cmdline.h cmdline.c
|
||||||
|
|
||||||
EXTRA_DIST = ccid-emulator.ggo ccid-emulator.ggo.in
|
EXTRA_DIST = ccid-emulator.ggo ccid-emulator.ggo.in
|
||||||
EXTRA_DIST += $(shell find $(top_srcdir)/src/opensc/src -path '*/.svn' -prune -o -type f -a -name '*.h' -print)
|
EXTRA_DIST += $(shell find $(top_srcdir)/src/opensc/src -path '*/.git' -prune -o -type f -a -name '*.h' -print)
|
||||||
EXTRA_DIST += $(shell find -L $(top_srcdir)/src/opensc-npa/src -path '*/.git' -prune -o -type f -a -name '*.h' -print)
|
|
||||||
MAINTAINERCLEANFILES = $(BUILT_SOURCES) ccid-emulator.ggo $(dist_man1_MANS)
|
MAINTAINERCLEANFILES = $(BUILT_SOURCES) ccid-emulator.ggo $(dist_man1_MANS)
|
||||||
|
|
||||||
dist_man1_MANS = ccid-emulator.1
|
dist_man1_MANS = ccid-emulator.1
|
||||||
|
|
||||||
ccid_emulator_SOURCES = ccid.c usbstring.c usb.c sslutil.c $(BUILT_SOURCES)
|
ccid_emulator_SOURCES = ccid.c usbstring.c usb.c $(BUILT_SOURCES)
|
||||||
ccid_emulator_LDADD = $(OPENSSL_LIBS) $(PTHREAD_LIBS)
|
ccid_emulator_LDADD = $(OPENSSL_LIBS) $(PTHREAD_LIBS)
|
||||||
ccid_emulator_CFLAGS = $(OPENSSL_CFLAGS) $(PTHREAD_CFLAGS)
|
ccid_emulator_CFLAGS = $(OPENSSL_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_srcdir)/src/opensc/src
|
||||||
|
|
||||||
|
|
||||||
ccid-emulator.c: $(BUILT_SOURCES)
|
ccid-emulator.c: $(BUILT_SOURCES)
|
||||||
@@ -38,27 +37,19 @@ ccid-emulator.1:
|
|||||||
$(srcdir)/ccid-emulator
|
$(srcdir)/ccid-emulator
|
||||||
|
|
||||||
|
|
||||||
bin_PROGRAMS =
|
bin_PROGRAMS = ccid-emulator
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
scutil.h \
|
|
||||||
ccid.h \
|
ccid.h \
|
||||||
|
npa/scutil.h \
|
||||||
sslutil.h \
|
sslutil.h \
|
||||||
usbstring.h
|
usbstring.h
|
||||||
|
|
||||||
if WITH_CCID
|
|
||||||
bin_PROGRAMS += ccid-emulator
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
if WITH_PACE
|
if WITH_PACE
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/src/opensc-npa/src
|
|
||||||
|
|
||||||
ccid_emulator_LDADD += $(LIBNPA_LIBS)
|
ccid_emulator_LDADD += $(LIBNPA_LIBS)
|
||||||
ccid_emulator_CFLAGS += $(LIBNPA_CFLAGS)
|
ccid_emulator_CFLAGS += $(LIBNPA_CFLAGS)
|
||||||
else
|
else
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/src/opensc/src
|
|
||||||
|
|
||||||
ccid_emulator_SOURCES += scutil.c
|
ccid_emulator_SOURCES += scutil.c
|
||||||
ccid_emulator_LDADD += $(OPENSC_LIBS)
|
ccid_emulator_LDADD += $(OPENSC_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -31,15 +31,12 @@
|
|||||||
#include "sslutil.h"
|
#include "sslutil.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <npa/scutil.h>
|
||||||
#ifdef WITH_PACE
|
#ifdef WITH_PACE
|
||||||
#include <npa/npa.h>
|
#include <npa/npa.h>
|
||||||
#include <npa/sm.h>
|
#include <npa/iso-sm.h>
|
||||||
#include <npa/scutil.h>
|
|
||||||
|
|
||||||
static struct sm_ctx sctx;
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include "scutil.h"
|
int sm_stop(struct sc_card *card) { return SC_SUCCESS; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static sc_context_t *ctx = NULL;
|
static sc_context_t *ctx = NULL;
|
||||||
@@ -130,13 +127,6 @@ detect_card_presence(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sm_stop() {
|
|
||||||
#ifdef WITH_PACE
|
|
||||||
sm_ctx_clear_free(&sctx);
|
|
||||||
memset(&sctx, 0, sizeof(sctx));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int ccid_initialize(int reader_id, const char *cdriver, int verbose)
|
int ccid_initialize(int reader_id, const char *cdriver, int verbose)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -145,24 +135,18 @@ int ccid_initialize(int reader_id, const char *cdriver, int verbose)
|
|||||||
if (i < 0)
|
if (i < 0)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
#ifdef WITH_PACE
|
|
||||||
memset(&sctx, 0, sizeof(sctx));
|
|
||||||
sm_stop();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return SC_SUCCESS;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ccid_shutdown()
|
void ccid_shutdown(void)
|
||||||
{
|
{
|
||||||
int i;
|
sm_stop(card);
|
||||||
|
|
||||||
if (card) {
|
if (card) {
|
||||||
sc_disconnect_card(card);
|
sc_disconnect_card(card);
|
||||||
}
|
}
|
||||||
if (ctx)
|
if (ctx)
|
||||||
sc_release_context(ctx);
|
sc_release_context(ctx);
|
||||||
|
|
||||||
sm_stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_rapdu(sc_apdu_t *apdu, __u8 **buf, size_t *resplen)
|
static int get_rapdu(sc_apdu_t *apdu, __u8 **buf, size_t *resplen)
|
||||||
@@ -183,11 +167,7 @@ static int get_rapdu(sc_apdu_t *apdu, __u8 **buf, size_t *resplen)
|
|||||||
}
|
}
|
||||||
*buf = apdu->resp;
|
*buf = apdu->resp;
|
||||||
|
|
||||||
#ifdef WITH_PACE
|
|
||||||
sc_result = sm_transmit_apdu(&sctx, card, apdu);
|
|
||||||
#else
|
|
||||||
sc_result = sc_transmit_apdu(card, apdu);
|
sc_result = sc_transmit_apdu(card, apdu);
|
||||||
#endif
|
|
||||||
if (sc_result < 0) {
|
if (sc_result < 0) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -401,7 +381,7 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, size_t inlen, __u8 **out, size_t *o
|
|||||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Card is already powered on.");
|
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Card is already powered on.");
|
||||||
sc_result = SC_SUCCESS;
|
sc_result = SC_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
sm_stop();
|
sm_stop(card);
|
||||||
sc_result = sc_connect_card(reader, &card);
|
sc_result = sc_connect_card(reader, &card);
|
||||||
card->caps |= SC_CARD_CAP_APDU_EXT;
|
card->caps |= SC_CARD_CAP_APDU_EXT;
|
||||||
}
|
}
|
||||||
@@ -936,8 +916,8 @@ perform_PC_to_RDR_Secure_EstablishPACEChannel(sc_card_t *card,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sc_result = EstablishPACEChannel(NULL, card, pace_input, &pace_output,
|
sc_result = perform_pace(card, pace_input, &pace_output,
|
||||||
&sctx, EAC_TR_VERSION_2_02);
|
EAC_TR_VERSION_2_02);
|
||||||
if (sc_result < 0)
|
if (sc_result < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@@ -1080,7 +1060,7 @@ perform_PC_to_RDR_Secure_GetReadersPACECapabilities(__u8 **abDataOut,
|
|||||||
return SC_ERROR_OUT_OF_MEMORY;
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
*abDataOut = BitMap;
|
*abDataOut = BitMap;
|
||||||
|
|
||||||
sc_result = GetReadersPACECapabilities(BitMap);
|
sc_result = get_pace_capabilities(BitMap);
|
||||||
if (sc_result < 0)
|
if (sc_result < 0)
|
||||||
return sc_result;
|
return sc_result;
|
||||||
|
|
||||||
@@ -1118,7 +1098,6 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
|
|||||||
size_t abDatalen = inlen - sizeof *request;
|
size_t abDatalen = inlen - sizeof *request;
|
||||||
u8 *abDataOut = NULL;
|
u8 *abDataOut = NULL;
|
||||||
size_t abDataOutLen = 0;
|
size_t abDataOutLen = 0;
|
||||||
RDR_to_PC_DataBlock_t *result;
|
|
||||||
|
|
||||||
memset(&curr_pin, 0, sizeof(curr_pin));
|
memset(&curr_pin, 0, sizeof(curr_pin));
|
||||||
memset(&new_pin, 0, sizeof(new_pin));
|
memset(&new_pin, 0, sizeof(new_pin));
|
||||||
@@ -1355,25 +1334,6 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
|
|||||||
break;
|
break;
|
||||||
case SC_APDU_CASE_2_SHORT:
|
case SC_APDU_CASE_2_SHORT:
|
||||||
apdu.cse = SC_APDU_CASE_4_SHORT;
|
apdu.cse = SC_APDU_CASE_4_SHORT;
|
||||||
#ifdef WITH_PACE
|
|
||||||
/* This is an ugly hack to support the current AusweisApp.
|
|
||||||
*
|
|
||||||
* AusweisApp predefines a case 2 apdu, that includes a Le.
|
|
||||||
* Unfortunately the nPA does only accept Reset Retry Counter
|
|
||||||
* without secured Le (Le is not specified by BSI TR-03110, p.
|
|
||||||
* 80).
|
|
||||||
* In addition AusweisApp predefines a short apdu, which is
|
|
||||||
* also incompatible with nPA. It accepts only extended length
|
|
||||||
* APDUs.
|
|
||||||
*
|
|
||||||
* Therefor we drop the Le and switch to extended length.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Note that this is only an approximation to find out if we
|
|
||||||
* have a nPA */
|
|
||||||
if (sctx.active)
|
|
||||||
apdu.cse = SC_APDU_CASE_3_EXT;
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case SC_APDU_CASE_2_EXT:
|
case SC_APDU_CASE_2_EXT:
|
||||||
apdu.cse = SC_APDU_CASE_4_EXT;
|
apdu.cse = SC_APDU_CASE_4_EXT;
|
||||||
@@ -1433,7 +1393,6 @@ err:
|
|||||||
static int
|
static int
|
||||||
get_RDR_to_PC_NotifySlotChange(RDR_to_PC_NotifySlotChange_t **out)
|
get_RDR_to_PC_NotifySlotChange(RDR_to_PC_NotifySlotChange_t **out)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int sc_result;
|
int sc_result;
|
||||||
uint8_t oldmask;
|
uint8_t oldmask;
|
||||||
uint8_t changed [] = {
|
uint8_t changed [] = {
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ int ccid_initialize(int reader_id, const char *cdriver, int verbose);
|
|||||||
/**
|
/**
|
||||||
* @brief Disconnects from card, reader and releases allocated memory
|
* @brief Disconnects from card, reader and releases allocated memory
|
||||||
*/
|
*/
|
||||||
void ccid_shutdown();
|
void ccid_shutdown(void);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
1
ccid/src/npa
Symbolic link
1
ccid/src/npa
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../npa/src/npa
|
||||||
1
ccid/src/opensc
Symbolic link
1
ccid/src/opensc
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../npa/src/opensc/
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../npa/src/npa/scutil.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../npa/src/sslutil.c
|
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/usb/gadgetfs.h>
|
#include <linux/usb/gadgetfs.h>
|
||||||
#include <linux/usb/ch9.h>
|
#include <linux/usb/ch9.h>
|
||||||
|
#include <npa/scutil.h>
|
||||||
//#include <usb.h>
|
//#include <usb.h>
|
||||||
//
|
//
|
||||||
|
|
||||||
@@ -255,11 +256,6 @@ static char *EP_IN_NAME, *EP_OUT_NAME, *EP_STATUS_NAME;
|
|||||||
|
|
||||||
static enum usb_device_speed current_speed;
|
static enum usb_device_speed current_speed;
|
||||||
|
|
||||||
static inline int min(unsigned a, unsigned b)
|
|
||||||
{
|
|
||||||
return (a < b) ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int autoconfig ()
|
static int autoconfig ()
|
||||||
{
|
{
|
||||||
struct stat statb;
|
struct stat statb;
|
||||||
@@ -774,6 +770,11 @@ static void close_fd (void *fd_ptr)
|
|||||||
fprintf (stderr, "closed fd\n");
|
fprintf (stderr, "closed fd\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void close_ccid()
|
||||||
|
{
|
||||||
|
ccid_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* you should be able to open and configure endpoints
|
/* you should be able to open and configure endpoints
|
||||||
* whether or not the host is connected
|
* whether or not the host is connected
|
||||||
@@ -894,7 +895,7 @@ static void *ccid (void *param)
|
|||||||
}
|
}
|
||||||
pthread_cleanup_push (close_fd, &sink_fd);
|
pthread_cleanup_push (close_fd, &sink_fd);
|
||||||
|
|
||||||
pthread_cleanup_push (ccid_shutdown, NULL);
|
pthread_cleanup_push (close_ccid, NULL);
|
||||||
|
|
||||||
__u8 *outbuf = NULL;
|
__u8 *outbuf = NULL;
|
||||||
pthread_cleanup_push (free, outbuf);
|
pthread_cleanup_push (free, outbuf);
|
||||||
@@ -1488,7 +1489,6 @@ main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
/*printf("%s:%d\n", __FILE__, __LINE__);*/
|
/*printf("%s:%d\n", __FILE__, __LINE__);*/
|
||||||
int fd, c, i;
|
int fd, c, i;
|
||||||
int oindex = 0;
|
|
||||||
|
|
||||||
struct gengetopt_args_info cmdline;
|
struct gengetopt_args_info cmdline;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user