[Pcsclite-cvs-commit] r2211 - in trunk: . pycsc
Ludovic Rousseau
rousseau at alioth.debian.org
Thu Nov 16 14:13:40 CET 2006
Author: rousseau
Date: 2006-11-16 14:13:40 +0100 (Thu, 16 Nov 2006)
New Revision: 2211
Added:
trunk/pycsc/
trunk/pycsc/CHANGELOG
trunk/pycsc/COPYING
trunk/pycsc/INSTALL
trunk/pycsc/README
trunk/pycsc/TODO
trunk/pycsc/example.py
trunk/pycsc/pycsc.c
trunk/pycsc/setup.py
Log:
Python wrapper for PC/SC
Added: trunk/pycsc/CHANGELOG
===================================================================
--- trunk/pycsc/CHANGELOG 2006-11-15 14:52:54 UTC (rev 2210)
+++ trunk/pycsc/CHANGELOG 2006-11-16 13:13:40 UTC (rev 2211)
@@ -0,0 +1,10 @@
+
+ChangeLog for Pycsc:
+
+v 0.3:
+-----
+- Implements getStatusChange
+- one setup.py for all platforms
+- added minimal pcsc_stringify_error for Win32 (thanks to Arah Leonard)
+- calling constructor with no args or "" is now similar (thanks to Arah Leonard)
+- defined more constants (thanks to Arah Leonard)
Added: trunk/pycsc/COPYING
===================================================================
--- trunk/pycsc/COPYING 2006-11-15 14:52:54 UTC (rev 2210)
+++ trunk/pycsc/COPYING 2006-11-16 13:13:40 UTC (rev 2211)
@@ -0,0 +1,24 @@
+Copyright (c) 2002-3 Jean-Luc Giraud <jlgiraud at mac.com>
+All rights reserved.
+
+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.
Added: trunk/pycsc/INSTALL
===================================================================
--- trunk/pycsc/INSTALL 2006-11-15 14:52:54 UTC (rev 2210)
+++ trunk/pycsc/INSTALL 2006-11-16 13:13:40 UTC (rev 2211)
@@ -0,0 +1,43 @@
+Python wrapper to use with pcsclite
+===================================
+
+Authors:
+========
+- Jean-Luc Giraud (jlgiraud at mac.com)
+
+
+Supported platforms:
+====================
+- Mac OS X
+- linux
+- Windows 2000
+
+Requirements:
+=============
+1- pcsclite installed and functional (http://www.musclecard.com/middle.html)
+2- pcsclite developer packages if you use precompiled binaries
+3- a card driver for your card reader
+4- python 2.2 or higher
+
+Step 1 and 2 do not apply to Windows as PC/SC is already part of the OS.
+
+Minimal help:
+=============
+
+On Linux:
+- to build:
+ $ python setup.py build
+- to install:
+ $ sudo python setup.py install
+
+On Mac OS X:
+- to build:
+ $ python setup_MacOSX.py build
+- to install:
+ $ sudo python setup_MacOSX.py install
+
+On Mac OS X:
+- to build and install:
+ $ python setup_Win32.py install
+
+See example.py for details on how to use pycsc.
Added: trunk/pycsc/README
===================================================================
--- trunk/pycsc/README 2006-11-15 14:52:54 UTC (rev 2210)
+++ trunk/pycsc/README 2006-11-16 13:13:40 UTC (rev 2211)
@@ -0,0 +1,38 @@
+
+Python wrapper to use with pcsclite
+===================================
+
+This package implements a new python type to communicate with smart cards.
+It relies on a working installation of pcscd (see http://www.musclecard.com).
+
+The communication level is very low (ADPU) so you are expected to be quite
+knowledgeable on smart cards to be able to make any use of this package.
+
+Limitations:
+============
+
+This is a very early prototype and lots of things are not implemented
+(particularly all the error management). They will hopefully be added in the
+near future.
+
+The package is NOT thread safe.
+
+On the function getStatusChange: Windows has a different behaviour from
+pcsc-lite. The safe way to use this function is to first run it to
+query the EventState and the call it again with the returned EventSate
+as CurrentState (see example.py)
+
+
+Authors:
+========
+- Jean-Luc Giraud (jlgiraud at mac.com)
+
+Contributors:
+=============
+- Franck Bui-Huu (franck_buihuu at yahoo.fr)
+
+Supported platforms:
+====================
+- python2.2, 2.3
+- Mac OS X, Linux, Windows 2000
+
Added: trunk/pycsc/TODO
===================================================================
--- trunk/pycsc/TODO 2006-11-15 14:52:54 UTC (rev 2210)
+++ trunk/pycsc/TODO 2006-11-16 13:13:40 UTC (rev 2211)
@@ -0,0 +1,5 @@
+
+Pycsc TODO list
+
+- Implement all the non implemented functions
+- Add documentation on each function
Added: trunk/pycsc/example.py
===================================================================
--- trunk/pycsc/example.py 2006-11-15 14:52:54 UTC (rev 2210)
+++ trunk/pycsc/example.py 2006-11-16 13:13:40 UTC (rev 2211)
@@ -0,0 +1,64 @@
+
+import pycsc
+
+# binascii is used to tranform hexstrings into binary strings
+# and vice versa. the struct package could also be used.
+import binascii
+
+card = pycsc.pycsc()
+
+#Print reader name
+print "Connected to reader: " + card.status()["ReaderName"]
+
+print "Card Protocol: " + str(card.status()["Protocol"])
+print "Card State: " + str(card.status()["State"])
+
+
+# Print ATR
+print "Card Answer To Reset: " + binascii.b2a_hex(card.status()["ATR"])
+
+# For T=0 transmit, use pycsc.SCARD_PROTOCOL_T0
+# For T=1 transmit, use pycsc.SCARD_PROTOCOL_T1
+binascii.b2a_hex(card.transmit("\x00\xA4\x00\x00\x02\x3F\x00",
+ pycsc.SCARD_PROTOCOL_T0))
+
+# Protocol argument is optional (default is pycsc.SCARD_PROTOCOL_T0)
+resp = card.transmit(binascii.a2b_hex("00A40000023F00"))
+
+print "APDU sent to card: Select MF"
+
+print "Response: " + binascii.b2a_hex(resp)
+
+print "APDU sent to card: Get Response"
+print "Response: " + binascii.b2a_hex(card.transmit("\x00\xC0\x00\x00" + resp[-1]))
+
+readerName = pycsc.listReader()[0]
+# if reader is empty, should block until card is inserted
+# if reader is not empty, should return right away
+newState = pycsc.getStatusChange(ReaderStates=[{'Reader': readerName, 'CurrentState':pycsc.SCARD_STATE_EMPTY}])
+
+print newState
+
+# Shoud return immediately with current state
+newState = pycsc.getStatusChange(ReaderStates=[{'Reader': readerName, 'CurrentState':pycsc.SCARD_STATE_UNAWARE}])
+
+# Block until any change of state
+newState = pycsc.getStatusChange(ReaderStates=[{'Reader': readerName, 'CurrentState': newState[0]['EventState']}])
+
+print newState
+
+
+# This works:
+pycsc.getStatusChange(ReaderStates=newState)
+
+# And so does this (default value for CurrentState is SCARD_STATE_EMPTY):
+# This code should block if the reader is empty
+# This is NOT true on Windows. CurrentState/EventState seem to behave differently
+# The only way to block is the one listed aove (i.e. read the state
+# update CurrentState with the returned EventState and call getStatusChange again)
+pycsc.getStatusChange(ReaderStates=[{'Reader': readerName}])
+
+# Block until card insertion with a 10000 ms timeout
+pycsc.getStatusChange(Timeout=10000, ReaderStates=[{'Reader': readerName}])
+
+
Property changes on: trunk/pycsc/example.py
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/pycsc/pycsc.c
===================================================================
--- trunk/pycsc/pycsc.c 2006-11-15 14:52:54 UTC (rev 2210)
+++ trunk/pycsc/pycsc.c 2006-11-16 13:13:40 UTC (rev 2211)
@@ -0,0 +1,985 @@
+/***********************************************************
+* Title: pycsc.c
+* Author: Jean-Luc Giraud <jlgiraud at mac.com>
+* Compiler: gcc
+* Platform: Mac OS X, Linux and Windows2000
+* Purpose: Python class to communicate with smart cards
+* License: See file COPYING
+* $Id: pycsc.c,v 1.4 2004-06-21 00:54:29 giraud Exp $
+*
+* Copyright (c) 2003 - Jean-Luc Giraud.
+*
+************************************************************/
+
+#include <Python.h>
+
+/* Include the header files */
+
+#ifdef __APPLE__
+#include <wintypes.h>
+#include <PCSC/winscard.h>
+#else
+#include <winscard.h>
+#endif
+
+/* Internal tool */
+static LONG getReaderList(SCARDCONTEXT hContext, LPSTR* pmszReaders,
+ DWORD *pdwReaders);
+
+#ifdef _WINDOWS_
+/* Windows does not provide the pcsc_stringify_error function */
+char ErrorString[200];
+char *pcsc_stringify_error(LONG rv)
+{
+ char strErrorCode[50];
+ switch(rv)
+ {
+ case SCARD_E_CANCELLED:
+ strcpy(strErrorCode, "SCARD_E_CANCELLED");
+ break;
+ case SCARD_E_CANT_DISPOSE:
+ strcpy(strErrorCode, "SCARD_E_CANT_DISPOSE");
+ break;
+ case SCARD_E_CARD_UNSUPPORTED:
+ strcpy(strErrorCode, "SCARD_E_CARD_UNSUPPORTED");
+ break;
+ case SCARD_E_DUPLICATE_READER:
+ strcpy(strErrorCode, "SCARD_E_DUPLICATE_READER");
+ break;
+ case SCARD_E_INSUFFICIENT_BUFFER:
+ strcpy(strErrorCode, "SCARD_E_INSUFFICIENT_BUFFER");
+ break;
+ case SCARD_E_INVALID_ATR:
+ strcpy(strErrorCode, "SCARD_E_INVALID_ATR");
+ break;
+ case SCARD_E_INVALID_HANDLE:
+ strcpy(strErrorCode, "SCARD_E_INVALID_HANDLE");
+ break;
+ case SCARD_E_INVALID_PARAMETER:
+ strcpy(strErrorCode, "SCARD_E_INVALID_PARAMETER");
+ break;
+ case SCARD_E_INVALID_TARGET:
+ strcpy(strErrorCode, "SCARD_E_INVALID_TARGET");
+ break;
+ case SCARD_E_INVALID_VALUE:
+ strcpy(strErrorCode, "SCARD_E_INVALID_VALUE");
+ break;
+ case SCARD_E_NOT_READY:
+ strcpy(strErrorCode, "SCARD_E_NOT_READY");
+ break;
+ case SCARD_E_NOT_TRANSACTED:
+ strcpy(strErrorCode, "SCARD_E_NOT_TRANSACTED");
+ break;
+ case SCARD_E_NO_MEMORY:
+ strcpy(strErrorCode, "SCARD_E_NO_MEMORY");
+ break;
+ case SCARD_E_NO_SERVICE:
+ strcpy(strErrorCode, "SCARD_E_NO_SERVICE");
+ break;
+ case SCARD_E_NO_SMARTCARD:
+ strcpy(strErrorCode, "SCARD_E_NO_SMARTCARD");
+ break;
+ case SCARD_E_PCI_TOO_SMALL:
+ strcpy(strErrorCode, "SCARD_E_PCI_TOO_SMALL");
+ break;
+ case SCARD_E_PROTO_MISMATCH:
+ strcpy(strErrorCode, "SCARD_E_PROTO_MISMATCH");
+ break;
+ case SCARD_E_READER_UNAVAILABLE:
+ strcpy(strErrorCode, "SCARD_E_READER_UNAVAILABLE");
+ break;
+ case SCARD_E_READER_UNSUPPORTED:
+ strcpy(strErrorCode, "SCARD_E_READER_UNSUPPORTED");
+ break;
+ case SCARD_E_SERVICE_STOPPED:
+ strcpy(strErrorCode, "SCARD_E_SERVICE_STOPPED");
+ break;
+ case SCARD_E_SHARING_VIOLATION:
+ strcpy(strErrorCode, "SCARD_E_SHARING_VIOLATION");
+ break;
+ case SCARD_E_SYSTEM_CANCELLED:
+ strcpy(strErrorCode, "SCARD_E_SYSTEM_CANCELLED");
+ break;
+ case SCARD_E_TIMEOUT:
+ strcpy(strErrorCode, "SCARD_E_TIMEOUT");
+ break;
+ case SCARD_E_UNKNOWN_CARD:
+ strcpy(strErrorCode, "SCARD_E_UNKNOWN_CARD");
+ break;
+ case SCARD_E_UNKNOWN_READER:
+ strcpy(strErrorCode, "SCARD_E_UNKNOWN_READER");
+ break;
+ case SCARD_F_COMM_ERROR:
+ strcpy(strErrorCode, "SCARD_F_COMM_ERROR");
+ break;
+ case SCARD_F_INTERNAL_ERROR:
+ strcpy(strErrorCode, "SCARD_F_INTERNAL_ERROR");
+ break;
+ case SCARD_F_UNKNOWN_ERROR:
+ strcpy(strErrorCode, "SCARD_F_UNKNOWN_ERROR");
+ break;
+ case SCARD_F_WAITED_TOO_LONG:
+ strcpy(strErrorCode, "SCARD_F_WAITED_TOO_LONG");
+ break;
+ case SCARD_S_SUCCESS:
+ strcpy(strErrorCode, "SCARD_S_SUCCESS");
+ break;
+ case SCARD_W_REMOVED_CARD:
+ strcpy(strErrorCode, "SCARD_W_REMOVED_CARD");
+ break;
+ case SCARD_W_RESET_CARD:
+ strcpy(strErrorCode, "SCARD_W_RESET_CARD");
+ break;
+ case SCARD_W_UNPOWERED_CARD:
+ strcpy(strErrorCode, "SCARD_W_UNPOWERED_CARD");
+ break;
+ case SCARD_W_UNRESPONSIVE_CARD:
+ strcpy(strErrorCode, "SCARD_W_UNRESPONSIVE_CARD");
+ break;
+ case SCARD_W_UNSUPPORTED_CARD:
+ strcpy(strErrorCode, "SCARD_W_UNSUPPORTED_CARD");
+ break;
+ default:
+ strcpy(strErrorCode, "Unknown");
+ }
+ sprintf(ErrorString, "Error returned by PCSC: 0x%08X (%s)", rv, strErrorCode);
+ return ErrorString;
+}
+#endif
+
+/* define MAX_ATR_SIZE for all platforms */
+#ifndef MAX_ATR_SIZE
+#define MAX_ATR_SIZE 300
+#endif
+
+
+/***********************************************************
+ * pycsc object structure
+ ***********************************************************/
+typedef struct
+{
+ PyObject_HEAD
+ SCARDHANDLE hCard;
+ SCARDCONTEXT hContext;
+ DWORD sMode;
+ DWORD dwProtocol;
+} pycscobject;
+
+/* Exception used by this object */
+static PyObject *PycscException;
+
+/* Forward declaration of type descriptor */
+staticforward PyTypeObject PycscType;
+
+/***********************************************************
+ * Intance methods:
+ *
+ * reconnect()
+ * disconnect()
+ * status()
+ * control()
+ * transmit()
+ * cancel()
+ * beginTransaction()
+ * endTransaction()
+ * cancelTransaction()
+ *
+ ***********************************************************/
+static PyObject * pycsc_reconnect( PyObject *self, PyObject *args, PyObject *keywds)
+{
+ pycscobject *object = (pycscobject *)self;
+ LONG rv;
+ DWORD dwPreferredProtocol = SCARD_PROTOCOL_T0;
+ DWORD dwInitialization = SCARD_LEAVE_CARD;
+ DWORD pdwActiveProtocol;
+
+ static char *kwlist[] = {"smode", "protocol", "init", NULL};
+
+ object->sMode = SCARD_SHARE_SHARED; /* default value */
+
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "|lll", kwlist,
+ &object->sMode, &dwPreferredProtocol,
+ &dwInitialization))
+ return NULL;
+
+#ifdef DEBUG
+ printf("sMode = %ld\n",object->sMode);
+ printf("pProt = %ld\n",dwPreferredProtocol);
+ printf("init = %ld\n",dwInitialization);
+#endif
+ rv = SCardReconnect(object->hCard, object->sMode, dwPreferredProtocol,
+ dwInitialization, &pdwActiveProtocol);
+
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject * pycsc_disconnect(PyObject *self, PyObject * args)
+{
+ pycscobject *object = (pycscobject *)self;
+ DWORD dwDisposition = SCARD_LEAVE_CARD;
+ LONG rv;
+
+ if (!PyArg_ParseTuple(args,"|l", &dwDisposition))
+ return NULL;
+
+ rv = SCardDisconnect(object->hCard, dwDisposition);
+
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+#ifdef DEBUG
+ printf("pycsc_disconnect : OK\n");
+#endif
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* Returns a dictionary with keys as follows:
+ "ReaderName"
+ "State"
+ "Protocol"
+ "ATR"
+*/
+static PyObject * pycsc_status(PyObject *self, PyObject * args)
+{
+ pycscobject *object = (pycscobject *)self;
+ BYTE pbAtr[MAX_ATR_SIZE];
+ DWORD dwAtrLen, dwProt=0, dwState=0;
+ DWORD dwReaderLen;
+ LPSTR pcReaders;
+ LONG rv;
+ PyObject *ret_value;
+
+ dwReaderLen = 10000;
+ dwAtrLen = 0;
+ /* Dry run to get the length of the reader name */
+ rv = SCardStatus( object->hCard, (LPSTR) NULL, &dwReaderLen,
+ &dwState, &dwProt, NULL, &dwAtrLen );
+
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+
+#ifdef DEBUG
+ printf("SCardStatus dry run returned dwReaderLen= %ld, dwAtrLen= %ld\n",
+ dwReaderLen, dwAtrLen);
+#endif
+ pcReaders = (char *)PyMem_Malloc(sizeof(char)*dwReaderLen);
+ if (!pcReaders)
+ {
+ return PyErr_NoMemory();
+ }
+
+ /* Get values */
+ dwAtrLen = sizeof(pbAtr);
+ rv = SCardStatus( object->hCard, pcReaders, &dwReaderLen,
+ &dwState, &dwProt, pbAtr, &dwAtrLen );
+
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ PyMem_Free((void *)pcReaders);
+ return NULL;
+ }
+
+#ifdef DEBUG
+ printf("pycsc_status : OK up to build value\n");
+#endif
+ ret_value = Py_BuildValue("{s:s, s:i, s:i, s:s#}",
+ "ReaderName", pcReaders,
+ "State", dwState,
+ "Protocol", dwProt,
+ "ATR", pbAtr, dwAtrLen);
+
+#ifdef DEBUG
+ printf("pycsc_status : OK\n");
+#endif
+ PyMem_Free((void *)pcReaders);
+ return ret_value;
+}
+
+static PyObject * pycsc_control(PyObject *self, PyObject * args)
+{
+ PyErr_SetString(PycscException, "Not implemented");
+ return NULL;
+}
+
+
+/* Retrieve SCARD_PCI_XX address from SCARD_PROTOCOL_XX constant */
+static SCARD_IO_REQUEST *protocoltoPCI(DWORD dwProtocol)
+{
+ switch (dwProtocol)
+ {
+ case SCARD_PROTOCOL_T0:
+ return (SCARD_IO_REQUEST *)SCARD_PCI_T0;
+ case SCARD_PROTOCOL_T1:
+ return (SCARD_IO_REQUEST *)SCARD_PCI_T1;
+ case SCARD_PROTOCOL_RAW:
+ return (SCARD_IO_REQUEST *)SCARD_PCI_RAW;
+ default:
+ PyErr_SetString(PycscException, "Unknow value of io request");
+ return NULL;
+ }
+}
+
+/* args : a string representing data to send */
+static PyObject * pycsc_transmit(PyObject *self, PyObject * args,
+ PyObject *keywds)
+{
+ pycscobject *object = (pycscobject *)self;
+ LONG rv;
+ unsigned long len;
+ unsigned char *sendBuffer;
+ DWORD bSendPci;
+ SCARD_IO_REQUEST *pioSendPci;
+ BYTE resparray[1024];
+ DWORD resplength = sizeof(resparray);
+ static char *kwlist[] = {"com","sendPCI", NULL};
+
+ /* Default values */
+ bSendPci = object->dwProtocol;
+
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "s#|l", kwlist,
+ &sendBuffer, &len, &bSendPci))
+ return NULL;
+
+ pioSendPci = protocoltoPCI(bSendPci);
+ if (pioSendPci == NULL)
+ return NULL;
+
+ rv = SCardTransmit( object->hCard, pioSendPci, sendBuffer, len,
+ NULL, resparray, &resplength);
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+
+ return Py_BuildValue("s#", resparray, resplength);
+}
+
+static PyObject * pycsc_cancel(PyObject *self, PyObject * args)
+{
+ PyErr_SetString(PycscException, "Not implemented");
+ return NULL;
+}
+
+static PyObject * pycsc_beginTransaction(PyObject *self, PyObject * args)
+{
+ PyErr_SetString(PycscException, "Not implemented");
+ return NULL;
+}
+
+static PyObject * pycsc_endTransaction(PyObject *self, PyObject * args)
+{
+ PyErr_SetString(PycscException, "Not implemented");
+ return NULL;
+}
+
+static PyObject * pycsc_cancelTransaction(PyObject *self, PyObject * args)
+{
+ PyErr_SetString(PycscException, "Not implemented");
+ return NULL;
+}
+
+
+/* Declaration of methods */
+static struct PyMethodDef pycsc_methods[] =
+{
+ {"reconnect",(PyCFunction)pycsc_reconnect, METH_VARARGS|METH_KEYWORDS},
+ {"disconnect", pycsc_disconnect, METH_VARARGS},
+ {"status", pycsc_status, METH_VARARGS},
+ {"control", pycsc_control, METH_VARARGS},
+ {"transmit",(PyCFunction)pycsc_transmit, METH_VARARGS|METH_KEYWORDS},
+ {"cancel", pycsc_cancel, METH_VARARGS},
+ {"beginTransaction", pycsc_beginTransaction, METH_VARARGS},
+ {"endTransaction", pycsc_endTransaction, METH_VARARGS},
+ {"cancelTransaction", pycsc_cancelTransaction, METH_VARARGS},
+ {NULL, NULL}
+};
+
+
+/***********************************************************
+ * Type methods
+ *
+ * dealloc() (Destructor)
+ * getattr()
+ * repr()
+ *
+ ***********************************************************/
+static void pycsc_dealloc(PyObject *self)
+{
+ pycscobject *object = (pycscobject *)self;
+#ifdef DEBUG
+ SCARDCONTEXT hContext;
+ SCARDHANDLE hCard;
+ hContext = ((pycscobject *)self)->hContext;
+ hCard = ((pycscobject *)self)->hCard;
+#endif
+
+
+ //+ Disconnect leaving card untouched, any better idea?
+ SCardDisconnect( object->hCard, SCARD_LEAVE_CARD );
+ SCardReleaseContext( object->hContext );
+ PyObject_Del(object);
+#ifdef DEBUG
+ printf("pycsc_dealloc successful for hContext = %08X, hCard = %08X\n",
+ hContext, hCard);
+#endif
+
+}
+
+static PyObject * pycsc_getattr(PyObject *self, char* name)
+{
+ pycscobject *object = (pycscobject *)self;
+
+ return Py_FindMethod(pycsc_methods, (PyObject *) object, name);
+}
+
+static PyObject * pycsc_repr(PyObject *self)
+{
+ pycscobject *object = (pycscobject *)self;
+ char buffer[1024];
+
+ snprintf(buffer, sizeof(buffer),
+ "< pycsc, hContext = 0x%08lX, hCard = 0x%08lX at %lx >",
+ object->hContext, object->hCard, (LONG) object);
+ return PyString_FromString(buffer);
+}
+
+statichere PyTypeObject PycscType =
+{
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "pycsc", /* tp_name */
+ sizeof(pycscobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ pycsc_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc) pycsc_getattr,/* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc) pycsc_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc) 0, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc) 0, /* tp_str */
+};
+
+
+
+
+/***********************************************************
+ * Class methods
+ *
+ * pycsc()
+ * listReader()
+ * listReaderGroups()
+ * getStatusChange()
+ *
+ ***********************************************************/
+
+
+/* This is the "creator" for a new pycsc object */
+static PyObject * pycscobject_pycsc(PyObject *self, PyObject * args, PyObject *keywds)
+{
+ /* No reader name in args, connect to the first reader */
+ LPSTR mszReaders = NULL;
+ LPSTR szRequestedReader = "";
+ DWORD dwReaders;
+ DWORD dwMode = SCARD_SHARE_SHARED;
+ DWORD eProtocol; /* effective protocol */
+ DWORD dwPreferredProtocol = SCARD_PROTOCOL_T0;
+ SCARDCONTEXT hContext;
+ SCARDHANDLE hCard;
+ LONG rv;
+ pycscobject *newself;
+ static char *kwlist[] = {"reader", "mode", "protocol", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "|s#ll", kwlist,
+ &szRequestedReader, &dwReaders,
+ &dwMode,
+ &dwPreferredProtocol))
+ return NULL;
+
+#ifdef DEBUG
+ printf("pycsc called with: ");
+ if (szRequestedReader)
+ printf("Reader name: %s\n", szRequestedReader);
+ else
+ printf("Reader name not specified\n");
+ printf("Mode: %ld\n", dwMode);
+ printf("Preferred protocol: %ld\n", dwPreferredProtocol);
+#endif
+
+
+ /* Initialise context */
+ rv = SCardEstablishContext( SCARD_SCOPE_SYSTEM, NULL, NULL,
+ &hContext);
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+
+#ifdef DEBUG
+ printf("SCardEstablishContext successful\n");
+#endif
+ if (strlen(szRequestedReader) > 0)
+ {
+ // malloc a buffer to copy the reader name to have the same behiaviour
+ // as when selecting the first one
+ mszReaders = (char *)PyMem_Malloc(sizeof(char)*
+ (strlen(szRequestedReader)+1));
+
+ if (!mszReaders)
+ {
+ SCardReleaseContext( hContext );
+ return PyErr_NoMemory();
+ }
+ strncpy(mszReaders, szRequestedReader, strlen(szRequestedReader)+1);
+ }
+ else
+ {
+ // No reader specified, need to locate the first one
+ rv = getReaderList(hContext, &mszReaders, &dwReaders);
+
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ SCardReleaseContext( hContext );
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+ }
+ if (*mszReaders == '\0')
+ {
+ SCardReleaseContext( hContext );
+ PyErr_SetString(PycscException, "No reader connected");
+ return NULL;
+ }
+ /* Connect */
+ rv = SCardConnect(hContext, mszReaders, dwMode,
+ dwPreferredProtocol, &hCard, &eProtocol);
+ /* Free the memory now */
+ PyMem_Free((void *)mszReaders);
+
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ SCardReleaseContext( hContext );
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+
+ /* Now that everything worked, alloc new object */
+ /* replace self from class with the new instance */
+ newself = PyObject_New(pycscobject, & PycscType);
+ if (newself == NULL)
+ {
+ SCardReleaseContext( hContext );
+ PyErr_SetString(PycscException, "Could not allocate new object");
+ return NULL;
+ }
+ newself->hContext = hContext;
+ newself->hCard = hCard;
+ newself->sMode = dwMode;
+ newself->dwProtocol = eProtocol;
+
+#ifdef DEBUG
+ printf("Active protocol: 0xld\n", eProtocol);
+ printf("pycsc_pycsc: OK with hContext = 0x%08X, hCard = 0x%08X\n",
+ hContext, hCard);
+#endif
+
+ return (PyObject *) newself;
+}
+
+static PyObject * pycscobject_listReader(PyObject *self, PyObject * args)
+{
+ SCARDCONTEXT hContext;
+ LPSTR mszReaders = NULL;
+ LPSTR mszReadersScan;
+ DWORD dwReaders;
+ LONG rv;
+
+ PyObject *ret_value;
+
+ rv = SCardEstablishContext( SCARD_SCOPE_SYSTEM, NULL, NULL,
+ &hContext);
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+ rv = getReaderList(hContext, &mszReaders, &dwReaders);
+
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+ // Build output from mszReaders
+ ret_value = Py_BuildValue("[]");
+ if (!ret_value)
+ {
+ PyErr_SetString(PycscException, "Could not create list");
+ SCardReleaseContext(hContext);
+ PyMem_Free((void *)mszReaders);
+ return NULL;
+ }
+ mszReadersScan = mszReaders;
+ while (*mszReadersScan != '\0')
+ {
+ //+ Does that free memomry properly in case of error with the append
+ //+ probably Py_BuildValue("s", mszReadersScan) needs a DECREF
+ //+ and so does ret_value
+ if (PyList_Append(ret_value, Py_BuildValue("s", mszReadersScan)))
+ {
+ PyErr_SetString(PycscException, "Could not append reader name");
+ SCardReleaseContext(hContext);
+ PyMem_Free((void *)mszReaders);
+ return NULL;
+ }
+ mszReadersScan += strlen(mszReadersScan)+1;
+ }
+ SCardReleaseContext(hContext);
+ PyMem_Free((void *)mszReaders);
+ return ret_value;
+
+}
+
+static PyObject * pycscobject_listReaderGroups(PyObject *self, PyObject * args)
+{
+ PyErr_SetString(PycscException, "Not implemented");
+ return NULL;
+}
+
+static PyObject * pycscobject_getStatusChange(PyObject *self, PyObject * args, PyObject *keywds)
+{
+ SCARDCONTEXT hContext;
+ PyObject *ret_value = NULL;
+ SCARD_READERSTATE *pstReaderStates;
+ DWORD timeout = INFINITE;
+ PyObject *pyReaderStates = NULL;
+ PyObject *tmpSeq;
+ int readerstatesLength = 0;
+ int i;
+ LONG rv;
+
+ static char *kwlist[] = {"Timeout", "ReaderStates", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "|lO", kwlist,
+ &timeout, &pyReaderStates))
+ {
+ PyErr_SetString(PycscException, "Error parsing arguments");
+ return NULL;
+ }
+ // Create an empty sequence in case pyReaderStates was not given as arg
+ tmpSeq = Py_BuildValue("[]");
+ if (pyReaderStates==NULL)
+ {
+ pyReaderStates = tmpSeq;
+ }
+ // Parse the readerstate argument
+ pyReaderStates = PySequence_Fast(pyReaderStates, "pycsc: getStatusChange: Expecting sequence argument for readerstates");
+ Py_DECREF(tmpSeq);
+ if ( ! pyReaderStates )
+ {
+ PyErr_SetString(PycscException, "Error in call to PySequence_Fast");
+ return NULL;
+ }
+ readerstatesLength = PySequence_Fast_GET_SIZE(pyReaderStates);
+ pstReaderStates = PyMem_Malloc(sizeof(SCARD_READERSTATE)*readerstatesLength);
+ if (!pstReaderStates)
+ {
+ Py_DECREF(pyReaderStates);
+ return PyErr_NoMemory();
+ }
+
+ // Iterate on the sequence. Each element should be a mapping reflecting the content of the struct
+ for (i=0; i<readerstatesLength; i++)
+ {
+ PyObject *pyReaderState;
+ pyReaderState = PySequence_Fast_GET_ITEM(pyReaderStates, i);
+ if ( (!pyReaderState) || (! PyMapping_Check(pyReaderState)) )
+ {
+ // Release memory
+ for (;i>0; i--)
+ {
+ PyMem_Free((void *)pstReaderStates[i-1].szReader);
+ }
+ PyMem_Free((void *)pstReaderStates);
+ Py_DECREF(pyReaderStates);
+ PyErr_SetString(PycscException, "pycsc: getStatusChange: Expecting mapping argument for each readerstate");
+ return NULL;
+ }
+ // Parse the content of the mapping to set the structure
+ // The keys of the mapping are:
+ // "reader" for the reader name
+ // "currentState" for the set of state information to watch for
+ // Missing value values will be replaced by default values ("" for reader, SCARD_STATE_EMPTY for currentState)
+ pstReaderStates[0].szReader = "";
+ pstReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;
+ // First deal with dwCurrentState as the szReader free loop on error will be the same as below
+ if (PyMapping_HasKeyString(pyReaderState, "CurrentState"))
+ {
+ PyObject *pycurrentState = NULL;
+ pycurrentState = PyMapping_GetItemString(pyReaderState, "CurrentState");
+ if (!PyInt_Check(pycurrentState))
+ {
+ for (;i>0; i--)
+ {
+ PyMem_Free((void *)pstReaderStates[i-1].szReader);
+ }
+ PyMem_Free((void *)pstReaderStates);
+ Py_DECREF(pyReaderStates);
+ PyErr_SetString(PycscException, "pycsc: getStatusChange: Expecting \"CurrentState\" key to reference an integer");
+ return NULL;
+ }
+ pstReaderStates[i].dwCurrentState = PyInt_AsLong(pycurrentState);
+ }
+ if (PyMapping_HasKeyString(pyReaderState, "Reader"))
+ {
+ PyObject *pyReader = NULL;
+ char *pcReaderName;
+ int length;
+ pyReader = PyMapping_GetItemString(pyReaderState, "Reader");
+ if (!PyString_Check(pyReader))
+ {
+ for (;i>0; i--)
+ {
+ PyMem_Free((void *)pstReaderStates[i-1].szReader);
+ }
+ PyMem_Free((void *)pstReaderStates);
+ Py_DECREF(pyReaderStates);
+ PyErr_SetString(PycscException, "pycsc: getStatusChange: Expecting \"Reader\" key to reference a string");
+ return NULL;
+ }
+ // Make a copy of the string.
+ length = sizeof(char)*(strlen(PyString_AsString(pyReader))+1);
+ pcReaderName = PyMem_Malloc(length);
+ if (!pcReaderName)
+ {
+ for (;i>0; i--)
+ {
+ PyMem_Free((void *)pstReaderStates[i-1].szReader);
+ }
+ PyMem_Free((void *)pstReaderStates);
+ Py_DECREF(pyReaderStates);
+ PyErr_SetString(PycscException, "pycsc: getStatusChange: Memory allocation error");
+ return NULL;
+ }
+ strncpy(pcReaderName, PyString_AsString(pyReader), length);
+ pcReaderName[length-1] = '\0';
+ pstReaderStates[i].szReader = pcReaderName;
+ pstReaderStates[i].pvUserData = NULL;
+ }
+ }
+ // Input is not required anymore.
+ Py_DECREF(pyReaderStates);
+
+ // Connect to pcsc.
+ rv = SCardEstablishContext( SCARD_SCOPE_SYSTEM, NULL, NULL,
+ &hContext);
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ for (i=0;i<readerstatesLength; i++)
+ {
+ PyMem_Free((void *)pstReaderStates[i].szReader);
+ }
+ PyMem_Free((void *)pstReaderStates);
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+
+
+ rv = SCardGetStatusChange(hContext, timeout, pstReaderStates,
+ readerstatesLength);
+ SCardReleaseContext(hContext);
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ for (i=0;i<readerstatesLength; i++)
+ {
+ PyMem_Free((void *)pstReaderStates[i].szReader);
+ }
+ PyMem_Free((void *)pstReaderStates);
+ PyErr_SetString(PycscException, pcsc_stringify_error(rv));
+ return NULL;
+ }
+
+ // Construct the response sequence of mappings
+ ret_value = Py_BuildValue("[]");
+ if (!ret_value)
+ {
+ for (i=0;i<readerstatesLength; i++)
+ {
+ PyMem_Free((void *)pstReaderStates[i].szReader);
+ }
+ PyMem_Free((void *)pstReaderStates);
+ PyErr_SetString(PycscException, "Could not create list");
+ return NULL;
+ }
+ for (i=0;i<readerstatesLength; i++)
+ {
+ PyObject *pyreaderstate;
+ pyreaderstate = Py_BuildValue("{s:s, s:s, s:i, s:i, s:s#}",
+ "Reader", pstReaderStates[i].szReader,
+ "UserData", "",
+ "CurrentState", pstReaderStates[i].dwCurrentState,
+ "EventState", pstReaderStates[i].dwEventState,
+ "Atr", pstReaderStates[i].rgbAtr, pstReaderStates[i].cbAtr);
+ if (!pyreaderstate)
+ {
+ Py_DECREF(ret_value);
+ // Up to the value of i (non inclusive), the memory has already been released
+ for (;i<readerstatesLength; i++)
+ {
+ PyMem_Free((void *)pstReaderStates[i].szReader);
+ }
+ PyMem_Free((void *)pstReaderStates);
+ PyErr_SetString(PycscException, "Could not create dictionnary");
+ return NULL;
+ }
+ if (PyList_Append(ret_value, Py_BuildValue("O", pyreaderstate)))
+ {
+ PyErr_SetString(PycscException, "Could not append dictionnary to sequence");
+ Py_DECREF(ret_value);
+ Py_DECREF(pyreaderstate);
+ // Up to the value of i (non inclusive), the memory has already been released
+ for (;i<readerstatesLength; i++)
+ {
+ PyMem_Free((void *)pstReaderStates[i].szReader);
+ }
+ PyMem_Free((void *)pstReaderStates);
+ PyErr_SetString(PycscException, "Could not create dictionnary");
+ return NULL;
+ }
+ // Release memory as soon as we don't need it anymore
+ PyMem_Free((void *)pstReaderStates[i].szReader);
+ }
+
+
+ // Release memory
+ PyMem_Free((void *)pstReaderStates);
+
+ return ret_value;
+}
+
+
+/* Declaration of methods */
+static struct PyMethodDef pycsctype_methods[] =
+{
+ {"pycsc",(PyCFunction)pycscobject_pycsc, METH_VARARGS|METH_KEYWORDS},
+ {"listReader", pycscobject_listReader, METH_VARARGS},
+ {"listReaderGroups", pycscobject_listReaderGroups, METH_VARARGS},
+ {"getStatusChange",(PyCFunction) pycscobject_getStatusChange, METH_VARARGS|METH_KEYWORDS},
+ {(char*)NULL, (PyCFunction)NULL, (int)NULL}
+};
+
+
+/* Module initialisation */
+void initpycsc(void)
+{
+ PyObject *m, *d;
+
+ /* patch object type for building dll on windows... */
+ PycscType.ob_type = &PyType_Type;
+ m = Py_InitModule("pycsc", pycsctype_methods);
+ d = PyModule_GetDict(m);
+
+ //+ Add error code and constants definitions
+ PyDict_SetItemString(d, "SCARD_LEAVE_CARD", PyInt_FromLong(SCARD_LEAVE_CARD));
+ PyDict_SetItemString(d, "SCARD_RESET_CARD", PyInt_FromLong(SCARD_RESET_CARD));
+ PyDict_SetItemString(d, "SCARD_SHARE_SHARED", PyInt_FromLong(SCARD_SHARE_SHARED));
+ PyDict_SetItemString(d, "SCARD_SHARE_EXCLUSIVE", PyInt_FromLong(SCARD_SHARE_EXCLUSIVE));
+ PyDict_SetItemString(d, "SCARD_SHARE_DIRECT", PyInt_FromLong(SCARD_SHARE_DIRECT));
+
+ PyDict_SetItemString(d, "SCARD_PROTOCOL_T0", PyInt_FromLong(SCARD_PROTOCOL_T0));
+ PyDict_SetItemString(d, "SCARD_PROTOCOL_T1", PyInt_FromLong(SCARD_PROTOCOL_T1));
+ PyDict_SetItemString(d, "SCARD_PROTOCOL_RAW", PyInt_FromLong(SCARD_PROTOCOL_RAW));
+#ifdef _WINDOWS_
+ PyDict_SetItemString(d, "SCARD_PROTOCOL_UNDEFINED", PyInt_FromLong(SCARD_PROTOCOL_UNDEFINED));
+#endif
+ PyDict_SetItemString(d, "SCARD_ABSENT", PyInt_FromLong(SCARD_ABSENT));
+ PyDict_SetItemString(d, "SCARD_PRESENT", PyInt_FromLong(SCARD_PRESENT));
+ PyDict_SetItemString(d, "SCARD_SWALLOWED", PyInt_FromLong(SCARD_SWALLOWED));
+ PyDict_SetItemString(d, "SCARD_POWERED", PyInt_FromLong(SCARD_POWERED));
+ PyDict_SetItemString(d, "SCARD_NEGOTIABLE", PyInt_FromLong(SCARD_NEGOTIABLE));
+ PyDict_SetItemString(d, "SCARD_SPECIFIC", PyInt_FromLong(SCARD_SPECIFIC));
+#ifndef _WINDOWS_
+ // PCSC-lite specific
+ PyDict_SetItemString(d, "SCARD_PROTOCOL_ANY", PyInt_FromLong(SCARD_PROTOCOL_ANY));
+#endif
+ PyDict_SetItemString(d, "SCARD_STATE_UNAWARE", PyInt_FromLong(SCARD_STATE_UNAWARE));
+ PyDict_SetItemString(d, "SCARD_STATE_IGNORE", PyInt_FromLong(SCARD_STATE_IGNORE));
+ PyDict_SetItemString(d, "SCARD_STATE_CHANGED", PyInt_FromLong(SCARD_STATE_CHANGED));
+ PyDict_SetItemString(d, "SCARD_STATE_UNKNOWN", PyInt_FromLong(SCARD_STATE_UNKNOWN));
+ PyDict_SetItemString(d, "SCARD_STATE_UNAVAILABLE", PyInt_FromLong(SCARD_STATE_UNAVAILABLE));
+ PyDict_SetItemString(d, "SCARD_STATE_EMPTY", PyInt_FromLong(SCARD_STATE_EMPTY));
+ PyDict_SetItemString(d, "SCARD_STATE_PRESENT", PyInt_FromLong(SCARD_STATE_PRESENT));
+ PyDict_SetItemString(d, "SCARD_STATE_ATRMATCH", PyInt_FromLong(SCARD_STATE_ATRMATCH));
+ PyDict_SetItemString(d, "SCARD_STATE_EXCLUSIVE", PyInt_FromLong(SCARD_STATE_EXCLUSIVE));
+ PyDict_SetItemString(d, "SCARD_STATE_INUSE", PyInt_FromLong(SCARD_STATE_INUSE));
+ PyDict_SetItemString(d, "SCARD_STATE_MUTE", PyInt_FromLong(SCARD_STATE_MUTE));
+ //+ Define the PycscException
+ PycscException = PyErr_NewException("pycsc.PycscException", NULL, NULL);
+ PyDict_SetItemString(d, "PycscException", PycscException);
+}
+
+/* Internal tool */
+static LONG getReaderList(SCARDCONTEXT hContext, LPSTR* pmszReaders, DWORD *pdwReaders)
+{
+ LPCSTR mszGroups = 0;
+ LPSTR mszReaders = NULL;
+ LONG dwReaders;
+ LONG rv;
+
+ /* Read size of reader list */
+ rv = SCardListReaders( hContext, mszGroups, 0, &dwReaders );
+
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ return rv;
+ }
+#ifdef DEBUG
+ printf("SCardListReaders dry run successful\n");
+#endif
+
+ /* malloc a buffer to store reader names */
+ mszReaders = (char *)PyMem_Malloc(sizeof(char)*dwReaders);
+
+ if (!mszReaders)
+ {
+ return SCARD_E_NO_MEMORY;
+ }
+
+ /* Get the list of readers*/
+ rv = SCardListReaders(hContext, mszGroups,
+ mszReaders, &dwReaders );
+
+ if ( rv != SCARD_S_SUCCESS )
+ {
+ PyMem_Free((void *)mszReaders);
+ return rv;
+ }
+#ifdef DEBUG
+ printf("SCardListReaders successful\n");
+#endif
+ *pmszReaders = mszReaders;
+ *pdwReaders = dwReaders;
+ return SCARD_S_SUCCESS;
+}
Added: trunk/pycsc/setup.py
===================================================================
--- trunk/pycsc/setup.py 2006-11-15 14:52:54 UTC (rev 2210)
+++ trunk/pycsc/setup.py 2006-11-16 13:13:40 UTC (rev 2211)
@@ -0,0 +1,50 @@
+#***********************************************************
+# Title: setup.py
+# Author: Jean-Luc Giraud <jlgiraud at mac.com>
+# Compiler: python2.2
+# Platform: Linux
+# Purpose: Python class to communicate with smart cards
+# License: See file COPYING
+# $Id: setup.py,v 1.4 2004-01-19 16:09:32 giraud Exp $
+#
+# Copyright (c) 2002 - Jean-Luc Giraud.
+#
+#************************************************************
+
+
+
+from distutils.core import setup, Extension
+import sys
+import os
+
+if sys.platform == 'darwin':
+
+ extra_link = ['-framework', 'PCSC']
+ lib_dirs = ["/System/Library/Frameworks/PCSC.framework/"]
+ libs = []
+ include = ["/System/Library/Frameworks/PCSC.framework/Headers/"]
+else:
+ extra_link = []
+ lib_dirs = []
+ if os.name == 'nt':
+ libs = ["winscard"]
+ include = []
+ else:
+ libs = ["pcsclite"]
+ include = ["/usr/include/pcsc"]
+
+
+setup(name="pycsc", version="0.3",
+ ext_modules=[
+ Extension(
+ "pycsc",
+ ["pycsc.c"],
+ include_dirs = include,
+# define_macros=[('DEBUG', '1')],
+ undef_macros=['RELEASE'],
+ library_dirs=[],
+ libraries = libs,
+ extra_link_args=extra_link
+ )
+ ]
+)
Property changes on: trunk/pycsc/setup.py
___________________________________________________________________
Name: svn:executable
+ *
More information about the Pcsclite-cvs-commit
mailing list