bool CBasicClient::open_connection() { close_connection(); struct sockaddr_un servaddr; int clilen; memset(&servaddr, 0, sizeof(struct sockaddr_un)); servaddr.sun_family = AF_UNIX; strcpy(servaddr.sun_path, getSocketName()); // no length check !!! clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path); if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { printf("[CBasicClient] socket failed.\n"); perror(getSocketName()); sock_fd = -1; return false; } if (connect(sock_fd, (struct sockaddr*) &servaddr, clilen) < 0) { printf("[CBasicClient] connect failed.\n"); perror(getSocketName()); close_connection(); return false; } return true; }
bool CBasicClient::receive_data(char* data, const size_t size, bool use_max_timeout) { timeval timeout; if (sock_fd == -1) return false; if (use_max_timeout) { timeout.tv_sec = MAX_TIMEOUT_SEC; timeout.tv_usec = MAX_TIMEOUT_USEC; } else { timeout.tv_sec = TIMEOUT_SEC; timeout.tv_usec = TIMEOUT_USEC; } if (::receive_data(sock_fd, data, size, timeout) == false) { printf("[CBasicClient] receive failed: %s\n", getSocketName()); close_connection(); return false; } return true; }
/** * @brief Prepares a communication channel for the client to talk to the server. * * This is called by the application to create a socket for local IPC with the * server. The socket is associated to the file \c PCSCLITE_CSOCK_NAME. * * @param[out] pdwClientID Client Connection ID. * * @retval 0 Success. * @retval -1 Can not create the socket. * @retval -1 The socket can not open a connection. * @retval -1 Can not set the socket to non-blocking. */ INTERNAL int ClientSetupSession(uint32_t *pdwClientID) { struct sockaddr_un svc_addr; int ret; char *socketName; ret = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); if (ret < 0) { Log2(PCSC_LOG_CRITICAL, "Error: create on client socket: %s", strerror(errno)); return -1; } *pdwClientID = ret; socketName = getSocketName(); svc_addr.sun_family = AF_UNIX; strncpy(svc_addr.sun_path, socketName, sizeof(svc_addr.sun_path)); if (connect(*pdwClientID, (struct sockaddr *) &svc_addr, sizeof(svc_addr.sun_family) + strlen(svc_addr.sun_path) + 1) < 0) { Log3(PCSC_LOG_CRITICAL, "Error: connect to client socket %s: %s", socketName, strerror(errno)); (void)close(*pdwClientID); return -1; } ret = fcntl(*pdwClientID, F_GETFL, 0); if (ret < 0) { Log3(PCSC_LOG_CRITICAL, "Error: cannot retrieve socket %s flags: %s", socketName, strerror(errno)); (void)close(*pdwClientID); return -1; } if (fcntl(*pdwClientID, F_SETFL, ret | O_NONBLOCK) < 0) { Log3(PCSC_LOG_CRITICAL, "Error: cannot set socket %s nonblocking: %s", socketName, strerror(errno)); (void)close(*pdwClientID); return -1; } return 0; }
bool CBasicClient::send_data(const char* data, const size_t size) { timeval timeout; if (sock_fd == -1) return false; timeout.tv_sec = TIMEOUT_SEC; timeout.tv_usec = TIMEOUT_USEC; if (::send_data(sock_fd, data, size, timeout) == false) { printf("[CBasicClient] send failed: %s\n", getSocketName()); close_connection(); return false; } return true; }