#include #include #include #include #include #include "response.h" #include "version.h" static int port = 3333; #define BUFSIZE 1024 GMainContext *context=NULL; GMainLoop *mainLoop=NULL; GSocketConnection * connection = NULL; GSocketClient * client = NULL; char exitTokens[5][7] = {"quit", "exit", "logout", "logoff", "local"}; //helper function to nicely terminate the client static void terminate(char *message, int exitCode) { g_object_unref(client); g_object_unref(connection); if (message) { g_print("%s\n", message); } exit(exitCode); } //a sort of strncmp but with \n or \r exception static gboolean Matches(char *src, char* dst, gssize size) { for(; *src != '\0', (size--)>0; src++) { if(g_ascii_toupper(*src) != g_ascii_toupper(*dst)) { return FALSE; } dst++; } for(; *dst != '\0'; dst++) if (*dst != '\r' && *dst != '\n') { return FALSE; } return TRUE; } //GIOChannel callback static gboolean stdinAvailable (GIOChannel *source, GIOCondition condition, gpointer data) { char tmp[BUFSIZE]; memset(tmp,0,BUFSIZE); int size = read(0, tmp, BUFSIZE); if(size<=0) { return TRUE; } //test if we have an exit word int idx=0; for(idx=0; idxmessage) { g_print("Got error: %s\n", error->message); } if (written != size || written <= 0) { g_print("Could not write. blocking. Written: %d\n", written); return FALSE; } return TRUE; } //callback for server input static gboolean cbServerInput(gpointer data, gpointer additional) { char buffer[BUFSIZE]; gssize size=0; memset(buffer,0,BUFSIZE); GPollableInputStream* inStream = (GPollableInputStream*)data; GError *error = NULL; size=g_pollable_input_stream_read_nonblocking(inStream, buffer, BUFSIZE, NULL, &error); if(size <=0) { terminate("Connection to server lost", -1); } if(buffer[0] != ' ') { g_print("%s", buffer); } return TRUE; } int main(int argc, char** argv) { /* create a new connection */ g_type_init (); GOutputStream *out; GInputStream *in; GError* error = NULL; GIOChannel* stdinChannel = NULL; client = g_socket_client_new(); /* connect to the host */ connection = g_socket_client_connect_to_host (client, (gchar*)"localhost", port, NULL, &error); if (error != NULL) { g_print("Could not connect to server on port %d\n", port); g_object_unref(client); return -1; } g_printf("\nWelcome to InstrumentShell v%s\n\n",FW_VERSION); g_print("> "); //register Pollable sources out = g_io_stream_get_output_stream (G_IO_STREAM (connection)); in = g_io_stream_get_input_stream (G_IO_STREAM (connection)); GSource *outSource = NULL; GSource *inSource = g_pollable_input_stream_create_source((struct GPollableInputStream*)in, NULL); outSource = g_pollable_output_stream_create_source((struct GPollableOutputStream*)out, NULL); //register stdin channel stdinChannel = g_io_channel_unix_new(0); if(stdinChannel == NULL) { terminate("Could not open STDIN channel", -2); } //attach the sources g_io_add_watch(stdinChannel, G_IO_IN, stdinAvailable, (struct GPollableOutputStream*)out); g_source_set_callback(inSource, cbServerInput, (GPollableOutputStream*)in, NULL); g_source_attach(inSource, NULL); g_main_loop_run (g_main_loop_new (NULL, FALSE)); return 0; }