Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

winscard_msg_srv.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 2001-2004
00005  *  David Corcoran <corcoran@linuxnet.com>
00006  *  Damien Sauveron <damien.sauveron@labri.fr>
00007  *  Ludoic Rousseau <ludovic.rousseau@free.fr>
00008  *
00009  * $Id: winscard_msg_srv.c 2190 2006-10-23 14:42:24Z rousseau $
00010  */
00011 
00021 #include "config.h"
00022 #include <fcntl.h>
00023 #include <unistd.h>
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <sys/socket.h>
00027 #include <sys/time.h>
00028 #include <sys/un.h>
00029 #include <sys/ioctl.h>
00030 #include <errno.h>
00031 #include <stdio.h>
00032 #include <time.h>
00033 #include <string.h>
00034 #ifdef HAVE_SYS_FILIO_H
00035 #include <sys/filio.h>
00036 #endif
00037 
00038 #include "misc.h"
00039 #include "pcsclite.h"
00040 #include "winscard.h"
00041 #include "debuglog.h"
00042 #include "winscard_msg.h"
00043 #include "sys_generic.h"
00044 
00048 static int commonSocket = 0;
00049 extern char AraKiri;
00050 extern char ReCheckSerialReaders;
00051 
00064 static int SHMProcessCommonChannelRequest(PDWORD pdwClientID)
00065 {
00066     socklen_t clnt_len;
00067     int new_sock;
00068     struct sockaddr_un clnt_addr;
00069     int one;
00070 
00071     clnt_len = sizeof(clnt_addr);
00072 
00073     if ((new_sock = accept(commonSocket, (struct sockaddr *) &clnt_addr,
00074                 &clnt_len)) < 0)
00075     {
00076         Log2(PCSC_LOG_CRITICAL, "Accept on common socket: %s",
00077             strerror(errno));
00078         return -1;
00079     }
00080 
00081     *pdwClientID = new_sock;
00082 
00083     one = 1;
00084     if (ioctl(*pdwClientID, FIONBIO, &one) < 0)
00085     {
00086         Log2(PCSC_LOG_CRITICAL, "Error: cannot set socket nonblocking: %s",
00087             strerror(errno));
00088         SYS_CloseFile(*pdwClientID);
00089         *pdwClientID = -1;
00090         return -1;
00091     }
00092 
00093     return 0;
00094 }
00095 
00110 INTERNAL int SHMInitializeCommonSegment(void)
00111 {
00112     static struct sockaddr_un serv_adr;
00113 
00114     /*
00115      * Create the common shared connection socket
00116      */
00117     if ((commonSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
00118     {
00119         Log2(PCSC_LOG_CRITICAL, "Unable to create common socket: %s",
00120             strerror(errno));
00121         return -1;
00122     }
00123 
00124     serv_adr.sun_family = AF_UNIX;
00125     strncpy(serv_adr.sun_path, PCSCLITE_CSOCK_NAME,
00126         sizeof(serv_adr.sun_path));
00127     SYS_Unlink(PCSCLITE_CSOCK_NAME);
00128 
00129     if (bind(commonSocket, (struct sockaddr *) &serv_adr,
00130             sizeof(serv_adr.sun_family) + strlen(serv_adr.sun_path) + 1) < 0)
00131     {
00132         Log2(PCSC_LOG_CRITICAL, "Unable to bind common socket: %s",
00133             strerror(errno));
00134         SHMCleanupSharedSegment(commonSocket, PCSCLITE_CSOCK_NAME);
00135         return -1;
00136     }
00137 
00138     if (listen(commonSocket, 1) < 0)
00139     {
00140         Log2(PCSC_LOG_CRITICAL, "Unable to listen common socket: %s",
00141             strerror(errno));
00142         SHMCleanupSharedSegment(commonSocket, PCSCLITE_CSOCK_NAME);
00143         return -1;
00144     }
00145 
00146     /*
00147      * Chmod the public entry channel
00148      */
00149     SYS_Chmod(PCSCLITE_CSOCK_NAME, S_IRWXO | S_IRWXG | S_IRWXU);
00150 
00151     return 0;
00152 }
00153 
00168 INTERNAL int SHMProcessEventsServer(PDWORD pdwClientID, int blocktime)
00169 {
00170     fd_set read_fd;
00171     int selret;
00172 
00173     FD_ZERO(&read_fd);
00174 
00175     /*
00176      * Set up the bit masks for select
00177      */
00178     FD_SET(commonSocket, &read_fd);
00179 
00180     selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL,
00181         (fd_set *) NULL, NULL);
00182 
00183     if (selret < 0)
00184     {
00185         if (EINTR == errno)
00186             return -2;
00187 
00188         Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s",
00189             strerror(errno));
00190         return -1;
00191     }
00192 
00193     /*
00194      * A common pipe packet has arrived - it could be a new application
00195      */
00196     if (FD_ISSET(commonSocket, &read_fd))
00197     {
00198         Log1(PCSC_LOG_DEBUG, "Common channel packet arrival");
00199         if (SHMProcessCommonChannelRequest(pdwClientID) == -1)
00200         {
00201             Log2(PCSC_LOG_ERROR,
00202                 "error in SHMProcessCommonChannelRequest: %d", *pdwClientID);
00203             return -1;
00204         } else
00205         {
00206             Log2(PCSC_LOG_DEBUG,
00207                 "SHMProcessCommonChannelRequest detects: %d", *pdwClientID);
00208             return 0;
00209         }
00210     }
00211 
00212     return -1;
00213 }
00214 
00220 INTERNAL int SHMProcessEventsContext(PDWORD pdwClientID, psharedSegmentMsg msgStruct, int blocktime)
00221 {
00222     fd_set read_fd;
00223     int selret, rv;
00224     struct timeval tv;
00225 
00226     tv.tv_sec = 1;
00227     tv.tv_usec = 0;
00228 
00229     FD_ZERO(&read_fd);
00230     FD_SET(*pdwClientID, &read_fd);
00231 
00232     selret = select(*pdwClientID + 1, &read_fd, (fd_set *) NULL,
00233         (fd_set *) NULL, &tv);
00234 
00235     if (selret < 0)
00236     {
00237         Log2(PCSC_LOG_ERROR, "select returns with failure: %s",
00238             strerror(errno));
00239         return -1;
00240     }
00241 
00242     if (selret == 0)
00243         /* timeout */
00244         return 2;
00245 
00246     if (FD_ISSET(*pdwClientID, &read_fd))
00247     {
00248         /*
00249          * Return the current handle
00250          */
00251         rv = SHMMessageReceive(msgStruct, sizeof(*msgStruct), *pdwClientID,
00252                        PCSCLITE_SERVER_ATTEMPTS);
00253 
00254         if (rv == -1)
00255         {   /* The client has died */
00256             Log2(PCSC_LOG_DEBUG, "Client has disappeared: %d",
00257                 *pdwClientID);
00258             msgStruct->mtype = CMD_CLIENT_DIED;
00259             msgStruct->command = 0;
00260             SYS_CloseFile(*pdwClientID);
00261 
00262             return 0;
00263         }
00264 
00265         /*
00266          * Set the identifier handle
00267          */
00268         Log2(PCSC_LOG_DEBUG, "correctly processed client: %d",
00269             *pdwClientID);
00270         return 1;
00271     }
00272 
00273     return -1;
00274 }
00275 

Generated on Tue Apr 1 22:45:23 2008 for pcsc-lite by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002