49#include <sys/socket.h>
82#define member_size(type, member) sizeof(((type *)0)->member)
84static char SocketName[member_size(
struct sockaddr_un, sun_path)];
85static pthread_once_t SocketName_init_control = PTHREAD_ONCE_INIT;
86static void SocketName_init(
void)
89 const char *socketNameEnv;
91 socketNameEnv =
SYS_GetEnv(
"PCSCLITE_CSOCK_NAME");
93 strncpy(SocketName, socketNameEnv,
sizeof SocketName);
95 strncpy(SocketName, PCSCLITE_CSOCK_NAME,
sizeof SocketName);
98 SocketName[
sizeof SocketName -1] =
'\0';
101char *getSocketName(
void)
103 pthread_once(&SocketName_init_control, SocketName_init);
123 struct sockaddr_un svc_addr;
127 ret = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
130 Log2(PCSC_LOG_CRITICAL,
"Error: create on client socket: %s",
136 socketName = getSocketName();
137 svc_addr.sun_family = AF_UNIX;
138 strncpy(svc_addr.sun_path, socketName,
sizeof(svc_addr.sun_path));
140 if (connect(*pdwClientID, (
struct sockaddr *) &svc_addr,
141 sizeof(svc_addr.sun_family) + strlen(svc_addr.sun_path) + 1) < 0)
143 Log3(PCSC_LOG_CRITICAL,
"Error: connect to client socket %s: %s",
144 socketName, strerror(errno));
145 (void)close(*pdwClientID);
149 ret = fcntl(*pdwClientID, F_GETFL, 0);
152 Log3(PCSC_LOG_CRITICAL,
"Error: cannot retrieve socket %s flags: %s",
153 socketName, strerror(errno));
154 (void)close(*pdwClientID);
158 if (fcntl(*pdwClientID, F_SETFL, ret | O_NONBLOCK) < 0)
160 Log3(PCSC_LOG_CRITICAL,
"Error: cannot set socket %s nonblocking: %s",
161 socketName, strerror(errno));
162 (void)close(*pdwClientID);
198 uint64_t buffer_size, int32_t filedes,
long timeOut)
200 char *buffer = buffer_void;
206 struct timeval start;
209 size_t remaining = buffer_size;
211 gettimeofday(&start, NULL);
214 while (remaining > 0)
216 struct pollfd read_fd;
221 gettimeofday(&now, NULL);
222 delta =
time_sub(&now, &start) / 1000;
232 delta = timeOut - delta;
234 read_fd.fd = filedes;
235 read_fd.events = POLLIN;
238 pollret = poll(&read_fd, 1, delta);
245 if (!(read_fd.revents & POLLIN))
251 bytes_read = read(filedes, buffer, remaining);
256 buffer += bytes_read;
257 remaining -= bytes_read;
258 }
else if (bytes_read == 0)
267 if (errno != EINTR && errno != EAGAIN)
273 }
else if (pollret == 0)
289 Log2(PCSC_LOG_INFO,
"Command 0x%X not yet finished", command);
295 Log2(PCSC_LOG_ERROR,
"select returns with failure: %s",
321 uint64_t size,
void *data_void)
329 ret =
MessageSend(&header,
sizeof(header), dwClientID);
360 unsigned char *buffer = buffer_void;
366 size_t remaining = buffer_size;
369 Log2(PCSC_LOG_DEBUG,
"write %ld bytes", buffer_size);
370 LogXxd(PCSC_LOG_DEBUG,
"write: ", buffer, buffer_size);
373 while (remaining > 0)
375 struct pollfd write_fd;
378 write_fd.fd = filedes;
379 write_fd.events = POLLOUT;
380 write_fd.revents = 0;
382 pollret = poll(&write_fd, 1, -1);
389 if (!(write_fd.revents & POLLOUT))
400 written = send(filedes, buffer, remaining, MSG_NOSIGNAL);
403 written = write(filedes, buffer, remaining);
410 remaining -= written;
411 }
else if (written == 0)
420 if (errno != EINTR && errno != EAGAIN)
426 }
else if (pollret == 0)
436 Log2(PCSC_LOG_ERROR,
"select returns with failure: %s",
464 char *buffer = buffer_void;
470 size_t remaining = buffer_size;
473 Log2(PCSC_LOG_DEBUG,
"read %ld bytes", buffer_size);
476 while (remaining > 0)
478 struct pollfd read_fd;
481 read_fd.fd = filedes;
482 read_fd.events = POLLIN;
485 pollret = poll(&read_fd, 1 , -1);
492 if (!(read_fd.revents & POLLIN))
498 bytes_read = read(filedes, buffer, remaining);
503 buffer += bytes_read;
504 remaining -= bytes_read;
505 }
else if (bytes_read == 0)
514 if (errno != EINTR && errno != EAGAIN)
517 if (ECONNRESET == errno)
530 Log2(PCSC_LOG_ERROR,
"select returns with failure: %s",
539 LogXxd(PCSC_LOG_DEBUG,
"read: ", buffer_void, buffer_size);
#define SCARD_W_SECURITY_VIOLATION
Access was denied because of a security violation.
#define SCARD_S_SUCCESS
No error was encountered.
#define SCARD_F_COMM_ERROR
An internal communications error has been detected.
#define SCARD_E_TIMEOUT
The user-specified timeout value has expired.
#define SCARD_E_NO_SERVICE
The Smart card resource manager is not running.
This handles abstract system level calls.
const char * SYS_GetEnv(const char *name)
(More) secure version of getenv(3)
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
This handles smart card reader communications.
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.
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 response from the server or vice-versa.
INTERNAL LONG MessageSendWithHeader(uint32_t command, uint32_t dwClientID, uint64_t size, void *data_void)
Wrapper for the MessageSend() function.
INTERNAL LONG MessageSend(void *buffer_void, uint64_t buffer_size, int32_t filedes)
Sends a menssage from client to server or vice-versa.
INTERNAL void ClientCloseSession(uint32_t dwClientID)
Closes the socket used by the client to communicate with the server.
INTERNAL LONG MessageReceive(void *buffer_void, uint64_t buffer_size, int32_t filedes)
Called by the Client to get the response from the server or vice-versa.
This defines some structures and #defines to be used over the transport layer.