/** * Allocates a new rfbClient instance given the parameters stored within the * client, returning NULL on failure. */ static rfbClient* __guac_vnc_get_client(guac_client* client) { rfbClient* rfb_client = rfbGetClient(8, 3, 4); /* 32-bpp client */ vnc_guac_client_data* guac_client_data = (vnc_guac_client_data*) client->data; /* Store Guac client in rfb client */ rfbClientSetClientData(rfb_client, __GUAC_CLIENT, client); /* Framebuffer update handler */ rfb_client->GotFrameBufferUpdate = guac_vnc_update; rfb_client->GotCopyRect = guac_vnc_copyrect; /* Do not handle clipboard and local cursor if read-only */ if (guac_client_data->read_only == 0) { /* Clipboard */ rfb_client->GotXCutText = guac_vnc_cut_text; /* Set remote cursor */ if (guac_client_data->remote_cursor) rfb_client->appData.useRemoteCursor = FALSE; else { /* Enable client-side cursor */ rfb_client->appData.useRemoteCursor = TRUE; rfb_client->GotCursorShape = guac_vnc_cursor; } } /* Password */ rfb_client->GetPassword = guac_vnc_get_password; /* Depth */ guac_vnc_set_pixel_format(rfb_client, guac_client_data->color_depth); /* Hook into allocation so we can handle resize. */ guac_client_data->rfb_MallocFrameBuffer = rfb_client->MallocFrameBuffer; rfb_client->MallocFrameBuffer = guac_vnc_malloc_framebuffer; rfb_client->canHandleNewFBSize = 1; /* Set hostname and port */ rfb_client->serverHost = strdup(guac_client_data->hostname); rfb_client->serverPort = guac_client_data->port; #ifdef ENABLE_VNC_REPEATER /* Set repeater parameters if specified */ if (guac_client_data->dest_host) { rfb_client->destHost = strdup(guac_client_data->dest_host); rfb_client->destPort = guac_client_data->dest_port; } #endif #ifdef ENABLE_VNC_LISTEN /* If reverse connection enabled, start listening */ if (guac_client_data->reverse_connect) { guac_client_log_info(client, "Listening for connections on port %i", guac_client_data->port); /* Listen for connection from server */ rfb_client->listenPort = guac_client_data->port; if (listenForIncomingConnectionsNoFork(rfb_client, guac_client_data->listen_timeout*1000) <= 0) return NULL; } #endif /* Set encodings if provided */ if (guac_client_data->encodings) rfb_client->appData.encodingsString = strdup(guac_client_data->encodings); /* Connect */ if (rfbInitClient(rfb_client, NULL, NULL)) return rfb_client; /* If connection fails, return NULL */ return NULL; }
rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) { int i,j; if(argv && argc && *argc) { if(client->programName==0) client->programName=argv[0]; for (i = 1; i < *argc; i++) { j = i; if (strcmp(argv[i], "-listen") == 0) { listenForIncomingConnections(client); break; } else if (strcmp(argv[i], "-listennofork") == 0) { listenForIncomingConnectionsNoFork(client, -1); break; } else if (strcmp(argv[i], "-play") == 0) { client->serverPort = -1; j++; } else if (i+1<*argc && strcmp(argv[i], "-encodings") == 0) { client->appData.encodingsString = argv[i+1]; j+=2; } else if (i+1<*argc && strcmp(argv[i], "-compress") == 0) { client->appData.compressLevel = atoi(argv[i+1]); j+=2; } else if (i+1<*argc && strcmp(argv[i], "-quality") == 0) { client->appData.qualityLevel = atoi(argv[i+1]); j+=2; } else if (i+1<*argc && strcmp(argv[i], "-scale") == 0) { client->appData.scaleSetting = atoi(argv[i+1]); j+=2; } else if (i+1<*argc && strcmp(argv[i], "-qosdscp") == 0) { client->QoS_DSCP = atoi(argv[i+1]); j+=2; } else if (i+1<*argc && strcmp(argv[i], "-repeaterdest") == 0) { char* colon=strchr(argv[i+1],':'); if(client->destHost) free(client->destHost); client->destPort = 5900; client->destHost = strdup(argv[i+1]); if(colon) { client->destHost[(int)(colon-argv[i+1])] = '\0'; client->destPort = atoi(colon+1); } j+=2; } else { char* colon=strchr(argv[i],':'); if(client->serverHost) free(client->serverHost); if(colon) { client->serverHost = strdup(argv[i]); client->serverHost[(int)(colon-argv[i])] = '\0'; client->serverPort = atoi(colon+1); } else { client->serverHost = strdup(argv[i]); } if(client->serverPort >= 0 && client->serverPort < 5900) client->serverPort += 5900; } /* purge arguments */ if (j>i) { *argc-=j-i; memmove(argv+i,argv+j,(*argc-i)*sizeof(char*)); i--; } } } if(!rfbInitConnection(client)) { rfbClientCleanup(client); return FALSE; } return TRUE; }