New upstream version 1.4.28

This commit is contained in:
Ludovic Rousseau 2017-12-08 19:39:30 +01:00
parent 2409d53482
commit 6e71ce20c9
104 changed files with 106693 additions and 0 deletions

1
AUTHORS Normal file
View File

@ -0,0 +1 @@
Ludovic Rousseau <ludovic.rousseau@free.fr>

510
COPYING Normal file
View File

@ -0,0 +1,510 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes a de-facto standard. To achieve this, non-free programs must
be allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at least
three years, to give the same user the materials specified in
Subsection 6a, above, for a charge no more than the cost of
performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding those
countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).
To apply these terms, attach the following notices to the library.
It is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should
have at least the "copyright" line and a pointer to where the full
notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or
your school, if any, to sign a "copyright disclaimer" for the library,
if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James
Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

32750
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

138
INSTALL Normal file
View File

@ -0,0 +1,138 @@
INSTALLATION PROCEDURE
======================
Installation from source:
"""""""""""""""""""""""""
get the ccid-x.y.z.tar.gz archive and do:
$ tar xzvf ccid-x.y.z.tar.gz
$ cd ccid-x.y.z
$ ./configure
$ make
$ sudo make install
By default pcscd and my ccid driver use /usr/local/pcsc/drivers/ as
directory for hotplug drivers. The ./configure script try to get the
directory used by pcscd using 'pkg-config libpcsclite --variable=usbdropdir'
So you should not have to use the --enable-usbdropdir=DIR argument.
libusb not found
~~~~~~~~~~~~~~~~
If the ./configure script says something like:
configure: error: usb.h not found, use --enable-libusb=PATH
You should use --enable-libusb=PATH to tell ./configure where to find
the usb.h and libusb.so files. The ./configure script will use
PATH/include/ to search for usb.h and PATH/lib/ to search for libusb.so
building serial reader driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A serial CCID reader can also be connected on a serial port. By default
the serial driver is not built. You must explicitely do:
$ ./configure --enable-twinserial
$ make
# make install
builing serial reader driver only
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is possible to generate the driver for the GemPC Twin using serial
communication only (for example on an embedded system without USB).
Just do:
$ ./configure --enable-twinserial --disable-libusb
$ make
# make install
By default ./configure try to get the directory used by pcscd using
'pkg-config libpcsclite --variable=usbdropdir' and add '/serial'.
You should not have to use --enable-ccidtwindir=DIR to specify the
target directory to use.
configuring the driver for the serial reader
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You have to create or edit the file /etc/reader.conf. The file should
contain something like:
# Gemalto reader with serial communication
# - n is the serial port to use n in [0..3]
# - reader is the reader name. It is needed for multi-slot readers.
# Possible reader values are:
# GemCorePOSPro
# GemCoreSIMPro
# GemCoreSIMPro2
# GemPCPinPad
# GemPCTwin (default value)
# example: /dev/ttyS0:GemPCPinPad
#DEVICENAME /dev/ttySn[:reader]
#FRIENDLYNAME "GemPCTwin serial"
#LIBPATH /usr/lib/pcsc/drivers/serial/libccidtwin.so
FRIENDLYNAME "GemPC Twin serial"
DEVICENAME /dev/ttyS0
LIBPATH /usr/lib/pcsc/drivers/serial/libccidtwin.so
You will have to adapt the library path to your configuration.
By default the GemPC Twin serial reader parameters are loaded by the
driver, if you use a GemPC PinPad, a GemCore POS Pro, a GemCore SIM
Pro or GemCore SIM Pro 2 (or IDBridge CR30) you have to indicate it in the
DEVICENAME field. Supported values are:
- GemCorePOSPro for GemCore POS Pro
- GemCoreSIMPro for GemCore SIM Pro
- GemCoreSIMPro2 for IDBridge CR30
- GemPCPinPad for GemPC PinPad
- GemPCTwin for GemPC Twin (default value)
You will then have something like:
DEVICENAME /dev/ttyS0:GemPCPinPad
/dev/ttyS0 (DEVICENAME field) is the first serial port under Linux
(known as COM1 under DOS/Windows). Of course if your reader is connected
to another serial port you have to adapt that.
Binary installation:
""""""""""""""""""""
Contact your distribution support.
Test procedure:
"""""""""""""""
- check the reader is supported by the driver.
Get your reader USB identification using the lsusb(1) command:
$ lsusb
[...]
Bus 001 Device 048: ID 08e6:4433 Gemplus
Look for 08E6 (ifdVendorID) and 4433 (ifdProductID) in
/usr/local/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist
Of course your numbers will be different.
If you can't find them add them (if you know what you do) and/or mail me.
- (re)start pcscd with debug on stdout. Simply do 'pcscd --debug stdout'
(you will need to have root priviledges). And look for:
[...]
readerfactory.c:1319 RFInitializeReader: Attempting startup of ReaderName
readerfactory.c:1061 RFBindFunctions: Loading IFD Handler 2.0
ifdhandler.c:76 Entering IFDHCreateChannel (lun: 0)
ccid_usb.c:131 Manufacturer: Ludovic Rousseau (ludovic.rousseau@free.fr)
ccid_usb.c:139 ProductString: Generic CCID reader v0.1.0
ccid_usb.c:143 Copyright: This driver is protected by terms of the GNU General Public License version 2, or (at your option) any later version.
ccid_usb.c:223 Found Vendor/Product: 08E6/4433 (GemPC433 SL)
ccid_usb.c:224 Using USB bus/device: 001/047
If you don't see this the driver is not installed correctly or your
reader is not yet supported. Read
http://pcsclite.alioth.debian.org/ccid.html#CCID_compliant to know
what to do.

151
MacOSX/configure vendored Executable file
View File

@ -0,0 +1,151 @@
#! /bin/bash
# Copyright (C) 2007-2009 Ludovic Rousseau <ludovic.rousseau@free.fr>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA.
# to use
# ./MacOSX/configure
# make
# make install
# the driver is installed in /usr/libexec/SmartCardServices/drivers
# Colors
RED="\033[31m"
NORMAL="\033[0m"
# run this script as ./MacOSX/configure to configure for Mac OS X
if [ ! -d MacOSX ]
then
echo -e $RED
echo "ERROR!"
echo "run ./MacOSX/configure from the source top directory"
echo -e $NORMAL
exit;
fi
# find pcsc-lite header files in MacOSX/
# use ${varname:-word} to return word only if varname is not already defined
PCSC_CFLAGS=${PCSC_CFLAGS:--I$(pwd)/MacOSX}
PCSC_LIBS=${PCSC_LIBS:--framework PCSC}
# use libusb-1.0
LIBUSB_DIR=$(pkg-config --variable=libdir libusb-1.0)
LIBUSB_ARCHIVE="$LIBUSB_DIR"/libusb-1.0.a
LIBUSB_CFLAGS=$(pkg-config --cflags --static libusb-1.0)
LIBUSB_LIBS=$(pkg-config --libs --static libusb-1.0)
if ls "$LIBUSB_DIR"/*.dylib 2> /dev/null
then
echo -en $RED
echo "*****************************"
echo "Dynamic library libusb found in $LIBUSB_DIR"
echo "*****************************"
echo -en $NORMAL
echo "Rename it to force a static link"
exit
fi
# RESPONSECODE is already defined by PCSC/wintypes.h
# define needed here to compile examples/scardcontrol.c since config.h is
# not included
CFLAGS="$CFLAGS -DRESPONSECODE_DEFINED_IN_WINTYPES_H"
# get the Mac OS X major version. Example: El Capitan 10.11 -> 10011
MAC_VERSION=$(sw_vers -productVersion | awk -F '.' '{print $1 * 1000 + $2}')
# check for Universal Binary only on macOS Mavericks 10.9 and earlier
if [ $MAC_VERSION -le 10009 ]
then
# Build a Universal Binary?
UB=$(file $LIBUSB_ARCHIVE | grep "Mach-O universal binary")
echo $UB
if [ -z "$UB" ]
then
echo -en $RED
echo "*************************"
echo "No Universal Binary build"
echo "*************************"
echo -en $NORMAL
else
echo "Universal Binary build"
CFLAGS="$CFLAGS -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk -arch i386 -arch x86_64"
fi
echo
fi
CONFIGURE_ARGS="--disable-dependency-tracking"
# Are we on a CryptoTokenKit system? (like Mac OS X 10.10 Yosemite)
if [ -d /System/Library/CryptoTokenKit ]
then
# so we use syslog(3) to log errors
CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-syslog"
fi
# Check where to install the driver
if [ 10011 -gt $MAC_VERSION ]
then
# Mac OS X < 10.11
DROPDIR="/usr/libexec/SmartCardServices/drivers"
else
# Mac OS X >= 10.11 (El Capitan)
DROPDIR="/usr/local/libexec/SmartCardServices/drivers"
fi
# do not build a static driver
# (building fails when linking statically with libusb)
CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-static"
# do not use pcscd debug feature
CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-pcsclite"
# simulate a composite device as multi slots
CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-composite-as-multislot"
# set BUNDLE_ID to a specific value for a specific driver
#BUNDLE_ID="vendor-reader"
if [ ! -z "$BUNDLE_ID" ]
then
# do not build a class driver (not yet used by pcsc-lite on Mac OS X)
CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-class"
# use a specific bundle name to NOT overwrite the official CCID driver
CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-bundle=ifd-ccid-$BUNDLE_ID.bundle"
# differentiate each libccid library by the dynamic linker
CONFIGURE_ARGS="$CONFIGURE_ARGS --prefix=/fake/$BUNDLE_ID"
fi
set -x
./configure \
CFLAGS="$CFLAGS" \
PCSC_CFLAGS="$PCSC_CFLAGS" \
PCSC_LIBS="$PCSC_LIBS" \
LIBUSB_CFLAGS="$LIBUSB_CFLAGS" \
LIBUSB_LIBS="$LIBUSB_LIBS" \
LDFLAGS="$LDFLAGS" \
--enable-usbdropdir="$DROPDIR" \
$CONFIGURE_ARGS \
"$@"
r=$?
# force a regeneration of Info.plist
rm -f src/Info.plist
# exit with the return code from ./configure
exit $r

43
MacOSX/convert_reader_h.pl Executable file
View File

@ -0,0 +1,43 @@
#!/usr/bin/env perl
# convert_reader_h.pl: convert reader.h.in in reader.h with
#
# Copyright (C) 2008 Ludovic Rousseau <ludovic.rousseau@free.fr>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use warnings;
use strict;
my $text =
"#ifdef __BIG_ENDIAN__
#define HOST_TO_CCID_16(x) ((((x) >> 8) & 0xFF) + ((x & 0xFF) << 8))
#define HOST_TO_CCID_32(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + ((x & 0xFF00) << 8) + (((x) & 0xFF) << 24))
#else
#define HOST_TO_CCID_16(x) (x)
#define HOST_TO_CCID_32(x) (x)
#endif
";
while (<>)
{
if (m/host_to_ccid_16/)
{
print $text;
<>;
next;
}
print;
}

133
MacOSX/debuglog.h Normal file
View File

@ -0,0 +1,133 @@
/*
* MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
*
* Copyright (C) 1999-2004
* David Corcoran <corcoran@musclecard.com>
* Copyright (C) 1999-2011
* Ludovic Rousseau <ludovic.rousseau@free.fr>
*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief This handles debugging.
*
* @note log message is sent to syslog or stderr depending on --foreground
* command line argument
*
* @code
* Log1(priority, "text");
* log "text" with priority level priority
* Log2(priority, "text: %d", 1234);
* log "text: 1234"
* the format string can be anything printf() can understand
* Log3(priority, "text: %d %d", 1234, 5678);
* log "text: 1234 5678"
* the format string can be anything printf() can understand
* LogXxd(priority, msg, buffer, size);
* log "msg" + a hex dump of size bytes of buffer[]
* @endcode
*/
#ifndef __debuglog_h__
#define __debuglog_h__
#ifndef PCSC_API
#define PCSC_API
#endif
enum {
DEBUGLOG_NO_DEBUG = 0,
DEBUGLOG_SYSLOG_DEBUG,
DEBUGLOG_STDOUT_DEBUG,
DEBUGLOG_STDOUT_COLOR_DEBUG
};
#define DEBUG_CATEGORY_NOTHING 0
#define DEBUG_CATEGORY_APDU 1
#define DEBUG_CATEGORY_SW 2
enum {
PCSC_LOG_DEBUG = 0,
PCSC_LOG_INFO,
PCSC_LOG_ERROR,
PCSC_LOG_CRITICAL
};
/* You can't do #ifndef __FUNCTION__ */
#if !defined(__GNUC__) && !defined(__IBMC__)
#define __FUNCTION__ ""
#endif
#ifndef __GNUC__
#define __attribute__(x) /*nothing*/
#endif
#ifdef NO_LOG
#define Log0(priority) do { } while(0)
#define Log1(priority, fmt) do { } while(0)
#define Log2(priority, fmt, data) do { } while(0)
#define Log3(priority, fmt, data1, data2) do { } while(0)
#define Log4(priority, fmt, data1, data2, data3) do { } while(0)
#define Log5(priority, fmt, data1, data2, data3, data4) do { } while(0)
#define Log9(priority, fmt, data1, data2, data3, data4, data5, data6, data7, data8) do { } while(0)
#define LogXxd(priority, msg, buffer, size) do { } while(0)
#define DebugLogA(a)
#define DebugLogB(a, b)
#define DebugLogC(a, b,c)
#else
#define Log0(priority) log_msg(priority, "%s:%d:%s()", __FILE__, __LINE__, __FUNCTION__)
#define Log1(priority, fmt) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__)
#define Log2(priority, fmt, data) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data)
#define Log3(priority, fmt, data1, data2) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2)
#define Log4(priority, fmt, data1, data2, data3) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3)
#define Log5(priority, fmt, data1, data2, data3, data4) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3, data4)
#define Log9(priority, fmt, data1, data2, data3, data4, data5, data6, data7, data8) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3, data4, data5, data6, data7, data8)
#define LogXxd(priority, msg, buffer, size) log_xxd(priority, msg, buffer, size)
#define DebugLogA(a) Log1(PCSC_LOG_INFO, a)
#define DebugLogB(a, b) Log2(PCSC_LOG_INFO, a, b)
#define DebugLogC(a, b,c) Log3(PCSC_LOG_INFO, a, b, c)
#endif /* NO_LOG */
PCSC_API void log_msg(const int priority, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
PCSC_API void log_xxd(const int priority, const char *msg,
const unsigned char *buffer, const int size);
void DebugLogSuppress(const int);
void DebugLogSetLogType(const int);
int DebugLogSetCategory(const int);
void DebugLogCategory(const int, const unsigned char *, const int);
PCSC_API void DebugLogSetLevel(const int level);
#endif /* __debuglog_h__ */

820
MacOSX/ifdhandler.h Normal file
View File

@ -0,0 +1,820 @@
/*
* MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
*
* Copyright (C) 1999-2004
* David Corcoran <corcoran@musclecard.com>
* Copyright (C) 2003-2004
* Damien Sauveron <damien.sauveron@labri.fr>
* Copyright (C) 2002-2011
* Ludovic Rousseau <ludovic.rousseau@free.fr>
*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @defgroup IFDHandler IFDHandler
* @brief This provides reader specific low-level calls.
The routines specified hereafter will allow you to write an IFD handler
for the PC/SC Lite resource manager. Please use the complement
developer's kit complete with headers and Makefile at:
http://www.musclecard.com/drivers.html
This gives a common API for communication to most readers in a
homogeneous fashion. This document assumes that the driver developer is
experienced with standards such as ISO-7816-(1, 2, 3, 4), EMV and MCT
specifications. For listings of these specifications please access the
above web site.
@section UsbReaders USB readers
USB readers use the bundle approach so that the reader can be loaded
and unloaded upon automatic detection of the device. The bundle
approach is simple: the actual library is just embedded in a
directory so additional information can be gathered about the device.
A bundle looks like the following:
@verbatim
GenericReader.bundle/
Contents/
Info.plist - XML file describing the reader
MacOS/ - Driver directory for OS X
Solaris/ - Driver directory for Solaris
Linux/ - Driver directory for Linux
HPUX/ - Driver directory for HPUX
@endverbatim
The @c Info.plist file describes the driver and gives the loader
all the necessary information. The following must be contained in the
@c Info.plist file:
@subsection ifdVendorID
The vendor ID of the USB device.
Example:
@verbatim
<key>ifdVendorID</key>
<string>0x04E6</string>
@endverbatim
You may have an OEM of this reader in which an additional @c <string>
can be used like in the below example:
@verbatim
<key>ifdVendorID</key>
<array>
<string>0x04E6</string>
<string>0x0973</string>
</array>
@endverbatim
If multiples exist all the other parameters must have a second value
also. You may chose not to support this feature but it is useful when
reader vendors OEM products so you only distribute one driver.
The CCID driver from Ludovic Rousseau
http://pcsclite.alioth.debian.org/ccid.html uses this feature since the
same driver supports many different readers.
@subsection ifdProductID
The product id of the USB device.
@verbatim
<key>ifdProductID</key>
<string>0x3437</string>
@endverbatim
@subsection ifdFriendlyName
Example:
@verbatim
<key>ifdFriendlyName</key>
<string>SCM Microsystems USB Reader</string>
@endverbatim
The reader name must use the ASCII character set.
@subsection CFBundleExecutable
The executable name which exists in the particular platform's directory.
Example:
@verbatim
<key>CFBundleExecutable</key>
<string>libccid.so.0.4.2</string>
@endverbatim
@subsection ifdCapabilities
List of capabilities supported by the driver. This is a bit field. Possible values are:
- 0
No special capabilities
- 1 IFD_GENERATE_HOTPLUG
The driver supports the hot plug feature.
Complete sample file:
@verbatim
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.0.1d1</string>
<key>ifdCapabilities</key>
<string>0x00000000</string>
<key>ifdProtocolSupport</key>
<string>0x00000001</string>
<key>ifdVersionNumber</key>
<string>0x00000001</string>
<key>CFBundleExecutable</key>
<string>libfoobar.so.x.y</string>
<key>ifdManufacturerString</key>
<string>Foo bar inc.</string>
<key>ifdProductString</key>
<string>Driver for Foobar reader, version x.y</string>
<key>ifdVendorID</key>
<string>0x1234</string>
<key>ifdProductID</key>
<string>0x5678</string>
<key>ifdFriendlyName</key>
<string>Foobar USB reader</string>
</dict>
</plist>
@endverbatim
As indicated in the XML file the DTD is available at
http://www.apple.com/DTDs/PropertyList-1.0.dtd.
@section SerialReaders Serial readers
Serial drivers must be configured to operate on a particular port and
respond to a particular name. The @c reader.conf file is used for this
purpose.
It has the following syntax:
@verbatim
# Configuration file for pcsc-lite
# David Corcoran <corcoran@musclecard.com>
FRIENDLYNAME Generic Reader
DEVICENAME /dev/ttyS0
LIBPATH /usr/lib/pcsc/drivers/libgen_ifd.so
CHANNELID 1
@endverbatim
The pound sign # denotes a comment.
@subsection FRIENDLYNAME
The FRIENDLYNAME field is an arbitrary text used to identify the reader.
This text is displayed by commands like @c pcsc_scan
http://ludovic.rousseau.free.fr/softwares/pcsc-tools/ that prints the
names of all the connected and detected readers.
@subsection DEVICENAME
The DEVICENAME field was not used for old drivers (using the IFD handler
version 2.0 or previous). It is now (IFD handler version 3.0) used to
identify the physical port on which the reader is connected. This is
the device name of this port. It is dependent of the OS kernel. For
example the first serial port device is called @c /dev/ttyS0 under Linux
and @c /dev/cuaa0 under FreeBSD.
If you want to use IFDHCreateChannel() instead of
IFDHCreateChannelByName() then do not use any DEVICENAME line in the
configuration file. IFDHCreateChannel() will then be called with the
CHANNELID parameter.
@subsection LIBPATH
The LIBPATH field is the filename of the driver code. The driver is a
dynamically loaded piece of code (generally a @c drivername.so* file).
@subsection CHANNELID
The CHANNELID is no more used for recent drivers (IFD handler 3.0) and
has been superseded by DEVICENAME.
If you have an old driver this field is used to indicate the port to
use. You should read your driver documentation to know what information
is needed here. It should be the serial port number for a serial reader.
CHANNELID was the numeric version of the port in which the reader will
be located. This may be done by a symbolic link where @c /dev/pcsc/1 is
the first device which may be a symbolic link to @c /dev/ttyS0 or
whichever location your reader resides.
*/
#ifndef _ifd_handler_h_
#define _ifd_handler_h_
#include <pcsclite.h>
/*
* List of data structures available to ifdhandler
*/
typedef struct _DEVICE_CAPABILITIES
{
LPSTR Vendor_Name; /**< Tag 0x0100 */
LPSTR IFD_Type; /**< Tag 0x0101 */
DWORD IFD_Version; /**< Tag 0x0102 */
LPSTR IFD_Serial; /**< Tag 0x0103 */
DWORD IFD_Channel_ID; /**< Tag 0x0110 */
DWORD Asynch_Supported; /**< Tag 0x0120 */
DWORD Default_Clock; /**< Tag 0x0121 */
DWORD Max_Clock; /**< Tag 0x0122 */
DWORD Default_Data_Rate; /**< Tag 0x0123 */
DWORD Max_Data_Rate; /**< Tag 0x0124 */
DWORD Max_IFSD; /**< Tag 0x0125 */
DWORD Synch_Supported; /**< Tag 0x0126 */
DWORD Power_Mgmt; /**< Tag 0x0131 */
DWORD Card_Auth_Devices; /**< Tag 0x0140 */
DWORD User_Auth_Device; /**< Tag 0x0142 */
DWORD Mechanics_Supported; /**< Tag 0x0150 */
DWORD Vendor_Features; /**< Tag 0x0180 - 0x01F0 User Defined. */
}
DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES;
typedef struct _ICC_STATE
{
UCHAR ICC_Presence; /**< Tag 0x0300 */
UCHAR ICC_Interface_Status; /**< Tag 0x0301 */
UCHAR ATR[MAX_ATR_SIZE]; /**< Tag 0x0303 */
UCHAR ICC_Type; /**< Tag 0x0304 */
}
ICC_STATE, *PICC_STATE;
typedef struct _PROTOCOL_OPTIONS
{
DWORD Protocol_Type; /**< Tag 0x0201 */
DWORD Current_Clock; /**< Tag 0x0202 */
DWORD Current_F; /**< Tag 0x0203 */
DWORD Current_D; /**< Tag 0x0204 */
DWORD Current_N; /**< Tag 0x0205 */
DWORD Current_W; /**< Tag 0x0206 */
DWORD Current_IFSC; /**< Tag 0x0207 */
DWORD Current_IFSD; /**< Tag 0x0208 */
DWORD Current_BWT; /**< Tag 0x0209 */
DWORD Current_CWT; /**< Tag 0x020A */
DWORD Current_EBC; /**< Tag 0x020B */
}
PROTOCOL_OPTIONS, *PPROTOCOL_OPTIONS;
/**
* Use by SCardTransmit()
*/
typedef struct _SCARD_IO_HEADER
{
DWORD Protocol;
DWORD Length;
}
SCARD_IO_HEADER, *PSCARD_IO_HEADER;
/*
* The list of tags should be alot more but this is all I use in the
* meantime
*/
#define TAG_IFD_ATR 0x0303 /**< ATR */
#define TAG_IFD_SLOTNUM 0x0180 /**< select a slot */
#define TAG_IFD_SLOT_THREAD_SAFE 0x0FAC /**< support access to different slots of the reader */
#define TAG_IFD_THREAD_SAFE 0x0FAD /**< driver is thread safe */
#define TAG_IFD_SLOTS_NUMBER 0x0FAE /**< number of slots of the reader */
#define TAG_IFD_SIMULTANEOUS_ACCESS 0x0FAF /**< number of reader the driver can manage */
#define TAG_IFD_POLLING_THREAD 0x0FB0 /**< not used. See TAG_IFD_POLLING_THREAD_WITH_TIMEOUT */
#define TAG_IFD_POLLING_THREAD_KILLABLE 0x0FB1 /**< the polling thread can be killed */
#define TAG_IFD_STOP_POLLING_THREAD 0x0FB2 /**< method used to stop the polling thread (instead of just pthread_kill()) */
#define TAG_IFD_POLLING_THREAD_WITH_TIMEOUT 0x0FB3 /**< driver uses a polling thread with a timeout parameter */
/*
* IFD Handler version number enummerations
*/
#define IFD_HVERSION_1_0 0x00010000
#define IFD_HVERSION_2_0 0x00020000
#define IFD_HVERSION_3_0 0x00030000
/*
* List of defines available to ifdhandler
*/
#define IFD_POWER_UP 500 /**< power up the card */
#define IFD_POWER_DOWN 501 /**< power down the card */
#define IFD_RESET 502 /**< warm reset */
#define IFD_NEGOTIATE_PTS1 1 /**< negotiate PTS1 */
#define IFD_NEGOTIATE_PTS2 2 /**< negotiate PTS2 */
#define IFD_NEGOTIATE_PTS3 4 /**< negotiate PTS3 */
#define IFD_SUCCESS 0 /**< no error */
#define IFD_ERROR_TAG 600 /**< tag unknown */
#define IFD_ERROR_SET_FAILURE 601 /**< set failed */
#define IFD_ERROR_VALUE_READ_ONLY 602 /**< value is read only */
#define IFD_ERROR_PTS_FAILURE 605 /**< failed to negotiate PTS */
#define IFD_ERROR_NOT_SUPPORTED 606
#define IFD_PROTOCOL_NOT_SUPPORTED 607 /**< requested protocol not supported */
#define IFD_ERROR_POWER_ACTION 608 /**< power up failed */
#define IFD_ERROR_SWALLOW 609
#define IFD_ERROR_EJECT 610
#define IFD_ERROR_CONFISCATE 611
#define IFD_COMMUNICATION_ERROR 612 /**< generic error */
#define IFD_RESPONSE_TIMEOUT 613 /**< timeout */
#define IFD_NOT_SUPPORTED 614 /**< request is not supported */
#define IFD_ICC_PRESENT 615 /**< card is present */
#define IFD_ICC_NOT_PRESENT 616 /**< card is absent */
/**
* The \ref IFD_NO_SUCH_DEVICE error must be returned by the driver when
* it detects the reader is no more present. This will tell pcscd to
* remove the reader from the list of available readers.
*/
#define IFD_NO_SUCH_DEVICE 617
#define IFD_ERROR_INSUFFICIENT_BUFFER 618 /**< buffer is too small */
#ifndef RESPONSECODE_DEFINED_IN_WINTYPES_H
typedef long RESPONSECODE;
#endif
/*
* If you want to compile a V2.0 IFDHandler, define IFDHANDLERv2
* before you include this file.
*
* By default it is setup for for most recent version of the API (V3.0)
*/
#ifndef IFDHANDLERv2
/*
* List of Defined Functions Available to IFD_Handler 3.0
*
* All the functions of IFD_Handler 2.0 are available
* IFDHCreateChannelByName() is new
* IFDHControl() API changed
*/
/**
This function is required to open a communications channel to the port
listed by @p DeviceName.
Once the channel is opened the reader must be in a state in which it is
possible to query IFDHICCPresence() for card status.
@ingroup IFDHandler
@param[in] Lun Logical Unit Number\n
Use this for multiple card slots or multiple readers. 0xXXXXYYYY -
XXXX multiple readers, YYYY multiple slots. The resource manager will
set these automatically. By default the resource manager loads a new
instance of the driver so if your reader does not have more than one
smart card slot then ignore the Lun in all the functions.\n
\n
PC/SC supports the loading of multiple readers through one instance of
the driver in which XXXX is important. XXXX identifies the unique
reader in which the driver communicates to. The driver should set up
an array of structures that asociate this XXXX with the underlying
details of the particular reader.
@param[in] DeviceName Filename to use by the driver.\n
For drivers configured by @p /etc/reader.conf this is the value of the
field \ref DEVICENAME.
\n
For USB drivers the @p DeviceName must start with @p usb:VID/PID. VID
is the Vendor ID and PID is the Product ID. Both are a 4-digits hex
number.
Typically the string is generated by:
@code
printf("usb:%04x/%04x", idVendor, idProduct);
@endcode
The @p DeviceName string may also contain a more specialised
identification string. This additional information is used to
differentiate between two identical readers connected at the same time.
In this case the driver can't differentiate the two readers using VID
and PID and must use some additional information identifying the USB
port used by each reader.
- libusb
For USB drivers using libusb-1.0 http://libusb.sourceforge.net/ for USB
abstraction the @p DeviceName the string may be generated by:
@code
printf("usb:%04x/%04x:libusb-1.0:%d:%d:%d",
idVendor, idProduct, bus_number, device_address, interface)
@endcode
So it is something like: <tt>usb:08e6/3437:libusb-1.0:7:99:0</tt> under
GNU/Linux.
- libudev
If pcscd is compiled with libudev support instead of libusb (default
since pcsc-lite 1.6.8) the string will look like:
@code
printf("usb:%04x/%04x:libudev:%d:%s", idVendor, idProduct,
bInterfaceNumber, devpath);
@endcode
bInterfaceNumber is the number of the interface on the device. It is
only usefull for devices with more than one CCID interface.
devpath is the filename of the device on the file system.
So it is something like:
<tt>usb:08e6/3437:libudev:0:/dev/bus/usb/008/047</tt>
under GNU/Linux.
- other
If the driver does not understand the <tt>:libusb:</tt> or
<tt>:libudev:</tt> scheme or if a new scheme is used, the driver should
ignore the part it does not understand instead of failing.
The driver shall recognize the <tt>usb:VID/PID</tt> part and, only if
possible, the remaining of the DeviceName field.
It is the responsibility of the driver to correctly identify the reader.
@return Error codes
@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref IFD_COMMUNICATION_ERROR)
@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref IFD_NO_SUCH_DEVICE)
*/
RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPSTR DeviceName);
/**
This function performs a data exchange with the reader (not the card)
specified by Lun. It is responsible for abstracting functionality such
as PIN pads, biometrics, LCD panels, etc. You should follow the MCT and
CTBCS specifications for a list of accepted commands to implement. This
function is fully voluntary and does not have to be implemented unless
you want extended functionality.
@ingroup IFDHandler
@param[in] Lun Logical Unit Number
@param[in] dwControlCode Control code for the operation\n
This value identifies the specific operation to be performed. This
value is driver specific.
@param[in] TxBuffer Transmit data
@param[in] TxLength Length of this buffer
@param[out] RxBuffer Receive data
@param[in] RxLength Length of the response buffer
@param[out] pdwBytesReturned Length of response\n
This function will be passed the length of the buffer RxBuffer in
RxLength and it must set the length of the received data in
pdwBytesReturned.
@note
@p *pdwBytesReturned should be set to zero on error.
@return Error codes
@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref IFD_COMMUNICATION_ERROR)
@retval IFD_RESPONSE_TIMEOUT The response timed out (\ref IFD_RESPONSE_TIMEOUT)
@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref IFD_NO_SUCH_DEVICE)
*/
RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode, PUCHAR
TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength,
LPDWORD pdwBytesReturned);
#else
/**
* Available in IFD_Handler 2.0
*
* @deprecated
* You should use the new form of IFDHControl()
*/
RESPONSECODE IFDHControl(DWORD Lun, PUCHAR TxBuffer, DWORD TxLength,
PUCHAR RxBuffer, PDWORD RxLength);
#endif
/*
* common functions in IFD_Handler 2.0 and 3.0
*/
/**
This function is required to open a communications channel to the port
listed by Channel. For example, the first serial reader on COM1 would
link to @p /dev/pcsc/1 which would be a symbolic link to @p /dev/ttyS0
on some machines This is used to help with inter-machine independence.
On machines with no /dev directory the driver writer may choose to map
their Channel to whatever they feel is appropriate.
Once the channel is opened the reader must be in a state in which it is
possible to query IFDHICCPresence() for card status.
USB readers can ignore the @p Channel parameter and query the USB bus
for the particular reader by manufacturer and product id.
@ingroup IFDHandler
@param[in] Lun Logical Unit Number\n
Use this for multiple card slots or multiple readers. 0xXXXXYYYY -
XXXX multiple readers, YYYY multiple slots. The resource manager will
set these automatically. By default the resource manager loads a new
instance of the driver so if your reader does not have more than one
smart card slot then ignore the Lun in all the functions.\n
\n
PC/SC supports the loading of multiple readers through one instance of
the driver in which XXXX is important. XXXX identifies the unique
reader in which the driver communicates to. The driver should set up
an array of structures that associate this XXXX with the underlying
details of the particular reader.
@param[in] Channel Channel ID
This is denoted by the following:
- 0x000001 @p /dev/pcsc/1
- 0x000002 @p /dev/pcsc/2
- 0x000003 @p /dev/pcsc/3
- 0x000004 @p /dev/pcsc/4
@return Error codes
@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref IFD_COMMUNICATION_ERROR)
@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref IFD_NO_SUCH_DEVICE)
*/
RESPONSECODE IFDHCreateChannel(DWORD Lun, DWORD Channel);
/**
This function should close the reader communication channel for the
particular reader. Prior to closing the communication channel the reader
should make sure the card is powered down and the terminal is also
powered down.
@ingroup IFDHandler
@param[in] Lun Logical Unit Number
@return Error codes
@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref IFD_COMMUNICATION_ERROR)
@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref IFD_NO_SUCH_DEVICE)
*/
RESPONSECODE IFDHCloseChannel(DWORD Lun);
/**
This function should get the slot/card capabilities for a particular
slot/card specified by Lun. Again, if you have only 1 card slot and
don't mind loading a new driver for each reader then ignore Lun.
@ingroup IFDHandler
@param[in] Lun Logical Unit Number
@param[in] Tag Tag of the desired data value
- \ref TAG_IFD_ATR
Return the ATR and its size (implementation is mandatory).
- \ref TAG_IFD_SLOTNUM
Unused/deprecated
- \ref SCARD_ATTR_ATR_STRING
Same as \ref TAG_IFD_ATR but this one is not mandatory. It is defined
in Microsoft PC/SC SCardGetAttrib().
- \ref TAG_IFD_SIMULTANEOUS_ACCESS
Return the number of sessions (readers) the driver can handle in
<tt>Value[0]</tt>.
This is used for multiple readers sharing the same driver.
- \ref TAG_IFD_THREAD_SAFE
If the driver supports more than one reader (see
\ref TAG_IFD_SIMULTANEOUS_ACCESS above) this tag indicates if the
driver supports access to multiple readers at the same time.\n
<tt>Value[0] = 1</tt> indicates the driver supports simultaneous accesses.
- \ref TAG_IFD_SLOTS_NUMBER
Return the number of slots in this reader in <tt>Value[0]</tt>.
- \ref TAG_IFD_SLOT_THREAD_SAFE
If the reader has more than one slot (see \ref TAG_IFD_SLOTS_NUMBER
above) this tag indicates if the driver supports access to multiple
slots of the same reader at the same time.\n
<tt>Value[0] = 1</tt> indicates the driver supports simultaneous slot
accesses.
- \ref TAG_IFD_POLLING_THREAD
Unused/deprecated
- \ref TAG_IFD_POLLING_THREAD_WITH_TIMEOUT
If the driver provides a polling thread then @p Value is a pointer to
this function. The function prototype is:
@verbatim
RESPONSECODE foo(DWORD Lun, int timeout);
@endverbatim
- \ref TAG_IFD_POLLING_THREAD_KILLABLE
Tell if the polling thread can be killed (pthread_kill()) by pcscd
- \ref TAG_IFD_STOP_POLLING_THREAD
Returns a pointer in @p Value to the function used to stop the polling
thread returned by \ref TAG_IFD_POLLING_THREAD_WITH_TIMEOUT. The
function prototype is:
@verbatim
RESPONSECODE foo(DWORD Lun);
@endverbatim
@param[in,out] Length Length of the desired data value
@param[out] Value Value of the desired data
@return Error codes
@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
@retval IFD_ERROR_TAG Invalid tag given (\ref IFD_ERROR_TAG)
@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref IFD_NO_SUCH_DEVICE)
*/
RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag, PDWORD Length,
PUCHAR Value);
/**
This function should set the slot/card capabilities for a particular
slot/card specified by @p Lun. Again, if you have only 1 card slot and
don't mind loading a new driver for each reader then ignore @p Lun.
@ingroup IFDHandler
@param[in] Lun Logical Unit Number
@param[in] Tag Tag of the desired data value
@param[in,out] Length Length of the desired data value
@param[out] Value Value of the desired data
This function is also called when the application uses the PC/SC
SCardGetAttrib() function. The list of supported tags is not limited.
@return Error codes
@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
@retval IFD_ERROR_TAG Invalid tag given (\ref IFD_ERROR_TAG)
@retval IFD_ERROR_SET_FAILURE Could not set value (\ref IFD_ERROR_SET_FAILURE)
@retval IFD_ERROR_VALUE_READ_ONLY Trying to set read only value (\ref IFD_ERROR_VALUE_READ_ONLY)
@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref IFD_NO_SUCH_DEVICE)
*/
RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag, DWORD Length, PUCHAR Value);
/**
This function should set the Protocol Type Selection (PTS) of a
particular card/slot using the three PTS parameters sent
@ingroup IFDHandler
@param[in] Lun Logical Unit Number
@param[in] Protocol Desired protocol
- \ref SCARD_PROTOCOL_T0
T=0 protocol
- \ref SCARD_PROTOCOL_T1
T=1 protocol
@param[in] Flags Logical OR of possible values to determine which PTS values
to negotiate
- \ref IFD_NEGOTIATE_PTS1
- \ref IFD_NEGOTIATE_PTS2
- \ref IFD_NEGOTIATE_PTS3
@param[in] PTS1 1st PTS Value
@param[in] PTS2 2nd PTS Value
@param[in] PTS3 3rd PTS Value\n
See ISO 7816/EMV documentation.
@return Error codes
@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
@retval IFD_ERROR_PTS_FAILURE Could not set PTS value (\ref IFD_ERROR_PTS_FAILURE)
@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref IFD_COMMUNICATION_ERROR)
@retval IFD_PROTOCOL_NOT_SUPPORTED Protocol is not supported (\ref IFD_PROTOCOL_NOT_SUPPORTED)
@retval IFD_NOT_SUPPORTED Action not supported (\ref IFD_NOT_SUPPORTED)
@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref IFD_NO_SUCH_DEVICE)
*/
RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol, UCHAR Flags,
UCHAR PTS1, UCHAR PTS2, UCHAR PTS3);
/**
This function controls the power and reset signals of the smart card
reader at the particular reader/slot specified by @p Lun.
@ingroup IFDHandler
@param[in] Lun Logical Unit Number
@param[in] Action Action to be taken on the card
- \ref IFD_POWER_UP
Power up the card (store and return Atr and AtrLength)
- \ref IFD_POWER_DOWN
Power down the card (Atr and AtrLength should be zeroed)
- \ref IFD_RESET
Perform a warm reset of the card (no power down). If the card is not powered then power up the card (store and return Atr and AtrLength)
@param[out] Atr Answer to Reset (ATR) of the card\n
The driver is responsible for caching this value in case
IFDHGetCapabilities() is called requesting the ATR and its length. The
ATR length should not exceed \ref MAX_ATR_SIZE.
@param[in,out] AtrLength Length of the ATR\n
This should not exceed \ref MAX_ATR_SIZE.
@note
Memory cards without an ATR should return \ref IFD_SUCCESS on reset but the
Atr should be zeroed and the length should be zero Reset errors should
return zero for the AtrLength and return \ref IFD_ERROR_POWER_ACTION.
@return Error codes
@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
@retval IFD_ERROR_POWER_ACTION Error powering/resetting card (\ref IFD_ERROR_POWER_ACTION)
@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref IFD_COMMUNICATION_ERROR)
@retval IFD_NOT_SUPPORTED Action not supported (\ref IFD_NOT_SUPPORTED)
@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref IFD_NO_SUCH_DEVICE)
*/
RESPONSECODE IFDHPowerICC(DWORD Lun, DWORD Action, PUCHAR Atr, PDWORD
AtrLength);
/**
This function performs an APDU exchange with the card/slot specified by
Lun. The driver is responsible for performing any protocol specific
exchanges such as T=0, 1, etc. differences. Calling this function will
abstract all protocol differences.
@ingroup IFDHandler
@param[in] Lun Logical Unit Number
@param[in] SendPci contains two structure members
- Protocol 0, 1, ... 14\n
T=0 ... T=14
- Length\n
Not used.
@param[in] TxBuffer Transmit APDU\n
Example: "\x00\xA4\x00\x00\x02\x3F\x00"
@param[in] TxLength Length of this buffer
@param[out] RxBuffer Receive APDU\n
Example: "\x61\x14"
@param[in,out] RxLength Length of the received APDU\n
This function will be passed the size of the buffer of RxBuffer and
this function is responsible for setting this to the length of the
received APDU response. This should be ZERO on all errors. The
resource manager will take responsibility of zeroing out any temporary
APDU buffers for security reasons.
@param[out] RecvPci contains two structure members
- Protocol - 0, 1, ... 14\n
T=0 ... T=14
- Length\n
Not used.
@note
The driver is responsible for knowing what type of card it has. If the
current slot/card contains a memory card then this command should ignore
the Protocol and use the MCT style commands for support for these style
cards and transmit them appropriately. If your reader does not support
memory cards or you don't want to implement this functionality, then
ignore this.
@par
RxLength should be set to zero on error.
@par
The driver is not responsible for doing an automatic Get Response
command for received buffers containing 61 XX.
@return Error codes
@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref IFD_COMMUNICATION_ERROR)
@retval IFD_RESPONSE_TIMEOUT The response timed out (\ref IFD_RESPONSE_TIMEOUT)
@retval IFD_ICC_NOT_PRESENT ICC is not present (\ref IFD_ICC_NOT_PRESENT)
@retval IFD_NOT_SUPPORTED Action not supported (\ref IFD_NOT_SUPPORTED)
@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref IFD_NO_SUCH_DEVICE)
*/
RESPONSECODE IFDHTransmitToICC(DWORD Lun, SCARD_IO_HEADER SendPci,
PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD
RxLength, PSCARD_IO_HEADER RecvPci);
/**
This function returns the status of the card inserted in the reader/slot
specified by @p Lun. In cases where the device supports asynchronous
card insertion/removal detection, it is advised that the driver manages
this through a thread so the driver does not have to send and receive a
command each time this function is called.
@ingroup IFDHandler
@param[in] Lun Logical Unit Number
@return Error codes
@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref IFD_COMMUNICATION_ERROR)
@retval IFD_ICC_NOT_PRESENT ICC is not present (\ref IFD_ICC_NOT_PRESENT)
@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref IFD_NO_SUCH_DEVICE)
*/
RESPONSECODE IFDHICCPresence(DWORD Lun);
#endif

2
MacOSX/pcsclite.h Normal file
View File

@ -0,0 +1,2 @@
#include <PCSC/pcsclite.h>
#include <PCSC/wintypes.h>

271
MacOSX/reader.h Normal file
View File

@ -0,0 +1,271 @@
/*
* MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
*
* Copyright (C) 1999-2005
* David Corcoran <corcoran@musclecard.com>
* Copyright (C) 2005-2009
* Ludovic Rousseau <ludovic.rousseau@free.fr>
*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief This keeps a list of defines shared between the driver and the application
*/
#ifndef __reader_h__
#define __reader_h__
/*
* Tags for requesting card and reader attributes
*/
#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag)))
#define SCARD_CLASS_VENDOR_INFO 1 /**< Vendor information definitions */
#define SCARD_CLASS_COMMUNICATIONS 2 /**< Communication definitions */
#define SCARD_CLASS_PROTOCOL 3 /**< Protocol definitions */
#define SCARD_CLASS_POWER_MGMT 4 /**< Power Management definitions */
#define SCARD_CLASS_SECURITY 5 /**< Security Assurance definitions */
#define SCARD_CLASS_MECHANICAL 6 /**< Mechanical characteristic definitions */
#define SCARD_CLASS_VENDOR_DEFINED 7 /**< Vendor specific definitions */
#define SCARD_CLASS_IFD_PROTOCOL 8 /**< Interface Device Protocol options */
#define SCARD_CLASS_ICC_STATE 9 /**< ICC State specific definitions */
#define SCARD_CLASS_SYSTEM 0x7fff /**< System-specific definitions */
#define SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0100) /**< Vendor name. */
#define SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0101) /**< Vendor-supplied interface device type (model designation of reader). */
#define SCARD_ATTR_VENDOR_IFD_VERSION SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0102) /**< Vendor-supplied interface device version (DWORD in the form 0xMMmmbbbb where MM = major version, mm = minor version, and bbbb = build number). */
#define SCARD_ATTR_VENDOR_IFD_SERIAL_NO SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0103) /**< Vendor-supplied interface device serial number. */
#define SCARD_ATTR_CHANNEL_ID SCARD_ATTR_VALUE(SCARD_CLASS_COMMUNICATIONS, 0x0110) /**< DWORD encoded as 0xDDDDCCCC, where DDDD = data channel type and CCCC = channel number */
#define SCARD_ATTR_ASYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0120) /**< FIXME */
#define SCARD_ATTR_DEFAULT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0121) /**< Default clock rate, in kHz. */
#define SCARD_ATTR_MAX_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0122) /**< Maximum clock rate, in kHz. */
#define SCARD_ATTR_DEFAULT_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0123) /**< Default data rate, in bps. */
#define SCARD_ATTR_MAX_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0124) /**< Maximum data rate, in bps. */
#define SCARD_ATTR_MAX_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0125) /**< Maximum bytes for information file size device. */
#define SCARD_ATTR_SYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0126) /**< FIXME */
#define SCARD_ATTR_POWER_MGMT_SUPPORT SCARD_ATTR_VALUE(SCARD_CLASS_POWER_MGMT, 0x0131) /**< Zero if device does not support power down while smart card is inserted. Nonzero otherwise. */
#define SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0140) /**< FIXME */
#define SCARD_ATTR_USER_AUTH_INPUT_DEVICE SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0142) /**< FIXME */
#define SCARD_ATTR_CHARACTERISTICS SCARD_ATTR_VALUE(SCARD_CLASS_MECHANICAL, 0x0150) /**< DWORD indicating which mechanical characteristics are supported. If zero, no special characteristics are supported. Note that multiple bits can be set */
#define SCARD_ATTR_CURRENT_PROTOCOL_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0201) /**< FIXME */
#define SCARD_ATTR_CURRENT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0202) /**< Current clock rate, in kHz. */
#define SCARD_ATTR_CURRENT_F SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0203) /**< Clock conversion factor. */
#define SCARD_ATTR_CURRENT_D SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0204) /**< Bit rate conversion factor. */
#define SCARD_ATTR_CURRENT_N SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0205) /**< Current guard time. */
#define SCARD_ATTR_CURRENT_W SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0206) /**< Current work waiting time. */
#define SCARD_ATTR_CURRENT_IFSC SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0207) /**< Current byte size for information field size card. */
#define SCARD_ATTR_CURRENT_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0208) /**< Current byte size for information field size device. */
#define SCARD_ATTR_CURRENT_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0209) /**< Current block waiting time. */
#define SCARD_ATTR_CURRENT_CWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020a) /**< Current character waiting time. */
#define SCARD_ATTR_CURRENT_EBC_ENCODING SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020b) /**< Current error block control encoding. */
#define SCARD_ATTR_EXTENDED_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020c) /**< FIXME */
#define SCARD_ATTR_ICC_PRESENCE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0300) /**< Single byte indicating smart card presence */
#define SCARD_ATTR_ICC_INTERFACE_STATUS SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0301) /**< Single byte. Zero if smart card electrical contact is not active; nonzero if contact is active. */
#define SCARD_ATTR_CURRENT_IO_STATE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0302) /**< FIXME */
#define SCARD_ATTR_ATR_STRING SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0303) /**< Answer to reset (ATR) string. */
#define SCARD_ATTR_ICC_TYPE_PER_ATR SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0304) /**< Single byte indicating smart card type */
#define SCARD_ATTR_ESC_RESET SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA000) /**< FIXME */
#define SCARD_ATTR_ESC_CANCEL SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA003) /**< FIXME */
#define SCARD_ATTR_ESC_AUTHREQUEST SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA005) /**< FIXME */
#define SCARD_ATTR_MAXINPUT SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA007) /**< FIXME */
#define SCARD_ATTR_DEVICE_UNIT SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0001) /**< Instance of this vendor's reader attached to the computer. The first instance will be device unit 0, the next will be unit 1 (if it is the same brand of reader) and so on. Two different brands of readers will both have zero for this value. */
#define SCARD_ATTR_DEVICE_IN_USE SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0002) /**< Reserved for future use. */
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0003)
#define SCARD_ATTR_DEVICE_SYSTEM_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0004)
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0005)
#define SCARD_ATTR_DEVICE_SYSTEM_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0006)
#define SCARD_ATTR_SUPRESS_T1_IFS_REQUEST SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0007) /**< FIXME */
#ifdef UNICODE
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_W /**< Reader's display name. */
#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_W /**< Reader's system name. */
#else
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_A /**< Reader's display name. */
#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_A /**< Reader's system name. */
#endif
/**
* Provide source compatibility on different platforms
*/
#define SCARD_CTL_CODE(code) (0x42000000 + (code))
/**
* PC/SC part 10 v2.02.07 March 2010 reader tags
*/
#define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
#define FEATURE_VERIFY_PIN_START 0x01
#define FEATURE_VERIFY_PIN_FINISH 0x02
#define FEATURE_MODIFY_PIN_START 0x03
#define FEATURE_MODIFY_PIN_FINISH 0x04
#define FEATURE_GET_KEY_PRESSED 0x05
#define FEATURE_VERIFY_PIN_DIRECT 0x06 /**< Verify PIN */
#define FEATURE_MODIFY_PIN_DIRECT 0x07 /**< Modify PIN */
#define FEATURE_MCT_READER_DIRECT 0x08
#define FEATURE_MCT_UNIVERSAL 0x09
#define FEATURE_IFD_PIN_PROPERTIES 0x0A /**< retrieve properties of the IFD regarding PIN handling */
#define FEATURE_ABORT 0x0B
#define FEATURE_SET_SPE_MESSAGE 0x0C
#define FEATURE_VERIFY_PIN_DIRECT_APP_ID 0x0D
#define FEATURE_MODIFY_PIN_DIRECT_APP_ID 0x0E
#define FEATURE_WRITE_DISPLAY 0x0F
#define FEATURE_GET_KEY 0x10
#define FEATURE_IFD_DISPLAY_PROPERTIES 0x11
#define FEATURE_GET_TLV_PROPERTIES 0x12
#define FEATURE_CCID_ESC_COMMAND 0x13
#define FEATURE_EXECUTE_PACE 0x20
/* structures used (but not defined) in PC/SC Part 10:
* "IFDs with Secure Pin Entry Capabilities" */
#include <inttypes.h>
/* Set structure elements aligment on bytes
* http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html */
#if defined(__APPLE__) | defined(sun)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
/** the structure must be 6-bytes long */
typedef struct
{
uint8_t tag;
uint8_t length;
uint32_t value; /**< This value is always in BIG ENDIAN format as documented in PCSC v2 part 10 ch 2.2 page 2. You can use ntohl() for example */
} PCSC_TLV_STRUCTURE;
/** Since CCID 1.4.1 (revision 5252) the byte order is no more important
* These macros are now deprecated and should be removed in the future */
#define HOST_TO_CCID_16(x) (x)
#define HOST_TO_CCID_32(x) (x)
/** structure used with \ref FEATURE_VERIFY_PIN_DIRECT */
typedef struct
{
uint8_t bTimerOut; /**< timeout is seconds (00 means use default timeout) */
uint8_t bTimerOut2; /**< timeout in seconds after first key stroke */
uint8_t bmFormatString; /**< formatting options */
uint8_t bmPINBlockString; /**< bits 7-4 bit size of PIN length in APDU,
* bits 3-0 PIN block size in bytes after
* justification and formatting */
uint8_t bmPINLengthFormat; /**< bits 7-5 RFU,
* bit 4 set if system units are bytes, clear if
* system units are bits,
* bits 3-0 PIN length position in system units */
uint16_t wPINMaxExtraDigit; /**< 0xXXYY where XX is minimum PIN size in digits,
and YY is maximum PIN size in digits */
uint8_t bEntryValidationCondition; /**< Conditions under which PIN entry should
* be considered complete */
uint8_t bNumberMessage; /**< Number of messages to display for PIN verification */
uint16_t wLangId; /**< Language for messages */
uint8_t bMsgIndex; /**< Message index (should be 00) */
uint8_t bTeoPrologue[3]; /**< T=1 block prologue field to use (fill with 00) */
uint32_t ulDataLength; /**< length of Data to be sent to the ICC */
uint8_t abData
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
[] /* valid C99 code */
#else
[0] /* non-standard, but usually working code */
#endif
; /**< Data to send to the ICC */
} PIN_VERIFY_STRUCTURE;
/** structure used with \ref FEATURE_MODIFY_PIN_DIRECT */
typedef struct
{
uint8_t bTimerOut; /**< timeout is seconds (00 means use default timeout) */
uint8_t bTimerOut2; /**< timeout in seconds after first key stroke */
uint8_t bmFormatString; /**< formatting options */
uint8_t bmPINBlockString; /**< bits 7-4 bit size of PIN length in APDU,
* bits 3-0 PIN block size in bytes after
* justification and formatting */
uint8_t bmPINLengthFormat; /**< bits 7-5 RFU,
* bit 4 set if system units are bytes, clear if
* system units are bits,
* bits 3-0 PIN length position in system units */
uint8_t bInsertionOffsetOld; /**< Insertion position offset in bytes for
the current PIN */
uint8_t bInsertionOffsetNew; /**< Insertion position offset in bytes for
the new PIN */
uint16_t wPINMaxExtraDigit;
/**< 0xXXYY where XX is minimum PIN size in digits,
and YY is maximum PIN size in digits */
uint8_t bConfirmPIN; /**< Flags governing need for confirmation of new PIN */
uint8_t bEntryValidationCondition; /**< Conditions under which PIN entry should
* be considered complete */
uint8_t bNumberMessage; /**< Number of messages to display for PIN verification*/
uint16_t wLangId; /**< Language for messages */
uint8_t bMsgIndex1; /**< index of 1st prompting message */
uint8_t bMsgIndex2; /**< index of 2d prompting message */
uint8_t bMsgIndex3; /**< index of 3d prompting message */
uint8_t bTeoPrologue[3]; /**< T=1 block prologue field to use (fill with 00) */
uint32_t ulDataLength; /**< length of Data to be sent to the ICC */
uint8_t abData
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
[] /* valid C99 code */
#else
[0] /* non-standard, but usually working code */
#endif
; /**< Data to send to the ICC */
} PIN_MODIFY_STRUCTURE;
/** structure used with \ref FEATURE_IFD_PIN_PROPERTIES */
typedef struct {
uint16_t wLcdLayout; /**< display characteristics */
uint8_t bEntryValidationCondition;
uint8_t bTimeOut2;
} PIN_PROPERTIES_STRUCTURE;
/* restore default structure elements alignment */
#if defined(__APPLE__) | defined(sun)
#pragma pack()
#else
#pragma pack(pop)
#endif
/* properties returned by FEATURE_GET_TLV_PROPERTIES */
#define PCSCv2_PART10_PROPERTY_wLcdLayout 1
#define PCSCv2_PART10_PROPERTY_bEntryValidationCondition 2
#define PCSCv2_PART10_PROPERTY_bTimeOut2 3
#define PCSCv2_PART10_PROPERTY_wLcdMaxCharacters 4
#define PCSCv2_PART10_PROPERTY_wLcdMaxLines 5
#define PCSCv2_PART10_PROPERTY_bMinPINSize 6
#define PCSCv2_PART10_PROPERTY_bMaxPINSize 7
#define PCSCv2_PART10_PROPERTY_sFirmwareID 8
#define PCSCv2_PART10_PROPERTY_bPPDUSupport 9
#define PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize 10
#define PCSCv2_PART10_PROPERTY_wIdVendor 11
#define PCSCv2_PART10_PROPERTY_wIdProduct 12
#endif

2
MacOSX/winscard.h Normal file
View File

@ -0,0 +1,2 @@
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>

1
MacOSX/wintypes.h Normal file
View File

@ -0,0 +1 @@
#include <PCSC/wintypes.h>

27
Makefile.am Normal file
View File

@ -0,0 +1,27 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = readers examples contrib src
EXTRA_DIST = bootstrap ChangeLog SCARDGETATTRIB.txt \
$(AUX_DIST) \
m4/ax_pthread.m4 \
MacOSX/configure \
MacOSX/convert_reader_h.pl \
MacOSX/debuglog.h \
MacOSX/ifdhandler.h \
MacOSX/pcsclite.h \
MacOSX/reader.h \
MacOSX/winscard.h \
MacOSX/wintypes.h
MAINTAINERCLEANFILES = $(AUX_DIST)
DISTCLEANFILES = ChangeLog
# Automatically update the libtool script if it becomes out-of-date.
LIBTOOL_DEPS = @LIBTOOL_DEPS@
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
ChangeLog:
git log --stat --decorate=short > $@

862
Makefile.in Normal file
View File

@ -0,0 +1,862 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
$(am__configure_deps) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
$(LISP)config.h.in
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \
COPYING ChangeLog INSTALL NEWS README ar-lib compile \
config.guess config.sub depcomp install-sh ltmain.sh missing \
ylwrap
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
if test -d "$(distdir)"; then \
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
GZIP_ENV = --best
DIST_ARCHIVES = $(distdir).tar.bz2
DIST_TARGETS = dist-bzip2
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUNDLE_HOST = @BUNDLE_HOST@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
DYN_LIB_EXT = @DYN_LIB_EXT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
# Automatically update the libtool script if it becomes out-of-date.
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
LIBUSB_LIBS = @LIBUSB_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NOCLASS = @NOCLASS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCSC_CFLAGS = @PCSC_CFLAGS@
PCSC_LIBS = @PCSC_LIBS@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SYMBOL_VISIBILITY = @SYMBOL_VISIBILITY@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_aux_dir = @ac_aux_dir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
bindir_exp = @bindir_exp@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
bundle = @bundle@
ccidtwindir = @ccidtwindir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
serialconfdir = @serialconfdir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
sysconfdir_exp = @sysconfdir_exp@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
usbdropdir = @usbdropdir@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = readers examples contrib src
EXTRA_DIST = bootstrap ChangeLog SCARDGETATTRIB.txt \
$(AUX_DIST) \
m4/ax_pthread.m4 \
MacOSX/configure \
MacOSX/convert_reader_h.pl \
MacOSX/debuglog.h \
MacOSX/ifdhandler.h \
MacOSX/pcsclite.h \
MacOSX/reader.h \
MacOSX/winscard.h \
MacOSX/wintypes.h
MAINTAINERCLEANFILES = $(AUX_DIST)
DISTCLEANFILES = ChangeLog
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
am--refresh: Makefile
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
config.h: stamp-h1
@test -f $@ || rm -f stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscope: cscope.files
test ! -s cscope.files \
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
clean-cscope:
-rm -f cscope.files
cscope.files: clean-cscope cscopelist
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__post_remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__post_remove_distdir)
dist-tarZ: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__post_remove_distdir)
dist dist-all:
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
$(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build/sub \
&& ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@test -n '$(distuninstallcheck_dir)' || { \
echo 'ERROR: trying to run $@ with an empty' \
'$$(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
$(am__cd) '$(distuninstallcheck_dir)' || { \
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr \
distclean-libtool distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(am__recursive_targets) all install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--refresh check check-am clean clean-cscope clean-generic \
clean-libtool cscope cscopelist-am ctags ctags-am dist \
dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
dist-xz dist-zip distcheck distclean distclean-generic \
distclean-hdr distclean-libtool distclean-tags distcleancheck \
distdir distuninstallcheck dvi dvi-am html html-am info \
info-am install install-am install-data install-data-am \
install-dvi install-dvi-am install-exec install-exec-am \
install-html install-html-am install-info install-info-am \
install-man install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am
.PRECIOUS: Makefile
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
ChangeLog:
git log --stat --decorate=short > $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

1
NEWS Normal file
View File

@ -0,0 +1 @@
Read the README file for news.

1270
README Normal file

File diff suppressed because it is too large Load Diff

95
SCARDGETATTRIB.txt Normal file
View File

@ -0,0 +1,95 @@
List of SCardGetAttrib() commands supported by the CCID driver
==============================================================
PC/SC provides the SCardGetAttrib() function to request some attributes from
the driver.
PC/SC function prototype
"""""""""""""""""""""""""
LONG SCardGetAttrib(SCARDHANDLE hCard,
DWORD dwAttrId,
LPBYTE pbAttr,
LPDWORD pcbAttrLen);
Parameters:
hCard IN Connection made from SCardConnect
dwAttrId IN Identifier for the attribute to get
pbAttr OUT Pointer to a buffer that receives the attribute
pcbAttrLen IN/OUT Length of the pbAttr buffer in bytes
If the attribute is not supported the applications receive the error
SCARD_E_UNSUPPORTED_FEATURE (or SCARD_E_NOT_TRANSACTED for pcsc-lite
version < 1.3.3)
supported attributes
""""""""""""""""""""
SCARD_ATTR_ATR_STRING
ATR of the card
SCARD_ATTR_ICC_INTERFACE_STATUS
Single byte. Zero if smart card electrical contact is not active;
nonzero if contact is active.
SCARD_ATTR_ICC_PRESENCE
Single byte indicating smart card presence:
0 = not present
1 = card present but not swallowed (applies only if reader supports
smart card swallowing)
2 = card present (and swallowed if reader supports smart card swallowing)
4 = card confiscated.
SCARD_ATTR_VENDOR_IFD_VERSION
Vendor-supplied interface device version
DWORD in the form 0xMMmmbbbb where
MM = major version,
mm = minor version,
and bbbb = build number
It is the bcdDevice USB field.
SCARD_ATTR_VENDOR_NAME
name of the IFD (reader) vendor. It is the iManufacturer USB field
(if any).
SCARD_ATTR_MAXINPUT
maximum size of an APDU supported by the reader.
format is unsigned 32-bit unsing the byte order of the platform.
Correct readers should support up to 261 bytes (CLA + INS + P1 + P2 +
Lc + 255 bytes of data) but some readers support less (253 bytes only
for example). It is a problem for T=1 cards when the reader works in
APDU mode instead of TPDU and for T=0 cards.
SCARD_ATTR_VENDOR_IFD_SERIAL_NO
reader serial number (if available).
Sample code
===========
#include <reader.h>
{
[...]
unsigned char pbAtr[MAX_ATR_SIZE];
DWORD dwAtrLen;
/* use a NULL buffer to just get the needed length */
rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &dwAtrLen);
if (rv == SCARD_S_SUCCESS)
printf("ATR length: %ld\n", dwAtrLen);
dwAtrLen = sizeof(pbAtr);
rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAtr, &dwAtrLen);
if (rv == SCARD_S_SUCCESS)
{
for (i = 0; i < dwAtrLen; i++)
printf("%02X ", pbAtr[i]);
printf("\n");
}
}

1549
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

270
ar-lib Executable file
View File

@ -0,0 +1,270 @@
#! /bin/sh
# Wrapper for Microsoft lib.exe
me=ar-lib
scriptversion=2012-03-01.08; # UTC
# Copyright (C) 2010-2014 Free Software Foundation, Inc.
# Written by Peter Rosin <peda@lysator.liu.se>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
# func_error message
func_error ()
{
echo "$me: $1" 1>&2
exit 1
}
file_conv=
# func_file_conv build_file
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv in
mingw)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin)
file=`cygpath -m "$file" || echo "$file"`
;;
wine)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_at_file at_file operation archive
# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
# for each of them.
# When interpreting the content of the @FILE, do NOT use func_file_conv,
# since the user would need to supply preconverted file names to
# binutils ar, at least for MinGW.
func_at_file ()
{
operation=$2
archive=$3
at_file_contents=`cat "$1"`
eval set x "$at_file_contents"
shift
for member
do
$AR -NOLOGO $operation:"$member" "$archive" || exit $?
done
}
case $1 in
'')
func_error "no command. Try '$0 --help' for more information."
;;
-h | --h*)
cat <<EOF
Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
Members may be specified in a file named with @FILE.
EOF
exit $?
;;
-v | --v*)
echo "$me, version $scriptversion"
exit $?
;;
esac
if test $# -lt 3; then
func_error "you must specify a program, an action and an archive"
fi
AR=$1
shift
while :
do
if test $# -lt 2; then
func_error "you must specify a program, an action and an archive"
fi
case $1 in
-lib | -LIB \
| -ltcg | -LTCG \
| -machine* | -MACHINE* \
| -subsystem* | -SUBSYSTEM* \
| -verbose | -VERBOSE \
| -wx* | -WX* )
AR="$AR $1"
shift
;;
*)
action=$1
shift
break
;;
esac
done
orig_archive=$1
shift
func_file_conv "$orig_archive"
archive=$file
# strip leading dash in $action
action=${action#-}
delete=
extract=
list=
quick=
replace=
index=
create=
while test -n "$action"
do
case $action in
d*) delete=yes ;;
x*) extract=yes ;;
t*) list=yes ;;
q*) quick=yes ;;
r*) replace=yes ;;
s*) index=yes ;;
S*) ;; # the index is always updated implicitly
c*) create=yes ;;
u*) ;; # TODO: don't ignore the update modifier
v*) ;; # TODO: don't ignore the verbose modifier
*)
func_error "unknown action specified"
;;
esac
action=${action#?}
done
case $delete$extract$list$quick$replace,$index in
yes,* | ,yes)
;;
yesyes*)
func_error "more than one action specified"
;;
*)
func_error "no action specified"
;;
esac
if test -n "$delete"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
for member
do
case $1 in
@*)
func_at_file "${1#@}" -REMOVE "$archive"
;;
*)
func_file_conv "$1"
$AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
;;
esac
done
elif test -n "$extract"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
if test $# -gt 0; then
for member
do
case $1 in
@*)
func_at_file "${1#@}" -EXTRACT "$archive"
;;
*)
func_file_conv "$1"
$AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
;;
esac
done
else
$AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
do
$AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
done
fi
elif test -n "$quick$replace"; then
if test ! -f "$orig_archive"; then
if test -z "$create"; then
echo "$me: creating $orig_archive"
fi
orig_archive=
else
orig_archive=$archive
fi
for member
do
case $1 in
@*)
func_file_conv "${1#@}"
set x "$@" "@$file"
;;
*)
func_file_conv "$1"
set x "$@" "$file"
;;
esac
shift
shift
done
if test -n "$orig_archive"; then
$AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
else
$AR -NOLOGO -OUT:"$archive" "$@" || exit $?
fi
elif test -n "$list"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
$AR -NOLOGO -LIST "$archive" || exit $?
fi

16
bootstrap Executable file
View File

@ -0,0 +1,16 @@
#! /bin/bash
set -x
LIBTOOLIZE=libtoolize
# From brew(1) on Mac OS X
# ==> Caveats
# In order to prevent conflicts with Apple's own libtool we have prepended a "g"
# so, you have instead: glibtool and glibtoolize.
which glibtoolize && LIBTOOLIZE=glibtoolize
aclocal -I m4
$LIBTOOLIZE --copy --force --automake
autoheader --force
autoconf --force
automake --add-missing --copy --force --foreign

347
compile Executable file
View File

@ -0,0 +1,347 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

1462
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

144
config.h.in Normal file
View File

@ -0,0 +1,144 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* bundle directory name */
#undef BUNDLE
/* Enable Zero Length Packet patch */
#undef ENABLE_ZLP
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <libusb.h> header file. */
#undef HAVE_LIBUSB_H
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Have PTHREAD_PRIO_INHERIT. */
#undef HAVE_PTHREAD_PRIO_INHERIT
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcat' function. */
#undef HAVE_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the `strncpy' function. */
#undef HAVE_STRNCPY
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Disable logging support */
#undef NO_LOG
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* directory containing USB drivers */
#undef PCSCLITE_HP_DROPDIR
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* composite device are seen as multi-slots */
#undef USE_COMPOSITE_AS_MULTISLOT
/* Use syslog(3) for debug */
#undef USE_SYSLOG
/* Version number of package */
#undef VERSION
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#undef YYTEXT_POINTER
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

1825
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

16470
configure vendored Executable file

File diff suppressed because it is too large Load Diff

338
configure.ac Normal file
View File

@ -0,0 +1,338 @@
# Process this file with autoconf to produce a configure script.
# You may need to use autoconf 2.56 or newer
# Require autoconf 2.61
AC_PREREQ([2.69])
AC_INIT([ccid],[1.4.28])
AC_CONFIG_SRCDIR(src/ifdhandler.c)
AC_CONFIG_AUX_DIR([.])
AM_INIT_AUTOMAKE(1.8 dist-bzip2 no-dist-gzip subdir-objects)
AC_CONFIG_MACRO_DIR([m4])
# silent build by default
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# Default install dir
AC_PREFIX_DEFAULT(/usr/local)
# Automake boilerplate.
AC_CANONICAL_HOST
# create a config.h file (Automake will add -DHAVE_CONFIG_H)
AC_CONFIG_HEADERS([config.h])
# Options
AM_MAINTAINER_MODE
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_LN_S
AM_PROG_LEX
AM_PROG_AR
PKG_PROG_PKG_CONFIG
# check pcsc-lite version
PCSC_NEEDED_VERSION="1.8.3"
PKG_CHECK_EXISTS([libpcsclite],
[PKG_CHECK_MODULES(PCSC, libpcsclite >= $PCSC_NEEDED_VERSION, [],
[
if test -f /usr/local/lib/pkgconfig/libpcsclite.pc -a "x$PKG_CONFIG" != x ; then
AC_MSG_ERROR([use PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure])
else
AC_MSG_WARN([install pcsc-lite $PCSC_NEEDED_VERSION or later])
fi
])],
[AC_MSG_WARN([libpcsclite not found by pkg-config])]
)
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $PCSC_CFLAGS"
PCSC_ERROR_MSG="install pcsc-lite $PCSC_NEEDED_VERSION or later, or use ./configure PCSC_CFLAGS=..."
AC_CHECK_HEADER(ifdhandler.h,, [AC_MSG_ERROR([$PCSC_ERROR_MSG])])
AC_CHECK_HEADER(reader.h,, [AC_MSG_ERROR([$PCSC_ERROR_MSG])])
CPPFLAGS="$saved_CPPFLAGS"
# Add libtool support.
# Static lib is disabled by default. Use --enable-static if needed
LT_INIT(disable-static)
LT_INIT
# Automatically update the libtool script if it becomes out-of-date.
AC_SUBST(LIBTOOL_DEPS)
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(errno.h fcntl.h stdlib.h unistd.h termios.h string.h sys/time.h sys/types.h stdarg.h arpa/inet.h stdio.h,,
[AC_MSG_ERROR([some header files not found])])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
AC_HEADER_TIME
# Checks for library functions.
AC_CHECK_FUNCS(select strerror strncpy memcpy strlcpy strlcat)
# Select OS specific versions of source files.
AC_SUBST(BUNDLE_HOST)
AC_SUBST(DYN_LIB_EXT)
BUNDLE_HOST=`uname | sed -e s,/,_,`
DYN_LIB_EXT="so"
case "$BUNDLE_HOST" in
Darwin)
BUNDLE_HOST=MacOS
DYN_LIB_EXT="dylib"
;;
SunOS)
BUNDLE_HOST=Solaris
;;
esac
# --disable-libusb
AC_ARG_ENABLE(libusb,
AS_HELP_STRING([--disable-libusb],[do not use libusb]),
[ use_libusb="${enableval}" ], [ use_libusb=yes ] )
# check if libusb is used
LIBUSB_NEEDED_VERSION="1.0.9"
if test "x$use_libusb" != xno ; then
PKG_CHECK_EXISTS([libusb-1.0], [
PKG_CHECK_MODULES(LIBUSB, libusb-1.0 >= $LIBUSB_NEEDED_VERSION, [],
[
AC_MSG_WARN([install libusb $LIBUSB_NEEDED_VERSION or later])
PKG_CHECK_MODULES(LIBUSB, libusb-1.0)
])
])
saved_CPPFLAGS="$CPPFLAGS"
saved_LIBS="$LIBS"
CPPFLAGS="$CPPFLAGS $LIBUSB_CFLAGS"
LIBS="$LDFLAGS $LIBUSB_LIBS"
AC_CHECK_HEADERS(libusb.h, [],
[ AC_MSG_ERROR([libusb.h not found, install libusb or use ./configure LIBUSB_CFLAGS=...]) ])
AC_MSG_CHECKING([for libusb_init])
AC_TRY_LINK_FUNC(libusb_init, [ AC_MSG_RESULT([yes]) ],
[ AC_MSG_ERROR([libusb not found, use ./configure LIBUSB_LIBS=...]) ])
CPPFLAGS="$saved_CPPFLAGS"
LIBS="$saved_LIBS"
use_libusb=yes
fi
AC_SUBST(LIBUSB_CFLAGS)
AC_SUBST(LIBUSB_LIBS)
AM_CONDITIONAL(WITH_LIBUSB, test "${use_libusb}" != "no")
# --enable-composite-as-multislot
use_composite_as_multislot=no
AC_ARG_ENABLE(composite-as-multislot,
AS_HELP_STRING([--enable-composite-as-multislot],[composite device are seen as multi-slots]),
[ use_composite_as_multislot="${enableval}" ] )
if test "x$use_composite_as_multislot" = xyes; then
AC_DEFINE(USE_COMPOSITE_AS_MULTISLOT, 1, [composite device are seen as multi-slots])
fi
# check if the compiler support -fvisibility=hidden (GCC >= 4)
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fvisibility=hidden"
AC_MSG_CHECKING([for -fvisibility=hidden])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([char foo;])],
[ AC_MSG_RESULT([yes])
SYMBOL_VISIBILITY="-fvisibility=hidden" ],
AC_MSG_RESULT([no]))
CFLAGS="$saved_CFLAGS"
AC_SUBST(SYMBOL_VISIBILITY)
# --disable-multi-thread
AC_ARG_ENABLE(multi-thread,
AS_HELP_STRING([--disable-multi-thread],[disable multi threading]),
[ multithread="${enableval}" ], [ multithread=yes ] )
if test "${multithread}" != no ; then
AX_PTHREAD(
[ AC_DEFINE(HAVE_PTHREAD, 1,
[Define if you have POSIX threads libraries and header files.])
], [ AC_MSG_ERROR([POSIX thread support required]) ])
multithread=yes
fi
# --enable-bundle=NAME
AC_ARG_ENABLE(bundle,
AS_HELP_STRING([--enable-bundle=NAME],[bundle directory name
(default ifd-ccid.bundle)]),
[bundle="${enableval}"], [bundle=false])
if test "${bundle}" = false ; then
bundle="ifd-ccid.bundle"
fi
AC_DEFINE_UNQUOTED(BUNDLE, "$bundle", [bundle directory name])
# --enable-usbdropdir=DIR
AC_ARG_ENABLE(usbdropdir,
AS_HELP_STRING([--enable-usbdropdir=DIR],[directory containing USB
drivers (default to pcscd config or $(prefix)/pcsc/drivers)]),
[usbdropdir="${enableval}"], [usbdropdir=false])
if test "${usbdropdir}" = false ; then
usbdropdir=`$PKG_CONFIG libpcsclite --variable=usbdropdir`
fi
AC_DEFINE_UNQUOTED(PCSCLITE_HP_DROPDIR, "$usbdropdir", [directory containing USB drivers])
if test "${usbdropdir}" = "" ; then
AC_MSG_ERROR([use --enable-usbdropdir=DIR])
fi
# --enable-twinserial
AC_ARG_ENABLE(twinserial,
AS_HELP_STRING([--enable-twinserial],[also compile and install the serial Twin driver]),
[twinserial="${enableval}"], [twinserial=no])
AM_CONDITIONAL(WITH_TWIN_SERIAL, test "${twinserial}" != "no")
# --enable-ccidtwindir=DIR
AC_ARG_ENABLE(ccidtwindir,
AS_HELP_STRING([--enable-ccidtwindir=DIR],[directory to install the
serial Twin driver (default to pcscd config or $(prefix)/pcsc/drivers/serial)]),
[ccidtwindir="${enableval}"], [ccidtwindir=false])
if test "${ccidtwindir}" = false ; then
ccidtwindir=$usbdropdir/serial
fi
# --enable-serialconfdir=DIR
AC_ARG_ENABLE(serialconfdir,
AS_HELP_STRING([--enable-serialconfdir=dir],[directory containing
serial drivers (default to pcscd config)]),
[serialconfdir="${enableval}"], [serialconfdir=false])
if test "${serialconfdir}" = false ; then
serialconfdir=`$PKG_CONFIG libpcsclite --variable=serialconfdir`
fi
# --disable-pcsclite
AC_ARG_ENABLE(pcsclite,
AS_HELP_STRING([--disable-pcsclite],[do not use pcsc-lite debug support]),
[ pcsclite="${enableval}" ], [ pcsclite=yes ] )
if test "${pcsclite}" != no ; then
# check that pcsc-lite is installed
OLD_LIBS="$LIBS"
OLD_CFLAGS="$CFLAGS"
LIBS="$LIBS $PCSC_LIBS"
CFLAGS="$CFLAGS $PCSC_CFLAGS"
AC_MSG_CHECKING([for SCardEstablishContext])
AC_TRY_LINK_FUNC(SCardEstablishContext,
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_ERROR([SCardEstablishContext() not found, install pcsc-lite, or use PCSC_LIBS=... ./configure]) ])
LIBS="$OLD_LIBS"
CFLAGS="$OLD_CFLAGS"
pcsclite=yes
fi
AM_CONDITIONAL(WITHOUT_PCSC, test "${pcsclite}" != "yes")
# --enable-syslog
AC_ARG_ENABLE(syslog,
AS_HELP_STRING([--enable-syslog],[use syslog instead of printf for debug (Yosemite)]),
[ use_syslog="${enableval}" ], [ use_syslog=no ] )
if test x$use_syslog = xyes; then
AC_DEFINE(USE_SYSLOG, 1, [Use syslog(3) for debug])
fi
# --disable-class
AC_ARG_ENABLE(class,
AS_HELP_STRING([--disable-class],[remove the CCIDCLASSDRIVER from Info.plist]),
[class="${enableval}"], [class=yes])
if test "${class}" != yes ; then
NOCLASS="--no-class"
fi
AC_SUBST(NOCLASS)
# --enable-embedded
AC_ARG_ENABLE(embedded,
AS_HELP_STRING([--enable-embedded],[limit RAM and CPU ressources by disabling features (log)]),
[ use_embedded="${enableval}" ])
if test x$use_embedded = xyes; then
AC_DEFINE(NO_LOG, 1, [Disable logging support])
fi
# --enable-zlp
AC_ARG_ENABLE(zlp,
AS_HELP_STRING([--enable-zlp],[enable the Zero Length Packet patch for some Gemalto readers]),
[ use_zlp="${enableval}" ])
if test x$use_zlp = xyes; then
AC_DEFINE(ENABLE_ZLP, 1, [Enable Zero Length Packet patch])
fi
# Setup dist stuff
AC_SUBST(ac_aux_dir)
AC_SUBST(bundle)
AC_SUBST(usbdropdir)
AC_SUBST(ccidtwindir)
AC_SUBST(serialconfdir)
AS_AC_EXPAND(bindir_exp,$bindir)
AS_AC_EXPAND(sysconfdir_exp,$sysconfdir)
cat << EOF
libccid has been configured with following options:
Version: ${PACKAGE_VERSION}
User binaries: $(eval eval eval echo "${bindir_exp}")
Configuration files: $(eval eval eval echo "${sysconfdir_exp}")
Host: ${host}
Compiler: ${CC}
Preprocessor flags: ${CPPFLAGS}
Compiler flags: ${CFLAGS}
Preprocessor flags: ${CPPFLAGS}
Linker flags: ${LDFLAGS}
Libraries: ${LIBS}
PCSC_CFLAGS: ${PCSC_CFLAGS}
PCSC_LIBS: ${PCSC_LIBS}
PTHREAD_CFLAGS: ${PTHREAD_CFLAGS}
PTHREAD_LIBS: ${PTHREAD_LIBS}
BUNDLE_HOST: ${BUNDLE_HOST}
DYN_LIB_EXT: ${DYN_LIB_EXT}
LIBUSB_CFLAGS: ${LIBUSB_CFLAGS}
LIBUSB_LIBS: ${LIBUSB_LIBS}
SYMBOL_VISIBILITY: ${SYMBOL_VISIBILITY}
NOCLASS: ${NOCLASS}
libusb support: ${use_libusb}
composite as multislot: ${use_composite_as_multislot}
multi threading: ${multithread}
bundle directory name: ${bundle}
USB drop directory: ${usbdropdir}
serial Twin support: ${twinserial}
serial twin install dir: ${ccidtwindir}
serial config directory: ${serialconfdir}
compiled for pcsc-lite: ${pcsclite}
syslog debug: ${use_syslog}
class driver: ${class}
EOF
# Write Makefiles.
AC_CONFIG_FILES(Makefile
src/Makefile
readers/Makefile
contrib/Makefile
contrib/Kobil_mIDentity_switch/Makefile
contrib/RSA_SecurID/Makefile
examples/Makefile)
AC_OUTPUT

View File

@ -0,0 +1,19 @@
.TH Kobil_mIDentity_switch 8 "February 2008"
.SH NAME
Kobil_mIDentity_switch \- activate mIDentity CCID reader
.
.SH SYNOPSIS
.B Kobil_mIDentity_switch
.
.SH DESCRIPTION
Kobil_mIDentity_switch is used to activate the CCID reader of the Kobil
mIDentity device.
.PP
The USB device is by default:
ID 0d46:4081 Kobil Systems GmbH mIDentity Basic/Classic (installationless)
and will be switched to:
ID 0d46:4001 Kobil Systems GmbH mIDentity Basic/Classic (composite device)
.
.SH AUTHORS
Norbert Federa <norbert.federa@neoware.com> wrote the tool.
Ludovic Rousseau <ludovic.rousseau@free.fr> wrote this manpage.

View File

@ -0,0 +1,225 @@
/*
Activate the smartcard interface on the kobil midentity usb device
Copyright (C) 2006 Norbert Federa <norbert.federa@neoware.com>
This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Author: Norbert Federa <norbert.federa@neoware.com>
Date: 2006-04-06
Description:
This tool is needed to activate the smartcard interface on the kobil midentity
usb device (vendor 0x04D6 id 0x4081)
Kobil's own implementation was a kernel usb driver which did just send a
libusb_control_transfer in the probe routine.
We do the same via libusb and call this program from our /sbin/hotblug script
if the mIDentity gets added.
The kobil switcher driver was found inside this zip ...
http://www.kobil.com/download/partner/KOBIL_mIDentity_SDK_Build_20060320_RELEASE.zip
... under Interfaces/Linux/module_with_binary_final.tar.gz.
Here the interesting part of the kernel driver inside the probe function:
if (dev->descriptor.idVendor == KOBIL_VENDOR_ID){
printk("!!!!! DEVICE FOUND !!! !\n");
ret = libusb_control_transfer(dev,
send_pipe,
0x09,
0x22,
0x0200,
0x0001,
switchCmd,
sizeof(switchCmd),
5000);
}
Initally the it did not work with libusb because the ioctl gets ignored with
the used RequestType of 0x22 in combination with index 0x0001, but index 0x0002
worked. See usb/devio.c functions proc_control() -> check_ctrlrecip() ->
findintfep() in order to understand why.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <libusb.h>
#include <errno.h>
#include "config.h"
#define KOBIL_VENDOR_ID 0x0D46
#define MID_DEVICE_ID 0x4081
#define KOBIL_TIMEOUT 5000
#define VAL_STARTUP_4080 1
#define VAL_STARTUP_4000 2
#define VAL_STARTUP_4020 3
#define VAL_STARTUP_40A0 4
#define HIDCMD_SWITCH_DEVICE 0x0004
#define bmRequestType 0x22
#define bRequest 0x09
#define wValue 0x0200
#define wIndex 0x0002 /* this was originally 0x0001 */
static int kobil_midentity_control_msg(libusb_device_handle *usb)
{
int ret;
unsigned char switchCmd[10];
unsigned char Sleep = 1;
unsigned char hardDisk = 1;
unsigned char param = ((hardDisk) << 4) | (Sleep);
memset(switchCmd, 0x0, sizeof(switchCmd));
switchCmd[0] = HIDCMD_SWITCH_DEVICE >> 8;
switchCmd[1] = HIDCMD_SWITCH_DEVICE;
switchCmd[5] = VAL_STARTUP_4000;
switchCmd[9] = param;
ret = libusb_control_transfer(usb, bmRequestType, bRequest, wValue, wIndex,
switchCmd, sizeof(switchCmd), KOBIL_TIMEOUT);
return(!(ret==sizeof(switchCmd)));
}
static int kobil_midentity_claim_interface(libusb_device_handle *usb, int ifnum)
{
int rv;
printf("claiming interface #%d ... ", ifnum);
rv = libusb_claim_interface(usb, ifnum);
if (rv == 0)
{
printf("success\n");
return rv;
}
else
printf("failed\n");
printf("failed with error %d, trying to detach kernel driver ....\n", rv);
rv = libusb_detach_kernel_driver(usb, ifnum);
if (rv == 0)
{
printf("success, claiming interface again ...");
rv = libusb_claim_interface(usb, ifnum);
if (rv == 0)
{
printf("success\n");
return rv;
}
else
printf("failed\n");
}
printf("failed with error %d, giving up.\n", rv);
return rv;
}
int main(int argc, char *argv[])
{
libusb_device **devs, *dev;
libusb_device *found_dev = NULL;
struct libusb_device_handle *usb = NULL;
int rv, i;
ssize_t cnt;
(void)argc;
(void)argv;
rv = libusb_init(NULL);
if (rv < 0)
{
(void)printf("libusb_init() failed\n");
return rv;
}
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0)
{
(void)printf("libusb_get_device_list() failed\n");
return (int)cnt;
}
/* for every device */
i = 0;
while ((dev = devs[i++]) != NULL)
{
struct libusb_device_descriptor desc;
rv = libusb_get_device_descriptor(dev, &desc);
if (rv < 0) {
(void)printf("failed to get device descriptor\n");
continue;
}
printf("vendor/product: %04X %04X\n", desc.idVendor, desc.idProduct);
if (desc.idVendor == KOBIL_VENDOR_ID && desc.idProduct == MID_DEVICE_ID)
found_dev = dev;
}
if (found_dev == NULL)
{
printf("device not found. aborting.\n");
if (0 != geteuid())
printf("Try to rerun this program as root.\n");
exit(1);
}
printf("Device found, opening ... ");
rv = libusb_open(found_dev, &usb);
if (rv < 0)
{
printf("failed, aborting.\n");
exit(2);
}
printf("success\n");
rv = kobil_midentity_claim_interface(usb, 0);
if (rv < 0)
{
libusb_close(usb);
exit(3);
}
rv = kobil_midentity_claim_interface(usb, 1);
if (rv < 0)
{
libusb_close(usb);
exit(3);
}
printf("Activating the CCID configuration .... ");
rv = kobil_midentity_control_msg(usb);
if (rv == 0)
printf("success\n");
else
printf("failed with error %d, giving up.\n", rv);
libusb_close(usb);
return 0;
}

View File

@ -0,0 +1,10 @@
noinst_PROGRAMS = Kobil_mIDentity_switch
Kobil_mIDentity_switch_SOURCES = Kobil_mIDentity_switch.c
Kobil_mIDentity_switch_CFLAGS = $(LIBUSB_CFLAGS)
Kobil_mIDentity_switch_LDADD = $(LIBUSB_LIBS)
noinst_DATA = README_Kobil_mIDentity_switch.txt
noinst_MANS = Kobil_mIDentity_switch.8
EXTRA_DIST = $(noinst_DATA) $(noinst_MANS)

View File

@ -0,0 +1,640 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = Kobil_mIDentity_switch$(EXEEXT)
subdir = contrib/Kobil_mIDentity_switch
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_Kobil_mIDentity_switch_OBJECTS = \
Kobil_mIDentity_switch-Kobil_mIDentity_switch.$(OBJEXT)
Kobil_mIDentity_switch_OBJECTS = $(am_Kobil_mIDentity_switch_OBJECTS)
am__DEPENDENCIES_1 =
Kobil_mIDentity_switch_DEPENDENCIES = $(am__DEPENDENCIES_1)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
Kobil_mIDentity_switch_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(Kobil_mIDentity_switch_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(Kobil_mIDentity_switch_SOURCES)
DIST_SOURCES = $(Kobil_mIDentity_switch_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
DATA = $(noinst_DATA)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUNDLE_HOST = @BUNDLE_HOST@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
DYN_LIB_EXT = @DYN_LIB_EXT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
LIBUSB_LIBS = @LIBUSB_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NOCLASS = @NOCLASS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCSC_CFLAGS = @PCSC_CFLAGS@
PCSC_LIBS = @PCSC_LIBS@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SYMBOL_VISIBILITY = @SYMBOL_VISIBILITY@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_aux_dir = @ac_aux_dir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
bindir_exp = @bindir_exp@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
bundle = @bundle@
ccidtwindir = @ccidtwindir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
serialconfdir = @serialconfdir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
sysconfdir_exp = @sysconfdir_exp@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
usbdropdir = @usbdropdir@
Kobil_mIDentity_switch_SOURCES = Kobil_mIDentity_switch.c
Kobil_mIDentity_switch_CFLAGS = $(LIBUSB_CFLAGS)
Kobil_mIDentity_switch_LDADD = $(LIBUSB_LIBS)
noinst_DATA = README_Kobil_mIDentity_switch.txt
noinst_MANS = Kobil_mIDentity_switch.8
EXTRA_DIST = $(noinst_DATA) $(noinst_MANS)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign contrib/Kobil_mIDentity_switch/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign contrib/Kobil_mIDentity_switch/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
Kobil_mIDentity_switch$(EXEEXT): $(Kobil_mIDentity_switch_OBJECTS) $(Kobil_mIDentity_switch_DEPENDENCIES) $(EXTRA_Kobil_mIDentity_switch_DEPENDENCIES)
@rm -f Kobil_mIDentity_switch$(EXEEXT)
$(AM_V_CCLD)$(Kobil_mIDentity_switch_LINK) $(Kobil_mIDentity_switch_OBJECTS) $(Kobil_mIDentity_switch_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Kobil_mIDentity_switch-Kobil_mIDentity_switch.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
Kobil_mIDentity_switch-Kobil_mIDentity_switch.o: Kobil_mIDentity_switch.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(Kobil_mIDentity_switch_CFLAGS) $(CFLAGS) -MT Kobil_mIDentity_switch-Kobil_mIDentity_switch.o -MD -MP -MF $(DEPDIR)/Kobil_mIDentity_switch-Kobil_mIDentity_switch.Tpo -c -o Kobil_mIDentity_switch-Kobil_mIDentity_switch.o `test -f 'Kobil_mIDentity_switch.c' || echo '$(srcdir)/'`Kobil_mIDentity_switch.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/Kobil_mIDentity_switch-Kobil_mIDentity_switch.Tpo $(DEPDIR)/Kobil_mIDentity_switch-Kobil_mIDentity_switch.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='Kobil_mIDentity_switch.c' object='Kobil_mIDentity_switch-Kobil_mIDentity_switch.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(Kobil_mIDentity_switch_CFLAGS) $(CFLAGS) -c -o Kobil_mIDentity_switch-Kobil_mIDentity_switch.o `test -f 'Kobil_mIDentity_switch.c' || echo '$(srcdir)/'`Kobil_mIDentity_switch.c
Kobil_mIDentity_switch-Kobil_mIDentity_switch.obj: Kobil_mIDentity_switch.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(Kobil_mIDentity_switch_CFLAGS) $(CFLAGS) -MT Kobil_mIDentity_switch-Kobil_mIDentity_switch.obj -MD -MP -MF $(DEPDIR)/Kobil_mIDentity_switch-Kobil_mIDentity_switch.Tpo -c -o Kobil_mIDentity_switch-Kobil_mIDentity_switch.obj `if test -f 'Kobil_mIDentity_switch.c'; then $(CYGPATH_W) 'Kobil_mIDentity_switch.c'; else $(CYGPATH_W) '$(srcdir)/Kobil_mIDentity_switch.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/Kobil_mIDentity_switch-Kobil_mIDentity_switch.Tpo $(DEPDIR)/Kobil_mIDentity_switch-Kobil_mIDentity_switch.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='Kobil_mIDentity_switch.c' object='Kobil_mIDentity_switch-Kobil_mIDentity_switch.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(Kobil_mIDentity_switch_CFLAGS) $(CFLAGS) -c -o Kobil_mIDentity_switch-Kobil_mIDentity_switch.obj `if test -f 'Kobil_mIDentity_switch.c'; then $(CYGPATH_W) 'Kobil_mIDentity_switch.c'; else $(CYGPATH_W) '$(srcdir)/Kobil_mIDentity_switch.c'; fi`
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS) $(DATA)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,250 @@
The Kobil_mIDentity_switch program is used to activate the Kobil mIDenty
smart card CCID reader.
The USB device is by default:
ID 0d46:4081 Kobil Systems GmbH mIDentity Basic/Classic (installationless)
and will be switched to:
ID 0d46:4001 Kobil Systems GmbH mIDentity Basic/Classic (composite device)
Bus 005 Device 016: ID 0d46:4081 Kobil Systems GmbH mIDentity Basic/Classic (installationless)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0d46 Kobil Systems GmbH
idProduct 0x4081 mIDentity Basic/Classic (installationless)
bcdDevice 0.00
iManufacturer 1 KOBIL Systems
iProduct 2 mIDentity M
iSerial 3 SN_K_05C901085
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 57
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 400mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 8 Mass Storage
bInterfaceSubClass 6 SCSI
bInterfaceProtocol 80 Bulk (Zip)
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Devices
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 0 None
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 8
UNRECOGNIZED: 09 21 00 01 00 01 22 22 00
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
bNumConfigurations 1
Device Status: 0x0002
(Bus Powered)
Remote Wakeup Enabled
Bus 005 Device 015: ID 0d46:4001 Kobil Systems GmbH mIDentity Basic/Classic (composite device)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0d46 Kobil Systems GmbH
idProduct 0x4001 mIDentity Basic/Classic (composite device)
bcdDevice 0.00
iManufacturer 1 KOBIL Systems
iProduct 2 mIDentity M
iSerial 3 SN_K_05C901085
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 134
bNumInterfaces 3
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 400mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 8 Mass Storage
bInterfaceSubClass 6 SCSI
bInterfaceProtocol 80 Bulk (Zip)
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 11 Chip/SmartCard
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
ChipCard Interface Descriptor:
bLength 54
bDescriptorType 33
bcdCCID 1.00
nMaxSlotIndex 0
bVoltageSupport 7 5.0V 3.0V 1.8V
dwProtocols 3 T=0 T=1
dwDefaultClock 4000
dwMaxiumumClock 4000
bNumClockSupported 0
dwDataRate 10752 bps
dwMaxDataRate 250000 bps
bNumDataRatesSupp. 0
dwMaxIFSD 254
dwSyncProtocols 00000000
dwMechanical 00000000
dwFeatures 000206BA
Auto configuration based on ATR
Auto voltage selection
Auto clock change
Auto baud rate change
Auto PPS made by CCID
NAD value other than 0x00 accpeted
Auto IFSD exchange
Short APDU level exchange
dwMaxCCIDMsgLen 271
bClassGetResponse echo
bClassEnvelope echo
wlcdLayout none
bPINSupport 0
bMaxCCIDBusySlots 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x88 EP 8 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Devices
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 0 None
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 10
UNRECOGNIZED: 09 21 00 01 00 01 22 22 00
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
bNumConfigurations 1
Device Status: 0x0002
(Bus Powered)
Remote Wakeup Enabled

5
contrib/Makefile.am Normal file
View File

@ -0,0 +1,5 @@
if WITH_LIBUSB
SUBDIRS = Kobil_mIDentity_switch RSA_SecurID
else
SUBDIRS = RSA_SecurID
endif

645
contrib/Makefile.in Normal file
View File

@ -0,0 +1,645 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = contrib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
distdir
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = RSA_SecurID Kobil_mIDentity_switch
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUNDLE_HOST = @BUNDLE_HOST@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
DYN_LIB_EXT = @DYN_LIB_EXT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
LIBUSB_LIBS = @LIBUSB_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NOCLASS = @NOCLASS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCSC_CFLAGS = @PCSC_CFLAGS@
PCSC_LIBS = @PCSC_LIBS@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SYMBOL_VISIBILITY = @SYMBOL_VISIBILITY@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_aux_dir = @ac_aux_dir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
bindir_exp = @bindir_exp@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
bundle = @bundle@
ccidtwindir = @ccidtwindir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
serialconfdir = @serialconfdir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
sysconfdir_exp = @sysconfdir_exp@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
usbdropdir = @usbdropdir@
@WITH_LIBUSB_FALSE@SUBDIRS = RSA_SecurID
@WITH_LIBUSB_TRUE@SUBDIRS = Kobil_mIDentity_switch RSA_SecurID
all: all-recursive
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign contrib/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign contrib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(am__recursive_targets) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
check-am clean clean-generic clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,9 @@
noinst_PROGRAMS = RSA_SecurID_getpasswd
RSA_SecurID_getpasswd_SOURCES = RSA_SecurID_getpasswd.c
RSA_SecurID_getpasswd_CFLAGS = $(PCSC_CFLAGS)
RSA_SecurID_getpasswd_LDADD = $(PCSC_LIBS)
noinst_MANS = RSA_SecurID_getpasswd.1
EXTRA_DIST = $(noinst_MANS)

View File

@ -0,0 +1,637 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = RSA_SecurID_getpasswd$(EXEEXT)
subdir = contrib/RSA_SecurID
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_RSA_SecurID_getpasswd_OBJECTS = \
RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.$(OBJEXT)
RSA_SecurID_getpasswd_OBJECTS = $(am_RSA_SecurID_getpasswd_OBJECTS)
am__DEPENDENCIES_1 =
RSA_SecurID_getpasswd_DEPENDENCIES = $(am__DEPENDENCIES_1)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
RSA_SecurID_getpasswd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(RSA_SecurID_getpasswd_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(RSA_SecurID_getpasswd_SOURCES)
DIST_SOURCES = $(RSA_SecurID_getpasswd_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUNDLE_HOST = @BUNDLE_HOST@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
DYN_LIB_EXT = @DYN_LIB_EXT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
LIBUSB_LIBS = @LIBUSB_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NOCLASS = @NOCLASS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCSC_CFLAGS = @PCSC_CFLAGS@
PCSC_LIBS = @PCSC_LIBS@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SYMBOL_VISIBILITY = @SYMBOL_VISIBILITY@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_aux_dir = @ac_aux_dir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
bindir_exp = @bindir_exp@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
bundle = @bundle@
ccidtwindir = @ccidtwindir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
serialconfdir = @serialconfdir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
sysconfdir_exp = @sysconfdir_exp@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
usbdropdir = @usbdropdir@
RSA_SecurID_getpasswd_SOURCES = RSA_SecurID_getpasswd.c
RSA_SecurID_getpasswd_CFLAGS = $(PCSC_CFLAGS)
RSA_SecurID_getpasswd_LDADD = $(PCSC_LIBS)
noinst_MANS = RSA_SecurID_getpasswd.1
EXTRA_DIST = $(noinst_MANS)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign contrib/RSA_SecurID/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign contrib/RSA_SecurID/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
RSA_SecurID_getpasswd$(EXEEXT): $(RSA_SecurID_getpasswd_OBJECTS) $(RSA_SecurID_getpasswd_DEPENDENCIES) $(EXTRA_RSA_SecurID_getpasswd_DEPENDENCIES)
@rm -f RSA_SecurID_getpasswd$(EXEEXT)
$(AM_V_CCLD)$(RSA_SecurID_getpasswd_LINK) $(RSA_SecurID_getpasswd_OBJECTS) $(RSA_SecurID_getpasswd_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.o: RSA_SecurID_getpasswd.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(RSA_SecurID_getpasswd_CFLAGS) $(CFLAGS) -MT RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.o -MD -MP -MF $(DEPDIR)/RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.Tpo -c -o RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.o `test -f 'RSA_SecurID_getpasswd.c' || echo '$(srcdir)/'`RSA_SecurID_getpasswd.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.Tpo $(DEPDIR)/RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='RSA_SecurID_getpasswd.c' object='RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(RSA_SecurID_getpasswd_CFLAGS) $(CFLAGS) -c -o RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.o `test -f 'RSA_SecurID_getpasswd.c' || echo '$(srcdir)/'`RSA_SecurID_getpasswd.c
RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.obj: RSA_SecurID_getpasswd.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(RSA_SecurID_getpasswd_CFLAGS) $(CFLAGS) -MT RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.obj -MD -MP -MF $(DEPDIR)/RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.Tpo -c -o RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.obj `if test -f 'RSA_SecurID_getpasswd.c'; then $(CYGPATH_W) 'RSA_SecurID_getpasswd.c'; else $(CYGPATH_W) '$(srcdir)/RSA_SecurID_getpasswd.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.Tpo $(DEPDIR)/RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='RSA_SecurID_getpasswd.c' object='RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(RSA_SecurID_getpasswd_CFLAGS) $(CFLAGS) -c -o RSA_SecurID_getpasswd-RSA_SecurID_getpasswd.obj `if test -f 'RSA_SecurID_getpasswd.c'; then $(CYGPATH_W) 'RSA_SecurID_getpasswd.c'; else $(CYGPATH_W) '$(srcdir)/RSA_SecurID_getpasswd.c'; fi`
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,14 @@
.TH RSA_SecurID_getpasswd 1 "February 2008"
.SH NAME
RSA_SecurID_getpasswd \- get the one-use password from a RSA sid-800
token
.
.SH SYNOPSIS
.B RSA_SecurID_getpasswd
.
.SH DESCRIPTION
RSA_SecurID_getpasswd sends to stdout the one-use password also
displayed on the screen of a RSA sid-800 USB token.
.
.SH AUTHOR
Ludovic Rousseau <ludovic.rousseau@free.fr>

View File

@ -0,0 +1,172 @@
/*
RSA_SecurID_getpasswd.c: get the one-use password from a RSA sid-800 token
Copyright (C) 2006 Ludovic Rousseau <ludovic.rousseau@free.fr>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc., 51
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winscard.h>
/* DWORD printf(3) format */
#ifdef __APPLE__
/* Apple defines DWORD as uint32_t so %d is correct */
#define LF
#else
/* pcsc-lite defines DWORD as unsigned long so %ld is correct */
#define LF "l"
#endif
/* PCSC error message pretty print */
#define PCSC_ERROR_EXIT(rv, text) \
if (rv != SCARD_S_SUCCESS) \
{ \
printf(text ": %s (0x%"LF"X)\n", pcsc_stringify_error(rv), rv); \
goto end; \
}
int main(void)
{
unsigned char cmd1[] = { 0x00, 0xa4, 0x04, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x63, 0x86, 0x53, 0x49, 0x44, 0x01};
unsigned char cmd2[] = { 0x80, 0x56, 0x00, 0x00, 0x04 };
unsigned char cmd3[] = { 0x80, 0x48, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff };
unsigned char cmd4[] = { 0x80, 0x44, 0x00, 0x00, 0x05};
LONG rv;
SCARDCONTEXT hContext;
DWORD dwReaders;
LPSTR mszReaders = NULL;
char **readers = NULL;
SCARDHANDLE hCard;
DWORD dwActiveProtocol;
unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
DWORD length;
SCARD_IO_REQUEST pioRecvPci;
SCARD_IO_REQUEST pioSendPci;
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
if (rv != SCARD_S_SUCCESS)
{
printf("SCardEstablishContext: Cannot Connect to Resource Manager %"LF"X\n", rv);
return 1;
}
/* Retrieve the available readers list */
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
PCSC_ERROR_EXIT(rv, "SCardListReader");
if (dwReaders < 4)
{
printf("No reader found!\n");
return -1;
}
mszReaders = malloc(sizeof(char)*dwReaders);
if (mszReaders == NULL)
{
printf("malloc: not enough memory\n");
goto end;
}
rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
PCSC_ERROR_EXIT(rv, "SCardListReader");
/* connect to the first reader */
dwActiveProtocol = -1;
rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_EXCLUSIVE,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
PCSC_ERROR_EXIT(rv, "SCardConnect")
switch(dwActiveProtocol)
{
case SCARD_PROTOCOL_T0:
pioSendPci = *SCARD_PCI_T0;
break;
case SCARD_PROTOCOL_T1:
pioSendPci = *SCARD_PCI_T1;
break;
default:
printf("Unknown protocol\n");
return -1;
}
/* APDU select applet */
length = sizeof(bRecvBuffer);
rv = SCardTransmit(hCard, &pioSendPci, cmd1, sizeof cmd1,
&pioRecvPci, bRecvBuffer, &length);
PCSC_ERROR_EXIT(rv, "SCardTransmit")
if ((length != 2) || (bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00))
{
printf("cmd1 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
bRecvBuffer[length-1]);
goto end;
}
/* non ISO APDU */
length = sizeof(bRecvBuffer);
rv = SCardTransmit(hCard, &pioSendPci, cmd2, sizeof cmd2,
&pioRecvPci, bRecvBuffer, &length);
PCSC_ERROR_EXIT(rv, "SCardTransmit")
if ((length != 6) || (bRecvBuffer[4] != 0x90) || (bRecvBuffer[5] != 0x00))
{
printf("cmd2 failed (%"LF"d) : %02X%02X\n", length,
bRecvBuffer[length-2], bRecvBuffer[length-1]);
goto end;
}
/* get the argument for cmd3 from result of cmd2 */
memcpy(cmd3+5, bRecvBuffer, 4);
/* non ISO APDU */
length = sizeof(bRecvBuffer);
rv = SCardTransmit(hCard, &pioSendPci, cmd3, sizeof cmd3,
&pioRecvPci, bRecvBuffer, &length);
PCSC_ERROR_EXIT(rv, "SCardTransmit")
if ((length != 2) || (bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00))
{
printf("cmd3 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
bRecvBuffer[length-1]);
goto end;
}
/* non iSO APDU */
length = sizeof(bRecvBuffer);
rv = SCardTransmit(hCard, &pioSendPci, cmd4, sizeof cmd4,
&pioRecvPci, bRecvBuffer, &length);
PCSC_ERROR_EXIT(rv, "SCardTransmit")
if ((length != 7) || (bRecvBuffer[5] != 0x90) || (bRecvBuffer[6] != 0x00))
{
printf("cmd4 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
bRecvBuffer[length-1]);
goto end;
}
printf("%02X%02X%02X\n", bRecvBuffer[2], bRecvBuffer[3], bRecvBuffer[4]);
end:
/* We try to leave things as clean as possible */
rv = SCardReleaseContext(hContext);
if (rv != SCARD_S_SUCCESS)
printf("SCardReleaseContext: %s (0x%"LF"X)\n", pcsc_stringify_error(rv),
rv);
/* free allocated memory */
free(mszReaders);
free(readers);
return 0;
} /* main */

791
depcomp Executable file
View File

@ -0,0 +1,791 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2013-05-30.07; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

339
examples/GPL-2 Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

8
examples/Makefile.am Normal file
View File

@ -0,0 +1,8 @@
# Process this file with automake to create Makefile.in.
noinst_PROGRAMS = scardcontrol
scardcontrol_SOURCES = scardcontrol.c PCSCv2part10.c PCSCv2part10.h
scardcontrol_CFLAGS = $(PCSC_CFLAGS) $(PTHREAD_CFLAGS)
scardcontrol_LDADD = $(PCSC_LIBS) $(PTHREAD_LIBS)
EXTRA_DIST = GPL-2

653
examples/Makefile.in Normal file
View File

@ -0,0 +1,653 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# Process this file with automake to create Makefile.in.
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = scardcontrol$(EXEEXT)
subdir = examples
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_scardcontrol_OBJECTS = scardcontrol-scardcontrol.$(OBJEXT) \
scardcontrol-PCSCv2part10.$(OBJEXT)
scardcontrol_OBJECTS = $(am_scardcontrol_OBJECTS)
am__DEPENDENCIES_1 =
scardcontrol_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
scardcontrol_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(scardcontrol_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(scardcontrol_SOURCES)
DIST_SOURCES = $(scardcontrol_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUNDLE_HOST = @BUNDLE_HOST@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
DYN_LIB_EXT = @DYN_LIB_EXT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
LIBUSB_LIBS = @LIBUSB_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NOCLASS = @NOCLASS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCSC_CFLAGS = @PCSC_CFLAGS@
PCSC_LIBS = @PCSC_LIBS@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SYMBOL_VISIBILITY = @SYMBOL_VISIBILITY@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_aux_dir = @ac_aux_dir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
bindir_exp = @bindir_exp@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
bundle = @bundle@
ccidtwindir = @ccidtwindir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
serialconfdir = @serialconfdir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
sysconfdir_exp = @sysconfdir_exp@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
usbdropdir = @usbdropdir@
scardcontrol_SOURCES = scardcontrol.c PCSCv2part10.c PCSCv2part10.h
scardcontrol_CFLAGS = $(PCSC_CFLAGS) $(PTHREAD_CFLAGS)
scardcontrol_LDADD = $(PCSC_LIBS) $(PTHREAD_LIBS)
EXTRA_DIST = GPL-2
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign examples/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
scardcontrol$(EXEEXT): $(scardcontrol_OBJECTS) $(scardcontrol_DEPENDENCIES) $(EXTRA_scardcontrol_DEPENDENCIES)
@rm -f scardcontrol$(EXEEXT)
$(AM_V_CCLD)$(scardcontrol_LINK) $(scardcontrol_OBJECTS) $(scardcontrol_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scardcontrol-PCSCv2part10.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scardcontrol-scardcontrol.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
scardcontrol-scardcontrol.o: scardcontrol.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(scardcontrol_CFLAGS) $(CFLAGS) -MT scardcontrol-scardcontrol.o -MD -MP -MF $(DEPDIR)/scardcontrol-scardcontrol.Tpo -c -o scardcontrol-scardcontrol.o `test -f 'scardcontrol.c' || echo '$(srcdir)/'`scardcontrol.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/scardcontrol-scardcontrol.Tpo $(DEPDIR)/scardcontrol-scardcontrol.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scardcontrol.c' object='scardcontrol-scardcontrol.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(scardcontrol_CFLAGS) $(CFLAGS) -c -o scardcontrol-scardcontrol.o `test -f 'scardcontrol.c' || echo '$(srcdir)/'`scardcontrol.c
scardcontrol-scardcontrol.obj: scardcontrol.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(scardcontrol_CFLAGS) $(CFLAGS) -MT scardcontrol-scardcontrol.obj -MD -MP -MF $(DEPDIR)/scardcontrol-scardcontrol.Tpo -c -o scardcontrol-scardcontrol.obj `if test -f 'scardcontrol.c'; then $(CYGPATH_W) 'scardcontrol.c'; else $(CYGPATH_W) '$(srcdir)/scardcontrol.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/scardcontrol-scardcontrol.Tpo $(DEPDIR)/scardcontrol-scardcontrol.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scardcontrol.c' object='scardcontrol-scardcontrol.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(scardcontrol_CFLAGS) $(CFLAGS) -c -o scardcontrol-scardcontrol.obj `if test -f 'scardcontrol.c'; then $(CYGPATH_W) 'scardcontrol.c'; else $(CYGPATH_W) '$(srcdir)/scardcontrol.c'; fi`
scardcontrol-PCSCv2part10.o: PCSCv2part10.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(scardcontrol_CFLAGS) $(CFLAGS) -MT scardcontrol-PCSCv2part10.o -MD -MP -MF $(DEPDIR)/scardcontrol-PCSCv2part10.Tpo -c -o scardcontrol-PCSCv2part10.o `test -f 'PCSCv2part10.c' || echo '$(srcdir)/'`PCSCv2part10.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/scardcontrol-PCSCv2part10.Tpo $(DEPDIR)/scardcontrol-PCSCv2part10.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='PCSCv2part10.c' object='scardcontrol-PCSCv2part10.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(scardcontrol_CFLAGS) $(CFLAGS) -c -o scardcontrol-PCSCv2part10.o `test -f 'PCSCv2part10.c' || echo '$(srcdir)/'`PCSCv2part10.c
scardcontrol-PCSCv2part10.obj: PCSCv2part10.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(scardcontrol_CFLAGS) $(CFLAGS) -MT scardcontrol-PCSCv2part10.obj -MD -MP -MF $(DEPDIR)/scardcontrol-PCSCv2part10.Tpo -c -o scardcontrol-PCSCv2part10.obj `if test -f 'PCSCv2part10.c'; then $(CYGPATH_W) 'PCSCv2part10.c'; else $(CYGPATH_W) '$(srcdir)/PCSCv2part10.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/scardcontrol-PCSCv2part10.Tpo $(DEPDIR)/scardcontrol-PCSCv2part10.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='PCSCv2part10.c' object='scardcontrol-PCSCv2part10.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(scardcontrol_CFLAGS) $(CFLAGS) -c -o scardcontrol-PCSCv2part10.obj `if test -f 'PCSCv2part10.c'; then $(CYGPATH_W) 'PCSCv2part10.c'; else $(CYGPATH_W) '$(srcdir)/PCSCv2part10.c'; fi`
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

123
examples/PCSCv2part10.c Normal file
View File

@ -0,0 +1,123 @@
/*
PCSCv2part10.c: helper functions for PC/SC v2 part 10 services
Copyright (C) 2012 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <arpa/inet.h>
#ifdef __APPLE__
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#else
#include <winscard.h>
#endif
#include "PCSCv2part10.h"
int PCSCv2Part10_find_TLV_property_by_tag_from_buffer(
unsigned char *buffer, int length, int property, int * value_int)
{
unsigned char *p;
int found = 0, len;
int value = -1;
int ret = -1; /* not found by default */
p = buffer;
while (p-buffer < length)
{
if (*p++ == property)
{
found = 1;
break;
}
/* go to next tag */
len = *p++;
p += len;
}
if (found)
{
len = *p++;
ret = 0;
switch(len)
{
case 1:
value = *p;
break;
case 2:
value = *p + (*(p+1)<<8);
break;
case 4:
value = *p + (*(p+1)<<8) + (*(p+2)<<16) + (*(p+3)<<24);
break;
default:
/* wrong length for an integer */
ret = -2;
}
}
if (value_int)
*value_int = value;
return ret;
} /* PCSCv2Part10_find_TLV_property_by_tag_from_buffer */
int PCSCv2Part10_find_TLV_property_by_tag_from_hcard(SCARDHANDLE hCard,
int property, int * value)
{
unsigned char buffer[MAX_BUFFER_SIZE];
LONG rv;
DWORD length;
unsigned int i;
PCSC_TLV_STRUCTURE *pcsc_tlv;
DWORD properties_in_tlv_ioctl;
int found;
rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
buffer, sizeof buffer, &length);
if (rv != SCARD_S_SUCCESS)
return -1;
/* get the number of elements instead of the complete size */
length /= sizeof(PCSC_TLV_STRUCTURE);
pcsc_tlv = (PCSC_TLV_STRUCTURE *)buffer;
found = 0;
for (i = 0; i < length; i++)
{
if (FEATURE_GET_TLV_PROPERTIES == pcsc_tlv[i].tag)
{
properties_in_tlv_ioctl = ntohl(pcsc_tlv[i].value);
found = 1;
}
}
if (! found)
return -3;
rv= SCardControl(hCard, properties_in_tlv_ioctl, NULL, 0,
buffer, sizeof buffer, &length);
if (rv != SCARD_S_SUCCESS)
return -1;
return PCSCv2Part10_find_TLV_property_by_tag_from_buffer(buffer,
length, property, value);
}

136
examples/PCSCv2part10.h Normal file
View File

@ -0,0 +1,136 @@
/*
PCSCv2part10.h: helper functions for PC/SC v2 part 10 services
Copyright (C) 2012 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __reader_h__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_READER_H
#include <reader.h>
#else
/**
* Provide source compatibility on different platforms
*/
#define SCARD_CTL_CODE(code) (0x42000000 + (code))
/**
* PC/SC part 10 v2.02.07 March 2010 reader tags
*/
#define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
#define FEATURE_GET_TLV_PROPERTIES 0x12 /**< Get TLV properties */
#include <inttypes.h>
/* Set structure elements aligment on bytes
* http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html */
#if defined(__APPLE__) | defined(sun)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
/** the structure must be 6-bytes long */
typedef struct
{
uint8_t tag; /**< Tag */
uint8_t length; /**< Length */
uint32_t value; /**< This value is always in BIG ENDIAN format as documented in PCSC v2 part 10 ch 2.2 page 2. You can use ntohl() for example */
} PCSC_TLV_STRUCTURE;
/* restore default structure elements alignment */
#if defined(__APPLE__) | defined(sun)
#pragma pack()
#else
#pragma pack(pop)
#endif
/* properties returned by FEATURE_GET_TLV_PROPERTIES */
#define PCSCv2_PART10_PROPERTY_wLcdLayout 1 /**< wLcdLayout */
#define PCSCv2_PART10_PROPERTY_bEntryValidationCondition 2 /**< bEntryValidationCondition */
#define PCSCv2_PART10_PROPERTY_bTimeOut2 3 /**< bTimeOut2 */
#define PCSCv2_PART10_PROPERTY_wLcdMaxCharacters 4 /**< wLcdMaxCharacters */
#define PCSCv2_PART10_PROPERTY_wLcdMaxLines 5 /**< wLcdMaxLines */
#define PCSCv2_PART10_PROPERTY_bMinPINSize 6 /**< bMinPINSize */
#define PCSCv2_PART10_PROPERTY_bMaxPINSize 7 /**< bMaxPINSize */
#define PCSCv2_PART10_PROPERTY_sFirmwareID 8 /**< sFirmwareID */
#define PCSCv2_PART10_PROPERTY_bPPDUSupport 9 /**< bPPDUSupport */
#define PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize 10 /**< dwMaxAPDUDataSize */
#define PCSCv2_PART10_PROPERTY_wIdVendor 11 /**< wIdVendor */
#define PCSCv2_PART10_PROPERTY_wIdProduct 12 /**< wIdProduct */
#endif
#endif
/**
* @file
* @defgroup API API
*
* The available PC/SC v2 part 10 tags are (from pcsc-lite 1.8.5):
*
* - \ref PCSCv2_PART10_PROPERTY_wLcdLayout
* - \ref PCSCv2_PART10_PROPERTY_bEntryValidationCondition
* - \ref PCSCv2_PART10_PROPERTY_bTimeOut2
* - \ref PCSCv2_PART10_PROPERTY_wLcdMaxCharacters
* - \ref PCSCv2_PART10_PROPERTY_wLcdMaxLines
* - \ref PCSCv2_PART10_PROPERTY_bMinPINSize
* - \ref PCSCv2_PART10_PROPERTY_bMaxPINSize
* - \ref PCSCv2_PART10_PROPERTY_sFirmwareID
* - \ref PCSCv2_PART10_PROPERTY_bPPDUSupport
* - \ref PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize
* - \ref PCSCv2_PART10_PROPERTY_wIdVendor
* - \ref PCSCv2_PART10_PROPERTY_wIdProduct
*
* Example of code:
* @include sample.c
*/
/**
* @brief Find an integer value by tag from TLV buffer
* @ingroup API
*
* @param buffer buffer received from FEATURE_GET_TLV_PROPERTIES
* @param length buffer length
* @param property tag searched
* @param[out] value value found
* @return Error code
*
* @retval 0 success
* @retval -1 not found
* @retval -2 invalid length in the TLV
*
*/
int PCSCv2Part10_find_TLV_property_by_tag_from_buffer(
unsigned char *buffer, int length, int property, int * value);
/**
* @brief Find a integer value by tag from a PC/SC card handle
* @ingroup API
*
* @param hCard card handle as returned by SCardConnect()
* @param property tag searched
* @param[out] value value found
* @return Error code (see PCSCv2Part10_find_TLV_property_by_tag_from_buffer())
*/
int PCSCv2Part10_find_TLV_property_by_tag_from_hcard(SCARDHANDLE hCard,
int property, int * value);

896
examples/scardcontrol.c Normal file
View File

@ -0,0 +1,896 @@
/*
scardcontrol.c: sample code to use/test SCardControl() API
Copyright (C) 2004-2011 Ludovic Rousseau
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc., 51
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#ifdef __APPLE__
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#else
#include <winscard.h>
#endif
#include <reader.h>
#include "PCSCv2part10.h"
#define VERIFY_PIN
#undef MODIFY_PIN
#undef GET_GEMPC_FIRMWARE
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE SCARD_CTL_CODE(1)
#define BLUE "\33[34m"
#define RED "\33[31m"
#define BRIGHT_RED "\33[01;31m"
#define GREEN "\33[32m"
#define NORMAL "\33[0m"
#define MAGENTA "\33[35m"
/* DWORD printf(3) format */
#ifdef __APPLE__
/* Apple defines DWORD as uint32_t so %d is correct */
#define LF
#else
/* pcsc-lite defines DWORD as unsigned long so %ld is correct */
#define LF "l"
#endif
/* PCSC error message pretty print */
#define PCSC_ERROR_EXIT(rv, text) \
if (rv != SCARD_S_SUCCESS) \
{ \
printf(text ": " RED "%s (0x%"LF"X)\n" NORMAL, pcsc_stringify_error(rv), rv); \
goto end; \
} \
else \
printf(text ": " BLUE "OK\n\n" NORMAL);
#define PCSC_ERROR_CONT(rv, text) \
if (rv != SCARD_S_SUCCESS) \
printf(text ": " BLUE "%s (0x%"LF"X)\n" NORMAL, pcsc_stringify_error(rv), rv); \
else \
printf(text ": " BLUE "OK\n\n" NORMAL);
#define PRINT_GREEN(text, value) \
printf("%s: " GREEN "%s\n" NORMAL, text, value)
#define PRINT_GREEN_DEC(text, value) \
printf("%s: " GREEN "%d\n" NORMAL, text, value)
#define PRINT_RED_DEC(text, value) \
printf("%s: " RED "%d\n" NORMAL, text, value)
#define PRINT_GREEN_HEX2(text, value) \
printf("%s: " GREEN "0x%02X\n" NORMAL, text, value)
#define PRINT_GREEN_HEX4(text, value) \
printf("%s: " GREEN "0x%04X\n" NORMAL, text, value)
static void parse_properties(unsigned char *bRecvBuffer, int length)
{
unsigned char *p;
int i;
p = bRecvBuffer;
while (p-bRecvBuffer < length)
{
int tag, len, value;
tag = *p++;
len = *p++;
switch(len)
{
case 1:
value = *p;
break;
case 2:
value = *p + (*(p+1)<<8);
break;
case 4:
value = *p + (*(p+1)<<8) + (*(p+2)<<16) + (*(p+3)<<24);
break;
default:
value = -1;
}
switch(tag)
{
case PCSCv2_PART10_PROPERTY_wLcdLayout:
PRINT_GREEN_HEX4(" wLcdLayout", value);
break;
case PCSCv2_PART10_PROPERTY_bEntryValidationCondition:
PRINT_GREEN_HEX2(" bEntryValidationCondition", value);
break;
case PCSCv2_PART10_PROPERTY_bTimeOut2:
PRINT_GREEN_HEX2(" bTimeOut2", value);
break;
case PCSCv2_PART10_PROPERTY_wLcdMaxCharacters:
PRINT_GREEN_HEX4(" wLcdMaxCharacters", value);
break;
case PCSCv2_PART10_PROPERTY_wLcdMaxLines:
PRINT_GREEN_HEX4(" wLcdMaxLines", value);
break;
case PCSCv2_PART10_PROPERTY_bMinPINSize:
PRINT_GREEN_HEX2(" bMinPINSize", value);
break;
case PCSCv2_PART10_PROPERTY_bMaxPINSize:
PRINT_GREEN_HEX2(" bMaxPINSize", value);
break;
case PCSCv2_PART10_PROPERTY_sFirmwareID:
printf(" sFirmwareID: " GREEN);
for (i=0; i<len; i++)
putchar(p[i]);
printf(NORMAL "\n");
break;
case PCSCv2_PART10_PROPERTY_bPPDUSupport:
PRINT_GREEN_HEX2(" bPPDUSupport", value);
if (value & 1)
printf(" PPDU is supported over SCardControl using FEATURE_CCID_ESC_COMMAND\n");
if (value & 2)
printf(" PPDU is supported over SCardTransmit\n");
break;
case PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize:
PRINT_GREEN_DEC(" dwMaxAPDUDataSize", value);
break;
case PCSCv2_PART10_PROPERTY_wIdVendor:
PRINT_GREEN_HEX2(" wIdVendor", value);
break;
case PCSCv2_PART10_PROPERTY_wIdProduct:
PRINT_GREEN_HEX2(" wIdProduct", value);
break;
default:
printf(" Unknown tag: 0x%02X (length = %d)\n", tag, len);
}
p += len;
}
} /* parse_properties */
static const char *pinpad_return_codes(unsigned char bRecvBuffer[])
{
const char * ret = "UNKNOWN";
if ((0x90 == bRecvBuffer[0]) && (0x00 == bRecvBuffer[1]))
ret = "Success";
if (0x64 == bRecvBuffer[0])
{
switch (bRecvBuffer[1])
{
case 0x00:
ret = "Timeout";
break;
case 0x01:
ret = "Cancelled by user";
break;
case 0x02:
ret = "PIN mismatch";
break;
case 0x03:
ret = "Too short or too long PIN";
break;
}
}
return ret;
}
int main(int argc, char *argv[])
{
LONG rv;
SCARDCONTEXT hContext;
DWORD dwReaders;
LPSTR mszReaders = NULL;
char *ptr, **readers = NULL;
int nbReaders;
SCARDHANDLE hCard;
DWORD dwActiveProtocol, dwReaderLen, dwState, dwProt, dwAtrLen;
BYTE pbAtr[MAX_ATR_SIZE] = "";
char pbReader[MAX_READERNAME] = "";
int reader_nb;
unsigned int i;
unsigned char bSendBuffer[MAX_BUFFER_SIZE];
unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
DWORD send_length, length;
DWORD verify_ioctl = 0;
DWORD modify_ioctl = 0;
DWORD pin_properties_ioctl = 0;
DWORD mct_readerdirect_ioctl = 0;
DWORD properties_in_tlv_ioctl = 0;
DWORD ccid_esc_command = 0;
SCARD_IO_REQUEST pioRecvPci;
SCARD_IO_REQUEST pioSendPci;
PCSC_TLV_STRUCTURE *pcsc_tlv;
#if defined(VERIFY_PIN) | defined(MODIFY_PIN)
int offset;
#endif
#ifdef VERIFY_PIN
PIN_VERIFY_STRUCTURE *pin_verify;
#endif
#ifdef MODIFY_PIN
PIN_MODIFY_STRUCTURE *pin_modify;
#endif
int PIN_min_size = 4;
int PIN_max_size = 8;
/* table for bEntryValidationCondition
* 0x01: Max size reached
* 0x02: Validation key pressed
* 0x04: Timeout occured
*/
int bEntryValidationCondition = 7;
printf("SCardControl sample code\n");
printf("V 1.4 © 2004-2010, Ludovic Rousseau <ludovic.rousseau@free.fr>\n\n");
printf(MAGENTA "THIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL!\n");
printf("Do NOT use it unless you really know what you do.\n\n" NORMAL);
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
if (rv != SCARD_S_SUCCESS)
{
printf("SCardEstablishContext: Cannot Connect to Resource Manager %"LF"X\n", rv);
return 1;
}
/* Retrieve the available readers list */
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
PCSC_ERROR_EXIT(rv, "SCardListReaders")
mszReaders = malloc(sizeof(char)*dwReaders);
if (mszReaders == NULL)
{
printf("malloc: not enough memory\n");
goto end;
}
rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
if (rv != SCARD_S_SUCCESS)
printf("SCardListReader: %"LF"X\n", rv);
/* Extract readers from the null separated string and get the total
* number of readers */
nbReaders = 0;
ptr = mszReaders;
while (*ptr != '\0')
{
ptr += strlen(ptr)+1;
nbReaders++;
}
if (nbReaders == 0)
{
printf("No reader found\n");
goto end;
}
/* allocate the readers table */
readers = calloc(nbReaders, sizeof(char *));
if (NULL == readers)
{
printf("Not enough memory for readers[]\n");
goto end;
}
/* fill the readers table */
nbReaders = 0;
ptr = mszReaders;
printf("Available readers (use command line argument to select)\n");
while (*ptr != '\0')
{
printf("%d: %s\n", nbReaders, ptr);
readers[nbReaders] = ptr;
ptr += strlen(ptr)+1;
nbReaders++;
}
printf("\n");
if (argc > 1)
{
reader_nb = atoi(argv[1]);
if (reader_nb < 0 || reader_nb >= nbReaders)
{
printf("Wrong reader index: %d\n", reader_nb);
goto end;
}
}
else
reader_nb = 0;
/* connect to a reader (even without a card) */
dwActiveProtocol = -1;
printf("Using reader: " GREEN "%s\n" NORMAL, readers[reader_nb]);
rv = SCardConnect(hContext, readers[reader_nb], SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
printf(" Protocol: " GREEN "%"LF"d\n" NORMAL, dwActiveProtocol);
PCSC_ERROR_EXIT(rv, "SCardConnect")
#ifdef GET_GEMPC_FIRMWARE
/* get GemPC firmware */
printf(" Get GemPC Firmware\n");
/* this is specific to Gemalto readers */
bSendBuffer[0] = 0x02;
rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE, bSendBuffer,
1, bRecvBuffer, sizeof(bRecvBuffer), &length);
printf(" Firmware: " GREEN);
for (i=0; i<length; i++)
printf("%02X ", bRecvBuffer[i]);
printf(NORMAL "\n");
bRecvBuffer[length] = '\0';
printf(" Firmware: " GREEN "%s" NORMAL" (length " GREEN "%ld" NORMAL " bytes)\n", bRecvBuffer, length);
PCSC_ERROR_CONT(rv, "SCardControl")
#endif
/* does the reader support PIN verification? */
rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
bRecvBuffer, sizeof(bRecvBuffer), &length);
PCSC_ERROR_EXIT(rv, "SCardControl")
printf(" TLV (%"LF"d): " GREEN, length);
for (i=0; i<length; i++)
printf("%02X ", bRecvBuffer[i]);
printf(NORMAL "\n");
PCSC_ERROR_CONT(rv, "SCardControl(CM_IOCTL_GET_FEATURE_REQUEST)")
if (length % sizeof(PCSC_TLV_STRUCTURE))
{
printf("Inconsistent result! Bad TLV values!\n");
goto end;
}
/* get the number of elements instead of the complete size */
length /= sizeof(PCSC_TLV_STRUCTURE);
pcsc_tlv = (PCSC_TLV_STRUCTURE *)bRecvBuffer;
for (i = 0; i < length; i++)
{
switch (pcsc_tlv[i].tag)
{
case FEATURE_VERIFY_PIN_DIRECT:
PRINT_GREEN("Reader supports", "FEATURE_VERIFY_PIN_DIRECT");
verify_ioctl = ntohl(pcsc_tlv[i].value);
break;
case FEATURE_MODIFY_PIN_DIRECT:
PRINT_GREEN("Reader supports", "FEATURE_MODIFY_PIN_DIRECT");
modify_ioctl = ntohl(pcsc_tlv[i].value);
break;
case FEATURE_IFD_PIN_PROPERTIES:
PRINT_GREEN("Reader supports", "FEATURE_IFD_PIN_PROPERTIES");
pin_properties_ioctl = ntohl(pcsc_tlv[i].value);
break;
case FEATURE_MCT_READER_DIRECT:
PRINT_GREEN("Reader supports", "FEATURE_MCT_READER_DIRECT");
mct_readerdirect_ioctl = ntohl(pcsc_tlv[i].value);
break;
case FEATURE_GET_TLV_PROPERTIES:
PRINT_GREEN("Reader supports", "FEATURE_GET_TLV_PROPERTIES");
properties_in_tlv_ioctl = ntohl(pcsc_tlv[i].value);
break;
case FEATURE_CCID_ESC_COMMAND:
PRINT_GREEN("Reader supports", "FEATURE_CCID_ESC_COMMAND");
ccid_esc_command = ntohl(pcsc_tlv[i].value);
break;
default:
PRINT_RED_DEC("Can't parse tag", pcsc_tlv[i].tag);
}
}
printf("\n");
if (properties_in_tlv_ioctl)
{
int value;
int ret;
rv = SCardControl(hCard, properties_in_tlv_ioctl, NULL, 0,
bRecvBuffer, sizeof(bRecvBuffer), &length);
PCSC_ERROR_CONT(rv, "SCardControl(GET_TLV_PROPERTIES)")
printf("GET_TLV_PROPERTIES (" GREEN "%"LF"d" NORMAL "): " GREEN, length);
for (i=0; i<length; i++)
printf("%02X ", bRecvBuffer[i]);
printf(NORMAL "\n");
printf("\nDisplay all the properties:\n");
parse_properties(bRecvBuffer, length);
printf("\nFind a specific property:\n");
ret = PCSCv2Part10_find_TLV_property_by_tag_from_buffer(bRecvBuffer, length, PCSCv2_PART10_PROPERTY_wIdVendor, &value);
if (ret)
PRINT_RED_DEC(" wIdVendor", ret);
else
PRINT_GREEN_HEX4(" wIdVendor", value);
ret = PCSCv2Part10_find_TLV_property_by_tag_from_hcard(hCard, PCSCv2_PART10_PROPERTY_wIdProduct, &value);
if (ret)
PRINT_RED_DEC(" wIdProduct", ret);
else
PRINT_GREEN_HEX4(" wIdProduct", value);
ret = PCSCv2Part10_find_TLV_property_by_tag_from_hcard(hCard, PCSCv2_PART10_PROPERTY_bMinPINSize, &value);
if (0 == ret)
{
PIN_min_size = value;
PRINT_GREEN_DEC(" PIN min size defined", PIN_min_size);
}
ret = PCSCv2Part10_find_TLV_property_by_tag_from_hcard(hCard, PCSCv2_PART10_PROPERTY_bMaxPINSize, &value);
if (0 == ret)
{
PIN_max_size = value;
PRINT_GREEN_DEC(" PIN max size defined", PIN_max_size);
}
ret = PCSCv2Part10_find_TLV_property_by_tag_from_hcard(hCard, PCSCv2_PART10_PROPERTY_bEntryValidationCondition, &value);
if (0 == ret)
{
bEntryValidationCondition = value;
PRINT_GREEN_DEC(" Entry Validation Condition defined",
bEntryValidationCondition);
}
printf("\n");
}
if (mct_readerdirect_ioctl)
{
char secoder_info[] = { 0x20, 0x70, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };
rv = SCardControl(hCard, mct_readerdirect_ioctl, secoder_info,
sizeof(secoder_info), bRecvBuffer, sizeof(bRecvBuffer), &length);
PCSC_ERROR_CONT(rv, "SCardControl(MCT_READER_DIRECT)")
printf("MCT_READER_DIRECT (%"LF"d): ", length);
for (i=0; i<length; i++)
printf("%02X ", bRecvBuffer[i]);
printf("\n");
}
if (pin_properties_ioctl)
{
PIN_PROPERTIES_STRUCTURE *pin_properties;
rv = SCardControl(hCard, pin_properties_ioctl, NULL, 0,
bRecvBuffer, sizeof(bRecvBuffer), &length);
PCSC_ERROR_CONT(rv, "SCardControl(pin_properties_ioctl)")
printf("PIN PROPERTIES (" GREEN "%"LF"d" NORMAL "): " GREEN, length);
for (i=0; i<length; i++)
printf("%02X ", bRecvBuffer[i]);
printf(NORMAL "\n");
pin_properties = (PIN_PROPERTIES_STRUCTURE *)bRecvBuffer;
bEntryValidationCondition = pin_properties -> bEntryValidationCondition;
PRINT_GREEN_HEX4(" wLcdLayout", pin_properties -> wLcdLayout);
PRINT_GREEN_DEC(" bEntryValidationCondition", bEntryValidationCondition);
PRINT_GREEN_DEC(" bTimeOut2", pin_properties -> bTimeOut2);
printf("\n");
}
#ifdef GET_GEMPC_FIRMWARE
if (ccid_esc_command)
{
/* get GemPC firmware */
printf("Get GemPC Firmware\n");
/* this is specific to Gemalto readers */
bSendBuffer[0] = 0x02;
rv = SCardControl(hCard, ccid_esc_command, bSendBuffer,
1, bRecvBuffer, sizeof(bRecvBuffer), &length);
printf(" Firmware: " GREEN);
for (i=0; i<length; i++)
printf("%02X ", bRecvBuffer[i]);
printf(NORMAL "\n");
bRecvBuffer[length] = '\0';
printf(" Firmware: " GREEN "%s" NORMAL" (length " GREEN "%ld" NORMAL " bytes)\n", bRecvBuffer, length);
PCSC_ERROR_CONT(rv, "SCardControl")
}
#endif
if (0 == verify_ioctl)
{
printf("Reader %s does not support PIN verification\n",
readers[reader_nb]);
goto end;
}
/* get card status */
dwAtrLen = sizeof(pbAtr);
dwReaderLen = sizeof(pbReader);
rv = SCardStatus(hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
pbAtr, &dwAtrLen);
printf(" Reader: %s (length %"LF"d bytes)\n", pbReader, dwReaderLen);
printf(" State: 0x%04"LF"X\n", dwState);
printf(" Prot: %"LF"d\n", dwProt);
printf(" ATR (length %"LF"d bytes):", dwAtrLen);
for (i=0; i<dwAtrLen; i++)
printf(" %02X", pbAtr[i]);
printf("\n");
PCSC_ERROR_CONT(rv, "SCardStatus")
if (dwState & SCARD_ABSENT)
{
printf("No card inserted\n");
goto end;
}
/* re-connect to a reader (with a card) */
dwActiveProtocol = -1;
rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, SCARD_LEAVE_CARD,
&dwActiveProtocol);
printf(" Protocol: %"LF"d\n", dwActiveProtocol);
PCSC_ERROR_EXIT(rv, "SCardReconnect")
switch(dwActiveProtocol)
{
case SCARD_PROTOCOL_T0:
pioSendPci = *SCARD_PCI_T0;
break;
case SCARD_PROTOCOL_T1:
pioSendPci = *SCARD_PCI_T1;
break;
default:
printf("Unknown protocol. No card present?\n");
return -1;
}
/* APDU select applet */
printf("Select applet: ");
send_length = 11;
memcpy(bSendBuffer, "\x00\xA4\x04\x00\x06\xA0\x00\x00\x00\x18\xFF",
send_length);
for (i=0; i<send_length; i++)
printf(" %02X", bSendBuffer[i]);
printf("\n");
length = sizeof(bRecvBuffer);
rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
&pioRecvPci, bRecvBuffer, &length);
printf(" card response:");
for (i=0; i<length; i++)
printf(" %02X", bRecvBuffer[i]);
printf("\n");
PCSC_ERROR_EXIT(rv, "SCardTransmit")
if ((bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00))
{
printf("Error: test applet not found!\n");
goto end;
}
#ifdef VERIFY_PIN
/* verify PIN */
printf(" Secure verify PIN\n");
pin_verify = (PIN_VERIFY_STRUCTURE *)bSendBuffer;
/* PC/SC v2.02.05 Part 10 PIN verification data structure */
pin_verify -> bTimerOut = 0x00;
pin_verify -> bTimerOut2 = 0x00;
pin_verify -> bmFormatString = 0x82;
pin_verify -> bmPINBlockString = 0x08;
pin_verify -> bmPINLengthFormat = 0x00;
pin_verify -> wPINMaxExtraDigit = (PIN_min_size << 8) + PIN_max_size;
pin_verify -> bEntryValidationCondition = bEntryValidationCondition;
pin_verify -> bNumberMessage = 0x01;
pin_verify -> wLangId = 0x0904;
pin_verify -> bMsgIndex = 0x00;
pin_verify -> bTeoPrologue[0] = 0x00;
pin_verify -> bTeoPrologue[1] = 0x00;
pin_verify -> bTeoPrologue[2] = 0x00;
/* pin_verify -> ulDataLength = 0x00; we don't know the size yet */
/* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
offset = 0;
pin_verify -> abData[offset++] = 0x00; /* CLA */
pin_verify -> abData[offset++] = 0x20; /* INS: VERIFY */
pin_verify -> abData[offset++] = 0x00; /* P1 */
pin_verify -> abData[offset++] = 0x00; /* P2 */
pin_verify -> abData[offset++] = 0x08; /* Lc: 8 data bytes */
pin_verify -> abData[offset++] = 0x30; /* '0' */
pin_verify -> abData[offset++] = 0x30; /* '0' */
pin_verify -> abData[offset++] = 0x30; /* '0' */
pin_verify -> abData[offset++] = 0x30; /* '0' */
pin_verify -> abData[offset++] = 0x00; /* '\0' */
pin_verify -> abData[offset++] = 0x00; /* '\0' */
pin_verify -> abData[offset++] = 0x00; /* '\0' */
pin_verify -> abData[offset++] = 0x00; /* '\0' */
pin_verify -> ulDataLength = offset; /* APDU size */
length = sizeof(PIN_VERIFY_STRUCTURE) + offset;
printf(" command:");
for (i=0; i<length; i++)
printf(" %02X", bSendBuffer[i]);
printf("\n");
printf("Enter your PIN: ");
fflush(stdout);
memset(bRecvBuffer, 0xAA, sizeof bRecvBuffer);
rv = SCardControl(hCard, verify_ioctl, bSendBuffer,
length, bRecvBuffer, sizeof(bRecvBuffer), &length);
{
#ifndef S_SPLINT_S
fd_set fd;
#endif
struct timeval timeout;
FD_ZERO(&fd);
FD_SET(STDIN_FILENO, &fd); /* stdin */
timeout.tv_sec = 0; /* timeout = 0.1s */
timeout.tv_usec = 100000;
/* we only try to read stdin if the pinpad is on a keyboard
* we do not read stdin for a SPR 532 for example */
if (select(1, &fd, NULL, NULL, &timeout) > 0)
{
/* read the fake digits */
char in[40]; /* 4 digits + \n + \0 */
char *s = fgets(in, sizeof(in), stdin);
if (s)
printf("keyboard sent: %s", in);
}
else
/* if it is not a keyboard */
printf("\n");
}
printf(" card response:");
for (i=0; i<length; i++)
printf(" %02X", bRecvBuffer[i]);
printf(": %s\n", pinpad_return_codes(bRecvBuffer));
PCSC_ERROR_CONT(rv, "SCardControl")
/* verify PIN dump */
printf("\nverify PIN dump: ");
send_length = 5;
memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
send_length);
for (i=0; i<send_length; i++)
printf(" %02X", bSendBuffer[i]);
printf("\n");
length = sizeof(bRecvBuffer);
rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
&pioRecvPci, bRecvBuffer, &length);
printf(" card response:");
for (i=0; i<length; i++)
printf(" %02X", bRecvBuffer[i]);
printf("\n");
PCSC_ERROR_EXIT(rv, "SCardTransmit")
if ((2 == length) && (0x6C == bRecvBuffer[0]))
{
printf("\nverify PIN dump: ");
send_length = 5;
memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
send_length);
bSendBuffer[4] = bRecvBuffer[1];
for (i=0; i<send_length; i++)
printf(" %02X", bSendBuffer[i]);
printf("\n");
length = sizeof(bRecvBuffer);
rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
&pioRecvPci, bRecvBuffer, &length);
printf(" card response:");
for (i=0; i<length; i++)
printf(" %02X", bRecvBuffer[i]);
printf("\n");
PCSC_ERROR_EXIT(rv, "SCardTransmit")
}
#endif
/* check if the reader supports Modify PIN */
if (0 == modify_ioctl)
{
printf("Reader %s does not support PIN modification\n",
readers[reader_nb]);
goto end;
}
#ifdef MODIFY_PIN
/* Modify PIN */
printf(" Secure modify PIN\n");
pin_modify = (PIN_MODIFY_STRUCTURE *)bSendBuffer;
/* Table for bConfirmPIN and bNumberMessage
* bConfirmPIN = 3, bNumberMessage = 3: "Enter Pin" "New Pin" "Confirm Pin"
* bConfirmPIN = 2, bNumberMessage = 2: "Enter Pin" "New Pin"
* bConfirmPIN = 1, bNumberMessage = 2: "New Pin" "Confirm Pin"
* bConfirmPIN = 0, bNumberMessage = 1: "New Pin"
*/
/* table for bMsgIndex[1-3]
* 00: PIN insertion prompt ENTER SMARTCARD PIN
* 01: PIN Modification prompt ENTER NEW PIN
* 02: NEW PIN Confirmation prompt CONFIRM NEW PIN
*/
/* PC/SC v2.02.05 Part 10 PIN modification data structure */
pin_modify -> bTimerOut = 0x00;
pin_modify -> bTimerOut2 = 0x00;
pin_modify -> bmFormatString = 0x82;
pin_modify -> bmPINBlockString = 0x04;
pin_modify -> bmPINLengthFormat = 0x00;
pin_modify -> bInsertionOffsetOld = 0x00; /* offset from APDU start */
pin_modify -> bInsertionOffsetNew = 0x04; /* offset from APDU start */
pin_modify -> wPINMaxExtraDigit = (PIN_min_size << 8) + PIN_max_size;
pin_modify -> bConfirmPIN = 0x03; /* b0 set = confirmation requested */
/* b1 set = current PIN entry requested */
pin_modify -> bEntryValidationCondition = bEntryValidationCondition;
pin_modify -> bNumberMessage = 0x03; /* see table above */
pin_modify -> wLangId = 0x0904;
pin_modify -> bMsgIndex1 = 0x00;
pin_modify -> bMsgIndex2 = 0x01;
pin_modify -> bMsgIndex3 = 0x02;
pin_modify -> bTeoPrologue[0] = 0x00;
pin_modify -> bTeoPrologue[1] = 0x00;
pin_modify -> bTeoPrologue[2] = 0x00;
/* pin_modify -> ulDataLength = 0x00; we don't know the size yet */
/* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
offset = 0;
pin_modify -> abData[offset++] = 0x00; /* CLA */
pin_modify -> abData[offset++] = 0x24; /* INS: CHANGE/UNBLOCK */
pin_modify -> abData[offset++] = 0x00; /* P1 */
pin_modify -> abData[offset++] = 0x00; /* P2 */
pin_modify -> abData[offset++] = 0x08; /* Lc: 2x8 data bytes */
pin_modify -> abData[offset++] = 0x30; /* '0' old PIN */
pin_modify -> abData[offset++] = 0x30; /* '0' */
pin_modify -> abData[offset++] = 0x30; /* '0' */
pin_modify -> abData[offset++] = 0x30; /* '0' */
pin_modify -> abData[offset++] = 0x30; /* '0' new PIN */
pin_modify -> abData[offset++] = 0x30; /* '0' */
pin_modify -> abData[offset++] = 0x30; /* '0' */
pin_modify -> abData[offset++] = 0x30; /* '0' */
pin_modify -> ulDataLength = offset; /* APDU size */
length = sizeof(PIN_MODIFY_STRUCTURE) + offset;
printf(" command:");
for (i=0; i<length; i++)
printf(" %02X", bSendBuffer[i]);
printf("\n");
printf("Enter your PIN: ");
fflush(stdout);
memset(bRecvBuffer, 0xAA, sizeof bRecvBuffer);
rv = SCardControl(hCard, modify_ioctl, bSendBuffer,
length, bRecvBuffer, sizeof(bRecvBuffer), &length);
{
#ifndef S_SPLINT_S
fd_set fd;
#endif
struct timeval timeout;
/* old PIN, new PIN, confirmation PIN */
/* if the command is aborted we will not read every "PIN" */
for (i=0; i<3; i++)
{
FD_ZERO(&fd);
FD_SET(STDIN_FILENO, &fd); /* stdin */
timeout.tv_sec = 0; /* timeout = 0.1s */
timeout.tv_usec = 100000;
/* we only try to read stdin if the pinpad is on a keyboard
* we do not read stdin for a SPR 532 for example */
if (select(1, &fd, NULL, NULL, &timeout) > 0)
{
/* read the fake digits */
char in[40]; /* 4 digits + \n + \0 */
char *ret;
ret = fgets(in, sizeof(in), stdin);
if (ret)
printf("keyboard sent: %s", in);
}
else
{
/* if it is not a keyboard */
printf("\n");
/* exit the for() loop */
break;
}
}
}
printf(" card response:");
for (i=0; i<length; i++)
printf(" %02X", bRecvBuffer[i]);
printf("\n");
PCSC_ERROR_CONT(rv, "SCardControl")
/* modify PIN dump */
printf("\nmodify PIN dump: ");
send_length = 5;
memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
send_length);
for (i=0; i<send_length; i++)
printf(" %02X", bSendBuffer[i]);
printf("\n");
length = sizeof(bRecvBuffer);
rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
&pioRecvPci, bRecvBuffer, &length);
printf(" card response:");
for (i=0; i<length; i++)
printf(" %02X", bRecvBuffer[i]);
printf("\n");
PCSC_ERROR_EXIT(rv, "SCardTransmit")
if ((2 == length) && (0x6C == bRecvBuffer[0]))
{
printf("\nverify PIN dump: ");
send_length = 5;
memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
send_length);
bSendBuffer[4] = bRecvBuffer[1];
for (i=0; i<send_length; i++)
printf(" %02X", bSendBuffer[i]);
printf("\n");
length = sizeof(bRecvBuffer);
rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
&pioRecvPci, bRecvBuffer, &length);
printf(" card response:");
for (i=0; i<length; i++)
printf(" %02X", bRecvBuffer[i]);
printf("\n");
PCSC_ERROR_EXIT(rv, "SCardTransmit")
}
#endif
/* card disconnect */
rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
PCSC_ERROR_CONT(rv, "SCardDisconnect")
end:
/* We try to leave things as clean as possible */
rv = SCardReleaseContext(hContext);
if (rv != SCARD_S_SUCCESS)
printf("SCardReleaseContext: %s (0x%"LF"X)\n", pcsc_stringify_error(rv),
rv);
/* free allocated memory */
if (mszReaders)
free(mszReaders);
if (readers)
free(readers);
return 0;
} /* main */

508
install-sh Executable file
View File

@ -0,0 +1,508 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2014-09-12.12; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
# $RANDOM is not portable (e.g. dash); use it when possible to
# lower collision chance
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
# As "mkdir -p" follows symlinks and we work in /tmp possibly; so
# create the $tmpdir first (and fail if unsuccessful) to make sure
# that nobody tries to guess the $tmpdir name.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

11156
ltmain.sh Normal file

File diff suppressed because it is too large Load Diff

43
m4/as-ac-expand.m4 Normal file
View File

@ -0,0 +1,43 @@
dnl as-ac-expand.m4 0.2.0
dnl autostars m4 macro for expanding directories using configure's prefix
dnl thomas@apestaart.org
dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR)
dnl example
dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir)
dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local
AC_DEFUN([AS_AC_EXPAND],
[
EXP_VAR=[$1]
FROM_VAR=[$2]
dnl first expand prefix and exec_prefix if necessary
prefix_save=$prefix
exec_prefix_save=$exec_prefix
dnl if no prefix given, then use /usr/local, the default prefix
if test "x$prefix" = "xNONE"; then
prefix="$ac_default_prefix"
fi
dnl if no exec_prefix given, then use prefix
if test "x$exec_prefix" = "xNONE"; then
exec_prefix=$prefix
fi
full_var="$FROM_VAR"
dnl loop until it doesn't change anymore
while true; do
new_full_var="`eval echo $full_var`"
if test "x$new_full_var" = "x$full_var"; then break; fi
full_var=$new_full_var
done
dnl clean up
full_var=$new_full_var
AC_SUBST([$1], "$full_var")
dnl restore prefix and exec_prefix
prefix=$prefix_save
exec_prefix=$exec_prefix_save
])

309
m4/ax_pthread.m4 Normal file
View File

@ -0,0 +1,309 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
#
# DESCRIPTION
#
# This macro figures out how to build C programs using POSIX threads. It
# sets the PTHREAD_LIBS output variable to the threads library and linker
# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise). (This
# is necessary on AIX to use the special cc_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also link it with them as well. e.g. you should link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threads programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
# PTHREAD_CFLAGS.
#
# ACTION-IF-FOUND is a list of shell commands to run if a threads library
# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
# is not found. If ACTION-IF-FOUND is not specified, the default action
# will define HAVE_PTHREAD.
#
# Please let the authors know if this macro fails on any platform, or if
# you have any other suggestions or comments. This macro was based on work
# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
# Alejandro Forero Cuervo to the autoconf macro repository. We are also
# grateful for the helpful feedback of numerous users.
#
# Updated for Autoconf 2.68 by Daniel Richard G.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program 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 General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 18
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_PUSH([C])
ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
AC_MSG_RESULT($ax_pthread_ok)
if test x"$ax_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case ${host_os} in
solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
;;
darwin*)
ax_pthread_flags="-pthread $ax_pthread_flags"
;;
esac
if test x"$ax_pthread_ok" = xno; then
for flag in $ax_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
if test x"$ax_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
static void routine(void *a) { a = 0; }
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
pthread_join(th, 0);
pthread_attr_init(&attr);
pthread_cleanup_push(routine, 0);
pthread_cleanup_pop(0) /* ; */])],
[ax_pthread_ok=yes],
[])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($ax_pthread_ok)
if test "x$ax_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$ax_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $attr; return attr /* ; */])],
[attr_name=$attr; break],
[])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case ${host_os} in
aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
osf* | hpux*) flag="-D_REENTRANT";;
solaris*)
if test "$GCC" = "yes"; then
flag="-D_REENTRANT"
else
flag="-mt -D_REENTRANT"
fi
;;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
ax_cv_PTHREAD_PRIO_INHERIT, [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
fi
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$ax_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
ax_pthread_ok=no
$2
fi
AC_LANG_POP
])dnl AX_PTHREAD

8387
m4/libtool.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

437
m4/ltoptions.m4 vendored Normal file
View File

@ -0,0 +1,437 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 8 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option '$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
_LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
[_LT_WITH_AIX_SONAME([aix])])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the 'shared' and
# 'disable-shared' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the 'static' and
# 'disable-static' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the 'fast-install'
# and 'disable-fast-install' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_AIX_SONAME([DEFAULT])
# ----------------------------------
# implement the --with-aix-soname flag, and support the `aix-soname=aix'
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
m4_define([_LT_WITH_AIX_SONAME],
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
shared_archive_member_spec=
case $host,$enable_shared in
power*-*-aix[[5-9]]*,yes)
AC_MSG_CHECKING([which variant of shared library versioning to provide])
AC_ARG_WITH([aix-soname],
[AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
[shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
[case $withval in
aix|svr4|both)
;;
*)
AC_MSG_ERROR([Unknown argument to --with-aix-soname])
;;
esac
lt_cv_with_aix_soname=$with_aix_soname],
[AC_CACHE_VAL([lt_cv_with_aix_soname],
[lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
with_aix_soname=$lt_cv_with_aix_soname])
AC_MSG_RESULT([$with_aix_soname])
if test aix != "$with_aix_soname"; then
# For the AIX way of multilib, we name the shared archive member
# based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
# and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
# Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
# the AIX toolchain works better with OBJECT_MODE set (default 32).
if test 64 = "${OBJECT_MODE-32}"; then
shared_archive_member_spec=shr_64
else
shared_archive_member_spec=shr
fi
fi
;;
*)
with_aix_soname=aix
;;
esac
_LT_DECL([], [shared_archive_member_spec], [0],
[Shared archive member basename, for filename based shared library versioning on AIX])dnl
])# _LT_WITH_AIX_SONAME
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
# LT_INIT options.
# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for lt_pkg in $withval; do
IFS=$lt_save_ifs
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[pic_mode=m4_default([$1], [default])])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

124
m4/ltsugar.m4 vendored Normal file
View File

@ -0,0 +1,124 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59, which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

23
m4/ltversion.m4 vendored Normal file
View File

@ -0,0 +1,23 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# @configure_input@
# serial 4179 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.6])
m4_define([LT_PACKAGE_REVISION], [2.4.6])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.6'
macro_revision='2.4.6'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

99
m4/lt~obsolete.m4 vendored Normal file
View File

@ -0,0 +1,99 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])

215
missing Executable file
View File

@ -0,0 +1,215 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2013-10-28.13; # UTC
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'autom4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

1
readers/Makefile.am Normal file
View File

@ -0,0 +1 @@
EXTRA_DIST = supported_readers.txt

464
readers/Makefile.in Normal file
View File

@ -0,0 +1,464 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = readers
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUNDLE_HOST = @BUNDLE_HOST@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
DYN_LIB_EXT = @DYN_LIB_EXT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
LIBUSB_LIBS = @LIBUSB_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NOCLASS = @NOCLASS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCSC_CFLAGS = @PCSC_CFLAGS@
PCSC_LIBS = @PCSC_LIBS@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SYMBOL_VISIBILITY = @SYMBOL_VISIBILITY@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_aux_dir = @ac_aux_dir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
bindir_exp = @bindir_exp@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
bundle = @bundle@
ccidtwindir = @ccidtwindir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
serialconfdir = @serialconfdir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
sysconfdir_exp = @sysconfdir_exp@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
usbdropdir = @usbdropdir@
EXTRA_DIST = supported_readers.txt
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign readers/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign readers/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
tags TAGS:
ctags CTAGS:
cscope cscopelist:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
cscopelist-am ctags-am distclean distclean-generic \
distclean-libtool distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,875 @@
#
# List of readers supported by the CCID driver
# Generated: 2017-10-02
#
# DO NOT EDIT BY HAND
# Website: http://pcsclite.alioth.debian.org/ccid.html
##########################
# section: supported
##########################
# ACS
0x072F:0x90CC:ACS ACR 38U-CCID
# ActivIdentity
0x09C3:0x0013:ActivIdentity USB Reader V3
0x09C3:0x0014:ActivIdentity Activkey_Sim
# Alcor Micro
0x058F:0x9520:Alcor Micro AU9520
0x058F:0x9540:Alcor Micro AU9560
# Athena
0x0DC3:0x1004:Athena ASE IIIe
0x0DC3:0x1102:Athena ASEDrive IIIe KB
# BLUTRONICS
0x1B0E:0x1078:BLUTRONICS BLUDRIVE II CCID
# C3PO
0x0783:0x0006:C3PO LTC31 v2
# Cherry GmbH
0x046A:0x0005:Cherry GmbH SmartBoard XX33
0x046A:0x0010:Cherry GmbH SmartBoard XX44
0x046A:0x002D:Cherry GmbH SmartTerminal XX44
0x046A:0x003E:Cherry GmbH SmartTerminal ST-2xxx
# COVADIS
0x0982:0x0007:COVADIS ALYA
# Dell
0x413C:0x2100:Dell keyboard SK-3106
0x413C:0x2101:Dell Dell Smart Card Reader Keyboard
# Eutron
0x073D:0x0007:Eutron CryptoIdentity CCID
0x073D:0x0008:Eutron CryptoIdentity CCID
0x073D:0x0B00:Eutron Digipass 860
0x073D:0x0C00:Eutron Card Reader
0x073D:0x0C01:Eutron Smart Pocket
# Gemalto
0x08E6:0x1227:Gemalto PDT
0x08E6:0x3437:Gemalto PC Twin Reader
0x08E6:0x3438:Gemalto USB Shell Token V2
0x08E6:0x3478:Gemalto USB GemPCPinpad SmartCard Reader
0x08E6:0x3480:Gemalto GemCore SIM Pro Smart Card Reader
0x08E6:0x34C0:Gemalto Ezio Shield
0x08E6:0x34C3:Gemalto EZIO CB+
0x08E6:0x4433:Gemalto Gemplus USB SmartCard Reader 433-Swap
0x08E6:0x5503:Gemalto Prox Dual USB PC Link Reader
0x08E6:0x5504:Gemalto Prox SU USB PC LinkReader
0x08E6:0x8000:Gemalto Smart Enterprise Guardian Secure USB Device
0x08E6:0x8141:Gemalto IDBridge K3000
# Giesecke & Devrient GmbH
0x1059:0x0017:Giesecke & Devrient GmbH StarSign Crypto USB Token
0x1059:0x0019:Giesecke & Devrient GmbH StarSign CUT S
# id3 Semiconductors
0x0B81:0x0200:id3 Semiconductors CL1356T
# INGENICO
0x0F14:0x003B:INGENICO Leo
# Ingenico
0x0F14:0x003D:Ingenico WITEO USB Smart Card Reader
# KOBIL
0x0D46:0x3001:KOBIL KAAN Base
0x0D46:0x3002:KOBIL KAAN Advanced
0x0D46:0x3003:KOBIL KAAN SIM III
0x0D46:0x3010:KOBIL EMV CAP - SecOVID Reader III
# Lenovo
0x17EF:0x1003:Lenovo Integrated Smart Card Reader
# MYSMART
0x09BE:0x0002:MYSMART MySMART PAD V2.0
# OMNIKEY AG
0x076B:0x3021:OMNIKEY AG CardMan 3121
# Precise Biometrics
0x076B:0xA022:Precise Biometrics Sense MC
# SCM Microsystems Inc.
0x03F0:0x0824:SCM Microsystems Inc. HP USB Smartcard Reader
0x04E6:0x5111:SCM Microsystems Inc. SCR 331-DI
0x04E6:0x5116:SCM Microsystems Inc. SCR 3310
0x04E6:0x511D:SCM Microsystems Inc. SCR 3311
0x04E6:0x5410:SCM Microsystems Inc. SCR 355
0x04E6:0xE001:SCM Microsystems Inc. SCR 331
0x04E6:0xE003:SCM Microsystems Inc. SPR 532
# TianYu CCID Key
0xA625:0x0801:TianYu CCID Key TianYu CCID SmartKey
# Verisign
0x08E6:0x1359:Verisign Secure Storage Token
0x08E6:0xACE0:Verisign Secure Token
# XIRING
0x0F14:0x0011:XIRING XI-SIGN USB V2
0x0F14:0x0037:XIRING MyLeo
0x0F14:0x0038:XIRING Leo v2
##########################
# section: shouldwork
##########################
# Access IS
0x0DB5:0x0138:Access IS ePassport Reader
0x0DB5:0x0160:Access IS NFC Smart Module
# ACS
0x072F:0x1204:ACS ACR101 ICC Reader
0x072F:0x221A:ACS ACR1251 Dual Reader
0x072F:0x223B:ACS ACR1252 Dual Reader
0x072F:0x223F:ACS ACR1255U-J1
0x072F:0x8201:ACS APG8201 PINhandy 1
0x072F:0x8202:ACS APG8201 USB Reader
0x072F:0x90DB:ACS CryptoMate64
0x072F:0xB000:ACS ACR3901U ICC Reader
0x072F:0xB100:ACS ACR39U ICC Reader
0x072F:0xB106:ACS CryptoMate (T2)
# AK910
0x2021:0x0001:AK910 CKey
0x2021:0x0011:AK910 CKey
0x2021:0x0101:AK910 IDONE
# Akasa
# Aktiv
0x0A89:0x0025:Aktiv Rutoken lite
0x0A89:0x0030:Aktiv Rutoken ECP
0x0A89:0x0080:Aktiv PINPad Ex
0x0A89:0x0081:Aktiv PINPad In
0x0A89:0x0082:Aktiv Rutoken PINPad 2
# Aktiv Co., ProgramPark
0x0A89:0x0060:Aktiv Co., ProgramPark Rutoken Magistra
# Aladdin R.D.
0x24DC:0x0101:Aladdin R.D. JaCarta
0x24DC:0x0102:Aladdin R.D. JaCarta LT
0x24DC:0x0201:Aladdin R.D. JCR-770
0x24DC:0x0401:Aladdin R.D. JC-WebPass (JC600)
0x24DC:0x0402:Aladdin R.D. JaCarta
0x24DC:0x0501:Aladdin R.D. JaCarta U2F (JC602)
0x24DC:0x100F:Aladdin R.D. JaCarta Flash
# Alcor Micro
0x058F:0x9522:Alcor Micro AU9522
# ANCUD
0x0483:0xACD1:ANCUD CCID USB Reader & RNG
# appidkey GmbH
0x2406:0x5003:appidkey GmbH ID50 -USB
0x2406:0x5004:appidkey GmbH ID100L-USB-SC-Reader
0x2406:0x5006:appidkey GmbH ID60-USB
# ASK-RFID
0x1FD3:0xCC1D:ASK-RFID CPL108
# Athena
0x0DC3:0x0900:Athena IDProtect Key v2
0x0DC3:0x1007:Athena ASEDrive IIIe KB Bio PIV
0x0DC3:0x1008:Athena ASEDrive IIIe Combo Bio PIV
# ATMEL
0x03EB:0x6004:ATMEL AT91SO CCID Smart Card Reader
0x03EB:0x6009:ATMEL AT98SC032CT-USB
0x03EB:0x600B:ATMEL AT91SC192192CT-USB ICCD reader
0x03EB:0x6010:ATMEL AT90SCR100
0x03EB:0x6011:ATMEL AT90SCR050
0x03EB:0x6012:ATMEL VaultIC420 Smart Object
0x03EB:0x6014:ATMEL VaultIC440
# Avtor
0x15CF:0x0019:Avtor SecureToken
0x15CF:0x001D:Avtor SC Reader 371
# Axalto
0x04E6:0x511C:Axalto Reflex USB v3
# BIFIT
0x23A0:0x0001:BIFIT USB-Token iBank2key
0x23A0:0x0002:BIFIT iBank2Key
0x23A0:0x0003:BIFIT iToken
# Bit4id
0x25DD:0x1101:Bit4id miniLector-s
0x25DD:0x1201:Bit4id cryptokey
0x25DD:0x2221:Bit4id iAM
0x25DD:0x2321:Bit4id CKey4
0x25DD:0x2341:Bit4id tokenME FIPS v3
0x25DD:0x2351:Bit4id Digital DNA Key
0x25DD:0x3111:Bit4id miniLector
# BLUTRONICS
0x1B0E:0x1079:BLUTRONICS BLUDRIVE II CCID
# Broadcom Corp
0x0A5C:0x5802:Broadcom Corp 5880
0x0A5C:0x5804:Broadcom Corp 5880
0x0A5C:0x5832:Broadcom Corp 5880
0x0A5C:0x5833:Broadcom Corp 5880
0x0A5C:0x5834:Broadcom Corp 5880
# C3PO
0x0783:0x0007:C3PO TLTC2USB
0x0783:0x0009:C3PO KBR36
0x0783:0x0010:C3PO LTC32
0x0783:0x0036:C3PO LTC36
# CASTLES
0x0CA6:0x00A0:CASTLES EZCCID Smart Card Reader
# CCB
0x8829:0xCCB2:CCB eSafeLD
# charismathics
0x19E7:0x0002:charismathics plug'n'crypt CCID token
# Cherry
0x046A:0x0090:Cherry Smart Card Reader USB
0x046A:0x0092:Cherry TC 1300
0x046A:0x00A1:Cherry KC 1000 SC
0x046A:0x00A2:Cherry KC 1000 SC/DI
0x046A:0x00A3:Cherry Smartcard Keyboard G87-1xx44
0x046A:0x00A4:Cherry KC 1000 SC Z
0x046A:0x00A5:Cherry KC 1000 SC/DI Z
0x046A:0x00A7:Cherry SmartTerminal XX44
# Cherry GmbH
0x046A:0x005B:Cherry GmbH SmartBoard XX1X
0x046A:0x0070:Cherry GmbH SmartTerminal XX1X
0x046A:0x0072:Cherry GmbH SmartTerminal ST-1275
# Chicony
0x04F2:0x0967:Chicony USB Smart Card Keyboard
0x03F0:0x114A:Chicony HP USB Smartcard CCID Keyboard KR
0x03F0:0x124A:Chicony HP USB Smartcard CCID Keyboard JP
# COVADIS
0x0982:0x0008:COVADIS VEGA-ALPHA
0x0982:0x0040:COVADIS Auriga
# DUALi
0x1DB2:0x0801:DUALi DE-620 Combi
0x1DB2:0x088B:DUALi DRAGON NFC READER
# eID_R6 001
0x257B:0xD205:eID_R6 001 X8
# Elatec
0x09D8:0x0427:Elatec TWN4 SmartCard NFC
0x09D8:0x0428:Elatec TWN4/B1.06/CPF3.05/S1SC1.32/P (Beta 3)
# ESMART
0x2CE4:0x7479:ESMART Token GOST
# FEITIAN
0x096E:0x0619:FEITIAN iR301
0x096E:0x061A:FEITIAN bR301
0x096E:0x061C:FEITIAN iR301
# Feitian
0x096E:0x0608:Feitian 502-CL
0x096E:0x060D:Feitian R502
0x096E:0x0622:Feitian VR504 VHBR Contactless & Contact Card Reader
0x096E:0x0623:Feitian bR500
0x096E:0x0624:Feitian bR301
0x096E:0x0807:Feitian ePass2003
0x096E:0x080F:Feitian eJAVA Token
# Feitian Technologies
0x096E:0x0505:Feitian Technologies FT SCR310
# Free Software Initiative of Japan
0x234B:0x0000:Free Software Initiative of Japan Gnuk
# FT
0x096E:0x080A:FT ePass2003Auto
0x096E:0x0853:FT U2F CCID KB
0x096E:0x0855:FT CCID KB
0x096E:0x0856:FT U2F CCID
0x096E:0x0859:FT CCID
# Fujitsu
0x0BF8:0x1024:Fujitsu Smartcard Reader D323
# Fujitsu Siemens Computers
0x0BF8:0x1005:Fujitsu Siemens Computers SmartCard Keyboard USB 2A
0x0BF8:0x1006:Fujitsu Siemens Computers SmartCard USB 2A
# FujitsuTechnologySolutions GmbH
0x0BF8:0x1017:FujitsuTechnologySolutions GmbH SmartCase KB SCR eSIG
0x0BF8:0x1021:FujitsuTechnologySolutions GmbH Smartcard Keyboard G87-914x
0x0BF8:0x1022:FujitsuTechnologySolutions GmbH Keyboard KB100 SCR
0x0BF8:0x1023:FujitsuTechnologySolutions GmbH Keyboard KB100 SCR eSIG
# GEMALTO
0x08E6:0x3440:GEMALTO CT1100
# Gemalto
0x08E6:0x2202:Gemalto Gem e-Seal Pro USB Token
0x08E6:0x34C1:Gemalto Ezio Shield Secure Channel
0x08E6:0x34C2:Gemalto Ezio Shield
0x08E6:0x34C5:Gemalto Ezio Shield Branch Reader
0x08E6:0x34EC:Gemalto GemPC Express
0x08E6:0x4042:Gemalto SA .NET Dual
0x08E6:0x5743:Gemalto Hybrid Smartcard Reader
0x08E6:0x8108:Gemalto Smart Enterprise Guardian Secure USB Device
# Gemplus
0x08E6:0x3479:Gemplus GemCore POS Pro Smart Card Reader
# Generic
0x0BDA:0x0169:Generic USB2.0-CRW
0x048D:0x1366:Generic MultiCard Device
# Generic USB
0x076B:0x3A21:Generic USB Smart Card Reader
# German Privacy Foundation
0x20A0:0x4107:German Privacy Foundation Crypto Stick v1.2
# Giesecke & Devrient GmbH
0x1059:0x000C:Giesecke & Devrient GmbH Star Sign Card Token 350 (ICCD)
0x1059:0x000D:Giesecke & Devrient GmbH Star Sign Card Token 550 (ICCD)
# GIS Ltd
0x0F1A:0x0002:GIS Ltd SmartMouse USB
# GoldKey Security
0x19C8:0x0012:GoldKey Security PIV Token
# HDZB
0x1677:0x0025:HDZB uKeyCI800-K18
# Hewlett Packard
0x03F0:0x104A:Hewlett Packard HP USB Smartcard CCID Keyboard
0x03F0:0x2924:Hewlett Packard MFP Smart Card Reader
# Hewlett-Packard
0x03F0:0x581D:Hewlett-Packard HP lt4112 Gobi 4G Module
# HID
# HID Global
0x076B:0x3031:HID Global OMNIKEY 3x21 Smart Card Reader
0x076B:0x5022:HID Global OMNIKEY 5022 Smart Card Reader
0x076B:0x5400:HID Global veriCLASS Reader
0x076B:0x5412:HID Global OMNIKEY 5122 Smartcard Reader
0x076B:0x5422:HID Global OMNIKEY 5422 Smartcard Reader
0x076B:0x5432:HID Global OMNIKEY 5122 Dual
0x076B:0x6632:HID Global OMNIKEY 6121 Smart Card Reader
# HID OMNIKEY
0x076B:0x502A:HID OMNIKEY 5025-CL
0x076B:0x5127:HID OMNIKEY 5127 CK
0x076B:0x5326:HID OMNIKEY 5326 DFR
0x076B:0x5427:HID OMNIKEY 5427 CK
# Hitachi, Ltd.
0x04A4:0x00C7:Hitachi, Ltd. Hitachi Biometric Reader
0x04A4:0x00D4:Hitachi, Ltd. Hitachi Portable Biometric Reader
# id3 Semiconductors
0x0B81:0x0220:id3 Semiconductors CL1356A_HID
# Identiv
0x04E6:0x5713:Identiv CLOUD 2980 F Smart Card Reader
0x04E6:0x5724:Identiv Identiv uTrust 4701 F Dual Interface Reader
0x04E6:0x5790:Identiv uTrust 3700 F CL Reader
0x04E6:0x5791:Identiv uTrust 3701 F CL Reader
0x04E6:0x5811:Identiv uTrust 2900 R Smart Card Reader
0x04E6:0x5812:Identiv uTrust 2910 R Smart Card Reader
0x04E6:0x5814:Identiv SCR3500 A Contact Reader
0x04E6:0x5815:Identiv SCR3500 B Contact Reader
0x04E6:0x5816:Identiv uTrust 3512 SAM slot Token
0x04E6:0x5818:Identiv @MAXX Light2 token
0x04E6:0x5819:Identiv @MAXX ID-1 Smart Card Reader
0x04E6:0x581A:Identiv uTrust 3522 embd SE RFID Token
0x04E6:0x581B:Identiv uTrust 2910 R Taglio SC Reader
0x04E6:0x581C:Identiv SCR35xx USB Smart Card Reader
# Identive
0x04E6:0x5710:Identive CLOUD 2700 F Smart Card Reader
0x04E6:0x5720:Identive Identive CLOUD 4500 F Dual Interface Reader
0x04E6:0x5721:Identive Identive CLOUD 4510 F Contactless + SAM Reader
0x04E6:0x5723:Identive Identive CLOUD 4000 F DTC
0x04E6:0x5810:Identive CLOUD 2700 R Smart Card Reader
0x04E6:0x5817:Identive SCT3522CC token
# Identive Technologies
0x1FFA:0x000C:Identive Technologies Multi-ISO HF Reader - USB
# IID
0x2406:0x6200:IID AT90S064 CCID READER
# IIT
0x03EB:0x9308:IIT E.Key Crystal-1
0x03EB:0x9324:IIT E.Key Almaz-1C
# InfoThink
0x1FC9:0x0102:InfoThink IT-102MU Reader
# Inside Secure
0x2406:0x6300:Inside Secure VaultIC 420 Smart Object
0x2406:0x6301:Inside Secure VaultIC 440 Smart Object
0x2406:0x6302:Inside Secure VaultIC 460 Smart Object
0x2406:0x6403:Inside Secure AT90SCR100
0x2406:0x6404:Inside Secure AT90SCR050
0x2406:0x6407:Inside Secure AT90SCR200
# INSIDE Secure
0x2406:0x6303:INSIDE Secure VaultIC 405 Smart Object
0x2406:0x6305:INSIDE Secure VaultIC 441 Smart Object
# IonIDe
0x076B:0x3B01:IonIDe Smartcard Reader
# KACST
0x2A18:0x5000:KACST HSID Reader
0x2A18:0x5001:KACST HSID Reader Single Storage
0x2A18:0x5002:KACST HSID Reader Dual Storage
# Kapsch TrafficCom
0x28B9:0x0002:Kapsch TrafficCom USB SAM reader
# Kingtrust
0x0483:0x0007:Kingtrust Multi-Reader
# KOBIL Systems
0x0D46:0x3014:KOBIL Systems Smart Token
0x0D46:0x301D:KOBIL Systems IDToken
0x0D46:0x4189:KOBIL Systems mIDentity 4smart
0x0D46:0x41A9:KOBIL Systems mIDentity 4smart AES
0x0D46:0x4289:KOBIL Systems mIDentity visual
0x0D46:0x4389:KOBIL Systems mIDentity fullsize
0x0D46:0x43A9:KOBIL Systems mIDentity fullsize AES
# KRONEGGER
0x2D25:0x0000:KRONEGGER NFC blue Reader Platform
0x2D25:0x0001:KRONEGGER Micro Core Platform
# Ledger
0x2C97:0x0001:Ledger Nano S
# Lenovo
0x17EF:0x6007:Lenovo Lenovo USB Smartcard Keyboard
0x17EF:0x6055:Lenovo Lenovo USB Smartcard Keyboard
# Liteon
0x03F0:0x164A:Liteon HP SC Keyboard - Apollo (Liteon)
0x03F0:0x174A:Liteon HP SC Keyboard - Apollo KR (Liteon)
0x03F0:0x184A:Liteon HP SC Keyboard - Apollo JP (Liteon)
# Macally
0x08AE:0x0BDF:Macally NFC CCID eNetPad
# mCore
0x1403:0x7502:mCore SCard-Reader
# Microchip
0x0424:0x1104:Microchip SEC1110
0x0424:0x1202:Microchip SEC1210
# MK Technology
0x0416:0xC136:MK Technology KeyPass S1
# Morpho
0x079B:0x0026:Morpho MSO350/MSO351 Fingerprint Sensor & SmartCard Reader
0x079B:0x0052:Morpho MSO1350 Fingerprint Sensor & SmartCard Reader
# MSI
0x0BDA:0x0161:MSI StarReader SMART
# Mulann
0x4D55:0x0010:Mulann PVT
# Neowave
0x1E0D:0x0013:Neowave Weneo
0x1E0D:0x0033:Neowave Weneo
0x1E0D:0x1023:Neowave Weneo
0x1E0D:0x8033:Neowave Weneo
# Nitrokey
0x20A0:0x4108:Nitrokey Nitrokey Pro
0x20A0:0x4109:Nitrokey Nitrokey Storage
0x20A0:0x4211:Nitrokey Nitrokey Start
0x20A0:0x4230:Nitrokey Nitrokey HSM
# NTT Communications Corp.
0x04E6:0x511A:NTT Communications Corp. SCR3310-NTTCom USB SmartCard Reader
# NXP
0x1FC9:0x0107:NXP Pegoda 2 N
0x1FC9:0x010B:NXP PR533
# OBERTHUR TECHNOLOGIES
0x1A74:0xB111:OBERTHUR TECHNOLOGIES ID-ONE TOKEN SLIM v2
# OCS ID-One Cosmo Card
0x1A74:0x6354:OCS ID-One Cosmo Card USB Smart Chip Device
# OMNIKEY
0x076B:0x1021:OMNIKEY CardMan 1021
0x076B:0x4321:OMNIKEY CardMan 4321
0x076B:0x5321:OMNIKEY CardMan 5321
0x076B:0x5421:OMNIKEY 5421
0x076B:0x6321:OMNIKEY 6321 CLi USB
# OMNIKEY AG
0x076B:0x3022:OMNIKEY AG 3121 USB
0x076B:0x3621:OMNIKEY AG CardMan 3621
0x076B:0x3821:OMNIKEY AG CardMan 3821
0x076B:0x5121:OMNIKEY AG CardMan 5121
0x076B:0x5125:OMNIKEY AG CardMan 5125
0x076B:0x6622:OMNIKEY AG CardMan 6121
0x076B:0x6623:OMNIKEY AG 6121 USB mobile
0x076B:0xA021:OMNIKEY AG Smart Card Reader
# Panasonic
0x04DA:0x117A:Panasonic Panasonic USB Smart Card Reader 7A-Smart
# Philips Semiconductors
0x0471:0x040F:Philips Semiconductors JCOP41V221
0x04B9:0x1400:Philips Semiconductors SmartMX Sample
# PIVKey
0x096E:0x0603:PIVKey T800
# Planeta
0x21AB:0x0010:Planeta RC700-NFC CCID
# Raritan
0x14DD:0x1006:Raritan D2CIM-DVUSB VM/CCID
# Regula
0x1C6A:0x7050:Regula RFID Reader
# REINER SCT
0x0C4B:0x0500:REINER SCT cyberJack RFID standard
0x0C4B:0x0504:REINER SCT cyberJack go
0x0C4B:0x0520:REINER SCT tanJack Bluetooth
0x0C4B:0x0580:REINER SCT cyberJack one
0x0C4B:0x9102:REINER SCT cyberJack RFID basis
# Rocketek
0x14CD:0x8166:Rocketek RT-SCR1
# SafeNet
0x0529:0x0602:SafeNet eToken 7300
0x0529:0x0620:SafeNet eToken 5100
0x08E6:0x34CC:SafeNet eToken 5300
# SafeTech
0x24A2:0x0102:SafeTech SafeTouch
# SAFETRUST
0x2EE1:0x0001:SAFETRUST SABRE SCR
# SchlumbergerSema
0x0973:0x0003:SchlumbergerSema SchlumbergerSema Cyberflex Access
# SCM Microsystems Inc.
0x04E6:0x5113:SCM Microsystems Inc. SCR33x USB Smart Card Reader
0x04E6:0x5115:SCM Microsystems Inc. SCR 335
0x04E6:0x5117:SCM Microsystems Inc. SCR3320 - Smart Card Reader
0x04E6:0x5119:SCM Microsystems Inc. SCR3340 - ExpressCard54 Smart Card Reader
0x04E6:0x511F:SCM Microsystems Inc. SCR3310 USB Smart Card Reader
0x04E6:0x5120:SCM Microsystems Inc. SCR331-DI USB Smart Card Reader
0x04E6:0x5121:SCM Microsystems Inc. SDI010 Smart Card Reader
0x04E6:0x512B:SCM Microsystems Inc. SDI011 Contactless Reader
0x04E6:0x512C:SCM Microsystems Inc. SDI011 Contactless Reader
0x04E6:0x5291:SCM Microsystems Inc. SCL010 Contactless Reader
0x04E6:0x5293:SCM Microsystems Inc. SCL01x Contactless Reader
# Secure Device Solutions
0x0B81:0x8007:Secure Device Solutions DOMINO-Key TWIN
# SecuTech
0x0403:0xC587:SecuTech SecuTech Token
# Sitecom
0x0DF6:0x800A:Sitecom Sitecom USB simcard reader MD-010
# Softforum Co., Ltd
0x04E8:0x0007:Softforum Co., Ltd XecureHSM
# SpringCard
0x1C34:0x7113:SpringCard CrazyWriter
0x1C34:0x7121:SpringCard CSB6 Basic
0x1C34:0x7123:SpringCard CSB6 Secure
0x1C34:0x7124:SpringCard CSB6 Ultimate
0x1C34:0x7136:SpringCard EasyFinger Standard
0x1C34:0x7138:SpringCard EasyFinger Ultimate
0x1C34:0x7141:SpringCard Prox'N'Roll
0x1C34:0x8141:SpringCard NFC'Roll
0x1C34:0x91B1:SpringCard H663 Series
0x1C34:0xA1A1:SpringCard H512 Series
# Spyrus Inc
0x08DF:0x3201:Spyrus Inc PocketVault P-3X
# SYNNIX
0x1206:0x2105:SYNNIX STD200
# Teridian Semiconductors
0x1862:0x0000:Teridian Semiconductors TSC12xxFV.09
# THURSBY SOFTWARE
0x1976:0x0001:THURSBY SOFTWARE TSS-PK1
# Thursby Software Systems, Inc.
# Tianyu
0xA625:0x0810:Tianyu Smart Card Reader
# Todos
0x0B0C:0x0050:Todos Argos Mini II
0x0B0C:0x0052:Todos CX00
# ubisys
0x19A6:0x0009:ubisys 13.56MHz RFID (CCID)
# udea
0x2A17:0x0001:udea MILKO V1.
# Unicept GmbH
0x2DFF:0x1540:Unicept GmbH AirID USB
0x2DFF:0x1543:Unicept GmbH AirID USB Dongle
# Validy
0x1CF0:0x0001:Validy TokenA sl vt
# VASCO
0x1A44:0x0001:VASCO DP905v1.1
0x1A44:0x0101:VASCO DIGIPASS KEY 101
0x1A44:0x0112:VASCO DIGIPASS KEY 860
0x1A44:0x0115:VASCO DIGIPASS KEY 200
0x1A44:0x0117:VASCO DIGIPASS KEY 860
0x1A44:0x0119:VASCO DIGIPASS KEY 200
0x1A44:0x0120:VASCO DIGIPASS KEY 202
0x1A44:0x0122:VASCO DIGIPASS KEY 202
0x1A44:0x0855:VASCO DP855
0x1A44:0x0865:VASCO DP865
0x1A44:0x0870:VASCO DIGIPASS 870
0x1A44:0x0875:VASCO DIGIPASS 875
0x1A44:0x0920:VASCO DIGIPASS 920
# VMware
0x0E0F:0x0004:VMware Virtual USB CCID
# WatchCNPC
0x163C:0x0406:WatchCNPC USB CCID Key
# Watchdata
0x163C:0x0407:Watchdata USB Key
0x163C:0x0417:Watchdata USB Key
# Watchdata W5181
0x163C:0x0A03:Watchdata W5181
# Winbond
0x0416:0x3815:Winbond CCID SmartCard Controller
# XIRING
# Yubico
0x1050:0x0111:Yubico Yubikey NEO OTP+CCID
0x1050:0x0112:Yubico Yubikey NEO CCID
0x1050:0x0115:Yubico Yubikey NEO U2F+CCID
0x1050:0x0116:Yubico Yubikey NEO OTP+U2F+CCID
0x1050:0x0404:Yubico Yubikey 4 CCID
0x1050:0x0405:Yubico Yubikey 4 OTP+CCID
0x1050:0x0406:Yubico Yubikey 4 U2F+CCID
0x1050:0x0407:Yubico Yubikey 4 OTP+U2F+CCID
##########################
# section: unsupported
##########################
# ACS
0x072F:0x2200:ACS ACR122U PICC Interface
# ActivCard
0x09C3:0x0008:ActivCard ActivCard USB Reader V2
# Aladdin
# Alcor Micro
# Athena
0x0DC3:0x100F:Athena IDProtect Flash
# ATMEL
0x03EB:0x6016:ATMEL VaultIC460
# Broadcom Corp
0x0A5C:0x5800:Broadcom Corp 5880
0x0A5C:0x5801:Broadcom Corp 5880
0x0A5C:0x5805:Broadcom Corp 5880
# C3PO
0x0783:0x0003:C3PO LTC3x USB
# Feitian
0x096E:0x0503:Feitian SCR301
# Generic
0x0BDA:0x0165:Generic Smart Card Reader Interface
# Hewlett-Packard Company
0x03F0:0x0036:Hewlett-Packard Company HP USB CCID Smartcard Keyboard
0x03F0:0x1024:Hewlett-Packard Company HP USB Smart Card Keyboard
# KEBTechnology
0x04CC:0x5072:KEBTechnology KONA USB SmartCard
# KOBIL Systems
0x0D46:0x4000:KOBIL Systems mIDentity M
0x0D46:0x4001:KOBIL Systems mIDentity XL
# O2
0x0B97:0x7762:O2 Micro Oz776
0x0B97:0x7772:O2 Micro Oz776
# Precise Biometrics
0x08C3:0x0401:Precise Biometrics Precise 250 MC
0x08C3:0x0402:Precise Biometrics Precise 200 MC
# RSA
0x15E1:0x2007:RSA RSA SecurID (R) Authenticator
# THRC
0x062D:0x0001:THRC Smart Card Reader
# VMware
##########################
# section: disabled
##########################
# DUALi
#0x1DB2:0x0600:DUALi DE-ABCM6
# HID OMNIKEY
#0x076B:0x5340:HID OMNIKEY 5021 CL
# Jinmuyu Electronics Co., Ltd.
#0x03EB:0x6120:Jinmuyu Electronics Co., Ltd. MR800
# jNet Technology inc.
#0x0483:0x2010:jNet Technology inc. jToken s1
# Morpho
#0x1A6F:0x0104:Morpho ypsID Key E
# MX5
#0x0980:0x902F:MX5 MX5 SMART CCID DRIVER
# OCS ID-One Cosmo Card
#0x1A74:0x6356:OCS ID-One Cosmo Card USB Smart Chip Device
# OMNIKEY
#0x076B:0x532A:OMNIKEY 5321 CLi USB
# Precise Biometrics
#0x08C3:0x0406:Precise Biometrics Precise 200 MC Upgrade
# Reiner-SCT
#0x0C4B:0x0300:Reiner-SCT cyberJack pinpad(a)
# SCM Microsystems Inc.
#0x04E6:0x5292:SCM Microsystems Inc. SCL01x Contactless Reader
# SMART
#0x0B8C:0x000E:SMART SBV280
##########################
# section: duplicates
##########################
#0x046A:0x0090:Cherry Smart Card Reader USB (Cherry_Smart_Card_Reader_USB.txt)
#0x046A:0x0090:Cherry Cherry TC 1100 (Cherry_Smart_Card_Reader_USB_2_04.txt)
#0x04E6:0x5291:SCM Microsystems Inc. SCL010 Contactless Reader (SCL010.txt)
#0x04E6:0x5291:SCM Microsystems Inc. SCL010 Contactless Reader (SCM_SCL010.txt)
#0x04E6:0x5410:SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader (SCR3500.txt)
#0x04E6:0x5410:SCM Microsystems Inc. SCR 355 (SCR355.txt)
#0x04E6:0x5720:Identive Identive CLOUD 4500 F Dual Interface Reader (Identive_CLOUD_4500_F.txt)
#0x04E6:0x5720:Identive Identive CLOUD 4700 F Dual Interface Reader (Identive_CLOUD_4700_F.txt)
#0x04E6:0x5721:Identive Identive CLOUD 4510 F Contactless + SAM Reader (Identive_CLOUD_4510_F.txt)
#0x04E6:0x5721:Identive Identive CLOUD 4710 F Contactless + SAM Reader (Identive_CLOUD_4710_F.txt)
#0x0529:0x0620:Aladdin eToken PRO USB 72K Java (Aladdin_eToken_PRO_USB_72K_Java.txt)
#0x0529:0x0620:SafeNet eToken 5100 (SafeNet_Token_JC.txt)
#0x058F:0x9520:Alcor Micro AU9520 (AU9520.txt)
#0x058F:0x9520:Akasa AK-CR-03 (Akasa_AK-CR-03.txt)
#0x058F:0x9520:Alcor Micro SCR001 (Alcor_SCR001.txt)
#0x058F:0x9540:Alcor Micro AU9540 (AU9540.txt)
#0x058F:0x9540:Alcor Micro AU9560 (AlcorMicro_AU9560.txt)
#0x072F:0x90CC:ACS ACR122U (ACR122U.txt)
#0x072F:0x90CC:ACS ACR 38U-CCID (ACR38U-CCID.txt)
#0x072F:0x90CC:ACS ACR100 (ACS_ACR100.txt)
#0x072F:0x90CC:ACS ACR38 plugin (ACS_ACR38_plugin.txt)
#0x072F:0x90CC:ACS AET65 (ACS_AET65.txt)
#0x073D:0x0C00:Eutron Card Reader (Eutron_SIM_Pocket_Combo_(Card_Reader).txt)
#0x073D:0x0C00:Eutron SIM Reader (Eutron_SIM_Pocket_Combo_(SIM_Reader).txt)
#0x076B:0x3021:OMNIKEY AG CardMan 3021 (CardMan3021.txt)
#0x076B:0x3021:OMNIKEY AG CardMan 3121 (CardMan3121.txt)
#0x076B:0x3A21:Generic USB Smart Card Reader (Generic_USB_Smart_Card_Reader.txt)
#0x076B:0x3A21:HID AVIATOR Generic (HID_Aviator.txt)
#0x076B:0xA022:Precise Biometrics Sense MC (Precise_Sense_MC.txt)
#0x076B:0xA022:XIRING Teo (Teo.txt)
#0x08E6:0x3437:Gemalto PC Twin Reader (GemPCTwin.txt)
#0x08E6:0x3437:Gemalto IDBridge CT30 (Gemalto_IDBridge_CT30.txt)
#0x08E6:0x3437:Gemalto K50 (Gemalto_K50.txt)
#0x08E6:0x3438:Gemalto USB Shell Token V2 (GemPCKey.txt)
#0x08E6:0x3438:Gemalto IDBridge K30 (Gemalto_IDBridge_K30.txt)
#0x08E6:0x3440:GEMALTO CT1100 (Gemalto_CT1100.txt)
#0x08E6:0x3440:GEMALTO K1100 (Gemalto_K1100.txt)
#0x08E6:0x3478:Gemalto USB GemPCPinpad SmartCard Reader (GemPCPinpad.txt)
#0x08E6:0x3478:Gemalto USB GemPCPinpad SmartCard Reader (GemPCPinpadv2.txt)
#0x08E6:0x34C0:Gemalto Ezio Shield (Gemalto_Ezio_Shield.txt)
#0x08E6:0x34C0:Gemalto Ezio Shield Pro SC (Gemalto_Ezio_Shield_Pro_SC.txt)
#0x0A5C:0x5802:Broadcom Corp 5880 (Broadcom_5880v3.txt)
#0x0A5C:0x5802:Broadcom Corp 5880 (Broadcom_5880v4.txt)
#0x0B81:0x0200:id3 Semiconductors CL1356T (id3_CL1356T.txt)
#0x0B81:0x0200:id3 Semiconductors CL1356T5 (id3_CL1356T5.txt)
#0x0E0F:0x0004:VMware Virtual USB CCID (VMware_Virtual_USB_CCID.txt)
#0x0E0F:0x0004:VMware Virtual USB CCID (VMware_Virtual_USB_CCID2.txt)
#0x0F14:0x0011:XIRING XI-SIGN USB V2 (Xiring_XI-SIGN.txt)
#0x0F14:0x0011:XIRING XI-SIGN USB V2 (Xiring_XI-SIGN_6000.txt)
#0x0F14:0x003D:Ingenico WITEO USB Smart Card Reader (Ingenico_WITEO_badge.txt)
#0x0F14:0x003D:Ingenico WITEO USB Smart Card Reader (Ingenico_WITEO_base.txt)

21
src/92_pcscd_ccid.rules Normal file
View File

@ -0,0 +1,21 @@
# udev rules for CCID devices
# Gemplus PCMCIA Card
#SUBSYSTEMS=="pcmcia", DRIVERS=="serial_cs", ACTION=="add", ATTRS{prod_id1}=="Gemplus", ATTRS{prod_id2}=="SerialPort", ATTRS{prod_id3}=="GemPC Card", RUN+="/usr/sbin/pcscd --hotplug"
# If not adding the device, go away
ACTION!="add", GOTO="pcscd_ccid_rules_end"
SUBSYSTEM!="usb", GOTO="pcscd_ccid_rules_end"
ENV{DEVTYPE}!="usb_device", GOTO="pcscd_ccid_rules_end"
# Kobil mIDentity
ATTRS{idVendor}=="0d46", ATTRS{idProduct}=="4081", RUN+="/usr/sbin/Kobil_mIDentity_switch"
# Keep USB autosuspend off for the C3PO LTC31 v1 SmartCard Reader
ATTR{idVendor}=="0783", ATTR{idProduct}=="0003", GOTO="pcscd_ccid_rules_end"
# set USB power management to auto.
ENV{ID_USB_INTERFACES}==":0b0000:", TEST=="power/control", ATTR{power/control}="auto"
# All done
LABEL="pcscd_ccid_rules_end"

121
src/Info.plist.src Normal file
View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>MAGIC_TARGET</string>
<key>CFBundleIdentifier</key>
<string>org.debian.alioth.pcsclite.smartcardccid</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
MAGIC_CLASS
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>MAGIC_VERSION</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.0.1d1</string>
<key>ifdCapabilities</key>
<string>0x00000000</string>
<!-- Possible values for ifdCapabilities bits
1: IFD_GENERATE_HOTPLUG
plugging the reader calls pcscd \-\-hotplug
Default value is 0x00000000
-->
<key>ifdProtocolSupport</key>
<string>0x00000001</string>
<key>ifdVersionNumber</key>
<string>0x00000001</string>
<key>ifdLogLevel</key>
<string>0x0003</string>
<!-- Possible values for ifdLogLevel
1: CRITICAL important error messages
2: INFO informative messages like what reader was detected
4: COMM a dump of all the bytes exchanged between the host and
the reader
8: PERIODIC periodic info when pcscd test if a card is present
(every 1/10 of a second)
The final value is a OR of these values
Default value: 3 (CRITICAL + INFO)
-->
<key>ifdDriverOptions</key>
<string>0x0000</string>
<!-- Possible values for ifdDriverOptions
0x01: DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED
the CCID Exchange command is allowed. You can use it through
SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE, ...)
0x02: DRIVER_OPTION_GEMPC_TWIN_KEY_APDU
If set the GemPC Twin and GemPC Key readers with be configured
so that the T=1 TPDU protocol is done by the firmware instead of
the driver.
This switches the reader in APDU mode and also in EMV mode so
may not work with non EMV cards.
0x04: DRIVER_OPTION_USE_BOGUS_FIRMWARE
Some reader firmwares have bugs. By default the driver refuses
to work with such firmware versions. If your reader is rejected
because of the firmware (log message: "Firmware (x.y) is
bogus!") you can:
- upgrade your reader firmware (not all readers can do that)
or
- get another reader with a new/bugfree firmware
or
- activate this option but you will have problems depending on
the bug
0x08: free
bits 4 & 5: (values 0x00, 0x10, 0x20, 0x30)
0x00: power on the card at 5V, then 1.8V then 3V (default value)
0x10: power on the card at 3V, then 5V then 1.8V
0x20: power on the card at 1.8V, then 3V and then 5V
0x30: let the reader decide
0x40: DRIVER_OPTION_DISABLE_PIN_RETRIES
The Gemalto pinpad reader sends a VERIFY command with no PIN
value in order to retreive the remaining retries from the card.
Some cards (like the OpenPGP card) do not support this.
Default value: 0
-->
<key>ifdManufacturerString</key>
<string>Ludovic Rousseau (ludovic.rousseau@free.fr)</string>
<key>ifdProductString</key>
<string>Generic CCID driver</string>
<key>ifdVendorID</key>
<array>
MAGIC_VENDOR
</array>
<key>ifdProductID</key>
<array>
MAGIC_PRODUCT
</array>
<key>ifdFriendlyName</key>
<array>
MAGIC_FRIENDLYNAME
</array>
<key>Copyright</key>
<string>This driver is protected by terms of the GNU Lesser General Public License version 2.1, or (at your option) any later version.</string>
</dict>
</plist>

110
src/Makefile.am Normal file
View File

@ -0,0 +1,110 @@
CCID_BUNDLE = $(bundle)
CCID_LIB = libccid.$(DYN_LIB_EXT)
CCIDTWIN_LIB = libccidtwin.$(DYN_LIB_EXT)
CCID_VERSION=CCID_VERSION=`$(srcdir)/convert_version.pl $(PACKAGE_VERSION)`
lib_LTLIBRARIES =
LIBS_TO_INSTALL =
LIBS_TO_UNINSTALL =
if WITH_LIBUSB
lib_LTLIBRARIES += libccid.la
LIBS_TO_INSTALL += install_ccid
LIBS_TO_UNINSTALL += uninstall_ccid
noinst_PROGRAMS = parse
endif
if WITH_TWIN_SERIAL
lib_LTLIBRARIES += libccidtwin.la
LIBS_TO_INSTALL += install_ccidtwin
LIBS_TO_UNINSTALL += uninstall_ccidtwin
endif
COMMON = ccid.c \
ccid.h \
ccid_ifdhandler.h \
commands.c \
commands.h \
debug.h \
defs.h \
ifdhandler.c \
utils.c \
utils.h
USB = ccid_usb.c ccid_usb.h
SERIAL = ccid_serial.c ccid_serial.h
T1 = towitoko/atr.c \
towitoko/atr.h \
towitoko/defines.h \
towitoko/pps.c \
towitoko/pps.h \
openct/buffer.c \
openct/buffer.h \
openct/checksum.c \
openct/checksum.h \
openct/proto-t1.c \
openct/proto-t1.h
TOKEN_PARSER = tokenparser.l parser.h \
strlcpy.c \
misc.h \
strlcpycat.h \
simclist.c \
simclist.h
if WITHOUT_PCSC
PROVIDED_BY_PCSC = debug.c
endif
libccid_la_SOURCES = $(COMMON) $(USB) $(TOKEN_PARSER) $(PROVIDED_BY_PCSC) $(T1)
libccid_la_LIBADD = $(LEXLIB) $(LIBUSB_LIBS) $(PTHREAD_LIBS)
libccid_la_CFLAGS = $(PCSC_CFLAGS) $(LIBUSB_CFLAGS) $(PTHREAD_CFLAGS) \
$(SYMBOL_VISIBILITY) -D$(CCID_VERSION) -DSIMCLIST_NO_DUMPRESTORE
libccid_la_LDFLAGS = -avoid-version
libccidtwin_la_SOURCES = $(COMMON) $(SERIAL) $(TOKEN_PARSER) \
$(PROVIDED_BY_PCSC) $(T1)
libccidtwin_la_CFLAGS = $(PCSC_CFLAGS) $(PTHREAD_CFLAGS) $(SYMBOL_VISIBILITY) \
-DTWIN_SERIAL -D$(CCID_VERSION) -DSIMCLIST_NO_DUMPRESTORE
libccidtwin_la_LIBADD = $(PTHREAD_LIBS)
libccidtwin_la_LDFLAGS = -avoid-version
parse_SOURCES = parse.c debug.c ccid_usb.c $(TOKEN_PARSER)
parse_LDADD = $(LIBUSB_LIBS)
parse_CFLAGS = $(PCSC_CFLAGS) $(LIBUSB_CFLAGS) -DSIMCLIST_NO_DUMPRESTORE
EXTRA_DIST = Info.plist.src create_Info_plist.pl reader.conf.in \
towitoko/COPYING towitoko/README openct/LICENSE openct/README \
convert_version.pl 92_pcscd_ccid.rules
# We can't use install-exec-local since we want to overwrite the install
# rule. We do not want to _add_ files to install
install: $(LIBS_TO_INSTALL)
INSTALL_UDEV_RULE_FILE=@/bin/echo "***************" ; echo "copy the src/92_pcscd_ccid.rules file in udev directory (/etc/udev/rules.d/)" ; /bin/echo "***************"
Info.plist: Info.plist.src $(srcdir)/../readers/supported_readers.txt
$(srcdir)/create_Info_plist.pl $(srcdir)/../readers/supported_readers.txt $(srcdir)/Info.plist.src --target=$(CCID_LIB) --version=$(VERSION) $(NOCLASS) > Info.plist
DISTCLEANFILES = tokenparser.c Info.plist
install_ccid: libccid.la Info.plist
$(mkinstalldirs) "$(DESTDIR)$(usbdropdir)/$(CCID_BUNDLE)/Contents/$(BUNDLE_HOST)/"
cp Info.plist "$(DESTDIR)$(usbdropdir)/$(CCID_BUNDLE)/Contents/"
cp .libs/$(CCID_LIB) "$(DESTDIR)$(usbdropdir)/$(CCID_BUNDLE)/Contents/$(BUNDLE_HOST)/$(CCID_LIB)"
$(INSTALL_UDEV_RULE_FILE)
install_ccidtwin: libccidtwin.la
$(mkinstalldirs) "$(DESTDIR)$(ccidtwindir)"
cp .libs/$(CCIDTWIN_LIB) "$(DESTDIR)$(ccidtwindir)/$(CCIDTWIN_LIB)"
$(mkinstalldirs) "$(DESTDIR)/$(serialconfdir)" ; \
perl -ne "s|TARGET|$(ccidtwindir)/$(CCIDTWIN_LIB)| ; print" $(srcdir)/reader.conf.in > "$(DESTDIR)/$(serialconfdir)/libccidtwin"
# do not uninstall the serial driver by default
# use explicitely 'make uninstall_ccidtwin'
uninstall: $(LIBS_TO_UNINSTALL)
uninstall_ccid:
rm -rf "$(DESTDIR)$(usbdropdir)/$(CCID_BUNDLE)"
uninstall_ccidtwin:
rm -f "$(DESTDIR)$(ccidtwindir)/$(CCIDTWIN_LIB)"
rm -f "$(DESTDIR)/$(serialconfdir)/libccidtwin"

1217
src/Makefile.in Normal file

File diff suppressed because it is too large Load Diff

699
src/ccid.c Normal file
View File

@ -0,0 +1,699 @@
/*
ccid.c: CCID common code
Copyright (C) 2003-2010 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <config.h>
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <pcsclite.h>
#include <ifdhandler.h>
#include "debug.h"
#include "ccid.h"
#include "defs.h"
#include "ccid_ifdhandler.h"
#include "commands.h"
#include "utils.h"
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#endif
/*****************************************************************************
*
* ccid_open_hack_pre
*
****************************************************************************/
int ccid_open_hack_pre(unsigned int reader_index)
{
_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
switch (ccid_descriptor->readerID)
{
case MYSMARTPAD:
ccid_descriptor->dwMaxIFSD = 254;
break;
case CL1356D:
/* the firmware needs some time to initialize */
(void)sleep(1);
ccid_descriptor->readTimeout = 60*1000; /* 60 seconds */
break;
#ifdef ENABLE_ZLP
case GEMPCTWIN:
case GEMPCKEY:
case DELLSCRK:
/* Only the chipset with firmware version 2.00 is "bogus"
* The reader may send packets of 0 bytes when the reader is
* connected to a USB 3 port */
if (0x0200 == ccid_descriptor->IFD_bcdDevice)
{
ccid_descriptor->zlp = TRUE;
DEBUG_INFO1("ZLP fixup");
}
break;
#endif
case OZ776:
case OZ776_7772:
ccid_descriptor->dwMaxDataRate = 9600;
break;
case ElatecTWN4_CCID_CDC:
case ElatecTWN4_CCID:
/* Use a timeout of 1000 ms instead of 100 ms in
* CmdGetSlotStatus() used by CreateChannelByNameOrChannel()
* The reader answers after up to 1 s if no tag is present */
ccid_descriptor->readTimeout = DEFAULT_COM_READ_TIMEOUT * 10;
break;
case SCM_SCL011:
/* The SCM SCL011 reader needs 350 ms to answer */
ccid_descriptor->readTimeout = DEFAULT_COM_READ_TIMEOUT * 4;
break;
}
/* CCID */
if ((PROTOCOL_CCID == ccid_descriptor->bInterfaceProtocol)
&& (3 == ccid_descriptor -> bNumEndpoints))
{
#ifndef TWIN_SERIAL
/* just wait for 100ms in case a notification is in the pipe */
(void)InterruptRead(reader_index, 100);
#endif
}
/* ICCD type A */
if (PROTOCOL_ICCD_A == ccid_descriptor->bInterfaceProtocol)
{
unsigned char tmp[MAX_ATR_SIZE];
unsigned int n = sizeof(tmp);
DEBUG_COMM("ICCD type A");
(void)CmdPowerOff(reader_index);
(void)CmdPowerOn(reader_index, &n, tmp, CCID_CLASS_AUTO_VOLTAGE);
(void)CmdPowerOff(reader_index);
}
/* ICCD type B */
if (PROTOCOL_ICCD_B == ccid_descriptor->bInterfaceProtocol)
{
unsigned char tmp[MAX_ATR_SIZE];
unsigned int n = sizeof(tmp);
DEBUG_COMM("ICCD type B");
if (CCID_CLASS_SHORT_APDU ==
(ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK))
{
/* use the extended APDU comm alogorithm */
ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
ccid_descriptor->dwFeatures |= CCID_CLASS_EXTENDED_APDU;
}
(void)CmdPowerOff(reader_index);
(void)CmdPowerOn(reader_index, &n, tmp, CCID_CLASS_AUTO_VOLTAGE);
(void)CmdPowerOff(reader_index);
}
return 0;
} /* ccid_open_hack_pre */
#ifndef NO_LOG
/*****************************************************************************
*
* dump_gemalto_firmware_features
*
****************************************************************************/
static void dump_gemalto_firmware_features(struct GEMALTO_FIRMWARE_FEATURES *gff)
{
DEBUG_INFO2("Dumping Gemalto firmware features (%zd bytes):",
sizeof(struct GEMALTO_FIRMWARE_FEATURES));
#define YESNO(x) (x) ? "yes" : "no"
DEBUG_INFO2(" bLogicalLCDLineNumber: %d", gff->bLogicalLCDLineNumber);
DEBUG_INFO2(" bLogicalLCDRowNumber: %d", gff->bLogicalLCDRowNumber);
DEBUG_INFO2(" bLcdInfo: 0x%02X", gff->bLcdInfo);
DEBUG_INFO2(" bEntryValidationCondition: 0x%02X",
gff->bEntryValidationCondition);
DEBUG_INFO1(" Reader supports PC/SCv2 features:");
DEBUG_INFO2(" VerifyPinStart: %s", YESNO(gff->VerifyPinStart));
DEBUG_INFO2(" VerifyPinFinish: %s", YESNO(gff->VerifyPinFinish));
DEBUG_INFO2(" ModifyPinStart: %s", YESNO(gff->ModifyPinStart));
DEBUG_INFO2(" ModifyPinFinish: %s", YESNO(gff->ModifyPinFinish));
DEBUG_INFO2(" GetKeyPressed: %s", YESNO(gff->GetKeyPressed));
DEBUG_INFO2(" VerifyPinDirect: %s", YESNO(gff->VerifyPinDirect));
DEBUG_INFO2(" ModifyPinDirect: %s", YESNO(gff->ModifyPinDirect));
DEBUG_INFO2(" Abort: %s", YESNO(gff->Abort));
DEBUG_INFO2(" GetKey: %s", YESNO(gff->GetKey));
DEBUG_INFO2(" WriteDisplay: %s", YESNO(gff->WriteDisplay));
DEBUG_INFO2(" SetSpeMessage: %s", YESNO(gff->SetSpeMessage));
DEBUG_INFO2(" bTimeOut2: %s", YESNO(gff->bTimeOut2));
DEBUG_INFO2(" bPPDUSupportOverXferBlock: %s",
YESNO(gff->bPPDUSupportOverXferBlock));
DEBUG_INFO2(" bPPDUSupportOverEscape: %s",
YESNO(gff->bPPDUSupportOverEscape));
DEBUG_INFO2(" bListSupportedLanguages: %s",
YESNO(gff->bListSupportedLanguages));
DEBUG_INFO2(" bNumberMessageFix: %s", YESNO(gff->bNumberMessageFix));
DEBUG_INFO2(" VersionNumber: 0x%02X", gff->VersionNumber);
DEBUG_INFO2(" MinimumPINSize: %d", gff->MinimumPINSize);
DEBUG_INFO2(" MaximumPINSize: %d", gff->MaximumPINSize);
DEBUG_INFO2(" Firewall: %s", YESNO(gff->Firewall));
if (gff->Firewall && gff->FirewalledCommand_SW1
&& gff->FirewalledCommand_SW2)
{
DEBUG_INFO2(" FirewalledCommand_SW1: 0x%02X",
gff->FirewalledCommand_SW1);
DEBUG_INFO2(" FirewalledCommand_SW2: 0x%02X",
gff->FirewalledCommand_SW2);
}
} /* dump_gemalto_firmware_features */
#endif
/*****************************************************************************
*
* set_gemalto_firmware_features
*
****************************************************************************/
static void set_gemalto_firmware_features(unsigned int reader_index)
{
_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
struct GEMALTO_FIRMWARE_FEATURES *gf_features;
gf_features = malloc(sizeof(struct GEMALTO_FIRMWARE_FEATURES));
if (gf_features)
{
unsigned char cmd[] = { 0x6A }; /* GET_FIRMWARE_FEATURES command id */
unsigned int len_features = sizeof *gf_features;
RESPONSECODE ret;
ret = CmdEscapeCheck(reader_index, cmd, sizeof cmd,
(unsigned char*)gf_features, &len_features, 0, TRUE);
if ((IFD_SUCCESS == ret) &&
(len_features == sizeof *gf_features))
{
/* Command is supported if it succeeds at CCID level */
/* and returned size matches our expectation */
ccid_descriptor->gemalto_firmware_features = gf_features;
#ifndef NO_LOG
dump_gemalto_firmware_features(gf_features);
#endif
}
else
{
/* Command is not supported, let's free allocated memory */
free(gf_features);
DEBUG_INFO3("GET_FIRMWARE_FEATURES failed: " DWORD_D ", len=%d",
ret, len_features);
}
}
} /* set_gemalto_firmware_features */
/*****************************************************************************
*
* ccid_open_hack_post
*
****************************************************************************/
int ccid_open_hack_post(unsigned int reader_index)
{
_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
RESPONSECODE return_value = IFD_SUCCESS;
switch (ccid_descriptor->readerID)
{
case GEMPCKEY:
case GEMPCTWIN:
/* Reader announces TPDU but can do APDU (EMV in fact) */
if (DriverOptions & DRIVER_OPTION_GEMPC_TWIN_KEY_APDU)
{
unsigned char cmd[] = { 0x1F, 0x02 };
unsigned char res[10];
unsigned int length_res = sizeof(res);
if (CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res, 0) == IFD_SUCCESS)
{
ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
}
}
break;
case VEGAALPHA:
case GEMPCPINPAD:
/* load the l10n strings in the pinpad memory */
{
#define L10N_HEADER_SIZE 5
#define L10N_STRING_MAX_SIZE 16
#define L10N_NB_STRING 10
unsigned char cmd[L10N_HEADER_SIZE + L10N_NB_STRING * L10N_STRING_MAX_SIZE];
unsigned char res[20];
unsigned int length_res = sizeof(res);
int offset, i, j;
const char *fr[] = {
"Entrer PIN",
"Nouveau PIN",
"Confirmer PIN",
"PIN correct",
"PIN Incorrect !",
"Delai depasse",
"* essai restant",
"Inserer carte",
"Erreur carte",
"PIN bloque" };
const char *de[] = {
"PIN eingeben",
"Neue PIN",
"PIN bestatigen",
"PIN korrect",
"Falsche PIN !",
"Zeit abgelaufen",
"* Versuche ubrig",
"Karte einstecken",
"Fehler Karte",
"PIN blockiert" };
const char *es[] = {
"Introducir PIN",
"Nuevo PIN",
"Confirmar PIN",
"PIN OK",
"PIN Incorrecto !",
"Tiempo Agotado",
"* ensayos quedan",
"Introducir Tarj.",
"Error en Tarjeta",
"PIN bloqueado" };
const char *it[] = {
"Inserire PIN",
"Nuovo PIN",
"Confermare PIN",
"PIN Corretto",
"PIN Errato !",
"Tempo scaduto",
"* prove rimaste",
"Inserire Carta",
"Errore Carta",
"PIN ostruito"};
const char *pt[] = {
"Insira PIN",
"Novo PIN",
"Conf. novo PIN",
"PIN OK",
"PIN falhou!",
"Tempo expirou",
"* tentiv. restam",
"Introduza cartao",
"Erro cartao",
"PIN bloqueado" };
const char *nl[] = {
"Inbrengen code",
"Nieuwe code",
"Bevestig code",
"Code aanvaard",
"Foute code",
"Time out",
"* Nog Pogingen",
"Kaart inbrengen",
"Kaart fout",
"Kaart blok" };
const char *tr[] = {
"PIN Giriniz",
"Yeni PIN",
"PIN Onayala",
"PIN OK",
"Yanlis PIN",
"Zaman Asimi",
"* deneme kaldi",
"Karti Takiniz",
"Kart Hatasi",
"Kart Kilitli" };
const char *en[] = {
"Enter PIN",
"New PIN",
"Confirm PIN",
"PIN OK",
"Incorrect PIN!",
"Time Out",
"* retries left",
"Insert Card",
"Card Error",
"PIN blocked" };
const char *lang;
const char **l10n;
#ifdef __APPLE__
CFArrayRef cfa;
CFStringRef slang;
/* Get the complete ordered list */
cfa = CFLocaleCopyPreferredLanguages();
/* Use the first/preferred language
* As the driver is run as root we get the language
* selected during install */
slang = CFArrayGetValueAtIndex(cfa, 0);
/* CFString -> C string */
lang = CFStringGetCStringPtr(slang, kCFStringEncodingMacRoman);
#else
/* The other Unixes just use the LANG env variable */
lang = getenv("LANG");
#endif
DEBUG_COMM2("Using lang: %s", lang);
if (NULL == lang)
l10n = en;
else
{
if (0 == strncmp(lang, "fr", 2))
l10n = fr;
else if (0 == strncmp(lang, "de", 2))
l10n = de;
else if (0 == strncmp(lang, "es", 2))
l10n = es;
else if (0 == strncmp(lang, "it", 2))
l10n = it;
else if (0 == strncmp(lang, "pt", 2))
l10n = pt;
else if (0 == strncmp(lang, "nl", 2))
l10n = nl;
else if (0 == strncmp(lang, "tr", 2))
l10n = tr;
else
l10n = en;
}
#ifdef __APPLE__
/* Release the allocated array */
CFRelease(cfa);
#endif
offset = 0;
cmd[offset++] = 0xB2; /* load strings */
cmd[offset++] = 0xA0; /* address of the memory */
cmd[offset++] = 0x00; /* address of the first byte */
cmd[offset++] = 0x4D; /* magic value */
cmd[offset++] = 0x4C; /* magic value */
/* for each string */
for (i=0; i<L10N_NB_STRING; i++)
{
/* copy the string */
for (j=0; l10n[i][j]; j++)
cmd[offset++] = l10n[i][j];
/* pad with " " */
for (; j<L10N_STRING_MAX_SIZE; j++)
cmd[offset++] = ' ';
}
(void)sleep(1);
if (IFD_SUCCESS == CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res, DEFAULT_COM_READ_TIMEOUT))
{
DEBUG_COMM("l10n string loaded successfully");
}
else
{
DEBUG_COMM("Failed to load l10n strings");
return_value = IFD_COMMUNICATION_ERROR;
}
if (DriverOptions & DRIVER_OPTION_DISABLE_PIN_RETRIES)
{
/* disable VERIFY from reader */
const unsigned char cmd2[] = {0xb5, 0x00};
length_res = sizeof(res);
if (IFD_SUCCESS == CmdEscape(reader_index, cmd2, sizeof(cmd2), res, &length_res, DEFAULT_COM_READ_TIMEOUT))
{
DEBUG_COMM("Disable SPE retry counter successful");
}
else
{
DEBUG_CRITICAL("Failed to disable SPE retry counter");
}
}
}
break;
case HPSMARTCARDKEYBOARD:
case HP_CCIDSMARTCARDKEYBOARD:
case FUJITSUSMARTKEYB:
/* the Secure Pin Entry is bogus so disable it
* https://web.archive.org/web/20120320001756/http://martinpaljak.net/2011/03/19/insecure-hp-usb-smart-card-keyboard/
*
* The problem is that the PIN code entered using the Secure
* Pin Entry function is also sent to the host.
*/
ccid_descriptor->bPINSupport = 0;
break;
case HID_AVIATOR: /* OMNIKEY Generic */
case HID_OMNIKEY_3X21: /* OMNIKEY 3121 or 3021 or 1021 */
case HID_OMNIKEY_6121: /* OMNIKEY 6121 */
case CHERRY_XX44: /* Cherry Smart Terminal xx44 */
case FUJITSU_D323: /* Fujitsu Smartcard Reader D323 */
/* The chip advertises pinpad but actually doesn't have one */
ccid_descriptor->bPINSupport = 0;
/* Firmware uses chaining */
ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
ccid_descriptor->dwFeatures |= CCID_CLASS_EXTENDED_APDU;
break;
#if 0
/* SCM SCR331-DI contactless */
case SCR331DI:
/* SCM SCR331-DI-NTTCOM contactless */
case SCR331DINTTCOM:
/* SCM SDI010 contactless */
case SDI010:
/* the contactless reader is in the second slot */
if (ccid_descriptor->bCurrentSlotIndex > 0)
{
unsigned char cmd1[] = { 0x00 };
/* command: 00 ??
* response: 06 10 03 03 00 00 00 01 FE FF FF FE 01 ?? */
unsigned char cmd2[] = { 0x02 };
/* command: 02 ??
* response: 00 ?? */
unsigned char res[20];
unsigned int length_res = sizeof(res);
if ((IFD_SUCCESS == CmdEscape(reader_index, cmd1, sizeof(cmd1), res, &length_res, 0))
&& (IFD_SUCCESS == CmdEscape(reader_index, cmd2, sizeof(cmd2), res, &length_res, 0)))
{
DEBUG_COMM("SCM SCR331-DI contactless detected");
}
else
{
DEBUG_COMM("SCM SCR331-DI contactless init failed");
}
/* hack since the contactless reader do not share dwFeatures */
ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
ccid_descriptor->dwFeatures |= CCID_CLASS_AUTO_IFSD;
}
break;
#endif
case CHERRY_KC1000SC:
if ((0x0100 == ccid_descriptor->IFD_bcdDevice)
&& (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK) == CCID_CLASS_SHORT_APDU)
{
/* firmware 1.00 is bogus
* With a T=1 card and case 2 APDU (data from card to
* host) the maximum size returned by the reader is 128
* byes. The reader is then using chaining as with
* extended APDU.
*/
ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
ccid_descriptor->dwFeatures |= CCID_CLASS_EXTENDED_APDU;
}
break;
case ElatecTWN4_CCID_CDC:
case ElatecTWN4_CCID:
case SCM_SCL011:
/* restore default timeout (modified in ccid_open_hack_pre()) */
ccid_descriptor->readTimeout = DEFAULT_COM_READ_TIMEOUT;
break;
}
/* Gemalto readers may report additional information */
if (GET_VENDOR(ccid_descriptor->readerID) == VENDOR_GEMALTO)
set_gemalto_firmware_features(reader_index);
return return_value;
} /* ccid_open_hack_post */
/*****************************************************************************
*
* ccid_error
*
****************************************************************************/
void ccid_error(int log_level, int error, const char *file, int line,
const char *function)
{
#ifndef NO_LOG
const char *text;
char var_text[30];
switch (error)
{
case 0x00:
text = "Command not supported or not allowed";
break;
case 0x01:
text = "Wrong command length";
break;
case 0x05:
text = "Invalid slot number";
break;
case 0xA2:
text = "Card short-circuiting. Card powered off";
break;
case 0xA3:
text = "ATR too long (> 33)";
break;
case 0xAB:
text = "No data exchanged";
break;
case 0xB0:
text = "Reader in EMV mode and T=1 message too long";
break;
case 0xBB:
text = "Protocol error in EMV mode";
break;
case 0xBD:
text = "Card error during T=1 exchange";
break;
case 0xBE:
text = "Wrong APDU command length";
break;
case 0xE0:
text = "Slot busy";
break;
case 0xEF:
text = "PIN cancelled";
break;
case 0xF0:
text = "PIN timeout";
break;
case 0xF2:
text = "Busy with autosequence";
break;
case 0xF3:
text = "Deactivated protocol";
break;
case 0xF4:
text = "Procedure byte conflict";
break;
case 0xF5:
text = "Class not supported";
break;
case 0xF6:
text = "Protocol not supported";
break;
case 0xF7:
text = "Invalid ATR checksum byte (TCK)";
break;
case 0xF8:
text = "Invalid ATR first byte";
break;
case 0xFB:
text = "Hardware error";
break;
case 0xFC:
text = "Overrun error";
break;
case 0xFD:
text = "Parity error during exchange";
break;
case 0xFE:
text = "Card absent or mute";
break;
case 0xFF:
text = "Activity aborted by Host";
break;
default:
if ((error >= 1) && (error <= 127))
(void)snprintf(var_text, sizeof(var_text), "error on byte %d",
error);
else
(void)snprintf(var_text, sizeof(var_text),
"Unknown CCID error: 0x%02X", error);
text = var_text;
break;
}
log_msg(log_level, "%s:%d:%s %s", file, line, function, text);
#endif
} /* ccid_error */

353
src/ccid.h Normal file
View File

@ -0,0 +1,353 @@
/*
ccid.h: CCID structures
Copyright (C) 2003-2010 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
typedef struct
{
/*
* CCID Sequence number
*/
unsigned char *pbSeq;
unsigned char real_bSeq;
/*
* VendorID << 16 + ProductID
*/
int readerID;
/*
* Maximum message length
*/
unsigned int dwMaxCCIDMessageLength;
/*
* Maximum IFSD
*/
int dwMaxIFSD;
/*
* Features supported by the reader (directly from Class Descriptor)
*/
int dwFeatures;
/*
* PIN support of the reader (directly from Class Descriptor)
*/
char bPINSupport;
/*
* Display dimensions of the reader (directly from Class Descriptor)
*/
unsigned int wLcdLayout;
/*
* Default Clock
*/
int dwDefaultClock;
/*
* Max Data Rate
*/
unsigned int dwMaxDataRate;
/*
* Number of available slots
*/
char bMaxSlotIndex;
/*
* Slot in use
*/
char bCurrentSlotIndex;
/*
* The array of data rates supported by the reader
*/
unsigned int *arrayOfSupportedDataRates;
/*
* Read communication port timeout
* value is milliseconds
* this value can evolve dynamically if card request it (time processing).
*/
unsigned int readTimeout;
/*
* Card protocol
*/
int cardProtocol;
/*
* bInterfaceProtocol (CCID, ICCD-A, ICCD-B)
*/
int bInterfaceProtocol;
/*
* bNumEndpoints
*/
int bNumEndpoints;
/*
* GemCore SIM PRO slot status management
* The reader always reports a card present even if no card is inserted.
* If the Power Up fails the driver will report IFD_ICC_NOT_PRESENT instead
* of IFD_ICC_PRESENT
*/
int dwSlotStatus;
/*
* bVoltageSupport (bit field)
* 1 = 5.0V
* 2 = 3.0V
* 4 = 1.8V
*/
int bVoltageSupport;
/*
* USB serial number of the device (if any)
*/
char *sIFD_serial_number;
/*
* USB iManufacturer string
*/
char *sIFD_iManufacturer;
/*
* USB bcdDevice
*/
int IFD_bcdDevice;
/*
* Gemalto extra features, if any
*/
struct GEMALTO_FIRMWARE_FEATURES *gemalto_firmware_features;
#ifdef ENABLE_ZLP
/*
* Zero Length Packet fixup (boolean)
*/
char zlp;
#endif
} _ccid_descriptor;
/* Features from dwFeatures */
#define CCID_CLASS_AUTO_CONF_ATR 0x00000002
#define CCID_CLASS_AUTO_ACTIVATION 0x00000004
#define CCID_CLASS_AUTO_VOLTAGE 0x00000008
#define CCID_CLASS_AUTO_BAUD 0x00000020
#define CCID_CLASS_AUTO_PPS_PROP 0x00000040
#define CCID_CLASS_AUTO_PPS_CUR 0x00000080
#define CCID_CLASS_AUTO_IFSD 0x00000400
#define CCID_CLASS_CHARACTER 0x00000000
#define CCID_CLASS_TPDU 0x00010000
#define CCID_CLASS_SHORT_APDU 0x00020000
#define CCID_CLASS_EXTENDED_APDU 0x00040000
#define CCID_CLASS_EXCHANGE_MASK 0x00070000
/* Features from bPINSupport */
#define CCID_CLASS_PIN_VERIFY 0x01
#define CCID_CLASS_PIN_MODIFY 0x02
/* See CCID specs ch. 4.2.1 */
#define CCID_ICC_PRESENT_ACTIVE 0x00 /* 00 0000 00 */
#define CCID_ICC_PRESENT_INACTIVE 0x01 /* 00 0000 01 */
#define CCID_ICC_ABSENT 0x02 /* 00 0000 10 */
#define CCID_ICC_STATUS_MASK 0x03 /* 00 0000 11 */
#define CCID_COMMAND_FAILED 0x40 /* 01 0000 00 */
#define CCID_TIME_EXTENSION 0x80 /* 10 0000 00 */
/* bInterfaceProtocol for ICCD */
#define PROTOCOL_CCID 0 /* plain CCID */
#define PROTOCOL_ICCD_A 1 /* ICCD Version A */
#define PROTOCOL_ICCD_B 2 /* ICCD Version B */
/* Product identification for special treatments */
#define GEMPC433 0x08E64433
#define GEMPCKEY 0x08E63438
#define GEMPCTWIN 0x08E63437
#define GEMPCPINPAD 0x08E63478
#define GEMCORESIMPRO 0x08E63480
#define GEMCORESIMPRO2 0x08E60000 /* Does NOT match a real VID/PID as new firmware release exposes same VID/PID */
#define GEMCOREPOSPRO 0x08E63479
#define GEMALTOPROXDU 0x08E65503
#define GEMALTOPROXSU 0x08E65504
#define GEMALTO_EZIO_CBP 0x08E634C3
#define CARDMAN3121 0x076B3021
#define LTC31 0x07830003
#define SCR331DI 0x04E65111
#define SCR331DINTTCOM 0x04E65120
#define SDI010 0x04E65121
#define SEC1210 0x04241202
#define CHERRYXX33 0x046A0005
#define CHERRYST2000 0x046A003E
#define OZ776 0x0B977762
#define OZ776_7772 0x0B977772
#define SPR532 0x04E6E003
#define MYSMARTPAD 0x09BE0002
#define CHERRYXX44 0x046a0010
#define CL1356D 0x0B810200
#define REINER_SCT 0x0C4B0300
#define SEG 0x08E68000
#define BLUDRIVEII_CCID 0x1B0E1078
#define DELLSCRK 0x413C2101
#define DELLSK 0x413C2100
#define KOBIL_TRIBANK 0x0D463010
#define KOBIL_MIDENTITY_VISUAL 0x0D464289
#define VEGAALPHA 0x09820008
#define HPSMARTCARDKEYBOARD 0x03F01024
#define HP_CCIDSMARTCARDKEYBOARD 0x03F00036
#define KOBIL_IDTOKEN 0x0D46301D
#define FUJITSUSMARTKEYB 0x0BF81017
#define FEITIANR502DUAL 0x096E060D
#define MICROCHIP_SEC1100 0x04241104
#define CHERRY_KC1000SC 0x046A00A1
#define ElatecTWN4_CCID_CDC 0x09D80427
#define ElatecTWN4_CCID 0x09D80428
#define SCM_SCL011 0x04E65293
#define HID_AVIATOR 0x076B3A21
#define HID_OMNIKEY_5422 0x076B5422
#define HID_OMNIKEY_3X21 0x076B3031 /* OMNIKEY 3121 or 3021 or 1021 */
#define HID_OMNIKEY_6121 0x076B6632 /* OMNIKEY 6121 */
#define CHERRY_XX44 0x046A00A7 /* Cherry Smart Terminal xx44 */
#define FUJITSU_D323 0x0BF81024 /* Fujitsu Smartcard Reader D323 */
#define VENDOR_GEMALTO 0x08E6
#define GET_VENDOR(readerID) ((readerID >> 16) & 0xFFFF)
/*
* The O2Micro OZ776S reader has a wrong USB descriptor
* The extra[] field is associated with the last endpoint instead of the
* main USB descriptor
*/
#define O2MICRO_OZ776_PATCH
/* Escape sequence codes */
#define ESC_GEMPC_SET_ISO_MODE 1
#define ESC_GEMPC_SET_APDU_MODE 2
/*
* Possible values :
* 3 -> 1.8V, 3V, 5V
* 2 -> 3V, 5V, 1.8V
* 1 -> 5V, 1.8V, 3V
* 0 -> automatic (selection made by the reader)
*/
/*
* The default is to start at 5V
* otherwise we would have to parse the ATR and get the value of TAi (i>2) when
* in T=15
*/
#define VOLTAGE_AUTO 0
#define VOLTAGE_5V 1
#define VOLTAGE_3V 2
#define VOLTAGE_1_8V 3
int ccid_open_hack_pre(unsigned int reader_index);
int ccid_open_hack_post(unsigned int reader_index);
void ccid_error(int log_level, int error, const char *file, int line,
const char *function);
_ccid_descriptor *get_ccid_descriptor(unsigned int reader_index);
/* convert a 4 byte integer in USB format into an int */
#define dw2i(a, x) (unsigned int)((((((a[x+3] << 8) + a[x+2]) << 8) + a[x+1]) << 8) + a[x])
/* all the data rates specified by ISO 7816-3 Fi/Di tables */
#define ISO_DATA_RATES 10753, 14337, 15625, 17204, \
20833, 21505, 23438, 25806, 28674, \
31250, 32258, 34409, 39063, 41667, \
43011, 46875, 52083, 53763, 57348, \
62500, 64516, 68817, 71685, 78125, \
83333, 86022, 93750, 104167, 107527, \
114695, 125000, 129032, 143369, 156250, \
166667, 172043, 215054, 229391, 250000, \
344086
/* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
#define GEMPLUS_CUSTOM_DATA_RATES 10753, 21505, 43011, 125000
/* data rates for GemCore SIM Pro 2 */
#define SIMPRO2_ISO_DATA_RATES 8709, 10322, 12403, 12500, \
12903, 17204, 18750, 20645, 24806, \
25000, 25806, 28125, 30967, 34408, \
37500, 41290, 46875, 49612, 50000, \
51612, 56250, 62500, 64516, 68817, \
74418, 75000, 82580, 86021, 93750, \
99224, 100000, 103225, 112500, 124031, \
125000, 137634, 150000, 154838, 165161, \
172043, 187500, 198449, 200000, 206451, \
258064, 275268, 300000, 396899, 400000, \
412903, 550537, 600000, 825806
/* Structure returned by Gemalto readers for the CCID Escape command 0x6A */
struct GEMALTO_FIRMWARE_FEATURES
{
unsigned char bLogicalLCDLineNumber; /* Logical number of LCD lines */
unsigned char bLogicalLCDRowNumber; /* Logical number of characters per LCD line */
unsigned char bLcdInfo; /* b0 indicates if scrolling is available */
unsigned char bEntryValidationCondition; /* See PIN_PROPERTIES */
/* Here come the PC/SC bit features to report */
unsigned char VerifyPinStart:1;
unsigned char VerifyPinFinish:1;
unsigned char ModifyPinStart:1;
unsigned char ModifyPinFinish:1;
unsigned char GetKeyPressed:1;
unsigned char VerifyPinDirect:1;
unsigned char ModifyPinDirect:1;
unsigned char Abort:1;
unsigned char GetKey:1;
unsigned char WriteDisplay:1;
unsigned char SetSpeMessage:1;
unsigned char RFUb1:5;
unsigned char RFUb2[2];
/* Additional flags */
unsigned char bTimeOut2:1;
unsigned char bListSupportedLanguages:1; /* Reader is able to indicate
the list of supported languages through CCID-ESC 0x6B */
unsigned char bNumberMessageFix:1; /* Reader handles correctly shifts
made by bNumberMessage in PIN modification data structure */
unsigned char bPPDUSupportOverXferBlock:1; /* Reader supports PPDU over
PC_to_RDR_XferBlock command */
unsigned char bPPDUSupportOverEscape:1; /* Reader supports PPDU over
PC_to_RDR_Escape command with abData[0]=0xFF */
unsigned char RFUb3:3;
unsigned char RFUb4[3];
unsigned char VersionNumber; /* ?? */
unsigned char MinimumPINSize; /* for Verify and Modify */
unsigned char MaximumPINSize;
/* Miscellaneous reader features */
unsigned char Firewall:1;
unsigned char RFUb5:7;
/* The following fields, FirewalledCommand_SW1 and
* FirewalledCommand_SW2 are only valid if Firewall=1
* These fields give the SW1 SW2 value used by the reader to
* indicate a command has been firewalled */
unsigned char FirewalledCommand_SW1;
unsigned char FirewalledCommand_SW2;
unsigned char RFUb6[3];
};

58
src/ccid_ifdhandler.h Normal file
View File

@ -0,0 +1,58 @@
/*
ccid_ifdhandler.h: non-generic ifdhandler functions
Copyright (C) 2004-2010 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _ccid_ifd_handler_h_
#define _ccid_ifd_handler_h_
#define IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE SCARD_CTL_CODE(1)
#define CLASS2_IOCTL_MAGIC 0x330000
#define IOCTL_FEATURE_VERIFY_PIN_DIRECT \
SCARD_CTL_CODE(FEATURE_VERIFY_PIN_DIRECT + CLASS2_IOCTL_MAGIC)
#define IOCTL_FEATURE_MODIFY_PIN_DIRECT \
SCARD_CTL_CODE(FEATURE_MODIFY_PIN_DIRECT + CLASS2_IOCTL_MAGIC)
#define IOCTL_FEATURE_MCT_READER_DIRECT \
SCARD_CTL_CODE(FEATURE_MCT_READER_DIRECT + CLASS2_IOCTL_MAGIC)
#define IOCTL_FEATURE_IFD_PIN_PROPERTIES \
SCARD_CTL_CODE(FEATURE_IFD_PIN_PROPERTIES + CLASS2_IOCTL_MAGIC)
#define IOCTL_FEATURE_GET_TLV_PROPERTIES \
SCARD_CTL_CODE(FEATURE_GET_TLV_PROPERTIES + CLASS2_IOCTL_MAGIC)
#define DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED 1
#define DRIVER_OPTION_GEMPC_TWIN_KEY_APDU 2
#define DRIVER_OPTION_USE_BOGUS_FIRMWARE 4
#define DRIVER_OPTION_DISABLE_PIN_RETRIES (1 << 6)
extern int DriverOptions;
/*
* Maximum number of CCID readers supported simultaneously
*
* The maximum number of readers is also limited in pcsc-lite (16 by default)
* see the definition of PCSCLITE_MAX_READERS_CONTEXTS in src/PCSC/pcsclite.h
*/
#define CCID_DRIVER_MAX_READERS 16
/*
* CCID driver specific functions
*/
CcidDesc *get_ccid_slot(unsigned int reader_index);
#endif

942
src/ccid_serial.c Normal file
View File

@ -0,0 +1,942 @@
/*
* ccid_serial.c: communicate with a GemPC Twin smart card reader
* Copyright (C) 2001-2010 Ludovic Rousseau <ludovic.rousseau@free.fr>
*
* Thanks to Niki W. Waibel <niki.waibel@gmx.net> for a prototype version
*
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <ifdhandler.h>
#include <config.h>
#include "defs.h"
#include "ccid_ifdhandler.h"
#include "debug.h"
#include "ccid.h"
#include "utils.h"
#include "commands.h"
#include "parser.h"
#include "strlcpycat.h"
#define SYNC 0x03
#define CTRL_ACK 0x06
#define CTRL_NAK 0x15
#define RDR_to_PC_NotifySlotChange 0x50
#define CARD_ABSENT 0x02
#define CARD_PRESENT 0x03
/*
* normal command:
* 1 : SYNC
* 1 : CTRL
* 10 +data length : CCID command
* 1 : LRC
*
* SYNC : 0x03
* CTRL : ACK (0x06) or NAK (0x15)
* CCID command : see USB CCID specs
* LRC : xor of all the previous byes
*
* Error message:
* 1 : SYNC (0x03)
* 1 : CTRL (NAK: 0x15)
* 1 : LRC (0x16)
*
* Card insertion/withdrawal
* 1 : RDR_to_PC_NotifySlotChange (0x50)
* 1 : bmSlotIccState
* 0x02 if card absent
* 0x03 is card present
*
* Time request
* T=1 : normal CCID command
* T=0 : 1 byte (value between 0x80 and 0xFF)
*
*/
/*
* You may get read timeout after a card movement.
* This is because you will get the echo of the CCID command
* but not the result of the command.
*
* This is not an applicative issue since the card is either removed (and
* powered off) or just inserted (and not yet powered on).
*/
/* 271 = max size for short APDU
* 2 bytes for header
* 1 byte checksum
* doubled for echo
*/
#define GEMPCTWIN_MAXBUF (271 +2 +1) * 2
typedef struct
{
/*
* File handle on the serial port
*/
int fd;
/*
* device used ("/dev/ttyS?" under Linux)
*/
/*@null@*/ char *device;
/*
* Number of slots using the same device
*/
int real_nb_opened_slots;
int *nb_opened_slots;
/*
* does the reader echoes the serial communication bytes?
*/
int echo;
/*
* serial communication buffer
*/
unsigned char buffer[GEMPCTWIN_MAXBUF];
/*
* next available byte
*/
int buffer_offset;
/*
* number of available bytes
*/
int buffer_offset_last;
/*
* CCID infos common to USB and serial
*/
_ccid_descriptor ccid;
} _serialDevice;
/* The _serialDevice structure must be defined before including ccid_serial.h */
#include "ccid_serial.h"
/* data rates supported by the GemPC Twin (serial and PCMCIA) */
unsigned int SerialTwinDataRates[] = { ISO_DATA_RATES, 0 };
/* data rates supported by the GemPC PinPad, GemCore Pos Pro & SIM Pro */
unsigned int SerialExtendedDataRates[] = { ISO_DATA_RATES, 500000, 0 };
/* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
/* data rates supported by the GemCore SIM Pro 2 */
unsigned int SIMPro2DataRates[] = { SIMPRO2_ISO_DATA_RATES, 0 };
/* no need to initialize to 0 since it is static */
static _serialDevice serialDevice[CCID_DRIVER_MAX_READERS];
/* unexported functions */
static int ReadChunk(unsigned int reader_index, unsigned char *buffer,
int buffer_length, int min_length);
static int get_bytes(unsigned int reader_index, /*@out@*/ unsigned char *buffer,
int length);
/*****************************************************************************
*
* WriteSerial: Send bytes to the card reader
*
*****************************************************************************/
status_t WriteSerial(unsigned int reader_index, unsigned int length,
unsigned char *buffer)
{
unsigned int i;
unsigned char lrc;
unsigned char low_level_buffer[GEMPCTWIN_MAXBUF];
char debug_header[] = "-> 123456 ";
(void)snprintf(debug_header, sizeof(debug_header), "-> %06X ",
reader_index);
if (length > GEMPCTWIN_MAXBUF-3)
{
DEBUG_CRITICAL3("command too long: %d for max %d",
length, GEMPCTWIN_MAXBUF-3);
return STATUS_UNSUCCESSFUL;
}
/* header */
low_level_buffer[0] = 0x03; /* SYNC */
low_level_buffer[1] = 0x06; /* ACK */
/* CCID command */
memcpy(low_level_buffer+2, buffer, length);
/* checksum */
lrc = 0;
for(i=0; i<length+2; i++)
lrc ^= low_level_buffer[i];
low_level_buffer[length+2] = lrc;
DEBUG_XXD(debug_header, low_level_buffer, length+3);
if (write(serialDevice[reader_index].fd, low_level_buffer,
length+3) != length+3)
{
DEBUG_CRITICAL2("write error: %s", strerror(errno));
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
} /* WriteSerial */
/*****************************************************************************
*
* ReadSerial: Receive bytes from the card reader
*
*****************************************************************************/
status_t ReadSerial(unsigned int reader_index,
unsigned int *length, unsigned char *buffer)
{
unsigned char c;
int rv;
int echo;
int to_read;
int i;
/* we get the echo first */
echo = serialDevice[reader_index].echo;
start:
DEBUG_COMM("start");
if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
return rv;
if (c == RDR_to_PC_NotifySlotChange)
goto slot_change;
if (c == SYNC)
goto sync;
if (c >= 0x80)
{
DEBUG_COMM2("time request: 0x%02X", c);
goto start;
}
DEBUG_CRITICAL2("Got 0x%02X", c);
return STATUS_COMM_ERROR;
slot_change:
DEBUG_COMM("slot change");
if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
return rv;
if (c == CARD_ABSENT)
{
DEBUG_COMM("Card removed");
}
else
if (c == CARD_PRESENT)
{
DEBUG_COMM("Card inserted");
}
else
{
DEBUG_COMM2("Unknown card movement: %d", c);
}
goto start;
sync:
DEBUG_COMM("sync");
if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
return rv;
if (c == CTRL_ACK)
goto ack;
if (c == CTRL_NAK)
goto nak;
DEBUG_CRITICAL2("Got 0x%02X instead of ACK/NAK", c);
return STATUS_COMM_ERROR;
nak:
DEBUG_COMM("nak");
if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
return rv;
if (c != (SYNC ^ CTRL_NAK))
{
DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
return STATUS_COMM_ERROR;
}
else
{
DEBUG_COMM("NAK requested");
return STATUS_COMM_NAK;
}
ack:
DEBUG_COMM("ack");
/* normal CCID frame */
if ((rv = get_bytes(reader_index, buffer, 5)) != STATUS_SUCCESS)
return rv;
/* total frame size */
to_read = 10+dw2i(buffer, 1);
if ((to_read < 10) || (to_read > (int)*length))
{
DEBUG_CRITICAL2("Wrong value for frame size: %d", to_read);
return STATUS_COMM_ERROR;
}
DEBUG_COMM2("frame size: %d", to_read);
if ((rv = get_bytes(reader_index, buffer+5, to_read-5)) != STATUS_SUCCESS)
return rv;
DEBUG_XXD("frame: ", buffer, to_read);
/* lrc */
DEBUG_COMM("lrc");
if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
return rv;
DEBUG_COMM2("lrc: 0x%02X", c);
for (i=0; i<to_read; i++)
c ^= buffer[i];
if (c != (SYNC ^ CTRL_ACK))
DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
if (echo)
{
echo = FALSE;
goto start;
}
/* length of data read */
*length = to_read;
return STATUS_SUCCESS;
} /* ReadSerial */
/*****************************************************************************
*
* get_bytes: get n bytes
*
*****************************************************************************/
int get_bytes(unsigned int reader_index, unsigned char *buffer, int length)
{
int offset = serialDevice[reader_index].buffer_offset;
int offset_last = serialDevice[reader_index].buffer_offset_last;
DEBUG_COMM3("available: %d, needed: %d", offset_last-offset,
length);
/* enough data are available */
if (offset + length <= offset_last)
{
DEBUG_COMM("data available");
memcpy(buffer, serialDevice[reader_index].buffer + offset, length);
serialDevice[reader_index].buffer_offset += length;
}
else
{
int present, rv;
/* copy available data */
present = offset_last - offset;
if (present > 0)
{
DEBUG_COMM2("some data available: %d", present);
memcpy(buffer, serialDevice[reader_index].buffer + offset,
present);
}
/* get fresh data */
DEBUG_COMM2("get more data: %d", length - present);
rv = ReadChunk(reader_index, serialDevice[reader_index].buffer,
sizeof(serialDevice[reader_index].buffer), length - present);
if (rv < 0)
return STATUS_COMM_ERROR;
/* fill the buffer */
memcpy(buffer + present, serialDevice[reader_index].buffer,
length - present);
serialDevice[reader_index].buffer_offset = length - present;
serialDevice[reader_index].buffer_offset_last = rv;
DEBUG_COMM3("offset: %d, last_offset: %d",
serialDevice[reader_index].buffer_offset,
serialDevice[reader_index].buffer_offset_last);
}
return STATUS_SUCCESS;
} /* get_bytes */
/*****************************************************************************
*
* ReadChunk: read a minimum number of bytes
*
*****************************************************************************/
static int ReadChunk(unsigned int reader_index, unsigned char *buffer,
int buffer_length, int min_length)
{
int fd = serialDevice[reader_index].fd;
# ifndef S_SPLINT_S
fd_set fdset;
# endif
struct timeval t;
int i, rv = 0;
int already_read;
char debug_header[] = "<- 123456 ";
(void)snprintf(debug_header, sizeof(debug_header), "<- %06X ",
reader_index);
already_read = 0;
while (already_read < min_length)
{
/* use select() to, eventually, timeout */
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
t.tv_sec = serialDevice[reader_index].ccid.readTimeout / 1000;
t.tv_usec = (serialDevice[reader_index].ccid.readTimeout - t.tv_sec*1000)*1000;
i = select(fd+1, &fdset, NULL, NULL, &t);
if (i == -1)
{
DEBUG_CRITICAL2("select: %s", strerror(errno));
return -1;
}
else
if (i == 0)
{
DEBUG_COMM2("Timeout! (%d ms)", serialDevice[reader_index].ccid.readTimeout);
return -1;
}
rv = read(fd, buffer + already_read, buffer_length - already_read);
if (rv < 0)
{
DEBUG_COMM2("read error: %s", strerror(errno));
return -1;
}
DEBUG_XXD(debug_header, buffer + already_read, rv);
already_read += rv;
DEBUG_COMM3("read: %d, to read: %d", already_read,
min_length);
}
return already_read;
} /* ReadChunk */
/*****************************************************************************
*
* OpenSerial: open the port
*
*****************************************************************************/
status_t OpenSerial(unsigned int reader_index, int channel)
{
char dev_name[FILENAME_MAX];
DEBUG_COMM3("Reader index: %X, Channel: %d", reader_index, channel);
/*
* Conversion of old-style ifd-hanler 1.0 CHANNELID
*/
if (channel == 0x0103F8)
channel = 1;
else
if (channel == 0x0102F8)
channel = 2;
else
if (channel == 0x0103E8)
channel = 3;
else
if (channel == 0x0102E8)
channel = 4;
if (channel < 0)
{
DEBUG_CRITICAL2("wrong port number: %d", channel);
return STATUS_UNSUCCESSFUL;
}
(void)snprintf(dev_name, sizeof(dev_name), "/dev/pcsc/%d", channel);
return OpenSerialByName(reader_index, dev_name);
} /* OpenSerial */
/*****************************************************************************
*
* set_ccid_descriptor: init ccid descriptor
* depending on reader type specified in device.
*
* return: STATUS_UNSUCCESSFUL,
* STATUS_SUCCESS,
* -1 (Reader already used)
*
*****************************************************************************/
static status_t set_ccid_descriptor(unsigned int reader_index,
const char *reader_name, const char *dev_name)
{
int readerID;
int i;
int already_used = FALSE;
static int previous_reader_index = -1;
readerID = GEMPCTWIN;
if (0 == strcasecmp(reader_name,"GemCorePOSPro"))
readerID = GEMCOREPOSPRO;
else if (0 == strcasecmp(reader_name,"GemCoreSIMPro"))
readerID = GEMCORESIMPRO;
else if (0 == strcasecmp(reader_name,"GemCoreSIMPro2"))
readerID = GEMCORESIMPRO2;
else if (0 == strcasecmp(reader_name,"GemPCPinPad"))
readerID = GEMPCPINPAD;
else if (0 == strcasecmp(reader_name,"SEC1210"))
readerID = SEC1210;
/* check if the same channel is not already used to manage multi-slots readers*/
for (i = 0; i < CCID_DRIVER_MAX_READERS; i++)
{
if (serialDevice[i].device
&& strcmp(serialDevice[i].device, dev_name) == 0)
{
already_used = TRUE;
DEBUG_COMM2("%s already used. Multi-slot reader?", dev_name);
break;
}
}
/* this reader is already managed by us */
if (already_used)
{
if ((previous_reader_index != -1)
&& serialDevice[previous_reader_index].device
&& (strcmp(serialDevice[previous_reader_index].device, dev_name) == 0)
&& serialDevice[previous_reader_index].ccid.bCurrentSlotIndex < serialDevice[previous_reader_index].ccid.bMaxSlotIndex)
{
/* we reuse the same device and the reader is multi-slot */
serialDevice[reader_index] = serialDevice[previous_reader_index];
*serialDevice[reader_index].nb_opened_slots += 1;
serialDevice[reader_index].ccid.bCurrentSlotIndex++;
serialDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
DEBUG_INFO2("Opening slot: %d",
serialDevice[reader_index].ccid.bCurrentSlotIndex);
switch (readerID)
{
case GEMCOREPOSPRO:
case GEMCORESIMPRO:
{
/* Allocate a memory buffer that will be
* released in CloseUSB() */
void *ptr = malloc(sizeof SerialCustomDataRates);
if (ptr)
{
memcpy(ptr, SerialCustomDataRates,
sizeof SerialCustomDataRates);
}
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = ptr;
}
serialDevice[reader_index].ccid.dwMaxDataRate = 125000;
break;
case SEC1210:
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = NULL;
serialDevice[reader_index].ccid.dwMaxDataRate = 826000;
break;
/* GemPC Twin or GemPC Card */
default:
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialTwinDataRates;
serialDevice[reader_index].ccid.dwMaxDataRate = 344086;
break;
}
goto end;
}
else
{
DEBUG_CRITICAL2("Trying to open too many slots on %s", dev_name);
return STATUS_UNSUCCESSFUL;
}
}
/* Common to all readers */
serialDevice[reader_index].ccid.real_bSeq = 0;
serialDevice[reader_index].ccid.pbSeq = &serialDevice[reader_index].ccid.real_bSeq;
serialDevice[reader_index].real_nb_opened_slots = 1;
serialDevice[reader_index].nb_opened_slots = &serialDevice[reader_index].real_nb_opened_slots;
serialDevice[reader_index].ccid.bCurrentSlotIndex = 0;
serialDevice[reader_index].ccid.dwMaxCCIDMessageLength = 271;
serialDevice[reader_index].ccid.dwMaxIFSD = 254;
serialDevice[reader_index].ccid.dwFeatures = 0x00010230;
serialDevice[reader_index].ccid.dwDefaultClock = 4000;
serialDevice[reader_index].buffer_offset = 0;
serialDevice[reader_index].buffer_offset_last = 0;
serialDevice[reader_index].ccid.readerID = readerID;
serialDevice[reader_index].ccid.bPINSupport = 0x0;
serialDevice[reader_index].ccid.dwMaxDataRate = 344086;
serialDevice[reader_index].ccid.bMaxSlotIndex = 0;
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialTwinDataRates;
serialDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
serialDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
serialDevice[reader_index].ccid.bVoltageSupport = 0x07; /* 1.8V, 3V and 5V */
serialDevice[reader_index].ccid.gemalto_firmware_features = NULL;
#ifdef ENABLE_ZLP
serialDevice[reader_index].ccid.zlp = FALSE;
#endif
serialDevice[reader_index].echo = TRUE;
/* change some values depending on the reader */
switch (readerID)
{
case GEMCOREPOSPRO:
serialDevice[reader_index].ccid.bMaxSlotIndex = 4; /* 5 slots */
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialExtendedDataRates;
serialDevice[reader_index].echo = FALSE;
serialDevice[reader_index].ccid.dwMaxDataRate = 500000;
break;
case GEMCORESIMPRO:
serialDevice[reader_index].ccid.bMaxSlotIndex = 1; /* 2 slots */
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialExtendedDataRates;
serialDevice[reader_index].echo = FALSE;
serialDevice[reader_index].ccid.dwMaxDataRate = 500000;
break;
case GEMCORESIMPRO2:
serialDevice[reader_index].ccid.dwDefaultClock = 4800;
serialDevice[reader_index].ccid.bMaxSlotIndex = 1; /* 2 slots */
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SIMPro2DataRates;
serialDevice[reader_index].echo = FALSE;
serialDevice[reader_index].ccid.dwMaxDataRate = 825806;
break;
case GEMPCPINPAD:
serialDevice[reader_index].ccid.bPINSupport = 0x03;
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialExtendedDataRates;
serialDevice[reader_index].ccid.dwMaxDataRate = 500000;
break;
case SEC1210:
serialDevice[reader_index].ccid.dwFeatures = 0x000100B2;
serialDevice[reader_index].ccid.dwDefaultClock = 4800;
serialDevice[reader_index].ccid.dwMaxDataRate = 826000;
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = NULL;
serialDevice[reader_index].ccid.bMaxSlotIndex = 1; /* 2 slots */
serialDevice[reader_index].echo = FALSE;
break;
}
end:
/* memorise the current reader_index so we can detect
* a new OpenSerialByName on a multi slot reader */
previous_reader_index = reader_index;
/* we just created a secondary slot on a multi-slot reader */
if (already_used)
return STATUS_SECONDARY_SLOT;
return STATUS_SUCCESS;
} /* set_ccid_descriptor */
/*****************************************************************************
*
* OpenSerialByName: open the port
*
*****************************************************************************/
status_t OpenSerialByName(unsigned int reader_index, char *dev_name)
{
struct termios current_termios;
unsigned int reader = reader_index;
/* 255 is MAX_DEVICENAME in pcscd.h */
char reader_name[255] = "GemPCTwin";
char *p;
status_t ret;
DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, dev_name);
/* parse dev_name using the pattern "device:name" */
p = strchr(dev_name, ':');
if (p)
{
/* copy the second part of the string */
strlcpy(reader_name, p+1, sizeof(reader_name));
/* replace ':' by '\0' so that dev_name only contains the device name */
*p = '\0';
}
ret = set_ccid_descriptor(reader_index, reader_name, dev_name);
if (STATUS_UNSUCCESSFUL == ret)
return STATUS_UNSUCCESSFUL;
/* secondary slot so do not physically open the device */
if (STATUS_SECONDARY_SLOT == ret)
return STATUS_SUCCESS;
serialDevice[reader].fd = open(dev_name, O_RDWR | O_NOCTTY);
if (-1 == serialDevice[reader].fd)
{
DEBUG_CRITICAL3("open %s: %s", dev_name, strerror(errno));
return STATUS_UNSUCCESSFUL;
}
/* Set RTS signal to low to prevent the smart card reader
* from sending its plug and play string. */
{
int flags;
if (ioctl(serialDevice[reader].fd, TIOCMGET, &flags) < 0)
{
DEBUG_CRITICAL2("Get RS232 signals state failed: %s",
strerror(errno));
}
else
{
flags &= ~TIOCM_RTS;
if (ioctl(serialDevice[reader].fd, TIOCMSET, &flags) < 0)
{
DEBUG_CRITICAL2("Set RTS to low failed: %s", strerror(errno));
}
else
{
DEBUG_COMM("Plug-n-Play inhibition successful");
}
}
}
/* set channel used */
serialDevice[reader].device = strdup(dev_name);
/* empty in and out serial buffers */
if (tcflush(serialDevice[reader].fd, TCIOFLUSH))
DEBUG_INFO2("tcflush() function error: %s", strerror(errno));
/* get config attributes */
if (tcgetattr(serialDevice[reader].fd, &current_termios) == -1)
{
DEBUG_INFO2("tcgetattr() function error: %s", strerror(errno));
(void)close(serialDevice[reader].fd);
serialDevice[reader].fd = -1;
return STATUS_UNSUCCESSFUL;
}
/* IGNBRK: ignore BREAK condition on input
* IGNPAR: ignore framing errors and parity errors. */
current_termios.c_iflag = IGNBRK | IGNPAR;
current_termios.c_oflag = 0; /* Raw output modes */
/* CS8: 8-bits character size
* CSTOPB: set two stop bits
* CREAD: enable receiver
* CLOCAL: ignore modem control lines */
current_termios.c_cflag = CS8 | CSTOPB | CREAD | CLOCAL;
/* Do not echo characters because if you connect to a host it or your modem
* will echo characters for you. Don't generate signals. */
current_termios.c_lflag = 0;
if (0 == strcasecmp(reader_name,"GemCoreSIMPro2"))
{
unsigned char pcbuffer[SIZE_GET_SLOT_STATUS];
unsigned int old_timeout;
RESPONSECODE r;
/* Unless we resume from a stand-by condition, GemCoreSIMPro2
* starts at 9600 bauds, so let's first try this speed */
/* set serial port speed to 9600 bauds */
(void)cfsetspeed(&current_termios, B9600);
DEBUG_INFO1("Set serial port baudrate to 9600 and correct configuration");
if (tcsetattr(serialDevice[reader_index].fd, TCSANOW, &current_termios) == -1)
{
(void)close(serialDevice[reader_index].fd);
serialDevice[reader_index].fd = -1;
DEBUG_CRITICAL2("tcsetattr error: %s", strerror(errno));
return STATUS_UNSUCCESSFUL;
}
/* Test current speed issuing a CmdGetSlotStatus with a very
* short time out of 1 seconds */
old_timeout = serialDevice[reader_index].ccid.readTimeout;
serialDevice[reader_index].ccid.readTimeout = 1*1000;
r = CmdGetSlotStatus(reader_index, pcbuffer);
/* Restore default time out value */
serialDevice[reader_index].ccid.readTimeout = old_timeout;
if (IFD_SUCCESS == r)
{
/* We are at 9600 bauds, let's move to 115200 */
unsigned char tx_buffer[] = { 0x01, 0x10, 0x20 };
unsigned char rx_buffer[50];
unsigned int rx_length = sizeof(rx_buffer);
if (IFD_SUCCESS == CmdEscape(reader_index, tx_buffer,
sizeof(tx_buffer), rx_buffer, &rx_length, 0))
{
/* Let the reader setup its new communication speed */
(void)usleep(250*1000);
}
else
{
DEBUG_INFO1("CmdEscape to configure 115200 bauds failed");
}
}
/* In case of a failure, reader is probably already at 115200
* bauds as code below assumes */
}
/* set serial port speed to 115200 bauds */
(void)cfsetspeed(&current_termios, B115200);
DEBUG_INFO1("Set serial port baudrate to 115200 and correct configuration");
if (tcsetattr(serialDevice[reader].fd, TCSANOW, &current_termios) == -1)
{
(void)close(serialDevice[reader].fd);
serialDevice[reader].fd = -1;
DEBUG_INFO2("tcsetattr error: %s", strerror(errno));
return STATUS_UNSUCCESSFUL;
}
/* perform a command to be sure a Gemalto reader is connected
* get the reader firmware */
{
unsigned char tx_buffer[1];
unsigned char rx_buffer[50];
unsigned int rx_length = sizeof(rx_buffer);
if (0 == strcasecmp(reader_name,"SEC1210"))
tx_buffer[0] = 0x06; // unknown but supported command
else
tx_buffer[0] = 0x02; // get reader firmware
/* 2 seconds timeout to not wait too long if no reader is connected */
if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer),
rx_buffer, &rx_length, 2*1000))
{
DEBUG_CRITICAL("Get firmware failed. Maybe the reader is not connected");
(void)CloseSerial(reader_index);
return STATUS_UNSUCCESSFUL;
}
rx_buffer[rx_length] = '\0';
DEBUG_INFO2("Firmware: %s", rx_buffer);
}
/* perform a command to configure GemPC Twin reader card movement
* notification to synchronous mode: the card movement is notified _after_
* the host command and _before_ the reader anwser */
if (0 != strcasecmp(reader_name,"SEC1210"))
{
unsigned char tx_buffer[] = { 0x01, 0x01, 0x01};
unsigned char rx_buffer[50];
unsigned int rx_length = sizeof(rx_buffer);
if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer),
rx_buffer, &rx_length, 0))
{
DEBUG_CRITICAL("Change card movement notification failed.");
(void)CloseSerial(reader_index);
return STATUS_UNSUCCESSFUL;
}
}
serialDevice[reader_index].ccid.sIFD_serial_number = NULL;
serialDevice[reader_index].ccid.sIFD_iManufacturer = NULL;
serialDevice[reader_index].ccid.IFD_bcdDevice = 0;
return STATUS_SUCCESS;
} /* OpenSerialByName */
/*****************************************************************************
*
* CloseSerial: close the port
*
*****************************************************************************/
status_t CloseSerial(unsigned int reader_index)
{
unsigned int reader = reader_index;
/* device not opened */
if (NULL == serialDevice[reader_index].device)
return STATUS_UNSUCCESSFUL;
DEBUG_COMM2("Closing serial device: %s", serialDevice[reader_index].device);
/* Decrement number of opened slot */
(*serialDevice[reader_index].nb_opened_slots)--;
/* release the allocated ressources for the last slot only */
if (0 == *serialDevice[reader_index].nb_opened_slots)
{
DEBUG_COMM("Last slot closed. Release resources");
(void)close(serialDevice[reader].fd);
serialDevice[reader].fd = -1;
free(serialDevice[reader].device);
serialDevice[reader].device = NULL;
}
return STATUS_SUCCESS;
} /* CloseSerial */
/*****************************************************************************
*
* get_ccid_descriptor
*
****************************************************************************/
_ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
{
return &serialDevice[reader_index].ccid;
} /* get_ccid_descriptor */

35
src/ccid_serial.h Normal file
View File

@ -0,0 +1,35 @@
/*
ccid_serial.h: Serial access routines
Copyright (C) 2003-2008 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __CCID_SERAL_H__
#define __CCID_SERAL_H__
status_t OpenSerial(unsigned int reader_index, int channel);
status_t OpenSerialByName(unsigned int reader_index, char *dev_name);
status_t WriteSerial(unsigned int reader_index, unsigned int length,
unsigned char *Buffer);
status_t ReadSerial(unsigned int reader_index, unsigned int *length,
unsigned char *Buffer);
status_t CloseSerial(unsigned int reader_index);
#endif

1758
src/ccid_usb.c Normal file

File diff suppressed because it is too large Load Diff

45
src/ccid_usb.h Normal file
View File

@ -0,0 +1,45 @@
/*
ccid_usb.h: USB access routines using the libusb library
Copyright (C) 2003-2010 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __CCID_USB_H__
#define __CCID_USB_H__
status_t OpenUSB(unsigned int reader_index, int channel);
status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device);
status_t WriteUSB(unsigned int reader_index, unsigned int length,
unsigned char *Buffer);
status_t ReadUSB(unsigned int reader_index, unsigned int *length,
/*@out@*/ unsigned char *Buffer);
status_t CloseUSB(unsigned int reader_index);
#include <libusb.h>
/*@null@*/ const struct libusb_interface *get_ccid_usb_interface(
struct libusb_config_descriptor *desc, int *num);
const unsigned char *get_ccid_device_descriptor(const struct libusb_interface *usb_interface);
int ControlUSB(int reader_index, int requesttype, int request, int value,
unsigned char *bytes, unsigned int size);
int InterruptRead(int reader_index, int timeout);
void InterruptStop(int reader_index);
#endif

2328
src/commands.c Normal file

File diff suppressed because it is too large Load Diff

65
src/commands.h Normal file
View File

@ -0,0 +1,65 @@
/*
commands.h: Commands sent to the card
Copyright (C) 2003-2009 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define SIZE_GET_SLOT_STATUS 10
#define STATUS_OFFSET 7
#define ERROR_OFFSET 8
#define CHAIN_PARAMETER_OFFSET 9
RESPONSECODE CmdPowerOn(unsigned int reader_index, unsigned int * nlength,
/*@out@*/ unsigned char buffer[], int voltage);
RESPONSECODE SecurePINVerify(unsigned int reader_index,
unsigned char TxBuffer[], unsigned int TxLength,
unsigned char RxBuffer[], unsigned int *RxLength);
RESPONSECODE SecurePINModify(unsigned int reader_index,
unsigned char TxBuffer[], unsigned int TxLength,
unsigned char RxBuffer[], unsigned int *RxLength);
RESPONSECODE CmdEscape(unsigned int reader_index,
const unsigned char TxBuffer[], unsigned int TxLength,
unsigned char RxBuffer[], unsigned int *RxLength, unsigned int timeout);
RESPONSECODE CmdEscapeCheck(unsigned int reader_index,
const unsigned char TxBuffer[], unsigned int TxLength,
unsigned char RxBuffer[], unsigned int *RxLength, unsigned int timeout,
int mayfail);
RESPONSECODE CmdPowerOff(unsigned int reader_index);
RESPONSECODE CmdGetSlotStatus(unsigned int reader_index,
/*@out@*/ unsigned char buffer[]);
RESPONSECODE CmdXfrBlock(unsigned int reader_index, unsigned int tx_length,
unsigned char tx_buffer[], unsigned int *rx_length,
unsigned char rx_buffer[], int protoccol);
RESPONSECODE CCID_Transmit(unsigned int reader_index, unsigned int tx_length,
const unsigned char tx_buffer[], unsigned short rx_length, unsigned char bBWI);
RESPONSECODE CCID_Receive(unsigned int reader_index,
/*@out@*/ unsigned int *rx_length,
/*@out@*/ unsigned char rx_buffer[], unsigned char *chain_parameter);
RESPONSECODE SetParameters(unsigned int reader_index, char protocol,
unsigned int length, unsigned char buffer[]);
int isCharLevel(int reader_index);

32
src/convert_version.pl Executable file
View File

@ -0,0 +1,32 @@
#!/usr/bin/env perl
# convert_version.pl: generate a version integer from a version text
#
# Copyright (C) 2006-2008 Ludovic Rousseau <ludovic.rousseau@free.fr>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA.
use warnings;
use strict;
# convert "1.2.3-svn-xyz" in "0x01020003"
my ($major, $minor, $patch) = split /\./, $ARGV[0];
# remove the -svn-xyz part if any
$patch =~ s/-.*//;
printf "0x%02X%02X%04X\n", $major, $minor, $patch;

111
src/create_Info_plist.pl Executable file
View File

@ -0,0 +1,111 @@
#!/usr/bin/env perl
# create_Info_plist.pl: generate Info.plist from a template and a
# list of supported readers
#
# Copyright (C) 2004-2009 Ludovic Rousseau <ludovic.rousseau@free.fr>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA.
use warnings;
use strict;
use Getopt::Long;
my (@manuf, @product, @name);
my ($manuf, $product, $name);
my $target = "libccid.so";
my $version = "1.0.0";
my $class = "<key>CFBundleName</key>
<string>CCIDCLASSDRIVER</string>";
my $noclass = 0;
GetOptions(
"target=s" => \$target,
"version=s" => \$version,
"no-class" => \$noclass);
if ($#ARGV < 1)
{
print "usage: $0 supported_readers.txt Info.plist
--target=$target
--version=$version\n";
exit;
}
open IN, "< $ARGV[0]" or die "Can't open $ARGV[0]: $!";
while (<IN>)
{
next if (m/^#/);
next if (m/^$/);
chomp;
($manuf, $product, $name) = split /:/;
# print "m: $manuf, p: $product, n: $name\n";
push @manuf, $manuf;
push @product, $product;
$name =~ s/&/&amp;/g;
push @name, $name
}
close IN;
map { $_ = "\t\t<string>$_</string>\n" } @manuf;
map { $_ = "\t\t<string>$_</string>\n" } @product;
map { $_ = "\t\t<string>$_</string>\n" } @name;
open IN, "< $ARGV[1]" or die "Can't open $ARGV[1]: $!";
while (<IN>)
{
if (m/MAGIC_VENDOR/)
{
print @manuf;
next;
}
if (m/MAGIC_PRODUCT/)
{
print @product;
next;
}
if (m/MAGIC_FRIENDLYNAME/)
{
print @name;
next;
}
if (m/MAGIC_TARGET/)
{
s/MAGIC_TARGET/$target/;
print;
next;
}
if (m/MAGIC_VERSION/)
{
s/MAGIC_VERSION/$version/;
print;
next;
}
if (m/MAGIC_CLASS/)
{
next if ($noclass);
s/MAGIC_CLASS/$class/;
print;
next;
}
print;
}
close IN;

183
src/debug.c Normal file
View File

@ -0,0 +1,183 @@
/*
debug.c: log (or not) messages
Copyright (C) 2003-2011 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <config.h>
#include "misc.h"
#include "debug.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <stdlib.h>
#ifdef USE_SYSLOG
#include <syslog.h>
#endif
#include "strlcpycat.h"
#undef LOG_TO_STDERR
#ifdef LOG_TO_STDERR
#define LOG_STREAM stderr
#else
#define LOG_STREAM stdout
#endif
void log_msg(const int priority, const char *fmt, ...)
{
char debug_buffer[3 * 80]; /* up to 3 lines of 80 characters */
va_list argptr;
static struct timeval last_time = { 0, 0 };
struct timeval new_time = { 0, 0 };
struct timeval tmp;
int delta;
#ifdef USE_SYSLOG
int syslog_level;
switch(priority)
{
case PCSC_LOG_CRITICAL:
syslog_level = LOG_CRIT;
break;
case PCSC_LOG_ERROR:
syslog_level = LOG_ERR;
break;
case PCSC_LOG_INFO:
syslog_level = LOG_INFO;
break;
default:
syslog_level = LOG_DEBUG;
}
#else
const char *color_pfx = "", *color_sfx = "";
const char *time_pfx = "", *time_sfx = "";
static int initialized = 0;
static int LogDoColor = 0;
if (!initialized)
{
char *term;
initialized = 1;
term = getenv("TERM");
if (term)
{
const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode", "xterm-256color" };
unsigned int i;
/* for each known color terminal */
for (i = 0; i < COUNT_OF(terms); i++)
{
/* we found a supported term? */
if (0 == strcmp(terms[i], term))
{
LogDoColor = 1;
break;
}
}
}
}
if (LogDoColor)
{
color_sfx = "\33[0m";
time_sfx = color_sfx;
time_pfx = "\33[36m"; /* Cyan */
switch (priority)
{
case PCSC_LOG_CRITICAL:
color_pfx = "\33[01;31m"; /* bright + Red */
break;
case PCSC_LOG_ERROR:
color_pfx = "\33[35m"; /* Magenta */
break;
case PCSC_LOG_INFO:
color_pfx = "\33[34m"; /* Blue */
break;
case PCSC_LOG_DEBUG:
color_pfx = ""; /* normal (black) */
color_sfx = "";
break;
}
}
#endif
gettimeofday(&new_time, NULL);
if (0 == last_time.tv_sec)
last_time = new_time;
tmp.tv_sec = new_time.tv_sec - last_time.tv_sec;
tmp.tv_usec = new_time.tv_usec - last_time.tv_usec;
if (tmp.tv_usec < 0)
{
tmp.tv_sec--;
tmp.tv_usec += 1000000;
}
if (tmp.tv_sec < 100)
delta = tmp.tv_sec * 1000000 + tmp.tv_usec;
else
delta = 99999999;
last_time = new_time;
va_start(argptr, fmt);
(void)vsnprintf(debug_buffer, sizeof debug_buffer, fmt, argptr);
va_end(argptr);
#ifdef USE_SYSLOG
syslog(syslog_level, "%.8d %s", delta, debug_buffer);
#else
(void)fprintf(LOG_STREAM, "%s%.8d%s %s%s%s\n", time_pfx, delta, time_sfx,
color_pfx, debug_buffer, color_sfx);
fflush(LOG_STREAM);
#endif
} /* log_msg */
void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
const int len)
{
int i;
char *c, debug_buffer[len*3 + strlen(msg) +1];
size_t l;
(void)priority;
l = strlcpy(debug_buffer, msg, sizeof debug_buffer);
c = debug_buffer + l;
for (i = 0; i < len; ++i)
{
/* 2 hex characters, 1 space, 1 NUL : total 4 characters */
(void)snprintf(c, 4, "%02X ", buffer[i]);
c += 3;
}
#ifdef USE_SYSLOG
syslog(LOG_DEBUG, "%s", debug_buffer);
#else
(void)fprintf(LOG_STREAM, "%s\n", debug_buffer);
fflush(LOG_STREAM);
#endif
} /* log_xxd */

96
src/debug.h Normal file
View File

@ -0,0 +1,96 @@
/*
debug.h: log (or not) messages using syslog
Copyright (C) 2003-2008 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* DEBUG_CRITICAL("text");
* log "text" if (LogLevel & DEBUG_LEVEL_CRITICAL) is TRUE
*
* DEBUG_CRITICAL2("text: %d", 1234);
* log "text: 1234" if (DEBUG_LEVEL_CRITICAL & DEBUG_LEVEL_CRITICAL) is TRUE
* the format string can be anything printf() can understand
*
* same thing for DEBUG_INFO, DEBUG_COMM and DEBUG_PERIODIC
*
* DEBUG_XXD(msg, buffer, size);
* log a dump of buffer if (LogLevel & DEBUG_LEVEL_COMM) is TRUE
*
*/
#ifndef _GCDEBUG_H_
#define _GCDEBUG_H_
/* You can't do #ifndef __FUNCTION__ */
#if !defined(__GNUC__) && !defined(__IBMC__)
#define __FUNCTION__ ""
#endif
extern int LogLevel;
#define DEBUG_LEVEL_CRITICAL 1
#define DEBUG_LEVEL_INFO 2
#define DEBUG_LEVEL_COMM 4
#define DEBUG_LEVEL_PERIODIC 8
#include <debuglog.h> /* from pcsc-lite */
/* DEBUG_CRITICAL */
#define DEBUG_CRITICAL(fmt) if (LogLevel & DEBUG_LEVEL_CRITICAL) Log1(PCSC_LOG_CRITICAL, fmt)
#define DEBUG_CRITICAL2(fmt, data) if (LogLevel & DEBUG_LEVEL_CRITICAL) Log2(PCSC_LOG_CRITICAL, fmt, data)
#define DEBUG_CRITICAL3(fmt, data1, data2) if (LogLevel & DEBUG_LEVEL_CRITICAL) Log3(PCSC_LOG_CRITICAL, fmt, data1, data2)
#define DEBUG_CRITICAL4(fmt, data1, data2, data3) if (LogLevel & DEBUG_LEVEL_CRITICAL) Log4(PCSC_LOG_CRITICAL, fmt, data1, data2, data3)
#define DEBUG_CRITICAL5(fmt, data1, data2, data3, data4) if (LogLevel & DEBUG_LEVEL_CRITICAL) Log5(PCSC_LOG_CRITICAL, fmt, data1, data2, data3, data4)
/* DEBUG_INFO */
#define DEBUG_INFO1(fmt) if (LogLevel & DEBUG_LEVEL_INFO) Log1(PCSC_LOG_INFO, fmt)
#define DEBUG_INFO2(fmt, data) if (LogLevel & DEBUG_LEVEL_INFO) Log2(PCSC_LOG_INFO, fmt, data)
#define DEBUG_INFO3(fmt, data1, data2) if (LogLevel & DEBUG_LEVEL_INFO) Log3(PCSC_LOG_INFO, fmt, data1, data2)
#define DEBUG_INFO4(fmt, data1, data2, data3) if (LogLevel & DEBUG_LEVEL_INFO) Log4(PCSC_LOG_INFO, fmt, data1, data2, data3)
#define DEBUG_INFO5(fmt, data1, data2, data3, data4) if (LogLevel & DEBUG_LEVEL_INFO) Log5(PCSC_LOG_INFO, fmt, data1, data2, data3, data4)
#define DEBUG_INFO_XXD(msg, buffer, size) if (LogLevel & DEBUG_LEVEL_INFO) LogXxd(PCSC_LOG_INFO, msg, buffer, size)
/* DEBUG_PERIODIC */
#define DEBUG_PERIODIC(fmt) if (LogLevel & DEBUG_LEVEL_PERIODIC) Log1(PCSC_LOG_DEBUG, fmt)
#define DEBUG_PERIODIC2(fmt, data) if (LogLevel & DEBUG_LEVEL_PERIODIC) Log2(PCSC_LOG_DEBUG, fmt, data)
#define DEBUG_PERIODIC3(fmt, data1, data2) if (LogLevel & DEBUG_LEVEL_PERIODIC) Log3(PCSC_LOG_DEBUG, fmt, data1, data2)
/* DEBUG_COMM */
#define DEBUG_COMM(fmt) if (LogLevel & DEBUG_LEVEL_COMM) Log1(PCSC_LOG_DEBUG, fmt)
#define DEBUG_COMM2(fmt, data) if (LogLevel & DEBUG_LEVEL_COMM) Log2(PCSC_LOG_DEBUG, fmt, data)
#define DEBUG_COMM3(fmt, data1, data2) if (LogLevel & DEBUG_LEVEL_COMM) Log3(PCSC_LOG_DEBUG, fmt, data1, data2)
#define DEBUG_COMM4(fmt, data1, data2, data3) if (LogLevel & DEBUG_LEVEL_COMM) Log4(PCSC_LOG_DEBUG, fmt, data1, data2, data3)
/* DEBUG_XXD */
#define DEBUG_XXD(msg, buffer, size) if (LogLevel & DEBUG_LEVEL_COMM) LogXxd(PCSC_LOG_DEBUG, msg, buffer, size)
#endif

111
src/defs.h Normal file
View File

@ -0,0 +1,111 @@
/*
defs.h:
Copyright (C) 2003-2010 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define max( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
#include <pcsclite.h>
#include "openct/proto-t1.h"
typedef struct CCID_DESC
{
/*
* ATR
*/
int nATRLength;
unsigned char pcATRBuffer[MAX_ATR_SIZE];
/*
* Card state
*/
unsigned char bPowerFlags;
/*
* T=1 Protocol context
*/
t1_state_t t1;
/* reader name passed to IFDHCreateChannelByName() */
char *readerName;
} CcidDesc;
typedef enum {
STATUS_NO_SUCH_DEVICE = 0xF9,
STATUS_SUCCESS = 0xFA,
STATUS_UNSUCCESSFUL = 0xFB,
STATUS_COMM_ERROR = 0xFC,
STATUS_DEVICE_PROTOCOL_ERROR = 0xFD,
STATUS_COMM_NAK = 0xFE,
STATUS_SECONDARY_SLOT = 0xFF
} status_t;
/* Powerflag (used to detect quick insertion removals unnoticed by the
* resource manager) */
/* Initial value */
#define POWERFLAGS_RAZ 0x00
/* Flag set when a power up has been requested */
#define MASK_POWERFLAGS_PUP 0x01
/* Flag set when a power down is requested */
#define MASK_POWERFLAGS_PDWN 0x02
/* Communication buffer size (max=adpu+Lc+data+Le)
* we use a 64kB for extended APDU on APDU mode readers */
#define CMD_BUF_SIZE (4 +3 +64*1024 +3)
/* Protocols */
#define T_0 0
#define T_1 1
/* Default communication read timeout in milliseconds */
#define DEFAULT_COM_READ_TIMEOUT (3*1000)
/* DWORD type formating */
#ifdef __APPLE__
/* Apple defines DWORD as uint32_t */
#define DWORD_X "%X"
#define DWORD_D "%d"
#else
/* pcsc-lite defines DWORD as unsigned long */
#define DWORD_X "%lX"
#define DWORD_D "%ld"
#endif
/*
* communication ports abstraction
*/
#ifdef TWIN_SERIAL
#define OpenPortByName OpenSerialByName
#define OpenPort OpenSerial
#define ClosePort CloseSerial
#define ReadPort ReadSerial
#define WritePort WriteSerial
#include "ccid_serial.h"
#else
#define OpenPortByName OpenUSBByName
#define OpenPort OpenUSB
#define ClosePort CloseUSB
#define ReadPort ReadUSB
#define WritePort WriteUSB
#include "ccid_usb.h"
#endif

2275
src/ifdhandler.c Normal file

File diff suppressed because it is too large Load Diff

85
src/misc.h Normal file
View File

@ -0,0 +1,85 @@
/*
* This handles GCC attributes
*
* MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
*
* Copyright (C) 2005-2010
* Ludovic Rousseau <ludovic.rousseau@free.fr>
*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __misc_h__
#define __misc_h__
/*
* Declare the function as internal to the library: the function name is
* not exported and can't be used by a program linked to the library
*
* see http://gcc.gnu.org/onlinedocs/gcc-3.3.5/gcc/Function-Attributes.html#Function-Attributes
* see http://www.nedprod.com/programs/gccvisibility.html
*/
#if defined(__GNUC__) && \
(__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) || \
defined(__SUNPRO_C) && __SUNPRO_C >= 0x590
#define INTERNAL __attribute__ ((visibility("hidden")))
#define PCSC_API __attribute__ ((visibility("default")))
#elif defined(__SUNPRO_C) && __SUNPRO_C >= 0x550
/* http://wikis.sun.com/display/SunStudio/Macros+for+Shared+Library+Symbol+Visibility */
#define INTERNAL __hidden
#define PCSC_API __global
#else
#define INTERNAL
#define PCSC_API
#endif
#define EXTERNAL PCSC_API
#if defined __GNUC__
/* GNU Compiler Collection (GCC) */
#define CONSTRUCTOR __attribute__ ((constructor))
#define DESTRUCTOR __attribute__ ((destructor))
#else
/* SUN C compiler does not use __attribute__ but #pragma init (function)
* We can't use a # inside a #define so it is not possible to use
* #define CONSTRUCTOR_DECLARATION(x) #pragma init (x)
* The #pragma is used directly where needed */
/* any other */
#define CONSTRUCTOR
#define DESTRUCTOR
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef COUNT_OF
#define COUNT_OF(arr) (sizeof(arr)/sizeof(arr[0]))
#endif
#endif /* __misc_h__ */

28
src/openct/LICENSE Normal file
View File

@ -0,0 +1,28 @@
OpenCT, a middleware framework for smart card terminals.
Copyright (c) 2003, Olaf Kirch <okir@suse.de>
Copyright (c) 2003, Andreas Jellinghaus <aj@dungeon.inka.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the authors nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

5
src/openct/README Normal file
View File

@ -0,0 +1,5 @@
The files buffer.[c|h], checksum.c and proto-t1.c comes from the OpenCT
project <http://www.opensc.org/>
I (Ludovic Rousseau) greatly patched proto-t1.c to add all the needed
code to reach the quality level requested by the EMV standard.

73
src/openct/buffer.c Normal file
View File

@ -0,0 +1,73 @@
/*
* Buffer handling functions
*
* Copyright (C) 2003, Olaf Kirch <okir@suse.de>
*/
#include <config.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <openct/buffer.h>
void
ct_buf_init(ct_buf_t *bp, void *mem, size_t len)
{
memset(bp, 0, sizeof(*bp));
bp->base = (unsigned char *) mem;
bp->size = len;
}
void
ct_buf_set(ct_buf_t *bp, void *mem, size_t len)
{
ct_buf_init(bp, mem, len);
bp->tail = len;
}
int
ct_buf_get(ct_buf_t *bp, void *mem, size_t len)
{
if (len > bp->tail - bp->head)
return -1;
if (mem)
memcpy(mem, bp->base + bp->head, len);
bp->head += len;
return len;
}
int
ct_buf_put(ct_buf_t *bp, const void *mem, size_t len)
{
if (len > bp->size - bp->tail) {
bp->overrun = 1;
return -1;
}
if (mem)
memcpy(bp->base + bp->tail, mem, len);
bp->tail += len;
return len;
}
int
ct_buf_putc(ct_buf_t *bp, int byte)
{
unsigned char c = byte;
return ct_buf_put(bp, &c, 1);
}
unsigned int
ct_buf_avail(ct_buf_t *bp)
{
return bp->tail - bp->head;
}
void *
ct_buf_head(ct_buf_t *bp)
{
return bp->base + bp->head;
}

36
src/openct/buffer.h Normal file
View File

@ -0,0 +1,36 @@
/*
* Buffer handling functions of the IFD handler library
*
* Copyright (C) 2003, Olaf Kirch <okir@suse.de>
*/
#ifndef OPENCT_BUFFER_H
#define OPENCT_BUFFER_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
typedef struct ct_buf {
unsigned char * base;
unsigned int head, tail, size;
unsigned int overrun;
} ct_buf_t;
extern void ct_buf_init(ct_buf_t *, void *, size_t);
extern void ct_buf_set(ct_buf_t *, void *, size_t);
extern int ct_buf_get(ct_buf_t *, void *, size_t);
extern int ct_buf_put(ct_buf_t *, const void *, size_t);
extern int ct_buf_putc(ct_buf_t *, int);
extern unsigned int ct_buf_avail(ct_buf_t *);
extern void * ct_buf_head(ct_buf_t *);
#ifdef __cplusplus
}
#endif
#endif /* OPENCT_BUFFER_H */

95
src/openct/checksum.c Normal file
View File

@ -0,0 +1,95 @@
/*
* Checksum handling
*
* Copyright Matthias Bruestle 1999-2002
* For licensing, see the file LICENCE
*/
#include <config.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include "checksum.h"
#define min( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
/* ISO STD 3309 */
/* From: medin@catbyte.b30.ingr.com (Dave Medin)
* Subject: CCITT checksums
* Newsgroups: sci.electronics
* Date: Mon, 7 Dec 1992 17:33:39 GMT
*/
/* Correct Table? */
static unsigned short crctab[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
/*
* Returns LRC of data.
*/
unsigned int
csum_lrc_compute(const uint8_t *in, size_t len, unsigned char *rc)
{
unsigned char lrc = 0;
while (len--)
lrc ^= *in++;
if (rc)
*rc = lrc;
return 1;
}
/*
* Compute CRC of data.
*/
unsigned int
csum_crc_compute(const uint8_t * data, size_t len, unsigned char *rc)
{
unsigned short v = 0xFFFF;
while (len--) {
v = ((v >> 8) & 0xFF) ^ crctab[(v ^ *data++) & 0xFF];
}
if (rc) {
rc[0] = (v >> 8) & 0xFF;
rc[1] = v & 0xFF;
}
return 2;
}

35
src/openct/checksum.h Normal file
View File

@ -0,0 +1,35 @@
/*
checksum.h: header file checksum.c
Copyright (C) 2004 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __CHECKSUM_H__
#define __CHECKSUM_H__
#include <config.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
extern unsigned int csum_lrc_compute(const uint8_t *, size_t, unsigned char *);
extern unsigned int csum_crc_compute(const uint8_t *, size_t, unsigned char *);
#endif

800
src/openct/proto-t1.c Normal file
View File

@ -0,0 +1,800 @@
/*
* Implementation of T=1
*
* Copyright (C) 2003, Olaf Kirch <okir@suse.de>
*
* improvements by:
* Copyright (C) 2004 Ludovic Rousseau <ludovic.rousseau@free.fr>
*/
#include <config.h>
#include <pcsclite.h>
#include <ifdhandler.h>
#include "commands.h"
#include "buffer.h"
#include "debug.h"
#include "proto-t1.h"
#include "checksum.h"
#include "ccid.h"
#ifdef HAVE_STRING_H
#include <string.h>
#endif
/* I block */
#define T1_I_SEQ_SHIFT 6
/* R block */
#define T1_IS_ERROR(pcb) ((pcb) & 0x0F)
#define T1_EDC_ERROR 0x01
#define T1_OTHER_ERROR 0x02
#define T1_R_SEQ_SHIFT 4
/* S block stuff */
#define T1_S_IS_RESPONSE(pcb) ((pcb) & T1_S_RESPONSE)
#define T1_S_TYPE(pcb) ((pcb) & 0x0F)
#define T1_S_RESPONSE 0x20
#define T1_S_RESYNC 0x00
#define T1_S_IFS 0x01
#define T1_S_ABORT 0x02
#define T1_S_WTX 0x03
#define swap_nibbles(x) ( (x >> 4) | ((x & 0xF) << 4) )
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define NAD 0
#define PCB 1
#define LEN 2
#define DATA 3
/* internal state, do not mess with it. */
/* should be != DEAD after reset/init */
enum {
SENDING, RECEIVING, RESYNCH, DEAD
};
static void t1_set_checksum(t1_state_t *, int);
static unsigned int t1_block_type(unsigned char);
static unsigned int t1_seq(unsigned char);
static unsigned int t1_rebuild(t1_state_t *t1, unsigned char *block);
static unsigned int t1_compute_checksum(t1_state_t *, unsigned char *, size_t);
static int t1_verify_checksum(t1_state_t *, unsigned char *, size_t);
static int t1_xcv(t1_state_t *, unsigned char *, size_t, size_t);
/*
* Set default T=1 protocol parameters
*/
static void t1_set_defaults(t1_state_t * t1)
{
t1->retries = 3;
/* This timeout is rather insane, but we need this right now
* to support cryptoflex keygen */
t1->ifsc = 32;
t1->ifsd = 32;
t1->nr = 0;
t1->ns = 0;
t1->wtx = 0;
}
static void t1_set_checksum(t1_state_t * t1, int csum)
{
switch (csum) {
case IFD_PROTOCOL_T1_CHECKSUM_LRC:
t1->rc_bytes = 1;
t1->checksum = csum_lrc_compute;
break;
case IFD_PROTOCOL_T1_CHECKSUM_CRC:
t1->rc_bytes = 2;
t1->checksum = csum_crc_compute;
break;
}
}
/*
* Attach t1 protocol
*/
int t1_init(t1_state_t * t1, int lun)
{
t1_set_defaults(t1);
t1_set_param(t1, IFD_PROTOCOL_T1_CHECKSUM_LRC, 0);
t1_set_param(t1, IFD_PROTOCOL_T1_STATE, SENDING);
t1_set_param(t1, IFD_PROTOCOL_T1_MORE, FALSE);
t1->lun = lun;
return 0;
}
/*
* Detach t1 protocol
*/
void t1_release(/*@unused@*/ t1_state_t * t1)
{
(void)t1;
/* NOP */
}
/*
* Get/set parmaters for T1 protocol
*/
int t1_set_param(t1_state_t * t1, int type, long value)
{
switch (type) {
case IFD_PROTOCOL_T1_CHECKSUM_LRC:
case IFD_PROTOCOL_T1_CHECKSUM_CRC:
t1_set_checksum(t1, type);
break;
case IFD_PROTOCOL_T1_IFSC:
t1->ifsc = value;
break;
case IFD_PROTOCOL_T1_IFSD:
t1->ifsd = value;
break;
case IFD_PROTOCOL_T1_STATE:
t1->state = value;
break;
case IFD_PROTOCOL_T1_MORE:
t1->more = value;
break;
default:
DEBUG_INFO2("Unsupported parameter %d", type);
return -1;
}
return 0;
}
/*
* Send an APDU through T=1
*/
int t1_transceive(t1_state_t * t1, unsigned int dad,
const void *snd_buf, size_t snd_len,
void *rcv_buf, size_t rcv_len)
{
ct_buf_t sbuf, rbuf, tbuf;
unsigned char sdata[T1_BUFFER_SIZE], sblk[5];
unsigned int slen, retries, resyncs;
size_t last_send = 0;
if (snd_len == 0)
return -1;
/* we can't talk to a dead card / reader. Reset it! */
if (t1->state == DEAD)
{
DEBUG_CRITICAL("T=1 state machine is DEAD. Reset the card first.");
return -1;
}
t1->state = SENDING;
retries = t1->retries;
resyncs = 3;
/* Initialize send/recv buffer */
ct_buf_set(&sbuf, (void *)snd_buf, snd_len);
ct_buf_init(&rbuf, rcv_buf, rcv_len);
/* Send the first block */
slen = t1_build(t1, sdata, dad, T1_I_BLOCK, &sbuf, &last_send);
while (1) {
unsigned char pcb;
int n;
retries--;
n = t1_xcv(t1, sdata, slen, sizeof(sdata));
if (-2 == n)
{
DEBUG_COMM("Parity error");
/* ISO 7816-3 Rule 7.4.2 */
if (retries <= 0)
goto resync;
/* ISO 7816-3 Rule 7.2 */
if (T1_R_BLOCK == t1_block_type(t1->previous_block[PCB]))
{
DEBUG_COMM("Rule 7.2");
slen = t1_rebuild(t1, sdata);
continue;
}
slen = t1_build(t1, sdata,
dad, T1_R_BLOCK | T1_EDC_ERROR,
NULL, NULL);
continue;
}
if (n < 0) {
DEBUG_CRITICAL("fatal: transmit/receive failed");
t1->state = DEAD;
goto error;
}
if ((sdata[NAD] != swap_nibbles(dad)) /* wrong NAD */
|| (sdata[LEN] == 0xFF)) /* length == 0xFF (illegal) */
{
DEBUG_COMM("R-BLOCK required");
/* ISO 7816-3 Rule 7.4.2 */
if (retries <= 0)
goto resync;
/* ISO 7816-3 Rule 7.2 */
if (T1_R_BLOCK == t1_block_type(t1->previous_block[PCB]))
{
DEBUG_COMM("Rule 7.2");
slen = t1_rebuild(t1, sdata);
continue;
}
slen = t1_build(t1, sdata,
dad, T1_R_BLOCK | T1_OTHER_ERROR,
NULL, NULL);
continue;
}
if (!t1_verify_checksum(t1, sdata, n)) {
DEBUG_COMM("checksum failed");
/* ISO 7816-3 Rule 7.4.2 */
if (retries <= 0)
goto resync;
/* ISO 7816-3 Rule 7.2 */
if (T1_R_BLOCK == t1_block_type(t1->previous_block[PCB]))
{
DEBUG_COMM("Rule 7.2");
slen = t1_rebuild(t1, sdata);
continue;
}
slen = t1_build(t1, sdata,
dad, T1_R_BLOCK | T1_EDC_ERROR,
NULL, NULL);
continue;
}
pcb = sdata[PCB];
switch (t1_block_type(pcb)) {
case T1_R_BLOCK:
if ((sdata[LEN] != 0x00) /* length != 0x00 (illegal) */
|| (pcb & 0x20) /* b6 of pcb is set */
)
{
DEBUG_COMM("R-Block required");
/* ISO 7816-3 Rule 7.4.2 */
if (retries <= 0)
goto resync;
/* ISO 7816-3 Rule 7.2 */
if (T1_R_BLOCK == t1_block_type(t1->previous_block[1]))
{
DEBUG_COMM("Rule 7.2");
slen = t1_rebuild(t1, sdata);
continue;
}
slen = t1_build(t1, sdata,
dad, T1_R_BLOCK | T1_OTHER_ERROR,
NULL, NULL);
continue;
}
if (((t1_seq(pcb) != t1->ns) /* wrong sequence number & no bit more */
&& ! t1->more)
)
{
DEBUG_COMM4("received: %d, expected: %d, more: %d",
t1_seq(pcb), t1->ns, t1->more);
/* ISO 7816-3 Rule 7.4.2 */
if (retries <= 0)
goto resync;
/* ISO 7816-3 Rule 7.2 */
if (T1_R_BLOCK == t1_block_type(t1->previous_block[PCB]))
{
DEBUG_COMM("Rule 7.2");
slen = t1_rebuild(t1, sdata);
continue;
}
DEBUG_COMM("R-Block required");
slen = t1_build(t1, sdata,
dad, T1_R_BLOCK | T1_OTHER_ERROR,
NULL, NULL);
continue;
}
if (t1->state == RECEIVING) {
/* ISO 7816-3 Rule 7.2 */
if (T1_R_BLOCK == t1_block_type(t1->previous_block[1]))
{
/* ISO 7816-3 Rule 7.4.2 */
if (retries <= 0)
goto resync;
DEBUG_COMM("Rule 7.2");
slen = t1_rebuild(t1, sdata);
continue;
}
DEBUG_COMM("");
slen = t1_build(t1, sdata,
dad, T1_R_BLOCK,
NULL, NULL);
break;
}
/* If the card terminal requests the next
* sequence number, it received the previous
* block successfully */
if (t1_seq(pcb) != t1->ns) {
ct_buf_get(&sbuf, NULL, last_send);
last_send = 0;
t1->ns ^= 1;
}
/* If there's no data available, the ICC
* shouldn't be asking for more */
if (ct_buf_avail(&sbuf) == 0)
goto resync;
slen = t1_build(t1, sdata, dad, T1_I_BLOCK,
&sbuf, &last_send);
break;
case T1_I_BLOCK:
/* The first I-block sent by the ICC indicates
* the last block we sent was received successfully. */
if (t1->state == SENDING) {
DEBUG_COMM("");
ct_buf_get(&sbuf, NULL, last_send);
last_send = 0;
t1->ns ^= 1;
}
t1->state = RECEIVING;
/* If the block sent by the card doesn't match
* what we expected it to send, reply with
* an R block */
if (t1_seq(pcb) != t1->nr) {
DEBUG_COMM("wrong nr");
/* ISO 7816-3 Rule 7.4.2 */
if (retries <= 0)
goto resync;
slen = t1_build(t1, sdata, dad,
T1_R_BLOCK | T1_OTHER_ERROR,
NULL, NULL);
continue;
}
t1->nr ^= 1;
if (ct_buf_put(&rbuf, sdata + 3, sdata[LEN]) < 0)
{
DEBUG_CRITICAL2("buffer overrun by %d bytes", sdata[LEN] - (rbuf.size - rbuf.tail));
goto error;
}
if ((pcb & T1_MORE_BLOCKS) == 0)
goto done;
slen = t1_build(t1, sdata, dad, T1_R_BLOCK, NULL, NULL);
break;
case T1_S_BLOCK:
if (T1_S_IS_RESPONSE(pcb) && t1->state == RESYNCH) {
/* ISO 7816-3 Rule 6.2 */
DEBUG_COMM("S-Block answer received");
/* ISO 7816-3 Rule 6.3 */
t1->state = SENDING;
last_send = 0;
resyncs = 3;
retries = t1->retries;
ct_buf_init(&rbuf, rcv_buf, rcv_len);
slen = t1_build(t1, sdata, dad, T1_I_BLOCK,
&sbuf, &last_send);
continue;
}
if (T1_S_IS_RESPONSE(pcb))
{
/* ISO 7816-3 Rule 7.4.2 */
if (retries <= 0)
goto resync;
/* ISO 7816-3 Rule 7.2 */
if (T1_R_BLOCK == t1_block_type(t1->previous_block[PCB]))
{
DEBUG_COMM("Rule 7.2");
slen = t1_rebuild(t1, sdata);
continue;
}
DEBUG_CRITICAL("wrong response S-BLOCK received");
slen = t1_build(t1, sdata,
dad, T1_R_BLOCK | T1_OTHER_ERROR,
NULL, NULL);
continue;
}
ct_buf_init(&tbuf, sblk, sizeof(sblk));
DEBUG_COMM("S-Block request received");
switch (T1_S_TYPE(pcb)) {
case T1_S_RESYNC:
if (sdata[LEN] != 0)
{
DEBUG_COMM2("Wrong length: %d", sdata[LEN]);
slen = t1_build(t1, sdata, dad,
T1_R_BLOCK | T1_OTHER_ERROR,
NULL, NULL);
continue;
}
DEBUG_COMM("Resync requested");
/* the card is not allowed to send a resync. */
goto resync;
case T1_S_ABORT:
if (sdata[LEN] != 0)
{
DEBUG_COMM2("Wrong length: %d", sdata[LEN]);
slen = t1_build(t1, sdata, dad,
T1_R_BLOCK | T1_OTHER_ERROR,
NULL, NULL);
continue;
}
/* ISO 7816-3 Rule 9 */
DEBUG_CRITICAL("abort requested");
break;
case T1_S_IFS:
if (sdata[LEN] != 1)
{
DEBUG_COMM2("Wrong length: %d", sdata[LEN]);
slen = t1_build(t1, sdata, dad,
T1_R_BLOCK | T1_OTHER_ERROR,
NULL, NULL);
continue;
}
DEBUG_CRITICAL2("CT sent S-block with ifs=%u", sdata[DATA]);
if (sdata[DATA] == 0)
goto resync;
t1->ifsc = sdata[DATA];
ct_buf_putc(&tbuf, sdata[DATA]);
break;
case T1_S_WTX:
if (sdata[LEN] != 1)
{
DEBUG_COMM2("Wrong length: %d", sdata[LEN]);
slen = t1_build(t1, sdata, dad,
T1_R_BLOCK | T1_OTHER_ERROR,
NULL, NULL);
continue;
}
DEBUG_COMM2("CT sent S-block with wtx=%u", sdata[DATA]);
t1->wtx = sdata[DATA];
ct_buf_putc(&tbuf, sdata[DATA]);
break;
default:
DEBUG_CRITICAL2("T=1: Unknown S block type 0x%02x", T1_S_TYPE(pcb));
goto resync;
}
slen = t1_build(t1, sdata, dad,
T1_S_BLOCK | T1_S_RESPONSE | T1_S_TYPE(pcb),
&tbuf, NULL);
}
/* Everything went just splendid */
retries = t1->retries;
continue;
resync:
/* the number or resyncs is limited, too */
/* ISO 7816-3 Rule 6.4 */
if (resyncs == 0)
goto error;
/* ISO 7816-3 Rule 6 */
resyncs--;
t1->ns = 0;
t1->nr = 0;
slen = t1_build(t1, sdata, dad, T1_S_BLOCK | T1_S_RESYNC, NULL,
NULL);
t1->state = RESYNCH;
t1->more = FALSE;
retries = 1;
continue;
}
done:
return ct_buf_avail(&rbuf);
error:
t1->state = DEAD;
return -1;
}
static unsigned t1_block_type(unsigned char pcb)
{
switch (pcb & 0xC0) {
case T1_R_BLOCK:
return T1_R_BLOCK;
case T1_S_BLOCK:
return T1_S_BLOCK;
default:
return T1_I_BLOCK;
}
}
static unsigned int t1_seq(unsigned char pcb)
{
switch (pcb & 0xC0) {
case T1_R_BLOCK:
return (pcb >> T1_R_SEQ_SHIFT) & 1;
case T1_S_BLOCK:
return 0;
default:
return (pcb >> T1_I_SEQ_SHIFT) & 1;
}
}
unsigned int t1_build(t1_state_t * t1, unsigned char *block,
unsigned char dad, unsigned char pcb,
ct_buf_t *bp, size_t *lenp)
{
unsigned int len;
char more = FALSE;
len = bp ? ct_buf_avail(bp) : 0;
if (len > t1->ifsc) {
pcb |= T1_MORE_BLOCKS;
len = t1->ifsc;
more = TRUE;
}
/* Add the sequence number */
switch (t1_block_type(pcb)) {
case T1_R_BLOCK:
pcb |= t1->nr << T1_R_SEQ_SHIFT;
break;
case T1_I_BLOCK:
pcb |= t1->ns << T1_I_SEQ_SHIFT;
t1->more = more;
DEBUG_COMM2("more bit: %d", more);
break;
}
block[0] = dad;
block[1] = pcb;
block[2] = len;
if (len)
memcpy(block + 3, ct_buf_head(bp), len);
if (lenp)
*lenp = len;
len = t1_compute_checksum(t1, block, len + 3);
/* memorize the last sent block */
/* only 4 bytes since we are only interesed in R-blocks */
memcpy(t1->previous_block, block, 4);
return len;
}
static unsigned int
t1_rebuild(t1_state_t *t1, unsigned char *block)
{
unsigned char pcb = t1 -> previous_block[1];
/* copy the last sent block */
if (T1_R_BLOCK == t1_block_type(pcb))
memcpy(block, t1 -> previous_block, 4);
else
{
DEBUG_CRITICAL2("previous block was not R-Block: %02X", pcb);
return 0;
}
return 4;
}
/*
* Build/verify checksum
*/
static unsigned int t1_compute_checksum(t1_state_t * t1,
unsigned char *data, size_t len)
{
return len + t1->checksum(data, len, data + len);
}
static int t1_verify_checksum(t1_state_t * t1, unsigned char *rbuf,
size_t len)
{
unsigned char csum[2];
int m, n;
m = len - t1->rc_bytes;
n = t1->rc_bytes;
if (m < 0)
return 0;
t1->checksum(rbuf, m, csum);
if (!memcmp(rbuf + m, csum, n))
return 1;
return 0;
}
/*
* Send/receive block
*/
static int t1_xcv(t1_state_t * t1, unsigned char *block, size_t slen,
size_t rmax)
{
int n;
_ccid_descriptor *ccid_desc ;
int oldReadTimeout;
unsigned int rmax_int;
DEBUG_XXD("sending: ", block, slen);
ccid_desc = get_ccid_descriptor(t1->lun);
oldReadTimeout = ccid_desc->readTimeout;
if (t1->wtx > 1)
{
/* set the new temporary timeout at WTX card request */
ccid_desc->readTimeout *= t1->wtx;
DEBUG_INFO2("New timeout at WTX request: %d sec",
ccid_desc->readTimeout);
}
if (isCharLevel(t1->lun))
{
rmax = 3;
n = CCID_Transmit(t1 -> lun, slen, block, rmax, t1->wtx);
if (n != IFD_SUCCESS)
return -1;
/* the second argument of CCID_Receive() is (unsigned int *)
* so we can't use &rmax since &rmax is a (size_t *) and may not
* be the same on 64-bits architectures for example (iMac G5) */
rmax_int = rmax;
n = CCID_Receive(t1 -> lun, &rmax_int, block, NULL);
if (n == IFD_PARITY_ERROR)
return -2;
if (n != IFD_SUCCESS)
return -1;
rmax = block[2] + 1;
n = CCID_Transmit(t1 -> lun, 0, block, rmax, t1->wtx);
if (n != IFD_SUCCESS)
return -1;
rmax_int = rmax;
n = CCID_Receive(t1 -> lun, &rmax_int, &block[3], NULL);
rmax = rmax_int;
if (n == IFD_PARITY_ERROR)
return -2;
if (n != IFD_SUCCESS)
return -1;
n = rmax + 3;
}
else
{
n = CCID_Transmit(t1 -> lun, slen, block, 0, t1->wtx);
t1->wtx = 0; /* reset to default value */
if (n != IFD_SUCCESS)
return -1;
/* Get the response en bloc */
rmax_int = rmax;
n = CCID_Receive(t1 -> lun, &rmax_int, block, NULL);
rmax = rmax_int;
if (n == IFD_PARITY_ERROR)
return -2;
if (n != IFD_SUCCESS)
return -1;
n = rmax;
}
if (n >= 0)
{
int m;
m = block[2] + 3 + t1->rc_bytes;
if (m < n)
n = m;
}
if (n >= 0)
DEBUG_XXD("received: ", block, n);
/* Restore initial timeout */
ccid_desc->readTimeout = oldReadTimeout;
return n;
}
int t1_negotiate_ifsd(t1_state_t * t1, unsigned int dad, int ifsd)
{
ct_buf_t sbuf;
unsigned char sdata[T1_BUFFER_SIZE];
unsigned int slen;
unsigned int retries;
size_t snd_len;
int n;
unsigned char snd_buf[1];
retries = t1->retries;
/* S-block IFSD request */
snd_buf[0] = ifsd;
snd_len = 1;
/* Initialize send/recv buffer */
ct_buf_set(&sbuf, (void *)snd_buf, snd_len);
while (TRUE)
{
/* Build the block */
slen = t1_build(t1, sdata, 0, T1_S_BLOCK | T1_S_IFS, &sbuf, NULL);
/* Send the block */
n = t1_xcv(t1, sdata, slen, sizeof(sdata));
retries--;
/* ISO 7816-3 Rule 7.4.2 */
if (retries <= 0)
goto error;
if (-1 == n)
{
DEBUG_CRITICAL("fatal: transmit/receive failed");
goto error;
}
if ((-2 == n) /* Parity error */
|| (sdata[DATA] != ifsd) /* Wrong ifsd received */
|| (sdata[NAD] != swap_nibbles(dad)) /* wrong NAD */
|| (!t1_verify_checksum(t1, sdata, n)) /* checksum failed */
|| (n != 4 + (int)t1->rc_bytes) /* wrong frame length */
|| (sdata[LEN] != 1) /* wrong data length */
|| (sdata[PCB] != (T1_S_BLOCK | T1_S_RESPONSE | T1_S_IFS))) /* wrong PCB */
continue;
/* no more error */
goto done;
}
done:
return n;
error:
t1->state = DEAD;
return -1;
}

83
src/openct/proto-t1.h Normal file
View File

@ -0,0 +1,83 @@
/*
proto-t1.h: header file for proto-t1.c
Copyright (C) 2004 Ludovic Rousseau
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __PROTO_T1_H__
#define __PROTO_T1_H__
#include <config.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include "buffer.h"
/* T=1 protocol constants */
#define T1_I_BLOCK 0x00
#define T1_R_BLOCK 0x80
#define T1_S_BLOCK 0xC0
#define T1_MORE_BLOCKS 0x20
enum {
IFD_PROTOCOL_RECV_TIMEOUT = 0x0000,
IFD_PROTOCOL_T1_BLOCKSIZE,
IFD_PROTOCOL_T1_CHECKSUM_CRC,
IFD_PROTOCOL_T1_CHECKSUM_LRC,
IFD_PROTOCOL_T1_IFSC,
IFD_PROTOCOL_T1_IFSD,
IFD_PROTOCOL_T1_STATE,
IFD_PROTOCOL_T1_MORE
};
#define T1_BUFFER_SIZE (3 + 254 + 2)
/* see /usr/include/PCSC/ifdhandler.h for other values
* this one is for internal use only */
#define IFD_PARITY_ERROR 699
typedef struct {
int lun;
int state;
unsigned char ns; /* reader side */
unsigned char nr; /* card side */
unsigned int ifsc;
unsigned int ifsd;
unsigned char wtx;
unsigned int retries;
unsigned int rc_bytes;
unsigned int (*checksum)(const uint8_t *, size_t, unsigned char *);
char more; /* more data bit */
unsigned char previous_block[4]; /* to store the last R-block */
} t1_state_t;
int t1_transceive(t1_state_t *t1, unsigned int dad,
const void *snd_buf, size_t snd_len,
void *rcv_buf, size_t rcv_len);
int t1_init(t1_state_t *t1, int lun);
void t1_release(t1_state_t *t1);
int t1_set_param(t1_state_t *t1, int type, long value);
int t1_negotiate_ifsd(t1_state_t *t1, unsigned int dad, int ifsd);
unsigned int t1_build(t1_state_t *, unsigned char *,
unsigned char, unsigned char, ct_buf_t *, size_t *);
#endif

589
src/parse.c Normal file
View File

@ -0,0 +1,589 @@
/*
parse.c: parse CCID structure
Copyright (C) 2003-2010 Ludovic Rousseau
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc., 51
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <string.h>
# ifdef S_SPLINT_S
# include <sys/types.h>
# endif
#include <errno.h>
#include <unistd.h>
#include "defs.h"
#include "ccid.h"
/* define DISPLAY_EXTRA_VALUES to display the extra (invalid) values
* returned by bNumClockSupported and bNumDataRatesSupported */
#undef DISPLAY_EXTRA_VALUES
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define BLUE "\33[34m"
#define RED "\33[31m"
#define BRIGHT_RED "\33[01;31m"
#define GREEN "\33[32m"
#define MAGENTA "\33[35m"
#define NORMAL "\33[0m"
/* global variables used in ccid_usb.c but defined in ifdhandler.c */
int LogLevel = 1+2+4+8; /* full debug */
int DriverOptions = 0;
static int ccid_parse_interface_descriptor(libusb_device_handle *handle,
struct libusb_device_descriptor desc,
struct libusb_config_descriptor *config_desc,
int num,
const struct libusb_interface *usb_interface);
/*****************************************************************************
*
* main
*
****************************************************************************/
int main(int argc, char *argv[])
{
libusb_device **devs, *dev;
int nb = 0, r, i;
unsigned char buffer[256];
char class_ff = FALSE;
ssize_t cnt;
if ((argc > 1) && (0 == strcmp(argv[1], "-p")))
class_ff = TRUE;
r = libusb_init(NULL);
if (r < 0)
{
(void)printf("libusb_init() failed\n");
return r;
}
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0)
{
(void)printf("libusb_get_device_list() failed\n");
return (int)cnt;
}
/* for every device */
i = 0;
while ((dev = devs[i++]) != NULL)
{
struct libusb_device_descriptor desc;
struct libusb_config_descriptor *config_desc;
struct libusb_device_handle *handle;
const struct libusb_interface *usb_interface = NULL;
#ifndef __APPLE__
int interface;
#endif
int num = 0;
r = libusb_open(dev, &handle);
if (r < 0)
{
(void)fprintf(stderr, "Can't libusb_open(): %s\n", strerror(errno));
if (getuid())
{
(void)fprintf(stderr,
BRIGHT_RED "Please, restart the command as root\n" NORMAL);
return 1;
}
continue;
}
r = libusb_get_device_descriptor(dev, &desc);
if (r < 0)
{
(void)fprintf(stderr,
BRIGHT_RED "failed to get device descriptor" NORMAL);
return 1;
}
(void)fprintf(stderr,
"Parsing USB bus/device: %04X:%04X (bus %d, device %d)\n",
desc.idVendor, desc.idProduct,
libusb_get_bus_number(dev), libusb_get_device_address(dev));
(void)fprintf(stderr, " idVendor: 0x%04X", desc.idVendor);
r = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer,
buffer, sizeof(buffer));
if (r < 0)
{
(void)fprintf(stderr, " Can't get iManufacturer string\n");
if (getuid())
{
(void)fprintf(stderr,
BRIGHT_RED "Please, restart the command as root\n" NORMAL);
return 1;
}
}
else
(void)fprintf(stderr,
" iManufacturer: " BLUE "%s\n" NORMAL, buffer);
(void)fprintf(stderr, " idProduct: 0x%04X", desc.idProduct);
r = libusb_get_string_descriptor_ascii(handle, desc.iProduct,
buffer, sizeof(buffer));
if (r < 0)
(void)fprintf(stderr, " Can't get iProduct string\n");
else
(void)fprintf(stderr, " iProduct: " BLUE "%s\n" NORMAL, buffer);
again:
/* check if the device has bInterfaceClass == 11 */
r = libusb_get_active_config_descriptor(dev, &config_desc);
if (r < 0)
{
(void)fprintf(stderr, " Can't get config descriptor: %d\n", r);
(void)libusb_close(handle);
continue;
}
usb_interface = get_ccid_usb_interface(config_desc, &num);
if (NULL == usb_interface)
{
(void)libusb_close(handle);
/* only if we found no CCID interface */
if (0 == num)
(void)fprintf(stderr, RED " NOT a CCID/ICCD device\n" NORMAL);
continue;
}
if (!class_ff && (0xFF == usb_interface->altsetting->bInterfaceClass))
{
(void)libusb_close(handle);
(void)fprintf(stderr, MAGENTA " Found a possibly CCID/ICCD device (bInterfaceClass = 0xFF). Use %s -p\n" NORMAL, argv[0]);
continue;
}
(void)fprintf(stderr,
GREEN " Found a CCID/ICCD device at interface %d\n" NORMAL, num);
/* now we found a free reader and we try to use it */
#if 0
if (NULL == dev->config)
{
(void)libusb_close(handle);
(void)fprintf(stderr, "No dev->config found for %s/%s\n",
bus->dirname, dev->filename);
continue;
}
#endif
#ifndef __APPLE__
interface = usb_interface->altsetting->bInterfaceNumber;
r = libusb_claim_interface(handle, interface);
if (r < 0)
{
(void)fprintf(stderr,
"Can't claim interface (bus %d, device %d): %s\n",
libusb_get_bus_number(dev), libusb_get_device_address(dev),
strerror(errno));
(void)libusb_close(handle);
if (EBUSY == errno)
{
(void)fprintf(stderr,
BRIGHT_RED " Please, stop pcscd and retry\n\n" NORMAL);
if (class_ff)
/* maybe the device with Class = 0xFF is NOT a CCID
* reader */
continue;
else
return TRUE;
}
continue;
}
#endif
(void)ccid_parse_interface_descriptor(handle, desc, config_desc, num,
usb_interface);
nb++;
#ifndef __APPLE__
(void)libusb_release_interface(handle, interface);
#endif
/* check for another CCID interface on the same device */
num++;
goto again;
}
if ((0 == nb) && (0 != geteuid()))
(void)fprintf(stderr,
"Can't find any CCID device.\nMaybe you must run parse as root?\n");
libusb_exit(NULL);
return 0;
} /* main */
/*****************************************************************************
*
* Parse a CCID USB Descriptor
*
****************************************************************************/
static int ccid_parse_interface_descriptor(libusb_device_handle *handle,
struct libusb_device_descriptor desc,
struct libusb_config_descriptor *config_desc,
int num,
const struct libusb_interface *usb_interface)
{
const struct libusb_interface_descriptor *usb_interface_descriptor;
const unsigned char *device_descriptor;
unsigned char buffer[256*sizeof(int)]; /* maximum is 256 records */
int r;
/*
* Vendor/model name
*/
(void)printf(" idVendor: 0x%04X\n", desc.idVendor);
r = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer,
buffer, sizeof(buffer));
if (r < 0)
{
(void)printf(" Can't get iManufacturer string\n");
if (getuid())
{
(void)fprintf(stderr,
BRIGHT_RED "Please, restart the command as root\n\n" NORMAL);
return TRUE;
}
}
else
(void)printf(" iManufacturer: %s\n", buffer);
(void)printf(" idProduct: 0x%04X\n", desc.idProduct);
r = libusb_get_string_descriptor_ascii(handle, desc.iProduct,
buffer, sizeof(buffer));
if (r < 0)
(void)printf(" Can't get iProduct string\n");
else
(void)printf(" iProduct: %s\n", buffer);
(void)printf(" bcdDevice: %X.%02X (firmware release?)\n",
desc.bcdDevice >> 8, desc.bcdDevice & 0xFF);
usb_interface_descriptor = get_ccid_usb_interface(config_desc, &num)->altsetting;
(void)printf(" bLength: %d\n", usb_interface_descriptor->bLength);
(void)printf(" bDescriptorType: %d\n", usb_interface_descriptor->bDescriptorType);
(void)printf(" bInterfaceNumber: %d\n", usb_interface_descriptor->bInterfaceNumber);
(void)printf(" bAlternateSetting: %d\n", usb_interface_descriptor->bAlternateSetting);
(void)printf(" bNumEndpoints: %d\n", usb_interface_descriptor->bNumEndpoints);
switch (usb_interface_descriptor->bNumEndpoints)
{
case 0:
(void)printf(" Control only\n");
break;
case 1:
(void)printf(" Interrupt-IN\n");
break;
case 2:
(void)printf(" bulk-IN and bulk-OUT\n");
break;
case 3:
(void)printf(" bulk-IN, bulk-OUT and Interrupt-IN\n");
break;
default:
(void)printf(" UNKNOWN value\n");
}
(void)printf(" bInterfaceClass: 0x%02X", usb_interface_descriptor->bInterfaceClass);
if (usb_interface_descriptor->bInterfaceClass == 0x0b)
(void)printf(" [Chip Card Interface Device Class (CCID)]\n");
else
{
(void)printf("\n NOT A CCID DEVICE\n");
if (usb_interface_descriptor->bInterfaceClass != 0xFF)
return TRUE;
else
(void)printf(" Class is 0xFF (proprietary)\n");
}
(void)printf(" bInterfaceSubClass: %d\n",
usb_interface_descriptor->bInterfaceSubClass);
if (usb_interface_descriptor->bInterfaceSubClass)
(void)printf(" UNSUPPORTED SubClass\n");
(void)printf(" bInterfaceProtocol: %d\n",
usb_interface_descriptor->bInterfaceProtocol);
switch (usb_interface_descriptor->bInterfaceProtocol)
{
case 0:
(void)printf(" bulk transfer, optional interrupt-IN (CCID)\n");
break;
case 1:
(void)printf(" ICCD Version A, Control transfers, (no interrupt-IN)\n");
break;
case 2:
(void)printf(" ICCD Version B, Control transfers, (optional interrupt-IN)\n");
break;
default:
(void)printf(" UNSUPPORTED InterfaceProtocol\n");
}
r = libusb_get_string_descriptor_ascii(handle, usb_interface_descriptor->iInterface,
buffer, sizeof(buffer));
if (r < 0)
(void)printf(" Can't get iInterface string\n");
else
(void)printf(" iInterface: %s\n", buffer);
device_descriptor = get_ccid_device_descriptor(usb_interface);
if (NULL == device_descriptor)
{
(void)printf("\n NOT A CCID DEVICE\n");
return TRUE;
}
/*
* CCID Class Descriptor
*/
(void)printf(" CCID Class Descriptor\n");
(void)printf(" bLength: 0x%02X\n", device_descriptor[0]);
if (device_descriptor[0] != 0x36)
{
(void)printf(" UNSUPPORTED bLength\n");
return TRUE;
}
(void)printf(" bDescriptorType: 0x%02X\n", device_descriptor[1]);
if (device_descriptor[1] != 0x21)
{
if (0xFF == device_descriptor[1])
(void)printf(" PROPRIETARY bDescriptorType\n");
else
{
(void)printf(" UNSUPPORTED bDescriptorType\n");
return TRUE;
}
}
(void)printf(" bcdCCID: %X.%02X\n", device_descriptor[3], device_descriptor[2]);
(void)printf(" bMaxSlotIndex: 0x%02X\n", device_descriptor[4]);
(void)printf(" bVoltageSupport: 0x%02X\n", device_descriptor[5]);
if (device_descriptor[5] & 0x01)
(void)printf(" 5.0V\n");
if (device_descriptor[5] & 0x02)
(void)printf(" 3.0V\n");
if (device_descriptor[5] & 0x04)
(void)printf(" 1.8V\n");
(void)printf(" dwProtocols: 0x%02X%02X 0x%02X%02X\n", device_descriptor[9], device_descriptor[8],
device_descriptor[7], device_descriptor[6]);
if (device_descriptor[6] & 0x01)
(void)printf(" T=0\n");
if (device_descriptor[6] & 0x02)
(void)printf(" T=1\n");
(void)printf(" dwDefaultClock: %.3f MHz\n", dw2i(device_descriptor, 10)/1000.0);
(void)printf(" dwMaximumClock: %.3f MHz\n", dw2i(device_descriptor, 14)/1000.0);
(void)printf(" bNumClockSupported: %d%s\n", device_descriptor[18],
device_descriptor[18] ? "" : " (will use whatever is returned)");
{
int n;
/* See CCID 3.7.2 page 25 */
n = libusb_control_transfer(handle,
0xA1, /* request type */
0x02, /* GET CLOCK FREQUENCIES */
0x00, /* value */
usb_interface_descriptor->bInterfaceNumber, /* interface */
buffer,
sizeof(buffer),
2 * 1000);
/* we got an error? */
if (n <= 0)
{
(void)(void)printf(" IFD does not support GET CLOCK FREQUENCIES request: %s\n", strerror(errno));
if (EBUSY == errno)
{
(void)fprintf(stderr,
BRIGHT_RED " Please, stop pcscd and retry\n\n" NORMAL);
return TRUE;
}
}
else
if (n % 4) /* not a multiple of 4 */
(void)printf(" wrong size for GET CLOCK FREQUENCIES: %d\n", n);
else
{
int i;
/* we do not get the expected number of data rates */
if ((n != device_descriptor[18]*4) && device_descriptor[18])
{
(void)printf(" Got %d clock frequencies but was expecting %d\n",
n/4, device_descriptor[18]);
/* we got more data than expected */
#ifndef DISPLAY_EXTRA_VALUES
if (n > device_descriptor[18]*4)
n = device_descriptor[18]*4;
#endif
}
for (i=0; i<n; i+=4)
(void)printf(" Support %d kHz\n", dw2i(buffer, i));
}
}
(void)printf(" dwDataRate: %d bps\n", dw2i(device_descriptor, 19));
(void)printf(" dwMaxDataRate: %d bps\n", dw2i(device_descriptor, 23));
(void)printf(" bNumDataRatesSupported: %d%s\n", device_descriptor[27],
device_descriptor[27] ? "" : " (will use whatever is returned)");
{
int n;
/* See CCID 3.7.3 page 25 */
n = libusb_control_transfer(handle,
0xA1, /* request type */
0x03, /* GET DATA RATES */
0x00, /* value */
usb_interface_descriptor->bInterfaceNumber, /* interface */
buffer,
sizeof(buffer),
2 * 1000);
/* we got an error? */
if (n <= 0)
(void)printf(" IFD does not support GET_DATA_RATES request: %s\n",
strerror(errno));
else
if (n % 4) /* not a multiple of 4 */
(void)printf(" wrong size for GET_DATA_RATES: %d\n", n);
else
{
int i;
/* we do not get the expected number of data rates */
if ((n != device_descriptor[27]*4) && device_descriptor[27])
{
(void)printf(" Got %d data rates but was expecting %d\n", n/4,
device_descriptor[27]);
/* we got more data than expected */
#ifndef DISPLAY_EXTRA_VALUES
if (n > device_descriptor[27]*4)
n = device_descriptor[27]*4;
#endif
}
for (i=0; i<n; i+=4)
(void)printf(" Support %d bps\n", dw2i(buffer, i));
}
}
(void)printf(" dwMaxIFSD: %d\n", dw2i(device_descriptor, 28));
(void)printf(" dwSynchProtocols: 0x%08X\n", dw2i(device_descriptor, 32));
if (device_descriptor[32] & 0x01)
(void)printf(" 2-wire protocol\n");
if (device_descriptor[32] & 0x02)
(void)printf(" 3-wire protocol\n");
if (device_descriptor[32] & 0x04)
(void)printf(" I2C protocol\n");
(void)printf(" dwMechanical: 0x%08X\n", dw2i(device_descriptor, 36));
if (device_descriptor[36] == 0)
(void)printf(" No special characteristics\n");
if (device_descriptor[36] & 0x01)
(void)printf(" Card accept mechanism\n");
if (device_descriptor[36] & 0x02)
(void)printf(" Card ejection mechanism\n");
if (device_descriptor[36] & 0x04)
(void)printf(" Card capture mechanism\n");
if (device_descriptor[36] & 0x08)
(void)printf(" Card lock/unlock mechanism\n");
(void)printf(" dwFeatures: 0x%08X\n", dw2i(device_descriptor, 40));
if (dw2i(device_descriptor, 40) == 0)
(void)printf(" No special characteristics\n");
if (device_descriptor[40] & 0x02)
(void)printf(" ....02 Automatic parameter configuration based on ATR data\n");
if (device_descriptor[40] & 0x04)
(void)printf(" ....04 Automatic activation of ICC on inserting\n");
if (device_descriptor[40] & 0x08)
(void)printf(" ....08 Automatic ICC voltage selection\n");
if (device_descriptor[40] & 0x10)
(void)printf(" ....10 Automatic ICC clock frequency change according to parameters\n");
if (device_descriptor[40] & 0x20)
(void)printf(" ....20 Automatic baud rate change according to frequency and Fi, Di params\n");
if (device_descriptor[40] & 0x40)
(void)printf(" ....40 Automatic parameters negotiation made by the CCID\n");
if (device_descriptor[40] & 0x80)
(void)printf(" ....80 Automatic PPS made by the CCID\n");
if (device_descriptor[41] & 0x01)
(void)printf(" ..01.. CCID can set ICC in clock stop mode\n");
if (device_descriptor[41] & 0x02)
(void)printf(" ..02.. NAD value other than 00 accepted (T=1)\n");
if (device_descriptor[41] & 0x04)
(void)printf(" ..04.. Automatic IFSD exchange as first exchange (T=1)\n");
if (device_descriptor[41] & 0x08)
(void)printf(" ..08.. Unknown (ICCD?)\n");
switch (device_descriptor[42] & 0x07)
{
case 0x00:
(void)printf(" 00.... Character level exchange\n");
break;
case 0x01:
(void)printf(" 01.... TPDU level exchange\n");
break;
case 0x02:
(void)printf(" 02.... Short APDU level exchange\n");
break;
case 0x04:
(void)printf(" 04.... Short and Extended APDU level exchange\n");
break;
}
if (device_descriptor[42] & 0x10)
(void)printf(" 10.... USB Wake up signaling supported on card insertion and removal\n");
(void)printf(" dwMaxCCIDMessageLength: %d bytes\n", dw2i(device_descriptor, 44));
(void)printf(" bClassGetResponse: 0x%02X\n", device_descriptor[48]);
if (0xFF == device_descriptor[48])
(void)printf(" echoes the APDU class\n");
(void)printf(" bClassEnvelope: 0x%02X\n", device_descriptor[49]);
if (0xFF == device_descriptor[49])
(void)printf(" echoes the APDU class\n");
(void)printf(" wLcdLayout: 0x%04X\n", (device_descriptor[51] << 8)+device_descriptor[50]);
if (device_descriptor[51])
(void)printf(" %2d lines\n", device_descriptor[51]);
if (device_descriptor[50])
(void)printf(" %2d characters per line\n", device_descriptor[50]);
(void)printf(" bPINSupport: 0x%02X\n", device_descriptor[52]);
if (device_descriptor[52] & 0x01)
(void)printf(" PIN Verification supported\n");
if (device_descriptor[52] & 0x02)
(void)printf(" PIN Modification supported\n");
(void)printf(" bMaxCCIDBusySlots: %d\n", device_descriptor[53]);
return FALSE;
} /* ccid_parse_interface_descriptor */

53
src/parser.h Normal file
View File

@ -0,0 +1,53 @@
/*
* MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
*
* Copyright (C) 2003
* Toni Andjelkovic <toni@soth.at>
* Copyright (C) 2003-2009
* Ludovic Rousseau <ludovic.rousseau@free.fr>
*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief Reads lexical config files and updates database.
*/
#ifndef __parser_h__
#define __parser_h__
#include "simclist.h"
struct bundleElt
{
char *key;
list_t values;
};
int LTPBundleFindValueWithKey(list_t *l, const char *key, list_t **values);
int bundleParse(const char *fileName, list_t *l);
void bundleRelease(list_t *l);
#endif

14
src/reader.conf.in Normal file
View File

@ -0,0 +1,14 @@
# Gemalto reader with serial communication
# - n is the serial port to use n in [0..3]
# - reader is the reader name. It is needed for multi-slot readers.
# Possible reader values are:
# GemCorePOSPro
# GemCoreSIMPro
# GemCoreSIMPro2
# GemPCPinPad
# GemPCTwin (default value)
# SEC1210 (Dual slot Reader)
# example: /dev/ttyS0:GemPCPinPad
#DEVICENAME /dev/ttySn[:reader]
#FRIENDLYNAME "GemPCTwin serial"
#LIBPATH TARGET

1525
src/simclist.c Normal file

File diff suppressed because it is too large Load Diff

980
src/simclist.h Normal file
View File

@ -0,0 +1,980 @@
/*
* Copyright (c) 2007,2008 Mij <mij@bitchx.it>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* SimCList library. See http://mij.oltrelinux.com/devel/simclist
*/
#ifndef SIMCLIST_H
#define SIMCLIST_H
#ifdef __cplusplus
extern "C" {
#endif
#include <inttypes.h>
#include <errno.h>
#include <sys/types.h>
#ifndef SIMCLIST_NO_DUMPRESTORE
# ifndef _WIN32
# include <sys/time.h> /* list_dump_info_t's struct timeval */
# else
# include <time.h>
# endif
#endif
/* Be friend of both C90 and C99 compilers */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/* "inline" and "restrict" are keywords */
#else
# define inline /* inline */
# define restrict /* restrict */
#endif
/**
* Type representing list hashes.
*
* This is a signed integer value.
*/
typedef int32_t list_hash_t;
#ifndef SIMCLIST_NO_DUMPRESTORE
typedef struct {
uint16_t version; /* dump version */
struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */
uint32_t list_size;
uint32_t list_numels;
list_hash_t list_hash; /* hash of the list when dumped, or 0 if invalid */
uint32_t dumpsize;
int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */
} list_dump_info_t;
#endif
/**
* a comparator of elements.
*
* A comparator of elements is a function that:
* -# receives two references to elements a and b
* -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively
*
* It is responsability of the function to handle possible NULL values.
*/
typedef int (*element_comparator)(const void *a, const void *b);
/**
* a seeker of elements.
*
* An element seeker is a function that:
* -# receives a reference to an element el
* -# receives a reference to some indicator data
* -# returns non-0 if the element matches the indicator, 0 otherwise
*
* It is responsability of the function to handle possible NULL values in any
* argument.
*/
typedef int (*element_seeker)(const void *el, const void *indicator);
/**
* an element lenght meter.
*
* An element meter is a function that:
* -# receives the reference to an element el
* -# returns its size in bytes
*
* It is responsability of the function to handle possible NULL values.
*/
typedef size_t (*element_meter)(const void *el);
/**
* a function computing the hash of elements.
*
* An hash computing function is a function that:
* -# receives the reference to an element el
* -# returns a hash value for el
*
* It is responsability of the function to handle possible NULL values.
*/
typedef list_hash_t (*element_hash_computer)(const void *el);
/**
* a function for serializing an element.
*
* A serializer function is one that gets a reference to an element,
* and returns a reference to a buffer that contains its serialization
* along with the length of this buffer.
* It is responsability of the function to handle possible NULL values,
* returning a NULL buffer and a 0 buffer length.
*
* These functions have 3 goals:
* -# "freeze" and "flatten" the memory representation of the element
* -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations
* -# possibly extract a compressed representation of the element
*
* @param el reference to the element data
* @param serialize_buffer reference to fill with the length of the buffer
* @return reference to the buffer with the serialized data
*/
typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len);
/**
* a function for un-serializing an element.
*
* An unserializer function accomplishes the inverse operation of the
* serializer function. An unserializer function is one that gets a
* serialized representation of an element and turns it backe to the original
* element. The serialized representation is passed as a reference to a buffer
* with its data, and the function allocates and returns the buffer containing
* the original element, and it sets the length of this buffer into the
* integer passed by reference.
*
* @param data reference to the buffer with the serialized representation of the element
* @param data_len reference to the location where to store the length of the data in the buffer returned
* @return reference to a buffer with the original, unserialized representation of the element
*/
typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len);
/* [private-use] list entry -- olds actual user datum */
struct list_entry_s {
void *data;
/* doubly-linked list service references */
struct list_entry_s *next;
struct list_entry_s *prev;
};
/* [private-use] list attributes */
struct list_attributes_s {
/* user-set routine for comparing list elements */
element_comparator comparator;
/* user-set routing for seeking elements */
element_seeker seeker;
/* user-set routine for determining the length of an element */
element_meter meter;
int copy_data;
/* user-set routine for computing the hash of an element */
element_hash_computer hasher;
/* user-set routine for serializing an element */
element_serializer serializer;
/* user-set routine for unserializing an element */
element_unserializer unserializer;
};
/** list object */
typedef struct {
struct list_entry_s *head_sentinel;
struct list_entry_s *tail_sentinel;
struct list_entry_s *mid;
unsigned int numels;
/* array of spare elements */
struct list_entry_s **spareels;
unsigned int spareelsnum;
#ifdef SIMCLIST_WITH_THREADS
/* how many threads are currently running */
unsigned int threadcount;
#endif
/* service variables for list iteration */
int iter_active;
unsigned int iter_pos;
struct list_entry_s *iter_curentry;
/* list attributes */
struct list_attributes_s attrs;
} list_t;
/**
* initialize a list object for use.
*
* @param l must point to a user-provided memory location
* @return 0 for success. -1 for failure
*/
int list_init(list_t *restrict l);
/**
* completely remove the list from memory.
*
* This function is the inverse of list_init(). It is meant to be called when
* the list is no longer going to be used. Elements and possible memory taken
* for internal use are freed.
*
* @param l list to destroy
*/
void list_destroy(list_t *restrict l);
/**
* set the comparator function for list elements.
*
* Comparator functions are used for searching and sorting. If NULL is passed
* as reference to the function, the comparator is disabled.
*
* @param l list to operate
* @param comparator_fun pointer to the actual comparator function
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_comparator()
*/
int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun);
/**
* set a seeker function for list elements.
*
* Seeker functions are used for finding elements. If NULL is passed as reference
* to the function, the seeker is disabled.
*
* @param l list to operate
* @param seeker_fun pointer to the actual seeker function
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_seeker()
*/
int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun);
/**
* require to free element data when list entry is removed (default: don't free).
*
* [ advanced preference ]
*
* By default, when an element is removed from the list, it disappears from
* the list by its actual data is not free()d. With this option, every
* deletion causes element data to be freed.
*
* It is responsability of this function to correctly handle NULL values, if
* NULL elements are inserted into the list.
*
* @param l list to operate
* @param metric_fun pointer to the actual metric function
* @param copy_data 0: do not free element data (default); non-0: do free
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_meter()
* @see list_meter_int8_t()
* @see list_meter_int16_t()
* @see list_meter_int32_t()
* @see list_meter_int64_t()
* @see list_meter_uint8_t()
* @see list_meter_uint16_t()
* @see list_meter_uint32_t()
* @see list_meter_uint64_t()
* @see list_meter_float()
* @see list_meter_double()
* @see list_meter_string()
*/
int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data);
/**
* set the element hash computing function for the list elements.
*
* [ advanced preference ]
*
* An hash can be requested depicting the list status at a given time. An hash
* only depends on the elements and their order. By default, the hash of an
* element is only computed on its reference. With this function, the user can
* set a custom function computing the hash of an element. If such function is
* provided, the list_hash() function automatically computes the list hash using
* the custom function instead of simply referring to element references.
*
* @param l list to operate
* @param hash_computer_fun pointer to the actual hash computing function
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_hash_computer()
*/
int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun);
/**
* set the element serializer function for the list elements.
*
* [ advanced preference ]
*
* Serialize functions are used for dumping the list to some persistent
* storage. The serializer function is called for each element; it is passed
* a reference to the element and a reference to a size_t object. It will
* provide (and return) the buffer with the serialization of the element and
* fill the size_t object with the length of this serialization data.
*
* @param l list to operate
* @param serializer_fun pointer to the actual serializer function
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_serializer()
* @see list_dump_filedescriptor()
* @see list_restore_filedescriptor()
*/
int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun);
/**
* set the element unserializer function for the list elements.
*
* [ advanced preference ]
*
* Unserialize functions are used for restoring the list from some persistent
* storage. The unserializer function is called for each element segment read
* from the storage; it is passed the segment and a reference to an integer.
* It shall allocate and return a buffer compiled with the resumed memory
* representation of the element, and set the integer value to the length of
* this buffer.
*
* @param l list to operate
* @param unserializer_fun pointer to the actual unserializer function
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_unserializer()
* @see list_dump_filedescriptor()
* @see list_restore_filedescriptor()
*/
int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun);
/**
* append data at the end of the list.
*
* This function is useful for adding elements with a FIFO/queue policy.
*
* @param l list to operate
* @param data pointer to user data to append
*
* @return 1 for success. < 0 for failure
*/
int list_append(list_t *restrict l, const void *data);
/**
* insert data in the head of the list.
*
* This function is useful for adding elements with a LIFO/Stack policy.
*
* @param l list to operate
* @param data pointer to user data to append
*
* @return 1 for success. < 0 for failure
*/
int list_prepend(list_t *restrict l, const void *restrict data);
/**
* extract the element in the top of the list.
*
* This function is for using a list with a FIFO/queue policy.
*
* @param l list to operate
* @return reference to user datum, or NULL on errors
*/
void *list_fetch(list_t *restrict l);
/**
* retrieve an element at a given position.
*
* @param l list to operate
* @param pos [0,size-1] position index of the element wanted
* @return reference to user datum, or NULL on errors
*/
void *list_get_at(const list_t *restrict l, unsigned int pos);
/**
* return the maximum element of the list.
*
* @warning Requires a comparator function to be set for the list.
*
* Returns the maximum element with respect to the comparator function output.
*
* @see list_attributes_comparator()
*
* @param l list to operate
* @return the reference to the element, or NULL
*/
void *list_get_max(const list_t *restrict l);
/**
* return the minimum element of the list.
*
* @warning Requires a comparator function to be set for the list.
*
* Returns the minimum element with respect to the comparator function output.
*
* @see list_attributes_comparator()
*
* @param l list to operate
* @return the reference to the element, or NULL
*/
void *list_get_min(const list_t *restrict l);
/**
* retrieve and remove from list an element at a given position.
*
* @param l list to operate
* @param pos [0,size-1] position index of the element wanted
* @return reference to user datum, or NULL on errors
*/
void *list_extract_at(list_t *restrict l, unsigned int pos);
/**
* insert an element at a given position.
*
* @param l list to operate
* @param data reference to data to be inserted
* @param pos [0,size-1] position index to insert the element at
* @return positive value on success. Negative on failure
*/
int list_insert_at(list_t *restrict l, const void *data, unsigned int pos);
/**
* expunge the first found given element from the list.
*
* Inspects the given list looking for the given element; if the element
* is found, it is removed. Only the first occurence is removed.
* If a comparator function was not set, elements are compared by reference.
* Otherwise, the comparator is used to match the element.
*
* @param l list to operate
* @param data reference of the element to search for
* @return 0 on success. Negative value on failure
*
* @see list_attributes_comparator()
* @see list_delete_at()
*/
int list_delete(list_t *restrict l, const void *data);
/**
* expunge an element at a given position from the list.
*
* @param l list to operate
* @param pos [0,size-1] position index of the element to be deleted
* @return 0 on success. Negative value on failure
*/
int list_delete_at(list_t *restrict l, unsigned int pos);
/**
* expunge an array of elements from the list, given their position range.
*
* @param l list to operate
* @param posstart [0,size-1] position index of the first element to be deleted
* @param posend [posstart,size-1] position of the last element to be deleted
* @return the number of elements successfully removed on success, <0 on error
*/
int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend);
/**
* clear all the elements off of the list.
*
* The element datums will not be freed.
*
* @see list_delete_range()
* @see list_size()
*
* @param l list to operate
* @return the number of elements removed on success, <0 on error
*/
int list_clear(list_t *restrict l);
/**
* inspect the number of elements in the list.
*
* @param l list to operate
* @return number of elements currently held by the list
*/
unsigned int list_size(const list_t *restrict l);
/**
* inspect whether the list is empty.
*
* @param l list to operate
* @return 0 iff the list is not empty
*
* @see list_size()
*/
int list_empty(const list_t *restrict l);
/**
* find the position of an element in a list.
*
* @warning Requires a comparator function to be set for the list.
*
* Inspects the given list looking for the given element; if the element
* is found, its position into the list is returned.
* Elements are inspected comparing references if a comparator has not been
* set. Otherwise, the comparator is used to find the element.
*
* @param l list to operate
* @param data reference of the element to search for
* @return position of element in the list, or <0 if not found
*
* @see list_attributes_comparator()
* @see list_get_at()
*/
int list_locate(const list_t *restrict l, const void *data);
/**
* returns an element given an indicator.
*
* @warning Requires a seeker function to be set for the list.
*
* Inspect the given list looking with the seeker if an element matches
* an indicator. If such element is found, the reference to the element
* is returned.
*
* @param l list to operate
* @param indicator indicator data to pass to the seeker along with elements
* @return reference to the element accepted by the seeker, or NULL if none found
*/
void *list_seek(list_t *restrict l, const void *indicator);
/**
* inspect whether some data is member of the list.
*
* @warning Requires a comparator function to be set for the list.
*
* By default, a per-reference comparison is accomplished. That is,
* the data is in list if any element of the list points to the same
* location of data.
* A "semantic" comparison is accomplished, otherwise, if a comparator
* function has been set previously, with list_attributes_comparator();
* in which case, the given data reference is believed to be in list iff
* comparator_fun(elementdata, userdata) == 0 for any element in the list.
*
* @param l list to operate
* @param data reference to the data to search
* @return 0 iff the list does not contain data as an element
*
* @see list_attributes_comparator()
*/
int list_contains(const list_t *restrict l, const void *data);
/**
* concatenate two lists
*
* Concatenates one list with another, and stores the result into a
* user-provided list object, which must be different from both the
* lists to concatenate. Attributes from the original lists are not
* cloned.
* The destination list referred is threated as virgin room: if it
* is an existing list containing elements, memory leaks will happen.
* It is OK to specify the same list twice as source, for "doubling"
* it in the destination.
*
* @param l1 base list
* @param l2 list to append to the base
* @param dest reference to the destination list
* @return 0 for success, -1 for errors
*/
int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest);
/**
* sort list elements.
*
* @warning Requires a comparator function to be set for the list.
*
* Sorts the list in ascending or descending order as specified by the versus
* flag. The algorithm chooses autonomously what algorithm is best suited for
* sorting the list wrt its current status.
*
* @param l list to operate
* @param versus positive: order small to big; negative: order big to small
* @return 0 iff sorting was successful
*
* @see list_attributes_comparator()
*/
int list_sort(list_t *restrict l, int versus);
/**
* start an iteration session.
*
* This function prepares the list to be iterated.
*
* @param l list to operate
* @return 0 if the list cannot be currently iterated. >0 otherwise
*
* @see list_iterator_stop()
*/
int list_iterator_start(list_t *restrict l);
/**
* return the next element in the iteration session.
*
* @param l list to operate
* @return element datum, or NULL on errors
*/
void *list_iterator_next(list_t *restrict l);
/**
* inspect whether more elements are available in the iteration session.
*
* @param l list to operate
* @return 0 iff no more elements are available.
*/
int list_iterator_hasnext(const list_t *restrict l);
/**
* end an iteration session.
*
* @param l list to operate
* @return 0 iff the iteration session cannot be stopped
*/
int list_iterator_stop(list_t *restrict l);
/**
* return the hash of the current status of the list.
*
* @param l list to operate
* @param hash where the resulting hash is put
*
* @return 0 for success; <0 for failure
*/
int list_hash(const list_t *restrict l, list_hash_t *restrict hash);
#ifndef SIMCLIST_NO_DUMPRESTORE
/**
* get meta informations on a list dump on filedescriptor.
*
* [ advanced function ]
*
* Extracts the meta information from a SimCList dump located in a file
* descriptor. The file descriptor must be open and positioned at the
* beginning of the SimCList dump block.
*
* @param fd file descriptor to get metadata from
* @param info reference to a dump metainformation structure to fill
* @return 0 for success; <0 for failure
*
* @see list_dump_filedescriptor()
*/
int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info);
/**
* get meta informations on a list dump on file.
*
* [ advanced function ]
*
* Extracts the meta information from a SimCList dump located in a file.
*
* @param filename filename of the file to fetch from
* @param info reference to a dump metainformation structure to fill
* @return 0 for success; <0 for failure
*
* @see list_dump_filedescriptor()
*/
int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info);
/**
* dump the list into an open, writable file descriptor.
*
* This function "dumps" the list to a persistent storage so it can be
* preserved across process terminations.
* When called, the file descriptor must be open for writing and positioned
* where the serialized data must begin. It writes its serialization of the
* list in a form which is portable across different architectures. Dump can
* be safely performed on stream-only (non seekable) descriptors. The file
* descriptor is not closed at the end of the operations.
*
* To use dump functions, either of these conditions must be satisfied:
* -# a metric function has been specified with list_attributes_copy()
* -# a serializer function has been specified with list_attributes_serializer()
*
* If a metric function has been specified, each element of the list is dumped
* as-is from memory, copying it from its pointer for its length down to the
* file descriptor. This might have impacts on portability of the dump to
* different architectures.
*
* If a serializer function has been specified, its result for each element is
* dumped to the file descriptor.
*
*
* @param l list to operate
* @param fd file descriptor to write to
* @param len location to store the resulting length of the dump (bytes), or NULL
*
* @return 0 if successful; -1 otherwise
*
* @see element_serializer()
* @see list_attributes_copy()
* @see list_attributes_serializer()
*/
int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len);
/**
* dump the list to a file name.
*
* This function creates a filename and dumps the current content of the list
* to it. If the file exists it is overwritten. The number of bytes written to
* the file can be returned in a specified argument.
*
* @param l list to operate
* @param filename filename to write to
* @param len location to store the resulting length of the dump (bytes), or NULL
*
* @return 0 if successful; -1 otherwise
*
* @see list_attributes_copy()
* @see element_serializer()
* @see list_attributes_serializer()
* @see list_dump_filedescriptor()
* @see list_restore_file()
*
* This function stores a representation of the list
*/
int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len);
/**
* restore the list from an open, readable file descriptor to memory.
*
* This function is the "inverse" of list_dump_filedescriptor(). It restores
* the list content from a (open, read-ready) file descriptor to memory. An
* unserializer might be needed to restore elements from the persistent
* representation back into memory-consistent format. List attributes can not
* be restored and must be set manually.
*
* @see list_dump_filedescriptor()
* @see list_attributes_serializer()
* @see list_attributes_unserializer()
*
* @param l list to restore to
* @param fd file descriptor to read from.
* @param len location to store the length of the dump read (bytes), or NULL
* @return 0 if successful; -1 otherwise
*/
int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len);
/**
* restore the list from a file name.
*
* This function restores the content of a list from a file into memory. It is
* the inverse of list_dump_file().
*
* @see element_unserializer()
* @see list_attributes_unserializer()
* @see list_dump_file()
* @see list_restore_filedescriptor()
*
* @param l list to restore to
* @param filename filename to read data from
* @param len location to store the length of the dump read (bytes), or NULL
* @return 0 if successful; -1 otherwise
*/
int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len);
#endif
/* ready-made comparators, meters and hash computers */
/* comparator functions */
/**
* ready-made comparator for int8_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_int8_t(const void *a, const void *b);
/**
* ready-made comparator for int16_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_int16_t(const void *a, const void *b);
/**
* ready-made comparator for int32_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_int32_t(const void *a, const void *b);
/**
* ready-made comparator for int64_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_int64_t(const void *a, const void *b);
/**
* ready-made comparator for uint8_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_uint8_t(const void *a, const void *b);
/**
* ready-made comparator for uint16_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_uint16_t(const void *a, const void *b);
/**
* ready-made comparator for uint32_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_uint32_t(const void *a, const void *b);
/**
* ready-made comparator for uint64_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_uint64_t(const void *a, const void *b);
/**
* ready-made comparator for float elements.
* @see list_attributes_comparator()
*/
int list_comparator_float(const void *a, const void *b);
/**
* ready-made comparator for double elements.
* @see list_attributes_comparator()
*/
int list_comparator_double(const void *a, const void *b);
/**
* ready-made comparator for string elements.
* @see list_attributes_comparator()
*/
int list_comparator_string(const void *a, const void *b);
/* metric functions */
/**
* ready-made metric function for int8_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_int8_t(const void *el);
/**
* ready-made metric function for int16_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_int16_t(const void *el);
/**
* ready-made metric function for int32_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_int32_t(const void *el);
/**
* ready-made metric function for int64_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_int64_t(const void *el);
/**
* ready-made metric function for uint8_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_uint8_t(const void *el);
/**
* ready-made metric function for uint16_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_uint16_t(const void *el);
/**
* ready-made metric function for uint32_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_uint32_t(const void *el);
/**
* ready-made metric function for uint64_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_uint64_t(const void *el);
/**
* ready-made metric function for float elements.
* @see list_attributes_copy()
*/
size_t list_meter_float(const void *el);
/**
* ready-made metric function for double elements.
* @see list_attributes_copy()
*/
size_t list_meter_double(const void *el);
/**
* ready-made metric function for string elements.
* @see list_attributes_copy()
*/
size_t list_meter_string(const void *el);
/* hash functions */
/**
* ready-made hash function for int8_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_int8_t(const void *el);
/**
* ready-made hash function for int16_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_int16_t(const void *el);
/**
* ready-made hash function for int32_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_int32_t(const void *el);
/**
* ready-made hash function for int64_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_int64_t(const void *el);
/**
* ready-made hash function for uint8_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_uint8_t(const void *el);
/**
* ready-made hash function for uint16_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_uint16_t(const void *el);
/**
* ready-made hash function for uint32_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_uint32_t(const void *el);
/**
* ready-made hash function for uint64_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_uint64_t(const void *el);
/**
* ready-made hash function for float elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_float(const void *el);
/**
* ready-made hash function for double elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_double(const void *el);
/**
* ready-made hash function for string elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_string(const void *el);
#ifdef __cplusplus
}
#endif
#endif

60
src/strlcpy.c Normal file
View File

@ -0,0 +1,60 @@
/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef HAVE_STRLCPY
#include <sys/types.h>
#include <string.h>
#include "strlcpycat.h"
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}
#endif

45
src/strlcpycat.h Normal file
View File

@ -0,0 +1,45 @@
/*
* MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
*
* Copyright (C) 2004-2010
* Ludovic Rousseau <ludovic.rousseau@free.fr>
*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief prototypes of strlcpy()/strlcat() imported from OpenBSD
*/
#ifdef HAVE_STRLCPY
#include <string.h>
#else
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif
#ifndef HAVE_STRLCAT
size_t strlcat(char *dst, const char *src, size_t siz);
#endif

2021
src/tokenparser.c Normal file

File diff suppressed because it is too large Load Diff

282
src/tokenparser.l Normal file
View File

@ -0,0 +1,282 @@
/*
* Reads lexical config files and updates database.
*
* MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
*
* Copyright (C) 2001-2003
* David Corcoran <corcoran@musclecard.com>
* Copyright (C) 2003-2010
* Ludovic Rousseau <ludovic.rousseau@free.fr>
*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief provides parsing functions for Info.plist files
* platforms
*/
%{
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define NDEBUG
#include <assert.h>
#include "simclist.h"
#include "debuglog.h"
#include "parser.h"
static void eval_key(char *pcToken, list_t *list_key);
static void eval_value(char *pcToken, list_t *list_values);
void tperrorCheck (char *pcToken_error);
static list_t *ListKeys;
static list_t *ListValues;
%}
%option nounput
%option noinput
%option noyywrap
%%
#.* {}
"\n" {}
\<key\>([A-Z]|[a-z]|[0-9]|[ \t])+\<\/key\> { eval_key(yytext, ListKeys); }
[ \t] {}
\<string\>([A-Z]|[a-z]|[0-9]|[ \t]|[!@#$%^&*()\-+/_\:?.,=~'";\[\]])+\<\/string\> { eval_value(yytext, ListValues); }
. { tperrorCheck(yytext); }
%%
static void eval_key(char *pcToken, list_t *list_key)
{
struct bundleElt *elt;
int r;
size_t len;
/* create a new list element */
elt = malloc(sizeof(*elt));
assert(elt);
/* <key>foobar</key>
* 012345 : 5 is the first key character index */
/* calculate the argument length */
for (len=0; pcToken[len+5] != '<'; len++)
;
len++; /* final NULL byte */
elt->key = malloc(len);
memcpy(elt->key, &pcToken[5], len-1);
elt->key[len-1] = '\0';
r = list_init(&elt->values);
assert(r >= 0);
(void)r;
/* add the key/values */
list_append(list_key, elt);
/* set the list to store the values */
ListValues = &elt->values;
}
static void eval_value(char *pcToken, list_t *list_values)
{
int r;
size_t len;
char *value;
char *amp;
/* <string>foobar</string>
* 012345678 : 8 is the first string character index */
/* calculate the argument length */
for (len=0; pcToken[len+8] != '<'; len++)
;
len++; /* final NULL byte */
value = malloc(len);
assert(value);
memcpy(value, &pcToken[8], len-1);
value[len-1] = '\0';
/* for all &amp; in the string */
amp = value;
while ((amp = strstr(amp, "&amp;")) != NULL)
{
char *p;
/* just skip "amp;" substring (4 letters) */
for (p = amp+1; *(p+4); p++)
{
*p = *(p+4);
}
/* terminate the now shorter string */
*p = '\0';
/* skip the & and continue */
amp++;
}
r = list_append(list_values, value);
assert(r >= 0);
(void)r;
}
void tperrorCheck (char *token_error)
{
(void)token_error;
}
/**
* Find an optional key in a configuration file
* No error is logged if the key is not found
*
* @param l list generated by bundleParse()
* @param key searched key
* @param[out] values list of token value (if key found)
* @retval 0 OK
* @retval 1 key not found
*/
int LTPBundleFindValueWithKey(list_t *l, const char *key, list_t **values)
{
unsigned int i;
int ret = 1;
for (i=0; i < list_size(l); i++)
{
struct bundleElt *elt;
elt = list_get_at(l, i);
assert(elt);
if (0 == strcmp(elt->key, key))
{
*values = &elt->values;
ret = 0;
}
}
return ret;
}
/**
* Parse a Info.plist file and file a list
*
* @param fileName file name
* @param l list containing the results
* @retval -1 configuration file not found
* @retval 0 OK
*/
int bundleParse(const char *fileName, list_t *l)
{
FILE *file = NULL;
int r;
#ifndef NDEBUG
int i;
#endif
file = fopen(fileName, "r");
if (!file)
{
Log3(PCSC_LOG_CRITICAL, "Could not open bundle file %s: %s",
fileName, strerror(errno));
return 1;
}
r = list_init(l);
assert(r >= 0);
(void)r;
ListKeys = l;
yyin = file;
do
{
(void)yylex();
} while (!feof(file));
yylex_destroy();
(void)fclose(file);
#ifndef NDEBUG
printf("size: %d\n", list_size(l));
for (i=0; i < list_size(l); i++)
{
struct bundleElt *elt;
unsigned int j;
elt = list_get_at(l, i);
assert(elt);
printf("Key: %s\n", elt->key);
for (j=0; j<list_size(&elt->values); j++)
{
char *v = list_get_at(&elt->values, j);
printf(" value: %s\n", v);
}
}
#endif
return 0;
}
/**
* Free the list created by bundleParse()
*
* @param l list containing the results
*/
void bundleRelease(list_t *l)
{
unsigned int i;
for (i=0; i < list_size(l); i++)
{
struct bundleElt *elt;
unsigned int j;
elt = list_get_at(l, i);
assert(elt);
/* free all the values */
for (j=0; j<list_size(&elt->values); j++)
free(list_get_at(&elt->values, j));
list_destroy(&elt->values);
/* free the key */
free(elt->key);
free(elt);
}
list_destroy(l);
}

505
src/towitoko/COPYING Normal file
View File

@ -0,0 +1,505 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

12
src/towitoko/README Normal file
View File

@ -0,0 +1,12 @@
All the files in the src/protocol_t1/ directory comes from Carlos
Prados Towitoko smartcard readers driver.
I (Ludovic Rousseau) hacked the source files a bit to include them in my
CCID driver. So bugs are mine and not Carlos' fault. As indicated in
the source files headers this code is protected by the GNU Lesser
General Public License.
I used version 2.0.7 of Carlos driver available at
http://www.geocities.com/cprados/
I added the function ATR_GetDefaultProtocol() in towitoko/atr.c

365
src/towitoko/atr.c Normal file
View File

@ -0,0 +1,365 @@
/*
atr.c
ISO 7816 ICC's answer to reset abstract data type implementation
This file is part of the Unix driver for Towitoko smartcard readers
Copyright (C) 2000 Carlos Prados <cprados@yahoo.com>
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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <config.h>
#include "atr.h"
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "debug.h"
/*
* Not exported variables definition
*/
static unsigned
atr_num_ib_table[16] =
{
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
};
/*
* Exported variables definition
*/
static unsigned
atr_f_table[16] =
{
372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, 1024, 1536, 2048, 0, 0
};
static unsigned
atr_d_table[16] =
{
0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0, 0, 0, 0, 0, 0
};
static unsigned
atr_i_table[4] =
{
25, 50, 100, 0
};
/*
* Exported functions definition
*/
int
ATR_InitFromArray (ATR_t * atr, const BYTE atr_buffer[ATR_MAX_SIZE], unsigned length)
{
BYTE TDi;
unsigned pointer = 0, pn = 0;
/* Check size of buffer */
if (length < 2)
return (ATR_MALFORMED);
/* Store T0 and TS */
atr->TS = atr_buffer[0];
atr->T0 = TDi = atr_buffer[1];
pointer = 1;
/* Store number of historical bytes */
atr->hbn = TDi & 0x0F;
/* TCK is not present by default */
(atr->TCK).present = FALSE;
/* Extract interface bytes */
while (pointer < length)
{
/* Check buffer is long enought */
if (pointer + atr_num_ib_table[(0xF0 & TDi) >> 4] >= length)
{
return (ATR_MALFORMED);
}
/* Check TAi is present */
if ((TDi | 0xEF) == 0xFF)
{
pointer++;
atr->ib[pn][ATR_INTERFACE_BYTE_TA].value = atr_buffer[pointer];
atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = TRUE;
}
else
atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = FALSE;
/* Check TBi is present */
if ((TDi | 0xDF) == 0xFF)
{
pointer++;
atr->ib[pn][ATR_INTERFACE_BYTE_TB].value = atr_buffer[pointer];
atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = TRUE;
}
else
atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = FALSE;
/* Check TCi is present */
if ((TDi | 0xBF) == 0xFF)
{
pointer++;
atr->ib[pn][ATR_INTERFACE_BYTE_TC].value = atr_buffer[pointer];
atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = TRUE;
}
else
atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = FALSE;
/* Read TDi if present */
if ((TDi | 0x7F) == 0xFF)
{
pointer++;
TDi = atr->ib[pn][ATR_INTERFACE_BYTE_TD].value = atr_buffer[pointer];
atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = TRUE;
(atr->TCK).present = ((TDi & 0x0F) != ATR_PROTOCOL_TYPE_T0);
pn++;
if (pn >= ATR_MAX_PROTOCOLS)
return (ATR_MALFORMED);
}
else
{
atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = FALSE;
break;
}
}
/* Store number of protocols */
atr->pn = pn + 1;
/* Store historical bytes */
if (pointer + atr->hbn >= length)
return (ATR_MALFORMED);
memcpy (atr->hb, atr_buffer + pointer + 1, atr->hbn);
pointer += (atr->hbn);
/* Store TCK */
if ((atr->TCK).present)
{
if (pointer + 1 >= length)
return (ATR_MALFORMED);
pointer++;
(atr->TCK).value = atr_buffer[pointer];
}
atr->length = pointer + 1;
return (ATR_OK);
}
int
ATR_GetConvention (ATR_t * atr, int *convention)
{
if (atr->TS == 0x3B)
(*convention) = ATR_CONVENTION_DIRECT;
else if (atr->TS == 0x3F)
(*convention) = ATR_CONVENTION_INVERSE;
else
return (ATR_MALFORMED);
return (ATR_OK);
}
int
ATR_GetIntegerValue (ATR_t * atr, int name, BYTE * value)
{
int ret;
if (name == ATR_INTEGER_VALUE_FI)
{
if (atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
{
(*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TA].value & 0xF0) >> 4;
ret = ATR_OK;
}
else
ret = ATR_NOT_FOUND;
}
else if (name == ATR_INTEGER_VALUE_DI)
{
if (atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
{
(*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TA].value & 0x0F);
ret = ATR_OK;
}
else
ret = ATR_NOT_FOUND;
}
else if (name == ATR_INTEGER_VALUE_II)
{
if (atr->ib[0][ATR_INTERFACE_BYTE_TB].present)
{
(*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TB].value & 0x60) >> 5;
ret = ATR_OK;
}
else
ret = ATR_NOT_FOUND;
}
else if (name == ATR_INTEGER_VALUE_PI1)
{
if (atr->ib[0][ATR_INTERFACE_BYTE_TB].present)
{
(*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TB].value & 0x1F);
ret = ATR_OK;
}
else
ret = ATR_NOT_FOUND;
}
else if (name == ATR_INTEGER_VALUE_PI2)
{
if (atr->ib[1][ATR_INTERFACE_BYTE_TB].present)
{
(*value) = atr->ib[1][ATR_INTERFACE_BYTE_TB].value;
ret = ATR_OK;
}
else
ret = ATR_NOT_FOUND;
}
else if (name == ATR_INTEGER_VALUE_N)
{
if (atr->ib[0][ATR_INTERFACE_BYTE_TC].present)
{
(*value) = atr->ib[0][ATR_INTERFACE_BYTE_TC].value;
ret = ATR_OK;
}
else
ret = ATR_NOT_FOUND;
}
else
ret = ATR_NOT_FOUND;
return ret;
}
int
ATR_GetParameter (ATR_t * atr, int name, double *parameter)
{
BYTE FI, DI, II, PI1, PI2, N;
if (name == ATR_PARAMETER_F)
{
if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_FI, &FI) == ATR_OK)
(*parameter) = (double) (atr_f_table[FI]);
else
(*parameter) = (double) ATR_DEFAULT_F;
return (ATR_OK);
}
else if (name == ATR_PARAMETER_D)
{
if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_DI, &DI) == ATR_OK)
(*parameter) = (double) (atr_d_table[DI]);
else
(*parameter) = (double) ATR_DEFAULT_D;
return (ATR_OK);
}
else if (name == ATR_PARAMETER_I)
{
if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_II, &II) == ATR_OK)
(*parameter) = (double) (atr_i_table[II]);
else
(*parameter) = ATR_DEFAULT_I;
return (ATR_OK);
}
else if (name == ATR_PARAMETER_P)
{
if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_PI2, &PI2) == ATR_OK)
(*parameter) = (double) PI2;
else if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_PI1, &PI1) == ATR_OK)
(*parameter) = (double) PI1;
else
(*parameter) = (double) ATR_DEFAULT_P;
return (ATR_OK);
}
else if (name == ATR_PARAMETER_N)
{
if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_N, &N) == ATR_OK)
(*parameter) = (double) N;
else
(*parameter) = (double) ATR_DEFAULT_N;
return (ATR_OK);
}
return (ATR_NOT_FOUND);
}
/*
* This function was greatly inspired by ATRDecodeAtr() and
* PHGetDefaultProtocol() from pcsc-lite
*
* It was rewritten by Ludovic Rousseau, 2004
*/
#define PROTOCOL_UNSET -1
int ATR_GetDefaultProtocol(ATR_t * atr, int *protocol, int *availableProtocols)
{
int i;
/* default value */
*protocol = PROTOCOL_UNSET;
if (availableProtocols)
*availableProtocols = 0;
for (i=0; i<ATR_MAX_PROTOCOLS; i++)
if (atr->ib[i][ATR_INTERFACE_BYTE_TD].present)
{
int T = atr->ib[i][ATR_INTERFACE_BYTE_TD].value & 0x0F;
DEBUG_COMM2("T=%d Protocol Found", T);
if (availableProtocols)
*availableProtocols |= 1 << T;
if (PROTOCOL_UNSET == *protocol)
{
/* set to the first protocol byte found */
*protocol = T;
DEBUG_COMM2("default protocol: T=%d", *protocol);
}
}
/* specific mode if TA2 present */
if (atr->ib[1][ATR_INTERFACE_BYTE_TA].present)
{
*protocol = atr->ib[1][ATR_INTERFACE_BYTE_TA].value & 0x0F;
if (availableProtocols)
*availableProtocols = 1 << *protocol;
DEBUG_COMM2("specific mode found: T=%d", *protocol);
}
if (PROTOCOL_UNSET == *protocol)
{
DEBUG_INFO1("no default protocol found in ATR. Using T=0");
*protocol = ATR_PROTOCOL_TYPE_T0;
if (availableProtocols)
*availableProtocols = 1 << *protocol;
}
return ATR_OK;
}

111
src/towitoko/atr.h Normal file
View File

@ -0,0 +1,111 @@
/*
atr.h
ISO 7816 ICC's answer to reset abstract data type definitions
This file is part of the Unix driver for Towitoko smartcard readers
Copyright (C) 2000 Carlos Prados <cprados@yahoo.com>
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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _ATR_
#define _ATR_
#include "defines.h"
/*
* Exported constants definition
*/
/* Return values */
#define ATR_OK 0 /* ATR could be parsed and data returned */
#define ATR_NOT_FOUND 1 /* Data not present in ATR */
#define ATR_MALFORMED 2 /* ATR could not be parsed */
#define ATR_IO_ERROR 3 /* I/O stream error */
/* Paramenters */
#define ATR_MAX_SIZE 33 /* Maximum size of ATR byte array */
#define ATR_MAX_HISTORICAL 15 /* Maximum number of historical bytes */
#define ATR_MAX_PROTOCOLS 7 /* Maximun number of protocols */
#define ATR_MAX_IB 4 /* Maximum number of interface bytes per protocol */
#define ATR_CONVENTION_DIRECT 0 /* Direct convention */
#define ATR_CONVENTION_INVERSE 1 /* Inverse convention */
#define ATR_PROTOCOL_TYPE_T0 0 /* Protocol type T=0 */
#define ATR_PROTOCOL_TYPE_T1 1 /* Protocol type T=1 */
#define ATR_PROTOCOL_TYPE_T2 2 /* Protocol type T=2 */
#define ATR_PROTOCOL_TYPE_T3 3 /* Protocol type T=3 */
#define ATR_PROTOCOL_TYPE_T14 14 /* Protocol type T=14 */
#define ATR_INTERFACE_BYTE_TA 0 /* Interface byte TAi */
#define ATR_INTERFACE_BYTE_TB 1 /* Interface byte TBi */
#define ATR_INTERFACE_BYTE_TC 2 /* Interface byte TCi */
#define ATR_INTERFACE_BYTE_TD 3 /* Interface byte TDi */
#define ATR_PARAMETER_F 0 /* Parameter F */
#define ATR_PARAMETER_D 1 /* Parameter D */
#define ATR_PARAMETER_I 2 /* Parameter I */
#define ATR_PARAMETER_P 3 /* Parameter P */
#define ATR_PARAMETER_N 4 /* Parameter N */
#define ATR_INTEGER_VALUE_FI 0 /* Integer value FI */
#define ATR_INTEGER_VALUE_DI 1 /* Integer value DI */
#define ATR_INTEGER_VALUE_II 2 /* Integer value II */
#define ATR_INTEGER_VALUE_PI1 3 /* Integer value PI1 */
#define ATR_INTEGER_VALUE_N 4 /* Integer value N */
#define ATR_INTEGER_VALUE_PI2 5 /* Integer value PI2 */
/* Default values for paramenters */
#define ATR_DEFAULT_F 372
#define ATR_DEFAULT_D 1
#define ATR_DEFAULT_I 50
#define ATR_DEFAULT_N 0
#define ATR_DEFAULT_P 5
/*
* Exported data types definition
*/
typedef struct
{
unsigned length;
BYTE TS;
BYTE T0;
struct
{
BYTE value;
bool present;
}
ib[ATR_MAX_PROTOCOLS][ATR_MAX_IB], TCK;
unsigned pn;
BYTE hb[ATR_MAX_HISTORICAL];
unsigned hbn;
}
ATR_t;
/*
* Exported functions declaraton
*/
/* Initialization */
extern int ATR_InitFromArray(ATR_t * atr, const BYTE buffer[ATR_MAX_SIZE],
unsigned length);
/* General smartcard characteristics */
extern int ATR_GetConvention(ATR_t * atr, /*@out@*/ int *convention);
extern int ATR_GetDefaultProtocol(ATR_t * atr, /*@out@*/ int *protocol, int *availableProtocols);
/* ATR parameters and integer values */
extern int ATR_GetIntegerValue(ATR_t * atr, int name, BYTE * value);
extern int ATR_GetParameter(ATR_t * atr, int name, /*@out@*/ double *parameter);
#endif /* _ATR_ */

56
src/towitoko/defines.h Normal file
View File

@ -0,0 +1,56 @@
/*
defines.h
This file is part of the Unix driver for Towitoko smartcard readers
Copyright (C) 2000 Carlos Prados <cprados@yahoo.com>
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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DEFINES_H
#define DEFINES_H
/*
* Get configuration information
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/*
* Boolean constants
*/
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/*
* Type definitions
*/
#include <wintypes.h>
#ifndef __cplusplus
typedef int bool;
#endif
#endif /* DEFINES_H */

136
src/towitoko/pps.c Normal file
View File

@ -0,0 +1,136 @@
/*
pps.c
Protocol Parameters Selection
This file is part of the Unix driver for Towitoko smartcard readers
Copyright (C) 2000 2001 Carlos Prados <cprados@yahoo.com>
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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "pps.h"
#include "atr.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <ifdhandler.h>
#include "commands.h"
#include "defs.h"
#include "debug.h"
/*
* Not exported funtions declaration
*/
static bool PPS_Match (BYTE * request, unsigned len_request, BYTE * reply, unsigned len_reply);
static unsigned PPS_GetLength (BYTE * block);
static BYTE PPS_GetPCK (BYTE * block, unsigned length);
int
PPS_Exchange (int lun, BYTE * params, unsigned *length, unsigned char *pps1)
{
BYTE confirm[PPS_MAX_LENGTH];
unsigned len_request, len_confirm;
int ret;
len_request = PPS_GetLength (params);
params[len_request - 1] = PPS_GetPCK(params, len_request - 1);
DEBUG_XXD ("PPS: Sending request: ", params, len_request);
/* Send PPS request */
if (CCID_Transmit (lun, len_request, params, isCharLevel(lun) ? 4 : 0, 0)
!= IFD_SUCCESS)
return PPS_ICC_ERROR;
/* Get PPS confirm */
len_confirm = sizeof(confirm);
if (CCID_Receive (lun, &len_confirm, confirm, NULL) != IFD_SUCCESS)
return PPS_ICC_ERROR;
DEBUG_XXD ("PPS: Receiving confirm: ", confirm, len_confirm);
if (!PPS_Match (params, len_request, confirm, len_confirm))
ret = PPS_HANDSAKE_ERROR;
else
ret = PPS_OK;
*pps1 = 0x11; /* default TA1 */
/* if PPS1 is echoed */
if (PPS_HAS_PPS1 (params) && PPS_HAS_PPS1 (confirm))
*pps1 = confirm[2];
/* Copy PPS handsake */
memcpy (params, confirm, len_confirm);
(*length) = len_confirm;
return ret;
}
static bool
PPS_Match (BYTE * request, unsigned len_request, BYTE * confirm, unsigned len_confirm)
{
/* See if the reply differs from request */
if ((len_request == len_confirm) && /* same length */
memcmp (request, confirm, len_request)) /* different contents */
return FALSE;
if (len_request < len_confirm) /* confirm longer than request */
return FALSE;
/* See if the card specifies other than default FI and D */
if ((PPS_HAS_PPS1 (confirm)) && (confirm[2] != request[2]))
return FALSE;
return TRUE;
}
static unsigned
PPS_GetLength (BYTE * block)
{
unsigned length = 3;
if (PPS_HAS_PPS1 (block))
length++;
if (PPS_HAS_PPS2 (block))
length++;
if (PPS_HAS_PPS3 (block))
length++;
return length;
}
static BYTE
PPS_GetPCK (BYTE * block, unsigned length)
{
BYTE pck;
unsigned i;
pck = block[0];
for (i = 1; i < length; i++)
pck ^= block[i];
return pck;
}

Some files were not shown because too many files have changed in this diff Show More