49 #include <sys/types.h>
51 #include <sys/socket.h>
54 #include <sys/ioctl.h>
60 #ifdef HAVE_SYS_FILIO_H
61 #include <sys/filio.h>
81 #define SOCK_CLOEXEC 0
84 char *getSocketName(
void)
86 static char socketName[
sizeof(
struct sockaddr_un)];
88 if (
'\0' == socketName[0])
93 socketNameEnv = getenv(
"PCSCLITE_CSOCK_NAME");
95 strncpy(socketName, socketNameEnv,
sizeof(socketName));
97 strncpy(socketName, PCSCLITE_CSOCK_NAME,
sizeof(socketName));
100 socketName[
sizeof socketName -1] =
'\0';
121 struct sockaddr_un svc_addr;
125 ret = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
128 Log2(PCSC_LOG_CRITICAL,
"Error: create on client socket: %s",
134 socketName = getSocketName();
135 svc_addr.sun_family = AF_UNIX;
136 strncpy(svc_addr.sun_path, socketName,
sizeof(svc_addr.sun_path));
138 if (connect(*pdwClientID, (
struct sockaddr *) &svc_addr,
139 sizeof(svc_addr.sun_family) + strlen(svc_addr.sun_path) + 1) < 0)
141 Log3(PCSC_LOG_CRITICAL,
"Error: connect to client socket %s: %s",
142 socketName, strerror(errno));
143 (void)close(*pdwClientID);
147 ret = fcntl(*pdwClientID, F_GETFL, 0);
150 Log3(PCSC_LOG_CRITICAL,
"Error: cannot retrieve socket %s flags: %s",
151 socketName, strerror(errno));
152 (void)close(*pdwClientID);
156 if (fcntl(*pdwClientID, F_SETFL, ret | O_NONBLOCK) < 0)
158 Log3(PCSC_LOG_CRITICAL,
"Error: cannot set socket %s nonblocking: %s",
159 socketName, strerror(errno));
160 (void)close(*pdwClientID);
176 return close(dwClientID);
196 uint64_t buffer_size, int32_t filedes,
long timeOut)
198 char *buffer = buffer_void;
204 struct timeval start;
207 size_t remaining = buffer_size;
209 gettimeofday(&start, NULL);
212 while (remaining > 0)
215 struct timeval timeout, now;
219 gettimeofday(&now, NULL);
222 if (delta > timeOut*1000)
230 delta = timeOut*1000 - delta;
233 FD_SET(filedes, &read_fd);
235 timeout.tv_sec = delta/1000000;
236 timeout.tv_usec = delta - timeout.tv_sec*1000000;
238 selret = select(filedes + 1, &read_fd, NULL, NULL, &timeout);
245 if (!FD_ISSET(filedes, &read_fd))
251 readed = read(filedes, buffer, remaining);
258 }
else if (readed == 0)
267 if (errno != EINTR && errno != EAGAIN)
273 }
else if (selret == 0)
286 Log2(PCSC_LOG_INFO,
"Command 0x%X not yet finished", command);
292 Log2(PCSC_LOG_ERROR,
"select returns with failure: %s",
318 uint64_t size,
void *data_void)
326 ret =
MessageSend(&header,
sizeof(header), dwClientID);
353 INTERNAL LONG
MessageSend(
void *buffer_void, uint64_t buffer_size,
356 char *buffer = buffer_void;
362 size_t remaining = buffer_size;
365 while (remaining > 0)
371 FD_SET(filedes, &write_fd);
373 selret = select(filedes + 1, NULL, &write_fd, NULL, NULL);
380 if (!FD_ISSET(filedes, &write_fd))
391 written = send(filedes, buffer, remaining, MSG_NOSIGNAL);
394 written = write(filedes, buffer, remaining);
401 remaining -= written;
402 }
else if (written == 0)
411 if (errno != EINTR && errno != EAGAIN)
417 }
else if (selret == 0)
427 Log2(PCSC_LOG_ERROR,
"select returns with failure: %s",
454 char *buffer = buffer_void;
460 size_t remaining = buffer_size;
463 while (remaining > 0)
469 FD_SET(filedes, &read_fd);
471 selret = select(filedes + 1, &read_fd, NULL, NULL, NULL);
478 if (!FD_ISSET(filedes, &read_fd))
484 readed = read(filedes, buffer, remaining);
491 }
else if (readed == 0)
500 if (errno != EINTR && errno != EAGAIN)
512 Log2(PCSC_LOG_ERROR,
"select returns with failure: %s",
INTERNAL int ClientCloseSession(uint32_t dwClientID)
Closes the socket used by the client to communicate with the server.
INTERNAL LONG MessageSendWithHeader(uint32_t command, uint32_t dwClientID, uint64_t size, void *data_void)
Wrapper for the MessageSend() function.
#define SCARD_F_COMM_ERROR
An internal communications error has been detected.
This handles abstract system level calls.
#define SCARD_E_NO_SERVICE
The Smart card resource manager is not running.
INTERNAL LONG MessageReceive(void *buffer_void, uint64_t buffer_size, int32_t filedes)
Called by the Client to get the reponse from the server or vice-versa.
This defines some structures and #defines to be used over the transport layer.
long int time_sub(struct timeval *a, struct timeval *b)
return the difference (as long int) in µs between 2 struct timeval r = a - b
LONG SCardCheckDaemonAvailability(void)
Checks if the server is running.
INTERNAL int ClientSetupSession(uint32_t *pdwClientID)
Prepares a communication channel for the client to talk to the server.
This keeps a list of defines for pcsc-lite.
INTERNAL LONG MessageSend(void *buffer_void, uint64_t buffer_size, int32_t filedes)
Sends a menssage from client to server or vice-versa.
#define SCARD_S_SUCCESS
error codes from http://msdn.microsoft.com/en-us/library/aa924526.aspx
This handles smart card reader communications.
INTERNAL LONG MessageReceiveTimeout(uint32_t command, void *buffer_void, uint64_t buffer_size, int32_t filedes, long timeOut)
Called by the Client to get the reponse from the server or vice-versa.
#define SCARD_E_TIMEOUT
The user-specified timeout value has expired.