int aceptar_conexion(struct pollfd* personajes, int* server,int cantidad_personajes) { int i = 0, indice = cantidad_personajes; while (i <= indice) { if (personajes[i].fd == 0) { indice = i; personajes[indice].fd = *socket_server_accept(server, logger); } i++; } return indice; }
int main(int argc, char** argv) { int c; while ((c = getopt(argc, argv, "v:")) != -1) { switch (c) { case 'v': verbose = atoi(optarg); break; default: usage(argv[0]); } } if (optind != argc-1) usage(argv[0]); char* display = argv[optind]; trueorabort(display[0] == ':', "Invalid display: '%s'", display); char* endptr; int displaynum = (int)strtol(display+1, &endptr, 10); trueorabort(display+1 != endptr && (*endptr == '\0' || *endptr == '.'), "Invalid display number: '%s'", display); init_display(display); socket_server_init(PORT_BASE + displaynum); unsigned char buffer[BUFFERSIZE]; int length; while (1) { set_connected(dpy, False); socket_server_accept(VERSION); write_init(); set_connected(dpy, True); while (1) { length = socket_client_read_frame((char*)buffer, sizeof(buffer)); if (length < 0) { socket_client_close(1); break; } if (length < 1) { error("Invalid packet from client (size <1)."); socket_client_close(0); break; } switch (buffer[0]) { case 'S': /* Screen */ if (!check_size(length, sizeof(struct screen), "screen")) break; write_image((struct screen*)buffer); break; case 'P': /* Cursor */ if (!check_size(length, sizeof(struct cursor), "cursor")) break; write_cursor(); break; case 'R': /* Resolution */ if (!check_size(length, sizeof(struct resolution), "resolution")) break; change_resolution((struct resolution*)buffer); break; case 'K': { /* Key */ if (!check_size(length, sizeof(struct key), "key")) break; struct key* k = (struct key*)buffer; log(2, "Key: kc=%04x\n", k->keycode); XTestFakeKeyEvent(dpy, k->keycode, k->down, CurrentTime); if (k->down) { kb_add(KEYBOARD, k->keycode); } else { kb_remove(KEYBOARD, k->keycode); } break; } case 'C': { /* Click */ if (!check_size(length, sizeof(struct mouseclick), "mouseclick")) break; struct mouseclick* mc = (struct mouseclick*)buffer; XTestFakeButtonEvent(dpy, mc->button, mc->down, CurrentTime); if (mc->down) { kb_add(MOUSE, mc->button); } else { kb_remove(MOUSE, mc->button); } break; } case 'M': { /* Mouse move */ if (!check_size(length, sizeof(struct mousemove), "mousemove")) break; struct mousemove* mm = (struct mousemove*)buffer; XTestFakeMotionEvent(dpy, 0, mm->x, mm->y, CurrentTime); break; } case 'Q': /* "Quit": release all keys */ kb_release_all(); break; default: error("Invalid packet from client (%d).", buffer[0]); socket_client_close(0); } } socket_client_close(0); kb_release_all(); close_mmap(&cache[0]); close_mmap(&cache[1]); } return 0; }
int main(int argc, char **argv) { int n; /* Poll array: * 0 - server_fd * 1 - pipein_fd * 2 - client_fd (if any) */ struct pollfd fds[3]; int nfds = 3; sigset_t sigmask; sigset_t sigmask_orig; struct sigaction act; int c; while ((c = getopt(argc, argv, "v:")) != -1) { switch (c) { case 'v': verbose = atoi(optarg); break; default: fprintf(stderr, "%s [-v 0-3]\n", argv[0]); return 1; } } /* Termination signal handler. */ memset(&act, 0, sizeof(act)); act.sa_handler = signal_handler; if (sigaction(SIGHUP, &act, 0) < 0 || sigaction(SIGINT, &act, 0) < 0 || sigaction(SIGTERM, &act, 0) < 0) { syserror("sigaction error."); return 2; } /* Ignore SIGPIPE in all cases: it may happen, since we write to pipes, but * it is not fatal. */ sigemptyset(&sigmask); sigaddset(&sigmask, SIGPIPE); if (sigprocmask(SIG_BLOCK, &sigmask, NULL) < 0) { syserror("sigprocmask error."); return 2; } /* Ignore terminating signals, except when ppoll is running. Save current * mask in sigmask_orig. */ sigemptyset(&sigmask); sigaddset(&sigmask, SIGHUP); sigaddset(&sigmask, SIGINT); sigaddset(&sigmask, SIGTERM); if (sigprocmask(SIG_BLOCK, &sigmask, &sigmask_orig) < 0) { syserror("sigprocmask error."); return 2; } /* Prepare pollfd structure. */ memset(fds, 0, sizeof(fds)); fds[0].events = POLLIN; fds[1].events = POLLIN; fds[2].events = POLLIN; /* Initialise pipe and WebSocket server */ socket_server_init(PORT); pipe_init(); while (!terminate) { /* Make sure fds is up to date. */ fds[0].fd = server_fd; fds[1].fd = pipein_fd; fds[2].fd = client_fd; /* Only handle signals in ppoll: this makes sure we complete processing * the current request before bailing out. */ n = ppoll(fds, nfds, NULL, &sigmask_orig); log(3, "poll ret=%d (%d, %d, %d)\n", n, fds[0].revents, fds[1].revents, fds[2].revents); if (n < 0) { /* Do not print error when ppoll is interupted by a signal. */ if (errno != EINTR || verbose >= 1) syserror("ppoll error."); break; } if (fds[0].revents & POLLIN) { log(1, "WebSocket accept."); socket_server_accept(VERSION); n--; } if (fds[1].revents & POLLIN) { log(2, "Pipe fd ready."); pipein_read(); n--; } if (fds[2].revents & POLLIN) { log(2, "Client fd ready."); socket_client_read(); n--; } if (n > 0) { /* Some events were not handled, this is a problem */ error("Some poll events could not be handled: " "ret=%d (%d, %d, %d).", n, fds[0].revents, fds[1].revents, fds[2].revents); break; } } log(1, "Terminating..."); if (client_fd) socket_client_close(1); return 0; }