From 323902f60939cbb7e3532b3baffe8a2efdbc289b Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Wed, 3 Jul 2019 13:34:00 -0300 Subject: [PATCH] Reorganizing sources. --- src/client/lib3270++.cbp | 24 ++++++++++++------------ src/client/private.h | 2 +- src/client/src/abstract.cc | 153 --------------------------------------------------------------------------------------------------------------------------------------------------------- src/client/src/core/abstract.cc | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/core/events.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/core/host.cc | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/core/session.cc | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/events.cc | 56 -------------------------------------------------------- src/client/src/host.cc | 180 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ src/client/src/ipc/session.cc | 365 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/client/src/linux/request.cc | 267 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/client/src/linux/session.cc | 98 -------------------------------------------------------------------------------------------------- src/client/src/local/events.cc | 175 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/client/src/local/session.cc | 389 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/client/src/os/linux/request.cc | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/os/linux/session.cc | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/os/windows/request.cc | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/os/windows/resources.rc.in | 29 +++++++++++++++++++++++++++++ src/client/src/os/windows/session.cc | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/session.cc | 78 ------------------------------------------------------------------------------ src/client/src/session/local/events.cc | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/session/local/session.cc | 389 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/session/remote/session.cc | 365 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/src/testprogram/testprogram.cc | 2 +- src/client/src/windows/request.cc | 191 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/client/src/windows/resources.rc.in | 29 ----------------------------- src/client/src/windows/session.cc | 142 ---------------------------------------------------------------------------------------------------------------------------------------------- 27 files changed, 2137 insertions(+), 2137 deletions(-) delete mode 100644 src/client/src/abstract.cc create mode 100644 src/client/src/core/abstract.cc create mode 100644 src/client/src/core/events.cc create mode 100644 src/client/src/core/host.cc create mode 100644 src/client/src/core/session.cc delete mode 100644 src/client/src/events.cc delete mode 100644 src/client/src/host.cc delete mode 100644 src/client/src/ipc/session.cc delete mode 100644 src/client/src/linux/request.cc delete mode 100644 src/client/src/linux/session.cc delete mode 100644 src/client/src/local/events.cc delete mode 100644 src/client/src/local/session.cc create mode 100644 src/client/src/os/linux/request.cc create mode 100644 src/client/src/os/linux/session.cc create mode 100644 src/client/src/os/windows/request.cc create mode 100644 src/client/src/os/windows/resources.rc.in create mode 100644 src/client/src/os/windows/session.cc delete mode 100644 src/client/src/session.cc create mode 100644 src/client/src/session/local/events.cc create mode 100644 src/client/src/session/local/session.cc create mode 100644 src/client/src/session/remote/session.cc delete mode 100644 src/client/src/windows/request.cc delete mode 100644 src/client/src/windows/resources.rc.in delete mode 100644 src/client/src/windows/session.cc diff --git a/src/client/lib3270++.cbp b/src/client/lib3270++.cbp index ae11564..dc30ae1 100644 --- a/src/client/lib3270++.cbp +++ b/src/client/lib3270++.cbp @@ -47,19 +47,19 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/client/private.h b/src/client/private.h index 1be0d5b..2670abb 100644 --- a/src/client/private.h +++ b/src/client/private.h @@ -18,7 +18,7 @@ * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin * St, Fifth Floor, Boston, MA 02110-1301 USA * - * Este programa está nomeado como lib3270++.h e possui - linhas de código. + * Este programa está nomeado como - e possui - linhas de código. * * Contatos: * diff --git a/src/client/src/abstract.cc b/src/client/src/abstract.cc deleted file mode 100644 index d65f3db..0000000 --- a/src/client/src/abstract.cc +++ /dev/null @@ -1,153 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como lib3270++.h e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/abstract.cc - * - * @brief - * - * @author perry.werneck@gmail.com - * - */ - - #include "private.h" - #include - - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - namespace TN3270 { - - Abstract::Session::Session() { - -#ifdef HAVE_ICONV - this->converter.local = (iconv_t) (-1); - this->converter.host = (iconv_t) (-1); -#endif - - this->baddr = 0; - - } - - Abstract::Session::~Session() { - -#ifdef HAVE_ICONV - - if(this->converter.local != (iconv_t) (-1)) - iconv_close(this->converter.local); - - if(this->converter.host != (iconv_t) (-1)) - iconv_close(this->converter.host); - -#endif - - } - - /// @brief Setup charsets - void Abstract::Session::setCharSet(const char *remote, const char *local) { - -#ifdef HAVE_ICONV - - if(this->converter.local != (iconv_t) (-1)) - iconv_close(converter.local); - - if(this->converter.host != (iconv_t) (-1)) - iconv_close(converter.host); - - if(strcmp(local,remote)) { - - // Local and remote charsets aren't the same, setup conversion - converter.local = iconv_open(local, remote); - converter.host = iconv_open(remote,local); - - } else { - // Same charset, doesn't convert - converter.local = converter.host = (iconv_t)(-1); - } - -#else - - #error No ICONV Support - -#endif - - - } - - /// @brief Converte charset. - std::string Abstract::Session::convertCharset(iconv_t &converter, const char *str) { - - std::string rc; - -#ifdef HAVE_ICONV - size_t in = strlen(str); - - if(in && converter != (iconv_t)(-1)) { - - size_t out = (in << 1); - char * ptr; - char * outBuffer = (char *) malloc(out); - ICONV_CONST char * inBuffer = (ICONV_CONST char *) str; - - memset(ptr=outBuffer,0,out); - - iconv(converter,NULL,NULL,NULL,NULL); // Reset state - - if(iconv(converter,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) - rc.assign(outBuffer); - - free(outBuffer); - - } - -#else - - rc = str; - -#endif // HAVE_ICONV - - return rc; - } - - /// @brief Converte string recebida do host para o charset atual. - std::string Abstract::Session::convertFromHost(const char *str) const { - return convertCharset(const_cast(this)->converter.local,str); - } - - /// @brief Converte string do charset atual para o charset do host. - std::string Abstract::Session::convertToHost(const char *str) const { - return convertCharset(const_cast(this)->converter.host,str); - } - - - } - - - - diff --git a/src/client/src/core/abstract.cc b/src/client/src/core/abstract.cc new file mode 100644 index 0000000..d723870 --- /dev/null +++ b/src/client/src/core/abstract.cc @@ -0,0 +1,153 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/core/abstract.cc + * + * @brief Implements abstract session object. + * + * @author perry.werneck@gmail.com + * + */ + + #include "private.h" + #include + + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + Abstract::Session::Session() { + +#ifdef HAVE_ICONV + this->converter.local = (iconv_t) (-1); + this->converter.host = (iconv_t) (-1); +#endif + + this->baddr = 0; + + } + + Abstract::Session::~Session() { + +#ifdef HAVE_ICONV + + if(this->converter.local != (iconv_t) (-1)) + iconv_close(this->converter.local); + + if(this->converter.host != (iconv_t) (-1)) + iconv_close(this->converter.host); + +#endif + + } + + /// @brief Setup charsets + void Abstract::Session::setCharSet(const char *remote, const char *local) { + +#ifdef HAVE_ICONV + + if(this->converter.local != (iconv_t) (-1)) + iconv_close(converter.local); + + if(this->converter.host != (iconv_t) (-1)) + iconv_close(converter.host); + + if(strcmp(local,remote)) { + + // Local and remote charsets aren't the same, setup conversion + converter.local = iconv_open(local, remote); + converter.host = iconv_open(remote,local); + + } else { + // Same charset, doesn't convert + converter.local = converter.host = (iconv_t)(-1); + } + +#else + + throw std::runtime_error("No ICONV Support"); + +#endif + + + } + + /// @brief Converte charset. + std::string Abstract::Session::convertCharset(iconv_t &converter, const char *str) { + + std::string rc; + +#ifdef HAVE_ICONV + size_t in = strlen(str); + + if(in && converter != (iconv_t)(-1)) { + + size_t out = (in << 1); + char * ptr; + char * outBuffer = (char *) malloc(out); + ICONV_CONST char * inBuffer = (ICONV_CONST char *) str; + + memset(ptr=outBuffer,0,out); + + iconv(converter,NULL,NULL,NULL,NULL); // Reset state + + if(iconv(converter,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) + rc.assign(outBuffer); + + free(outBuffer); + + } + +#else + + rc = str; + +#endif // HAVE_ICONV + + return rc; + } + + /// @brief Converte string recebida do host para o charset atual. + std::string Abstract::Session::convertFromHost(const char *str) const { + return convertCharset(const_cast(this)->converter.local,str); + } + + /// @brief Converte string do charset atual para o charset do host. + std::string Abstract::Session::convertToHost(const char *str) const { + return convertCharset(const_cast(this)->converter.host,str); + } + + + } + + + + diff --git a/src/client/src/core/events.cc b/src/client/src/core/events.cc new file mode 100644 index 0000000..6e5d168 --- /dev/null +++ b/src/client/src/core/events.cc @@ -0,0 +1,56 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/core/events.cc + * + * @brief Implements event object. + * + * @author perry.werneck@gmail.com + * + */ + + #include "private.h" + + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + Event::Event(enum Event::Type type) { + this->type = type; + } + + Event::~Event() { + } + + } + + + diff --git a/src/client/src/core/host.cc b/src/client/src/core/host.cc new file mode 100644 index 0000000..a4a6f6a --- /dev/null +++ b/src/client/src/core/host.cc @@ -0,0 +1,180 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/core/host.cc + * + * @brief Implements host object. + * + * @author perry.werneck@gmail.com + * + */ + + #include "private.h" + + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + Host::Host(const char *id, const char *url, time_t timeout) { + this->timeout = timeout; + this->session = Session::create(id); + if(url) { + this->connect(url); + } + } + + Host::~Host() { + delete this->session; + this->session = nullptr; + } + + void Host::connect(const char *url, bool sync) { + this->session->connect(url); + if(sync) { + this->sync(); + } + } + + + /// @brief Writes characters to the associated file from the put area + int Host::sync() { + this->session->waitForReady(this->timeout); + return 0; + } + + /// @brief Writes characters to the associated output sequence from the put area. + int Host::overflow(int c) { + + if (c != EOF) { + char str[] = { static_cast(c), 0 }; + this->session->push((const char *) str); + } else { + sync(); + } + + return c; + + } + + Host & Host::push(const Action action) { + session->push(action); + sync(); + return *this; + } + + bool Host::isReady() const { + this->session->waitForReady(this->timeout); + return getProgramMessage() == MESSAGE_NONE; + } + + bool Host::isConnected() const { + this->session->waitForReady(this->timeout); + return getConnectionState() == CONNECTED_TN3270E; + } + + std::string Host::toString() const { + + this->session->waitForReady(this->timeout); + + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { + throw std::system_error(ENOTCONN, std::system_category()); + } + + return this->session->toString(); + } + + std::string Host::toString(int baddr, size_t len, char lf) const { + + this->session->waitForReady(this->timeout); + + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { + throw std::system_error(ENOTCONN, std::system_category()); + } + + return this->session->toString(baddr,len,lf); + + } + + std::string Host::toString(int row, int col, size_t sz, char lf) const { + + this->session->waitForReady(this->timeout); + + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { + throw std::system_error(ENOTCONN, std::system_category()); + } + + return this->session->toString(row,col,sz,lf); + + + } + + Host & Host::pop(int baddr, std::string &text) { + + this->session->waitForReady(this->timeout); + + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { + throw std::system_error(ENOTCONN, std::system_category()); + } + + session->pop(baddr, text); + + return *this; + } + + Host & Host::pop(int row, int col, std::string &text) { + + this->session->waitForReady(this->timeout); + + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { + throw std::system_error(ENOTCONN, std::system_category()); + } + + session->pop(row,col,text); + + return *this; + } + + Host & Host::pop(std::string &text) { + + this->session->waitForReady(this->timeout); + + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { + throw std::system_error(ENOTCONN, std::system_category()); + } + + session->pop(text); + + return *this; + } + + + } + diff --git a/src/client/src/core/session.cc b/src/client/src/core/session.cc new file mode 100644 index 0000000..240ad04 --- /dev/null +++ b/src/client/src/core/session.cc @@ -0,0 +1,78 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/core/session.cc + * + * @brief Implements common session object. + * + * @author perry.werneck@gmail.com + * + */ + + #include "private.h" + + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + /// @brief Create a tn3270 session. + Session * Session::create(const char *id) { + + if(!id) { + return new Local::Session(); + } + + return new IPC::Session(id); + + } + + + Session::Session() { + + } + + Session::~Session() { + + } + + void Session::insert(Event::Type type, std::function listener) { + } + + /// @brief Fire event. + void Session::fire(const Event &event) { + + + } + + } + + + diff --git a/src/client/src/events.cc b/src/client/src/events.cc deleted file mode 100644 index c29f39f..0000000 --- a/src/client/src/events.cc +++ /dev/null @@ -1,56 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como lib3270++.h e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/events.cc - * - * @brief - * - * @author perry.werneck@gmail.com - * - */ - - #include "private.h" - - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - namespace TN3270 { - - Event::Event(enum Event::Type type) { - this->type = type; - } - - Event::~Event() { - } - - } - - - diff --git a/src/client/src/host.cc b/src/client/src/host.cc deleted file mode 100644 index d34f984..0000000 --- a/src/client/src/host.cc +++ /dev/null @@ -1,180 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como lib3270++.h e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/host.cc - * - * @brief - * - * @author perry.werneck@gmail.com - * - */ - - #include "private.h" - - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - namespace TN3270 { - - Host::Host(const char *id, const char *url, time_t timeout) { - this->timeout = timeout; - this->session = Session::create(id); - if(url) { - this->connect(url); - } - } - - Host::~Host() { - delete this->session; - this->session = nullptr; - } - - void Host::connect(const char *url, bool sync) { - this->session->connect(url); - if(sync) { - this->sync(); - } - } - - - /// @brief Writes characters to the associated file from the put area - int Host::sync() { - this->session->waitForReady(this->timeout); - return 0; - } - - /// @brief Writes characters to the associated output sequence from the put area. - int Host::overflow(int c) { - - if (c != EOF) { - char str[] = { static_cast(c), 0 }; - this->session->push((const char *) str); - } else { - sync(); - } - - return c; - - } - - Host & Host::push(const Action action) { - session->push(action); - sync(); - return *this; - } - - bool Host::isReady() const { - this->session->waitForReady(this->timeout); - return getProgramMessage() == MESSAGE_NONE; - } - - bool Host::isConnected() const { - this->session->waitForReady(this->timeout); - return getConnectionState() == CONNECTED_TN3270E; - } - - std::string Host::toString() const { - - this->session->waitForReady(this->timeout); - - if(this->session->getConnectionState() == TN3270::DISCONNECTED) { - throw std::system_error(ENOTCONN, std::system_category()); - } - - return this->session->toString(); - } - - std::string Host::toString(int baddr, size_t len, char lf) const { - - this->session->waitForReady(this->timeout); - - if(this->session->getConnectionState() == TN3270::DISCONNECTED) { - throw std::system_error(ENOTCONN, std::system_category()); - } - - return this->session->toString(baddr,len,lf); - - } - - std::string Host::toString(int row, int col, size_t sz, char lf) const { - - this->session->waitForReady(this->timeout); - - if(this->session->getConnectionState() == TN3270::DISCONNECTED) { - throw std::system_error(ENOTCONN, std::system_category()); - } - - return this->session->toString(row,col,sz,lf); - - - } - - Host & Host::pop(int baddr, std::string &text) { - - this->session->waitForReady(this->timeout); - - if(this->session->getConnectionState() == TN3270::DISCONNECTED) { - throw std::system_error(ENOTCONN, std::system_category()); - } - - session->pop(baddr, text); - - return *this; - } - - Host & Host::pop(int row, int col, std::string &text) { - - this->session->waitForReady(this->timeout); - - if(this->session->getConnectionState() == TN3270::DISCONNECTED) { - throw std::system_error(ENOTCONN, std::system_category()); - } - - session->pop(row,col,text); - - return *this; - } - - Host & Host::pop(std::string &text) { - - this->session->waitForReady(this->timeout); - - if(this->session->getConnectionState() == TN3270::DISCONNECTED) { - throw std::system_error(ENOTCONN, std::system_category()); - } - - session->pop(text); - - return *this; - } - - - } - diff --git a/src/client/src/ipc/session.cc b/src/client/src/ipc/session.cc deleted file mode 100644 index 380602a..0000000 --- a/src/client/src/ipc/session.cc +++ /dev/null @@ -1,365 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como - e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/ipc/session.cc - * - * @brief Implements lib3270 access using IPC calls. - * - * @author perry.werneck@gmail.com - * - */ - - #include "../private.h" - #include - - using std::string; - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - namespace TN3270 { - - void IPC::Session::connect(const char *url) { - Request request(*this,"connect"); - request.push(url).call(); - } - - void IPC::Session::disconnect() { - Request(*this,"disconnect").call(); - } - - // Wait for session state. - void IPC::Session::waitForReady(time_t timeout) { - - int rc; - - time_t end = time(nullptr) + timeout; - - while(time(nullptr) < end) { - - debug("Running waitForReady request..."); - - Request(*this,"waitForReady") - .push((uint32_t) 1) - .call() - .pop(rc); - - debug("Wait for ready returned ",rc); - - if(rc == 0) - return; - - } - - throw std::system_error(ETIMEDOUT, std::system_category()); - } - - std::string IPC::Session::toString(int baddr, size_t len, char lf) const { - - std::string rc; - - Request(*this,"getStringAtAddress") - .push((uint32_t) baddr) - .push((uint32_t) len) - .push((uint8_t) lf) - .call() - .pop(rc); - - return rc; - } - - std::string IPC::Session::toString(int row, int col, size_t sz, char lf) const { - - std::string rc; - - Request(*this,"getStringAt") - .push((uint32_t) row) - .push((uint32_t) col) - .push((uint32_t) sz) - .push((uint8_t) lf) - .call() - .pop(rc); - - return rc; - } - - ProgramMessage IPC::Session::getProgramMessage() const { - - int program_message; - getProperty("program_message",program_message); - return (ProgramMessage) program_message; - - } - - ConnectionState IPC::Session::getConnectionState() const { - - int cstate; - getProperty("cstate",cstate); - return (ConnectionState) cstate; - - } - - /// @brief Set field at current position, jumps to next writable field. - TN3270::Session & IPC::Session::push(const char *text) { - - int rc; - - Request(*this,"setString") - .push(text) - .call() - .pop(rc); - - if(rc) { - throw std::system_error((int) rc, std::system_category()); - } - - return *this; - - } - - TN3270::Session & IPC::Session::push(int baddr, const std::string &text) { - - int rc; - - Request(*this,"setStringAtAddress") - .push((uint32_t) baddr) - .push(text.c_str()) - .call() - .pop(rc); - - if(rc) { - throw std::system_error((int) rc, std::system_category()); - } - - return *this; - - } - - TN3270::Session & IPC::Session::push(int row, int col, const std::string &text) { - - int32_t rc; - - Request(*this,"setStringAt") - .push((uint32_t) row) - .push((uint32_t) col) - .push(text.c_str()) - .call() - .pop(rc); - - if(rc) { - throw std::system_error((int) rc, std::system_category()); - } - - return *this; - - } - - TN3270::Session & IPC::Session::push(const PFKey key) { - - int32_t rc; - - Request(*this,"pfkey") - .push((uint32_t) key) - .call() - .pop(rc); - - if(rc) { - throw std::system_error((int) rc, std::system_category()); - } - - return *this; - - } - - TN3270::Session & IPC::Session::push(const PAKey key) { - - int32_t rc; - - Request(*this,"pakey") - .push((uint32_t) key) - .call() - .pop(rc); - - if(rc) { - throw std::system_error((int) rc, std::system_category()); - } - - return *this; - - } - - TN3270::Session & IPC::Session::push(const Action action) { - - const char * actions[] = { - "enter", - "erase", - "eraseeof", - "eraseeol", - "eraseinput" - }; - - if( ((size_t) action) > (sizeof(actions)/sizeof(actions[0]))) { - throw std::system_error(EINVAL, std::system_category()); - } - - return this->action(actions[action]); - - } - - TN3270::Session & IPC::Session::pop(int baddr, std::string &text) { - - Request(*this,"getFieldAtAddress") - .push((uint32_t) baddr) - .call() - .pop(text); - - return *this; - } - - TN3270::Session & IPC::Session::pop(int row, int col, std::string &text) { - - Request(*this,"getFieldAt") - .push((uint32_t) row) - .push((uint32_t) col) - .call() - .pop(text); - - return *this; - } - - TN3270::Session & IPC::Session::pop(std::string &text) { - - Request(*this,"getFieldAtCursor") - .call() - .pop(text); - - return *this; - - } - - /// @brief Set cursor address. - /// - /// @param addr Cursor address. - TN3270::Session & IPC::Session::setCursorPosition(unsigned short addr) { - - int32_t rc; - - Request(*this,"setCursorAddress") - .push((uint32_t) addr) - .call() - .pop(rc); - - if(rc) { - throw std::system_error((int) rc, std::system_category()); - } - - return *this; - - } - - /// @brief Set cursor position. - /// - /// @param row New cursor row. - /// @param col New cursor column. - TN3270::Session & IPC::Session::setCursorPosition(unsigned short row, unsigned short col) { - - int32_t rc; - - Request(*this,"setCursorPosition") - .push((uint32_t) row) - .push((uint32_t) col) - .call() - .pop(rc); - - if(rc) { - throw std::system_error((int) rc, std::system_category()); - } - - return *this; - - } - - void IPC::Session::getProperty(const char *name, int &value) const { - - Request(*this,false,name) - .call() - .pop(value); - - } - - void IPC::Session::getProperty(const char *name, std::string &value) const { - - Request(*this,false,name) - .call() - .pop(value); - - } - - void IPC::Session::getProperty(const char *name, bool &value) const { - throw std::system_error(ENOENT, std::system_category()); - } - - /// @brief Get lib3270 version. - std::string IPC::Session::getVersion() const { - - string rc; - getProperty("version",rc); - return rc; - - } - - /// @brief Get lib3270 revision. - std::string IPC::Session::getRevision() const { - - string rc; - getProperty("revision",rc); - return rc; - - } - - /// @brief Execute action by name. - TN3270::Session & IPC::Session::action(const char *action_name) { - - int32_t rc; - - Request(*this,"action") - .push(action_name) - .call() - .pop(rc); - - if(rc) { - throw std::system_error((int) rc, std::system_category()); - } - - return *this; - } - - } - - diff --git a/src/client/src/linux/request.cc b/src/client/src/linux/request.cc deleted file mode 100644 index f7d7ea9..0000000 --- a/src/client/src/linux/request.cc +++ /dev/null @@ -1,267 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como - e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/linux/request.cc - * - * @brief Implements D-Bus message. - * - * @author perry.werneck@gmail.com - * - */ - - #include "../private.h" - - using std::string; - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - namespace TN3270 { - - IPC::Request::Request(const Session &session) { - this->conn = session.conn; - this->msg.in = nullptr; - this->msg.out = nullptr; - } - - IPC::Request::Request(const Session &session, const char *method) : Request(session) { - - this->msg.out = dbus_message_new_method_call( - session.name.c_str(), // Destination - session.path.c_str(), // Path - session.interface.c_str(), // Interface - method // Method - ); - - if(!msg.out) { - throw std::runtime_error("Can't create D-Bus Method Call"); - } - - } - - IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session) { - -/* - dbus-send \ - --session \ - --dest=br.com.bb.pw3270.a\ - --print-reply \ - "/br/com/bb/tn3270/session" \ - "org.freedesktop.DBus.Properties.Get" \ - string:br.com.bb.tn3270.session \ - string:${1} -*/ - this->msg.out = dbus_message_new_method_call( - session.name.c_str(), // Destination - session.path.c_str(), // Path - "org.freedesktop.DBus.Properties", // Interface - (isSet ? "Set" : "Get") - ); - - if(!msg.out) { - throw std::runtime_error("Can't create D-Bus Property Call"); - } - - // - // https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties - // org.freedesktop.DBus.Properties.Get (in STRING interface_name, - // in STRING property_name, - // out VARIANT value); - // org.freedesktop.DBus.Properties.Set (in STRING interface_name, - // in STRING property_name, - // - const char *interface_name = session.interface.c_str(); - - dbus_message_append_args( - this->msg.out, - DBUS_TYPE_STRING,&interface_name, - DBUS_TYPE_STRING,&property, - DBUS_TYPE_INVALID - ); - - } - - IPC::Request::~Request() { - if(msg.out) { - dbus_message_unref(msg.out); - } - if(msg.in) { - dbus_message_unref(msg.in); - } - } - - IPC::Request & IPC::Request::call() { - - if(msg.in) { - dbus_message_unref(msg.in); - msg.in = nullptr; - } - - DBusError error; - dbus_error_init(&error); - this->msg.in = dbus_connection_send_with_reply_and_block(this->conn,this->msg.out,10000,&error); - - if(!this->msg.in) { - string message = error.message; - dbus_error_free(&error); - throw std::runtime_error(message.c_str()); - } - - dbus_message_iter_init(msg.in, &msg.iter); - - debug(__FUNCTION__," got a valid response"); - - return *this; - - } - - IPC::Request & IPC::Request::push(const char *arg) { - dbus_message_append_args(this->msg.out,DBUS_TYPE_STRING,&arg,DBUS_TYPE_INVALID); - return *this; - } - - IPC::Request & IPC::Request::push(const bool arg) { - dbus_message_append_args(this->msg.out,DBUS_TYPE_BOOLEAN,&arg,DBUS_TYPE_INVALID); - return *this; - } - - IPC::Request & IPC::Request::push(const uint8_t arg) { - dbus_message_append_args(this->msg.out,DBUS_TYPE_BYTE,&arg,DBUS_TYPE_INVALID); - return *this; - } - - IPC::Request & IPC::Request::push(const int32_t arg) { - dbus_message_append_args(this->msg.out,DBUS_TYPE_INT32,&arg,DBUS_TYPE_INVALID); - return *this; - } - - IPC::Request & IPC::Request::push(const uint32_t arg) { - dbus_message_append_args(this->msg.out,DBUS_TYPE_UINT32,&arg,DBUS_TYPE_INVALID); - return *this; - } - - - IPC::Request & IPC::Request::pop(std::string &value) { - - const char * str = ""; - - if(dbus_message_iter_get_arg_type(&msg.iter) == DBUS_TYPE_STRING) { - - dbus_message_iter_get_basic(&msg.iter, &str); - - } else if(dbus_message_iter_get_arg_type(&msg.iter) == DBUS_TYPE_VARIANT) { - - DBusMessageIter sub; - int current_type; - - dbus_message_iter_recurse(&msg.iter, &sub); - - while ((current_type = dbus_message_iter_get_arg_type(&sub)) != DBUS_TYPE_INVALID) { - - if (current_type == DBUS_TYPE_STRING) { - dbus_message_iter_get_basic(&sub, &str); - break; - } - dbus_message_iter_next(&sub); - } - - } else { - - debug("Argument type is ", ((char) dbus_message_iter_get_arg_type(&msg.iter)) ); - throw std::runtime_error("Expected an string data type"); - - } - - dbus_message_iter_next(&msg.iter); - - value.assign(str); - - debug(__FUNCTION__,"= \"",str,"\""); - - return *this; - } - - static int getIntValue(DBusMessageIter &iter) { - - if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT32) { - - dbus_int32_t rc = 0; - dbus_message_iter_get_basic(&iter, &rc); - return (int) rc; - - } else if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT16) { - - dbus_int16_t rc = 0; - dbus_message_iter_get_basic(&iter, &rc); - return (int) rc; - - } else if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) { - - DBusMessageIter sub; - int current_type; - - dbus_message_iter_recurse(&iter, &sub); - - while ((current_type = dbus_message_iter_get_arg_type(&sub)) != DBUS_TYPE_INVALID) { - - if (current_type == DBUS_TYPE_INT32) { - - dbus_int32_t rc = 0; - dbus_message_iter_get_basic(&sub, &rc); - return (int) rc; - - } else if (current_type == DBUS_TYPE_INT16) { - dbus_int16_t rc = 0; - dbus_message_iter_get_basic(&sub, &rc); - return (int) rc; - - } - dbus_message_iter_next(&sub); - } - - } - - debug("Argument type is ", ((char) dbus_message_iter_get_arg_type(&iter)) ); - throw std::runtime_error("Expected an integer data type"); - - } - - IPC::Request & IPC::Request::Request::pop(int &value) { - - value = getIntValue(msg.iter); - dbus_message_iter_next(&msg.iter); - debug(__FUNCTION__,"= \"",value,"\""); - - return *this; - - } - - } - - diff --git a/src/client/src/linux/session.cc b/src/client/src/linux/session.cc deleted file mode 100644 index 2197ec8..0000000 --- a/src/client/src/linux/session.cc +++ /dev/null @@ -1,98 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como - e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/ipc/linux/session.cc - * - * @brief Implements Linux session create/destroy session. - * - * @author perry.werneck@gmail.com - * - */ - - #include "../private.h" - #include - #include - - using std::string; - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - static void throws_if_error(DBusError &err) { - - if(dbus_error_is_set(&err)) { - string message = err.message; - dbus_error_free(&err); - throw std::runtime_error(message.c_str()); - } - - return; - - } - - namespace TN3270 { - - IPC::Session::Session(const char *id) : Abstract::Session() { - - // Create D-Bus session. - DBusError err; - - dbus_error_init(&err); - this->conn = dbus_bus_get(DBUS_BUS_SESSION, &err); - - debug("dbus_bus_get conn=",conn); - - throws_if_error(err); - - if(!conn) - throw std::runtime_error("DBUS Connection failed"); - - auto sep = strchr(id,':'); - if(!sep) { - throw std::system_error(EINVAL, std::system_category()); - } - - this->name = "br.com.bb."; - this->name += string(id,(sep - id)); - this->name += "."; - this->name += (sep+1); - this->path = "/br/com/bb/tn3270/session"; - this->interface = "br.com.bb.tn3270.session"; - - debug("D-Bus Object name=\"",this->name,"\" D-Bus Object path=\"",this->path,"\""); - - } - - IPC::Session::~Session() { - - } - - } - - diff --git a/src/client/src/local/events.cc b/src/client/src/local/events.cc deleted file mode 100644 index 39cd2e2..0000000 --- a/src/client/src/local/events.cc +++ /dev/null @@ -1,175 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como lib3270++.h e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/local/events.cc - * - * @brief Implement lib3270 direct access events. - * - * @author perry.werneck@gmail.com - * - */ - - #include "../private.h" - #include - - extern "C" { - #include - #include - } - - using std::string; - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - -#ifndef HAVE_VASPRINTF - int vasprintf(char **strp, const char *fmt, va_list ap) { - char buf[1024]; - - int nc = vsnprintf(buf, sizeof(buf), fmt, args); - - if(nc < 0) { - - *strp = strdup(_("Error in vasprintf")); - - } else if (nc < sizeof(buf)) { - - *strp = malloc(nc+1); - strcpy(*strp, buf); - - } else { - - *strp = malloc(nc + 1); - if(vsnprintf(*strp, nc, fmt, args) < 0) { - free(*strp); - *strp = strdup(NULL,_( "Out of memory in vasprintf" ) ); - } - - } - - return nc; - } -#endif // !HAVE_VASPRINTF - - namespace TN3270 { - - /// @brief Popup Handler. - void Local::Session::popupHandler(H3270 *h3270, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg) { - - Local::Session * session = (Local::Session *) lib3270_get_user_data(h3270); - - if(!session) { - throw std::runtime_error(_( "Invalid session handler" )); - } - - class PopupEvent : public TN3270::Event { - private: - LIB3270_NOTIFY type; - string title; - string msg; - string description; - - public: - PopupEvent(LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg) : Event(Event::Popup) { - - this->type = type; - this->title = title; - this->msg = msg; - - char * buffer = NULL; - if(vasprintf(&buffer,fmt,arg) != -1) { - this->description = buffer; - free(buffer); - } - -#ifdef DEBUG - std::cerr << "Popup:" << std::endl - << "\t" << title << std::endl - << "\t" << msg << std::endl - << "\t" << description << std::endl; -#endif // DEBUG - - } - - virtual ~PopupEvent() { - } - - /// @brief Get event description. - std::string toString() const override { - return msg; - } - - - }; - - session->fire(PopupEvent(type,title,msg,fmt,arg)); - - } - - /// @brief Connect Handler. - void Local::Session::connectHandler(H3270 *h3270, unsigned char connected) { - - Local::Session * session = (Local::Session *) lib3270_get_user_data(h3270); - - if(!session) { - throw std::runtime_error(_("Invalid session handler")); - } - - class ConnectionEvent : public TN3270::Event { - private: - bool connected; - - public: - ConnectionEvent(unsigned char connected) : Event(Event::Connection) { - this->connected = (connected != 0); - -#ifdef DEBUG - std::cerr << "Session is " << this->toString().c_str() << std::endl; -#endif // DEBUG - - } - - virtual ~ConnectionEvent() { - } - - /// @brief Get event description. - std::string toString() const override { - return this->connected ? _("connected") : _("disconnected"); - } - - }; - - session->fire(ConnectionEvent(connected)); - - } - - - } - - diff --git a/src/client/src/local/session.cc b/src/client/src/local/session.cc deleted file mode 100644 index be73527..0000000 --- a/src/client/src/local/session.cc +++ /dev/null @@ -1,389 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como lib3270++.h e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/local/session.cc - * - * @brief Implement lib3270 direct access layout (NO IPC). - * - * @author perry.werneck@gmail.com - * - */ - - #include "../private.h" - #include - #include - #include - - extern "C" { - #include - } - - using std::string; - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - namespace TN3270 { - - Local::Session::Session() : Abstract::Session() { - - std::lock_guard lock(sync); - - this->hSession = lib3270_session_new(""); - lib3270_set_user_data(this->hSession,(void *) this); - setCharSet(lib3270_get_display_charset(this->hSession)); - - lib3270_set_popup_handler(this->hSession, popupHandler); - - // Setup callbacks - struct lib3270_session_callbacks *cbk; - - cbk = lib3270_get_session_callbacks(this->hSession,sizeof(struct lib3270_session_callbacks)); - if(!cbk) { - throw std::runtime_error( _("Invalid callback table, possible version mismatch in lib3270") ); - } - - cbk->update_connect = connectHandler; - - - } - - Local::Session::~Session() { - - std::lock_guard lock(sync); - - lib3270_session_free(this->hSession); - this->hSession = nullptr; - } - - void Local::Session::wait(time_t timeout) { - - std::lock_guard lock(sync); - - int rc = lib3270_wait_for_ready(this->hSession, timeout); - - if(rc) { - throw std::system_error(rc, std::system_category()); - } - - } - - void Local::Session::connect(const char *url) { - std::lock_guard lock(sync); - int rc = lib3270_connect_url(hSession,url,0); - - if(rc) { - throw std::system_error(rc, std::system_category()); - } - - } - - void Local::Session::disconnect() { - std::lock_guard lock(sync); - lib3270_disconnect(hSession); - } - - // Wait for session state. - void Local::Session::waitForReady(time_t timeout) throw() { - this->wait(timeout); - } - - std::string Local::Session::toString(int baddr, size_t len, char lf) const { - - std::lock_guard lock(const_cast(this)->sync); - - char * text = lib3270_get_string_at_address(hSession, baddr, len, lf); - - if(!text) { - throw std::runtime_error( _("Can't get screen contents") ); - } - - string rc = convertFromHost(text); - - lib3270_free(text); - - return rc; - - } - - std::string Local::Session::toString(int row, int col, size_t sz, char lf) const { - - std::lock_guard lock(const_cast(this)->sync); - - char * text = lib3270_get_string_at(hSession, row, col, sz, lf); - - if(!text) { - throw std::runtime_error( _("Can't get screen contents") ); - } - - string rc = convertFromHost(text); - - lib3270_free(text); - - return rc; - } - - void Local::Session::getProperty(const char *name, int &value) const { - - const LIB3270_INT_PROPERTY * intprop = lib3270_get_int_properties_list(); - for(size_t ix = 0; intprop[ix].name; ix++) { - - if(!strcasecmp(name,intprop[ix].name)) { - - std::lock_guard lock(const_cast(this)->sync); - - value = intprop[ix].get(hSession); - - if(value < 0 && errno != 0) { - throw std::system_error(errno, std::system_category()); - } - - - } - - } - - throw std::system_error(ENOENT, std::system_category()); - - } - - void Local::Session::getProperty(const char *name, std::string &value) const { - - const LIB3270_STRING_PROPERTY * strprop = lib3270_get_string_properties_list(); - - for(size_t ix = 0; strprop[ix].name; ix++) { - - if(!strcasecmp(name,strprop[ix].name)) { - - std::lock_guard lock(const_cast(this)->sync); - - // Found it! - const char * str = strprop[ix].get(hSession); - - if(str) { - value.assign(str); - return; - } - - throw std::system_error(errno, std::system_category()); - - } - - } - - throw std::system_error(ENOENT, std::system_category()); - } - - void Local::Session::getProperty(const char *name, bool &value) const { - - LIB3270_TOGGLE toggle = lib3270_get_toggle_id(name); - if(toggle != (LIB3270_TOGGLE) -1) { - - // Is a Tn3270 toggle, get it! - std::lock_guard lock(const_cast(this)->sync); - value = lib3270_get_toggle(hSession,toggle); - - } - - throw std::system_error(ENOENT, std::system_category()); - } - - ProgramMessage Local::Session::getProgramMessage() const { - std::lock_guard lock(const_cast(this)->sync); - return (ProgramMessage) lib3270_get_program_message(this->hSession); - } - - ConnectionState Local::Session::getConnectionState() const { - std::lock_guard lock(const_cast(this)->sync); - return (ConnectionState) lib3270_get_connection_state(this->hSession); - } - - /// @brief Set field at current position, jumps to next writable field. - TN3270::Session & Local::Session::push(const char *text) { - std::lock_guard lock(sync); - return *this; - } - - TN3270::Session & Local::Session::push(int baddr, const std::string &text) { - std::lock_guard lock(sync); - return *this; - } - - TN3270::Session & Local::Session::push(int row, int col, const std::string &text) { - std::lock_guard lock(sync); - return *this; - } - - TN3270::Session & Local::Session::push(const PFKey key) { - std::lock_guard lock(sync); - lib3270_pfkey(hSession,(int) key); - return *this; - } - - TN3270::Session & Local::Session::push(const PAKey key) { - std::lock_guard lock(sync); - lib3270_pakey(hSession,(int) key); - return *this; - } - - TN3270::Session & Local::Session::push(const Action action) { - - typedef int (*ActionCallback)(H3270 *); - - static const ActionCallback actions[] = { - lib3270_enter, - lib3270_erase, - lib3270_eraseeof, - lib3270_eraseeol, - lib3270_eraseinput - }; - - if( ((size_t) action) > (sizeof(actions)/sizeof(actions[0]))) { - throw std::system_error(EINVAL, std::system_category()); - } - - std::lock_guard lock(sync); - - int rc = actions[(size_t) action](hSession); - - if(rc) { - throw std::system_error(errno, std::system_category()); - } - - return *this; - } - - TN3270::Session & Local::Session::pop(int baddr, std::string &text) { - - std::lock_guard lock(sync); - - if(!lib3270_is_connected(hSession)) { - throw std::system_error(ENOTCONN, std::system_category()); - } - - char *contents = lib3270_get_field_text_at(hSession, baddr); - - if(!contents) { - throw std::system_error(errno, std::system_category()); - } - - text.assign(convertFromHost(contents).c_str()); - - lib3270_free(contents); - - return *this; - } - - TN3270::Session & Local::Session::pop(int row, int col, std::string &text) { - return this->pop(lib3270_translate_to_address(hSession,row,col),text); - } - - TN3270::Session & Local::Session::pop(std::string &text) { - - std::lock_guard lock(sync); - - if(!lib3270_is_connected(hSession)) { - throw std::system_error(ENOTCONN, std::system_category()); - } - - int baddr = lib3270_get_cursor_address(hSession); - if(baddr < 0) { - throw std::system_error(errno, std::system_category()); - } - - char *contents = lib3270_get_field_text_at(hSession, baddr); - - if(!contents) { - throw std::system_error(errno, std::system_category()); - } - - text.assign(convertFromHost(contents).c_str()); - - lib3270_free(contents); - - baddr = lib3270_get_next_unprotected(hSession,baddr); - if(!baddr) { - baddr = lib3270_get_next_unprotected(hSession,0); - } - - if(lib3270_set_cursor_address(hSession,baddr)) { - throw std::system_error(errno, std::system_category()); - } - - return *this; - } - - /// @brief Set cursor address. - /// - /// @param addr Cursor address. - TN3270::Session & Local::Session::setCursorPosition(unsigned short addr) { - - if(lib3270_set_cursor_address(hSession,addr) < 0) { - throw std::system_error(errno, std::system_category()); - } - - return *this; - } - - /// @brief Set cursor position. - /// - /// @param row New cursor row. - /// @param col New cursor column. - TN3270::Session & Local::Session::setCursorPosition(unsigned short row, unsigned short col) { - - if(lib3270_set_cursor_position(hSession,row,col)) { - throw std::system_error(errno, std::system_category()); - } - - return *this; - - } - - // Get properties. - std::string Local::Session::getVersion() const { - return lib3270_get_version(); - } - - std::string Local::Session::getRevision() const { - return lib3270_get_revision(); - } - - /// @brief Execute action by name. - TN3270::Session & Local::Session::action(const char *action_name) { - - if(lib3270_action(hSession,action_name)) { - throw std::system_error(errno, std::system_category()); - } - - return *this; - } - - } - - diff --git a/src/client/src/os/linux/request.cc b/src/client/src/os/linux/request.cc new file mode 100644 index 0000000..522f102 --- /dev/null +++ b/src/client/src/os/linux/request.cc @@ -0,0 +1,267 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/os/linux/request.cc + * + * @brief Implements linux request methods for remote session. + * + * @author perry.werneck@gmail.com + * + */ + + #include "../private.h" + + using std::string; + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + IPC::Request::Request(const Session &session) { + this->conn = session.conn; + this->msg.in = nullptr; + this->msg.out = nullptr; + } + + IPC::Request::Request(const Session &session, const char *method) : Request(session) { + + this->msg.out = dbus_message_new_method_call( + session.name.c_str(), // Destination + session.path.c_str(), // Path + session.interface.c_str(), // Interface + method // Method + ); + + if(!msg.out) { + throw std::runtime_error("Can't create D-Bus Method Call"); + } + + } + + IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session) { + +/* + dbus-send \ + --session \ + --dest=br.com.bb.pw3270.a\ + --print-reply \ + "/br/com/bb/tn3270/session" \ + "org.freedesktop.DBus.Properties.Get" \ + string:br.com.bb.tn3270.session \ + string:${1} +*/ + this->msg.out = dbus_message_new_method_call( + session.name.c_str(), // Destination + session.path.c_str(), // Path + "org.freedesktop.DBus.Properties", // Interface + (isSet ? "Set" : "Get") + ); + + if(!msg.out) { + throw std::runtime_error("Can't create D-Bus Property Call"); + } + + // + // https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties + // org.freedesktop.DBus.Properties.Get (in STRING interface_name, + // in STRING property_name, + // out VARIANT value); + // org.freedesktop.DBus.Properties.Set (in STRING interface_name, + // in STRING property_name, + // + const char *interface_name = session.interface.c_str(); + + dbus_message_append_args( + this->msg.out, + DBUS_TYPE_STRING,&interface_name, + DBUS_TYPE_STRING,&property, + DBUS_TYPE_INVALID + ); + + } + + IPC::Request::~Request() { + if(msg.out) { + dbus_message_unref(msg.out); + } + if(msg.in) { + dbus_message_unref(msg.in); + } + } + + IPC::Request & IPC::Request::call() { + + if(msg.in) { + dbus_message_unref(msg.in); + msg.in = nullptr; + } + + DBusError error; + dbus_error_init(&error); + this->msg.in = dbus_connection_send_with_reply_and_block(this->conn,this->msg.out,10000,&error); + + if(!this->msg.in) { + string message = error.message; + dbus_error_free(&error); + throw std::runtime_error(message.c_str()); + } + + dbus_message_iter_init(msg.in, &msg.iter); + + debug(__FUNCTION__," got a valid response"); + + return *this; + + } + + IPC::Request & IPC::Request::push(const char *arg) { + dbus_message_append_args(this->msg.out,DBUS_TYPE_STRING,&arg,DBUS_TYPE_INVALID); + return *this; + } + + IPC::Request & IPC::Request::push(const bool arg) { + dbus_message_append_args(this->msg.out,DBUS_TYPE_BOOLEAN,&arg,DBUS_TYPE_INVALID); + return *this; + } + + IPC::Request & IPC::Request::push(const uint8_t arg) { + dbus_message_append_args(this->msg.out,DBUS_TYPE_BYTE,&arg,DBUS_TYPE_INVALID); + return *this; + } + + IPC::Request & IPC::Request::push(const int32_t arg) { + dbus_message_append_args(this->msg.out,DBUS_TYPE_INT32,&arg,DBUS_TYPE_INVALID); + return *this; + } + + IPC::Request & IPC::Request::push(const uint32_t arg) { + dbus_message_append_args(this->msg.out,DBUS_TYPE_UINT32,&arg,DBUS_TYPE_INVALID); + return *this; + } + + + IPC::Request & IPC::Request::pop(std::string &value) { + + const char * str = ""; + + if(dbus_message_iter_get_arg_type(&msg.iter) == DBUS_TYPE_STRING) { + + dbus_message_iter_get_basic(&msg.iter, &str); + + } else if(dbus_message_iter_get_arg_type(&msg.iter) == DBUS_TYPE_VARIANT) { + + DBusMessageIter sub; + int current_type; + + dbus_message_iter_recurse(&msg.iter, &sub); + + while ((current_type = dbus_message_iter_get_arg_type(&sub)) != DBUS_TYPE_INVALID) { + + if (current_type == DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&sub, &str); + break; + } + dbus_message_iter_next(&sub); + } + + } else { + + debug("Argument type is ", ((char) dbus_message_iter_get_arg_type(&msg.iter)) ); + throw std::runtime_error("Expected an string data type"); + + } + + dbus_message_iter_next(&msg.iter); + + value.assign(str); + + debug(__FUNCTION__,"= \"",str,"\""); + + return *this; + } + + static int getIntValue(DBusMessageIter &iter) { + + if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT32) { + + dbus_int32_t rc = 0; + dbus_message_iter_get_basic(&iter, &rc); + return (int) rc; + + } else if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT16) { + + dbus_int16_t rc = 0; + dbus_message_iter_get_basic(&iter, &rc); + return (int) rc; + + } else if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) { + + DBusMessageIter sub; + int current_type; + + dbus_message_iter_recurse(&iter, &sub); + + while ((current_type = dbus_message_iter_get_arg_type(&sub)) != DBUS_TYPE_INVALID) { + + if (current_type == DBUS_TYPE_INT32) { + + dbus_int32_t rc = 0; + dbus_message_iter_get_basic(&sub, &rc); + return (int) rc; + + } else if (current_type == DBUS_TYPE_INT16) { + dbus_int16_t rc = 0; + dbus_message_iter_get_basic(&sub, &rc); + return (int) rc; + + } + dbus_message_iter_next(&sub); + } + + } + + debug("Argument type is ", ((char) dbus_message_iter_get_arg_type(&iter)) ); + throw std::runtime_error("Expected an integer data type"); + + } + + IPC::Request & IPC::Request::Request::pop(int &value) { + + value = getIntValue(msg.iter); + dbus_message_iter_next(&msg.iter); + debug(__FUNCTION__,"= \"",value,"\""); + + return *this; + + } + + } + + diff --git a/src/client/src/os/linux/session.cc b/src/client/src/os/linux/session.cc new file mode 100644 index 0000000..7a931cd --- /dev/null +++ b/src/client/src/os/linux/session.cc @@ -0,0 +1,98 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/os/linux/linux/session.cc + * + * @brief Implements Linux session methods. + * + * @author perry.werneck@gmail.com + * + */ + + #include "../private.h" + #include + #include + + using std::string; + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + static void throws_if_error(DBusError &err) { + + if(dbus_error_is_set(&err)) { + string message = err.message; + dbus_error_free(&err); + throw std::runtime_error(message.c_str()); + } + + return; + + } + + namespace TN3270 { + + IPC::Session::Session(const char *id) : Abstract::Session() { + + // Create D-Bus session. + DBusError err; + + dbus_error_init(&err); + this->conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + + debug("dbus_bus_get conn=",conn); + + throws_if_error(err); + + if(!conn) + throw std::runtime_error("DBUS Connection failed"); + + auto sep = strchr(id,':'); + if(!sep) { + throw std::system_error(EINVAL, std::system_category()); + } + + this->name = "br.com.bb."; + this->name += string(id,(sep - id)); + this->name += "."; + this->name += (sep+1); + this->path = "/br/com/bb/tn3270/session"; + this->interface = "br.com.bb.tn3270.session"; + + debug("D-Bus Object name=\"",this->name,"\" D-Bus Object path=\"",this->path,"\""); + + } + + IPC::Session::~Session() { + + } + + } + + diff --git a/src/client/src/os/windows/request.cc b/src/client/src/os/windows/request.cc new file mode 100644 index 0000000..f5f3bae --- /dev/null +++ b/src/client/src/os/windows/request.cc @@ -0,0 +1,191 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/os/windows/request.cc + * + * @brief Implements WIN32 request methods. + * + * @author perry.werneck@gmail.com + * + */ + + #include "../private.h" + + using std::string; + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + #define PIPE_BUFFER_LENGTH 8192 + + IPC::Request::Request(const Session &session) { + + this->hPipe = session.hPipe; + + in.length = PIPE_BUFFER_LENGTH; + in.used = 0; + in.block = new uint8_t[in.length]; + + out.length = PIPE_BUFFER_LENGTH; + out.used = 0; + out.block = new uint8_t[out.length]; + + } + + IPC::Request::Request(const Session &session, const char *method) : Request(session) { + + // Add name + strcpy((char *) out.block, method); + out.used += strlen((char *) method) + 1; + + // Add ID + *((uint16_t *) (out.block + out.used)) = (uint16_t) 3; + out.used += sizeof(uint16_t); + + } + + IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session) { + + // Add name + strcpy((char *) out.block, property); + out.used += strlen((char *) property) + 1; + + // Add ID (SetProperty = 2, getProperty = 1) + *((uint16_t *) (out.block + out.used)) = (uint16_t) (isSet ? 2 : 1); + out.used += sizeof(uint16_t); + + } + + IPC::Request::~Request() { + + delete[] ((uint8_t *) in.block); + delete[] ((uint8_t *) out.block); + + } + + /// @brief Store value on data block. + IPC::Request::DataBlock * IPC::Request::pushBlock(const void *ptr, size_t length) { + + if((out.used + length + sizeof(IPC::Request::DataBlock)) >= out.length) { + throw std::runtime_error("Too big"); + } + + IPC::Request::DataBlock * rc = (IPC::Request::DataBlock *) (out.block + out.used); + memcpy(((uint8_t *) (rc+1)), ((uint8_t *) ptr), length); + + out.used += (sizeof(IPC::Request::DataBlock) + length); + + return rc; + + } + + /// @brief Get next argument. + IPC::Request::DataBlock * IPC::Request::getNextBlock() const { + + if((in.current + sizeof(IPC::Request::DataBlock)) >= in.used) { + throw std::runtime_error("Out of range"); + } + + return (IPC::Request::DataBlock *) (in.block + in.current); + + } + + IPC::Request & IPC::Request::push(const char *arg) { + pushBlock(arg, strlen(arg)+1)->type = IPC::Request::String; + return *this; + } + + IPC::Request & IPC::Request::push(const bool arg) { + uint8_t value = (uint8_t) (arg ? 0xff : 0); + pushBlock(&value, sizeof(value))->type = IPC::Request::Boolean; + return *this; + } + + IPC::Request & IPC::Request::push(const uint8_t arg) { + pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uchar; + return *this; + } + + IPC::Request & IPC::Request::push(const int32_t arg) { + pushBlock(&arg, sizeof(arg))->type = IPC::Request::Int32; + return *this; + } + + IPC::Request & IPC::Request::push(const uint32_t arg) { + pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uint32; + return *this; + } + + IPC::Request & IPC::Request::pop(std::string &value) { + DataBlock * block = getNextBlock(); + + if(block->type != IPC::Request::String) + throw std::runtime_error("Invalid format"); + + const char *ptr = (const char *) (block+1); + + in.current += (strlen(ptr)+1+sizeof(DataBlock)); + + value.assign(ptr); + + return *this; + } + + IPC::Request & IPC::Request::Request::pop(int &value) { + + DataBlock * block = getNextBlock(); + + switch(block->type) { + case IPC::Request::Int16: + value = * ((int16_t *) (block+1)); + in.current += sizeof(int16_t) + sizeof(DataBlock); + break; + + case IPC::Request::Int32: + value = * ((int32_t *) (block+1)); + in.current += sizeof(int32_t) + sizeof(DataBlock); + break; + + case IPC::Request::Int64: + value = * ((int64_t *) (block+1)); + in.current += sizeof(int64_t) + sizeof(DataBlock); + break; + + default: + throw std::runtime_error("Invalid format"); + } + + return *this; + } + + } + + diff --git a/src/client/src/os/windows/resources.rc.in b/src/client/src/os/windows/resources.rc.in new file mode 100644 index 0000000..eac7424 --- /dev/null +++ b/src/client/src/os/windows/resources.rc.in @@ -0,0 +1,29 @@ +#include + +VS_VERSION_INFO VERSIONINFO +FILEVERSION @PACKAGE_MAJOR_VERSION@,@PACKAGE_MINOR_VERSION@,@PACKAGE_MAJOR_RELEASE@,0 +PRODUCTVERSION @PACKAGE_MAJOR_VERSION@,@PACKAGE_MINOR_VERSION@,@PACKAGE_MAJOR_RELEASE@,0 + +BEGIN + + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904E4" + BEGIN + VALUE "FileDescription", "3270 C++ Access Library\0" + VALUE "CompanyName", "Banco do Brasil S/A.\0" + VALUE "FileVersion", "@WIN32_VERSION@\0" + VALUE "LegalCopyright", "(C) 2017 Banco do Brasil S/A. All Rights Reserved\0" + VALUE "OriginalFilename", "@PACKAGE_TARNAME@@DLLEXT@\0" + VALUE "ProductName", "@PACKAGE_NAME@\0" + VALUE "ProductVersion", "@PACKAGE_MAJOR_VERSION@.@PACKAGE_MINOR_VERSION@.@PACKAGE_MAJOR_RELEASE@.0\0" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 0x04E4 + END + +END + diff --git a/src/client/src/os/windows/session.cc b/src/client/src/os/windows/session.cc new file mode 100644 index 0000000..a35ab24 --- /dev/null +++ b/src/client/src/os/windows/session.cc @@ -0,0 +1,142 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/os/windows/session.cc + * + * @brief Implements WIN32 remote session methods. + * + * @author perry.werneck@gmail.com + * + */ + + #include "../private.h" + #include + #include + #include + + using std::string; + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + IPC::Session::Session(const char *id) : Abstract::Session() { + + char *ptr = strchr(id,':'); + + if(!ptr) + throw std::system_error(EINVAL, std::system_category()); + + string pipename{"\\\\.\\pipe\\"}; + + pipename += string(id,ptr - id); + pipename += "\\"; + pipename += (ptr+1); + + std::transform(pipename.begin(), pipename.end(), pipename.begin(), ::tolower); + + debug("pipename: \"%s\"",pipename.c_str()); + + this->hPipe = CreateFile( + TEXT(pipename.c_str()), // pipe name + GENERIC_READ | // read and write access + GENERIC_WRITE, + 0, // no sharing + NULL, // default security attributes + OPEN_EXISTING, // opens existing pipe + 0, // default attributes + NULL // no template file + ); + + if (hPipe == INVALID_HANDLE_VALUE) { + throw std::runtime_error("Can't open IPC Channel"); + } + + // The pipe connected; change to message-read mode. + DWORD dwMode = PIPE_READMODE_MESSAGE; + if(!SetNamedPipeHandleState(hPipe,&dwMode,NULL,NULL)) { + throw std::runtime_error("Can't set IPC Channel mode"); + } + + } + + IPC::Session::~Session() { + CloseHandle(this->hPipe); + } + + + IPC::Request & IPC::Request::call() { + +#ifdef DEBUG + // lib3270_trace_data(NULL,"Request block",(const char *) this->out.block, this->out.used); +#endif // DEBUG + + in.current = 0; + + if(!TransactNamedPipe( + this->hPipe, + this->out.block, + this->out.used, + this->in.block, + this->in.length, + &this->in.used, + NULL) + ) { + + throw std::runtime_error("Can't transact on IPC Channel"); + + } + + debug("Received response \"", in.block, "\" with ", in.used, " bytes"); +#ifdef DEBUG + // lib3270_trace_data(NULL,"Response block",(const char *) this->in.block, this->in.used); +#endif // DEBUG + + // Extract response name + in.current = strlen((const char *) in.block)+1; + + // Extract return code + uint16_t rc = *((uint16_t *) (in.block + in.current)); + in.current += sizeof(uint16_t); + + // Extract argc + uint16_t argc = *((uint16_t *) (in.block + in.current)); + in.current += sizeof(uint16_t); + + debug("Received response \"", ((const char *) in.block), "\" with rc=", rc, " and ", argc, " arguments"); + + return *this; + } + + + + } + + diff --git a/src/client/src/session.cc b/src/client/src/session.cc deleted file mode 100644 index 539c82e..0000000 --- a/src/client/src/session.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como lib3270++.h e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/session.cc - * - * @brief - * - * @author perry.werneck@gmail.com - * - */ - - #include "private.h" - - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - namespace TN3270 { - - /// @brief Create a tn3270 session. - Session * Session::create(const char *id) { - - if(!id) { - return new Local::Session(); - } - - return new IPC::Session(id); - - } - - - Session::Session() { - - } - - Session::~Session() { - - } - - void Session::insert(Event::Type type, std::function listener) { - } - - /// @brief Fire event. - void Session::fire(const Event &event) { - - - } - - } - - - diff --git a/src/client/src/session/local/events.cc b/src/client/src/session/local/events.cc new file mode 100644 index 0000000..647a3cd --- /dev/null +++ b/src/client/src/session/local/events.cc @@ -0,0 +1,175 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/session/local/events.cc + * + * @brief Implement lib3270 direct access events. + * + * @author perry.werneck@gmail.com + * + */ + + #include "../private.h" + #include + + extern "C" { + #include + #include + } + + using std::string; + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + +#ifndef HAVE_VASPRINTF + int vasprintf(char **strp, const char *fmt, va_list ap) { + char buf[1024]; + + int nc = vsnprintf(buf, sizeof(buf), fmt, args); + + if(nc < 0) { + + *strp = strdup(_("Error in vasprintf")); + + } else if (nc < sizeof(buf)) { + + *strp = malloc(nc+1); + strcpy(*strp, buf); + + } else { + + *strp = malloc(nc + 1); + if(vsnprintf(*strp, nc, fmt, args) < 0) { + free(*strp); + *strp = strdup(NULL,_( "Out of memory in vasprintf" ) ); + } + + } + + return nc; + } +#endif // !HAVE_VASPRINTF + + namespace TN3270 { + + /// @brief Popup Handler. + void Local::Session::popupHandler(H3270 *h3270, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg) { + + Local::Session * session = (Local::Session *) lib3270_get_user_data(h3270); + + if(!session) { + throw std::runtime_error(_( "Invalid session handler" )); + } + + class PopupEvent : public TN3270::Event { + private: + LIB3270_NOTIFY type; + string title; + string msg; + string description; + + public: + PopupEvent(LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg) : Event(Event::Popup) { + + this->type = type; + this->title = title; + this->msg = msg; + + char * buffer = NULL; + if(vasprintf(&buffer,fmt,arg) != -1) { + this->description = buffer; + free(buffer); + } + +#ifdef DEBUG + std::cerr << "Popup:" << std::endl + << "\t" << title << std::endl + << "\t" << msg << std::endl + << "\t" << description << std::endl; +#endif // DEBUG + + } + + virtual ~PopupEvent() { + } + + /// @brief Get event description. + std::string toString() const override { + return msg; + } + + + }; + + session->fire(PopupEvent(type,title,msg,fmt,arg)); + + } + + /// @brief Connect Handler. + void Local::Session::connectHandler(H3270 *h3270, unsigned char connected) { + + Local::Session * session = (Local::Session *) lib3270_get_user_data(h3270); + + if(!session) { + throw std::runtime_error(_("Invalid session handler")); + } + + class ConnectionEvent : public TN3270::Event { + private: + bool connected; + + public: + ConnectionEvent(unsigned char connected) : Event(Event::Connection) { + this->connected = (connected != 0); + +#ifdef DEBUG + std::cerr << "Session is " << this->toString().c_str() << std::endl; +#endif // DEBUG + + } + + virtual ~ConnectionEvent() { + } + + /// @brief Get event description. + std::string toString() const override { + return this->connected ? _("connected") : _("disconnected"); + } + + }; + + session->fire(ConnectionEvent(connected)); + + } + + + } + + diff --git a/src/client/src/session/local/session.cc b/src/client/src/session/local/session.cc new file mode 100644 index 0000000..5816200 --- /dev/null +++ b/src/client/src/session/local/session.cc @@ -0,0 +1,389 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/session/local/session.cc + * + * @brief Implement lib3270 direct access layout (NO IPC). + * + * @author perry.werneck@gmail.com + * + */ + + #include "../private.h" + #include + #include + #include + + extern "C" { + #include + } + + using std::string; + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + Local::Session::Session() : Abstract::Session() { + + std::lock_guard lock(sync); + + this->hSession = lib3270_session_new(""); + lib3270_set_user_data(this->hSession,(void *) this); + setCharSet(lib3270_get_display_charset(this->hSession)); + + lib3270_set_popup_handler(this->hSession, popupHandler); + + // Setup callbacks + struct lib3270_session_callbacks *cbk; + + cbk = lib3270_get_session_callbacks(this->hSession,sizeof(struct lib3270_session_callbacks)); + if(!cbk) { + throw std::runtime_error( _("Invalid callback table, possible version mismatch in lib3270") ); + } + + cbk->update_connect = connectHandler; + + + } + + Local::Session::~Session() { + + std::lock_guard lock(sync); + + lib3270_session_free(this->hSession); + this->hSession = nullptr; + } + + void Local::Session::wait(time_t timeout) { + + std::lock_guard lock(sync); + + int rc = lib3270_wait_for_ready(this->hSession, timeout); + + if(rc) { + throw std::system_error(rc, std::system_category()); + } + + } + + void Local::Session::connect(const char *url) { + std::lock_guard lock(sync); + int rc = lib3270_connect_url(hSession,url,0); + + if(rc) { + throw std::system_error(rc, std::system_category()); + } + + } + + void Local::Session::disconnect() { + std::lock_guard lock(sync); + lib3270_disconnect(hSession); + } + + // Wait for session state. + void Local::Session::waitForReady(time_t timeout) throw() { + this->wait(timeout); + } + + std::string Local::Session::toString(int baddr, size_t len, char lf) const { + + std::lock_guard lock(const_cast(this)->sync); + + char * text = lib3270_get_string_at_address(hSession, baddr, len, lf); + + if(!text) { + throw std::runtime_error( _("Can't get screen contents") ); + } + + string rc = convertFromHost(text); + + lib3270_free(text); + + return rc; + + } + + std::string Local::Session::toString(int row, int col, size_t sz, char lf) const { + + std::lock_guard lock(const_cast(this)->sync); + + char * text = lib3270_get_string_at(hSession, row, col, sz, lf); + + if(!text) { + throw std::runtime_error( _("Can't get screen contents") ); + } + + string rc = convertFromHost(text); + + lib3270_free(text); + + return rc; + } + + void Local::Session::getProperty(const char *name, int &value) const { + + const LIB3270_INT_PROPERTY * intprop = lib3270_get_int_properties_list(); + for(size_t ix = 0; intprop[ix].name; ix++) { + + if(!strcasecmp(name,intprop[ix].name)) { + + std::lock_guard lock(const_cast(this)->sync); + + value = intprop[ix].get(hSession); + + if(value < 0 && errno != 0) { + throw std::system_error(errno, std::system_category()); + } + + + } + + } + + throw std::system_error(ENOENT, std::system_category()); + + } + + void Local::Session::getProperty(const char *name, std::string &value) const { + + const LIB3270_STRING_PROPERTY * strprop = lib3270_get_string_properties_list(); + + for(size_t ix = 0; strprop[ix].name; ix++) { + + if(!strcasecmp(name,strprop[ix].name)) { + + std::lock_guard lock(const_cast(this)->sync); + + // Found it! + const char * str = strprop[ix].get(hSession); + + if(str) { + value.assign(str); + return; + } + + throw std::system_error(errno, std::system_category()); + + } + + } + + throw std::system_error(ENOENT, std::system_category()); + } + + void Local::Session::getProperty(const char *name, bool &value) const { + + LIB3270_TOGGLE toggle = lib3270_get_toggle_id(name); + if(toggle != (LIB3270_TOGGLE) -1) { + + // Is a Tn3270 toggle, get it! + std::lock_guard lock(const_cast(this)->sync); + value = lib3270_get_toggle(hSession,toggle); + + } + + throw std::system_error(ENOENT, std::system_category()); + } + + ProgramMessage Local::Session::getProgramMessage() const { + std::lock_guard lock(const_cast(this)->sync); + return (ProgramMessage) lib3270_get_program_message(this->hSession); + } + + ConnectionState Local::Session::getConnectionState() const { + std::lock_guard lock(const_cast(this)->sync); + return (ConnectionState) lib3270_get_connection_state(this->hSession); + } + + /// @brief Set field at current position, jumps to next writable field. + TN3270::Session & Local::Session::push(const char *text) { + std::lock_guard lock(sync); + return *this; + } + + TN3270::Session & Local::Session::push(int baddr, const std::string &text) { + std::lock_guard lock(sync); + return *this; + } + + TN3270::Session & Local::Session::push(int row, int col, const std::string &text) { + std::lock_guard lock(sync); + return *this; + } + + TN3270::Session & Local::Session::push(const PFKey key) { + std::lock_guard lock(sync); + lib3270_pfkey(hSession,(int) key); + return *this; + } + + TN3270::Session & Local::Session::push(const PAKey key) { + std::lock_guard lock(sync); + lib3270_pakey(hSession,(int) key); + return *this; + } + + TN3270::Session & Local::Session::push(const Action action) { + + typedef int (*ActionCallback)(H3270 *); + + static const ActionCallback actions[] = { + lib3270_enter, + lib3270_erase, + lib3270_eraseeof, + lib3270_eraseeol, + lib3270_eraseinput + }; + + if( ((size_t) action) > (sizeof(actions)/sizeof(actions[0]))) { + throw std::system_error(EINVAL, std::system_category()); + } + + std::lock_guard lock(sync); + + int rc = actions[(size_t) action](hSession); + + if(rc) { + throw std::system_error(errno, std::system_category()); + } + + return *this; + } + + TN3270::Session & Local::Session::pop(int baddr, std::string &text) { + + std::lock_guard lock(sync); + + if(!lib3270_is_connected(hSession)) { + throw std::system_error(ENOTCONN, std::system_category()); + } + + char *contents = lib3270_get_field_text_at(hSession, baddr); + + if(!contents) { + throw std::system_error(errno, std::system_category()); + } + + text.assign(convertFromHost(contents).c_str()); + + lib3270_free(contents); + + return *this; + } + + TN3270::Session & Local::Session::pop(int row, int col, std::string &text) { + return this->pop(lib3270_translate_to_address(hSession,row,col),text); + } + + TN3270::Session & Local::Session::pop(std::string &text) { + + std::lock_guard lock(sync); + + if(!lib3270_is_connected(hSession)) { + throw std::system_error(ENOTCONN, std::system_category()); + } + + int baddr = lib3270_get_cursor_address(hSession); + if(baddr < 0) { + throw std::system_error(errno, std::system_category()); + } + + char *contents = lib3270_get_field_text_at(hSession, baddr); + + if(!contents) { + throw std::system_error(errno, std::system_category()); + } + + text.assign(convertFromHost(contents).c_str()); + + lib3270_free(contents); + + baddr = lib3270_get_next_unprotected(hSession,baddr); + if(!baddr) { + baddr = lib3270_get_next_unprotected(hSession,0); + } + + if(lib3270_set_cursor_address(hSession,baddr)) { + throw std::system_error(errno, std::system_category()); + } + + return *this; + } + + /// @brief Set cursor address. + /// + /// @param addr Cursor address. + TN3270::Session & Local::Session::setCursorPosition(unsigned short addr) { + + if(lib3270_set_cursor_address(hSession,addr) < 0) { + throw std::system_error(errno, std::system_category()); + } + + return *this; + } + + /// @brief Set cursor position. + /// + /// @param row New cursor row. + /// @param col New cursor column. + TN3270::Session & Local::Session::setCursorPosition(unsigned short row, unsigned short col) { + + if(lib3270_set_cursor_position(hSession,row,col)) { + throw std::system_error(errno, std::system_category()); + } + + return *this; + + } + + // Get properties. + std::string Local::Session::getVersion() const { + return lib3270_get_version(); + } + + std::string Local::Session::getRevision() const { + return lib3270_get_revision(); + } + + /// @brief Execute action by name. + TN3270::Session & Local::Session::action(const char *action_name) { + + if(lib3270_action(hSession,action_name)) { + throw std::system_error(errno, std::system_category()); + } + + return *this; + } + + } + + diff --git a/src/client/src/session/remote/session.cc b/src/client/src/session/remote/session.cc new file mode 100644 index 0000000..65e2d9a --- /dev/null +++ b/src/client/src/session/remote/session.cc @@ -0,0 +1,365 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file src/session/remote/session.cc + * + * @brief Implements lib3270 access using IPC calls. + * + * @author perry.werneck@gmail.com + * + */ + + #include "../private.h" + #include + + using std::string; + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + void IPC::Session::connect(const char *url) { + Request request(*this,"connect"); + request.push(url).call(); + } + + void IPC::Session::disconnect() { + Request(*this,"disconnect").call(); + } + + // Wait for session state. + void IPC::Session::waitForReady(time_t timeout) { + + int rc; + + time_t end = time(nullptr) + timeout; + + while(time(nullptr) < end) { + + debug("Running waitForReady request..."); + + Request(*this,"waitForReady") + .push((uint32_t) 1) + .call() + .pop(rc); + + debug("Wait for ready returned ",rc); + + if(rc == 0) + return; + + } + + throw std::system_error(ETIMEDOUT, std::system_category()); + } + + std::string IPC::Session::toString(int baddr, size_t len, char lf) const { + + std::string rc; + + Request(*this,"getStringAtAddress") + .push((uint32_t) baddr) + .push((uint32_t) len) + .push((uint8_t) lf) + .call() + .pop(rc); + + return rc; + } + + std::string IPC::Session::toString(int row, int col, size_t sz, char lf) const { + + std::string rc; + + Request(*this,"getStringAt") + .push((uint32_t) row) + .push((uint32_t) col) + .push((uint32_t) sz) + .push((uint8_t) lf) + .call() + .pop(rc); + + return rc; + } + + ProgramMessage IPC::Session::getProgramMessage() const { + + int program_message; + getProperty("program_message",program_message); + return (ProgramMessage) program_message; + + } + + ConnectionState IPC::Session::getConnectionState() const { + + int cstate; + getProperty("cstate",cstate); + return (ConnectionState) cstate; + + } + + /// @brief Set field at current position, jumps to next writable field. + TN3270::Session & IPC::Session::push(const char *text) { + + int rc; + + Request(*this,"setString") + .push(text) + .call() + .pop(rc); + + if(rc) { + throw std::system_error((int) rc, std::system_category()); + } + + return *this; + + } + + TN3270::Session & IPC::Session::push(int baddr, const std::string &text) { + + int rc; + + Request(*this,"setStringAtAddress") + .push((uint32_t) baddr) + .push(text.c_str()) + .call() + .pop(rc); + + if(rc) { + throw std::system_error((int) rc, std::system_category()); + } + + return *this; + + } + + TN3270::Session & IPC::Session::push(int row, int col, const std::string &text) { + + int32_t rc; + + Request(*this,"setStringAt") + .push((uint32_t) row) + .push((uint32_t) col) + .push(text.c_str()) + .call() + .pop(rc); + + if(rc) { + throw std::system_error((int) rc, std::system_category()); + } + + return *this; + + } + + TN3270::Session & IPC::Session::push(const PFKey key) { + + int32_t rc; + + Request(*this,"pfkey") + .push((uint32_t) key) + .call() + .pop(rc); + + if(rc) { + throw std::system_error((int) rc, std::system_category()); + } + + return *this; + + } + + TN3270::Session & IPC::Session::push(const PAKey key) { + + int32_t rc; + + Request(*this,"pakey") + .push((uint32_t) key) + .call() + .pop(rc); + + if(rc) { + throw std::system_error((int) rc, std::system_category()); + } + + return *this; + + } + + TN3270::Session & IPC::Session::push(const Action action) { + + const char * actions[] = { + "enter", + "erase", + "eraseeof", + "eraseeol", + "eraseinput" + }; + + if( ((size_t) action) > (sizeof(actions)/sizeof(actions[0]))) { + throw std::system_error(EINVAL, std::system_category()); + } + + return this->action(actions[action]); + + } + + TN3270::Session & IPC::Session::pop(int baddr, std::string &text) { + + Request(*this,"getFieldAtAddress") + .push((uint32_t) baddr) + .call() + .pop(text); + + return *this; + } + + TN3270::Session & IPC::Session::pop(int row, int col, std::string &text) { + + Request(*this,"getFieldAt") + .push((uint32_t) row) + .push((uint32_t) col) + .call() + .pop(text); + + return *this; + } + + TN3270::Session & IPC::Session::pop(std::string &text) { + + Request(*this,"getFieldAtCursor") + .call() + .pop(text); + + return *this; + + } + + /// @brief Set cursor address. + /// + /// @param addr Cursor address. + TN3270::Session & IPC::Session::setCursorPosition(unsigned short addr) { + + int32_t rc; + + Request(*this,"setCursorAddress") + .push((uint32_t) addr) + .call() + .pop(rc); + + if(rc) { + throw std::system_error((int) rc, std::system_category()); + } + + return *this; + + } + + /// @brief Set cursor position. + /// + /// @param row New cursor row. + /// @param col New cursor column. + TN3270::Session & IPC::Session::setCursorPosition(unsigned short row, unsigned short col) { + + int32_t rc; + + Request(*this,"setCursorPosition") + .push((uint32_t) row) + .push((uint32_t) col) + .call() + .pop(rc); + + if(rc) { + throw std::system_error((int) rc, std::system_category()); + } + + return *this; + + } + + void IPC::Session::getProperty(const char *name, int &value) const { + + Request(*this,false,name) + .call() + .pop(value); + + } + + void IPC::Session::getProperty(const char *name, std::string &value) const { + + Request(*this,false,name) + .call() + .pop(value); + + } + + void IPC::Session::getProperty(const char *name, bool &value) const { + throw std::system_error(ENOENT, std::system_category()); + } + + /// @brief Get lib3270 version. + std::string IPC::Session::getVersion() const { + + string rc; + getProperty("version",rc); + return rc; + + } + + /// @brief Get lib3270 revision. + std::string IPC::Session::getRevision() const { + + string rc; + getProperty("revision",rc); + return rc; + + } + + /// @brief Execute action by name. + TN3270::Session & IPC::Session::action(const char *action_name) { + + int32_t rc; + + Request(*this,"action") + .push(action_name) + .call() + .pop(rc); + + if(rc) { + throw std::system_error((int) rc, std::system_category()); + } + + return *this; + } + + } + + diff --git a/src/client/src/testprogram/testprogram.cc b/src/client/src/testprogram/testprogram.cc index 590f1aa..11601fc 100644 --- a/src/client/src/testprogram/testprogram.cc +++ b/src/client/src/testprogram/testprogram.cc @@ -18,7 +18,7 @@ * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin * St, Fifth Floor, Boston, MA 02110-1301 USA * - * Este programa está nomeado como lib3270++.h e possui - linhas de código. + * Este programa está nomeado como - e possui - linhas de código. * * Contatos: * diff --git a/src/client/src/windows/request.cc b/src/client/src/windows/request.cc deleted file mode 100644 index f186bc7..0000000 --- a/src/client/src/windows/request.cc +++ /dev/null @@ -1,191 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como - e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/windows/request.cc - * - * @brief Implements WIN32 Pipe Based IPC. - * - * @author perry.werneck@gmail.com - * - */ - - #include "../private.h" - - using std::string; - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - namespace TN3270 { - - #define PIPE_BUFFER_LENGTH 8192 - - IPC::Request::Request(const Session &session) { - - this->hPipe = session.hPipe; - - in.length = PIPE_BUFFER_LENGTH; - in.used = 0; - in.block = new uint8_t[in.length]; - - out.length = PIPE_BUFFER_LENGTH; - out.used = 0; - out.block = new uint8_t[out.length]; - - } - - IPC::Request::Request(const Session &session, const char *method) : Request(session) { - - // Add name - strcpy((char *) out.block, method); - out.used += strlen((char *) method) + 1; - - // Add ID - *((uint16_t *) (out.block + out.used)) = (uint16_t) 3; - out.used += sizeof(uint16_t); - - } - - IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session) { - - // Add name - strcpy((char *) out.block, property); - out.used += strlen((char *) property) + 1; - - // Add ID (SetProperty = 2, getProperty = 1) - *((uint16_t *) (out.block + out.used)) = (uint16_t) (isSet ? 2 : 1); - out.used += sizeof(uint16_t); - - } - - IPC::Request::~Request() { - - delete[] ((uint8_t *) in.block); - delete[] ((uint8_t *) out.block); - - } - - /// @brief Store value on data block. - IPC::Request::DataBlock * IPC::Request::pushBlock(const void *ptr, size_t length) { - - if((out.used + length + sizeof(IPC::Request::DataBlock)) >= out.length) { - throw std::runtime_error("Too big"); - } - - IPC::Request::DataBlock * rc = (IPC::Request::DataBlock *) (out.block + out.used); - memcpy(((uint8_t *) (rc+1)), ((uint8_t *) ptr), length); - - out.used += (sizeof(IPC::Request::DataBlock) + length); - - return rc; - - } - - /// @brief Get next argument. - IPC::Request::DataBlock * IPC::Request::getNextBlock() const { - - if((in.current + sizeof(IPC::Request::DataBlock)) >= in.used) { - throw std::runtime_error("Out of range"); - } - - return (IPC::Request::DataBlock *) (in.block + in.current); - - } - - IPC::Request & IPC::Request::push(const char *arg) { - pushBlock(arg, strlen(arg)+1)->type = IPC::Request::String; - return *this; - } - - IPC::Request & IPC::Request::push(const bool arg) { - uint8_t value = (uint8_t) (arg ? 0xff : 0); - pushBlock(&value, sizeof(value))->type = IPC::Request::Boolean; - return *this; - } - - IPC::Request & IPC::Request::push(const uint8_t arg) { - pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uchar; - return *this; - } - - IPC::Request & IPC::Request::push(const int32_t arg) { - pushBlock(&arg, sizeof(arg))->type = IPC::Request::Int32; - return *this; - } - - IPC::Request & IPC::Request::push(const uint32_t arg) { - pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uint32; - return *this; - } - - IPC::Request & IPC::Request::pop(std::string &value) { - DataBlock * block = getNextBlock(); - - if(block->type != IPC::Request::String) - throw std::runtime_error("Invalid format"); - - const char *ptr = (const char *) (block+1); - - in.current += (strlen(ptr)+1+sizeof(DataBlock)); - - value.assign(ptr); - - return *this; - } - - IPC::Request & IPC::Request::Request::pop(int &value) { - - DataBlock * block = getNextBlock(); - - switch(block->type) { - case IPC::Request::Int16: - value = * ((int16_t *) (block+1)); - in.current += sizeof(int16_t) + sizeof(DataBlock); - break; - - case IPC::Request::Int32: - value = * ((int32_t *) (block+1)); - in.current += sizeof(int32_t) + sizeof(DataBlock); - break; - - case IPC::Request::Int64: - value = * ((int64_t *) (block+1)); - in.current += sizeof(int64_t) + sizeof(DataBlock); - break; - - default: - throw std::runtime_error("Invalid format"); - } - - return *this; - } - - } - - diff --git a/src/client/src/windows/resources.rc.in b/src/client/src/windows/resources.rc.in deleted file mode 100644 index eac7424..0000000 --- a/src/client/src/windows/resources.rc.in +++ /dev/null @@ -1,29 +0,0 @@ -#include - -VS_VERSION_INFO VERSIONINFO -FILEVERSION @PACKAGE_MAJOR_VERSION@,@PACKAGE_MINOR_VERSION@,@PACKAGE_MAJOR_RELEASE@,0 -PRODUCTVERSION @PACKAGE_MAJOR_VERSION@,@PACKAGE_MINOR_VERSION@,@PACKAGE_MAJOR_RELEASE@,0 - -BEGIN - - BLOCK "StringFileInfo" - BEGIN - BLOCK "080904E4" - BEGIN - VALUE "FileDescription", "3270 C++ Access Library\0" - VALUE "CompanyName", "Banco do Brasil S/A.\0" - VALUE "FileVersion", "@WIN32_VERSION@\0" - VALUE "LegalCopyright", "(C) 2017 Banco do Brasil S/A. All Rights Reserved\0" - VALUE "OriginalFilename", "@PACKAGE_TARNAME@@DLLEXT@\0" - VALUE "ProductName", "@PACKAGE_NAME@\0" - VALUE "ProductVersion", "@PACKAGE_MAJOR_VERSION@.@PACKAGE_MINOR_VERSION@.@PACKAGE_MAJOR_RELEASE@.0\0" - END - END - - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x809, 0x04E4 - END - -END - diff --git a/src/client/src/windows/session.cc b/src/client/src/windows/session.cc deleted file mode 100644 index b4a07f9..0000000 --- a/src/client/src/windows/session.cc +++ /dev/null @@ -1,142 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como - e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -/** - * @file src/lib3270++/ipc/windows/session.cc - * - * @brief Implements Windows session create/destroy session. - * - * @author perry.werneck@gmail.com - * - */ - - #include "../private.h" - #include - #include - #include - - using std::string; - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - namespace TN3270 { - - IPC::Session::Session(const char *id) : Abstract::Session() { - - char *ptr = strchr(id,':'); - - if(!ptr) - throw std::system_error(EINVAL, std::system_category()); - - string pipename{"\\\\.\\pipe\\"}; - - pipename += string(id,ptr - id); - pipename += "\\"; - pipename += (ptr+1); - - std::transform(pipename.begin(), pipename.end(), pipename.begin(), ::tolower); - - debug("pipename: \"%s\"",pipename.c_str()); - - this->hPipe = CreateFile( - TEXT(pipename.c_str()), // pipe name - GENERIC_READ | // read and write access - GENERIC_WRITE, - 0, // no sharing - NULL, // default security attributes - OPEN_EXISTING, // opens existing pipe - 0, // default attributes - NULL // no template file - ); - - if (hPipe == INVALID_HANDLE_VALUE) { - throw std::runtime_error("Can't open IPC Channel"); - } - - // The pipe connected; change to message-read mode. - DWORD dwMode = PIPE_READMODE_MESSAGE; - if(!SetNamedPipeHandleState(hPipe,&dwMode,NULL,NULL)) { - throw std::runtime_error("Can't set IPC Channel mode"); - } - - } - - IPC::Session::~Session() { - CloseHandle(this->hPipe); - } - - - IPC::Request & IPC::Request::call() { - -#ifdef DEBUG - // lib3270_trace_data(NULL,"Request block",(const char *) this->out.block, this->out.used); -#endif // DEBUG - - in.current = 0; - - if(!TransactNamedPipe( - this->hPipe, - this->out.block, - this->out.used, - this->in.block, - this->in.length, - &this->in.used, - NULL) - ) { - - throw std::runtime_error("Can't transact on IPC Channel"); - - } - - debug("Received response \"", in.block, "\" with ", in.used, " bytes"); -#ifdef DEBUG - // lib3270_trace_data(NULL,"Response block",(const char *) this->in.block, this->in.used); -#endif // DEBUG - - // Extract response name - in.current = strlen((const char *) in.block)+1; - - // Extract return code - uint16_t rc = *((uint16_t *) (in.block + in.current)); - in.current += sizeof(uint16_t); - - // Extract argc - uint16_t argc = *((uint16_t *) (in.block + in.current)); - in.current += sizeof(uint16_t); - - debug("Received response \"", ((const char *) in.block), "\" with rc=", rc, " and ", argc, " arguments"); - - return *this; - } - - - - } - - -- libgit2 0.21.2