diff --git a/.gitignore b/.gitignore index c6254da..f4b617d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,4 @@ Makefile conf/systemd.service src/core/windows/resources.rc src/plugin/windows/resources.rc - +*.pid diff --git a/configure.ac b/configure.ac index 177cb96..cd9ef94 100644 --- a/configure.ac +++ b/configure.ac @@ -180,7 +180,7 @@ dnl --------------------------------------------------------------------------- dnl Check for LIBV3270 dnl --------------------------------------------------------------------------- -PKG_CHECK_MODULES( [V3270], [v3270], AC_DEFINE(HAVE_V3270), AC_MSG_ERROR([V3270 not present.])) +PKG_CHECK_MODULES( [V3270], [libv3270], AC_DEFINE(HAVE_V3270), AC_MSG_ERROR([V3270 not present.])) AC_SUBST(V3270_LIBS) AC_SUBST(V3270_CFLAGS) @@ -189,7 +189,7 @@ dnl --------------------------------------------------------------------------- dnl Check for GTK dnl --------------------------------------------------------------------------- -PKG_CHECK_MODULES( [GTK], [gtk+-3.0 gmodule-2.0], AC_DEFINE(HAVE_GTK), AC_MSG_ERROR([GTK not present.])) +PKG_CHECK_MODULES( [GTK], [gtk+-3.0], AC_DEFINE(HAVE_GTK), AC_MSG_ERROR([GTK not present.])) AC_SUBST(GTK_LIBS) AC_SUBST(GTK_CFLAGS) @@ -198,7 +198,7 @@ dnl --------------------------------------------------------------------------- dnl Check for GLIB dnl --------------------------------------------------------------------------- -PKG_CHECK_MODULES( [GLIB], [glib-2.0], AC_DEFINE(HAVE_GLIB), AC_MSG_ERROR([GLIB not present.] )) +PKG_CHECK_MODULES( [GLIB], [glib-2.0 gobject-2.0 gmodule-2.0 gio-2.0], AC_DEFINE(HAVE_GLIB), AC_MSG_ERROR([GLIB not present.] )) AC_SUBST(GLIB_LIBS) AC_SUBST(GLIB_CFLAGS) diff --git a/pw3270-plugin-ipc.cbp b/pw3270-plugin-ipc.cbp index 54a6792..8b8aceb 100644 --- a/pw3270-plugin-ipc.cbp +++ b/pw3270-plugin-ipc.cbp @@ -106,7 +106,6 @@ - diff --git a/src/core/windows/gobject.c b/src/core/windows/gobject.c index dd23ed3..f775b73 100644 --- a/src/core/windows/gobject.c +++ b/src/core/windows/gobject.c @@ -36,10 +36,9 @@ G_DEFINE_TYPE(ipc3270, ipc3270, G_TYPE_OBJECT) static void ipc3270_finalize(GObject *object) { - ipc3270 * ipc = IPC3270(object); - - + // ipc3270 * ipc = IPC3270(object); G_OBJECT_CLASS(ipc3270_parent_class)->finalize(object); + } @@ -102,6 +101,7 @@ void ipc3270_set_session(GObject *object, H3270 *hSession, const char *name, GEr lib3270_set_session_id(ipc->hSession, id); ipc->source->hPipe = hPipe; + ipc->source->object = object; ipc->source->state = PIPE_STATE_WAITING; ipc->source->overlap.hEvent = CreateEvent( NULL,TRUE,TRUE,NULL); diff --git a/src/core/windows/gobject.h b/src/core/windows/gobject.h index 8ef2598..0b3e1cc 100644 --- a/src/core/windows/gobject.h +++ b/src/core/windows/gobject.h @@ -67,6 +67,7 @@ typedef struct _ipc3270_pipe_source { GSource gsrc; + GObject * object; HANDLE hPipe; IPC3270_PIPE_STATE state; diff --git a/src/core/windows/inout.c b/src/core/windows/inout.c index 7edbd71..41c964d 100644 --- a/src/core/windows/inout.c +++ b/src/core/windows/inout.c @@ -41,6 +41,31 @@ /*---[ Implement ]----------------------------------------------------------------------------------*/ +unsigned char * ipc3270_pack_error(const GError *error, size_t * szPacket) { + + static const char * error_response = "error"; + + *szPacket = strlen(error_response) + 1 + (sizeof(guint16) * 2) + strlen(error->message); + + // Allocate buffer + unsigned char * outputBuffer = g_malloc0(*szPacket); + unsigned char * txtptr = outputBuffer; + + // Add name + strcpy((char *) txtptr,error_response); + txtptr += strlen((char *) txtptr) + 1; + + // Add RC + *((guint16 *) txtptr) = (guint16) error->code; + txtptr += sizeof(guint16); + + // Add message + strcpy((char *) txtptr,error->message); + txtptr += (strlen((char *) txtptr)+1); + + return outputBuffer; +} + unsigned char * ipc3270_pack(const gchar * name, int id, GVariant *values, size_t * szPacket) { GVariantIter iter; @@ -50,7 +75,7 @@ unsigned char * ipc3270_pack(const gchar * name, int id, GVariant *values, size_ size_t ix = 0; // Init packet size; - *szPacket = strlen(name) + 1 + (sizeof(guint16) * 2) ; + *szPacket = strlen(name) + 1 + (sizeof(guint16) * 2); g_print("Packaging %u itens for \"%s\"\n", (unsigned int) count, name); while ((child = g_variant_iter_next_value (&iter))) { diff --git a/src/core/windows/pipesource.c b/src/core/windows/pipesource.c index 4434ac0..6a8ee86 100644 --- a/src/core/windows/pipesource.c +++ b/src/core/windows/pipesource.c @@ -42,10 +42,10 @@ void ipc3270_wait_for_client(IPC3270_PIPE_SOURCE *source) { source->state = PIPE_STATE_WAITING; break; - case ERROR_PIPE_CONNECTED: // Client is already connected, so signal an event. - if(SetEvent(source->overlap.hEvent)) - break; + source->state = PIPE_STATE_WAITING; + SetEvent(source->overlap.hEvent); + break; default: g_message("Error %u in ConnectNamedPipe",(unsigned int) GetLastError()); @@ -93,6 +93,57 @@ static gboolean IO_check(GSource *source) { static void process_input(IPC3270_PIPE_SOURCE *source, DWORD cbRead) { + const gchar * request_name = (const gchar *) (source->buffer); + int request_type = 0; + + debug("Received packet \"%s\" with %u bytes", request_name, (unsigned int) cbRead); + + g_autoptr (GError) error = NULL; + g_autoptr (GVariant) parameters = ipc3270_unpack(source->buffer, &request_type); + g_autoptr (GVariant) response = NULL; + + if(!parameters) { + g_message("Rejecting invalid request \"%s\"", request_name); + } + + // Process query + switch(request_type) { + case 1: // getProperty + response = ipc3270_get_property(source->object, request_name, &error); + break; + + case 2: // setProperty + ipc3270_set_property(source->object, request_name, parameters, &error); + break; + + case 3: // method + response = ipc3270_method_call(source->object, request_name, parameters, &error); + break; + + default: + g_message("Rejecting request \"%s\": Invalid type %d",request_name, request_type); + g_set_error(&error,IPC3270(source->object)->error_domain,EINVAL,"Invalid or unexpected type %d",request_type); + + } + + // Pack response + size_t szPacket = 0; + g_autofree unsigned char * buffer = NULL; + + if(error) { + + buffer = ipc3270_pack_error(error, &szPacket); + + } else { + + buffer = ipc3270_pack(request_name, 0, response, &szPacket); + + } + + // Send response + DWORD wrote = (DWORD) szPacket; + WriteFile(source->hPipe,buffer,wrote,&wrote,NULL); + } static void read_input_pipe(IPC3270_PIPE_SOURCE *source) { @@ -167,7 +218,7 @@ static gboolean IO_dispatch(GSource *source, GSourceFunc callback, gpointer data } else { - // popup_lasterror("%s", _( "Pipe connection failed" )); + g_message("Pipe connection failed with rc=%u",(unsigned int) GetLastError()); } break; diff --git a/src/include/lib3270/ipc.h b/src/include/lib3270/ipc.h index 5dc935f..21e829e 100644 --- a/src/include/lib3270/ipc.h +++ b/src/include/lib3270/ipc.h @@ -71,6 +71,7 @@ // TODO: Move for windows private.h unsigned char * ipc3270_pack(const gchar *name, int id, GVariant *values, size_t * szPacket); + unsigned char * ipc3270_pack_error(const GError *error, size_t * szPacket); GVariant * ipc3270_unpack(const unsigned char *packet, int *id); G_END_DECLS diff --git a/src/service/session.c b/src/service/session.c index f312f2d..86e3831 100644 --- a/src/service/session.c +++ b/src/service/session.c @@ -46,7 +46,7 @@ G_DEFINE_TYPE(session, session, GLIB_TYPE_IPC3270) static void session_finalize(GObject *object) { - lib3270_session_free(ipc3270_get_session(IPC3270(object))); + lib3270_session_free(ipc3270_get_session(object)); G_OBJECT_CLASS(session_parent_class)->finalize(object); } @@ -64,9 +64,7 @@ static void session_class_init(sessionClass *klass) { static void session_init(session *object) { debug("%s",__FUNCTION__); - - ipc3270 *ipc = IPC3270(object); - ipc3270_set_session(ipc,lib3270_session_new(""),PACKAGE_NAME,NULL); + ipc3270_set_session(&object->parent,lib3270_session_new(""),PACKAGE_NAME,NULL); } -- libgit2 0.21.2