[Pcsclite-cvs-commit] r6052 - in /trunk/PCSC/src/spy: pcsc-spy.c pcsc-spy.py
rousseau at users.alioth.debian.org
rousseau at users.alioth.debian.org
Thu Oct 20 14:15:37 UTC 2011
Author: rousseau
Date: Thu Oct 20 14:15:37 2011
New Revision: 6052
URL: http://svn.debian.org/wsvn/pcsclite/?sc=1&rev=6052
Log:
Add support of SCardCancel() and multi-threaded applications
The pcsc-spy.py client is now a demultiplexer with one thread and data
queue per applicatin thread. Each log line contains the application
threadID.
Modified:
trunk/PCSC/src/spy/pcsc-spy.c
trunk/PCSC/src/spy/pcsc-spy.py
Modified: trunk/PCSC/src/spy/pcsc-spy.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/spy/pcsc-spy.c?rev=6052&op=diff
==============================================================================
--- trunk/PCSC/src/spy/pcsc-spy.c (original)
+++ trunk/PCSC/src/spy/pcsc-spy.c Thu Oct 20 14:15:37 2011
@@ -27,11 +27,10 @@
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
+#include <pthread.h>
#include "misc.h"
#include <winscard.h>
-
-#define VERSION 1
#define DEBUG
@@ -130,6 +129,7 @@
static int Log_fd = -1;
static void *Lib_handle = NULL;
+static pthread_mutex_t Log_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
#ifdef DEBUG
static void log_line(const char *fmt, ...)
@@ -149,12 +149,18 @@
static void spy_line_direct(char *line)
{
+ char threadid[30];
+
/* spying disabled */
if (Log_fd < 0)
return;
+ snprintf(threadid, sizeof threadid, "%lX@", pthread_self());
+ pthread_mutex_lock(&Log_fd_mutex);
+ write(Log_fd, threadid, strlen(threadid));
write(Log_fd, line, strlen(line));
write(Log_fd, "\n", 1);
+ pthread_mutex_unlock(&Log_fd_mutex);
}
static void spy_line(const char *fmt, ...)
@@ -162,6 +168,7 @@
va_list args;
char line[256];
int size;
+ char threadid[30];
/* spying disabled */
if (Log_fd < 0)
@@ -174,8 +181,12 @@
printf("Buffer is too small. Exiting!\n");
exit(-1);
}
+ snprintf(threadid, sizeof threadid, "%lX@", pthread_self());
+ pthread_mutex_lock(&Log_fd_mutex);
+ write(Log_fd, threadid, strlen(threadid));
write(Log_fd, line, size);
write(Log_fd, "\n", 1);
+ pthread_mutex_unlock(&Log_fd_mutex);
va_end(args);
}
@@ -381,8 +392,6 @@
{
log_line("open %s failed: %s", log_pipe, strerror(errno));
}
- else
- spy_line("PCSC SPY VERSION: %d", VERSION);
}
Enter();
@@ -625,6 +634,7 @@
LONG rv;
Enter();
+ spy_long(hContext);
rv = spy.SCardCancel(hContext);
Quit();
return rv;
Modified: trunk/PCSC/src/spy/pcsc-spy.py
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/spy/pcsc-spy.py?rev=6052&op=diff
==============================================================================
--- trunk/PCSC/src/spy/pcsc-spy.py (original)
+++ trunk/PCSC/src/spy/pcsc-spy.py Thu Oct 20 14:15:37 2011
@@ -21,6 +21,8 @@
# $Id$
import os
+from Queue import Queue
+from threading import Thread
class PCSCspy(object):
@@ -48,7 +50,7 @@
def _log_rv(self):
""" log the return value """
- line = self.filedesc.readline().strip()
+ line = self.queue.get()
(code, rv, sec, usec) = self._parse_rv(line)
delta_sec = sec - self.sec
delta_usec = usec - self.usec
@@ -146,17 +148,17 @@
def log_in_hCard(self):
""" log hCard IN parameter """
- hContext = self.filedesc.readline().strip()
+ hContext = self.queue.get()
self.log_in("hCard: %s" % hContext)
def log_in_hContext(self):
""" log hContext IN parameter """
- hContext = self.filedesc.readline().strip()
+ hContext = self.queue.get()
self.log_in("hContext: %s" % hContext)
def log_in_disposition(self):
""" log dwDisposition IN parameter """
- dwDisposition = self.filedesc.readline().strip()
+ dwDisposition = self.queue.get()
dispositions = {0: 'SCARD_LEAVE_CARD',
1: 'SCARD_RESET_CARD',
2: 'SCARD_UNPOWER_CARD',
@@ -170,7 +172,7 @@
def log_in_attrid(self):
""" log dwAttrId IN parameter """
- dwAttrId = self.filedesc.readline().strip()
+ dwAttrId = self.queue.get()
attrids = {0x00010100: 'SCARD_ATTR_VENDOR_NAME',
0x00010102: 'SCARD_ATTR_VENDOR_IFD_VERSION',
0x00010103: 'SCARD_ATTR_VENDOR_IFD_SERIAL_NO',
@@ -187,7 +189,7 @@
def log_in_dwShareMode(self):
""" log dwShareMode IN parameter """
- dwShareMode = self.filedesc.readline().strip()
+ dwShareMode = self.queue.get()
sharemodes = {1: 'SCARD_SHARE_EXCLUSIVE',
2: 'SCARD_SHARE_SHARED',
3: 'SCARD_SHARE_DIRECT'}
@@ -199,7 +201,7 @@
def log_in_dwPreferredProtocols(self):
""" log dwPreferredProtocols IN parameter """
- dwPreferredProtocols = self.filedesc.readline().strip()
+ dwPreferredProtocols = self.queue.get()
PreferredProtocols = list()
protocol = int(dwPreferredProtocols, 16)
if protocol & 1:
@@ -215,7 +217,7 @@
def log_out_dwActiveProtocol(self):
""" log dwActiveProtocol OUT parameter """
- dwActiveProtocol = self.filedesc.readline().strip()
+ dwActiveProtocol = self.queue.get()
protocol = int(dwActiveProtocol, 16)
if protocol & 1:
protocol = "T=0"
@@ -232,7 +234,7 @@
def log_out_hContext(self):
""" log hContext OUT parameter """
- hContext = self.filedesc.readline().strip()
+ hContext = self.queue.get()
self.log_out("hContext: %s" % hContext)
def _get_state(self, dwState):
@@ -258,19 +260,19 @@
def log_dwCurrentState(self, log):
""" log dwCurrentState IN/OUT parameter """
- dwCurrentState = self.filedesc.readline().strip()
+ dwCurrentState = self.queue.get()
state = self._get_state(int(dwCurrentState, 16))
log(" dwCurrentState: %s (%s)" % (state, dwCurrentState))
def log_dwEventState(self, log):
""" log dwEventState IN/OUT parameter """
- dwEventState = self.filedesc.readline().strip()
+ dwEventState = self.queue.get()
state = self._get_state(int(dwEventState, 16))
log(" dwEventState: %s (%s)" % (state, dwEventState))
def log_dwControlCode(self):
""" log SCardControl() dwControlCode """
- dwControlCode = self.filedesc.readline().strip()
+ dwControlCode = self.queue.get()
try:
code = self.ControlCodes[int(dwControlCode, 16)]
@@ -282,7 +284,7 @@
def log_in2(self, header):
""" generic log IN parameter """
- data = self.filedesc.readline().strip()
+ data = self.queue.get()
if data.startswith("0x"):
decimal = int(data, 16)
self.log_in("%s %s (%d)" % (header, data, decimal))
@@ -292,7 +294,7 @@
def log_out2(self, header):
""" generic log OUT parameter """
- data = self.filedesc.readline().strip()
+ data = self.queue.get()
if data.startswith("0x"):
decimal = int(data, 16)
self.log_out("%s %s (%d)" % (header, data, decimal))
@@ -302,12 +304,12 @@
def log_out_n_str(self, size_name, field_name):
""" log multi-lines entries """
- data = self.filedesc.readline().strip()
+ data = self.queue.get()
self.log_out("%s %s" % (size_name, data))
size = int(data, 16)
data_read = 0
while data_read < size:
- data = self.filedesc.readline().strip()
+ data = self.queue.get()
self.log_out("%s %s" % (field_name, data))
if data == 'NULL':
break
@@ -356,7 +358,7 @@
return ''.join(['.', chr(c)][c > 31 and c < 127]
for c in data_buffer)
- hex_buffer = self.filedesc.readline().strip()
+ hex_buffer = self.queue.get()
log(field)
if hex_buffer == "NULL":
log(" NULL")
@@ -370,7 +372,7 @@
def _SCardEstablishContext(self):
""" SCardEstablishContext """
self.log_name("SCardEstablishContext")
- dwScope = self.filedesc.readline().strip()
+ dwScope = self.queue.get()
scopes = {0: 'SCARD_SCOPE_USER',
1: 'SCARD_SCOPE_TERMINAL',
2: 'SCARD_SCOPE_SYSTEM'}
@@ -411,7 +413,7 @@
self.log_name("SCardGetStatusChange")
self.log_in_hContext()
self.log_in2("dwTimeout:")
- readers = int(self.filedesc.readline().strip(), 16)
+ readers = int(self.queue.get(), 16)
self.log_in("cReaders: %d" % readers)
self._log_readers(readers, direction="in")
self._log_readers(readers, direction="out")
@@ -584,32 +586,17 @@
self.log_in_disposition()
self._log_rv()
- def __del__(self):
- """ cleanup """
- from stat import S_ISFIFO
- file_stat = os.stat(self.fifo)
-
- # remove the log fifo only if it is a FIFO and not a log file
- if S_ISFIFO(file_stat.st_mode):
- os.unlink(self.fifo)
-
- def __init__(self, logfile=None):
+ def _SCardCancel(self):
+ """ SCardCancel """
+ self.log_name("SCardCancel")
+ self.log_in_hCard()
+ self._log_rv()
+
+ def __init__(self, queue):
""" constructor """
- # use default fifo file?
- if logfile == None:
- logfile = os.path.expanduser('~/pcsc-spy')
-
- # create the FIFO file
- try:
- os.mkfifo(logfile)
- except (OSError):
- print "fifo %s already present. Reusing it." % logfile
-
- self.sec = self.usec = 0
-
- self.fifo = logfile
- self.filedesc = open(self.fifo, 'r')
+ # communication queue
+ self.queue = queue
self.features = {0x01: "FEATURE_VERIFY_PIN_START",
0x02: "FEATURE_VERIFY_PIN_FINISH",
@@ -643,20 +630,15 @@
for key in self.features.keys():
self.__dict__[self.features[key]] = -1
- def loop(self):
- """ loop reading logs """
-
- # check version
- version = self.filedesc.readline().strip()
- if version != "PCSC SPY VERSION: 1":
- print "Wrong version:", version
- return
-
- line = self.filedesc.readline()
+ def worker(self, *args):
+ line = self.queue.get()
while line != '':
# Enter function?
if line[0] != '>':
- print "Garbage: ", line
+ if line == 'EXIT':
+ return
+ else:
+ print "Garbage: ", line
else:
# dispatch
(direction, sec, usec, fct) = line.strip().split('|')
@@ -696,15 +678,72 @@
self._SCardBeginTransaction()
elif fct == 'SCardEndTransaction':
self._SCardEndTransaction()
+ elif fct == 'SCardCancel':
+ self._SCardCancel()
else:
print "Unknown function:", fct
- line = self.filedesc.readline()
+ line = self.queue.get()
+
+class PCSCdemultiplexer(object):
+ def __init__(self, logfile=None):
+ """ constructor """
+
+ # use default fifo file?
+ if logfile == None:
+ logfile = os.path.expanduser('~/pcsc-spy')
+
+ # create the FIFO file
+ try:
+ os.mkfifo(logfile)
+ except (OSError):
+ print "fifo %s already present. Reusing it." % logfile
+
+ self.sec = self.usec = 0
+
+ self.fifo = logfile
+ self.filedesc2 = open(self.fifo, 'r')
+
+ self.queues = dict()
+
+ def __del__(self):
+ """ cleanup """
+ from stat import S_ISFIFO
+ file_stat = os.stat(self.fifo)
+
+ # remove the log fifo only if it is a FIFO and not a log file
+ if S_ISFIFO(file_stat.st_mode):
+ os.unlink(self.fifo)
+
+ def loop(self):
+ """ loop reading logs """
+
+ # dispatch
+ line = self.filedesc2.readline().strip()
+ threads = dict()
+ while line != '':
+ (thread, tail) = line.split('@')
+
+ try:
+ queue = self.queues[thread]
+ except KeyError:
+ queue = self.queues[thread] = Queue()
+ # new worker
+ spy = PCSCspy(queue)
+ threads[thread] = Thread(target=spy.worker)
+ threads[thread].start()
+
+ queue.put(tail)
+
+ line = self.filedesc2.readline().strip()
+
+ for thread in self.queues.keys():
+ self.queues[thread].put('EXIT')
def main(logfile=None):
""" main """
- spy = PCSCspy(logfile)
+ spy = PCSCdemultiplexer(logfile)
spy.loop()
More information about the Pcsclite-cvs-commit
mailing list