From ef0594fab7ea7b4dd8fe51d50500b7ce5d7ab38a Mon Sep 17 00:00:00 2001 From: perry.werneck@gmail.com Date: Fri, 5 Jul 2013 19:41:38 +0000 Subject: [PATCH] Iniciando implementação de uma classe básica capaz de funcionar via DBUS/HLLAPI ou carregando dinamicamente a lib3270 para evitar a duplicação de código a manter nos módulos rx3270 e jni --- src/classlib/Makefile | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/classlib/classlib.cbp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/classlib/exception.cc | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/classlib/local.cc | 478 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/classlib/main.cc | 29 +++++++++++++++++++++++++++++ src/classlib/pw3270class.h | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/classlib/remote.cc | 787 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/classlib/session.cc | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/classlib/testprogram.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 1881 insertions(+), 0 deletions(-) create mode 100644 src/classlib/Makefile create mode 100644 src/classlib/classlib.cbp create mode 100644 src/classlib/exception.cc create mode 100644 src/classlib/local.cc create mode 100644 src/classlib/main.cc create mode 100644 src/classlib/pw3270class.h create mode 100644 src/classlib/remote.cc create mode 100644 src/classlib/session.cc create mode 100644 src/classlib/testprogram.cc diff --git a/src/classlib/Makefile b/src/classlib/Makefile new file mode 100644 index 0000000..8ddae97 --- /dev/null +++ b/src/classlib/Makefile @@ -0,0 +1,89 @@ +# +# "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) +# + +LIBNAME=pw3270cxx.a + +#---[ Sources ]---------------------------------------------------------------- + +SOURCES=main.cc session.cc exception.cc local.cc remote.cc + +#---[ Paths ]------------------------------------------------------------------ + +ROOTDIR ?= . +OBJDIR ?= $(ROOTDIR)/.obj +BINDIR ?= $(ROOTDIR)/.bin +BINDBG ?= $(BINDIR)/Debug +BINRLS ?= $(BINDIR)/Release + +OBJDBG = $(OBJDIR)/Debug +OBJRLS = $(OBJDIR)/Release + +#---[ Tools ]------------------------------------------------------------------ + +MKDIR = mkdir -p + +#---[ Flags ]------------------------------------------------------------------ + +LIBS=-ldl -ldbus-glib-1 -ldbus-1 +CFLAGS=-fPIC -I../include -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include +DEBUG_CFLAGS=-DDEBUG=1 -g -Wall + + +#---[ Rules ]------------------------------------------------------------------ + +CXX=g++ +LD=g++ + +DEPENDS=*.h ../include/*.h ../include/lib3270/*.h Makefile + +$(OBJDBG)/%.o: %.cc $(DEPENDS) + @echo " CC `basename $@`" + @$(MKDIR) `dirname $@` + @$(CXX) $(CFLAGS) $(DEBUG_CFLAGS) -o $@ -c $< + + +#---[ 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) -o $@ $^ $(LIBS) + +$(BINDBG)/$(LIBNAME): $(foreach SRC, $(basename $(SOURCES)), $(OBJDBG)/$(SRC).o) + @echo " CCLD `basename $@`" + @$(MKDIR) `dirname $@` + @ar rs $@ $^ + +clean: + @rm -fr $(OBJDIR) + @rm -fr $(BINDIR) + @rm -f testprogram + @find . -name "*~" -exec rm -f {} \; diff --git a/src/classlib/classlib.cbp b/src/classlib/classlib.cbp new file mode 100644 index 0000000..e1dc6bc --- /dev/null +++ b/src/classlib/classlib.cbp @@ -0,0 +1,50 @@ + + + + + + diff --git a/src/classlib/exception.cc b/src/classlib/exception.cc new file mode 100644 index 0000000..000c876 --- /dev/null +++ b/src/classlib/exception.cc @@ -0,0 +1,65 @@ +/* + * "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 + * + * 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 "pw3270class.h" + +/*--[ Implement ]--------------------------------------------------------------------------------------------------*/ + + namespace pw3270 + { + + exception::exception(int code, const char *fmt, ...) + { + va_list arg_ptr; + va_start(arg_ptr, fmt); + vsnprintf(this->msg,4095,fmt,arg_ptr); + va_end(arg_ptr); + + this->code = code; + } + + 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); + + this->code = -1; + } + + const char * exception::what() const throw() + { + return this->msg; + } + + } diff --git a/src/classlib/local.cc b/src/classlib/local.cc new file mode 100644 index 0000000..4384a1f --- /dev/null +++ b/src/classlib/local.cc @@ -0,0 +1,478 @@ +/* + * "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 + * + * 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 "pw3270class.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,line); + closelog(); + *line = 0; + } + return; + } + + *ptr = 0; + strncat(line,temp,MAX_LOG_LENGTH); + + openlog(PACKAGE_NAME, LOG_NDELAY, LOG_USER); + syslog(LOG_DEBUG,line); + closelog(); + + strncpy(line,ptr+1,MAX_LOG_LENGTH); + + #endif // HAVE_SYSLOG + } + + } + + namespace pw3270 + { + + class local : public session + { + private: + + H3270 * hSession; + + #ifdef WIN32 + + HMODULE hModule; + + int 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; + } + #else + + void * hModule; + + #endif // WIN32 + + /** + * Dynamically load lib3270 + * + * @return 0 if the library was loaded, -1 on error. + * + */ + int load3270(void) + { + #ifdef WIN32 + static const char *dllname = "lib3270.dll." PACKAGE_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); + #else + snprintf(buffer,4096,"%s\\%s",datadir,dllname); + #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); + rc = GetLastError(); + } + + SetErrorMode(errorMode); + + trace("%s hModule=%p rc=%d",dllname,hModule,(int) rc); + + if(cookie && RemoveDllDirectory) + RemoveDllDirectory(cookie); + + if(kernel) + FreeLibrary(kernel); + + if(hModule) + return 0; + + throw exception("Can't load %s",dllname); + + #else + dlerror(); + + hModule = dlopen("lib3270.so." PACKAGE_VERSION, RTLD_NOW); + if(hModule) + return 0; + + throw exception("Can't load lib3270: %s",dlerror()); + + #endif // WIN32 + + return -1; + + } + + void * get_symbol(const char *name) + { +#ifdef WIN32 + void *symbol = (void *) GetProcAddress(hModule,name); + + if(symbol) + return symbol; + +#else + void *symbol; + + symbol = dlsym(hModule,name); + + if(symbol) + return symbol; + + throw exception("Can't load symbol lib3270::%s dlerror was \"%s\"",name,dlerror()); + +#endif // WIN32 + + return NULL; + + } + + + // Lib3270 entry points + const char * (*_get_version)(void); + LIB3270_CSTATE (*_get_connection_state)(H3270 *h); + int (*_disconnect)(H3270 *h); + int (*_connect)(H3270 *h,const char *n, int wait); + 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); + void (*_popup_va)(H3270 *session, LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, va_list); + void * (*_free)(void *); + + public: + + local() + { + H3270 * (*lib3270_new)(const char *); + 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 **) & lib3270_new, "lib3270_session_new" }, + { (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_version, "lib3270_get_version" }, + { (void **) & _disconnect, "lib3270_disconnect" }, + { (void **) & _connect, "lib3270_connect" }, + { (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 **) & _popup_va, "lib3270_popup_va" }, + { (void **) & _free, "lib3270_free" }, + }; + + + if(load3270()) + return; + + trace("hModule=%p",hModule); + + 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) + return; + } + + // Get Session handle, setup base callbacks + set_log_handler(loghandler); + set_trace_handler(tracehandler); + this->hSession = lib3270_new(""); + + } + + virtual ~local() + { + try + { + static void (*session_free)(H3270 *h) = (void (*)(H3270 *)) get_symbol("lib3270_session_free"); + + if(session_free && this->hSession) + session_free(this->hSession); + } + catch(exception e) { } + + #ifdef WIN32 + FreeLibrary(hModule); + #else + dlclose(hModule); + #endif // WIN32 + + } + + bool is_connected(void) + { + return _is_connected(hSession); + } + + LIB3270_CSTATE get_cstate(void) + { + return _get_connection_state(hSession); + } + + int connect(const char *uri, bool wait) + { + return _connect(hSession,uri,(int) wait); + } + + int disconnect(void) + { + return _disconnect(hSession); + } + + 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) + { + _main_iterate(hSession,wait); + return 0; + } + + string * get_text_at(int row, int col, size_t sz) + { + char * ptr = _get_text_at(hSession,row,col,sz); + + if(ptr) + { + string *s = new string(ptr); + _free(ptr); + return s; + } + + return new string(""); + } + + 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) + { + char *ptr = _get_text(hSession,offset,len); + + if(ptr) + { + string *s = new string(ptr); + _free(ptr); + return s; + } + + return new string(""); + } + + + }; + + session * session::create_local(void) + { + return new local(); + } + + } + diff --git a/src/classlib/main.cc b/src/classlib/main.cc new file mode 100644 index 0000000..3933766 --- /dev/null +++ b/src/classlib/main.cc @@ -0,0 +1,29 @@ +/* + * "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 + * + * Este programa está nomeado como main.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) + * + */ + diff --git a/src/classlib/pw3270class.h b/src/classlib/pw3270class.h new file mode 100644 index 0000000..10f8809 --- /dev/null +++ b/src/classlib/pw3270class.h @@ -0,0 +1,164 @@ +/* + * "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 + * + * Este programa está nomeado como pw3270class.c 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 + + #ifdef HAVE_ICONV + #include + #endif // HAVE_ICONV + + #include + #include + #include + + namespace pw3270 + { + using namespace std; + + class exception : public std::exception + { + public: + exception(int code, const char *fmt, ...); + exception(const char *fmt, ...); + + virtual const char * what() const throw(); + + private: + int code; + char msg[4096]; + + }; + + class session + { + public: + + session(); + virtual ~session(); + + // Factory methods and settings + static session * create(const char *name = 0); + static session * start(const char *name = 0); + static session * get_default(void); + static void set_plugin(session * (*factory)(const char *name)); + + // Object settings + void set_charset(const char *charset); + + // Log management + void log(const char *fmt, ...); + void logva(const char *fmt, va_list args); + + // 3270 methods + virtual string get_version(void); + virtual string get_revision(void); + + virtual bool is_connected(void) = 0; + virtual bool is_ready(void) = 0; + + virtual LIB3270_CSTATE get_cstate(void) = 0; + + virtual int connect(const char *uri, bool wait = true) = 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; + + 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 string * get_text(int baddr, size_t len) = 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 set_cursor_position(int row, int col) = 0; +// virtual int set_cursor_addr(int addr) = 0; +// virtual int get_cursor_addr(void) = 0; + +// virtual int set_toggle(LIB3270_TOGGLE ix, bool value) = 0; + +// virtual int enter(void) = 0; +// virtual int pfkey(int key) = 0; +// virtual int pakey(int key) = 0; + +// virtual int emulate_input(const char *str) = 0; + +// 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 set_copy(const char *text); +// virtual char * get_copy(void); + +// virtual char * get_clipboard(void); +// virtual int set_clipboard(const char *text); + +// virtual int quit(void) = 0; + + // Dialogs +// virtual int popup_dialog(LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, ...); +// virtual char * file_chooser_dialog(GtkFileChooserAction action, const char *title, const char *extension, const char *filename); + + private: + + session * prev; + session * next; + + static session * first; + static session * last; + + static session * (*factory)(const char *name); + + static session * create_remote(const char *name); + static session * create_local(void); + +#ifdef HAVE_ICONV + iconv_t conv2Local; + iconv_t conv2Host; +#endif + + }; + + + } + + +#endif // PW3270_CLASS_H_INCLUDED diff --git a/src/classlib/remote.cc b/src/classlib/remote.cc new file mode 100644 index 0000000..b4c4143 --- /dev/null +++ b/src/classlib/remote.cc @@ -0,0 +1,787 @@ +/* + * "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 + * + * 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 + + #if defined(HAVE_DBUS) + #include + #include + #include + #include + #include + #include + #endif // HAVE_DBUS + + #if defined(WIN32) + #include + #include + #endif // WIN32 + + #include "pw3270class.h" + #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 + { + + class remote : public session + { + private: +#if defined(WIN32) + + HANDLE hPipe; + +#elif defined(HAVE_DBUS) + + DBusConnection * conn; + char * dest; + char * path; + char * intf; + + 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 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) + { + if(msg) + { + DBusMessageIter iter; + + if(dbus_message_iter_init(msg, &iter)) + { + if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) + { + string * rc; + const char * str; + dbus_message_iter_get_basic(&iter, &str); + trace("Response: [%s]",str); + rc = new string(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 NULL; + } + + } + + return NULL; + } + + 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; + } + + int query_intval(const char *method) + { + if(conn) + return get_intval(call(create_message(method))); + return -1; + } + +#endif + + public: + + remote(const char *session) + { +#if defined(WIN32) + static DWORD dwMode = PIPE_READMODE_MESSAGE; + char buffer[4096]; + char * str = strdup(session); + char * ptr; + + hPipe = INVALID_HANDLE_VALUE; + + for(ptr=str;*ptr;ptr++) + { + if(*ptr == ':') + *ptr = '_'; + else + *ptr = tolower(*ptr); + } + + snprintf(buffer,4095,"\\\\.\\pipe\\%s",str); + + free(str); + + if(!WaitNamedPipe(buffer,NMPWAIT_USE_DEFAULT_WAIT)) + { + throw exception("Invalid service instance: %s",name); + return; + } + + hPipe = CreateFile(buffer,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); + + if(hPipe == INVALID_HANDLE_VALUE) + { + throw exception("Can´t create service pipe %s",buffer); + } + else if(!SetNamedPipeHandleState(hPipe,&dwMode,NULL,NULL)) + { + exception e = exception("%s","Can´t set pipe state"); + CloseHandle(hPipe); + hPipe = INVALID_HANDLE_VALUE; + throw e; + } + +#elif defined(HAVE_DBUS) + + DBusError err; + int rc; + char * str = strdup(session); + char * ptr; + char busname[4096]; + char pidname[10]; + int pid = (int) getpid(); + + trace("%s str=%p",__FUNCTION__,str); + + 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; + } + + if(!conn) + { + throw exception("%s", "DBUS Connection failed"); + return; + } + + memset(pidname,0,10); + for(int f = 0; f < 9 && pid > 0;f++) + { + pidname[f] = 'a'+(pid % 25); + pid /= 25; + } + + snprintf(busname, 4095, "%s.rx3270.br.com.bb",pidname); + + trace("Busname: [%s]",busname); + + rc = dbus_bus_request_name(conn, busname, DBUS_NAME_FLAG_REPLACE_EXISTING , &err); + trace("dbus_bus_request_name rc=%d",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); + + DBusMessage * msg = create_message("setScript"); + + if(msg) + { + const char * id = "r"; + static const dbus_int32_t flag = 1; + dbus_message_append_args(msg, DBUS_TYPE_STRING, &id, DBUS_TYPE_INT32, &flag, DBUS_TYPE_INVALID); + get_intval(call(msg)); + } + + #else + +#endif + } + + virtual ~remote() + { +#if defined(WIN32) + + if(hPipe != INVALID_HANDLE_VALUE) + CloseHandle(hPipe); + +#elif defined(HAVE_DBUS) + + try + { + DBusMessage * msg = create_message("setScript"); + if(msg) + { + const char * id = "r"; + static const dbus_int32_t flag = 0; + dbus_message_append_args(msg, DBUS_TYPE_STRING, &id, DBUS_TYPE_INT32, &flag, DBUS_TYPE_INVALID); + get_intval(call(msg)); + } + } + catch(exception e) + { + + } + + free(dest); + free(path); + free(intf); + +#else + +#endif + } + + bool is_connected(void) + { +#if defined(WIN32) + + static const struct hllapi_packet_query query = { HLLAPI_PACKET_IS_CONNECTED }; + struct hllapi_packet_result response; + DWORD cbSize = sizeof(query); + TransactNamedPipe(hPipe,(LPVOID) &query, cbSize, &response, sizeof(response), &cbSize,NULL); + return response.rc != 0; + +#elif defined(HAVE_DBUS) + + return query_intval("isConnected") != 0; + +#endif + + return false; + } + + LIB3270_CSTATE get_cstate(void) + { +#if defined(WIN32) + + static const struct hllapi_packet_query query = { HLLAPI_PACKET_GET_CSTATE }; + struct hllapi_packet_result response; + DWORD cbSize = sizeof(query); + TransactNamedPipe(hPipe,(LPVOID) &query, cbSize, &response, sizeof(response), &cbSize,NULL); + return (LIB3270_CSTATE) response.rc; + +#elif defined(HAVE_DBUS) + + return (LIB3270_CSTATE) query_intval("getConnectionState"); + +#else + + return (LIB3270_CSTATE) -1; + +#endif + + } + + int connect(const char *uri, bool wait) + { +#if defined(WIN32) + struct hllapi_packet_connect * pkt; + struct hllapi_packet_result response; + DWORD cbSize; + + cbSize = sizeof(struct hllapi_packet_connect)+strlen(uri); + pkt = (struct hllapi_packet_connect *) malloc(cbSize); + + pkt->packet_id = HLLAPI_PACKET_CONNECT; + pkt->wait = (unsigned char) wait; + strcpy(pkt->hostname,uri); + + trace("Sending %s",pkt->hostname); + + if(TransactNamedPipe(hPipe,(LPVOID) pkt, cbSize, &response, sizeof(response), &cbSize,NULL)) + { + free(pkt); + return response.rc + } + + free(pkt); + + throw exception("Transaction error %d",GetLastError()); + +#elif defined(HAVE_DBUS) + + int rc; + DBusMessage * msg = create_message("connect"); + if(!msg) + return -1; + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &uri, DBUS_TYPE_INVALID); + + rc = get_intval(call(msg)); + + if(!rc && wait) + return wait_for_ready(120); + + return rc; + +#else + return -1; + +#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; + + DBusMessage * msg = create_message("waitForReady"); + int rc; + + if(!msg) + return -1; + + dbus_message_append_args(msg, DBUS_TYPE_INT32, &delay, DBUS_TYPE_INVALID); + + rc = get_intval(call(msg)); + trace("waitForReady exits with rc=%d",rc); + + if(rc != ETIMEDOUT) + return rc; + } + + return ETIMEDOUT; + +#else + + return -1; + +#endif + + } + + bool is_ready(void) + { +#if defined(WIN32) + + static const struct hllapi_packet_query query = { HLLAPI_PACKET_IS_READY }; + struct hllapi_packet_result response; + DWORD cbSize = sizeof(query); + TransactNamedPipe(hPipe,(LPVOID) &query, cbSize, &response, sizeof(response), &cbSize,NULL); + return response.rc != 0; + +#elif defined(HAVE_DBUS) + + return query_intval("isReady") != 0; + +#endif + + return false; + } + + + int disconnect(void) + { +#if defined(WIN32) + + static const struct hllapi_packet_query query = { HLLAPI_PACKET_DISCONNECT }; + struct hllapi_packet_result response; + DWORD cbSize = sizeof(query); + TransactNamedPipe(hPipe,(LPVOID) &query, cbSize, &response, sizeof(response), &cbSize,NULL); + return 0; + +#elif defined(HAVE_DBUS) + + return query_intval("disconnect"); + +#else + + return -1; + +#endif + + } + + + 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) + return 0; +#elif defined(HAVE_DBUS) + 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 }; + struct hllapi_packet_text * response; + DWORD cbSize = sizeof(struct hllapi_packet_text)+sz; + string * s; + + response = (struct hllapi_packet_text *) malloc(cbSize+2); + memset(response,0,cbSize+2); + + if(TransactNamedPipe(hPipe,(LPVOID) &query, sizeof(struct hllapi_packet_query_at), &response, cbSize, &cbSize,NULL)) + { + if(response->packet_id) + s = new string(""); + else + s = new string(response->text); + } + else + { + s = new string(""); + } + + free(response); + + return s; + +#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 NULL; + +#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; + + DBusMessage * msg = create_message("setTextAt"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); + return get_intval(call(msg)); + } + + return -1; + +#else + + return -1; + +#endif + + } + + int cmp_text_at(int row, int col, const char *text) + { +#if defined(WIN32) + + struct hllapi_packet_text_at * query; + struct hllapi_packet_result response; + DWORD 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); + + 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; + + DBusMessage * msg = create_message("cmpTextAt"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID); + return get_intval(call(msg)); + } + +#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) + { + #warning IMPLEMENTAR + return NULL; + } + + + }; + + session * session::create_remote(const char *session) + { + return new remote(session); + } + + } + diff --git a/src/classlib/session.cc b/src/classlib/session.cc new file mode 100644 index 0000000..44967ca --- /dev/null +++ b/src/classlib/session.cc @@ -0,0 +1,163 @@ +/* + * "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 + * + * 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 "pw3270class.h" + + #ifdef HAVE_SYSLOG + #include + #endif // HAVE_SYSLOG + +/*--[ Implement ]--------------------------------------------------------------------------------------------------*/ + + namespace pw3270 + { + session * session::first = 0; + session * session::last = 0; + session * (*session::factory)(const char *name) = 0; + + session::session() + { + if(first) + { + prev = last; + next = 0; + last->next = this; + last = this; + } + else + { + prev = next = 0; + first = last = this; + } + } + + session::~session() + { + 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) + { + if(factory) + return factory(name); + + if(name && *name) + return create_remote(name); + + return create_local(); + } + + session * session::start(const char *name) + { + return create(name); + } + + session * session::get_default(void) + { + if(first) + return first; + return create(NULL); + } + + void session::set_plugin(session * (*factory)(const char *name)) + { + session::factory = factory; + } + + // Object settings + void session::set_charset(const char *charset) + { + + } + + // 3270 methods + string session::get_version(void) + { + return string(PACKAGE_VERSION); + } + + 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; + + while(time(0) < end) + { + if(!is_connected()) + return ENOTCONN; + + if(!cmp_text_at(row,col,key)) + return 0; + + iterate(); + } + + return ETIMEDOUT; + } + + + + } + + diff --git a/src/classlib/testprogram.cc b/src/classlib/testprogram.cc new file mode 100644 index 0000000..abf938e --- /dev/null +++ b/src/classlib/testprogram.cc @@ -0,0 +1,56 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA, 02111-1307, 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 "pw3270class.h" + #include + + using namespace std; + using namespace pw3270; + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + + int main(int numpar, char *param[]) + { + session *session = session::start(); + + 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; + + delete session; + return 0; + } + + -- libgit2 0.21.2