diff --git a/Makefile.in b/Makefile.in index 4022108..f2dea0b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -120,6 +120,13 @@ $(DESTDIR)$(libdir)/%@DLLEXT@: \ @$(MAKE) DESTDIR=$(DESTDIR) -C src/$(basename $(notdir $@)) install +$(DESTDIR)$(libdir)/%.a: \ + $(DEPENDS) \ + ./src/%/* + + @$(MAKE) DESTDIR=$(DESTDIR) -C src/$(basename $(notdir $@)) $@ + + $(DESTDIR)$(libdir)/$(PACKAGE_TARNAME)-plugins/%@DLLEXT@: \ $(DEPENDS) \ ./src/plugins/%/* @@ -185,6 +192,7 @@ locale/$(PACKAGE_TARNAME).pot: \ install: \ $(DESTDIR)$(libdir)/lib3270@DLLEXT@ \ $(DESTDIR)$(libdir)/$(PACKAGE_TARNAME)@EXEEXT@ \ + $(DESTDIR)$(libdir)/libpw3270cpp.a \ $(foreach PLG, $(PLUGINS), $(DESTDIR)$(libdir)/$(PACKAGE_TARNAME)-plugins/$(PLG)@DLLEXT@) \ locale/$(PACKAGE_TARNAME).pot @@ -255,6 +263,7 @@ $(SRCDIR): \ $(SRCDIR)/ui \ $(SRCDIR)/src/lib3270 \ $(SRCDIR)/src/pw3270 \ + $(SRCDIR)/src/libpw3270cpp \ $(SRCDIR)/sdk \ $(SRCDIR)/src/plugins/dbus3270 diff --git a/configure.ac b/configure.ac index dcc5740..2256072 100644 --- a/configure.ac +++ b/configure.ac @@ -356,6 +356,7 @@ AC_CONFIG_FILES(src/pw3270/v3270/Makefile) AC_CONFIG_FILES(src/pw3270/v3270ft/Makefile) AC_CONFIG_FILES(src/pw3270/uiparser/Makefile) AC_CONFIG_FILES(src/pw3270/common/Makefile) +AC_CONFIG_FILES(src/libpw3270cpp/Makefile) AC_CONFIG_FILES(ui/Makefile) AC_CONFIG_FILES(locale/Makefile) diff --git a/locale/pw3270.pot b/locale/pw3270.pot index 5a189a4..ebc8fb3 100644 --- a/locale/pw3270.pot +++ b/locale/pw3270.pot @@ -9,7 +9,7 @@ msgstr "" "#-#-#-#-# lib3270.pot (PACKAGE VERSION) #-#-#-#-#\n" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-01-19 10:28-0200\n" +"POT-Creation-Date: 2017-01-19 11:07-0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -20,7 +20,7 @@ msgstr "" "#-#-#-#-# pw3270.pot (PACKAGE VERSION) #-#-#-#-#\n" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-01-19 10:28-0200\n" +"POT-Creation-Date: 2017-01-19 11:07-0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -42,7 +42,7 @@ msgstr "" "#-#-#-#-# dbus3270.pot (PACKAGE VERSION) #-#-#-#-#\n" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-01-19 10:28-0200\n" +"POT-Creation-Date: 2017-01-19 11:07-0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/rpm/pw3270.spec b/rpm/pw3270.spec index 5e9c40b..fec4956 100644 --- a/rpm/pw3270.spec +++ b/rpm/pw3270.spec @@ -44,8 +44,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build Requires: lib3270-%{_libvrs} = %{version} Requires: shared-mime-info -Provides: libpw3270 = %{version} -Provides: libpw3270.so = %{version} +Requires: libpw3270-%{MAJOR_VERSION}_%{MINOR_VERSION} #--[ Setup by distribution ]------------------------------------------------------------------------------------------ # @@ -130,6 +129,7 @@ BuildRequires: m4 BuildRequires: pkgconfig BuildRequires: sed BuildRequires: optipng +BuildRequires: fdupes %description Open-source GTK-based IBM 3270 terminal emulator with many advanced features. It can be used to communicate with any IBM host that supports 3270-style connections over TELNET. @@ -153,7 +153,8 @@ This package contains the tn3270 protocol library for %{name} %package -n lib3270-devel Summary: Devel for 3270 Communication library for %{name} Group: Development/Libraries/C and C++ -Requires: lib3270 = %{version} +Provides: lib3270-devel-%{MAJOR_VERSION}_%{MINOR_VERSION} +Requires: lib3270-%{MAJOR_VERSION}_%{MINOR_VERSION} %description -n lib3270-devel Open-source GTK-based IBM 3270 terminal emulator with many advanced features. It can be used to communicate with any IBM host that supports 3270-style connections over TELNET. @@ -162,11 +163,8 @@ This package contains the development files for tn3270 protocol library for %{na %package -n %{name}-devel Summary: Files required for development of %{name} plugins Group: Development/Libraries/C and C++ - -Requires: lib3270-devel = %{version} -Requires: %{name} = %{version} - -Provides: pw3270-devel = %{MAJOR_VERSION}.%{MINOR_VERSION} +Requires: lib3270-devel-%{MAJOR_VERSION}_%{MINOR_VERSION} +Requires: libpw3270-%{MAJOR_VERSION}_%{MINOR_VERSION} %description -n %{name}-devel Open-source GTK-based IBM 3270 terminal emulator with many advanced features. It can be used to communicate with any IBM host that supports 3270-style connections over TELNET. @@ -240,6 +238,8 @@ rm ${RPM_BUILD_ROOT}/%{_datadir}/pw3270/ui/*java*.xml # ooRexx now lives in another package rm ${RPM_BUILD_ROOT}/%{_datadir}/pw3270/ui/*rexx*.xml +%fdupes $RPM_BUILD_ROOT + %clean rm -rf %{buildroot} @@ -265,7 +265,6 @@ rm -rf %{buildroot} %{_datadir}/pw3270/colors.conf %{_datadir}/pw3270/pw3270.png %{_datadir}/pw3270/pw3270-logo.png -%{_datadir}/locale/pt_BR/LC_MESSAGES/pw3270.mo %dir %{_libdir}/pw3270-plugins %files -n lib3270-%{_libvrs} @@ -279,6 +278,7 @@ rm -rf %{buildroot} %{_includedir}/lib3270.h %{_libdir}/pkgconfig/lib3270.pc %{_libdir}/lib3270.so +%{_datadir}/pw3270/locale %files -n %{name}-devel %defattr(-,root,root) @@ -292,9 +292,6 @@ rm -rf %{buildroot} %{_libdir}/libpw3270cpp.a %{_includedir}/pw3270cpp.h -%dir %{_datadir}/pw3270/sample -%{_datadir}/pw3270/sample/* - %if 0%{?_dbus} %files plugin-dbus %defattr(-,root,root) diff --git a/sdk/Makefile.in b/sdk/Makefile.in index c8d4879..32dd0b9 100644 --- a/sdk/Makefile.in +++ b/sdk/Makefile.in @@ -71,14 +71,16 @@ install: \ $(foreach SRC, $(notdir $(wildcard $(BASEDIR)/src/include/lib3270/*.h)), $(DESTDIR)$(includedir)/lib3270/$(SRC)) \ $(foreach SRC, $(notdir $(wildcard $(BASEDIR)/src/include/pw3270/*.h)), $(DESTDIR)$(includedir)/pw3270/$(SRC)) \ $(DESTDIR)$(includedir)/lib3270.h \ - $(DESTDIR)$(includedir)/pw3270.h + $(DESTDIR)$(includedir)/pw3270.h \ + $(DESTDIR)$(includedir)/pw3270cpp.h \ $(SRCDIR)/sdk: \ $(foreach SRC, $(notdir $(wildcard $(BASEDIR)/src/include/lib3270/*.h)), $(SRCDIR)/src/include/lib3270/$(SRC)) \ $(foreach SRC, $(notdir $(wildcard $(BASEDIR)/src/include/pw3270/*.h)), $(SRCDIR)/src/include/pw3270/$(SRC)) \ $(SRCDIR)/src/include/lib3270.h \ - $(SRCDIR)/src/include/pw3270.h + $(SRCDIR)/src/include/pw3270.h \ + $(SRCDIR)/src/include/pw3270cpp.h @$(MKDIR) $@ @$(INSTALL_DATA) *.in $@ diff --git a/src/include/pw3270/class.h b/src/include/pw3270/class.h deleted file mode 100644 index 529eb53..0000000 --- a/src/include/pw3270/class.h +++ /dev/null @@ -1,284 +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 class.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) - * - */ - -#ifndef PW3270_CLASS_H_INCLUDED - - #define PW3270_CLASS_H_INCLUDED 1 - - #ifdef WIN32 - #define SYSTEM_CHARSET "CP1252" - #else - #define SYSTEM_CHARSET "UTF-8" - #endif // WIN32 - - #include - #include - #include - #include - #include - #include - - #ifdef HAVE_ICONV - #include - #endif // HAVE_ICONV - - #include - #include - #include - #include - - #ifdef DEBUG - #include - #define trace( fmt, ... ) fprintf(stderr, "%s(%d) " fmt "\n", __FILE__, __LINE__, __VA_ARGS__ ); fflush(stderr); - #else - #define trace(x, ...) // __VA_ARGS__ - #endif - - #ifndef ETIMEDOUT - #define ETIMEDOUT 1238 - #endif // !ETIMEDOUT - - #define PW3270_NAMESPACE h3270 - - namespace PW3270_NAMESPACE - { - using namespace std; - - class exception : public std::exception - { - public: - exception(int syserror = errno); - exception(const char *fmt, ...); - -#ifdef WIN32 - exception(DWORD error, const char *fmt, ...); -#else - exception(int error, const char *fmt, ...); -#endif // WIN32 - - virtual const char * what() const throw(); - - private: - char msg[4096]; - - }; - - class module - { - private: -#ifdef WIN32 - HMODULE hModule; - int get_datadir(LPSTR datadir); -#else - void * hModule; - -#endif // WIN32 - - public: - module(const char *name, const char *version = NULL) throw (std::exception); - ~module(); - - void * get_symbol(const char *name); - - }; - - class session - { - public: - - virtual ~session(); - - // Internal methods, used to init/deinit control tables. - static void init(); - static void deinit(); - - // Factory methods and settings - static session * start(const char *name = 0); - static session * create(const char *name = 0) throw (std::exception); - static session * create_local(H3270 *hSession) throw (std::exception); - static session * create_local() throw (std::exception); - - static session * get_default(void); - static bool has_default(void); - static void set_plugin(session * (*factory)(const char *name)); - - // Log management - void log(const char *fmt, ...); - void logva(const char *fmt, va_list args); - - // Information - virtual const string get_version(void); - virtual const string get_revision(void); - - virtual bool is_connected(void) = 0; - virtual bool is_ready(void) = 0; - - virtual LIB3270_CSTATE get_cstate(void) = 0; - virtual LIB3270_MESSAGE get_program_message(void) = 0; - virtual LIB3270_SSL_STATE get_secure(void) = 0; - - virtual int get_width(void) = 0; - virtual int get_height(void) = 0; - virtual int get_length(void) = 0; - - // Misc - virtual void set_unlock_delay(unsigned short ms) = 0; - - // charset -#ifdef WIN32 - void set_display_charset(const char *remote = 0, const char *local = "CP1252"); - static string win32_strerror(int e); -#else - void set_display_charset(const char *remote = 0, const char *local = "UTF-8"); -#endif // WIN32 - - virtual int set_host_charset(const char *charset) = 0; - virtual string get_host_charset(void) = 0; - virtual string get_display_charset(void); - - // Connection & Network - int connect(const char *host, time_t wait = 0); - int set_host(const char *host); - virtual int connect(void) = 0; - - virtual int set_url(const char *hostname) = 0; - virtual string get_url() = 0; - - virtual int disconnect(void) = 0; - virtual int wait_for_ready(int seconds) = 0; - virtual int wait(int seconds) = 0; - virtual int iterate(bool wait = true) = 0; - - // Ascii<->EBCDIC translation - virtual const char * asc2ebc(unsigned char *str, int sz = -1) = 0; - virtual const char * ebc2asc(unsigned char *str, int sz = -1) = 0; - string asc2ebc(string &str); - string ebc2asc(string &str); - - // Get/Set/Text with charset translation - string get_string(int baddr = 0, size_t len = -1); - string get_string_at(int row, int col, size_t sz); - int set_string_at(int row, int col, const char *str); - int cmp_string_at(int row, int col, const char *text); - int wait_for_string_at(int row, int col, const char *key, int timeout); - int input_string(const char *str); - - inline operator string() { - return get_string(); - } - - // Cursor management - virtual int set_cursor_position(int row, int col) = 0; - virtual int set_cursor_addr(int addr) = 0; - virtual int get_cursor_addr(void) = 0; - - // Toggle management - virtual int set_toggle(LIB3270_TOGGLE ix, bool value) = 0; - - // Keyboard actions - virtual int enter(void) = 0; - virtual int pfkey(int key) = 0; - virtual int pakey(int key) = 0; - - // Actions - virtual int quit(void) = 0; - virtual int action(const char *name) = 0; - - int erase(int mode); - - virtual int erase(void) = 0; - virtual int erase_eof(void) = 0; - virtual int erase_eol(void) = 0; - virtual int erase_input(void) = 0; - - virtual int print(void) = 0; - - // Field management - virtual int get_field_start(int baddr = -1) = 0; - virtual int get_field_len(int baddr = -1) = 0; - virtual int get_next_unprotected(int baddr = -1) = 0; - - virtual int get_is_protected(int baddr = -1) = 0; - virtual int get_is_protected_at(int row, int col) = 0; - - // Clipboard management - virtual int set_copy(const char *text); - virtual string get_copy(void); - - virtual string get_clipboard(void); - virtual int set_clipboard(const char *text); - - // Dialogs - virtual int popup_dialog(LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, ...); - virtual string file_chooser_dialog(int action, const char *title, const char *extension, const char *filename); - - // File transfer - virtual int file_transfer(LIB3270_FT_OPTION options, const char *local, const char *remote, int lrecl = 0, int blksize = 0, int primspace = 0, int secspace = 0, int dft = 4096); - - // Charset translation - const char * get_encoding(void); - - string get_3270_text(const char *str); - string get_local_text(const char *str); - - protected: - session(); - - // Get/Set/Test without charset translation - virtual string get_text(int baddr = 0, size_t len = 1) = 0; - virtual string get_text_at(int row, int col, size_t sz) = 0; - virtual int set_text_at(int row, int col, const char *str) = 0; - virtual int cmp_text_at(int row, int col, const char *text) = 0; - virtual int wait_for_text_at(int row, int col, const char *key, int timeout); - virtual int emulate_input(const char *str) = 0; - - private: - - session * prev; - session * next; - - static session * first; - static session * last; - - static session * (*factory)(const char *name); - - static session * create_remote(const char *name) throw (std::exception); - -#ifdef HAVE_ICONV - iconv_t conv2Local; - iconv_t conv2Host; -#endif - - }; - - - } - - -#endif // PW3270_CLASS_H_INCLUDED diff --git a/src/include/pw3270cpp.h b/src/include/pw3270cpp.h new file mode 100644 index 0000000..ea0f6ba --- /dev/null +++ b/src/include/pw3270cpp.h @@ -0,0 +1,301 @@ +/* + * "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 class.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) + * + */ + +#ifndef PW3270_CLASS_H_INCLUDED + + #define PW3270_CLASS_H_INCLUDED 1 + + #ifdef WIN32 + #define SYSTEM_CHARSET "CP1252" + #else + #define SYSTEM_CHARSET "UTF-8" + #endif // WIN32 + + #include + #include + #include + #include + #include + #include + + #ifdef HAVE_ICONV + #include + #endif // HAVE_ICONV + + #include + #include + #include + #include + + #ifdef DEBUG + #include + #define trace( fmt, ... ) fprintf(stderr, "%s(%d) " fmt "\n", __FILE__, __LINE__, __VA_ARGS__ ); fflush(stderr); + #else + #define trace(x, ...) // __VA_ARGS__ + #endif + + #ifndef ETIMEDOUT + #define ETIMEDOUT 1238 + #endif // !ETIMEDOUT + +/** + * @brief Obtém nome de variável como string. + * + */ + #define STRINGIZE(x) #x + +/** + * @brief Converte valor passado ao gcc via linha de comando em string. + * + * Macro usada para converter valores passados ao gcc via definições de + * linha de comando em uma string. Geralmente usado para converter os + * nomes de diretórios ajustados pelo ./configure. + * + * + */ + #define STRINGIZE_VALUE_OF(x) STRINGIZE(x) + + #define PW3270_NAMESPACE h3270 + + namespace PW3270_NAMESPACE + { + using namespace std; + + class exception : public std::exception + { + public: + exception(int syserror = errno); + exception(const char *fmt, ...); + +#ifdef WIN32 + exception(DWORD error, const char *fmt, ...); +#else + exception(int error, const char *fmt, ...); +#endif // WIN32 + + virtual const char * what() const throw(); + + private: + char msg[4096]; + + }; + + class module + { + private: +#ifdef WIN32 + HMODULE hModule; + int get_datadir(LPSTR datadir); +#else + void * hModule; + +#endif // WIN32 + + public: + module(const char *name, const char *version = NULL) throw (std::exception); + ~module(); + + void * get_symbol(const char *name); + + }; + + class session + { + public: + + virtual ~session(); + + // Internal methods, used to init/deinit control tables. + static void init(); + static void deinit(); + + // Factory methods and settings + static session * start(const char *name = 0); + static session * create(const char *name = 0) throw (std::exception); + static session * create_local(H3270 *hSession) throw (std::exception); + static session * create_local() throw (std::exception); + + static session * get_default(void); + static bool has_default(void); + static void set_plugin(session * (*factory)(const char *name)); + + // Log management + void log(const char *fmt, ...); + void logva(const char *fmt, va_list args); + + // Information + virtual const string get_version(void); + virtual const string get_revision(void); + + virtual bool is_connected(void) = 0; + virtual bool is_ready(void) = 0; + + virtual LIB3270_CSTATE get_cstate(void) = 0; + virtual LIB3270_MESSAGE get_program_message(void) = 0; + virtual LIB3270_SSL_STATE get_secure(void) = 0; + + virtual int get_width(void) = 0; + virtual int get_height(void) = 0; + virtual int get_length(void) = 0; + + // Misc + virtual void set_unlock_delay(unsigned short ms) = 0; + + // charset +#ifdef WIN32 + void set_display_charset(const char *remote = 0, const char *local = "CP1252"); + static string win32_strerror(int e); +#else + void set_display_charset(const char *remote = 0, const char *local = "UTF-8"); +#endif // WIN32 + + virtual int set_host_charset(const char *charset) = 0; + virtual string get_host_charset(void) = 0; + virtual string get_display_charset(void); + + // Connection & Network + int connect(const char *host, time_t wait = 0); + int set_host(const char *host); + virtual int connect(void) = 0; + + virtual int set_url(const char *hostname) = 0; + virtual string get_url() = 0; + + virtual int disconnect(void) = 0; + virtual int wait_for_ready(int seconds) = 0; + virtual int wait(int seconds) = 0; + virtual int iterate(bool wait = true) = 0; + + // Ascii<->EBCDIC translation + virtual const char * asc2ebc(unsigned char *str, int sz = -1) = 0; + virtual const char * ebc2asc(unsigned char *str, int sz = -1) = 0; + string asc2ebc(string &str); + string ebc2asc(string &str); + + // Get/Set/Text with charset translation + string get_string(int baddr = 0, size_t len = -1); + string get_string_at(int row, int col, size_t sz); + int set_string_at(int row, int col, const char *str); + int cmp_string_at(int row, int col, const char *text); + int wait_for_string_at(int row, int col, const char *key, int timeout); + int input_string(const char *str); + + inline operator string() { + return get_string(); + } + + // Cursor management + virtual int set_cursor_position(int row, int col) = 0; + virtual int set_cursor_addr(int addr) = 0; + virtual int get_cursor_addr(void) = 0; + + // Toggle management + virtual int set_toggle(LIB3270_TOGGLE ix, bool value) = 0; + + // Keyboard actions + virtual int enter(void) = 0; + virtual int pfkey(int key) = 0; + virtual int pakey(int key) = 0; + + // Actions + virtual int quit(void) = 0; + virtual int action(const char *name) = 0; + + int erase(int mode); + + virtual int erase(void) = 0; + virtual int erase_eof(void) = 0; + virtual int erase_eol(void) = 0; + virtual int erase_input(void) = 0; + + virtual int print(void) = 0; + + // Field management + virtual int get_field_start(int baddr = -1) = 0; + virtual int get_field_len(int baddr = -1) = 0; + virtual int get_next_unprotected(int baddr = -1) = 0; + + virtual int get_is_protected(int baddr = -1) = 0; + virtual int get_is_protected_at(int row, int col) = 0; + + // Clipboard management + virtual int set_copy(const char *text); + virtual string get_copy(void); + + virtual string get_clipboard(void); + virtual int set_clipboard(const char *text); + + // Dialogs + virtual int popup_dialog(LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, ...); + virtual string file_chooser_dialog(int action, const char *title, const char *extension, const char *filename); + + // File transfer + virtual int file_transfer(LIB3270_FT_OPTION options, const char *local, const char *remote, int lrecl = 0, int blksize = 0, int primspace = 0, int secspace = 0, int dft = 4096); + + // Charset translation + const char * get_encoding(void); + + string get_3270_text(const char *str); + string get_local_text(const char *str); + + protected: + session(); + + // Get/Set/Test without charset translation + virtual string get_text(int baddr = 0, size_t len = 1) = 0; + virtual string get_text_at(int row, int col, size_t sz) = 0; + virtual int set_text_at(int row, int col, const char *str) = 0; + virtual int cmp_text_at(int row, int col, const char *text) = 0; + virtual int wait_for_text_at(int row, int col, const char *key, int timeout); + virtual int emulate_input(const char *str) = 0; + + private: + + session * prev; + session * next; + + static session * first; + static session * last; + + static session * (*factory)(const char *name); + + static session * create_remote(const char *name) throw (std::exception); + +#ifdef HAVE_ICONV + iconv_t conv2Local; + iconv_t conv2Host; +#endif + + }; + + + } + + +#endif // PW3270_CLASS_H_INCLUDED diff --git a/src/libpw3270cpp/Makefile.in b/src/libpw3270cpp/Makefile.in new file mode 100644 index 0000000..0d6aedc --- /dev/null +++ b/src/libpw3270cpp/Makefile.in @@ -0,0 +1,172 @@ +# +# "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., 59 Temple +# Place, Suite 330, Boston, MA, 02111-1307, USA +# +# Contatos: +# +# perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) +# erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça) +# + +MODULE_NAME=libpw3270cpp + +SOURCES=session.cc exception.cc local.cc remote.cc module.cc + +#---[ Configuration values ]------------------------------------------------------------- + +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +sbindir=@sbindir@ +libdir=@libdir@ + +BASEDIR=@BASEDIR@ +SRCDIR=$(BASEDIR)/.src/$(PACKAGE_TARNAME)-$(PACKAGE_VERSION)/src/$(MODULE_NAME) +POTDIR=$(BASEDIR)/.pot/$(PACKAGE_TARNAME)/$(MODULE_NAME) + +OBJDIR=.obj +OBJDBG=$(OBJDIR)/Debug +OBJRLS=$(OBJDIR)/Release + +MKDIR=@MKDIR_P@ +CC=@CXX@ +AR=@AR@ +XGETTEXT=@XGETTEXT@ +MSGCAT=@MSGCAT@ +INSTALL=@INSTALL@ +INSTALL_DATA=@INSTALL_DATA@ +INSTALL_PROGRAM=@INSTALL_PROGRAM@ + +CFLAGS=@CFLAGS@ @LIB3270_CFLAGS@ -Wno-deprecated-declarations @GTK_CFLAGS@ -I$(BASEDIR)/src/include/pw3270 + +#---[ Rules ]---------------------------------------------------------------------------- + +DEPENDS=$(BASEDIR)/src/include/*.h $(BASEDIR)/src/include/lib3270/*.h $(BASEDIR)/src/include/pw3270/*.h *.h Makefile + +$(OBJDBG)/%.o: \ + %.cc \ + $(DEPENDS) + + @echo $< ... + @$(MKDIR) `dirname $@` + @$(CC) $(CFLAGS) \ + @DBG_CFLAGS@ \ + -DBUILD_DATE=`date +"0x%Y%m%d"`\ + -o $@ -c $< + +$(OBJRLS)/%.o: \ + %.cc \ + $(DEPENDS) + + @echo $< ... + @$(MKDIR) `dirname $@` + @$(CC) $(CFLAGS) \ + @RLS_CFLAGS@ \ + -DBUILD_DATE=`date +"0x%Y%m%d"` \ + -o $@ -c $< + +$(POTDIR)/%.pot: %.c + + @echo $(notdir $@) ... + @$(MKDIR) `dirname $@` + @$(XGETTEXT) \ + --default-domain=$(PACKAGE) \ + --language=C \ + --keyword=_ \ + --keyword=N_ \ + --keyword=MSG_:2 \ + --output=$@ \ + $< + + @touch $@ + +#---[ Release Targets ]------------------------------------------------------------------ + +Release: \ + $(BASEDIR)/.obj/Release/$(MODULE_NAME).a + +install: \ + $(DESTDIR)$(libdir)/$(MODULE_NAME).a + +$(DESTDIR)$(libdir)/$(MODULE_NAME).a: \ + $(BASEDIR)/.obj/Release/$(MODULE_NAME).a + + @echo $@ ... + @$(MKDIR) `dirname $@` + @$(INSTALL_PROGRAM) $^ $@ + +$(BASEDIR)/.obj/Release/$(MODULE_NAME).a: \ + $(foreach SRC, $(basename $(SOURCES)), $(OBJRLS)/$(SRC).o) + + @echo $@ ... + @$(MKDIR) `dirname $@` + @$(AR) rcs $@ $^ + +pot: \ + $(BASEDIR)/.pot/$(PACKAGE_TARNAME)/$(MODULE_NAME).pot + +$(BASEDIR)/.pot/$(PACKAGE_TARNAME)/$(MODULE_NAME).pot: \ + $(foreach SRC, $(basename $(SOURCES)), $(POTDIR)/$(SRC).pot) + + @rm -f $@ + @mkdir -p `dirname $@` + @$(MSGCAT) --sort-output $^ > $@ + +$(SRCDIR): \ + clean + + @$(MKDIR) $@ + @$(INSTALL_DATA) *.cc *.h *.in *.cbp $@ + + +#---[ Debug Targets ]-------------------------------------------------------------------- + +Debug: \ + $(BASEDIR)/.obj/Debug/$(MODULE_NAME).a + +$(BASEDIR)/.obj/Debug/$(MODULE_NAME).a: \ + $(foreach SRC, $(basename $(SOURCES)), $(OBJDBG)/$(SRC).o) + + @echo $@ ... + @$(MKDIR) `dirname $@` + @$(AR) rcs $@ $^ + +#---[ Clean Targets]--------------------------------------------------------------------- + +cleanDebug: + + @rm -fr $(BASEDIR)/.obj/Debug/$(MODULE_NAME).a \ + $(OBJDBG) + +cleanRelease: + + @rm -fr $(BASEDIR)/.obj/Release/$(MODULE_NAME).a \ + $(OBJRLS) + + @rm -fr $(POTDIR) + +clean: \ + cleanDebug \ + cleanRelease + + diff --git a/src/libpw3270cpp/classlib.cbp b/src/libpw3270cpp/classlib.cbp new file mode 100644 index 0000000..81afaff --- /dev/null +++ b/src/libpw3270cpp/classlib.cbp @@ -0,0 +1,50 @@ + + + + + + diff --git a/src/libpw3270cpp/exception.cc b/src/libpw3270cpp/exception.cc new file mode 100644 index 0000000..2741350 --- /dev/null +++ b/src/libpw3270cpp/exception.cc @@ -0,0 +1,100 @@ +/* + * "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 exception.cc e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + #include + #include + + #include + +/*--[ Implement ]--------------------------------------------------------------------------------------------------*/ + + namespace PW3270_NAMESPACE + { + + exception::exception(int syscode) + { + snprintf(this->msg,4095,"%s",strerror(syscode)); + } + + exception::exception(const char *fmt, ...) + { + va_list arg_ptr; + va_start(arg_ptr, fmt); + vsnprintf(this->msg,4095,fmt,arg_ptr); + va_end(arg_ptr); + } + +#ifdef WIN32 + exception::exception(DWORD error, const char *fmt, ...) + { + LPVOID lpMsgBuf = 0; + char * ptr; + size_t szPrefix; + + va_list arg_ptr; + va_start(arg_ptr, fmt); + vsnprintf(this->msg,4095,fmt,arg_ptr); + va_end(arg_ptr); + + szPrefix = strlen(this->msg); + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); + + for(ptr= (char *) lpMsgBuf;*ptr && *ptr != '\n';ptr++); + *ptr = 0; + + snprintf(this->msg+szPrefix,4095-szPrefix,": %s (rc=%d)",(char *) lpMsgBuf,(int) error); + + LocalFree(lpMsgBuf); + + } +#else + exception::exception(int error, const char *fmt, ...) + { + size_t szPrefix; + + va_list arg_ptr; + va_start(arg_ptr, fmt); + vsnprintf(this->msg,4095,fmt,arg_ptr); + va_end(arg_ptr); + + szPrefix = strlen(this->msg); + + snprintf(this->msg+szPrefix,4095-szPrefix,": %s (rc=%d)",strerror(error),(int) error); + + } +#endif // WIN32 + + const char * exception::what() const throw() + { + return this->msg; + } + + } diff --git a/src/libpw3270cpp/local.cc b/src/libpw3270cpp/local.cc new file mode 100644 index 0000000..8eb78ad --- /dev/null +++ b/src/libpw3270cpp/local.cc @@ -0,0 +1,599 @@ +/* + * "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 local.cc e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +#if defined WIN32 + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx + #ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS + #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 + #endif // LOAD_LIBRARY_SEARCH_DEFAULT_DIRS + + #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR + #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 + #endif // LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR + + #include + +#else + + #include + +#endif + +#include "private.h" + +#include +#include +#include +#include + +#ifdef HAVE_SYSLOG + #include + #include +#endif // HAVE_SYSLOG + +/*--[ Implement ]--------------------------------------------------------------------------------------------------*/ + + extern "C" + { + static void loghandler(H3270 *session, const char *module, int rc, const char *fmt, va_list args) + { + #ifdef HAVE_SYSLOG + openlog(PACKAGE_NAME, LOG_NDELAY, LOG_USER); + vsyslog(LOG_INFO,fmt,args); + closelog(); + #endif // HAVE_SYSLOG + } + + static void tracehandler(H3270 *session, const char *fmt, va_list args) + { + #ifdef HAVE_SYSLOG + + #define MAX_LOG_LENGTH 200 + + static char line[MAX_LOG_LENGTH+1]; + char temp[MAX_LOG_LENGTH]; + char * ptr; + size_t len = strlen(line); + + vsnprintf(temp,MAX_LOG_LENGTH-len,fmt,args); + + ptr = strchr(temp,'\n'); + if(!ptr) + { + strncat(line,temp,MAX_LOG_LENGTH); + if(strlen(line) >= MAX_LOG_LENGTH) + { + openlog(PACKAGE_NAME, LOG_NDELAY, LOG_USER); + syslog(LOG_INFO,"%s",line); + closelog(); + *line = 0; + } + return; + } + + *ptr = 0; + strncat(line,temp,MAX_LOG_LENGTH); + + openlog(PACKAGE_NAME, LOG_NDELAY, LOG_USER); + syslog(LOG_DEBUG,"%s",line); + closelog(); + + strncpy(line,ptr+1,MAX_LOG_LENGTH); + + #endif // HAVE_SYSLOG + } + + } + + namespace PW3270_NAMESPACE + { + + class local : public session, protected module, protected recursive_mutex + { + private: + + // Lib3270 entry points + const char * (*_get_version)(void); + LIB3270_CSTATE (*_get_connection_state)(H3270 *h); + LIB3270_MESSAGE (*_get_program_message)(H3270 *h); + LIB3270_SSL_STATE (*_get_secure)(H3270 *h); + + + int (*_disconnect)(H3270 *h); + int (*_connect)(H3270 *h,int wait); + const char (*_set_url)(H3270 *h, const char *n); + const char * (*_get_url)(H3270 *h, char *str, int len); + int (*_is_connected)(H3270 *h); + void (*_main_iterate)(H3270 *h, int wait); + int (*_wait)(H3270 *hSession, int seconds); + int (*_enter)(H3270 *hSession); + int (*_pfkey)(H3270 *hSession, int key); + int (*_pakey)(H3270 *hSession, int key); + int (*_wait_for_ready)(H3270 *hSession, int seconds); + char * (*_get_text)(H3270 *h, int offset, int len); + char * (*_get_text_at)(H3270 *h, int row, int col, int len); + int (*_cmp_text_at)(H3270 *h, int row, int col, const char *text); + int (*_set_text_at)(H3270 *h, int row, int col, const unsigned char *str); + int (*_is_ready)(H3270 *h); + int (*_set_cursor_position)(H3270 *h, int row, int col); + int (*_set_toggle)(H3270 *h, LIB3270_TOGGLE ix, int value); + int (*_get_field_start)(H3270 *h, int baddr); + int (*_get_field_len)(H3270 *h, int baddr); + int (*_set_cursor_addr)(H3270 *h, int addr); + int (*_get_cursor_addr)(H3270 *h); + int (*_emulate_input)(H3270 *session, const char *s, int len, int pasting); + int (*_get_next_unprotected)(H3270 *hSession, int baddr0); + int (*_get_is_protected)(H3270 *hSession, int baddr); + int (*_get_is_protected_at)(H3270 *hSession, int row, int col); + void (*_popup_va)(H3270 *session, LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, va_list); + void * (*_free)(void *); + const char * (*_get_display_charset)(H3270 *hSession); + int (*_set_host_charset)(H3270 *hSession, const char *name); + const char * (*_get_host_charset)(H3270 *hSession); + int (*_print)(H3270 *hSession); + int (*_erase)(H3270 *hSession); + int (*_erase_eof)(H3270 *hSession); + int (*_erase_eol)(H3270 *hSession); + int (*_erase_input)(H3270 *hSession); + int (*_action)(H3270 *hSession, const char *name); + int (*_set_unlock_delay)(H3270 *hSession, unsigned short ms); + + int (*_get_width)(H3270 *hSession); + int (*_get_height)(H3270 *hSession); + int (*_get_length)(H3270 *hSession); + + const char * (*_ebc2asc)(H3270 *hSession, unsigned char *buffer, int sz); + const char * (*_asc2ebc)(H3270 *hSession, unsigned char *buffer, int sz); + + protected: + + H3270 * hSession; + + void load_methods() { + + void (*set_log_handler)(void (*loghandler)(H3270 *, const char *, int, const char *, va_list)); + void (*set_trace_handler)( void (*handler)(H3270 *session, const char *fmt, va_list args) ); + + struct _call + { + void **entry; + const char * name; + } call[] = + { + { (void **) & set_log_handler, "lib3270_set_log_handler" }, + { (void **) & set_trace_handler, "lib3270_set_trace_handler" }, + + { (void **) & _is_connected, "lib3270_is_connected" }, + { (void **) & _get_connection_state, "lib3270_get_connection_state" }, + { (void **) & _get_program_message, "lib3270_get_program_message" }, + { (void **) & _get_secure, "lib3270_get_secure" }, + + { (void **) & _get_version, "lib3270_get_version" }, + { (void **) & _disconnect, "lib3270_disconnect" }, + { (void **) & _connect, "lib3270_connect" }, + { (void **) & _set_url, "lib3270_set_url" }, + { (void **) & _get_url, "lib3270_get_url" }, + { (void **) & _main_iterate, "lib3270_main_iterate" }, + { (void **) & _wait, "lib3270_wait" }, + { (void **) & _enter, "lib3270_enter" }, + { (void **) & _pfkey, "lib3270_pfkey" }, + { (void **) & _pakey, "lib3270_pakey" }, + { (void **) & _wait_for_ready, "lib3270_wait_for_ready" }, + { (void **) & _get_text, "lib3270_get_text" }, + { (void **) & _get_text_at, "lib3270_get_text_at" }, + { (void **) & _cmp_text_at, "lib3270_cmp_text_at" }, + { (void **) & _set_text_at, "lib3270_set_string_at" }, + { (void **) & _is_ready, "lib3270_is_ready" }, + { (void **) & _set_cursor_position, "lib3270_set_cursor_position" }, + { (void **) & _set_toggle, "lib3270_set_toggle" }, + { (void **) & _get_field_start, "lib3270_get_field_start" }, + { (void **) & _get_field_len, "lib3270_get_field_len" }, + { (void **) & _set_cursor_addr, "lib3270_set_cursor_address" }, + { (void **) & _get_cursor_addr, "lib3270_get_cursor_address" }, + { (void **) & _emulate_input, "lib3270_emulate_input" }, + { (void **) & _get_next_unprotected, "lib3270_get_next_unprotected" }, + { (void **) & _get_is_protected, "lib3270_get_is_protected" }, + { (void **) & _get_is_protected_at, "lib3270_get_is_protected_at" }, + { (void **) & _popup_va, "lib3270_popup_va" }, + { (void **) & _free, "lib3270_free" }, + { (void **) & _get_display_charset, "lib3270_get_display_charset" }, + { (void **) & _set_host_charset, "lib3270_set_host_charset" }, + { (void **) & _get_host_charset, "lib3270_get_host_charset" }, + + { (void **) & _erase, "lib3270_erase" }, + { (void **) & _erase_eof, "lib3270_eraseeof" }, + { (void **) & _erase_eol, "lib3270_eraseeol" }, + { (void **) & _erase_input, "lib3270_eraseinput" }, + + { (void **) & _print, "lib3270_print" }, + { (void **) & _ebc2asc, "lib3270_ebc2asc" }, + { (void **) & _asc2ebc, "lib3270_asc2ebc" }, + + { (void **) & _action, "lib3270_action" }, + { (void **) & _set_unlock_delay, "lib3270_set_unlock_delay" }, + + { (void **) & _get_width, "lib3270_get_width" }, + { (void **) & _get_height, "lib3270_get_height" }, + { (void **) & _get_length, "lib3270_get_length" }, + + }; + + for(unsigned int f = 0; f < (sizeof (call) / sizeof ((call)[0]));f++) + { + *call[f].entry = (void *) get_symbol(call[f].name); + if(!*call[f].entry) + throw exception("Can't find symbol %s",call[f].name); + } + + // Get Session handle, setup base callbacks + set_log_handler(loghandler); + set_trace_handler(tracehandler); + + set_display_charset(); + + } + + public: + + local() throw(std::exception) : module("lib3270",PACKAGE_VERSION) + { + } + + virtual ~local() + { + } + + bool is_connected(void) + { + return _is_connected(hSession); + } + + LIB3270_CSTATE get_cstate(void) + { + return _get_connection_state(hSession); + } + + LIB3270_MESSAGE get_program_message(void) { + return _get_program_message(hSession); + } + + LIB3270_SSL_STATE get_secure(void) { + return _get_secure(hSession); + }; + + int connect(void) + { + this->lock(); + int rc = _connect(hSession,0); + this->unlock(); + + return rc; + } + + int set_url(const char *uri) + { + return (_set_url(hSession,uri) == 0); + } + + string get_url() + { + char buffer[1024]; + return string(_get_url(hSession,buffer,sizeof(buffer))); + } + + int disconnect(void) + { + this->lock(); + int rc = _disconnect(hSession); + this->unlock(); + + return rc; + } + + bool is_ready(void) + { + return _is_ready(hSession) != 0; + } + + int wait_for_ready(int seconds) + { + return _wait_for_ready(hSession,seconds); + } + + int wait(int seconds) + { + return _wait(hSession,seconds); + } + + int iterate(bool wait) + { + this->lock(); + _main_iterate(hSession,wait); + this->unlock(); + return 0; + } + + string get_text_at(int row, int col, size_t sz) + { + string rc; + char * ptr = _get_text_at(hSession,row,col,sz); + + if(ptr) + { + rc.assign(ptr); + _free(ptr); + } + + return rc; + } + + int set_text_at(int row, int col, const char *str) + { + return _set_text_at(hSession,row,col,(const unsigned char *) str); + } + + int cmp_text_at(int row, int col, const char *text) + { + return _cmp_text_at(hSession,row,col,text); + } + + string get_text(int offset, size_t len) + { + string rc; + char * ptr = _get_text(hSession,offset,len); + + if(ptr) + { + rc.assign(ptr); + _free(ptr); + } + + return rc; + } + + int set_cursor_position(int row, int col) + { + return _set_cursor_position(hSession,row,col); + } + + int set_cursor_addr(int addr) + { + return _set_cursor_addr(hSession,addr); + } + + int get_cursor_addr(void) + { + return _get_cursor_addr(hSession); + } + + int enter(void) + { + return _enter(hSession); + } + + int pfkey(int key) + { + return _pfkey(hSession,key); + } + + int pakey(int key) + { + return _pakey(hSession,key); + } + + int quit(void) + { + return EINVAL; + } + + int set_toggle(LIB3270_TOGGLE ix, bool value) + { + return _set_toggle(hSession, ix, (int) value); + } + + int emulate_input(const char *str) + { + return _emulate_input(hSession,str,-1,1); + } + + int get_field_start(int baddr) + { + return _get_field_start(hSession,baddr); + } + + int get_field_len(int baddr) + { + return _get_field_len(hSession,baddr); + } + + int get_next_unprotected(int baddr) + { + return _get_next_unprotected(hSession,baddr); + } + + int get_is_protected(int baddr) + { + return _get_is_protected(hSession,baddr); + } + + int get_is_protected_at(int row, int col) + { + return _get_is_protected_at(hSession,row,col); + } + + int popup_dialog(LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, ...) + { + va_list args; + va_start(args, fmt); + _popup_va(hSession, id, title, message, fmt, args); + va_end(args); + return 0; + } + + string get_display_charset(void) + { + return string(_get_display_charset(hSession)); + } + + int set_host_charset(const char *charset) + { + return _set_host_charset(hSession,charset); + } + + string get_host_charset(void) + { + return string(_get_host_charset(hSession)); + } + + int erase(void) + { + return _erase(hSession); + } + + int erase_eof(void) + { + return _erase_eof(hSession); + } + + int erase_eol(void) + { + return _erase_eol(hSession); + } + + int erase_input(void) + { + return _erase_input(hSession); + } + + int print(void) + { + return _print(hSession); + } + + + const char * asc2ebc(unsigned char *str, int sz) + { + return _asc2ebc(hSession,str,sz); + } + + const char * ebc2asc(unsigned char *str, int sz) + { + return _ebc2asc(hSession,str,sz); + } + + int action(const char *name) + { + return _action(hSession,name); + } + + void set_unlock_delay(unsigned short ms) + { + _set_unlock_delay(hSession,ms); + } + + int get_width(void) { + return _get_width(hSession); + } + + int get_height(void) { + return _get_height(hSession); + } + + int get_length(void) { + return _get_length(hSession); + } + + }; + + session * session::create_local(void) throw (std::exception) + { + class obj : public local { + public: + obj() : local() { + + H3270 * (*lib3270_new)(const char *) = (H3270 * (*)(const char *)) get_symbol("lib3270_session_new"); + + if(!lib3270_new) + throw exception("Can't find symbol %s","lib3270_session_new"); + + this->hSession = lib3270_new(""); + + load_methods(); + + } + + virtual ~obj() { + + this->lock(); + + if(is_connected()) { + disconnect(); + } + + try + { + static void (*session_free)(H3270 *h) = (void (*)(H3270 *)) get_symbol("lib3270_session_free"); + + if(session_free && this->hSession) + session_free(this->hSession); + + this->hSession = 0; + + } + catch(exception e) { } + + this->unlock(); + + } + }; + + return new obj(); + } + + session * session::create_local(H3270 *hSession) throw (std::exception) + { + class obj : public local { + public: + obj(H3270 *hSession) : local() + { + this->hSession = hSession; + load_methods(); + } + + virtual ~obj() { + } + + }; + + return new obj(hSession); + } + + } + diff --git a/src/libpw3270cpp/module.cc b/src/libpw3270cpp/module.cc new file mode 100644 index 0000000..1d6e982 --- /dev/null +++ b/src/libpw3270cpp/module.cc @@ -0,0 +1,217 @@ +/* + * "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 module.cc e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +#if defined WIN32 + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx + #ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS + #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 + #endif // LOAD_LIBRARY_SEARCH_DEFAULT_DIRS + + #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR + #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 + #endif // LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR + + #include + +#else + + #include + +#endif + +#include + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + +namespace PW3270_NAMESPACE +{ + +#ifdef WIN32 + int module::get_datadir(LPSTR datadir) + { + HKEY hKey = 0; + unsigned long datalen = strlen(datadir); + + *datadir = 0; + + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\pw3270",0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) + { + unsigned long datatype; // #defined in winnt.h (predefined types 0-11) + if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) datadir,&datalen) != ERROR_SUCCESS) + *datadir = 0; + RegCloseKey(hKey); + } + + return *datadir; + } +#endif // WIN32 + + module::module(const char *name, const char *version) throw (std::exception) + { + string dllname = name; + +#ifdef WIN32 + + dllname += ".dll"; + if(version) + { + dllname += "."; + dllname += version; + } + + HMODULE kernel; + HANDLE cookie = NULL; + DWORD rc; + HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory); + BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie); + UINT errorMode; + char datadir[4096]; + char buffer[4096]; + + kernel = LoadLibrary("kernel32.dll"); + AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory"); + RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory"); + + // Notify user in case of error loading protocol DLL + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx + errorMode = SetErrorMode(1); + + memset(datadir,' ',4095); + datadir[4095] = 0; + + if(get_datadir(datadir)) + { + trace("Datadir=[%s] AddDllDirectory=%p RemoveDllDirectory=%p\n",datadir,AddDllDirectory,RemoveDllDirectory); + + if(AddDllDirectory) + { + wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t)); + mbstowcs(path, datadir, 4095); + cookie = AddDllDirectory(path); + free(path); + } + +#ifdef DEBUG + snprintf(buffer,4096,"%s\\.bin\\Debug\\%s",datadir,dllname.c_str()); +#else + snprintf(buffer,4096,"%s\\%s",datadir,dllname.c_str()); +#endif // DEBUG + + trace("Loading [%s] [%s]",buffer,datadir); + hModule = LoadLibrary(buffer); + + trace("Module=%p rc=%d",hModule,(int) GetLastError()); + + if(hModule == NULL) + { + // Enable DLL error popup and try again with full path + SetErrorMode(0); + hModule = LoadLibraryEx(buffer,NULL,LOAD_LIBRARY_SEARCH_DEFAULT_DIRS|LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); + } + + rc = GetLastError(); + + trace("%s hModule=%p rc=%d",buffer,hModule,(int) rc); + } + else + { + hModule = LoadLibrary(dllname.c_str()); + rc = GetLastError(); + } + + SetErrorMode(errorMode); + + trace("%s hModule=%p rc=%d",dllname.c_str(),hModule,(int) rc); + + if(cookie && RemoveDllDirectory) + RemoveDllDirectory(cookie); + + if(kernel) + FreeLibrary(kernel); + + if(!hModule) + { + throw exception("%s: %s",dllname.c_str(),session::win32_strerror(rc).c_str()); + } + +#else + dllname += ".so"; + if(version) + { + dllname += "."; + dllname += version; + } + + dlerror(); + + hModule = dlopen(dllname.c_str(), RTLD_NOW); + if(!hModule) + throw exception("Can't load lib3270: %s",dllname.c_str()); + +#endif // WIN32 + + + } + + module::~module() + { +#ifdef WIN32 + FreeLibrary(hModule); +#else + dlclose(hModule); +#endif // WIN32 + } + + + void * module::get_symbol(const char *name) + { + void *symbol; + +#ifdef WIN32 + + symbol = (void *) GetProcAddress(hModule,name); + + if(!symbol) + throw exception("Can't load symbol %s",name); + +#else + symbol = dlsym(hModule,name); + + if(!symbol) + throw exception("Can't load symbol %s dlerror was \"%s\"",name,dlerror()); + +#endif // WIN32 + + return symbol; + } + +} + diff --git a/src/libpw3270cpp/private.h b/src/libpw3270cpp/private.h new file mode 100644 index 0000000..00e8220 --- /dev/null +++ b/src/libpw3270cpp/private.h @@ -0,0 +1,113 @@ +/* + * "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 private.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) + * + */ + +#ifndef PRIVATE_H_INCLUDED + + #define PRIVATE_H_INCLUDED + + #include + #include + + #if defined(_WIN32) + + class recursive_mutex { + private: + HANDLE hMutex; + + public: + recursive_mutex() { + hMutex = CreateMutex(NULL,FALSE,NULL); + }; + + ~recursive_mutex() { + CloseHandle(hMutex); + }; + + void lock(void) { + WaitForSingleObject(hMutex,INFINITE); + }; + + void unlock(void) { + ReleaseMutex(hMutex); + }; + + bool try_lock(void) { + if(WaitForSingleObject(hMutex,1) == WAIT_OBJECT_0) + return true; + return false; + }; + }; + + #elif __cplusplus < 201103L + + #define nullptr NULL + + class recursive_mutex { + private: + pthread_mutex_t mtx; + pthread_mutexattr_t mtxAttr; + + public: + recursive_mutex() { + + memset(&mtx,0,sizeof(mtx)); + memset(&mtxAttr,0,sizeof(mtxAttr)); + + pthread_mutexattr_init(&mtxAttr); + pthread_mutexattr_settype(&mtxAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mtx, &mtxAttr); + }; + + ~recursive_mutex() { + pthread_mutex_destroy(&mtx); + }; + + void lock(void) { + pthread_mutex_lock(&mtx); + }; + + void unlock(void) { + pthread_mutex_unlock(&mtx); + }; + + bool try_lock(void) { + return pthread_mutex_trylock(&mtx) == 0; + }; + }; + + #else + + #include + + #endif // !c11 + + + + +#endif // PRIVATE_H_INCLUDED diff --git a/src/libpw3270cpp/remote.cc b/src/libpw3270cpp/remote.cc new file mode 100644 index 0000000..eb32179 --- /dev/null +++ b/src/libpw3270cpp/remote.cc @@ -0,0 +1,1599 @@ +/* + * "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 remote.cc e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + #include + + #if defined(HAVE_DBUS) + #include + #include + #include + #include + #include + #include + #include + + #ifndef DBUS_TIMEOUT_INFINITE + #define DBUS_TIMEOUT_INFINITE ((int) 0x7fffffff) + #endif // !DBUS_TIMEOUT_INFINITE + + #endif // HAVE_DBUS + + #if defined(WIN32) + #include + #include + #include + #else + #define HLLAPI_PACKET_IS_CONNECTED "isConnected" + #define HLLAPI_PACKET_GET_CSTATE "getConnectionState" + #define HLLAPI_PACKET_GET_PROGRAM_MESSAGE "getProgramMessage" + #define HLLAPI_PACKET_GET_SSL_STATE "getSecureState" + #define HLLAPI_PACKET_IS_READY "isReady" + #define HLLAPI_PACKET_DISCONNECT "disconnect" + #define HLLAPI_PACKET_GET_HOST "getURL" + #define HLLAPI_PACKET_SET_HOST "setURL" + #define HLLAPI_PACKET_GET_CURSOR "getCursorAddress" + #define HLLAPI_PACKET_GET_WIDTH "getScreenWidth" + #define HLLAPI_PACKET_GET_HEIGHT "getScreenHeight" + #define HLLAPI_PACKET_GET_LENGTH "getScreenLength" + #define HLLAPI_PACKET_ENTER "enter" + #define HLLAPI_PACKET_QUIT "quit" + #define HLLAPI_PACKET_ERASE "erase" + #define HLLAPI_PACKET_ERASE_EOF "eraseEOF" + #define HLLAPI_PACKET_ERASE_EOL "eraseEOL" + #define HLLAPI_PACKET_ERASE_INPUT "eraseInput" + #define HLLAPI_PACKET_PRINT "print" + #define HLLAPI_PACKET_ASC2EBC "asc2ebc" + #define HLLAPI_PACKET_EBC2ASC "ebc2asc" + #define HLLAPI_PACKET_SET_UNLOCK_DELAY "setUnlockDelay" + #endif // WIN32 + + #include + #include + +#if defined(HAVE_DBUS) + static const char * prefix_dest = "br.com.bb."; + static const char * prefix_path = "/br/com/bb/"; +#endif // HAVE_DBUS + +/*--[ Implement ]--------------------------------------------------------------------------------------------------*/ + + namespace PW3270_NAMESPACE + { + + class remote : public session + { + private: + +#if defined(WIN32) + + HANDLE hPipe; + + int query_intval(HLLAPI_PACKET id) + { + struct hllapi_packet_query query = { id }; + struct hllapi_packet_result response; + DWORD cbSize = sizeof(query); + if(TransactNamedPipe(hPipe,(LPVOID) &query, cbSize, &response, sizeof(response), &cbSize,NULL)) + return response.rc; + + throw exception(GetLastError(),"%s","Transaction error"); + } + + int query_strval(HLLAPI_PACKET id, unsigned char *buffer, size_t sz) + { + DWORD cbSize = sizeof(struct hllapi_packet_text)+sz; + struct hllapi_packet_text * query; + struct hllapi_packet_text * response; + int rc = -1; + + query = (struct hllapi_packet_text *) malloc(cbSize+2); + memset(query,0,cbSize+2); + query->packet_id = id; + memcpy(query->text,buffer,sz); + + response = (struct hllapi_packet_text *) malloc(cbSize+2); + memset(response,0,cbSize+2); + + if(TransactNamedPipe(hPipe,(LPVOID) query, cbSize, &response, cbSize, &cbSize,NULL)) + { + if(response->packet_id) + { + rc = response->packet_id; + } + else + { + rc = 0; + strncpy((char *) buffer,response->text,sz); + } + } + + free(response); + free(query); + + return rc; + + } + + string query_string(void *query, size_t szQuery, size_t len) + { + struct hllapi_packet_text * response; + DWORD sz = sizeof(struct hllapi_packet_text)+len; + DWORD cbSize = (DWORD) sz; + string s; + char buffer[sz+2]; + + memset(buffer,0,sz+2); + + response = (struct hllapi_packet_text *) buffer; + + if(TransactNamedPipe(hPipe,(LPVOID) query, szQuery, response, sz, &cbSize,NULL)) + { + buffer[min(cbSize,sz)] = 0; + + trace("TransactNamedPipe call %d returns \"%s\"",(int) *( (unsigned char *) query), response->text); + + if(!response->packet_id) + s.assign(response->text); + } + else + { + trace("TransactNamedPipe error on call %d",(int) *( (unsigned char *) query)); + s.assign(""); + } + + return s; + } + + int query_intval(void *pkt, size_t szQuery, bool dynamic = false) + { + struct hllapi_packet_result response; + DWORD cbSize = (DWORD) szQuery; + BOOL status; + + status = TransactNamedPipe(hPipe,(LPVOID) pkt, cbSize, &response, sizeof(response), &cbSize,NULL); + + if(dynamic) + free(pkt); + + if(status) + return response.rc; + + throw exception(GetLastError(),"%s","Transaction error"); + + } + + void set_intval(HLLAPI_PACKET id, int value) + { + struct hllapi_packet_set_int packet; + DWORD cbSize = (DWORD) sizeof(packet); + BOOL status; + + memset(&packet,0,sizeof(packet)); + packet.packet_id = id; + packet.value = value; + + status = TransactNamedPipe(hPipe,(LPVOID) &packet, cbSize, &packet, sizeof(packet), &cbSize,NULL); + + if(!status) + throw exception(GetLastError(),"%s","Transaction error"); + + } + + +#elif defined(HAVE_DBUS) + + DBusConnection * conn; + char * dest; + char * path; + char * intf; + int sequence; + + DBusMessage * create_message(const char *method) + { + DBusMessage * msg = dbus_message_new_method_call( this->dest, // Destination + this->path, // Path + this->intf, // Interface + method); // method + + if (!msg) + throw exception("Error creating DBUS message for method %s",method); + + return msg; + + } + + DBusMessage * call(DBusMessage *msg) + { + DBusMessage * reply; + DBusError error; + + dbus_error_init(&error); + reply = dbus_connection_send_with_reply_and_block(conn,msg,10000,&error); + dbus_message_unref(msg); + + if(!reply) + { + exception e = exception("%s",error.message); + dbus_error_free(&error); + throw e; + } + return reply; + } + + string get_string(DBusMessage * msg) + { + string rc; + + if(msg) + { + DBusMessageIter iter; + + if(dbus_message_iter_init(msg, &iter)) + { + if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) + { + const char * str; + dbus_message_iter_get_basic(&iter, &str); + trace("Response: [%s]",str); + rc.assign(str); + dbus_message_unref(msg); + return rc; + } + + exception e = exception("DBUS Return type was %c, expecting %c",dbus_message_iter_get_arg_type(&iter),DBUS_TYPE_INT32); + dbus_message_unref(msg); + + throw e; + + } + + } + + return rc; + } + + string query_string(const char *method) + { + return get_string(call(create_message(method))); + } + + int get_intval(DBusMessage * msg) + { + if(msg) + { + DBusMessageIter iter; + + if(dbus_message_iter_init(msg, &iter)) + { + if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT32) + { + dbus_int32_t iSigned; + dbus_message_iter_get_basic(&iter, &iSigned); + dbus_message_unref(msg); + return (int) iSigned; + } + + exception e = exception("DBUS Return type was %c, expecting %c",dbus_message_iter_get_arg_type(&iter),DBUS_TYPE_INT32); + + dbus_message_unref(msg); + throw e; + return -1; + } + dbus_message_unref(msg); + } + return -1; + } + + int query_intval(const char *method) + { + return get_intval(call(create_message(method))); + } + + int query_intval(const char *method, int first_arg_type, ...) + { + va_list var_args; + DBusMessage * msg = dbus_message_new_method_call( this->dest, // Destination + this->path, // Path + this->intf, // Interface + method); // method + + if (!msg) + { + throw exception("Error creating DBUS message for method %s",method); + return -1; + } + + va_start(var_args, first_arg_type); + dbus_message_append_args_valist(msg,first_arg_type,var_args); + va_end(var_args); + + return get_intval(call(msg)); + } + + int query_strval(const char *method, unsigned char *buffer, size_t sz) + { + DBusMessage * outMsg = create_message(method); + + if(outMsg) + { + dbus_message_append_args(outMsg, DBUS_TYPE_STRING, &buffer, DBUS_TYPE_INVALID); + + DBusMessage * rspMsg = call(outMsg); + if(rspMsg) + { + DBusMessageIter iter; + + if(dbus_message_iter_init(rspMsg, &iter)) + { + if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) + { + const char * str; + dbus_message_iter_get_basic(&iter, &str); + trace("Response: [%s]",str); + strncpy((char *) buffer,str,sz); + dbus_message_unref(rspMsg); + return 0; + } + + exception e = exception("DBUS Return type was %c, expecting %c",dbus_message_iter_get_arg_type(&iter),DBUS_TYPE_INT32); + dbus_message_unref(rspMsg); + + throw e; + + } + } + } + + return -1; + } + + void set_intval(const char *method, int value) + { + DBusMessage * outMsg = create_message(method); + + if(outMsg) + { + dbus_int32_t v = (dbus_int32_t) value; + + dbus_message_append_args(outMsg, DBUS_TYPE_INT32, &v, DBUS_TYPE_INVALID); + + DBusMessage * rspMsg = call(outMsg); + dbus_message_unref(rspMsg); + + } + } + +#else + + + int query_intval(const char *method) + { + throw exception("Call to unimplemented RPC method \"%s\"",method); + return -1; + } + + int query_strval(const char *method, unsigned char *buffer, size_t sz) + { + throw exception("Call to unimplemented RPC method \"%s\"",method); + return -1; + } + + +#endif + + public: + +#if defined(HAVE_DBUS) + const char * makeBusName(char *buffer, size_t sz) + { + size_t bytes = strlen(buffer); + char * ptr = buffer; + int val; + + sz -= 2; + + // First uses the object ID + val = this->sequence; + while(bytes < sz && val > 0) + { + *(ptr++) = 'a'+(val % 25); + val /= 25; + bytes++; + } + *(ptr++) = '.'; + + // Then the PID + val = (int) getpid(); + while(bytes < sz && val > 0) + { + *(ptr++) = 'a'+(val % 25); + val /= 25; + bytes++; + } + *(ptr++) = '.'; + + // And last, the project info + strncpy(ptr,intf,sz); + + trace("Busname=\"%s\" sequence=%d this=%p",buffer,sequence,this); + + return buffer; + + } +#endif // HAVE_DBUS + +#if defined(WIN32) + + static string getRegistryKey(const char *name) throw (std::exception) + { + char buffer[4096]; + HKEY hKey = 0; + unsigned long datalen = sizeof(buffer); + + debug("%s(%s)",__FUNCTION__,name); + + *buffer = 0; + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\pw3270",0,KEY_QUERY_VALUE,&hKey) != ERROR_SUCCESS) + { + throw exception("Can't open key %s","HKLM\\Software\\pw3270"); + } + else + { + unsigned long datatype; // #defined in winnt.h (predefined types 0-11) + + if(RegQueryValueExA(hKey,name,NULL,&datatype,(LPBYTE) buffer,&datalen) != ERROR_SUCCESS) + *buffer = 0; + RegCloseKey(hKey); + } + + return string(buffer); + + } + +#endif // defined + + remote(const char *session) throw (std::exception) + { +#if defined(WIN32) + static DWORD dwMode = PIPE_READMODE_MESSAGE; + char buffer[4096]; + char * str; + char * ptr; + time_t timer = time(0)+1; + + hPipe = INVALID_HANDLE_VALUE; + + trace("%s(%s)",__FUNCTION__,session); + + if(strcasecmp(session,"start") == 0 || strcasecmp(session,"new") == 0) + { + // Start a new session + string appName = getRegistryKey("appName"); + char buffer[80]; + STARTUPINFO si; + PROCESS_INFORMATION pi; + + // Get application path + + if(!appName.size()) + { + throw exception("key %s\\appName is invalid","HKLM\\Software\\pw3270"); + return; + } + + trace("%s appname=%s\n",__FUNCTION__,appName.c_str()); + + snprintf(buffer,79,"%s --session=\"H%06d\"",appName.c_str(),getpid()); + + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory( &pi, sizeof(pi) ); + + // si.dwFlags = STARTF_PREVENTPINNING; + trace("App: %s",appName.c_str()); + trace("CmdLine: %s",buffer); + + if(CreateProcess(NULL,buffer,NULL,NULL,0,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi)) + { + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + } + else + { + throw exception("Can't start %s",appName.c_str()); + return; + } + + snprintf(buffer,4095,"H%06d_a",getpid()); + str = strdup(buffer); + + // Até 20 segundos para o processo iniciar. + timer = time(0)+20; + + } + else + { + // Use an existing session + str = strdup(session); + + // Convert session name + for(ptr=str;*ptr;ptr++) + { + if(*ptr == ':') + *ptr = '_'; + else + *ptr = tolower(*ptr); + } + + // Wait? + int delay; + + try + { + delay = atoi(getRegistryKey("hllapiWait").c_str()); + } + catch(std::exception &e) + { + delay = 0; + } + + if(delay) { + timer = time(0) + delay; + } + + + } + + snprintf(buffer,4095,"\\\\.\\pipe\\%s",str); + + free(str); + + trace("Searching for \"%s\"",buffer); + + hPipe = CreateFile(buffer,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); + + if(hPipe == INVALID_HANDLE_VALUE) + { + // Cant get session, wait. + while(hPipe == INVALID_HANDLE_VALUE && time(0) < timer) + { + hPipe = CreateFile(buffer,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); + Sleep(1); + } + } + + if(hPipe == INVALID_HANDLE_VALUE) + { + throw exception("Can´t create service pipe %s",buffer); + } + else if(!SetNamedPipeHandleState(hPipe,&dwMode,NULL,NULL)) + { + exception e = exception(GetLastError(),"%s","Can´t set pipe state"); + CloseHandle(hPipe); + hPipe = INVALID_HANDLE_VALUE; + throw e; + } + +#elif defined(HAVE_DBUS) + + static int sq = 0; + DBusError err; + int rc; + char * str = strdup(session); + char * ptr; + char busname[4096]; + + this->sequence = (++sq) + time(0); + + trace("%s str=%p sequence=%d",__FUNCTION__,str,sequence); + + for(ptr=str;*ptr;ptr++) + *ptr = tolower(*ptr); + + ptr = strchr(str,':'); + + if(ptr) + { + size_t sz; + + *(ptr++) = 0; + + // Build destination + sz = strlen(ptr)+strlen(str)+strlen(prefix_dest)+2; + dest = (char *) malloc(sz+1); + strncpy(dest,prefix_dest,sz); + strncat(dest,str,sz); + strncat(dest,".",sz); + strncat(dest,ptr,sz); + + // Build path + sz = strlen(str)+strlen(prefix_path); + path = (char *) malloc(sz+1); + strncpy(path,prefix_path,sz); + strncat(path,str,sz); + + // Build intf + sz = strlen(str)+strlen(prefix_dest)+1; + intf = (char *) malloc(sz+1); + strncpy(intf,prefix_dest,sz); + strncat(intf,str,sz); + + } + else + { + size_t sz; + + // Build destination + sz = strlen(str)+strlen(prefix_dest)+2; + dest = (char *) malloc(sz+1); + strncpy(dest,prefix_dest,sz); + strncat(dest,str,sz); + + // Build path + sz = strlen(str)+strlen(prefix_path); + path = (char *) malloc(sz+1); + strncpy(path,prefix_path,sz); + strncat(path,str,sz); + + // Build intf + sz = strlen(str)+strlen(prefix_dest)+1; + intf = (char *) malloc(sz+1); + strncpy(intf,prefix_dest,sz); + strncat(intf,str,sz); + + } + + trace("DBUS:\nDestination:\t[%s]\nPath:\t\t[%s]\nInterface:\t[%s]",dest,path,intf); + + free(str); + + dbus_error_init(&err); + + conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + trace("dbus_bus_get conn=%p",conn); + + if (dbus_error_is_set(&err)) + { + exception e = exception("DBUS Connection Error (%s)", err.message); + dbus_error_free(&err); + throw e; + return; + } + + if(!conn) + { + throw exception("%s", "DBUS Connection failed"); + return; + } + + + rc = dbus_bus_request_name(conn, makeBusName(busname,4095), DBUS_NAME_FLAG_REPLACE_EXISTING , &err); + trace("dbus_bus_request_name(%s) rc=%d",busname,rc); + + if (dbus_error_is_set(&err)) + { + exception e = exception("Name Error (%s)", err.message); + dbus_error_free(&err); + throw e; + return; + } + + if(rc != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) + { + trace("%s: DBUS request for name %s failed",__FUNCTION__, busname); + throw exception("DBUS request for \"%s\" failed",session); + return; + } + + trace("%s: Using DBUS name %s",__FUNCTION__,busname); + + const char * id = "r"; + static const dbus_int32_t flag = 1; + query_intval("setScript", DBUS_TYPE_STRING, &id, DBUS_TYPE_INT32, &flag, DBUS_TYPE_INVALID); + + +#else + + throw exception("%s","RPC support is incomplete."); + +#endif + } + + virtual ~remote() + { +#if defined(WIN32) + + if(hPipe != INVALID_HANDLE_VALUE) + CloseHandle(hPipe); + +#elif defined(HAVE_DBUS) + + try + { + const char * id = "r"; + static const dbus_int32_t flag = 0; + query_intval("setScript", DBUS_TYPE_STRING, &id, DBUS_TYPE_INT32, &flag, DBUS_TYPE_INVALID); + } + catch(exception e) + { + std::cerr << e.what(); + } + + char busname[4096]; + makeBusName(busname,4096); + + free(dest); + free(path); + free(intf); + + DBusError err; + + dbus_error_init(&err); + dbus_bus_release_name(conn,busname,&err); + + if (dbus_error_is_set(&err)) + { + //exception e = exception("Error when releasing DBUS name (%s)", err.message); + std::cerr << err.message; + dbus_error_free(&err); + //throw e; + } + +#else + +#endif + } + + bool is_connected(void) + { + return query_intval(HLLAPI_PACKET_IS_CONNECTED) != 0; + } + + LIB3270_CSTATE get_cstate(void) + { + return (LIB3270_CSTATE) query_intval(HLLAPI_PACKET_GET_CSTATE); + } + + LIB3270_MESSAGE get_program_message(void) { + return (LIB3270_MESSAGE) query_intval(HLLAPI_PACKET_GET_PROGRAM_MESSAGE); + } + + LIB3270_SSL_STATE get_secure(void) { + return (LIB3270_SSL_STATE) query_intval(HLLAPI_PACKET_GET_SSL_STATE); + } + + + int connect(void) + { + int rc; + +#if defined(WIN32) + + size_t cbSize = sizeof(struct hllapi_packet_connect); + struct hllapi_packet_connect * pkt = (struct hllapi_packet_connect *) malloc(cbSize); + + memset(pkt,0,cbSize); + + pkt->packet_id = HLLAPI_PACKET_CONNECT; + pkt->wait = 0; + + rc = query_intval((void *) pkt,cbSize,true); + +#elif defined(HAVE_DBUS) + + static const char * str = ""; + + rc = query_intval("connect", DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); + +#else + rc = -1; + +#endif + return rc; + + } + + int set_url(const char *uri) + { + int rc; + +#if defined(WIN32) + + size_t cbSize = sizeof(struct hllapi_packet_text)+strlen(uri); + struct hllapi_packet_text * pkt = (struct hllapi_packet_text *) malloc(cbSize); + + pkt->packet_id = HLLAPI_PACKET_SET_HOST; + strcpy(pkt->text,uri); + + rc = query_intval((void *) pkt,cbSize,true); + +#elif defined(HAVE_DBUS) + + rc = query_intval(HLLAPI_PACKET_SET_HOST, DBUS_TYPE_STRING, &uri, DBUS_TYPE_INVALID); + +#else + + rc = -1; + +#endif + + return rc; + + } + + string get_url() + { +#if defined(WIN32) + + struct hllapi_packet_query query = { HLLAPI_PACKET_GET_HOST }; + return query_string(&query,sizeof(query),1024); + +#elif defined(HAVE_DBUS) + + return query_string(HLLAPI_PACKET_GET_HOST); + +#else + return string(); +#endif + } + + int wait_for_ready(int seconds) + { +#if defined(WIN32) + + time_t end = time(0)+seconds; + + while(time(0) < end) + { + if(!is_connected()) + return ENOTCONN; + + if(is_ready()) + return 0; + + Sleep(250); + } + + return ETIMEDOUT; + +#elif defined(HAVE_DBUS) + + time_t end = time(0)+seconds; + + while(time(0) < end) + { + static const dbus_int32_t delay = 2; + + int rc = query_intval("waitForReady", DBUS_TYPE_INT32, &delay, DBUS_TYPE_INVALID); + + trace("waitForReady exits with rc=%d",rc); + + if(rc != ETIMEDOUT) + return rc; + } + + return ETIMEDOUT; + +#else + + return -1; + +#endif + + } + + bool is_ready(void) + { + return query_intval(HLLAPI_PACKET_IS_READY) != 0; + } + + + int disconnect(void) + { + return query_intval(HLLAPI_PACKET_DISCONNECT); + } + + + int wait(int seconds) + { +#if defined(WIN32) + + time_t end = time(0)+seconds; + + while(time(0) < end) + { + if(!is_connected()) + return ENOTCONN; + Sleep(500); + } + + return 0; + +#elif defined(HAVE_DBUS) + + time_t end = time(0)+seconds; + + while(time(0) < end) + { + if(!is_connected()) + return ENOTCONN; + usleep(500); + } + + return 0; + +#else + + return -1; + +#endif + + } + + int iterate(bool wait) + { +#if defined(WIN32) + if(wait) + Sleep(250); + return 0; +#elif defined(HAVE_DBUS) + if(wait) + usleep(250); + return 0; +#else + return -1; +#endif + } + + string get_text_at(int row, int col, size_t sz) + { +#if defined(WIN32) + + struct hllapi_packet_query_at query = { HLLAPI_PACKET_GET_TEXT_AT, (unsigned short) row, (unsigned short) col, (unsigned short) sz }; + + return query_string(&query,sizeof(query),sz); + +#elif defined(HAVE_DBUS) + + dbus_int32_t r = (dbus_int32_t) row; + dbus_int32_t c = (dbus_int32_t) col; + dbus_int32_t l = (dbus_int32_t) sz; + + DBusMessage * msg = create_message("getTextAt"); + if(!msg) + return NULL; + + trace("%s(%d,%d,%d)",__FUNCTION__,r,c,l); + dbus_message_append_args(msg, DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_INT32, &l, DBUS_TYPE_INVALID); + + return get_string(call(msg)); + +#else + + return string(); + +#endif + + } + + int set_text_at(int row, int col, const char *str) + { +#if defined(WIN32) + + struct hllapi_packet_text_at * query; + struct hllapi_packet_result response; + DWORD cbSize = sizeof(struct hllapi_packet_text_at)+strlen((const char *) str); + + query = (struct hllapi_packet_text_at *) malloc(cbSize); + query->packet_id = HLLAPI_PACKET_SET_TEXT_AT; + query->row = row; + query->col = col; + strcpy(query->text,(const char *) str); + + TransactNamedPipe(hPipe,(LPVOID) query, cbSize, &response, sizeof(response), &cbSize,NULL); + + free(query); + + return response.rc; + +#elif defined(HAVE_DBUS) + + dbus_int32_t r = (dbus_int32_t) row; + dbus_int32_t c = (dbus_int32_t) col; + + return query_intval("setTextAt", DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); + +#else + + return -1; + +#endif + + } + + int cmp_text_at(int row, int col, const char *text) + { + debug("%s(%d,%d,\"%s\")",__FUNCTION__,row,col,text); + +#if defined(WIN32) + + struct hllapi_packet_text_at * query; + size_t cbSize = sizeof(struct hllapi_packet_text_at)+strlen(text); + + query = (struct hllapi_packet_text_at *) malloc(cbSize); + query->packet_id = HLLAPI_PACKET_CMP_TEXT_AT; + query->row = row; + query->col = col; + strcpy(query->text,text); + + return query_intval((void *) query, cbSize, true); + +#elif defined(HAVE_DBUS) + + dbus_int32_t r = (dbus_int32_t) row; + dbus_int32_t c = (dbus_int32_t) col; + + return query_intval("cmpTextAt", DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID); + +#endif + + return 0; + } + + int wait_for_text_at(int row, int col, const char *key, int timeout) + { + time_t end = time(0)+timeout; + + while(time(0) < end) + { + if(!is_connected()) + return ENOTCONN; + + if(!cmp_text_at(row,col,key)) + return 0; + +#ifdef WIN32 + Sleep(500); +#else + usleep(500); +#endif + } + + return ETIMEDOUT; + } + + string get_text(int baddr, size_t len) + { +#if defined(WIN32) + struct hllapi_packet_query_offset query = { HLLAPI_PACKET_GET_TEXT_AT_OFFSET, (unsigned short) baddr, (unsigned short) len }; + return query_string(&query,sizeof(query),len); + +#elif defined(HAVE_DBUS) + + dbus_int32_t b = (dbus_int32_t) baddr; + dbus_int32_t l = (dbus_int32_t) len; + + DBusMessage * msg = create_message("getText"); + if(!msg) + return NULL; + + trace("%s(%d,%d)",__FUNCTION__,b,l); + dbus_message_append_args(msg, DBUS_TYPE_INT32, &b, DBUS_TYPE_INT32, &l, DBUS_TYPE_INVALID); + + return get_string(call(msg)); +#else + throw exception("%s","IPC support is unavailable"); + return string(); +#endif + } + + + int set_cursor_position(int row, int col) + { +#if defined(WIN32) + + struct hllapi_packet_cursor query = { HLLAPI_PACKET_SET_CURSOR_POSITION, (unsigned short) row, (unsigned short) col }; + + return query_intval((void *) &query, sizeof(query)); + +#elif defined(HAVE_DBUS) + + dbus_int32_t r = (dbus_int32_t) row; + dbus_int32_t c = (dbus_int32_t) col; + + return query_intval("setCursorAt", DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_INVALID); + +#endif + + return -1; + } + + int set_cursor_addr(int addr) + { +#if defined(WIN32) + + struct hllapi_packet_addr query = { HLLAPI_PACKET_SET_CURSOR, (unsigned short) addr }; + + return query_intval((void *) &query, sizeof(query)); + +#elif defined(HAVE_DBUS) + + dbus_int32_t k = (dbus_int32_t) addr; + + return query_intval("setCursorAddress", DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); + +#endif + + return -1; + } + + int get_cursor_addr(void) + { + return query_intval(HLLAPI_PACKET_GET_CURSOR); + } + + int get_width(void) { + return query_intval(HLLAPI_PACKET_GET_WIDTH); + } + + int get_height(void) { + return query_intval(HLLAPI_PACKET_GET_HEIGHT); + } + + int get_length(void) { + return query_intval(HLLAPI_PACKET_GET_LENGTH); + } + + int enter(void) + { + return query_intval(HLLAPI_PACKET_ENTER); + } + + int pfkey(int key) + { +#if defined(WIN32) + + struct hllapi_packet_keycode query = { HLLAPI_PACKET_PFKEY, (unsigned short) key }; + + return query_intval((void *) &query, sizeof(query)); + +#elif defined(HAVE_DBUS) + + dbus_int32_t k = (dbus_int32_t) key; + + return query_intval("pfKey", DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); + +#else + + return -1; + +#endif + + } + + int pakey(int key) + { +#if defined(WIN32) + + struct hllapi_packet_keycode query = { HLLAPI_PACKET_PAKEY, (unsigned short) key }; + + return query_intval((void *) &query, sizeof(query)); + +#elif defined(HAVE_DBUS) + + dbus_int32_t k = (dbus_int32_t) key; + + return query_intval("paKey", DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); + +#else + + return -1; + +#endif + + } + + int quit(void) + { + return query_intval(HLLAPI_PACKET_QUIT); + } + + int set_toggle(LIB3270_TOGGLE ix, bool value) + { +#if defined(WIN32) + + struct hllapi_packet_set query = { HLLAPI_PACKET_SET_TOGGLE, (unsigned short) ix, (unsigned short) value }; + + return query_intval((void *) &query, sizeof(query)); + +#elif defined(HAVE_DBUS) + + dbus_int32_t i = (dbus_int32_t) ix; + dbus_int32_t v = (dbus_int32_t) value; + + return query_intval("setToggle", DBUS_TYPE_INT32, &i, DBUS_TYPE_INT32, &v, DBUS_TYPE_INVALID); + +#else + return -1; + +#endif + + } + + int emulate_input(const char *str) + { +#if defined(WIN32) + + size_t len = strlen(str); + struct hllapi_packet_emulate_input * query; + size_t cbSize = sizeof(struct hllapi_packet_emulate_input)+len; + + query = (struct hllapi_packet_emulate_input *) malloc(cbSize); + query->packet_id = HLLAPI_PACKET_EMULATE_INPUT; + query->len = len; + query->pasting = 1; + strcpy(query->text,str); + + return query_intval((void *) query, cbSize, true); + +#elif defined(HAVE_DBUS) + + return query_intval("input", DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); +#else + + return -1; + +#endif + + } + + int action(const char *str) + { + +#if defined(WIN32) + + size_t len = strlen(str); + struct hllapi_packet_text * query; + size_t cbSize = sizeof(struct hllapi_packet_text)+len; + + query = (struct hllapi_packet_text *) malloc(cbSize); + query->packet_id = HLLAPI_PACKET_ACTION; + strcpy(query->text,str); + + return query_intval((void *) query, cbSize, true); + +#elif defined(HAVE_DBUS) + + return query_intval("action", DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); +#else + + return -1; + +#endif + + } + + + int get_field_start(int baddr) + { +#if defined(WIN32) + + struct hllapi_packet_addr query = { HLLAPI_PACKET_FIELD_START, (unsigned short) baddr }; + + return query_intval((void *) &query, sizeof(query)); + +#elif defined(HAVE_DBUS) + + dbus_int32_t k = (dbus_int32_t) baddr; + + return query_intval("getFieldStart", DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); + +#else + + return -1; + +#endif + + } + + int get_field_len(int baddr) + { +#if defined(WIN32) + + struct hllapi_packet_addr query = { HLLAPI_PACKET_FIELD_LEN, (unsigned short) baddr }; + + return query_intval((void *) &query, sizeof(query)); + +#elif defined(HAVE_DBUS) + + dbus_int32_t k = (dbus_int32_t) baddr; + + return query_intval("getFieldLength", DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); + +#else + + return -1; + +#endif + } + + int get_next_unprotected(int baddr) + { +#if defined(WIN32) + + struct hllapi_packet_addr query = { HLLAPI_PACKET_NEXT_UNPROTECTED, (unsigned short) baddr }; + + return query_intval((void *) &query, sizeof(query)); + +#elif defined(HAVE_DBUS) + + dbus_int32_t k = (dbus_int32_t) baddr; + + DBusMessage * msg = create_message("getNextUnprotected"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); + return get_intval(call(msg)); + } + + return -1; + +#else + + return -1; + +#endif + + } + + int get_is_protected(int baddr) + { +#if defined(WIN32) + + struct hllapi_packet_addr query = { HLLAPI_PACKET_IS_PROTECTED, (unsigned short) baddr }; + + return query_intval((void *) &query, sizeof(query)); + +#elif defined(HAVE_DBUS) + + dbus_int32_t k = (dbus_int32_t) baddr; + + DBusMessage * msg = create_message("getIsProtected"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); + return get_intval(call(msg)); + } + + return -1; + +#else + + return -1; + +#endif + + } + + int get_is_protected_at(int row,int col) + { +#if defined(WIN32) + + struct hllapi_packet_query_at query = { HLLAPI_PACKET_IS_PROTECTED_AT, (unsigned short) row, (unsigned short) col, 0 }; + + return query_intval((void *) &query, sizeof(query)); + +#elif defined(HAVE_DBUS) + + dbus_int32_t r = (dbus_int32_t) row; + dbus_int32_t c = (dbus_int32_t) col; + + DBusMessage * msg = create_message("getIsProtectedAt"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_INVALID); + return get_intval(call(msg)); + } + + return -1; + +#else + + return -1; + +#endif + + } + + + int set_host_charset(const char *charset) + { +#if defined(WIN32) + + size_t len = strlen(charset); + struct hllapi_packet_set_text * query; + size_t cbSize = sizeof(struct hllapi_packet_set_text)+len; + + query = (struct hllapi_packet_set_text *) malloc(cbSize); + query->packet_id = HLLAPI_PACKET_SET_HOST_CHARSET; + query->len = len; + strcpy(query->text,charset); + + return query_intval((void *) query, cbSize, true); + +#elif defined(HAVE_DBUS) + + return query_intval("setHostCharset", DBUS_TYPE_STRING, &charset, DBUS_TYPE_INVALID); + +#else + return -1; +#endif + } + + string get_host_charset(void) + { +#if defined(WIN32) + + struct hllapi_packet_query query = { HLLAPI_PACKET_GET_HOST_CHARSET }; + return query_string(&query,sizeof(query),100); + +#elif defined(HAVE_DBUS) + + return query_string("getHostCharset"); + +#else + + return NULL; + +#endif + } + + +#if defined(HAVE_DBUS) + string get_clipboard(void) + { + return query_string("getClipboard"); + } + + int set_clipboard(const char *text) + { + return query_intval("setClipboard", DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID); + } + + string get_display_charset(void) + { + return query_string("getDisplayCharset"); + } + + int popup_dialog(LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, ...) + { + DBusMessage * msg = dbus_message_new_method_call( this->dest, // Destination + this->path, // Path + this->intf, // Interface + "showPopup"); // method + + if (!msg) + { + throw exception("%s","Error creating DBUS message for popup"); + return -1; + } + else + { + char text[4096]; + char * ptr = text; + va_list arg_ptr; + dbus_int32_t i = (dbus_int32_t) id; + + va_start(arg_ptr, fmt); + vsnprintf(text,4095,fmt,arg_ptr); + va_end(arg_ptr); + + if(!dbus_message_append_args(msg, DBUS_TYPE_INT32, &i, DBUS_TYPE_STRING, &title, DBUS_TYPE_STRING, &message, DBUS_TYPE_STRING, &ptr, DBUS_TYPE_INVALID)) + { + dbus_message_unref(msg); + throw exception("%s","Cant append args for popup message"); + } + else + { + DBusMessage * reply; + DBusError error; + + dbus_error_init(&error); + reply = dbus_connection_send_with_reply_and_block(conn,msg,DBUS_TIMEOUT_INFINITE,&error); + dbus_message_unref(msg); + + if(!reply) + { + exception e = exception("%s",error.message); + dbus_error_free(&error); + throw e; + return -1; + } + + return get_intval(reply); + + } + } + return 0; + } + +#endif // HAVE_DBUS + + int erase(void) + { + return query_intval(HLLAPI_PACKET_ERASE); + } + + int erase_eof(void) + { + return query_intval(HLLAPI_PACKET_ERASE_EOF); + } + + int erase_eol(void) + { + return query_intval(HLLAPI_PACKET_ERASE_EOL); + } + + int erase_input(void) + { + return query_intval(HLLAPI_PACKET_ERASE_INPUT); + } + + int print(void) + { + return query_intval(HLLAPI_PACKET_PRINT); + } + + const char * asc2ebc(unsigned char *text, int sz) + { + query_strval(HLLAPI_PACKET_ASC2EBC,text,sz); + return (const char *) text; + } + + const char * ebc2asc(unsigned char *text, int sz) + { + query_strval(HLLAPI_PACKET_EBC2ASC,text,sz); + return (const char *) text; + } + + void set_unlock_delay(unsigned short ms) + { + set_intval(HLLAPI_PACKET_SET_UNLOCK_DELAY,(int) ms); + } + + }; + + session * session::create_remote(const char *session) throw (std::exception) + { + return new remote(session); + } + + } + diff --git a/src/libpw3270cpp/session.cc b/src/libpw3270cpp/session.cc new file mode 100644 index 0000000..45918ef --- /dev/null +++ b/src/libpw3270cpp/session.cc @@ -0,0 +1,702 @@ +/* + * "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 session.cc e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + #include + #include + #include + + #include "private.h" + +#ifndef WIN32 + #include +#endif // !WIN32 + +#ifdef HAVE_SYSLOG + #include +#endif // HAVE_SYSLOG + + +/*--[ Implement ]--------------------------------------------------------------------------------------------------*/ + + using namespace PW3270_NAMESPACE; + +#if defined(linux) + static void onLoad() __attribute__((constructor)); + static void onUnLoad() __attribute__((destructor)); + + static void onLoad() + { + session::init(); + } + + static void onUnLoad() + { + session::deinit(); + } + +#endif // linux + +#ifdef _WIN32 + + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) + { + switch(fdwReason) + { + case DLL_PROCESS_ATTACH: + session::init(); + break; + + case DLL_PROCESS_DETACH: + session::deinit(); + break; + } + + return TRUE; + } + +#endif // _WIN32 + + + namespace PW3270_NAMESPACE { + + session * session::first = nullptr; + session * session::last = nullptr; + session * (*session::factory)(const char *name) = nullptr; + + static recursive_mutex mtx; + + inline void lock() + { + mtx.lock(); + } + + inline void unlock() + { + mtx.unlock(); + } + + void session::init() + { + trace("Loading %s objects",PACKAGE_NAME); + } + + void session::deinit() + { + trace("Unloading %s objects",PACKAGE_NAME); + while(first) + { + delete first; + } + + } + + session::session() + { + +#ifdef HAVE_ICONV + this->conv2Local = (iconv_t) (-1); + this->conv2Host = (iconv_t) (-1); +#endif + + if(first) + { + prev = last; + next = 0; + last->next = this; + last = this; + } + else + { + prev = next = 0; + first = last = this; + } + + } + + session::~session() + { +#ifdef HAVE_ICONV + + if(this->conv2Local != (iconv_t) (-1)) + iconv_close(this->conv2Local); + + if(this->conv2Host != (iconv_t) (-1)) + iconv_close(this->conv2Host); + +#endif + + if(prev) + prev->next = next; + else + first = next; + + if(next) + next->prev = prev; + else + last = prev; + } + + // Factory methods and settings + session * session::create(const char *name) throw (std::exception) + { + session *rc = nullptr; + + trace("%s(%s)",__FUNCTION__,name); + + lock(); + + try + { + if(factory) + rc = factory(name); + else if(name && *name) + rc = create_remote(name); + else + rc = create_local(); + + } + catch(std::exception &e) + { + unlock(); + throw e; + } + + unlock(); + + return rc; + } + + session * session::start(const char *name) + { + return create(name); + } + + bool session::has_default(void) + { + return first != nullptr; + } + + session * session::get_default(void) + { + if(first) + return first; + return create(NULL); + } + + void session::set_plugin(session * (*factory)(const char *name)) + { + trace("%s(%p)",__FUNCTION__,factory); + session::factory = factory; + } + + // Object settings + void session::set_display_charset(const char *remote, const char *local) + { + trace("%s(%s,%s)",__FUNCTION__,remote,local); + +#ifdef HAVE_ICONV + string display_charset = this->get_display_charset(); + + if(this->conv2Local != (iconv_t) (-1)) + iconv_close(this->conv2Local); + + if(this->conv2Host != (iconv_t) (-1)) + iconv_close(this->conv2Host); + + if(!remote) + remote = display_charset.c_str(); + + trace("%s remote=%s local=%s",__FUNCTION__,remote,local); + + if(strcmp(local,remote)) + { + // Local and remote charsets aren't the same, setup conversion + conv2Local = iconv_open(local, remote); + conv2Host = iconv_open(remote,local); + } + else + { + conv2Local = conv2Host = (iconv_t)(-1); + } + +#endif + + } + + string session::get_display_charset(void) + { + return string(get_encoding()); + } + + const char * session::get_encoding(void) + { + return "ISO-8859-1"; + } + + // 3270 methods + const string session::get_version(void) + { + return string(PACKAGE_VERSION); + } + + const string session::get_revision(void) + { +#ifdef PACKAGE_REVISION + return string(PACKAGE_REVISION); +#else + return string(STRINGIZE_VALUE_OF(BUILD_DATE)); +#endif // PACKAGE_REVISION + } + + void session::log(const char *fmt, ...) + { + va_list arg_ptr; + va_start(arg_ptr, fmt); + this->logva(fmt,arg_ptr); + va_end(arg_ptr); + } + + void session::logva(const char *fmt, va_list args) + { + #ifdef HAVE_SYSLOG + openlog(PACKAGE_NAME, LOG_NDELAY, LOG_USER); + vsyslog(LOG_INFO,fmt,args); + closelog(); + #else + vfprintf(stderr,fmt,args); + #endif + } + + int session::wait_for_text_at(int row, int col, const char *key, int timeout) + { + time_t end = time(0)+timeout; + + trace("%s(%d,%d,%s,%d)",__FUNCTION__,row,col,key,timeout); + + iterate(false); + while(time(0) < end) + { + trace("Aguardar %d segundos por \"%s\" @%d,%d (%s)",(int) (end - time(0)),key,row,col,get_text_at(row,col,strlen(key)).c_str()); + + int rc = wait_for_ready(end - time(0)); + if(rc) { + return rc; + } + + if(!cmp_text_at(row,col,key)) { + return 0; + } + + iterate(true); + + } + + trace("Tela:\n%s\n", ((string) *this).c_str()); + + return ETIMEDOUT; + } + + int session::set_copy(const char *text) + { + return EINVAL; + } + + string session::get_copy(void) + { + errno = EINVAL; + return string(); + } + + string session::get_clipboard(void) + { +#if defined(WIN32) + + if (! OpenClipboard(0)) + { + throw exception(GetLastError(),"%s","Can´t open system clipboard"); + return NULL; + } + + HANDLE hData = GetClipboardData(CF_TEXT); + if(!hData) + { + throw exception(GetLastError(),"%s","Can´t get clipboard data"); + return NULL; + } + + char * pszText = static_cast( GlobalLock(hData) ); + if(!pszText) + { + throw exception(GetLastError(),"%s","Can´t lock clipboard"); + return NULL; + } + + string text = string ( pszText ); + + GlobalUnlock( hData ); + + CloseClipboard(); + + return text; + +#else + errno = EINVAL; + return NULL; + +#endif // WIN32 + } + + int session::set_clipboard(const char *text) + { +#if defined(WIN32) + if (! OpenClipboard(0)) + { + throw exception(GetLastError(),"%s","Can´t open system clipboard"); + return -1; + } + + EmptyClipboard(); + + size_t size = strlen(text)+1; + HGLOBAL hClipboardData = GlobalAlloc(GMEM_MOVEABLE , size); + + strcpy((char *) GlobalLock(hClipboardData), text); + + if(!SetClipboardData(CF_TEXT, hClipboardData)) + { + GlobalUnlock(hClipboardData); + CloseClipboard(); + throw exception(GetLastError(),"%s","Can´t set system clipboard"); + } + + GlobalUnlock(hClipboardData); + CloseClipboard(); + + return 0; +#else + + return EINVAL; + +#endif // WIN32 + } + + + int session::popup_dialog(LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, ...) + { + return -1; + } + + string session::file_chooser_dialog(int action, const char *title, const char *extension, const char *filename) + { + return string(""); + } + + string session::get_3270_text(const char *str) + { + string rc; + +#ifdef HAVE_ICONV + size_t in = strlen(str); + + if(in && conv2Host != (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(conv2Host,NULL,NULL,NULL,NULL); // Reset state + + if(iconv(conv2Host,&inBuffer,&in,&ptr,&out) == ((size_t) -1)) { + rc.assign(str); + } else { + rc.assign(outBuffer); + } + + free(outBuffer); + } else { + rc.assign(str); + } +#else + rc.assign(str); +#endif // HAVE_ICONV + + trace("%s(\"%s\")=\"%s\"",__FUNCTION__,str,rc.c_str()); + + return rc; + } + + string session::get_local_text(const char *str) + { + string rc; + +#ifdef HAVE_ICONV + size_t in = strlen(str); + + if(in && conv2Local != (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(conv2Local,NULL,NULL,NULL,NULL); // Reset state + + if(iconv(conv2Local,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) + rc.assign(outBuffer); + + free(outBuffer); + } + else + { + char * text = strdup(str); + for(char *ptr = text;*ptr;ptr++) + { + if(*ptr < ' ' || *ptr > 128) + { + *ptr = '?'; + } + } + rc = text; + free(text); + } +#else + char * text = strdup(str); + for(char *ptr = text;*ptr;ptr++) + { + if(*ptr < ' ' || *ptr > 128) + { + *ptr = '?'; + } + } + rc = text; + free(text); +#endif // HAVE_ICONV + + return rc; + } + + string session::get_string_at(int row, int col, size_t sz) + { + return this->get_local_text(this->get_text_at(row,col,sz).c_str()); + } + + int session::set_string_at(int row, int col, const char *str) + { + if(!str) + return -1; + +#ifdef HAVE_ICONV + if(conv2Host != (iconv_t)(-1)) + { + size_t in = strlen(str); + 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(conv2Host,NULL,NULL,NULL,NULL); // Reset state + + if(iconv(conv2Host,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) + { + int rc = this->set_text_at(row,col,outBuffer); + free(outBuffer); + return rc; + } + + free(outBuffer); + } +#endif // HAVE_ICONV + + return this->set_text_at(row,col,str); + + } + + int session::input_string(const char *str) + { + if(!str) + return -1; + +#ifdef HAVE_ICONV + if(conv2Host != (iconv_t)(-1)) + { + size_t in = strlen(str); + 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(conv2Host,NULL,NULL,NULL,NULL); // Reset state + + if(iconv(conv2Host,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) + { + int rc = this->emulate_input(outBuffer); + free(outBuffer); + return rc; + } + + free(outBuffer); + } +#endif // HAVE_ICONV + + return this->emulate_input(str); + + } + + int session::cmp_string_at(int row, int col, const char *text) + { + return cmp_text_at(row,col,get_3270_text(text).c_str()); + } + + int session::wait_for_string_at(int row, int col, const char *key, int timeout) + { + return wait_for_text_at(row,col,get_3270_text(key).c_str(),timeout); + } + + string session::get_string(int baddr, size_t len) + { + return get_local_text(get_text(baddr,len).c_str()); + } + + string session::asc2ebc(string &str) + { + size_t sz = str.size(); + unsigned char buffer[sz+1]; + + memcpy(buffer,str.c_str(),sz); + return string(asc2ebc(buffer,sz)); + } + + string session::ebc2asc(string &str) + { + size_t sz = str.size(); + unsigned char buffer[sz+1]; + memcpy(buffer,str.c_str(),sz); + return string(ebc2asc(buffer,sz)); + } + + int session::file_transfer(LIB3270_FT_OPTION options, const char *local, const char *remote, int lrecl, int blksize, int primspace, int secspace, int dft) + { + log("Can't transfer %s: File transfer is unavailable", local ? local : "file"); + return EINVAL; + } + + int session::set_host(const char *host) + { + return set_url(host); + } + + int session::connect(const char *host, time_t wait) + { + int rc = 0; + + if(host && *host) + { + rc = set_url(host); + trace("%s: set_url(%s) = %d",__FUNCTION__,host,rc); + } + + rc = connect(); + trace("%s: connect=%d",__FUNCTION__,rc); + + if(!rc && wait) + { + time_t timeout = time(0)+wait; + rc = ETIMEDOUT; + + while(time(0) < timeout && rc == ETIMEDOUT) + { + trace("%s: Waiting",__FUNCTION__); + if(is_connected()) + rc = 0; + iterate(true); + } + } + + return rc; + } + +#ifdef WIN32 + string session::win32_strerror(int e) + { + static char buffer[4096]; + + memset(buffer,0,sizeof(buffer)); + + if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,e,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),buffer,sizeof(buffer),NULL) == 0) + { + snprintf(buffer,4095,"Windows error %d", e); + } + + for(size_t f=0;f + * + * 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 testprogram.cc e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + #include + #include + + using namespace std; + using namespace PW3270_NAMESPACE; + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + + int main(int numpar, char *param[]) + { + + { + string s; + session *session = session::start(""); + // session *session = session::start("new"); + + cout << "pw3270 version: " << session->get_version() << endl; + cout << "pw3270 revision: " << session->get_revision() << endl << endl; + + if(session->is_connected()) + cout << "\tConnected to host" << endl; + else + cout << "\tDisconnected" << endl; + + cout << "\tSession state: " << session->get_cstate() << endl; + + s = session->get_display_charset(); + cout << "\tDisplay charset: " << s.c_str() << endl; + + s = session->get_host_charset(); + cout << "\tHost charset: " << s.c_str() << endl; + + cout << "Connect: " << session->connect("fandezhi.efglobe.com:23",60) << endl << endl; + + cout << "\tWaitForReady: " << session->wait_for_ready(10) << endl; + + cout << "\tIsConnected: " << session->is_connected() << endl; + cout << "\tIsReady: " << session->is_ready() << endl; + cout << "\tString(3,2,14) " << session->get_string_at(3,2,14) << endl; + + delete session; + } + + // Waits + sleep(2); + + // Create another session + /* + { + session *session = session::start("pw3270:a"); + + session->disconnect(); + delete session; + + } + */ + + + return 0; + } + + diff --git a/src/pw3270cpp/Makefile.in b/src/pw3270cpp/Makefile.in deleted file mode 100644 index 94983fc..0000000 --- a/src/pw3270cpp/Makefile.in +++ /dev/null @@ -1,161 +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., 59 Temple -# Place, Suite 330, Boston, MA, 02111-1307, USA -# -# Contatos: -# -# perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) -# erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça) -# - -PACKAGE=@PACKAGE_NAME@ -LIBNAME=lib$(PACKAGE)cpp.a - -#---[ Sources ]---------------------------------------------------------------- - -include class.mak - -#---[ Paths ]------------------------------------------------------------------ - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -datarootdir=@datarootdir@ -includedir=@includedir@ -libdir=@libdir@ - -ROOTDIR ?= . -OBJDIR ?= $(ROOTDIR)/.obj -BINDIR ?= $(ROOTDIR)/.bin -BINDBG ?= $(BINDIR)/Debug -BINRLS ?= $(BINDIR)/Release - -OBJDBG = $(OBJDIR)/Debug -OBJRLS = $(OBJDIR)/Release - -#---[ Tools ]------------------------------------------------------------------ - -MKDIR=@MKDIR_P@ -LN_S=@LN_S@ -INSTALL=@INSTALL@ -INSTALL_DATA=$(INSTALL) -m 644 -INSTALL_PROGRAM=@INSTALL_PROGRAM@ - -#---[ Flags ]------------------------------------------------------------------ - -CFLAGS=$(CLASS_CFLAGS) -I../include -LIBS=@LIBS@ $(CLASS_LIBS) - -DEBUG_CFLAGS=-DDEBUG=1 -g -Wall - -EXEEXT=@EXEEXT@ - -#---[ Rules ]------------------------------------------------------------------ - -CXX=@CXX@ -LD=@CXX@ - -DEPENDS=../include/*.h ../include/lib3270/*.h ../include/pw3270/*.h Makefile - -#---[ Rules ]------------------------------------------------------------------ - -$(OBJDBG)/%.o: %.cc $(DEPENDS) - @echo " CC `basename $@`" - @$(MKDIR) `dirname $@` - @$(CXX) $(CFLAGS) $(DEBUG_CFLAGS) -o $@ -c $< - -$(OBJRLS)/%.o: %.cc $(DEPENDS) - @echo " CC `basename $@`" - @$(MKDIR) `dirname $@` - @$(CXX) $(CFLAGS) -o $@ -c $< - -#---[ Release targets ]-------------------------------------------------------- - -Release: \ - $(BINRLS)/$(LIBNAME) - -$(BINRLS)/$(LIBNAME): \ - $(foreach SRC, $(basename $(CLASS_SRC)), $(OBJRLS)/$(SRC).o) - - @echo " CCLD `basename $@`" - @$(MKDIR) `dirname $@` - @ar rs $@ $^ - -install: \ - Release - - @$(MKDIR) $(DESTDIR)$(libdir) - @$(INSTALL_PROGRAM) $(BINRLS)/$(LIBNAME) $(DESTDIR)$(libdir) - - @$(MKDIR) $(DESTDIR)$(includedir) - @$(INSTALL_DATA) ../include/pw3270/class.h $(DESTDIR)/$(includedir)/@PACKAGE_NAME@cpp.h - -zip: \ - lib$(PACKAGE)cpp-@PACKAGE_VERSION@.@PACKAGE_REVISION@.@host@.zip - -lib$(PACKAGE)cpp-@PACKAGE_VERSION@.@PACKAGE_REVISION@.@host@.zip: \ - $(BINRLS)/$(LIBNAME) - - @rm -f $@ - - @$(INSTALL_DATA) ../include/pw3270/class.h $(BINRLS)/@PACKAGE_NAME@cpp.h - - @zip -9 -j $@ \ - $(BINRLS)/$(LIBNAME) \ - $(BINRLS)/@PACKAGE_NAME@cpp.h - - -#---[ Debug targets ]---------------------------------------------------------- - -Debug: $(BINDBG)/testprogram$(EXEEXT) - -run: $(BINDBG)/testprogram$(EXEEXT) - $(BINDBG)/testprogram$(EXEEXT) - -$(BINDBG)/testprogram$(EXEEXT): $(OBJDBG)/testprogram.o $(BINDBG)/$(LIBNAME) - @echo " CCLD `basename $@`" - @$(MKDIR) `dirname $@` - @$(LD) $(LIBS) -o $@ $^ - -$(BINDBG)/$(LIBNAME): $(foreach SRC, $(basename $(CLASS_SRC)), $(OBJDBG)/$(SRC).o) - @echo " CCLD `basename $@`" - @$(MKDIR) `dirname $@` - @ar rs $@ $^ - -#---[ Misc targets ]----------------------------------------------------------- -install-sdk: \ - $(BINRLS)/$(LIBNAME) - - @$(MKDIR) $(DESTDIR)$(datarootdir)/$(PACKAGE)/sample/classlib - @$(INSTALL_DATA) *.cc $(DESTDIR)$(datarootdir)/$(PACKAGE)/sample/classlib - - @$(MKDIR) $(DESTDIR)/$(includedir)/pw3270 - @$(INSTALL_DATA) ../include/pw3270/class.h $(DESTDIR)/$(includedir)/pw3270 - - @$(LN_S) ./pw3270/class.h $(DESTDIR)/$(includedir)/$(PACKAGE)cpp.h - - @$(MKDIR) $(DESTDIR)/$(libdir) - @$(INSTALL_DATA) $(BINRLS)/$(LIBNAME) $(DESTDIR)/$(libdir) - -cleanDebug: clean - -clean: - @rm -fr $(OBJDIR) - @rm -fr $(BINDIR) - @rm -f testprogram - diff --git a/src/pw3270cpp/class.mak.in b/src/pw3270cpp/class.mak.in deleted file mode 100644 index 70b1964..0000000 --- a/src/pw3270cpp/class.mak.in +++ /dev/null @@ -1,50 +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., 59 Temple -# Place, Suite 330, Boston, MA, 02111-1307, USA -# -# Contatos: -# -# perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) -# erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça) -# - -CLASS_CFLAGS=@CFLAGS@ @DLL_CFLAGS@ @DBUS_CFLAGS@ -CLASS_LIBS=@LIBICONV@ @DBUS_LIBS@ - -CLASS_SRC=session.cc exception.cc local.cc remote.cc module.cc - -CLASS_DEBUG_OBJECTS=$(foreach SRC, $(basename $(CLASS_SRC)), $(OBJDBG)/classlib/$(SRC)@OBJEXT@) -CLASS_RELEASE_OBJECTS=$(foreach SRC, $(basename $(CLASS_SRC)), $(OBJRLS)/classlib/$(SRC)@OBJEXT@) - -#---[ Rules ]------------------------------------------------------------------ - -$(OBJDBG)/classlib/%.o: \ - $(CLASSLIBDIR)/%.cc - - @echo " CC `basename $@`" - @$(MKDIR) `dirname $@` - @$(CXX) $(CLASS_CFLAGS) $(PW3270_CFLAGS) $(LIB3270_CFLAGS) $(DEBUG_CFLAGS) -o $@ -c $< - -$(OBJRLS)/classlib/%.o: \ - $(CLASSLIBDIR)/%.cc - - @echo " CC `basename $@`" - @$(MKDIR) `dirname $@` - @$(CXX) $(CLASS_CFLAGS) $(PW3270_CFLAGS) $(LIB3270_CFLAGS) -o $@ -c $< - diff --git a/src/pw3270cpp/classlib.cbp b/src/pw3270cpp/classlib.cbp deleted file mode 100644 index e7fb023..0000000 --- a/src/pw3270cpp/classlib.cbp +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - diff --git a/src/pw3270cpp/exception.cc b/src/pw3270cpp/exception.cc deleted file mode 100644 index 2741350..0000000 --- a/src/pw3270cpp/exception.cc +++ /dev/null @@ -1,100 +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 exception.cc e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - - #include - #include - #include - - #include - -/*--[ Implement ]--------------------------------------------------------------------------------------------------*/ - - namespace PW3270_NAMESPACE - { - - exception::exception(int syscode) - { - snprintf(this->msg,4095,"%s",strerror(syscode)); - } - - exception::exception(const char *fmt, ...) - { - va_list arg_ptr; - va_start(arg_ptr, fmt); - vsnprintf(this->msg,4095,fmt,arg_ptr); - va_end(arg_ptr); - } - -#ifdef WIN32 - exception::exception(DWORD error, const char *fmt, ...) - { - LPVOID lpMsgBuf = 0; - char * ptr; - size_t szPrefix; - - va_list arg_ptr; - va_start(arg_ptr, fmt); - vsnprintf(this->msg,4095,fmt,arg_ptr); - va_end(arg_ptr); - - szPrefix = strlen(this->msg); - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); - - for(ptr= (char *) lpMsgBuf;*ptr && *ptr != '\n';ptr++); - *ptr = 0; - - snprintf(this->msg+szPrefix,4095-szPrefix,": %s (rc=%d)",(char *) lpMsgBuf,(int) error); - - LocalFree(lpMsgBuf); - - } -#else - exception::exception(int error, const char *fmt, ...) - { - size_t szPrefix; - - va_list arg_ptr; - va_start(arg_ptr, fmt); - vsnprintf(this->msg,4095,fmt,arg_ptr); - va_end(arg_ptr); - - szPrefix = strlen(this->msg); - - snprintf(this->msg+szPrefix,4095-szPrefix,": %s (rc=%d)",strerror(error),(int) error); - - } -#endif // WIN32 - - const char * exception::what() const throw() - { - return this->msg; - } - - } diff --git a/src/pw3270cpp/local.cc b/src/pw3270cpp/local.cc deleted file mode 100644 index 8eb78ad..0000000 --- a/src/pw3270cpp/local.cc +++ /dev/null @@ -1,599 +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 local.cc e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -#if defined WIN32 - - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx - #ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS - #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 - #endif // LOAD_LIBRARY_SEARCH_DEFAULT_DIRS - - #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR - #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 - #endif // LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR - - #include - -#else - - #include - -#endif - -#include "private.h" - -#include -#include -#include -#include - -#ifdef HAVE_SYSLOG - #include - #include -#endif // HAVE_SYSLOG - -/*--[ Implement ]--------------------------------------------------------------------------------------------------*/ - - extern "C" - { - static void loghandler(H3270 *session, const char *module, int rc, const char *fmt, va_list args) - { - #ifdef HAVE_SYSLOG - openlog(PACKAGE_NAME, LOG_NDELAY, LOG_USER); - vsyslog(LOG_INFO,fmt,args); - closelog(); - #endif // HAVE_SYSLOG - } - - static void tracehandler(H3270 *session, const char *fmt, va_list args) - { - #ifdef HAVE_SYSLOG - - #define MAX_LOG_LENGTH 200 - - static char line[MAX_LOG_LENGTH+1]; - char temp[MAX_LOG_LENGTH]; - char * ptr; - size_t len = strlen(line); - - vsnprintf(temp,MAX_LOG_LENGTH-len,fmt,args); - - ptr = strchr(temp,'\n'); - if(!ptr) - { - strncat(line,temp,MAX_LOG_LENGTH); - if(strlen(line) >= MAX_LOG_LENGTH) - { - openlog(PACKAGE_NAME, LOG_NDELAY, LOG_USER); - syslog(LOG_INFO,"%s",line); - closelog(); - *line = 0; - } - return; - } - - *ptr = 0; - strncat(line,temp,MAX_LOG_LENGTH); - - openlog(PACKAGE_NAME, LOG_NDELAY, LOG_USER); - syslog(LOG_DEBUG,"%s",line); - closelog(); - - strncpy(line,ptr+1,MAX_LOG_LENGTH); - - #endif // HAVE_SYSLOG - } - - } - - namespace PW3270_NAMESPACE - { - - class local : public session, protected module, protected recursive_mutex - { - private: - - // Lib3270 entry points - const char * (*_get_version)(void); - LIB3270_CSTATE (*_get_connection_state)(H3270 *h); - LIB3270_MESSAGE (*_get_program_message)(H3270 *h); - LIB3270_SSL_STATE (*_get_secure)(H3270 *h); - - - int (*_disconnect)(H3270 *h); - int (*_connect)(H3270 *h,int wait); - const char (*_set_url)(H3270 *h, const char *n); - const char * (*_get_url)(H3270 *h, char *str, int len); - int (*_is_connected)(H3270 *h); - void (*_main_iterate)(H3270 *h, int wait); - int (*_wait)(H3270 *hSession, int seconds); - int (*_enter)(H3270 *hSession); - int (*_pfkey)(H3270 *hSession, int key); - int (*_pakey)(H3270 *hSession, int key); - int (*_wait_for_ready)(H3270 *hSession, int seconds); - char * (*_get_text)(H3270 *h, int offset, int len); - char * (*_get_text_at)(H3270 *h, int row, int col, int len); - int (*_cmp_text_at)(H3270 *h, int row, int col, const char *text); - int (*_set_text_at)(H3270 *h, int row, int col, const unsigned char *str); - int (*_is_ready)(H3270 *h); - int (*_set_cursor_position)(H3270 *h, int row, int col); - int (*_set_toggle)(H3270 *h, LIB3270_TOGGLE ix, int value); - int (*_get_field_start)(H3270 *h, int baddr); - int (*_get_field_len)(H3270 *h, int baddr); - int (*_set_cursor_addr)(H3270 *h, int addr); - int (*_get_cursor_addr)(H3270 *h); - int (*_emulate_input)(H3270 *session, const char *s, int len, int pasting); - int (*_get_next_unprotected)(H3270 *hSession, int baddr0); - int (*_get_is_protected)(H3270 *hSession, int baddr); - int (*_get_is_protected_at)(H3270 *hSession, int row, int col); - void (*_popup_va)(H3270 *session, LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, va_list); - void * (*_free)(void *); - const char * (*_get_display_charset)(H3270 *hSession); - int (*_set_host_charset)(H3270 *hSession, const char *name); - const char * (*_get_host_charset)(H3270 *hSession); - int (*_print)(H3270 *hSession); - int (*_erase)(H3270 *hSession); - int (*_erase_eof)(H3270 *hSession); - int (*_erase_eol)(H3270 *hSession); - int (*_erase_input)(H3270 *hSession); - int (*_action)(H3270 *hSession, const char *name); - int (*_set_unlock_delay)(H3270 *hSession, unsigned short ms); - - int (*_get_width)(H3270 *hSession); - int (*_get_height)(H3270 *hSession); - int (*_get_length)(H3270 *hSession); - - const char * (*_ebc2asc)(H3270 *hSession, unsigned char *buffer, int sz); - const char * (*_asc2ebc)(H3270 *hSession, unsigned char *buffer, int sz); - - protected: - - H3270 * hSession; - - void load_methods() { - - void (*set_log_handler)(void (*loghandler)(H3270 *, const char *, int, const char *, va_list)); - void (*set_trace_handler)( void (*handler)(H3270 *session, const char *fmt, va_list args) ); - - struct _call - { - void **entry; - const char * name; - } call[] = - { - { (void **) & set_log_handler, "lib3270_set_log_handler" }, - { (void **) & set_trace_handler, "lib3270_set_trace_handler" }, - - { (void **) & _is_connected, "lib3270_is_connected" }, - { (void **) & _get_connection_state, "lib3270_get_connection_state" }, - { (void **) & _get_program_message, "lib3270_get_program_message" }, - { (void **) & _get_secure, "lib3270_get_secure" }, - - { (void **) & _get_version, "lib3270_get_version" }, - { (void **) & _disconnect, "lib3270_disconnect" }, - { (void **) & _connect, "lib3270_connect" }, - { (void **) & _set_url, "lib3270_set_url" }, - { (void **) & _get_url, "lib3270_get_url" }, - { (void **) & _main_iterate, "lib3270_main_iterate" }, - { (void **) & _wait, "lib3270_wait" }, - { (void **) & _enter, "lib3270_enter" }, - { (void **) & _pfkey, "lib3270_pfkey" }, - { (void **) & _pakey, "lib3270_pakey" }, - { (void **) & _wait_for_ready, "lib3270_wait_for_ready" }, - { (void **) & _get_text, "lib3270_get_text" }, - { (void **) & _get_text_at, "lib3270_get_text_at" }, - { (void **) & _cmp_text_at, "lib3270_cmp_text_at" }, - { (void **) & _set_text_at, "lib3270_set_string_at" }, - { (void **) & _is_ready, "lib3270_is_ready" }, - { (void **) & _set_cursor_position, "lib3270_set_cursor_position" }, - { (void **) & _set_toggle, "lib3270_set_toggle" }, - { (void **) & _get_field_start, "lib3270_get_field_start" }, - { (void **) & _get_field_len, "lib3270_get_field_len" }, - { (void **) & _set_cursor_addr, "lib3270_set_cursor_address" }, - { (void **) & _get_cursor_addr, "lib3270_get_cursor_address" }, - { (void **) & _emulate_input, "lib3270_emulate_input" }, - { (void **) & _get_next_unprotected, "lib3270_get_next_unprotected" }, - { (void **) & _get_is_protected, "lib3270_get_is_protected" }, - { (void **) & _get_is_protected_at, "lib3270_get_is_protected_at" }, - { (void **) & _popup_va, "lib3270_popup_va" }, - { (void **) & _free, "lib3270_free" }, - { (void **) & _get_display_charset, "lib3270_get_display_charset" }, - { (void **) & _set_host_charset, "lib3270_set_host_charset" }, - { (void **) & _get_host_charset, "lib3270_get_host_charset" }, - - { (void **) & _erase, "lib3270_erase" }, - { (void **) & _erase_eof, "lib3270_eraseeof" }, - { (void **) & _erase_eol, "lib3270_eraseeol" }, - { (void **) & _erase_input, "lib3270_eraseinput" }, - - { (void **) & _print, "lib3270_print" }, - { (void **) & _ebc2asc, "lib3270_ebc2asc" }, - { (void **) & _asc2ebc, "lib3270_asc2ebc" }, - - { (void **) & _action, "lib3270_action" }, - { (void **) & _set_unlock_delay, "lib3270_set_unlock_delay" }, - - { (void **) & _get_width, "lib3270_get_width" }, - { (void **) & _get_height, "lib3270_get_height" }, - { (void **) & _get_length, "lib3270_get_length" }, - - }; - - for(unsigned int f = 0; f < (sizeof (call) / sizeof ((call)[0]));f++) - { - *call[f].entry = (void *) get_symbol(call[f].name); - if(!*call[f].entry) - throw exception("Can't find symbol %s",call[f].name); - } - - // Get Session handle, setup base callbacks - set_log_handler(loghandler); - set_trace_handler(tracehandler); - - set_display_charset(); - - } - - public: - - local() throw(std::exception) : module("lib3270",PACKAGE_VERSION) - { - } - - virtual ~local() - { - } - - bool is_connected(void) - { - return _is_connected(hSession); - } - - LIB3270_CSTATE get_cstate(void) - { - return _get_connection_state(hSession); - } - - LIB3270_MESSAGE get_program_message(void) { - return _get_program_message(hSession); - } - - LIB3270_SSL_STATE get_secure(void) { - return _get_secure(hSession); - }; - - int connect(void) - { - this->lock(); - int rc = _connect(hSession,0); - this->unlock(); - - return rc; - } - - int set_url(const char *uri) - { - return (_set_url(hSession,uri) == 0); - } - - string get_url() - { - char buffer[1024]; - return string(_get_url(hSession,buffer,sizeof(buffer))); - } - - int disconnect(void) - { - this->lock(); - int rc = _disconnect(hSession); - this->unlock(); - - return rc; - } - - bool is_ready(void) - { - return _is_ready(hSession) != 0; - } - - int wait_for_ready(int seconds) - { - return _wait_for_ready(hSession,seconds); - } - - int wait(int seconds) - { - return _wait(hSession,seconds); - } - - int iterate(bool wait) - { - this->lock(); - _main_iterate(hSession,wait); - this->unlock(); - return 0; - } - - string get_text_at(int row, int col, size_t sz) - { - string rc; - char * ptr = _get_text_at(hSession,row,col,sz); - - if(ptr) - { - rc.assign(ptr); - _free(ptr); - } - - return rc; - } - - int set_text_at(int row, int col, const char *str) - { - return _set_text_at(hSession,row,col,(const unsigned char *) str); - } - - int cmp_text_at(int row, int col, const char *text) - { - return _cmp_text_at(hSession,row,col,text); - } - - string get_text(int offset, size_t len) - { - string rc; - char * ptr = _get_text(hSession,offset,len); - - if(ptr) - { - rc.assign(ptr); - _free(ptr); - } - - return rc; - } - - int set_cursor_position(int row, int col) - { - return _set_cursor_position(hSession,row,col); - } - - int set_cursor_addr(int addr) - { - return _set_cursor_addr(hSession,addr); - } - - int get_cursor_addr(void) - { - return _get_cursor_addr(hSession); - } - - int enter(void) - { - return _enter(hSession); - } - - int pfkey(int key) - { - return _pfkey(hSession,key); - } - - int pakey(int key) - { - return _pakey(hSession,key); - } - - int quit(void) - { - return EINVAL; - } - - int set_toggle(LIB3270_TOGGLE ix, bool value) - { - return _set_toggle(hSession, ix, (int) value); - } - - int emulate_input(const char *str) - { - return _emulate_input(hSession,str,-1,1); - } - - int get_field_start(int baddr) - { - return _get_field_start(hSession,baddr); - } - - int get_field_len(int baddr) - { - return _get_field_len(hSession,baddr); - } - - int get_next_unprotected(int baddr) - { - return _get_next_unprotected(hSession,baddr); - } - - int get_is_protected(int baddr) - { - return _get_is_protected(hSession,baddr); - } - - int get_is_protected_at(int row, int col) - { - return _get_is_protected_at(hSession,row,col); - } - - int popup_dialog(LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, ...) - { - va_list args; - va_start(args, fmt); - _popup_va(hSession, id, title, message, fmt, args); - va_end(args); - return 0; - } - - string get_display_charset(void) - { - return string(_get_display_charset(hSession)); - } - - int set_host_charset(const char *charset) - { - return _set_host_charset(hSession,charset); - } - - string get_host_charset(void) - { - return string(_get_host_charset(hSession)); - } - - int erase(void) - { - return _erase(hSession); - } - - int erase_eof(void) - { - return _erase_eof(hSession); - } - - int erase_eol(void) - { - return _erase_eol(hSession); - } - - int erase_input(void) - { - return _erase_input(hSession); - } - - int print(void) - { - return _print(hSession); - } - - - const char * asc2ebc(unsigned char *str, int sz) - { - return _asc2ebc(hSession,str,sz); - } - - const char * ebc2asc(unsigned char *str, int sz) - { - return _ebc2asc(hSession,str,sz); - } - - int action(const char *name) - { - return _action(hSession,name); - } - - void set_unlock_delay(unsigned short ms) - { - _set_unlock_delay(hSession,ms); - } - - int get_width(void) { - return _get_width(hSession); - } - - int get_height(void) { - return _get_height(hSession); - } - - int get_length(void) { - return _get_length(hSession); - } - - }; - - session * session::create_local(void) throw (std::exception) - { - class obj : public local { - public: - obj() : local() { - - H3270 * (*lib3270_new)(const char *) = (H3270 * (*)(const char *)) get_symbol("lib3270_session_new"); - - if(!lib3270_new) - throw exception("Can't find symbol %s","lib3270_session_new"); - - this->hSession = lib3270_new(""); - - load_methods(); - - } - - virtual ~obj() { - - this->lock(); - - if(is_connected()) { - disconnect(); - } - - try - { - static void (*session_free)(H3270 *h) = (void (*)(H3270 *)) get_symbol("lib3270_session_free"); - - if(session_free && this->hSession) - session_free(this->hSession); - - this->hSession = 0; - - } - catch(exception e) { } - - this->unlock(); - - } - }; - - return new obj(); - } - - session * session::create_local(H3270 *hSession) throw (std::exception) - { - class obj : public local { - public: - obj(H3270 *hSession) : local() - { - this->hSession = hSession; - load_methods(); - } - - virtual ~obj() { - } - - }; - - return new obj(hSession); - } - - } - diff --git a/src/pw3270cpp/module.cc b/src/pw3270cpp/module.cc deleted file mode 100644 index 1d6e982..0000000 --- a/src/pw3270cpp/module.cc +++ /dev/null @@ -1,217 +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 module.cc e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -#if defined WIN32 - - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx - #ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS - #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 - #endif // LOAD_LIBRARY_SEARCH_DEFAULT_DIRS - - #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR - #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 - #endif // LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR - - #include - -#else - - #include - -#endif - -#include - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - -namespace PW3270_NAMESPACE -{ - -#ifdef WIN32 - int module::get_datadir(LPSTR datadir) - { - HKEY hKey = 0; - unsigned long datalen = strlen(datadir); - - *datadir = 0; - - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\pw3270",0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) - { - unsigned long datatype; // #defined in winnt.h (predefined types 0-11) - if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) datadir,&datalen) != ERROR_SUCCESS) - *datadir = 0; - RegCloseKey(hKey); - } - - return *datadir; - } -#endif // WIN32 - - module::module(const char *name, const char *version) throw (std::exception) - { - string dllname = name; - -#ifdef WIN32 - - dllname += ".dll"; - if(version) - { - dllname += "."; - dllname += version; - } - - HMODULE kernel; - HANDLE cookie = NULL; - DWORD rc; - HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory); - BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie); - UINT errorMode; - char datadir[4096]; - char buffer[4096]; - - kernel = LoadLibrary("kernel32.dll"); - AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory"); - RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory"); - - // Notify user in case of error loading protocol DLL - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx - errorMode = SetErrorMode(1); - - memset(datadir,' ',4095); - datadir[4095] = 0; - - if(get_datadir(datadir)) - { - trace("Datadir=[%s] AddDllDirectory=%p RemoveDllDirectory=%p\n",datadir,AddDllDirectory,RemoveDllDirectory); - - if(AddDllDirectory) - { - wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t)); - mbstowcs(path, datadir, 4095); - cookie = AddDllDirectory(path); - free(path); - } - -#ifdef DEBUG - snprintf(buffer,4096,"%s\\.bin\\Debug\\%s",datadir,dllname.c_str()); -#else - snprintf(buffer,4096,"%s\\%s",datadir,dllname.c_str()); -#endif // DEBUG - - trace("Loading [%s] [%s]",buffer,datadir); - hModule = LoadLibrary(buffer); - - trace("Module=%p rc=%d",hModule,(int) GetLastError()); - - if(hModule == NULL) - { - // Enable DLL error popup and try again with full path - SetErrorMode(0); - hModule = LoadLibraryEx(buffer,NULL,LOAD_LIBRARY_SEARCH_DEFAULT_DIRS|LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); - } - - rc = GetLastError(); - - trace("%s hModule=%p rc=%d",buffer,hModule,(int) rc); - } - else - { - hModule = LoadLibrary(dllname.c_str()); - rc = GetLastError(); - } - - SetErrorMode(errorMode); - - trace("%s hModule=%p rc=%d",dllname.c_str(),hModule,(int) rc); - - if(cookie && RemoveDllDirectory) - RemoveDllDirectory(cookie); - - if(kernel) - FreeLibrary(kernel); - - if(!hModule) - { - throw exception("%s: %s",dllname.c_str(),session::win32_strerror(rc).c_str()); - } - -#else - dllname += ".so"; - if(version) - { - dllname += "."; - dllname += version; - } - - dlerror(); - - hModule = dlopen(dllname.c_str(), RTLD_NOW); - if(!hModule) - throw exception("Can't load lib3270: %s",dllname.c_str()); - -#endif // WIN32 - - - } - - module::~module() - { -#ifdef WIN32 - FreeLibrary(hModule); -#else - dlclose(hModule); -#endif // WIN32 - } - - - void * module::get_symbol(const char *name) - { - void *symbol; - -#ifdef WIN32 - - symbol = (void *) GetProcAddress(hModule,name); - - if(!symbol) - throw exception("Can't load symbol %s",name); - -#else - symbol = dlsym(hModule,name); - - if(!symbol) - throw exception("Can't load symbol %s dlerror was \"%s\"",name,dlerror()); - -#endif // WIN32 - - return symbol; - } - -} - diff --git a/src/pw3270cpp/private.h b/src/pw3270cpp/private.h deleted file mode 100644 index 9a422da..0000000 --- a/src/pw3270cpp/private.h +++ /dev/null @@ -1,113 +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 private.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) - * - */ - -#ifndef PRIVATE_H_INCLUDED - - #define PRIVATE_H_INCLUDED - - #include - #include - - #if defined(_WIN32) - - class recursive_mutex { - private: - HANDLE hMutex; - - public: - recursive_mutex() { - hMutex = CreateMutex(NULL,FALSE,NULL); - }; - - ~recursive_mutex() { - CloseHandle(hMutex); - }; - - void lock(void) { - WaitForSingleObject(hMutex,INFINITE); - }; - - void unlock(void) { - ReleaseMutex(hMutex); - }; - - bool try_lock(void) { - if(WaitForSingleObject(hMutex,1) == WAIT_OBJECT_0) - return true; - return false; - }; - }; - - #elif __cplusplus < 201103L - - #define nullptr NULL - - class recursive_mutex { - private: - pthread_mutex_t mtx; - pthread_mutexattr_t mtxAttr; - - public: - recursive_mutex() { - - memset(&mtx,0,sizeof(mtx)); - memset(&mtxAttr,0,sizeof(mtxAttr)); - - pthread_mutexattr_init(&mtxAttr); - pthread_mutexattr_settype(&mtxAttr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&mtx, &mtxAttr); - }; - - ~recursive_mutex() { - pthread_mutex_destroy(&mtx); - }; - - void lock(void) { - pthread_mutex_lock(&mtx); - }; - - void unlock(void) { - pthread_mutex_unlock(&mtx); - }; - - bool try_lock(void) { - return pthread_mutex_trylock(&mtx) == 0; - }; - }; - - #else - - #include - - #endif // !c11 - - - - -#endif // PRIVATE_H_INCLUDED diff --git a/src/pw3270cpp/remote.cc b/src/pw3270cpp/remote.cc deleted file mode 100644 index eb32179..0000000 --- a/src/pw3270cpp/remote.cc +++ /dev/null @@ -1,1599 +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 remote.cc e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - - #include - #include - - #if defined(HAVE_DBUS) - #include - #include - #include - #include - #include - #include - #include - - #ifndef DBUS_TIMEOUT_INFINITE - #define DBUS_TIMEOUT_INFINITE ((int) 0x7fffffff) - #endif // !DBUS_TIMEOUT_INFINITE - - #endif // HAVE_DBUS - - #if defined(WIN32) - #include - #include - #include - #else - #define HLLAPI_PACKET_IS_CONNECTED "isConnected" - #define HLLAPI_PACKET_GET_CSTATE "getConnectionState" - #define HLLAPI_PACKET_GET_PROGRAM_MESSAGE "getProgramMessage" - #define HLLAPI_PACKET_GET_SSL_STATE "getSecureState" - #define HLLAPI_PACKET_IS_READY "isReady" - #define HLLAPI_PACKET_DISCONNECT "disconnect" - #define HLLAPI_PACKET_GET_HOST "getURL" - #define HLLAPI_PACKET_SET_HOST "setURL" - #define HLLAPI_PACKET_GET_CURSOR "getCursorAddress" - #define HLLAPI_PACKET_GET_WIDTH "getScreenWidth" - #define HLLAPI_PACKET_GET_HEIGHT "getScreenHeight" - #define HLLAPI_PACKET_GET_LENGTH "getScreenLength" - #define HLLAPI_PACKET_ENTER "enter" - #define HLLAPI_PACKET_QUIT "quit" - #define HLLAPI_PACKET_ERASE "erase" - #define HLLAPI_PACKET_ERASE_EOF "eraseEOF" - #define HLLAPI_PACKET_ERASE_EOL "eraseEOL" - #define HLLAPI_PACKET_ERASE_INPUT "eraseInput" - #define HLLAPI_PACKET_PRINT "print" - #define HLLAPI_PACKET_ASC2EBC "asc2ebc" - #define HLLAPI_PACKET_EBC2ASC "ebc2asc" - #define HLLAPI_PACKET_SET_UNLOCK_DELAY "setUnlockDelay" - #endif // WIN32 - - #include - #include - -#if defined(HAVE_DBUS) - static const char * prefix_dest = "br.com.bb."; - static const char * prefix_path = "/br/com/bb/"; -#endif // HAVE_DBUS - -/*--[ Implement ]--------------------------------------------------------------------------------------------------*/ - - namespace PW3270_NAMESPACE - { - - class remote : public session - { - private: - -#if defined(WIN32) - - HANDLE hPipe; - - int query_intval(HLLAPI_PACKET id) - { - struct hllapi_packet_query query = { id }; - struct hllapi_packet_result response; - DWORD cbSize = sizeof(query); - if(TransactNamedPipe(hPipe,(LPVOID) &query, cbSize, &response, sizeof(response), &cbSize,NULL)) - return response.rc; - - throw exception(GetLastError(),"%s","Transaction error"); - } - - int query_strval(HLLAPI_PACKET id, unsigned char *buffer, size_t sz) - { - DWORD cbSize = sizeof(struct hllapi_packet_text)+sz; - struct hllapi_packet_text * query; - struct hllapi_packet_text * response; - int rc = -1; - - query = (struct hllapi_packet_text *) malloc(cbSize+2); - memset(query,0,cbSize+2); - query->packet_id = id; - memcpy(query->text,buffer,sz); - - response = (struct hllapi_packet_text *) malloc(cbSize+2); - memset(response,0,cbSize+2); - - if(TransactNamedPipe(hPipe,(LPVOID) query, cbSize, &response, cbSize, &cbSize,NULL)) - { - if(response->packet_id) - { - rc = response->packet_id; - } - else - { - rc = 0; - strncpy((char *) buffer,response->text,sz); - } - } - - free(response); - free(query); - - return rc; - - } - - string query_string(void *query, size_t szQuery, size_t len) - { - struct hllapi_packet_text * response; - DWORD sz = sizeof(struct hllapi_packet_text)+len; - DWORD cbSize = (DWORD) sz; - string s; - char buffer[sz+2]; - - memset(buffer,0,sz+2); - - response = (struct hllapi_packet_text *) buffer; - - if(TransactNamedPipe(hPipe,(LPVOID) query, szQuery, response, sz, &cbSize,NULL)) - { - buffer[min(cbSize,sz)] = 0; - - trace("TransactNamedPipe call %d returns \"%s\"",(int) *( (unsigned char *) query), response->text); - - if(!response->packet_id) - s.assign(response->text); - } - else - { - trace("TransactNamedPipe error on call %d",(int) *( (unsigned char *) query)); - s.assign(""); - } - - return s; - } - - int query_intval(void *pkt, size_t szQuery, bool dynamic = false) - { - struct hllapi_packet_result response; - DWORD cbSize = (DWORD) szQuery; - BOOL status; - - status = TransactNamedPipe(hPipe,(LPVOID) pkt, cbSize, &response, sizeof(response), &cbSize,NULL); - - if(dynamic) - free(pkt); - - if(status) - return response.rc; - - throw exception(GetLastError(),"%s","Transaction error"); - - } - - void set_intval(HLLAPI_PACKET id, int value) - { - struct hllapi_packet_set_int packet; - DWORD cbSize = (DWORD) sizeof(packet); - BOOL status; - - memset(&packet,0,sizeof(packet)); - packet.packet_id = id; - packet.value = value; - - status = TransactNamedPipe(hPipe,(LPVOID) &packet, cbSize, &packet, sizeof(packet), &cbSize,NULL); - - if(!status) - throw exception(GetLastError(),"%s","Transaction error"); - - } - - -#elif defined(HAVE_DBUS) - - DBusConnection * conn; - char * dest; - char * path; - char * intf; - int sequence; - - DBusMessage * create_message(const char *method) - { - DBusMessage * msg = dbus_message_new_method_call( this->dest, // Destination - this->path, // Path - this->intf, // Interface - method); // method - - if (!msg) - throw exception("Error creating DBUS message for method %s",method); - - return msg; - - } - - DBusMessage * call(DBusMessage *msg) - { - DBusMessage * reply; - DBusError error; - - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(conn,msg,10000,&error); - dbus_message_unref(msg); - - if(!reply) - { - exception e = exception("%s",error.message); - dbus_error_free(&error); - throw e; - } - return reply; - } - - string get_string(DBusMessage * msg) - { - string rc; - - if(msg) - { - DBusMessageIter iter; - - if(dbus_message_iter_init(msg, &iter)) - { - if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) - { - const char * str; - dbus_message_iter_get_basic(&iter, &str); - trace("Response: [%s]",str); - rc.assign(str); - dbus_message_unref(msg); - return rc; - } - - exception e = exception("DBUS Return type was %c, expecting %c",dbus_message_iter_get_arg_type(&iter),DBUS_TYPE_INT32); - dbus_message_unref(msg); - - throw e; - - } - - } - - return rc; - } - - string query_string(const char *method) - { - return get_string(call(create_message(method))); - } - - int get_intval(DBusMessage * msg) - { - if(msg) - { - DBusMessageIter iter; - - if(dbus_message_iter_init(msg, &iter)) - { - if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT32) - { - dbus_int32_t iSigned; - dbus_message_iter_get_basic(&iter, &iSigned); - dbus_message_unref(msg); - return (int) iSigned; - } - - exception e = exception("DBUS Return type was %c, expecting %c",dbus_message_iter_get_arg_type(&iter),DBUS_TYPE_INT32); - - dbus_message_unref(msg); - throw e; - return -1; - } - dbus_message_unref(msg); - } - return -1; - } - - int query_intval(const char *method) - { - return get_intval(call(create_message(method))); - } - - int query_intval(const char *method, int first_arg_type, ...) - { - va_list var_args; - DBusMessage * msg = dbus_message_new_method_call( this->dest, // Destination - this->path, // Path - this->intf, // Interface - method); // method - - if (!msg) - { - throw exception("Error creating DBUS message for method %s",method); - return -1; - } - - va_start(var_args, first_arg_type); - dbus_message_append_args_valist(msg,first_arg_type,var_args); - va_end(var_args); - - return get_intval(call(msg)); - } - - int query_strval(const char *method, unsigned char *buffer, size_t sz) - { - DBusMessage * outMsg = create_message(method); - - if(outMsg) - { - dbus_message_append_args(outMsg, DBUS_TYPE_STRING, &buffer, DBUS_TYPE_INVALID); - - DBusMessage * rspMsg = call(outMsg); - if(rspMsg) - { - DBusMessageIter iter; - - if(dbus_message_iter_init(rspMsg, &iter)) - { - if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) - { - const char * str; - dbus_message_iter_get_basic(&iter, &str); - trace("Response: [%s]",str); - strncpy((char *) buffer,str,sz); - dbus_message_unref(rspMsg); - return 0; - } - - exception e = exception("DBUS Return type was %c, expecting %c",dbus_message_iter_get_arg_type(&iter),DBUS_TYPE_INT32); - dbus_message_unref(rspMsg); - - throw e; - - } - } - } - - return -1; - } - - void set_intval(const char *method, int value) - { - DBusMessage * outMsg = create_message(method); - - if(outMsg) - { - dbus_int32_t v = (dbus_int32_t) value; - - dbus_message_append_args(outMsg, DBUS_TYPE_INT32, &v, DBUS_TYPE_INVALID); - - DBusMessage * rspMsg = call(outMsg); - dbus_message_unref(rspMsg); - - } - } - -#else - - - int query_intval(const char *method) - { - throw exception("Call to unimplemented RPC method \"%s\"",method); - return -1; - } - - int query_strval(const char *method, unsigned char *buffer, size_t sz) - { - throw exception("Call to unimplemented RPC method \"%s\"",method); - return -1; - } - - -#endif - - public: - -#if defined(HAVE_DBUS) - const char * makeBusName(char *buffer, size_t sz) - { - size_t bytes = strlen(buffer); - char * ptr = buffer; - int val; - - sz -= 2; - - // First uses the object ID - val = this->sequence; - while(bytes < sz && val > 0) - { - *(ptr++) = 'a'+(val % 25); - val /= 25; - bytes++; - } - *(ptr++) = '.'; - - // Then the PID - val = (int) getpid(); - while(bytes < sz && val > 0) - { - *(ptr++) = 'a'+(val % 25); - val /= 25; - bytes++; - } - *(ptr++) = '.'; - - // And last, the project info - strncpy(ptr,intf,sz); - - trace("Busname=\"%s\" sequence=%d this=%p",buffer,sequence,this); - - return buffer; - - } -#endif // HAVE_DBUS - -#if defined(WIN32) - - static string getRegistryKey(const char *name) throw (std::exception) - { - char buffer[4096]; - HKEY hKey = 0; - unsigned long datalen = sizeof(buffer); - - debug("%s(%s)",__FUNCTION__,name); - - *buffer = 0; - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\pw3270",0,KEY_QUERY_VALUE,&hKey) != ERROR_SUCCESS) - { - throw exception("Can't open key %s","HKLM\\Software\\pw3270"); - } - else - { - unsigned long datatype; // #defined in winnt.h (predefined types 0-11) - - if(RegQueryValueExA(hKey,name,NULL,&datatype,(LPBYTE) buffer,&datalen) != ERROR_SUCCESS) - *buffer = 0; - RegCloseKey(hKey); - } - - return string(buffer); - - } - -#endif // defined - - remote(const char *session) throw (std::exception) - { -#if defined(WIN32) - static DWORD dwMode = PIPE_READMODE_MESSAGE; - char buffer[4096]; - char * str; - char * ptr; - time_t timer = time(0)+1; - - hPipe = INVALID_HANDLE_VALUE; - - trace("%s(%s)",__FUNCTION__,session); - - if(strcasecmp(session,"start") == 0 || strcasecmp(session,"new") == 0) - { - // Start a new session - string appName = getRegistryKey("appName"); - char buffer[80]; - STARTUPINFO si; - PROCESS_INFORMATION pi; - - // Get application path - - if(!appName.size()) - { - throw exception("key %s\\appName is invalid","HKLM\\Software\\pw3270"); - return; - } - - trace("%s appname=%s\n",__FUNCTION__,appName.c_str()); - - snprintf(buffer,79,"%s --session=\"H%06d\"",appName.c_str(),getpid()); - - ZeroMemory( &si, sizeof(si) ); - si.cb = sizeof(si); - ZeroMemory( &pi, sizeof(pi) ); - - // si.dwFlags = STARTF_PREVENTPINNING; - trace("App: %s",appName.c_str()); - trace("CmdLine: %s",buffer); - - if(CreateProcess(NULL,buffer,NULL,NULL,0,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi)) - { - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - } - else - { - throw exception("Can't start %s",appName.c_str()); - return; - } - - snprintf(buffer,4095,"H%06d_a",getpid()); - str = strdup(buffer); - - // Até 20 segundos para o processo iniciar. - timer = time(0)+20; - - } - else - { - // Use an existing session - str = strdup(session); - - // Convert session name - for(ptr=str;*ptr;ptr++) - { - if(*ptr == ':') - *ptr = '_'; - else - *ptr = tolower(*ptr); - } - - // Wait? - int delay; - - try - { - delay = atoi(getRegistryKey("hllapiWait").c_str()); - } - catch(std::exception &e) - { - delay = 0; - } - - if(delay) { - timer = time(0) + delay; - } - - - } - - snprintf(buffer,4095,"\\\\.\\pipe\\%s",str); - - free(str); - - trace("Searching for \"%s\"",buffer); - - hPipe = CreateFile(buffer,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); - - if(hPipe == INVALID_HANDLE_VALUE) - { - // Cant get session, wait. - while(hPipe == INVALID_HANDLE_VALUE && time(0) < timer) - { - hPipe = CreateFile(buffer,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); - Sleep(1); - } - } - - if(hPipe == INVALID_HANDLE_VALUE) - { - throw exception("Can´t create service pipe %s",buffer); - } - else if(!SetNamedPipeHandleState(hPipe,&dwMode,NULL,NULL)) - { - exception e = exception(GetLastError(),"%s","Can´t set pipe state"); - CloseHandle(hPipe); - hPipe = INVALID_HANDLE_VALUE; - throw e; - } - -#elif defined(HAVE_DBUS) - - static int sq = 0; - DBusError err; - int rc; - char * str = strdup(session); - char * ptr; - char busname[4096]; - - this->sequence = (++sq) + time(0); - - trace("%s str=%p sequence=%d",__FUNCTION__,str,sequence); - - for(ptr=str;*ptr;ptr++) - *ptr = tolower(*ptr); - - ptr = strchr(str,':'); - - if(ptr) - { - size_t sz; - - *(ptr++) = 0; - - // Build destination - sz = strlen(ptr)+strlen(str)+strlen(prefix_dest)+2; - dest = (char *) malloc(sz+1); - strncpy(dest,prefix_dest,sz); - strncat(dest,str,sz); - strncat(dest,".",sz); - strncat(dest,ptr,sz); - - // Build path - sz = strlen(str)+strlen(prefix_path); - path = (char *) malloc(sz+1); - strncpy(path,prefix_path,sz); - strncat(path,str,sz); - - // Build intf - sz = strlen(str)+strlen(prefix_dest)+1; - intf = (char *) malloc(sz+1); - strncpy(intf,prefix_dest,sz); - strncat(intf,str,sz); - - } - else - { - size_t sz; - - // Build destination - sz = strlen(str)+strlen(prefix_dest)+2; - dest = (char *) malloc(sz+1); - strncpy(dest,prefix_dest,sz); - strncat(dest,str,sz); - - // Build path - sz = strlen(str)+strlen(prefix_path); - path = (char *) malloc(sz+1); - strncpy(path,prefix_path,sz); - strncat(path,str,sz); - - // Build intf - sz = strlen(str)+strlen(prefix_dest)+1; - intf = (char *) malloc(sz+1); - strncpy(intf,prefix_dest,sz); - strncat(intf,str,sz); - - } - - trace("DBUS:\nDestination:\t[%s]\nPath:\t\t[%s]\nInterface:\t[%s]",dest,path,intf); - - free(str); - - dbus_error_init(&err); - - conn = dbus_bus_get(DBUS_BUS_SESSION, &err); - trace("dbus_bus_get conn=%p",conn); - - if (dbus_error_is_set(&err)) - { - exception e = exception("DBUS Connection Error (%s)", err.message); - dbus_error_free(&err); - throw e; - return; - } - - if(!conn) - { - throw exception("%s", "DBUS Connection failed"); - return; - } - - - rc = dbus_bus_request_name(conn, makeBusName(busname,4095), DBUS_NAME_FLAG_REPLACE_EXISTING , &err); - trace("dbus_bus_request_name(%s) rc=%d",busname,rc); - - if (dbus_error_is_set(&err)) - { - exception e = exception("Name Error (%s)", err.message); - dbus_error_free(&err); - throw e; - return; - } - - if(rc != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) - { - trace("%s: DBUS request for name %s failed",__FUNCTION__, busname); - throw exception("DBUS request for \"%s\" failed",session); - return; - } - - trace("%s: Using DBUS name %s",__FUNCTION__,busname); - - const char * id = "r"; - static const dbus_int32_t flag = 1; - query_intval("setScript", DBUS_TYPE_STRING, &id, DBUS_TYPE_INT32, &flag, DBUS_TYPE_INVALID); - - -#else - - throw exception("%s","RPC support is incomplete."); - -#endif - } - - virtual ~remote() - { -#if defined(WIN32) - - if(hPipe != INVALID_HANDLE_VALUE) - CloseHandle(hPipe); - -#elif defined(HAVE_DBUS) - - try - { - const char * id = "r"; - static const dbus_int32_t flag = 0; - query_intval("setScript", DBUS_TYPE_STRING, &id, DBUS_TYPE_INT32, &flag, DBUS_TYPE_INVALID); - } - catch(exception e) - { - std::cerr << e.what(); - } - - char busname[4096]; - makeBusName(busname,4096); - - free(dest); - free(path); - free(intf); - - DBusError err; - - dbus_error_init(&err); - dbus_bus_release_name(conn,busname,&err); - - if (dbus_error_is_set(&err)) - { - //exception e = exception("Error when releasing DBUS name (%s)", err.message); - std::cerr << err.message; - dbus_error_free(&err); - //throw e; - } - -#else - -#endif - } - - bool is_connected(void) - { - return query_intval(HLLAPI_PACKET_IS_CONNECTED) != 0; - } - - LIB3270_CSTATE get_cstate(void) - { - return (LIB3270_CSTATE) query_intval(HLLAPI_PACKET_GET_CSTATE); - } - - LIB3270_MESSAGE get_program_message(void) { - return (LIB3270_MESSAGE) query_intval(HLLAPI_PACKET_GET_PROGRAM_MESSAGE); - } - - LIB3270_SSL_STATE get_secure(void) { - return (LIB3270_SSL_STATE) query_intval(HLLAPI_PACKET_GET_SSL_STATE); - } - - - int connect(void) - { - int rc; - -#if defined(WIN32) - - size_t cbSize = sizeof(struct hllapi_packet_connect); - struct hllapi_packet_connect * pkt = (struct hllapi_packet_connect *) malloc(cbSize); - - memset(pkt,0,cbSize); - - pkt->packet_id = HLLAPI_PACKET_CONNECT; - pkt->wait = 0; - - rc = query_intval((void *) pkt,cbSize,true); - -#elif defined(HAVE_DBUS) - - static const char * str = ""; - - rc = query_intval("connect", DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); - -#else - rc = -1; - -#endif - return rc; - - } - - int set_url(const char *uri) - { - int rc; - -#if defined(WIN32) - - size_t cbSize = sizeof(struct hllapi_packet_text)+strlen(uri); - struct hllapi_packet_text * pkt = (struct hllapi_packet_text *) malloc(cbSize); - - pkt->packet_id = HLLAPI_PACKET_SET_HOST; - strcpy(pkt->text,uri); - - rc = query_intval((void *) pkt,cbSize,true); - -#elif defined(HAVE_DBUS) - - rc = query_intval(HLLAPI_PACKET_SET_HOST, DBUS_TYPE_STRING, &uri, DBUS_TYPE_INVALID); - -#else - - rc = -1; - -#endif - - return rc; - - } - - string get_url() - { -#if defined(WIN32) - - struct hllapi_packet_query query = { HLLAPI_PACKET_GET_HOST }; - return query_string(&query,sizeof(query),1024); - -#elif defined(HAVE_DBUS) - - return query_string(HLLAPI_PACKET_GET_HOST); - -#else - return string(); -#endif - } - - int wait_for_ready(int seconds) - { -#if defined(WIN32) - - time_t end = time(0)+seconds; - - while(time(0) < end) - { - if(!is_connected()) - return ENOTCONN; - - if(is_ready()) - return 0; - - Sleep(250); - } - - return ETIMEDOUT; - -#elif defined(HAVE_DBUS) - - time_t end = time(0)+seconds; - - while(time(0) < end) - { - static const dbus_int32_t delay = 2; - - int rc = query_intval("waitForReady", DBUS_TYPE_INT32, &delay, DBUS_TYPE_INVALID); - - trace("waitForReady exits with rc=%d",rc); - - if(rc != ETIMEDOUT) - return rc; - } - - return ETIMEDOUT; - -#else - - return -1; - -#endif - - } - - bool is_ready(void) - { - return query_intval(HLLAPI_PACKET_IS_READY) != 0; - } - - - int disconnect(void) - { - return query_intval(HLLAPI_PACKET_DISCONNECT); - } - - - int wait(int seconds) - { -#if defined(WIN32) - - time_t end = time(0)+seconds; - - while(time(0) < end) - { - if(!is_connected()) - return ENOTCONN; - Sleep(500); - } - - return 0; - -#elif defined(HAVE_DBUS) - - time_t end = time(0)+seconds; - - while(time(0) < end) - { - if(!is_connected()) - return ENOTCONN; - usleep(500); - } - - return 0; - -#else - - return -1; - -#endif - - } - - int iterate(bool wait) - { -#if defined(WIN32) - if(wait) - Sleep(250); - return 0; -#elif defined(HAVE_DBUS) - if(wait) - usleep(250); - return 0; -#else - return -1; -#endif - } - - string get_text_at(int row, int col, size_t sz) - { -#if defined(WIN32) - - struct hllapi_packet_query_at query = { HLLAPI_PACKET_GET_TEXT_AT, (unsigned short) row, (unsigned short) col, (unsigned short) sz }; - - return query_string(&query,sizeof(query),sz); - -#elif defined(HAVE_DBUS) - - dbus_int32_t r = (dbus_int32_t) row; - dbus_int32_t c = (dbus_int32_t) col; - dbus_int32_t l = (dbus_int32_t) sz; - - DBusMessage * msg = create_message("getTextAt"); - if(!msg) - return NULL; - - trace("%s(%d,%d,%d)",__FUNCTION__,r,c,l); - dbus_message_append_args(msg, DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_INT32, &l, DBUS_TYPE_INVALID); - - return get_string(call(msg)); - -#else - - return string(); - -#endif - - } - - int set_text_at(int row, int col, const char *str) - { -#if defined(WIN32) - - struct hllapi_packet_text_at * query; - struct hllapi_packet_result response; - DWORD cbSize = sizeof(struct hllapi_packet_text_at)+strlen((const char *) str); - - query = (struct hllapi_packet_text_at *) malloc(cbSize); - query->packet_id = HLLAPI_PACKET_SET_TEXT_AT; - query->row = row; - query->col = col; - strcpy(query->text,(const char *) str); - - TransactNamedPipe(hPipe,(LPVOID) query, cbSize, &response, sizeof(response), &cbSize,NULL); - - free(query); - - return response.rc; - -#elif defined(HAVE_DBUS) - - dbus_int32_t r = (dbus_int32_t) row; - dbus_int32_t c = (dbus_int32_t) col; - - return query_intval("setTextAt", DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); - -#else - - return -1; - -#endif - - } - - int cmp_text_at(int row, int col, const char *text) - { - debug("%s(%d,%d,\"%s\")",__FUNCTION__,row,col,text); - -#if defined(WIN32) - - struct hllapi_packet_text_at * query; - size_t cbSize = sizeof(struct hllapi_packet_text_at)+strlen(text); - - query = (struct hllapi_packet_text_at *) malloc(cbSize); - query->packet_id = HLLAPI_PACKET_CMP_TEXT_AT; - query->row = row; - query->col = col; - strcpy(query->text,text); - - return query_intval((void *) query, cbSize, true); - -#elif defined(HAVE_DBUS) - - dbus_int32_t r = (dbus_int32_t) row; - dbus_int32_t c = (dbus_int32_t) col; - - return query_intval("cmpTextAt", DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID); - -#endif - - return 0; - } - - int wait_for_text_at(int row, int col, const char *key, int timeout) - { - time_t end = time(0)+timeout; - - while(time(0) < end) - { - if(!is_connected()) - return ENOTCONN; - - if(!cmp_text_at(row,col,key)) - return 0; - -#ifdef WIN32 - Sleep(500); -#else - usleep(500); -#endif - } - - return ETIMEDOUT; - } - - string get_text(int baddr, size_t len) - { -#if defined(WIN32) - struct hllapi_packet_query_offset query = { HLLAPI_PACKET_GET_TEXT_AT_OFFSET, (unsigned short) baddr, (unsigned short) len }; - return query_string(&query,sizeof(query),len); - -#elif defined(HAVE_DBUS) - - dbus_int32_t b = (dbus_int32_t) baddr; - dbus_int32_t l = (dbus_int32_t) len; - - DBusMessage * msg = create_message("getText"); - if(!msg) - return NULL; - - trace("%s(%d,%d)",__FUNCTION__,b,l); - dbus_message_append_args(msg, DBUS_TYPE_INT32, &b, DBUS_TYPE_INT32, &l, DBUS_TYPE_INVALID); - - return get_string(call(msg)); -#else - throw exception("%s","IPC support is unavailable"); - return string(); -#endif - } - - - int set_cursor_position(int row, int col) - { -#if defined(WIN32) - - struct hllapi_packet_cursor query = { HLLAPI_PACKET_SET_CURSOR_POSITION, (unsigned short) row, (unsigned short) col }; - - return query_intval((void *) &query, sizeof(query)); - -#elif defined(HAVE_DBUS) - - dbus_int32_t r = (dbus_int32_t) row; - dbus_int32_t c = (dbus_int32_t) col; - - return query_intval("setCursorAt", DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_INVALID); - -#endif - - return -1; - } - - int set_cursor_addr(int addr) - { -#if defined(WIN32) - - struct hllapi_packet_addr query = { HLLAPI_PACKET_SET_CURSOR, (unsigned short) addr }; - - return query_intval((void *) &query, sizeof(query)); - -#elif defined(HAVE_DBUS) - - dbus_int32_t k = (dbus_int32_t) addr; - - return query_intval("setCursorAddress", DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); - -#endif - - return -1; - } - - int get_cursor_addr(void) - { - return query_intval(HLLAPI_PACKET_GET_CURSOR); - } - - int get_width(void) { - return query_intval(HLLAPI_PACKET_GET_WIDTH); - } - - int get_height(void) { - return query_intval(HLLAPI_PACKET_GET_HEIGHT); - } - - int get_length(void) { - return query_intval(HLLAPI_PACKET_GET_LENGTH); - } - - int enter(void) - { - return query_intval(HLLAPI_PACKET_ENTER); - } - - int pfkey(int key) - { -#if defined(WIN32) - - struct hllapi_packet_keycode query = { HLLAPI_PACKET_PFKEY, (unsigned short) key }; - - return query_intval((void *) &query, sizeof(query)); - -#elif defined(HAVE_DBUS) - - dbus_int32_t k = (dbus_int32_t) key; - - return query_intval("pfKey", DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); - -#else - - return -1; - -#endif - - } - - int pakey(int key) - { -#if defined(WIN32) - - struct hllapi_packet_keycode query = { HLLAPI_PACKET_PAKEY, (unsigned short) key }; - - return query_intval((void *) &query, sizeof(query)); - -#elif defined(HAVE_DBUS) - - dbus_int32_t k = (dbus_int32_t) key; - - return query_intval("paKey", DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); - -#else - - return -1; - -#endif - - } - - int quit(void) - { - return query_intval(HLLAPI_PACKET_QUIT); - } - - int set_toggle(LIB3270_TOGGLE ix, bool value) - { -#if defined(WIN32) - - struct hllapi_packet_set query = { HLLAPI_PACKET_SET_TOGGLE, (unsigned short) ix, (unsigned short) value }; - - return query_intval((void *) &query, sizeof(query)); - -#elif defined(HAVE_DBUS) - - dbus_int32_t i = (dbus_int32_t) ix; - dbus_int32_t v = (dbus_int32_t) value; - - return query_intval("setToggle", DBUS_TYPE_INT32, &i, DBUS_TYPE_INT32, &v, DBUS_TYPE_INVALID); - -#else - return -1; - -#endif - - } - - int emulate_input(const char *str) - { -#if defined(WIN32) - - size_t len = strlen(str); - struct hllapi_packet_emulate_input * query; - size_t cbSize = sizeof(struct hllapi_packet_emulate_input)+len; - - query = (struct hllapi_packet_emulate_input *) malloc(cbSize); - query->packet_id = HLLAPI_PACKET_EMULATE_INPUT; - query->len = len; - query->pasting = 1; - strcpy(query->text,str); - - return query_intval((void *) query, cbSize, true); - -#elif defined(HAVE_DBUS) - - return query_intval("input", DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); -#else - - return -1; - -#endif - - } - - int action(const char *str) - { - -#if defined(WIN32) - - size_t len = strlen(str); - struct hllapi_packet_text * query; - size_t cbSize = sizeof(struct hllapi_packet_text)+len; - - query = (struct hllapi_packet_text *) malloc(cbSize); - query->packet_id = HLLAPI_PACKET_ACTION; - strcpy(query->text,str); - - return query_intval((void *) query, cbSize, true); - -#elif defined(HAVE_DBUS) - - return query_intval("action", DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); -#else - - return -1; - -#endif - - } - - - int get_field_start(int baddr) - { -#if defined(WIN32) - - struct hllapi_packet_addr query = { HLLAPI_PACKET_FIELD_START, (unsigned short) baddr }; - - return query_intval((void *) &query, sizeof(query)); - -#elif defined(HAVE_DBUS) - - dbus_int32_t k = (dbus_int32_t) baddr; - - return query_intval("getFieldStart", DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); - -#else - - return -1; - -#endif - - } - - int get_field_len(int baddr) - { -#if defined(WIN32) - - struct hllapi_packet_addr query = { HLLAPI_PACKET_FIELD_LEN, (unsigned short) baddr }; - - return query_intval((void *) &query, sizeof(query)); - -#elif defined(HAVE_DBUS) - - dbus_int32_t k = (dbus_int32_t) baddr; - - return query_intval("getFieldLength", DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); - -#else - - return -1; - -#endif - } - - int get_next_unprotected(int baddr) - { -#if defined(WIN32) - - struct hllapi_packet_addr query = { HLLAPI_PACKET_NEXT_UNPROTECTED, (unsigned short) baddr }; - - return query_intval((void *) &query, sizeof(query)); - -#elif defined(HAVE_DBUS) - - dbus_int32_t k = (dbus_int32_t) baddr; - - DBusMessage * msg = create_message("getNextUnprotected"); - if(msg) - { - dbus_message_append_args(msg, DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); - return get_intval(call(msg)); - } - - return -1; - -#else - - return -1; - -#endif - - } - - int get_is_protected(int baddr) - { -#if defined(WIN32) - - struct hllapi_packet_addr query = { HLLAPI_PACKET_IS_PROTECTED, (unsigned short) baddr }; - - return query_intval((void *) &query, sizeof(query)); - -#elif defined(HAVE_DBUS) - - dbus_int32_t k = (dbus_int32_t) baddr; - - DBusMessage * msg = create_message("getIsProtected"); - if(msg) - { - dbus_message_append_args(msg, DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); - return get_intval(call(msg)); - } - - return -1; - -#else - - return -1; - -#endif - - } - - int get_is_protected_at(int row,int col) - { -#if defined(WIN32) - - struct hllapi_packet_query_at query = { HLLAPI_PACKET_IS_PROTECTED_AT, (unsigned short) row, (unsigned short) col, 0 }; - - return query_intval((void *) &query, sizeof(query)); - -#elif defined(HAVE_DBUS) - - dbus_int32_t r = (dbus_int32_t) row; - dbus_int32_t c = (dbus_int32_t) col; - - DBusMessage * msg = create_message("getIsProtectedAt"); - if(msg) - { - dbus_message_append_args(msg, DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_INVALID); - return get_intval(call(msg)); - } - - return -1; - -#else - - return -1; - -#endif - - } - - - int set_host_charset(const char *charset) - { -#if defined(WIN32) - - size_t len = strlen(charset); - struct hllapi_packet_set_text * query; - size_t cbSize = sizeof(struct hllapi_packet_set_text)+len; - - query = (struct hllapi_packet_set_text *) malloc(cbSize); - query->packet_id = HLLAPI_PACKET_SET_HOST_CHARSET; - query->len = len; - strcpy(query->text,charset); - - return query_intval((void *) query, cbSize, true); - -#elif defined(HAVE_DBUS) - - return query_intval("setHostCharset", DBUS_TYPE_STRING, &charset, DBUS_TYPE_INVALID); - -#else - return -1; -#endif - } - - string get_host_charset(void) - { -#if defined(WIN32) - - struct hllapi_packet_query query = { HLLAPI_PACKET_GET_HOST_CHARSET }; - return query_string(&query,sizeof(query),100); - -#elif defined(HAVE_DBUS) - - return query_string("getHostCharset"); - -#else - - return NULL; - -#endif - } - - -#if defined(HAVE_DBUS) - string get_clipboard(void) - { - return query_string("getClipboard"); - } - - int set_clipboard(const char *text) - { - return query_intval("setClipboard", DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID); - } - - string get_display_charset(void) - { - return query_string("getDisplayCharset"); - } - - int popup_dialog(LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, ...) - { - DBusMessage * msg = dbus_message_new_method_call( this->dest, // Destination - this->path, // Path - this->intf, // Interface - "showPopup"); // method - - if (!msg) - { - throw exception("%s","Error creating DBUS message for popup"); - return -1; - } - else - { - char text[4096]; - char * ptr = text; - va_list arg_ptr; - dbus_int32_t i = (dbus_int32_t) id; - - va_start(arg_ptr, fmt); - vsnprintf(text,4095,fmt,arg_ptr); - va_end(arg_ptr); - - if(!dbus_message_append_args(msg, DBUS_TYPE_INT32, &i, DBUS_TYPE_STRING, &title, DBUS_TYPE_STRING, &message, DBUS_TYPE_STRING, &ptr, DBUS_TYPE_INVALID)) - { - dbus_message_unref(msg); - throw exception("%s","Cant append args for popup message"); - } - else - { - DBusMessage * reply; - DBusError error; - - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(conn,msg,DBUS_TIMEOUT_INFINITE,&error); - dbus_message_unref(msg); - - if(!reply) - { - exception e = exception("%s",error.message); - dbus_error_free(&error); - throw e; - return -1; - } - - return get_intval(reply); - - } - } - return 0; - } - -#endif // HAVE_DBUS - - int erase(void) - { - return query_intval(HLLAPI_PACKET_ERASE); - } - - int erase_eof(void) - { - return query_intval(HLLAPI_PACKET_ERASE_EOF); - } - - int erase_eol(void) - { - return query_intval(HLLAPI_PACKET_ERASE_EOL); - } - - int erase_input(void) - { - return query_intval(HLLAPI_PACKET_ERASE_INPUT); - } - - int print(void) - { - return query_intval(HLLAPI_PACKET_PRINT); - } - - const char * asc2ebc(unsigned char *text, int sz) - { - query_strval(HLLAPI_PACKET_ASC2EBC,text,sz); - return (const char *) text; - } - - const char * ebc2asc(unsigned char *text, int sz) - { - query_strval(HLLAPI_PACKET_EBC2ASC,text,sz); - return (const char *) text; - } - - void set_unlock_delay(unsigned short ms) - { - set_intval(HLLAPI_PACKET_SET_UNLOCK_DELAY,(int) ms); - } - - }; - - session * session::create_remote(const char *session) throw (std::exception) - { - return new remote(session); - } - - } - diff --git a/src/pw3270cpp/session.cc b/src/pw3270cpp/session.cc deleted file mode 100644 index ef0ee52..0000000 --- a/src/pw3270cpp/session.cc +++ /dev/null @@ -1,698 +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 session.cc e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - - #include - #include - #include - #include - - #include "private.h" - -#ifndef WIN32 - #include -#endif // !WIN32 - -#ifdef HAVE_SYSLOG - #include -#endif // HAVE_SYSLOG - - -/*--[ Implement ]--------------------------------------------------------------------------------------------------*/ - - using namespace PW3270_NAMESPACE; - -#if defined(linux) - static void onLoad() __attribute__((constructor)); - static void onUnLoad() __attribute__((destructor)); - - static void onLoad() - { - session::init(); - } - - static void onUnLoad() - { - session::deinit(); - } - -#endif // linux - -#ifdef _WIN32 - - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) - { - switch(fdwReason) - { - case DLL_PROCESS_ATTACH: - session::init(); - break; - - case DLL_PROCESS_DETACH: - session::deinit(); - break; - } - - return TRUE; - } - -#endif // _WIN32 - - - namespace PW3270_NAMESPACE { - - session * session::first = nullptr; - session * session::last = nullptr; - session * (*session::factory)(const char *name) = nullptr; - - static recursive_mutex mtx; - - inline void lock() - { - mtx.lock(); - } - - inline void unlock() - { - mtx.unlock(); - } - - void session::init() - { - trace("Loading %s objects",PACKAGE_NAME); - } - - void session::deinit() - { - trace("Unloading %s objects",PACKAGE_NAME); - while(first) - { - delete first; - } - - } - - session::session() - { - -#ifdef HAVE_ICONV - this->conv2Local = (iconv_t) (-1); - this->conv2Host = (iconv_t) (-1); -#endif - - if(first) - { - prev = last; - next = 0; - last->next = this; - last = this; - } - else - { - prev = next = 0; - first = last = this; - } - - } - - session::~session() - { -#ifdef HAVE_ICONV - - if(this->conv2Local != (iconv_t) (-1)) - iconv_close(this->conv2Local); - - if(this->conv2Host != (iconv_t) (-1)) - iconv_close(this->conv2Host); - -#endif - - if(prev) - prev->next = next; - else - first = next; - - if(next) - next->prev = prev; - else - last = prev; - } - - // Factory methods and settings - session * session::create(const char *name) throw (std::exception) - { - session *rc = nullptr; - - trace("%s(%s)",__FUNCTION__,name); - - lock(); - - try - { - if(factory) - rc = factory(name); - else if(name && *name) - rc = create_remote(name); - else - rc = create_local(); - - } - catch(std::exception &e) - { - unlock(); - throw e; - } - - unlock(); - - return rc; - } - - session * session::start(const char *name) - { - return create(name); - } - - bool session::has_default(void) - { - return first != nullptr; - } - - session * session::get_default(void) - { - if(first) - return first; - return create(NULL); - } - - void session::set_plugin(session * (*factory)(const char *name)) - { - trace("%s(%p)",__FUNCTION__,factory); - session::factory = factory; - } - - // Object settings - void session::set_display_charset(const char *remote, const char *local) - { - trace("%s(%s,%s)",__FUNCTION__,remote,local); - -#ifdef HAVE_ICONV - string display_charset = this->get_display_charset(); - - if(this->conv2Local != (iconv_t) (-1)) - iconv_close(this->conv2Local); - - if(this->conv2Host != (iconv_t) (-1)) - iconv_close(this->conv2Host); - - if(!remote) - remote = display_charset.c_str(); - - trace("%s remote=%s local=%s",__FUNCTION__,remote,local); - - if(strcmp(local,remote)) - { - // Local and remote charsets aren't the same, setup conversion - conv2Local = iconv_open(local, remote); - conv2Host = iconv_open(remote,local); - } - else - { - conv2Local = conv2Host = (iconv_t)(-1); - } - -#endif - - } - - string session::get_display_charset(void) - { - return string(get_encoding()); - } - - const char * session::get_encoding(void) - { - return "ISO-8859-1"; - } - - // 3270 methods - const string session::get_version(void) - { - return string(PACKAGE_VERSION); - } - - const string session::get_revision(void) - { - return string(PACKAGE_REVISION); - } - - void session::log(const char *fmt, ...) - { - va_list arg_ptr; - va_start(arg_ptr, fmt); - this->logva(fmt,arg_ptr); - va_end(arg_ptr); - } - - void session::logva(const char *fmt, va_list args) - { - #ifdef HAVE_SYSLOG - openlog(PACKAGE_NAME, LOG_NDELAY, LOG_USER); - vsyslog(LOG_INFO,fmt,args); - closelog(); - #else - vfprintf(stderr,fmt,args); - #endif - } - - int session::wait_for_text_at(int row, int col, const char *key, int timeout) - { - time_t end = time(0)+timeout; - - trace("%s(%d,%d,%s,%d)",__FUNCTION__,row,col,key,timeout); - - iterate(false); - while(time(0) < end) - { - trace("Aguardar %d segundos por \"%s\" @%d,%d (%s)",(int) (end - time(0)),key,row,col,get_text_at(row,col,strlen(key)).c_str()); - - int rc = wait_for_ready(end - time(0)); - if(rc) { - return rc; - } - - if(!cmp_text_at(row,col,key)) { - return 0; - } - - iterate(true); - - } - - trace("Tela:\n%s\n", ((string) *this).c_str()); - - return ETIMEDOUT; - } - - int session::set_copy(const char *text) - { - return EINVAL; - } - - string session::get_copy(void) - { - errno = EINVAL; - return string(); - } - - string session::get_clipboard(void) - { -#if defined(WIN32) - - if (! OpenClipboard(0)) - { - throw exception(GetLastError(),"%s","Can´t open system clipboard"); - return NULL; - } - - HANDLE hData = GetClipboardData(CF_TEXT); - if(!hData) - { - throw exception(GetLastError(),"%s","Can´t get clipboard data"); - return NULL; - } - - char * pszText = static_cast( GlobalLock(hData) ); - if(!pszText) - { - throw exception(GetLastError(),"%s","Can´t lock clipboard"); - return NULL; - } - - string text = string ( pszText ); - - GlobalUnlock( hData ); - - CloseClipboard(); - - return text; - -#else - errno = EINVAL; - return NULL; - -#endif // WIN32 - } - - int session::set_clipboard(const char *text) - { -#if defined(WIN32) - if (! OpenClipboard(0)) - { - throw exception(GetLastError(),"%s","Can´t open system clipboard"); - return -1; - } - - EmptyClipboard(); - - size_t size = strlen(text)+1; - HGLOBAL hClipboardData = GlobalAlloc(GMEM_MOVEABLE , size); - - strcpy((char *) GlobalLock(hClipboardData), text); - - if(!SetClipboardData(CF_TEXT, hClipboardData)) - { - GlobalUnlock(hClipboardData); - CloseClipboard(); - throw exception(GetLastError(),"%s","Can´t set system clipboard"); - } - - GlobalUnlock(hClipboardData); - CloseClipboard(); - - return 0; -#else - - return EINVAL; - -#endif // WIN32 - } - - - int session::popup_dialog(LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, ...) - { - return -1; - } - - string session::file_chooser_dialog(int action, const char *title, const char *extension, const char *filename) - { - return string(""); - } - - string session::get_3270_text(const char *str) - { - string rc; - -#ifdef HAVE_ICONV - size_t in = strlen(str); - - if(in && conv2Host != (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(conv2Host,NULL,NULL,NULL,NULL); // Reset state - - if(iconv(conv2Host,&inBuffer,&in,&ptr,&out) == ((size_t) -1)) { - rc.assign(str); - } else { - rc.assign(outBuffer); - } - - free(outBuffer); - } else { - rc.assign(str); - } -#else - rc.assign(str); -#endif // HAVE_ICONV - - trace("%s(\"%s\")=\"%s\"",__FUNCTION__,str,rc.c_str()); - - return rc; - } - - string session::get_local_text(const char *str) - { - string rc; - -#ifdef HAVE_ICONV - size_t in = strlen(str); - - if(in && conv2Local != (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(conv2Local,NULL,NULL,NULL,NULL); // Reset state - - if(iconv(conv2Local,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) - rc.assign(outBuffer); - - free(outBuffer); - } - else - { - char * text = strdup(str); - for(char *ptr = text;*ptr;ptr++) - { - if(*ptr < ' ' || *ptr > 128) - { - *ptr = '?'; - } - } - rc = text; - free(text); - } -#else - char * text = strdup(str); - for(char *ptr = text;*ptr;ptr++) - { - if(*ptr < ' ' || *ptr > 128) - { - *ptr = '?'; - } - } - rc = text; - free(text); -#endif // HAVE_ICONV - - return rc; - } - - string session::get_string_at(int row, int col, size_t sz) - { - return this->get_local_text(this->get_text_at(row,col,sz).c_str()); - } - - int session::set_string_at(int row, int col, const char *str) - { - if(!str) - return -1; - -#ifdef HAVE_ICONV - if(conv2Host != (iconv_t)(-1)) - { - size_t in = strlen(str); - 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(conv2Host,NULL,NULL,NULL,NULL); // Reset state - - if(iconv(conv2Host,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) - { - int rc = this->set_text_at(row,col,outBuffer); - free(outBuffer); - return rc; - } - - free(outBuffer); - } -#endif // HAVE_ICONV - - return this->set_text_at(row,col,str); - - } - - int session::input_string(const char *str) - { - if(!str) - return -1; - -#ifdef HAVE_ICONV - if(conv2Host != (iconv_t)(-1)) - { - size_t in = strlen(str); - 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(conv2Host,NULL,NULL,NULL,NULL); // Reset state - - if(iconv(conv2Host,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) - { - int rc = this->emulate_input(outBuffer); - free(outBuffer); - return rc; - } - - free(outBuffer); - } -#endif // HAVE_ICONV - - return this->emulate_input(str); - - } - - int session::cmp_string_at(int row, int col, const char *text) - { - return cmp_text_at(row,col,get_3270_text(text).c_str()); - } - - int session::wait_for_string_at(int row, int col, const char *key, int timeout) - { - return wait_for_text_at(row,col,get_3270_text(key).c_str(),timeout); - } - - string session::get_string(int baddr, size_t len) - { - return get_local_text(get_text(baddr,len).c_str()); - } - - string session::asc2ebc(string &str) - { - size_t sz = str.size(); - unsigned char buffer[sz+1]; - - memcpy(buffer,str.c_str(),sz); - return string(asc2ebc(buffer,sz)); - } - - string session::ebc2asc(string &str) - { - size_t sz = str.size(); - unsigned char buffer[sz+1]; - memcpy(buffer,str.c_str(),sz); - return string(ebc2asc(buffer,sz)); - } - - int session::file_transfer(LIB3270_FT_OPTION options, const char *local, const char *remote, int lrecl, int blksize, int primspace, int secspace, int dft) - { - log("Can't transfer %s: File transfer is unavailable", local ? local : "file"); - return EINVAL; - } - - int session::set_host(const char *host) - { - return set_url(host); - } - - int session::connect(const char *host, time_t wait) - { - int rc = 0; - - if(host && *host) - { - rc = set_url(host); - trace("%s: set_url(%s) = %d",__FUNCTION__,host,rc); - } - - rc = connect(); - trace("%s: connect=%d",__FUNCTION__,rc); - - if(!rc && wait) - { - time_t timeout = time(0)+wait; - rc = ETIMEDOUT; - - while(time(0) < timeout && rc == ETIMEDOUT) - { - trace("%s: Waiting",__FUNCTION__); - if(is_connected()) - rc = 0; - iterate(true); - } - } - - return rc; - } - -#ifdef WIN32 - string session::win32_strerror(int e) - { - static char buffer[4096]; - - memset(buffer,0,sizeof(buffer)); - - if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,e,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),buffer,sizeof(buffer),NULL) == 0) - { - snprintf(buffer,4095,"Windows error %d", e); - } - - for(size_t f=0;f - * - * 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 testprogram.cc e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - - #include - #include - #include - - using namespace std; - using namespace PW3270_NAMESPACE; - -/*--[ Implement ]------------------------------------------------------------------------------------*/ - - int main(int numpar, char *param[]) - { - - { - string s; - session *session = session::start(""); - // session *session = session::start("new"); - - cout << "pw3270 version: " << session->get_version() << endl; - cout << "pw3270 revision: " << session->get_revision() << endl << endl; - - if(session->is_connected()) - cout << "\tConnected to host" << endl; - else - cout << "\tDisconnected" << endl; - - cout << "\tSession state: " << session->get_cstate() << endl; - - s = session->get_display_charset(); - cout << "\tDisplay charset: " << s.c_str() << endl; - - s = session->get_host_charset(); - cout << "\tHost charset: " << s.c_str() << endl; - - cout << "Connect: " << session->connect("fandezhi.efglobe.com:23",60) << endl << endl; - - cout << "\tWaitForReady: " << session->wait_for_ready(10) << endl; - - cout << "\tIsConnected: " << session->is_connected() << endl; - cout << "\tIsReady: " << session->is_ready() << endl; - cout << "\tString(3,2,14) " << session->get_string_at(3,2,14) << endl; - - delete session; - } - - // Waits - sleep(2); - - // Create another session - /* - { - session *session = session::start("pw3270:a"); - - session->disconnect(); - delete session; - - } - */ - - - return 0; - } - - -- libgit2 0.21.2