2
* MUSCLE SmartCard Development ( http://www.linuxnet.com )
4
* Copyright (C) 2001-2004
5
* David Corcoran <corcoran@linuxnet.com>
6
* Damien Sauveron <damien.sauveron@labri.fr>
7
* Ludoic Rousseau <ludovic.rousseau@free.fr>
9
* $Id: winscard_msg_srv.c,v 1.2 2005-11-27 17:08:31 rousseau Exp $
14
* @brief client/server communication (on the server side only)
16
* A file based socket (\c commonSocket) is used to send/receive only messages
17
* among clients and server.\n
18
* The messages' data are passed throw a memory mapped file: \c sharedSegmentMsg.
24
#include <sys/types.h>
26
#include <sys/socket.h>
29
#include <sys/ioctl.h>
34
#ifdef HAVE_SYS_FILIO_H
35
#include <sys/filio.h>
41
#include "winscard_msg.h"
42
#include "sys_generic.h"
46
* Socket to a file, used for clients-server comminication.
48
static int commonSocket = 0;
50
extern char ReCheckSerialReaders;
53
* @brief Accepts a Client connection.
55
* Called by \c SHMProcessEventsServer().
57
* @param[out] pdwClientID Connection ID used to reference the Client.
61
* @retval -1 Can not establish the connection.
62
* @retval -1 Can not set the connection to non-blocking mode.
64
static int SHMProcessCommonChannelRequest(PDWORD pdwClientID)
68
struct sockaddr_un clnt_addr;
71
clnt_len = sizeof(clnt_addr);
73
if ((new_sock = accept(commonSocket, (struct sockaddr *) &clnt_addr,
76
Log2(PCSC_LOG_CRITICAL, "Accept on common socket: %s",
81
*pdwClientID = new_sock;
84
if (ioctl(*pdwClientID, FIONBIO, &one) < 0)
86
Log2(PCSC_LOG_CRITICAL, "Error: cannot set socket nonblocking: %s",
88
SYS_CloseFile(*pdwClientID);
97
* @brief Prepares the communication channel used by the server to talk to the
100
* This is called by the server to create a socket for local IPC with the
101
* clients. The socket is associated to the file \c PCSCLITE_CSOCK_NAME.
102
* Each client will open a connection to this socket.
104
* @return Error code.
106
* @retval -1 Can not create the socket.
107
* @retval -1 Can not bind the socket to the file \c PCSCLITE_CSOCK_NAME.
108
* @retval -1 Can not put the socket in listen mode.
110
INTERNAL int SHMInitializeCommonSegment(void)
112
static struct sockaddr_un serv_adr;
115
* Create the common shared connection socket
117
if ((commonSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
119
Log2(PCSC_LOG_CRITICAL, "Unable to create common socket: %s",
124
serv_adr.sun_family = AF_UNIX;
125
strncpy(serv_adr.sun_path, PCSCLITE_CSOCK_NAME,
126
sizeof(serv_adr.sun_path));
127
SYS_Unlink(PCSCLITE_CSOCK_NAME);
129
if (bind(commonSocket, (struct sockaddr *) &serv_adr,
130
sizeof(serv_adr.sun_family) + strlen(serv_adr.sun_path) + 1) < 0)
132
Log2(PCSC_LOG_CRITICAL, "Unable to bind common socket: %s",
134
SHMCleanupSharedSegment(commonSocket, PCSCLITE_CSOCK_NAME);
138
if (listen(commonSocket, 1) < 0)
140
Log2(PCSC_LOG_CRITICAL, "Unable to listen common socket: %s",
142
SHMCleanupSharedSegment(commonSocket, PCSCLITE_CSOCK_NAME);
147
* Chmod the public entry channel
149
SYS_Chmod(PCSCLITE_CSOCK_NAME, S_IRWXO | S_IRWXG | S_IRWXU);
155
* @brief Looks for messages sent by clients.
157
* This is called by the Server's function \c SVCServiceRunLoop().
159
* @param[out] pdwClientID Connection ID used to reference the Client.
160
* @param[in] blocktime Timeout (not used).
162
* @return Error code.
164
* @retval -1 Error accessing the communication channel.
165
* @retval -1 Can not set the connection to non-blocking mode.
168
INTERNAL int SHMProcessEventsServer(PDWORD pdwClientID, int blocktime)
180
* Set up the bit masks for select
182
FD_SET(commonSocket, &read_fd);
184
selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL,
185
(fd_set *) NULL, &tv);
189
if ((!AraKiri) && (!ReCheckSerialReaders))
190
Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s",
199
* A common pipe packet has arrived - it could be a new application
201
if (FD_ISSET(commonSocket, &read_fd))
203
Log1(PCSC_LOG_DEBUG, "Common channel packet arrival");
204
if (SHMProcessCommonChannelRequest(pdwClientID) == -1)
207
"error in SHMProcessCommonChannelRequest: %d", *pdwClientID);
212
"SHMProcessCommonChannelRequest detects: %d", *pdwClientID);
223
* Called by \c ContextThread().
225
INTERNAL int SHMProcessEventsContext(PDWORD pdwClientID, psharedSegmentMsg msgStruct, int blocktime)
235
FD_SET(*pdwClientID, &read_fd);
237
selret = select(*pdwClientID + 1, &read_fd, (fd_set *) NULL,
238
(fd_set *) NULL, &tv);
242
Log2(PCSC_LOG_ERROR, "select returns with failure: %s",
251
if (FD_ISSET(*pdwClientID, &read_fd))
254
* Return the current handle
256
rv = SHMMessageReceive(msgStruct, *pdwClientID,
257
PCSCLITE_SERVER_ATTEMPTS);
260
{ /* The client has died */
261
Log2(PCSC_LOG_DEBUG, "Client has disappeared: %d",
263
msgStruct->mtype = CMD_CLIENT_DIED;
264
msgStruct->command = 0;
265
SYS_CloseFile(*pdwClientID);
271
* Set the identifier handle
273
Log2(PCSC_LOG_DEBUG, "correctly processed client: %d",