Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00023 #include "config.h"
00024 #include <fcntl.h>
00025 #include <unistd.h>
00026 #include <sys/types.h>
00027 #include <sys/stat.h>
00028 #include <sys/socket.h>
00029 #include <sys/time.h>
00030 #include <sys/un.h>
00031 #include <sys/ioctl.h>
00032 #include <errno.h>
00033 #include <stdio.h>
00034 #include <time.h>
00035 #include <string.h>
00036 #ifdef HAVE_SYS_FILIO_H
00037 #include <sys/filio.h>
00038 #endif
00039
00040 #include "misc.h"
00041 #include "pcscd.h"
00042 #include "winscard.h"
00043 #include "debuglog.h"
00044 #include "winscard_msg.h"
00045
00049 static int commonSocket = 0;
00050 extern char AraKiri;
00051
00063 static int ProcessCommonChannelRequest( uint32_t *pdwClientID)
00064 {
00065 socklen_t clnt_len;
00066 int new_sock;
00067 struct sockaddr_un clnt_addr;
00068
00069 clnt_len = sizeof(clnt_addr);
00070
00071 if ((new_sock = accept(commonSocket, (struct sockaddr *) &clnt_addr,
00072 &clnt_len)) < 0)
00073 {
00074 Log2(PCSC_LOG_CRITICAL, "Accept on common socket: %s",
00075 strerror(errno));
00076 return -1;
00077 }
00078
00079 *pdwClientID = new_sock;
00080
00081 return 0;
00082 }
00083
00098 INTERNAL int32_t InitializeSocket(void)
00099 {
00100 static struct sockaddr_un serv_adr;
00101
00102
00103
00104
00105 if ((commonSocket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
00106 {
00107 Log2(PCSC_LOG_CRITICAL, "Unable to create common socket: %s",
00108 strerror(errno));
00109 return -1;
00110 }
00111
00112 serv_adr.sun_family = AF_UNIX;
00113 strncpy(serv_adr.sun_path, PCSCLITE_CSOCK_NAME,
00114 sizeof(serv_adr.sun_path));
00115 (void)remove(PCSCLITE_CSOCK_NAME);
00116
00117 if (bind(commonSocket, (struct sockaddr *) &serv_adr,
00118 sizeof(serv_adr.sun_family) + strlen(serv_adr.sun_path) + 1) < 0)
00119 {
00120 Log2(PCSC_LOG_CRITICAL, "Unable to bind common socket: %s",
00121 strerror(errno));
00122 CleanupSharedSegment(commonSocket, PCSCLITE_CSOCK_NAME);
00123 return -1;
00124 }
00125
00126 if (listen(commonSocket, 1) < 0)
00127 {
00128 Log2(PCSC_LOG_CRITICAL, "Unable to listen common socket: %s",
00129 strerror(errno));
00130 CleanupSharedSegment(commonSocket, PCSCLITE_CSOCK_NAME);
00131 return -1;
00132 }
00133
00134
00135
00136
00137 (void)chmod(PCSCLITE_CSOCK_NAME, S_IRWXO | S_IRWXG | S_IRWXU);
00138
00139 return 0;
00140 }
00141
00155 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
00156 #define DO_TIMEOUT
00157 #endif
00158 INTERNAL int32_t ProcessEventsServer(uint32_t *pdwClientID)
00159 {
00160 fd_set read_fd;
00161 int selret;
00162 #ifdef DO_TIMEOUT
00163 struct timeval tv;
00164
00165 tv.tv_sec = 1;
00166 tv.tv_usec = 0;
00167 #endif
00168
00169 FD_ZERO(&read_fd);
00170
00171
00172
00173
00174 FD_SET(commonSocket, &read_fd);
00175
00176 selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL,
00177 (fd_set *) NULL,
00178 #ifdef DO_TIMEOUT
00179 &tv
00180 #else
00181 NULL
00182 #endif
00183 );
00184
00185 if (selret < 0)
00186 {
00187 if (EINTR == errno)
00188 return -2;
00189
00190 Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s",
00191 strerror(errno));
00192 return -1;
00193 }
00194
00195 if (selret == 0)
00196
00197 return 2;
00198
00199
00200
00201
00202 if (FD_ISSET(commonSocket, &read_fd))
00203 {
00204 Log1(PCSC_LOG_DEBUG, "Common channel packet arrival");
00205 if (ProcessCommonChannelRequest(pdwClientID) == -1)
00206 {
00207 Log2(PCSC_LOG_ERROR,
00208 "error in ProcessCommonChannelRequest: %d", *pdwClientID);
00209 return -1;
00210 }
00211 }
00212 else
00213 return -1;
00214
00215 Log2(PCSC_LOG_DEBUG,
00216 "ProcessCommonChannelRequest detects: %d", *pdwClientID);
00217
00218 return 0;
00219 }
00220