00001
00002
00003
00004
00005
00006
00007
00008
00009
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 "debug.h"
00042 #include "winscard_msg.h"
00043 #include "sys_generic.h"
00044
00056 INTERNAL int SHMClientRead(psharedSegmentMsg msgStruct, DWORD dwClientID, int blockamount)
00057 {
00058 return SHMMessageReceive(msgStruct, dwClientID, blockamount);
00059 }
00060
00074 INTERNAL int SHMClientSetupSession(PDWORD pdwClientID)
00075 {
00076 struct sockaddr_un svc_addr;
00077 int one;
00078
00079 if ((*pdwClientID = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
00080 {
00081 Log2(PCSC_LOG_CRITICAL, "Error: create on client socket: %s",
00082 strerror(errno));
00083 return -1;
00084 }
00085
00086 svc_addr.sun_family = AF_UNIX;
00087 strncpy(svc_addr.sun_path, PCSCLITE_CSOCK_NAME,
00088 sizeof(svc_addr.sun_path));
00089
00090 if (connect(*pdwClientID, (struct sockaddr *) &svc_addr,
00091 sizeof(svc_addr.sun_family) + strlen(svc_addr.sun_path) + 1) < 0)
00092 {
00093 Log2(PCSC_LOG_CRITICAL, "Error: connect to client socket: %s",
00094 strerror(errno));
00095 SYS_CloseFile(*pdwClientID);
00096 return -1;
00097 }
00098
00099 one = 1;
00100 if (ioctl(*pdwClientID, FIONBIO, &one) < 0)
00101 {
00102 Log2(PCSC_LOG_CRITICAL, "Error: cannot set socket nonblocking: %s",
00103 strerror(errno));
00104 SYS_CloseFile(*pdwClientID);
00105 return -1;
00106 }
00107
00108 return 0;
00109 }
00110
00118 INTERNAL int SHMClientCloseSession(DWORD dwClientID)
00119 {
00120 SYS_CloseFile(dwClientID);
00121 return 0;
00122 }
00123
00138 INTERNAL int SHMMessageSend(psharedSegmentMsg msgStruct, int filedes,
00139 int blockAmount)
00140 {
00141
00142
00143
00144 int retval = 0;
00145
00146
00147
00148 time_t start = time(0);
00149
00150
00151
00152 unsigned char *buffer = (unsigned char *) msgStruct;
00153
00154
00155
00156 size_t remaining = sizeof(sharedSegmentMsg);
00157
00158
00159
00160
00161 while (remaining > 0)
00162 {
00163 fd_set write_fd;
00164 struct timeval timeout;
00165 int selret;
00166
00167 FD_ZERO(&write_fd);
00168 FD_SET(filedes, &write_fd);
00169
00170 timeout.tv_usec = 0;
00171 if ((timeout.tv_sec = start + blockAmount - time(0)) < 0)
00172 {
00173
00174
00175
00176 retval = -1;
00177 break;
00178 }
00179
00180 selret = select(filedes + 1, NULL, &write_fd, NULL, &timeout);
00181
00182
00183
00184
00185 if (selret > 0)
00186 {
00187 int written;
00188
00189 if (!FD_ISSET(filedes, &write_fd))
00190 {
00191
00192
00193
00194 retval = -1;
00195 break;
00196 }
00197 written = write(filedes, buffer, remaining);
00198
00199 if (written > 0)
00200 {
00201
00202
00203
00204 buffer += written;
00205 remaining -= written;
00206 } else if (written == 0)
00207 {
00208
00209
00210
00211 retval = -1;
00212 break;
00213 } else
00214 {
00215
00216
00217
00218
00219 if (errno != EINTR && errno != EAGAIN)
00220 {
00221 retval = -1;
00222 break;
00223 }
00224 }
00225 } else if (selret == 0)
00226 {
00227
00228
00229
00230 retval = -1;
00231 break;
00232 } else
00233 {
00234
00235
00236
00237 if (errno != EINTR)
00238 {
00239 Log2(PCSC_LOG_ERROR, "select returns with failure: %s",
00240 strerror(errno));
00241 retval = -1;
00242 break;
00243 }
00244 }
00245 }
00246
00247 return retval;
00248 }
00249
00264 INTERNAL int SHMMessageReceive(psharedSegmentMsg msgStruct, int filedes,
00265 int blockAmount)
00266 {
00267
00268
00269
00270 int retval = 0;
00271
00272
00273
00274 time_t start = time(0);
00275
00276
00277
00278 unsigned char *buffer = (unsigned char *) msgStruct;
00279
00280
00281
00282 size_t remaining = sizeof(sharedSegmentMsg);
00283
00284
00285
00286
00287 while (remaining > 0)
00288 {
00289 fd_set read_fd;
00290 struct timeval timeout;
00291 int selret;
00292
00293 FD_ZERO(&read_fd);
00294 FD_SET(filedes, &read_fd);
00295
00296 timeout.tv_usec = 0;
00297 if ((timeout.tv_sec = start + blockAmount - time(0)) < 0)
00298 {
00299
00300
00301
00302 retval = -1;
00303 break;
00304 }
00305
00306 selret = select(filedes + 1, &read_fd, NULL, NULL, &timeout);
00307
00308
00309
00310
00311 if (selret > 0)
00312 {
00313 int readed;
00314
00315 if (!FD_ISSET(filedes, &read_fd))
00316 {
00317
00318
00319
00320 retval = -1;
00321 break;
00322 }
00323 readed = read(filedes, buffer, remaining);
00324
00325 if (readed > 0)
00326 {
00327
00328
00329
00330 buffer += readed;
00331 remaining -= readed;
00332 } else if (readed == 0)
00333 {
00334
00335
00336
00337 retval = -1;
00338 break;
00339 } else
00340 {
00341
00342
00343
00344
00345 if (errno != EINTR && errno != EAGAIN)
00346 {
00347 retval = -1;
00348 break;
00349 }
00350 }
00351 } else if (selret == 0)
00352 {
00353
00354
00355
00356 retval = -1;
00357 break;
00358 } else
00359 {
00360
00361
00362
00363 if (errno != EINTR)
00364 {
00365 Log2(PCSC_LOG_ERROR, "select returns with failure: %s",
00366 strerror(errno));
00367 retval = -1;
00368 break;
00369 }
00370 }
00371 }
00372
00373 return retval;
00374 }
00375
00391 INTERNAL int WrapSHMWrite(unsigned int command, DWORD dwClientID,
00392 unsigned int size, unsigned int blockAmount, void *data)
00393 {
00394 sharedSegmentMsg msgStruct;
00395
00396
00397
00398
00399
00400 memset(&msgStruct, 0, sizeof(msgStruct));
00401 msgStruct.mtype = CMD_FUNCTION;
00402 msgStruct.user_id = SYS_GetUID();
00403 msgStruct.group_id = SYS_GetGID();
00404 msgStruct.command = command;
00405 msgStruct.date = time(NULL);
00406 memcpy(msgStruct.data, data, size);
00407
00408 return SHMMessageSend(&msgStruct, dwClientID, blockAmount);
00409 }
00410
00420 INTERNAL void SHMCleanupSharedSegment(int sockValue, char *pcFilePath)
00421 {
00422 SYS_CloseFile(sockValue);
00423 SYS_Unlink(pcFilePath);
00424 }
00425