From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:32792) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UHZqj-00042J-H6 for qemu-devel@nongnu.org; Mon, 18 Mar 2013 09:11:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UHZqa-0000mf-VP for qemu-devel@nongnu.org; Mon, 18 Mar 2013 09:11:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:25188) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UHZqa-0000mR-Ia for qemu-devel@nongnu.org; Mon, 18 Mar 2013 09:11:28 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2IDBSLD010607 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 18 Mar 2013 09:11:28 -0400 From: Alon Levy Date: Mon, 18 Mar 2013 15:10:55 +0200 Message-Id: <1363612272-13713-10-git-send-email-alevy@redhat.com> In-Reply-To: <1363612272-13713-1-git-send-email-alevy@redhat.com> References: <1363612272-13713-1-git-send-email-alevy@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH 09/26] libcacard: split vscclient main() from socket reading List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: mlureau@redhat.com From: Marc-Andr=C3=A9 Lureau --- libcacard/vscclient.c | 314 ++++++++++++++++++++++++++------------------= ------ 1 file changed, 162 insertions(+), 152 deletions(-) diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c index 9b744f2..5e00db3 100644 --- a/libcacard/vscclient.c +++ b/libcacard/vscclient.c @@ -211,6 +211,166 @@ get_id_from_string(char *string, unsigned int defau= lt_id) return id; } =20 +static int +on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) +{ + uint32_t *capabilities =3D (incoming->capabilities); + int num_capabilities =3D + 1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t))= ; + int i; + int rv; + pthread_t thread_id; + + incoming->version =3D ntohl(incoming->version); + if (incoming->version !=3D VSCARD_VERSION) { + if (verbose > 0) { + printf("warning: host has version %d, we have %d\n", + verbose, VSCARD_VERSION); + } + } + if (incoming->magic !=3D VSCARD_MAGIC) { + printf("unexpected magic: got %d, expected %d\n", + incoming->magic, VSCARD_MAGIC); + return -1; + } + for (i =3D 0 ; i < num_capabilities; ++i) { + capabilities[i] =3D ntohl(capabilities[i]); + } + /* Future: check capabilities */ + /* remove whatever reader might be left in qemu, + * in case of an unclean previous exit. */ + send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0); + /* launch the event_thread. This will trigger reader adds for all th= e + * existing readers */ + rv =3D pthread_create(&thread_id, NULL, event_thread, NULL); + if (rv < 0) { + perror("pthread_create"); + return rv; + } + return 0; +} + +#define APDUBufSize 270 + +static int +do_socket_read(void) +{ + int rv; + int dwSendLength; + int dwRecvLength; + uint8_t pbRecvBuffer[APDUBufSize]; + uint8_t pbSendBuffer[APDUBufSize]; + VReaderStatus reader_status; + VReader *reader =3D NULL; + VSCMsgHeader mhHeader; + VSCMsgError *error_msg; + + rv =3D read(sock, &mhHeader, sizeof(mhHeader)); + if (rv < sizeof(mhHeader)) { + /* Error */ + if (rv < 0) { + perror("header read error\n"); + } else { + fprintf(stderr, "header short read %d\n", rv); + } + return -1; + } + mhHeader.type =3D ntohl(mhHeader.type); + mhHeader.reader_id =3D ntohl(mhHeader.reader_id); + mhHeader.length =3D ntohl(mhHeader.length); + if (verbose) { + printf("Header: type=3D%d, reader_id=3D%u length=3D%d (0x%x)\n", + mhHeader.type, mhHeader.reader_id, mhHeader.length, + mhHeader.length); + } + switch (mhHeader.type) { + case VSC_APDU: + case VSC_Flush: + case VSC_Error: + case VSC_Init: + rv =3D read(sock, pbSendBuffer, mhHeader.length); + break; + default: + fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.ty= pe); + return -1; + } + switch (mhHeader.type) { + case VSC_APDU: + if (rv < 0) { + /* Error */ + fprintf(stderr, "read error\n"); + close(sock); + return -1; + } + if (verbose) { + printf(" recv APDU: "); + print_byte_array(pbSendBuffer, mhHeader.length); + } + /* Transmit received APDU */ + dwSendLength =3D mhHeader.length; + dwRecvLength =3D sizeof(pbRecvBuffer); + reader =3D vreader_get_reader_by_id(mhHeader.reader_id); + reader_status =3D vreader_xfr_bytes(reader, + pbSendBuffer, dwSendLength, + pbRecvBuffer, &dwRecvLength); + if (reader_status =3D=3D VREADER_OK) { + mhHeader.length =3D dwRecvLength; + if (verbose) { + printf(" send response: "); + print_byte_array(pbRecvBuffer, mhHeader.length); + } + send_msg(VSC_APDU, mhHeader.reader_id, + pbRecvBuffer, dwRecvLength); + } else { + rv =3D reader_status; /* warning: not meaningful */ + send_msg(VSC_Error, mhHeader.reader_id, &rv, sizeof(uint32_t= )); + } + vreader_free(reader); + reader =3D NULL; /* we've freed it, don't use it by accident + again */ + break; + case VSC_Flush: + /* TODO: actually flush */ + send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0); + break; + case VSC_Error: + error_msg =3D (VSCMsgError *) pbSendBuffer; + if (error_msg->code =3D=3D VSC_SUCCESS) { + qemu_mutex_lock(&pending_reader_lock); + if (pending_reader) { + vreader_set_id(pending_reader, mhHeader.reader_id); + vreader_free(pending_reader); + pending_reader =3D NULL; + qemu_cond_signal(&pending_reader_condition); + } + qemu_mutex_unlock(&pending_reader_lock); + break; + } + printf("warning: qemu refused to add reader\n"); + if (error_msg->code =3D=3D VSC_CANNOT_ADD_MORE_READERS) { + /* clear pending reader, qemu can't handle any more */ + qemu_mutex_lock(&pending_reader_lock); + if (pending_reader) { + pending_reader =3D NULL; + /* make sure the event loop doesn't hang */ + qemu_cond_signal(&pending_reader_condition); + } + qemu_mutex_unlock(&pending_reader_lock); + } + break; + case VSC_Init: + if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) { + return -1; + } + break; + default: + printf("Default\n"); + return -1; + } + + return 0; +} + static void do_command(void) { @@ -339,8 +499,6 @@ do_command(void) } =20 =20 -#define APDUBufSize 270 - /* just for ease of parsing command line arguments. */ #define MAX_CERTS 100 =20 @@ -385,44 +543,6 @@ connect_to_qemu( return sock; } =20 -static int on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) -{ - uint32_t *capabilities =3D (incoming->capabilities); - int num_capabilities =3D - 1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t))= ; - int i; - int rv; - pthread_t thread_id; - - incoming->version =3D ntohl(incoming->version); - if (incoming->version !=3D VSCARD_VERSION) { - if (verbose > 0) { - printf("warning: host has version %d, we have %d\n", - verbose, VSCARD_VERSION); - } - } - if (incoming->magic !=3D VSCARD_MAGIC) { - printf("unexpected magic: got %d, expected %d\n", - incoming->magic, VSCARD_MAGIC); - return -1; - } - for (i =3D 0 ; i < num_capabilities; ++i) { - capabilities[i] =3D ntohl(capabilities[i]); - } - /* Future: check capabilities */ - /* remove whatever reader might be left in qemu, - * in case of an unclean previous exit. */ - send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0); - /* launch the event_thread. This will trigger reader adds for all th= e - * existing readers */ - rv =3D pthread_create(&thread_id, NULL, event_thread, NULL); - if (rv < 0) { - perror("pthread_create"); - return rv; - } - return 0; -} - int main( int argc, @@ -431,21 +551,13 @@ main( char *qemu_host; char *qemu_port; VSCMsgHeader mhHeader; - VSCMsgError *error_msg; =20 - int rv; - int dwSendLength; - int dwRecvLength; - uint8_t pbRecvBuffer[APDUBufSize]; - uint8_t pbSendBuffer[APDUBufSize]; - VReaderStatus reader_status; - VReader *reader =3D NULL; VCardEmulOptions *command_line_options =3D NULL; =20 char *cert_names[MAX_CERTS]; char *emul_args =3D NULL; int cert_count =3D 0; - int c; + int c, rv; =20 while ((c =3D getopt(argc, argv, "c:e:pd:")) !=3D -1) { switch (c) { @@ -548,109 +660,7 @@ main( if (!FD_ISSET(sock, &fds)) { continue; } - - rv =3D read(sock, &mhHeader, sizeof(mhHeader)); - if (rv < sizeof(mhHeader)) { - /* Error */ - if (rv < 0) { - perror("header read error\n"); - } else { - fprintf(stderr, "header short read %d\n", rv); - } - return 8; - } - mhHeader.type =3D ntohl(mhHeader.type); - mhHeader.reader_id =3D ntohl(mhHeader.reader_id); - mhHeader.length =3D ntohl(mhHeader.length); - if (verbose) { - printf("Header: type=3D%d, reader_id=3D%u length=3D%d (0x%x)= \n", - mhHeader.type, mhHeader.reader_id, mhHeader.length, - mhHeader.length); - } - switch (mhHeader.type) { - case VSC_APDU: - case VSC_Flush: - case VSC_Error: - case VSC_Init: - rv =3D read(sock, pbSendBuffer, mhHeader.length); - break; - default: - fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeade= r.type); - return 0; - } - switch (mhHeader.type) { - case VSC_APDU: - if (rv < 0) { - /* Error */ - fprintf(stderr, "read error\n"); - close(sock); - return 8; - } - if (verbose) { - printf(" recv APDU: "); - print_byte_array(pbSendBuffer, mhHeader.length); - } - /* Transmit received APDU */ - dwSendLength =3D mhHeader.length; - dwRecvLength =3D sizeof(pbRecvBuffer); - reader =3D vreader_get_reader_by_id(mhHeader.reader_id); - reader_status =3D vreader_xfr_bytes(reader, - pbSendBuffer, dwSendLength, - pbRecvBuffer, &dwRecvLength); - if (reader_status =3D=3D VREADER_OK) { - mhHeader.length =3D dwRecvLength; - if (verbose) { - printf(" send response: "); - print_byte_array(pbRecvBuffer, mhHeader.length); - } - send_msg(VSC_APDU, mhHeader.reader_id, - pbRecvBuffer, dwRecvLength); - } else { - rv =3D reader_status; /* warning: not meaningful */ - send_msg(VSC_Error, mhHeader.reader_id, &rv, sizeof(uint= 32_t)); - } - vreader_free(reader); - reader =3D NULL; /* we've freed it, don't use it by accident - again */ - break; - case VSC_Flush: - /* TODO: actually flush */ - send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0); - break; - case VSC_Error: - error_msg =3D (VSCMsgError *) pbSendBuffer; - if (error_msg->code =3D=3D VSC_SUCCESS) { - qemu_mutex_lock(&pending_reader_lock); - if (pending_reader) { - vreader_set_id(pending_reader, mhHeader.reader_id); - vreader_free(pending_reader); - pending_reader =3D NULL; - qemu_cond_signal(&pending_reader_condition); - } - qemu_mutex_unlock(&pending_reader_lock); - break; - } - printf("warning: qemu refused to add reader\n"); - if (error_msg->code =3D=3D VSC_CANNOT_ADD_MORE_READERS) { - /* clear pending reader, qemu can't handle any more */ - qemu_mutex_lock(&pending_reader_lock); - if (pending_reader) { - pending_reader =3D NULL; - /* make sure the event loop doesn't hang */ - qemu_cond_signal(&pending_reader_condition); - } - qemu_mutex_unlock(&pending_reader_lock); - } - break; - case VSC_Init: - if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0)= { - return -1; - } - break; - default: - printf("Default\n"); - return 0; - } + rv =3D do_socket_read(); } while (rv >=3D 0); =20 return 0; --=20 1.8.1.4