diff options
Diffstat (limited to '')
-rw-r--r-- | src/mds-kkbd.c | 2285 |
1 files changed, 1132 insertions, 1153 deletions
diff --git a/src/mds-kkbd.c b/src/mds-kkbd.c index 80f67af..59214e8 100644 --- a/src/mds-kkbd.c +++ b/src/mds-kkbd.c @@ -38,49 +38,49 @@ #ifdef __sparc__ -# define GET_LED KIOCGLED -# define SET_LED KIOCSLED +# define GET_LED KIOCGLED +# define SET_LED KIOCSLED #else -# define GET_LED KDGETLED -# define SET_LED KDSETLED +# define GET_LED KDGETLED +# define SET_LED KDSETLED #endif #ifdef __sparc__ -# define LED_NUM_LOCK 1 -# define LED_CAPS_LOCK 8 -# define LED_SCRL_LOCK 4 -# define LED_COMPOSE 2 +# define LED_NUM_LOCK 1 +# define LED_CAPS_LOCK 8 +# define LED_SCRL_LOCK 4 +# define LED_COMPOSE 2 #else -# define LED_NUM_LOCK LED_NUM -# define LED_CAPS_LOCK LED_CAP -# define LED_SCRL_LOCK LED_SCR +# define LED_NUM_LOCK LED_NUM +# define LED_CAPS_LOCK LED_CAP +# define LED_SCRL_LOCK LED_SCR #endif -#define MDS_KKBD_VARS_VERSION 0 +#define MDS_KKBD_VARS_VERSION 0 /** * The name of the keyboard for which its server implements control */ -#define KEYBOARD_ID "kernel" +#define KEYBOARD_ID "kernel" /* NOTE: length hardcoded in `initialise_server` */ /** * LED:s that we believe are present on the keyboard */ #ifdef LED_COMPOSE -# define PRESENT_LEDS "num caps scrl compose" +# define PRESENT_LEDS "num caps scrl compose" #else -# define PRESENT_LEDS "num caps scrl" +# define PRESENT_LEDS "num caps scrl" #endif /** * Measure a string literal in compile time */ -#define lengthof(str) (sizeof(str) / sizeof(char) - 1) +#define lengthof(str) (sizeof(str) / sizeof(char) - 1) @@ -90,15 +90,14 @@ * * This tells the server-base how to behave */ -server_characteristics_t server_characteristics = - { - .require_privileges = 0, - .require_display = 1, - .require_respawn_info = 0, - .sanity_check_argc = 1, - .fork_for_safety = 1, - .danger_is_deadly = 0 - }; +server_characteristics_t server_characteristics = { + .require_privileges = 0, + .require_display = 1, + .require_respawn_info = 0, + .sanity_check_argc = 1, + .fork_for_safety = 1, + .danger_is_deadly = 0 +}; @@ -140,7 +139,7 @@ static int saved_kbd_mode; /** * Keycode remapping table */ -static int* restrict mapping = NULL; +static int *restrict mapping = NULL; /** * The size of `mapping` @@ -165,7 +164,7 @@ static char key_send_buffer[80 + 3 * 3 + 5 + lengthof(KEYBOARD_ID) + 10 + 1]; /** * Message buffer for the main thread */ -static char* send_buffer = NULL; +static char *send_buffer = NULL; /** * The size of `send_buffer` @@ -223,8 +222,8 @@ static int led_compose = LED_COMPOSE; * @param length:size_t The length of the message * @return :int Zero on success, -1 on error */ -#define full_send(message, length) \ - ((full_send)(socket_fd, message, length)) +#define full_send(message, length)\ + ((full_send)(socket_fd, message, length)) /** @@ -232,51 +231,47 @@ static int led_compose = LED_COMPOSE; * * @return Non-zero on error */ -int parse_cmdline(void) +int +parse_cmdline(void) { - int i; - - /* Parse command line arguments. */ - for (i = 1; i < argc; i++) - { - char* arg = argv[i]; - int v; - if ((v = strequals(arg, "--initial-spawn")) || /* Initial spawn? */ - strequals(arg, "--respawn")) /* Respawning after crash? */ - { - exit_if (is_respawn == v, - eprintf("conflicting arguments %s and %s cannot be combined.", - "--initial-spawn", "--respawn");); - is_respawn = !v; + int i, v; + char *arg; + + /* Parse command line arguments. */ + for (i = 1; i < argc; i++) { + arg = argv[i]; + if ((v = strequals(arg, "--initial-spawn")) || /* Initial spawn? */ + strequals(arg, "--respawn")) { /* Respawning after crash? */ + exit_if (is_respawn == v, + eprintf("conflicting arguments %s and %s cannot be combined.", + "--initial-spawn", "--respawn");); + is_respawn = !v; + } else if (strequals(arg, "--re-exec")) { /* Re-exec state-marshal. */ + is_reexec = 1; + } else if (startswith(arg, "--alarm=")) { /* Schedule an alarm signal for forced abort. */ + alarm(min(atou(arg + strlen("--alarm=")), 60)); /* At most 1 minute. */ + } else if (strequals(arg, "--on-init-fork")) { /* Fork process when initialised. */ + on_init_fork = 1; + } else if (startswith(arg, "--on-init-sh=")) { /* Run a command when initialised. */ + on_init_sh = arg + strlen("--on-init-sh="); + } else if (strequals(arg, "--immortal")) { /* I return to serve. */ + is_immortal = 1; + } else if (startswith(arg, "--led=")) { /* Remap LED:s. */ + if (remap_led_cmdline(arg + strlen("--led=")) < 0) + return -1; + } } - else if (strequals(arg, "--re-exec")) /* Re-exec state-marshal. */ - is_reexec = 1; - else if (startswith(arg, "--alarm=")) /* Schedule an alarm signal for forced abort. */ - alarm(min(atou(arg + strlen("--alarm=")), 60)); /* At most 1 minute. */ - else if (strequals(arg, "--on-init-fork")) /* Fork process when initialised. */ - on_init_fork = 1; - else if (startswith(arg, "--on-init-sh=")) /* Run a command when initialised. */ - on_init_sh = arg + strlen("--on-init-sh="); - else if (strequals(arg, "--immortal")) /* I return to serve. */ - is_immortal = 1; - else if (startswith(arg, "--led=")) /* Remap LED:s. */ - { - if (remap_led_cmdline(arg + strlen("--led=")) < 0) - return -1; + if (is_reexec) { + is_respawn = 1; + eprint("re-exec performed."); } - } - if (is_reexec) - { - is_respawn = 1; - eprint("re-exec performed."); - } - - /* Check that mandatory arguments have been specified. */ - if (server_characteristics.require_respawn_info) - exit_if (is_respawn < 0, - eprintf("missing state argument, require either %s or %s.", - "--initial-spawn", "--respawn");); - return 0; + + /* Check that mandatory arguments have been specified. */ + if (server_characteristics.require_respawn_info) + exit_if (is_respawn < 0, + eprintf("missing state argument, require either %s or %s.", + "--initial-spawn", "--respawn");); + return 0; } @@ -286,9 +281,10 @@ int parse_cmdline(void) * * @return Non-zero on error */ -int __attribute__((const)) preinitialise_server(void) +int __attribute__((const)) +preinitialise_server(void) { - return 0; + return 0; } @@ -298,54 +294,54 @@ int __attribute__((const)) preinitialise_server(void) * * @return Non-zero on error */ -int initialise_server(void) +int +initialise_server(void) { - int stage = 0; - const char* const message = - "Command: intercept\n" - "Message ID: 0\n" - "Length: 102\n" - "\n" - "Command: set-keyboard-leds\n" - "Command: get-keyboard-leds\n" - "Command: map-keyboard-leds\n" - "Command: keycode-map\n" - /* NEXT MESSAGE */ - "Command: intercept\n" - "Message ID: 1\n" - "Modifying: yes\n" - "Length: 59\n" - "\n" - "Command: enumerate-keyboards\n" - "Command: keyboard-enumeration\n" - /* NEXT MESSAGE */ - "Command: new-keyboard\n" - "Message ID: 2\n" - "Length: 7\n" - "\n" - KEYBOARD_ID "\n"; - - fail_if (open_leds() < 0); stage++; - fail_if (open_input() < 0); stage++; - fail_if (pthread_mutex_init(&send_mutex, NULL)); stage++; - fail_if (pthread_mutex_init(&mapping_mutex, NULL)); stage++; - fail_if (full_send(message, strlen(message))); - fail_if (server_initialised()); stage++; - fail_if (mds_message_initialise(&received)); - - return 0; - - fail: - xperror(*argv); - if (stage < 5) - { - if (stage >= 2) close_input(); - if (stage >= 1) close_leds(); - } - if (stage >= 3) pthread_mutex_destroy(&send_mutex); - if (stage >= 4) pthread_mutex_destroy(&mapping_mutex); - if (stage >= 5) mds_message_destroy(&received); - return 1; + int stage = 0; + const char *const message = + "Command: intercept\n" + "Message ID: 0\n" + "Length: 102\n" + "\n" + "Command: set-keyboard-leds\n" + "Command: get-keyboard-leds\n" + "Command: map-keyboard-leds\n" + "Command: keycode-map\n" + /* NEXT MESSAGE */ + "Command: intercept\n" + "Message ID: 1\n" + "Modifying: yes\n" + "Length: 59\n" + "\n" + "Command: enumerate-keyboards\n" + "Command: keyboard-enumeration\n" + /* NEXT MESSAGE */ + "Command: new-keyboard\n" + "Message ID: 2\n" + "Length: 7\n" + "\n" + KEYBOARD_ID "\n"; + + fail_if (open_leds() < 0); stage++; + fail_if (open_input() < 0); stage++; + fail_if (pthread_mutex_init(&send_mutex, NULL)); stage++; + fail_if (pthread_mutex_init(&mapping_mutex, NULL)); stage++; + fail_if (full_send(message, strlen(message))); + fail_if (server_initialised()); stage++; + fail_if (mds_message_initialise(&received)); + + return 0; + +fail: + xperror(*argv); + if (stage < 5) { + if (stage >= 2) close_input(); + if (stage >= 1) close_leds(); + } + if (stage >= 3) pthread_mutex_destroy(&send_mutex); + if (stage >= 4) pthread_mutex_destroy(&mapping_mutex); + if (stage >= 5) mds_message_destroy(&received); + return 1; } @@ -355,17 +351,18 @@ int initialise_server(void) * * @return Non-zero on error */ -int postinitialise_server(void) +int +postinitialise_server(void) { - if (connected) - return 0; - - fail_if (reconnect_to_display()); - connected = 1; - return 0; - fail: - mds_message_destroy(&received); - return 1; + if (connected) + return 0; + + fail_if (reconnect_to_display()); + connected = 1; + return 0; +fail: + mds_message_destroy(&received); + return 1; } @@ -376,11 +373,12 @@ int postinitialise_server(void) * * @param status The status witch which the child died */ -void fork_cleanup(int status) +void +fork_cleanup(int status) { - (void) status; - close_input(); - close_leds(); + close_input(); + close_leds(); + (void) status; } @@ -392,12 +390,13 @@ void fork_cleanup(int status) * * @return The number of bytes that will be stored by `marshal_server` */ -size_t marshal_server_size(void) +size_t +marshal_server_size(void) { - size_t rc = 9 * sizeof(int) + sizeof(uint32_t) + sizeof(struct termios); - rc += sizeof(size_t) + mapping_size * sizeof(int); - rc += mds_message_marshal_size(&received); - return rc; + size_t rc = 9 * sizeof(int) + sizeof(uint32_t) + sizeof(struct termios); + rc += sizeof(size_t) + mapping_size * sizeof(int); + rc += mds_message_marshal_size(&received); + return rc; } @@ -407,30 +406,30 @@ size_t marshal_server_size(void) * @param state_buf The buffer for the marshalled data * @return Non-zero on error */ -int marshal_server(char* state_buf) +int +marshal_server(char *state_buf) { - buf_set_next(state_buf, int, MDS_KKBD_VARS_VERSION); - buf_set_next(state_buf, int, connected); - buf_set_next(state_buf, uint32_t, message_id); - buf_set_next(state_buf, int, ledfd); - buf_set_next(state_buf, int, saved_leds); - buf_set_next(state_buf, struct termios, saved_stty); - buf_set_next(state_buf, int, saved_kbd_mode); - buf_set_next(state_buf, int, scancode_ptr); - buf_set_next(state_buf, int, scancode_buf[0]); - buf_set_next(state_buf, int, scancode_buf[1]); - buf_set_next(state_buf, int, scancode_buf[2]); - buf_set_next(state_buf, size_t, mapping_size); - if (mapping_size > 0) - { - memcpy(state_buf, mapping, mapping_size * sizeof(int)); - state_buf += mapping_size * sizeof(int) / sizeof(char); - } - mds_message_marshal(&received, state_buf); - - mds_message_destroy(&received); - free(mapping); - return 0; + buf_set_next(state_buf, int, MDS_KKBD_VARS_VERSION); + buf_set_next(state_buf, int, connected); + buf_set_next(state_buf, uint32_t, message_id); + buf_set_next(state_buf, int, ledfd); + buf_set_next(state_buf, int, saved_leds); + buf_set_next(state_buf, struct termios, saved_stty); + buf_set_next(state_buf, int, saved_kbd_mode); + buf_set_next(state_buf, int, scancode_ptr); + buf_set_next(state_buf, int, scancode_buf[0]); + buf_set_next(state_buf, int, scancode_buf[1]); + buf_set_next(state_buf, int, scancode_buf[2]); + buf_set_next(state_buf, size_t, mapping_size); + if (mapping_size > 0) { + memcpy(state_buf, mapping, mapping_size * sizeof(int)); + state_buf += mapping_size * sizeof(int) / sizeof(char); + } + mds_message_marshal(&received, state_buf); + + mds_message_destroy(&received); + free(mapping); + return 0; } @@ -444,37 +443,37 @@ int marshal_server(char* state_buf) * @param state_buf The marshalled data that as not been read already * @return Non-zero on error */ -int unmarshal_server(char* state_buf) +int +unmarshal_server(char *state_buf) { - /* buf_get_next(state_buf, int, MDS_KKBD_VARS_VERSION); */ - buf_next(state_buf, int, 1); - buf_get_next(state_buf, int, connected); - buf_get_next(state_buf, uint32_t, message_id); - buf_get_next(state_buf, int, ledfd); - buf_get_next(state_buf, int, saved_leds); - buf_get_next(state_buf, struct termios, saved_stty); - buf_get_next(state_buf, int, saved_kbd_mode); - buf_get_next(state_buf, int, scancode_ptr); - buf_get_next(state_buf, int, scancode_buf[0]); - buf_get_next(state_buf, int, scancode_buf[1]); - buf_get_next(state_buf, int, scancode_buf[2]); - buf_get_next(state_buf, size_t, mapping_size); - if (mapping_size > 0) - { - fail_if (xmemdup(mapping, state_buf, mapping_size, int)); - state_buf += mapping_size * sizeof(int) / sizeof(char); - } - fail_if (mds_message_unmarshal(&received, state_buf)); - - return 0; - fail: - xperror(*argv); - mds_message_destroy(&received); - free(mapping); - abort(); /* We must abort on failure to not risk the keyboard - getting stuck and freeze up the computer until - someone ssh:es into it and kill the server. */ - return -1; + /* buf_get_next(state_buf, int, MDS_KKBD_VARS_VERSION); */ + buf_next(state_buf, int, 1); + buf_get_next(state_buf, int, connected); + buf_get_next(state_buf, uint32_t, message_id); + buf_get_next(state_buf, int, ledfd); + buf_get_next(state_buf, int, saved_leds); + buf_get_next(state_buf, struct termios, saved_stty); + buf_get_next(state_buf, int, saved_kbd_mode); + buf_get_next(state_buf, int, scancode_ptr); + buf_get_next(state_buf, int, scancode_buf[0]); + buf_get_next(state_buf, int, scancode_buf[1]); + buf_get_next(state_buf, int, scancode_buf[2]); + buf_get_next(state_buf, size_t, mapping_size); + if (mapping_size > 0) { + fail_if (xmemdup(mapping, state_buf, mapping_size, int)); + state_buf += mapping_size * sizeof(int) / sizeof(char); + } + fail_if (mds_message_unmarshal(&received, state_buf)); + + return 0; +fail: + xperror(*argv); + mds_message_destroy(&received); + free(mapping); + abort(); /* We must abort on failure to not risk the keyboard + getting stuck and freeze up the computer until + someone ssh:es into it and kill the server. */ + return -1; } @@ -484,9 +483,10 @@ int unmarshal_server(char* state_buf) * * @return Non-zero on error */ -int __attribute__((const)) reexec_failure_recover(void) +int __attribute__((const)) +reexec_failure_recover(void) { - return -1; + return -1; } @@ -495,63 +495,62 @@ int __attribute__((const)) reexec_failure_recover(void) * * @return Non-zero on error */ -int master_loop(void) +int +master_loop(void) { - int rc = 1, joined = 0, r; - void* kbd_ret; - - /* Start thread that reads input from the keyboard. */ - fail_if ((errno = pthread_create(&kbd_thread, NULL, keyboard_loop, NULL))); - - /* Listen for messages. */ - while (!reexecing && !terminating) - { - if (danger) - { - danger = 0; - free(send_buffer), send_buffer = NULL; - send_buffer_size = 0; - } - - if (r = mds_message_read(&received, socket_fd), r == 0) - if (r = handle_message(), r == 0) - continue; - - if (r == -2) - { - eprint("corrupt message received, aborting."); - goto done; + int rc = 1, joined = 0, r; + void *kbd_ret; + + /* Start thread that reads input from the keyboard. */ + fail_if ((errno = pthread_create(&kbd_thread, NULL, keyboard_loop, NULL))); + + /* Listen for messages. */ + while (!reexecing && !terminating) { + if (danger) { + danger = 0; + free(send_buffer); + send_buffer = NULL; + send_buffer_size = 0; + } + + if (!(r = mds_message_read(&received, socket_fd))) + if (!(r = handle_message())) + continue; + + if (r == -2) { + eprint("corrupt message received, aborting."); + goto done; + } else if (errno == EINTR) { + continue; + } else { + fail_if (errno != ECONNRESET); + } + + eprint("lost connection to server."); + mds_message_destroy(&received); + mds_message_initialise(&received); + connected = 0; + fail_if (reconnect_to_display()); + connected = 1; } - else if (errno == EINTR) - continue; - else - fail_if (errno != ECONNRESET); - - eprint("lost connection to server."); - mds_message_destroy(&received); - mds_message_initialise(&received); - connected = 0; - fail_if (reconnect_to_display()); - connected = 1; - } - - joined = 1; - fail_if ((errno = pthread_join(kbd_thread, &kbd_ret))); - rc = kbd_ret == NULL ? 0 : 1; - goto done; + + joined = 1; + fail_if ((errno = pthread_join(kbd_thread, &kbd_ret))); + rc = kbd_ret == NULL ? 0 : 1; + goto done; fail: - xperror(*argv); + xperror(*argv); done: - pthread_mutex_destroy(&send_mutex); - pthread_mutex_destroy(&mapping_mutex); - free(send_buffer); - if ((!joined) && (errno = pthread_join(kbd_thread, NULL))) - xperror(*argv); - if (!rc && reexecing) - return 0; - mds_message_destroy(&received); - free(mapping); - return rc; + pthread_mutex_destroy(&send_mutex); + pthread_mutex_destroy(&mapping_mutex); + free(send_buffer); + if (!joined && (errno = pthread_join(kbd_thread, NULL))) + xperror(*argv); + if (!rc && reexecing) + return 0; + mds_message_destroy(&received); + free(mapping); + return rc; } @@ -561,22 +560,22 @@ int master_loop(void) * @param data Input data * @return Output data */ -void* keyboard_loop(void* data) +void * +keyboard_loop(void *data) { - (void) data; - - kbd_thread_started = 1; - - while (!reexecing && !terminating) - if (fetch_keys() < 0) - fail_if (errno != EINTR); - - return NULL; - - fail: - xperror(*argv); - raise(SIGTERM); - return (void*)1024; + kbd_thread_started = 1; + + while (!reexecing && !terminating) + if (fetch_keys() < 0) + fail_if (errno != EINTR); + + return NULL; + +fail: + xperror(*argv); + raise(SIGTERM); + return (void*)1024; + (void) data; } @@ -585,63 +584,63 @@ void* keyboard_loop(void* data) * * @return Zero on success, -1 on error */ -int handle_message(void) +int +handle_message(void) { - const char* recv_command = NULL; - const char* recv_client_id = "0:0"; - const char* recv_message_id = NULL; - const char* recv_modify_id = NULL; - const char* recv_active = NULL; - const char* recv_mask = NULL; - const char* recv_keyboard = NULL; - const char* recv_action = NULL; - size_t i; - -#define __get_header(storage, header) \ - (startswith(received.headers[i], header)) \ - storage = received.headers[i] + strlen(header) - - for (i = 0; i < received.header_count; i++) - { - if __get_header(recv_command, "Command: "); - else if __get_header(recv_client_id, "Client ID: "); - else if __get_header(recv_message_id, "Message ID: "); - else if __get_header(recv_modify_id, "Modify ID: "); - else if __get_header(recv_active, "Active: "); - else if __get_header(recv_mask, "Mask: "); - else if __get_header(recv_keyboard, "Keyboard: "); - else if __get_header(recv_action, "Action: "); - } - + const char *recv_command = NULL; + const char *recv_client_id = "0:0"; + const char *recv_message_id = NULL; + const char *recv_modify_id = NULL; + const char *recv_active = NULL; + const char *recv_mask = NULL; + const char *recv_keyboard = NULL; + const char *recv_action = NULL; + size_t i; + +#define __get_header(storage, header)\ + (startswith(received.headers[i], header))\ + storage = received.headers[i] + strlen(header) + + for (i = 0; i < received.header_count; i++) { + if __get_header(recv_command, "Command: "); + else if __get_header(recv_client_id, "Client ID: "); + else if __get_header(recv_message_id, "Message ID: "); + else if __get_header(recv_modify_id, "Modify ID: "); + else if __get_header(recv_active, "Active: "); + else if __get_header(recv_mask, "Mask: "); + else if __get_header(recv_keyboard, "Keyboard: "); + else if __get_header(recv_action, "Action: "); + } + #undef __get_header - - if (recv_message_id == NULL) - return eprint("received message without ID, ignoring, master server is misbehaving."), 0; - - if (recv_command == NULL) - return 0; /* How did that get here, no matter, just ignore it? */ - -#define t(expr) do { fail_if (expr); return 0; } while (0) - if (strequals(recv_command, "enumerate-keyboards")) - t (handle_enumerate_keyboards(recv_client_id, recv_message_id, recv_modify_id)); - if (strequals(recv_command, "keyboard-enumeration")) - t (handle_keyboard_enumeration(recv_modify_id)); - if (strequals(recv_command, "keycode-map")) - t (handle_keycode_map(recv_client_id, recv_message_id, recv_action, recv_keyboard)); - /* The following do not need to be inside a mutex, because this server - only interprets on message at the time, thus there can not be any - conflicts and access to LED:s are automatically atomic. */ - if (strequals(recv_command, "set-keyboard-leds")) - t (handle_set_keyboard_leds(recv_active, recv_mask, recv_keyboard)); - if (strequals(recv_command, "get-keyboard-leds")) - t (handle_get_keyboard_leds(recv_client_id, recv_message_id, recv_keyboard)); - if (strequals(recv_command, "map-keyboard-leds")) - t (handle_map_keyboard_leds(recv_keyboard)); + + if (!recv_message_id) + return eprint("received message without ID, ignoring, master server is misbehaving."), 0; + + if (!recv_command) + return 0; /* How did that get here, no matter, just ignore it? */ + +#define t(expr) do { fail_if (expr); return 0; } while (0) + if (strequals(recv_command, "enumerate-keyboards")) + t (handle_enumerate_keyboards(recv_client_id, recv_message_id, recv_modify_id)); + if (strequals(recv_command, "keyboard-enumeration")) + t (handle_keyboard_enumeration(recv_modify_id)); + if (strequals(recv_command, "keycode-map")) + t (handle_keycode_map(recv_client_id, recv_message_id, recv_action, recv_keyboard)); + /* The following do not need to be inside a mutex, because this server + only interprets on message at the time, thus there can not be any + conflicts and access to LED:s are automatically atomic. */ + if (strequals(recv_command, "set-keyboard-leds")) + t (handle_set_keyboard_leds(recv_active, recv_mask, recv_keyboard)); + if (strequals(recv_command, "get-keyboard-leds")) + t (handle_get_keyboard_leds(recv_client_id, recv_message_id, recv_keyboard)); + if (strequals(recv_command, "map-keyboard-leds")) + t (handle_map_keyboard_leds(recv_keyboard)); #undef t - - return 0; /* How did that get here, no matter, just ignore it? */ - fail: - return -1; + + return 0; /* How did that get here, no matter, just ignore it? */ +fail: + return -1; } @@ -651,20 +650,21 @@ int handle_message(void) * @param size The size required for the buffer * @return Zero on success, -1 on error */ -static int ensure_send_buffer_size(size_t size) +static int +ensure_send_buffer_size(size_t size) { - char* old = send_buffer; - - if (send_buffer_size >= size) - return 0; - - fail_if (xrealloc(send_buffer, size, char)); - send_buffer_size = size; - - return 0; - fail: - send_buffer = old; - return -1; + char *old = send_buffer; + + if (send_buffer_size >= size) + return 0; + + fail_if (xrealloc(send_buffer, size, char)); + send_buffer_size = size; + + return 0; +fail: + send_buffer = old; + return -1; } @@ -677,75 +677,74 @@ static int ensure_send_buffer_size(size_t size) * @param recv_modify_id The value of the `Modify ID`-header, `NULL` if omitted * @return Zero on success, -1 on error */ -int handle_enumerate_keyboards(const char* recv_client_id, const char* recv_message_id, - const char* recv_modify_id) +int +handle_enumerate_keyboards(const char *recv_client_id, const char *recv_message_id, const char *recv_modify_id) { - uint32_t msgid; - size_t n; - int r; - - if (recv_modify_id == NULL) - return eprint("did not get a modify ID, ignoring."), 0; - - - if (strequals(recv_client_id, "0:0")) - { - eprint("received information request from an anonymous client, sending non-modifying response."); - - with_mutex (send_mutex, - msgid = message_id; - message_id = message_id == UINT32_MAX ? 0 : (message_id + 1); - ); - - fail_if (ensure_send_buffer_size(47 + strlen(recv_modify_id) + 1) < 0); - sprintf(send_buffer, - "Modify: no\n" - "Modify ID: %s\n" - "Message ID: %" PRIu32 "\n" - "\n", - recv_modify_id, msgid); - - with_mutex (send_mutex, - r = full_send(send_buffer, strlen(send_buffer)); - if (r) r = errno ? errno : -1; - ); - fail_if (errno = (r == -1 ? 0 : r), r); - return 0; - } - - with_mutex (send_mutex, - msgid = message_id; - message_id = message_id == INT32_MAX ? 0 : (message_id + 1); - message_id = message_id == INT32_MAX ? 0 : (message_id + 1); - ); - - n = 134 + 3 * sizeof(size_t) + lengthof(KEYBOARD_ID); - n += strlen(recv_client_id) + strlen(recv_modify_id) + strlen(recv_message_id); - fail_if (ensure_send_buffer_size(n + 1) < 0); - sprintf(send_buffer, - "Modify: yes\n" - "Modify ID: %s\n" - "Message ID: %" PRIu32 "\n" - "\n" - /* NEXT MESSAGE */ - "Command: keyboard-enumeration\n" - "To: %s\n" - "In response to: %s\n" - "Length: %zu\n" - "Message ID: %" PRIu32 "\n" - "\n" - KEYBOARD_ID "\n", - recv_modify_id, msgid, - recv_client_id, recv_message_id, lengthof(KEYBOARD_ID) + 1, msgid + 1); - - with_mutex (send_mutex, - r = full_send(send_buffer, strlen(send_buffer)); - if (r) r = errno ? errno : -1; - ); - fail_if (errno = (r == -1 ? 0 : r), r); - return 0; - fail: - return -1; + uint32_t msgid; + size_t n; + int r; + + if (!recv_modify_id) + return eprint("did not get a modify ID, ignoring."), 0; + + + if (strequals(recv_client_id, "0:0")) { + eprint("received information request from an anonymous client, sending non-modifying response."); + + with_mutex (send_mutex, + msgid = message_id; + message_id = message_id == UINT32_MAX ? 0 : (message_id + 1); + ); + + fail_if (ensure_send_buffer_size(47 + strlen(recv_modify_id) + 1) < 0); + sprintf(send_buffer, + "Modify: no\n" + "Modify ID: %s\n" + "Message ID: %" PRIu32 "\n" + "\n", + recv_modify_id, msgid); + + with_mutex (send_mutex, + r = full_send(send_buffer, strlen(send_buffer)); + if (r) r = errno ? errno : -1; + ); + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; + } + + with_mutex (send_mutex, + msgid = message_id; + message_id = message_id == INT32_MAX ? 0 : (message_id + 1); + message_id = message_id == INT32_MAX ? 0 : (message_id + 1); + ); + + n = 134 + 3 * sizeof(size_t) + lengthof(KEYBOARD_ID); + n += strlen(recv_client_id) + strlen(recv_modify_id) + strlen(recv_message_id); + fail_if (ensure_send_buffer_size(n + 1) < 0); + sprintf(send_buffer, + "Modify: yes\n" + "Modify ID: %s\n" + "Message ID: %" PRIu32 "\n" + "\n" + /* NEXT MESSAGE */ + "Command: keyboard-enumeration\n" + "To: %s\n" + "In response to: %s\n" + "Length: %zu\n" + "Message ID: %" PRIu32 "\n" + "\n" + KEYBOARD_ID "\n", + recv_modify_id, msgid, + recv_client_id, recv_message_id, lengthof(KEYBOARD_ID) + 1, msgid + 1); + + with_mutex (send_mutex, + r = full_send(send_buffer, strlen(send_buffer)); + if (r) r = errno ? errno : -1; + ); + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; +fail: + return -1; } @@ -756,127 +755,126 @@ int handle_enumerate_keyboards(const char* recv_client_id, const char* recv_mess * @param recv_modify_id The value of the `Modify ID`-header, `NULL` if omitted * @return Zero on success, -1 on error */ -int handle_keyboard_enumeration(const char* recv_modify_id) +int +handle_keyboard_enumeration(const char *recv_modify_id) { - size_t i, off, m, n = lengthof(KEYBOARD_ID "\n") + 3 * sizeof(size_t); - ssize_t top; - uint32_t msgid; - int r, have_len = 0; - - if (recv_modify_id == NULL) - return eprint("did not get a modify ID, ignoring."), 0; - - - /* Calculate length of received message. */ - - /* Measure the length of the headers. */ - for (i = 0; i < received.header_count; i++) - n += strlen(received.headers[i]); - /* Count the line feeds after the headers. */ - n += received.header_count; - /* There is an empty line between headers and payload. */ - n += 1; - /* Add the length of the payload. */ - n += received.payload_size; - - - /* Calculate upper bound for the outbound message's payload */ - n += lengthof("Length: \n") + 3 * sizeof(size_t); - n += lengthof(KEYBOARD_ID "\n"); - - - /* Calculate an upper bound for the outbound message. - `off` is an upper bound for the outbound message's - headers plus empty line and thus where we should - write the payload to the buffer. */ - off = sizeof("Modify ID: \nMessage ID: \nLength: \n\n") / sizeof(char) - 1; - n += off += strlen(recv_modify_id) + 10 + 3 * sizeof(size_t); - - - /* Make sure the buffer fits the message, add one additional - character to the allocation so sprintf does not write outside - the buffer. */ - fail_if (ensure_send_buffer_size(n + 1) < 0); - - /* Fetch and increase local message ID. */ - with_mutex (send_mutex, - msgid = message_id; - message_id = message_id == INT32_MAX ? 0 : (message_id + 1); - ); - - - /* Write outbound message payload. */ - - /* Write inbound message's headers to the outbound message, - `n` keeps track of were we are. */ - n = off; - for (i = 0; i < received.header_count; i++) - { - const char* header = received.headers[i]; - if (!have_len && startswith(header, "Length: ")) - { - have_len = 1; - sprintf(send_buffer + n, - "Length: %zu\n", - received.payload_size + lengthof(KEYBOARD_ID "\n")); - n += strlen(send_buffer + n); + size_t i, off, m, n = lengthof(KEYBOARD_ID "\n") + 3 * sizeof(size_t); + ssize_t top; + uint32_t msgid; + int r, have_len = 0; + const char *header; + + if (!recv_modify_id) + return eprint("did not get a modify ID, ignoring."), 0; + + + /* Calculate length of received message. */ + + /* Measure the length of the headers. */ + for (i = 0; i < received.header_count; i++) + n += strlen(received.headers[i]); + /* Count the line feeds after the headers. */ + n += received.header_count; + /* There is an empty line between headers and payload. */ + n += 1; + /* Add the length of the payload. */ + n += received.payload_size; + + + /* Calculate upper bound for the outbound message's payload */ + n += lengthof("Length: \n") + 3 * sizeof(size_t); + n += lengthof(KEYBOARD_ID "\n"); + + + /* Calculate an upper bound for the outbound message. + `off` is an upper bound for the outbound message's + headers plus empty line and thus where we should + write the payload to the buffer. */ + off = sizeof("Modify ID: \nMessage ID: \nLength: \n\n") / sizeof(char) - 1; + n += off += strlen(recv_modify_id) + 10 + 3 * sizeof(size_t); + + + /* Make sure the buffer fits the message, add one additional + character to the allocation so sprintf does not write outside + the buffer. */ + fail_if (ensure_send_buffer_size(n + 1) < 0); + + /* Fetch and increase local message ID. */ + with_mutex (send_mutex, + msgid = message_id; + message_id = message_id == INT32_MAX ? 0 : (message_id + 1); + ); + + + /* Write outbound message payload. */ + + /* Write inbound message's headers to the outbound message, + `n` keeps track of were we are. */ + n = off; + for (i = 0; i < received.header_count; i++) { + header = received.headers[i]; + if (!have_len && startswith(header, "Length: ")) { + have_len = 1; + sprintf(send_buffer + n, + "Length: %zu\n", + received.payload_size + lengthof(KEYBOARD_ID "\n")); + n += strlen(send_buffer + n); + } else { + m = strlen(header); + memcpy(send_buffer + n, header, m * sizeof(char)), n += m; + send_buffer[n++] = '\n'; + } } - else - { - m = strlen(header); - memcpy(send_buffer + n, header, m * sizeof(char)), n += m; - send_buffer[n++] = '\n'; + /* If we did not `Length`-header we must add it as we will extend the payload. */ + if (!have_len) { + sprintf(send_buffer + n, + "Length: %zu\n", + lengthof(KEYBOARD_ID "\n")); + n += strlen(send_buffer + n); } - } - /* If we did not `Length`-header we must add it as we will extend the payload. */ - if (!have_len) - sprintf(send_buffer + n, - "Length: %zu\n", - lengthof(KEYBOARD_ID "\n")), - n += strlen(send_buffer + n); - /* Mark end of inbound headers. */ - send_buffer[n++] = '\n'; - /* Write inbound message's payload to the outbound message. */ - memcpy(send_buffer + n, received.payload, received.payload_size * sizeof(char)); - n += received.payload_size; - /* Add our keyboard to the payload. */ - memcpy(send_buffer + n, KEYBOARD_ID "\n", lengthof(KEYBOARD_ID "\n") * sizeof(char)); - n += lengthof(KEYBOARD_ID "\n"); - /* Change `n` to tell the length of the outbound message's payload. */ - n -= off; - - - /* Complete outbound message. */ - - /* Write the outbound message's headers. */ - sprintf(send_buffer, - "Modify ID: %s\n" - "Message ID: %" PRIu32 "\n" - "Length: %zu\n%zn", - recv_modify_id, msgid, n, &top); - /* Write the empty line. */ - send_buffer[(size_t)(top++)] = '\n'; - /* Calculate what the offset in the entire buffer for the - message should be, and move the message to that offset. - Only the headers and the empty line should be moved, so - that it is juxtaposed with the payload. */ - off -= (size_t)top; - memmove(send_buffer + off, send_buffer, ((size_t)top) * sizeof(char)); - /* Calculate the final length of the message. */ - n += (size_t)top; - - - /* Send message. */ - - with_mutex (send_mutex, - r = full_send(send_buffer + off, n); - if (r) r = errno ? errno : -1; - ); - - fail_if (errno = (r == -1 ? 0 : r), r); - return 0; - fail: - return -1; + /* Mark end of inbound headers. */ + send_buffer[n++] = '\n'; + /* Write inbound message's payload to the outbound message. */ + memcpy(send_buffer + n, received.payload, received.payload_size * sizeof(char)); + n += received.payload_size; + /* Add our keyboard to the payload. */ + memcpy(send_buffer + n, KEYBOARD_ID "\n", lengthof(KEYBOARD_ID "\n") * sizeof(char)); + n += lengthof(KEYBOARD_ID "\n"); + /* Change `n` to tell the length of the outbound message's payload. */ + n -= off; + + + /* Complete outbound message. */ + + /* Write the outbound message's headers. */ + sprintf(send_buffer, + "Modify ID: %s\n" + "Message ID: %" PRIu32 "\n" + "Length: %zu\n%zn", + recv_modify_id, msgid, n, &top); + /* Write the empty line. */ + send_buffer[(size_t)(top++)] = '\n'; + /* Calculate what the offset in the entire buffer for the + message should be, and move the message to that offset. + Only the headers and the empty line should be moved, so + that it is juxtaposed with the payload. */ + off -= (size_t)top; + memmove(send_buffer + off, send_buffer, ((size_t)top) * sizeof(char)); + /* Calculate the final length of the message. */ + n += (size_t)top; + + + /* Send message. */ + + with_mutex (send_mutex, + r = full_send(send_buffer + off, n); + if (r) r = errno ? errno : -1; + ); + + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; +fail: + return -1; } @@ -889,66 +887,63 @@ int handle_keyboard_enumeration(const char* recv_modify_id) * @param recv_keyboard The value of the `Keyboard`-header, `NULL` if omitted * @return Zero on success, -1 on error */ -int handle_set_keyboard_leds(const char* recv_active, const char* recv_mask, const char* recv_keyboard) +int +handle_set_keyboard_leds(const char *recv_active, const char *recv_mask, const char *recv_keyboard) { - int active = 0; - int mask = 0; - int current; - const char* begin; - const char* end; - - if ((recv_keyboard != NULL) && !strequals(recv_keyboard, KEYBOARD_ID)) - return 0; - - if (recv_active == NULL) - return eprint("received LED writing request without active header, ignoring."), 0; + int active = 0; + int mask = 0; + int current; + const char *begin; + const char *end; - if (recv_mask == NULL) - return eprint("received LED writing request without mask header, ignoring."), 0; - - current = get_leds(); - if (current < 0) - { - xperror(*argv); - return 0; /* Not fatal */ - } - -#define __test(have, want) (startswith(have, want " ") || strequals(have, want)) - - for (begin = end = recv_active; end != NULL;) - { - end = strchr(begin, ' '); - if (__test(begin, "num")) active |= led_num_lock; - else if (__test(begin, "caps")) active |= led_caps_lock; - else if (__test(begin, "scrl")) active |= led_scrl_lock; + if ((recv_keyboard) && !strequals(recv_keyboard, KEYBOARD_ID)) + return 0; + + if (!recv_active) + return eprint("received LED writing request without active header, ignoring."), 0; + + if (!recv_mask) + return eprint("received LED writing request without mask header, ignoring."), 0; + + current = get_leds(); + if (current < 0) { + xperror(*argv); + return 0; /* Not fatal */ + } + +#define __test(have, want) (startswith(have, want " ") || strequals(have, want)) + + for (begin = end = recv_active; end;) { + end = strchr(begin, ' '); + if (__test(begin, "num")) active |= led_num_lock; + else if (__test(begin, "caps")) active |= led_caps_lock; + else if (__test(begin, "scrl")) active |= led_scrl_lock; #ifdef LED_COMPOSE - else if (__test(begin, "compose")) active |= led_compose; + else if (__test(begin, "compose")) active |= led_compose; #endif - begin = end + 1; - } - - for (begin = end = recv_mask; end != NULL;) - { - end = strchr(begin, ' '); - if (__test(begin, "num")) mask |= led_num_lock; - else if (__test(begin, "caps")) mask |= led_caps_lock; - else if (__test(begin, "scrl")) mask |= led_scrl_lock; + begin = end + 1; + } + + for (begin = end = recv_mask; end;) { + end = strchr(begin, ' '); + if (__test(begin, "num")) mask |= led_num_lock; + else if (__test(begin, "caps")) mask |= led_caps_lock; + else if (__test(begin, "scrl")) mask |= led_scrl_lock; #ifdef LED_COMPOSE - else if (__test(begin, "compose")) mask |= led_compose; + else if (__test(begin, "compose")) mask |= led_compose; #endif - begin = end + 1; - } - + begin = end + 1; + } + #undef __test - - current = (active & mask) | ((current ^ active) & ~mask); - if (set_leds(current) < 0) - { - xperror(*argv); /* Not fatal */ - return 0; - } - - return 0; + + current = (active & mask) | ((current ^ active) & ~mask); + if (set_leds(current) < 0) { + xperror(*argv); /* Not fatal */ + return 0; + } + + return 0; } @@ -961,66 +956,65 @@ int handle_set_keyboard_leds(const char* recv_active, const char* recv_mask, con * @param recv_keyboard The value of the `Keyboard`-header, `NULL` if omitted * @return Zero on success, -1 on error */ -int handle_get_keyboard_leds(const char* recv_client_id, const char* recv_message_id, const char* recv_keyboard) +int +handle_get_keyboard_leds(const char *recv_client_id, const char *recv_message_id, const char *recv_keyboard) { - uint32_t msgid; - size_t n; - int r, leds; - - if ((recv_keyboard != NULL) && !strequals(recv_keyboard, KEYBOARD_ID)) - return 0; - - if (recv_keyboard == NULL) - return eprint("received LED reading request but no specified keyboard, ignoring."), 0; - - if (strequals(recv_client_id, "0:0")) - return eprint("received information request from an anonymous client, ignoring."), 0; + uint32_t msgid; + size_t n; + int r, leds, error; - leds = get_leds(); - if (leds < 0) - { - int error = errno; - xperror(*argv); - send_errno(error, recv_client_id, recv_message_id); - fail_if (errno = error, 1); - } - - with_mutex (send_mutex, - msgid = message_id; - message_id = message_id == INT32_MAX ? 0 : (message_id + 1); - ); - - n = 65 + 2 * strlen(PRESENT_LEDS); - n += strlen(recv_client_id) + strlen(recv_message_id); - fail_if (ensure_send_buffer_size(n + 1) < 0); - sprintf(send_buffer, - "To: %s\n" - "In response to: %s\n" - "Message ID: %" PRIu32 "\n" - "Active:%s%s%s%s%s\n" - "Present: " PRESENT_LEDS "\n" - "\n", - recv_client_id, recv_message_id, msgid, - (leds & led_num_lock) ? " num" : "", - (leds & led_caps_lock) ? " caps" : "", - (leds & led_scrl_lock) ? " scrl" : "", + if (recv_keyboard && !strequals(recv_keyboard, KEYBOARD_ID)) + return 0; + + if (!recv_keyboard) + return eprint("received LED reading request but no specified keyboard, ignoring."), 0; + + if (strequals(recv_client_id, "0:0")) + return eprint("received information request from an anonymous client, ignoring."), 0; + + leds = get_leds(); + if (leds < 0) { + error = errno; + xperror(*argv); + send_errno(error, recv_client_id, recv_message_id); + fail_if (errno = error, 1); + } + + with_mutex (send_mutex, + msgid = message_id; + message_id = message_id == INT32_MAX ? 0 : (message_id + 1); + ); + + n = 65 + 2 * strlen(PRESENT_LEDS); + n += strlen(recv_client_id) + strlen(recv_message_id); + fail_if (ensure_send_buffer_size(n + 1) < 0); + sprintf(send_buffer, + "To: %s\n" + "In response to: %s\n" + "Message ID: %" PRIu32 "\n" + "Active:%s%s%s%s%s\n" + "Present: " PRESENT_LEDS "\n" + "\n", + recv_client_id, recv_message_id, msgid, + (leds & led_num_lock) ? " num" : "", + (leds & led_caps_lock) ? " caps" : "", + (leds & led_scrl_lock) ? " scrl" : "", #ifdef LED_COMPOSE - (leds & led_compose) ? " compose" : + (leds & led_compose) ? " compose" : #endif - "", - leds == 0 ? " none" : "" - ); - - with_mutex (send_mutex, - r = full_send(send_buffer, strlen(send_buffer)); - if (r) r = errno ? errno : -1; - ); + "", + leds == 0 ? " none" : ""); - fail_if (errno = (r == -1 ? 0 : r), r); - return 0; - fail: - xperror(*argv); - return -1; + with_mutex (send_mutex, + r = full_send(send_buffer, strlen(send_buffer)); + if (r) r = errno ? errno : -1; + ); + + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; +fail: + xperror(*argv); + return -1; } @@ -1050,46 +1044,45 @@ static int parse_led(const char* name) * @param position The new position of the LED, either zero-based index * or name of the original LED with that position */ -__attribute__((nonnull)) -static void remap_led(const char* name, const char* position) +static void __attribute__((nonnull)) +remap_led(const char *name, const char *position) { - int* leds[] = { [LED_NUM_LOCK] = &led_num_lock, - [LED_CAPS_LOCK] = &led_caps_lock, + int *leds[] = {[LED_NUM_LOCK] = &led_num_lock, + [LED_CAPS_LOCK] = &led_caps_lock, #ifdef LED_COMPOSE - [LED_COMPOSE] = &led_compose, + [LED_COMPOSE] = &led_compose, #endif - [LED_SCRL_LOCK] = &led_scrl_lock}; - - int led = parse_led(name); - int pos = parse_led(position); - size_t i, n; - char c; - - if (led < 0) - { - eprintf("received invalid LED, %s, to remap, ignoring.", name); - return; - } - - if (pos >= 0) - goto done; - - for (pos = 0, i = 0, n = strlen(position); i < n; i++) - if (c = position[i], ('0' <= c) && (c <= '9')) - pos = pos * 10 + (c & 15); - else - break; - - if (i < n) - { - eprintf("received invalid LED position, %s, ignoring.", position); - return; - } - - pos = 1 << pos; - - done: - *(leds[led]) = pos; + [LED_SCRL_LOCK] = &led_scrl_lock}; + + int led = parse_led(name); + int pos = parse_led(position); + size_t i, n; + char c; + + if (led < 0) { + eprintf("received invalid LED, %s, to remap, ignoring.", name); + return; + } + + if (pos >= 0) + goto done; + + for (pos = 0, i = 0, n = strlen(position); i < n; i++) { + if (c = position[i], ('0' <= c) && (c <= '9')) + pos = pos * 10 + (c & 15); + else + break; + } + + if (i < n) { + eprintf("received invalid LED position, %s, ignoring.", position); + return; + } + + pos = 1 << pos; + +done: + *(leds[led]) = pos; } @@ -1101,20 +1094,20 @@ static void remap_led(const char* name, const char* position) * that position; delimited by an equals-sign * @return Zero on success, -1 on error */ -int remap_led_cmdline(char* arg) +int +remap_led_cmdline(char *arg) { - char* pos = strchr(arg, '='); - - if ((pos == NULL) || (strlen(pos) == 1)) - { - eprintf("received invalid argument for --led: %s", arg); - errno = 0; - return -1; - } - - *pos++ = '\0'; - remap_led(arg, pos); - return 0; + char *pos = strchr(arg, '='); + + if (!pos || strlen(pos) == 1) { + eprintf("received invalid argument for --led: %s", arg); + errno = 0; + return -1; + } + + *pos++ = '\0'; + remap_led(arg, pos); + return 0; } @@ -1125,56 +1118,54 @@ int remap_led_cmdline(char* arg) * @param recv_keyboard The value of the `Keyboard`-header, `NULL` if omitted * @return Zero on success, -1 on error */ -int handle_map_keyboard_leds(const char* recv_keyboard) +int +handle_map_keyboard_leds(const char *recv_keyboard) { - char* led = NULL; - char* pos = NULL; - int stage = 0; - size_t i; - - if ((recv_keyboard != NULL) && !strequals(recv_keyboard, KEYBOARD_ID)) - return 0; - - /* Parse the payload. `led` and `pos` are set just when thier first - character is iterated over, rather than at the delimiter. This way - we can easily check for message corruption at the end and give a - better error message. */ - for (i = 0; i < received.payload_size; i++) - if (stage == 0) - { - if (led == NULL) - led = received.payload + i; - if (received.payload[i] == ' ') - received.payload[i] = '\0', stage = 1; - } - else if (stage == 1) - { - if (pos == NULL) - pos = received.payload + i; - if (received.payload[i] == '\n') - { - received.payload[i] = '\0'; - remap_led(led, pos); - led = pos = NULL; - stage = 0; - } - } - if ((stage == 1) && (pos != NULL)) - { - /* Copy over the position value to a new allocation on the stack - and NUL-terminate it. We are at the of the payload and cannot - besure sure that we can put an extra NUL at the end of it - without reallocating the payload which is much ore complicated. */ - size_t len = (size_t)(pos - received.payload); - char* pos_ = alloca((len + 1) * sizeof(char)); - memcpy(pos_, pos, len * sizeof(char)); - pos_[len] = '\0'; - remap_led(led, pos_); - } - else if (led != NULL) - eprint("received incomplete LED remapping instruction, ignoring."); - - return 0; + char *led = NULL; + char *pos = NULL; + int stage = 0; + size_t i, len; + char *pos_; + + if (recv_keyboard && !strequals(recv_keyboard, KEYBOARD_ID)) + return 0; + + /* Parse the payload. `led` and `pos` are set just when thier first + character is iterated over, rather than at the delimiter. This way + we can easily check for message corruption at the end and give a + better error message. */ + for (i = 0; i < received.payload_size; i++) { + if (stage == 0) { + if (led == NULL) + led = received.payload + i; + if (received.payload[i] == ' ') + received.payload[i] = '\0', stage = 1; + } else if (stage == 1) { + if (pos == NULL) + pos = received.payload + i; + if (received.payload[i] == '\n') { + received.payload[i] = '\0'; + remap_led(led, pos); + led = pos = NULL; + stage = 0; + } + } + } + if (stage == 1 && pos) { + /* Copy over the position value to a new allocation on the stack + and NUL-terminate it. We are at the of the payload and cannot + besure sure that we can put an extra NUL at the end of it + without reallocating the payload which is much ore complicated. */ + len = (size_t)(pos - received.payload); + pos_ = alloca((len + 1) * sizeof(char)); + memcpy(pos_, pos, len * sizeof(char)); + pos_[len] = '\0'; + remap_led(led, pos_); + } else if (led) { + eprint("received incomplete LED remapping instruction, ignoring."); + } + + return 0; } @@ -1188,37 +1179,34 @@ int handle_map_keyboard_leds(const char* recv_keyboard) * @param out Output parameter for the keycode's new mapping * @return -1 on error, 1 if parsed, 0 if the line is empty */ -__attribute__((nonnull(1, 4, 5))) -static int parse_remap_line(char* begin, char* end, size_t n, int* restrict in, int* restrict out) +static int __attribute__((nonnull(1, 4, 5))) +parse_remap_line(char *begin, char *end, size_t n, int *restrict in, int *restrict out) { - static char buf[3 * sizeof(int) + 1]; - - size_t len = end == NULL ? n : (size_t)(end - begin); - char* delimiter = memchr(begin, ' ', len); - - if (len == 0) - return 0; - - if (delimiter == NULL) - fail_if (*in = -1, *out = -1); - - *delimiter++ = '\0'; - *in = atoi(begin); - if (end == NULL) - { - snprintf(buf, sizeof(buf) / sizeof(char), "%.*s", - (int)(len - (size_t)(delimiter - begin)), delimiter); - *out = atoi(buf); - } - else - { - *end = '\0'; - *out = atoi(delimiter); - } - - return 1; - fail: - return -1; + static char buf[3 * sizeof(int) + 1]; + + size_t len = !end ? n : (size_t)(end - begin); + char *delimiter = memchr(begin, ' ', len); + + if (!len) + return 0; + + if (!delimiter) + fail_if (*in = -1, *out = -1); + + *delimiter++ = '\0'; + *in = atoi(begin); + if (!end) { + snprintf(buf, sizeof(buf) / sizeof(char), "%.*s", + (int)(len - (size_t)(delimiter - begin)), delimiter); + *out = atoi(buf); + } else { + *end = '\0'; + *out = atoi(delimiter); + } + + return 1; +fail: + return -1; } @@ -1229,27 +1217,28 @@ static int parse_remap_line(char* begin, char* end, size_t n, int* restrict in, * @parma out The keycode's new mapping * @return Zero on success, -1 on error */ -static int add_mapping(int in, int out) +static int +add_mapping(int in, int out) { - size_t n = ((size_t)in) + 1; - int* old; - - if (n > mapping_size) - { - if (in == out) + size_t n = ((size_t)in) + 1; + int *old; + + if (n > mapping_size) { + if (in == out) + return 0; + + old = mapping; + if (xrealloc(mapping, n, int)) + fail_if (mapping = old, 1); + + for (; mapping_size < n; mapping_size++) + mapping[mapping_size] = (int)mapping_size; + } + + mapping[in] = out; return 0; - - if (old = mapping, xrealloc(mapping, n, int)) - fail_if (mapping = old, 1); - - for (; mapping_size < n; mapping_size++) - mapping[mapping_size] = (int)mapping_size; - } - - mapping[in] = out; - return 0; - fail: - return -1; +fail: + return -1; } @@ -1260,45 +1249,44 @@ static int add_mapping(int in, int out) * @param n The size of `table` * @return Zero on success, -1 on error */ -__attribute__((nonnull)) -static int remap(char* table, size_t n) +static int __attribute__((nonnull)) +remap(char *table, size_t n) { - char* begin = table; - int greatest_remap = -1; - int greatest_reset = -1; - - for (;;) - { - char* end = memchr(begin, '\n', n); - int in, out; - - if (!parse_remap_line(begin, end, n, &in, &out)) - goto next; - if ((in < 0) || (out < 0) || ((in | out) >= 0x4000)) - { - eprint("received malformated remapping table."); - goto next; + char *begin = table; + int greatest_remap = -1; + int greatest_reset = -1; + char *end; + int in, out; + + for (;;) { + end = memchr(begin, '\n', n); + + if (!parse_remap_line(begin, end, n, &in, &out)) + goto next; + if (in < 0 || out < 0 || (in | out) >= 0x4000) { + eprint("received malformated remapping table."); + goto next; + } + + if (in != out) greatest_remap = max(greatest_remap, in); + else greatest_reset = max(greatest_reset, in); + + fail_if (add_mapping(in, out) < 0); + + next: + if (!end) + break; + end++; + n -= (size_t)(end - begin); + begin = end; } - - if (in != out) greatest_remap = max(greatest_remap, in); - else greatest_reset = max(greatest_reset, in); - - fail_if (add_mapping(in, out) < 0); - - next: - if (end == NULL) - break; - end++; - n -= (size_t)(end - begin); - begin = end; - } - - if ((greatest_reset > greatest_remap) && (((((size_t)greatest_remap) + 1) >> 1) < mapping_size)) - shrink_map(); - - return 0; - fail: - return -1; + + if (greatest_reset > greatest_remap && ((size_t)greatest_remap + 1) >> 1 < mapping_size) + shrink_map(); + + return 0; +fail: + return -1; } @@ -1309,79 +1297,79 @@ static int remap(char* table, size_t n) * @param recv_message_id The value of the `Message ID`-header * @return Zero on success, -1 on error */ -__attribute__((nonnull)) -static int mapping_query(const char* recv_client_id, const char* recv_message_id) +static int __attribute__((nonnull)) +mapping_query(const char *recv_client_id, const char *recv_message_id) { - size_t top = 64 + 3 * sizeof(size_t), n = 0, off, i; - ssize_t len; - int greatest = 0, r; - uint32_t msgid; - - /* Count the number of non-identity mappings, and - figure out the value of non-identity mapping - with the highest value. */ - for (i = 0; i < mapping_size; i++) - if (mapping[i] != (int)i) - { - greatest = max(greatest, mapping[i]); - n++; - } - /* If the highest source is larger than the - highest targt, that source value will - be highest integer that will be included - the mapping-table. */ - greatest = max(greatest, (int)mapping_size); - /* Calculate an upper bound for the payload. */ - n *= 2 + 2 * (size_t)(greatest > 0x00FF ? 5 : 3); - - /* Ensure that the buffer is large enough for - the message and that `sprintf` will not - write outside it. */ - fail_if (ensure_send_buffer_size(top + n + 2) < 0); - - /* Fetch and increase local message ID. */ - with_mutex (send_mutex, - msgid = message_id; - message_id = message_id == INT32_MAX ? 0 : (message_id + 1); - ); - - /* The offset for the payload should fit all - headers and an empty line. */ - off = top + 1; - /* Write all non-identity mappings to the payload. */ - for (i = 0; i < mapping_size; i++) - if (mapping[i] != (int)i) - sprintf(send_buffer + off, "%i %i\n%zn", i, mapping[i], &len), - off += (size_t)len; - /* Calculate the length of the payload. */ - n = (size_t)(off - (top + 1)); - - /* Write the headers, and the empty line after them. */ - sprintf(send_buffer, - "To: %s\n" - "In response to: %s\n" - "Message ID: %" PRIu32 "\n" - "Length: %zu\n" - "\n%zn", - recv_client_id, recv_message_id, msgid, n, &len); - top = (size_t)len; - /* Move the headers and the empty line so that they are - juxtaposed with the payload. */ - off -= top; - memmove(send_buffer + off, send_buffer, top * sizeof(char)); - - - /* Send the message. */ - - with_mutex (send_mutex, - r = full_send(send_buffer + off, top + n); - if (r) r = errno ? errno : -1; - ); - - fail_if (errno = (r == -1 ? 0 : r), r); - return 0; - fail: - return -1; + size_t top = 64 + 3 * sizeof(size_t), n = 0, off, i; + ssize_t len; + int greatest = 0, r; + uint32_t msgid; + + /* Count the number of non-identity mappings, and + figure out the value of non-identity mapping + with the highest value. */ + for (i = 0; i < mapping_size; i++) { + if (mapping[i] != (int)i) { + greatest = max(greatest, mapping[i]); + n++; + } + } + /* If the highest source is larger than the + highest targt, that source value will + be highest integer that will be included + the mapping-table. */ + greatest = max(greatest, (int)mapping_size); + /* Calculate an upper bound for the payload. */ + n *= 2 + 2 * (size_t)(greatest > 0x00FF ? 5 : 3); + + /* Ensure that the buffer is large enough for + the message and that `sprintf` will not + write outside it. */ + fail_if (ensure_send_buffer_size(top + n + 2) < 0); + + /* Fetch and increase local message ID. */ + with_mutex (send_mutex, + msgid = message_id; + message_id = message_id == INT32_MAX ? 0 : (message_id + 1); + ); + + /* The offset for the payload should fit all + headers and an empty line. */ + off = top + 1; + /* Write all non-identity mappings to the payload. */ + for (i = 0; i < mapping_size; i++) + if (mapping[i] != (int)i) + sprintf(send_buffer + off, "%i %i\n%zn", i, mapping[i], &len), + off += (size_t)len; + /* Calculate the length of the payload. */ + n = (size_t)(off - (top + 1)); + + /* Write the headers, and the empty line after them. */ + sprintf(send_buffer, + "To: %s\n" + "In response to: %s\n" + "Message ID: %" PRIu32 "\n" + "Length: %zu\n" + "\n%zn", + recv_client_id, recv_message_id, msgid, n, &len); + top = (size_t)len; + /* Move the headers and the empty line so that they are + juxtaposed with the payload. */ + off -= top; + memmove(send_buffer + off, send_buffer, top * sizeof(char)); + + + /* Send the message. */ + + with_mutex (send_mutex, + r = full_send(send_buffer + off, top + n); + if (r) r = errno ? errno : -1; + ); + + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; +fail: + return -1; } @@ -1395,46 +1383,40 @@ static int mapping_query(const char* recv_client_id, const char* recv_message_id * @param recv_keyboard The value of the `Keyboard`-header, `NULL` if omitted * @return Zero on success, -1 on error */ -int handle_keycode_map(const char* recv_client_id, const char* recv_message_id, - const char* recv_action, const char* recv_keyboard) +int +handle_keycode_map(const char *recv_client_id, const char *recv_message_id, + const char *recv_action, const char *recv_keyboard) { - int r; - if ((recv_keyboard != NULL) && !strequals(recv_keyboard, KEYBOARD_ID)) - return 0; - - if (recv_action == NULL) - eprint("received keycode map request but without any action, ignoring."); - else if (strequals(recv_action, "remap")) - { - if (received.payload_size == 0) - return eprint("received keycode remap request without a payload, ignoring."), 0; - - with_mutex (mapping_mutex, - r = remap(received.payload, received.payload_size); - if (r) r = errno ? errno : -1; - ); - fail_if (errno = (r == -1 ? 0 : r), r); - } - else if (strequals(recv_action, "reset")) - { - with_mutex (mapping_mutex, - free(mapping); - mapping_size = 0; - ); - } - else if (strequals(recv_action, "query")) - { - if (strequals(recv_client_id, "0:0")) - return eprint("received information request from an anonymous client, ignoring."), 0; - - fail_if (mapping_query(recv_client_id, recv_message_id)); - } - else - eprint("received keycode map request with invalid action, ignoring."); - - return 0; - fail: - return -1; + int r; + if (recv_keyboard && !strequals(recv_keyboard, KEYBOARD_ID)) + return 0; + + if (!recv_action) { + eprint("received keycode map request but without any action, ignoring."); + } else if (strequals(recv_action, "remap")) { + if (!received.payload_size) + return eprint("received keycode remap request without a payload, ignoring."), 0; + with_mutex (mapping_mutex, + r = remap(received.payload, received.payload_size); + if (r) r = errno ? errno : -1; + ); + fail_if (errno = (r == -1 ? 0 : r), r); + } else if (strequals(recv_action, "reset")) { + with_mutex (mapping_mutex, + free(mapping); + mapping_size = 0; + ); + } else if (strequals(recv_action, "query")) { + if (strequals(recv_client_id, "0:0")) + return eprint("received information request from an anonymous client, ignoring."), 0; + fail_if (mapping_query(recv_client_id, recv_message_id)); + } else { + eprint("received keycode map request with invalid action, ignoring."); + } + + return 0; +fail: + return -1; } @@ -1443,16 +1425,17 @@ int handle_keycode_map(const char* recv_client_id, const char* recv_message_id, * * @param signo The signal */ -void signal_all(int signo) +void +signal_all(int signo) { - pthread_t current_thread = pthread_self(); - - if (pthread_equal(current_thread, master_thread) == 0) - pthread_kill(master_thread, signo); - - if (kbd_thread_started) - if (pthread_equal(current_thread, kbd_thread) == 0) - pthread_kill(kbd_thread, signo); + pthread_t current_thread = pthread_self(); + + if (!pthread_equal(current_thread, master_thread)) + pthread_kill(master_thread, signo); + + if (kbd_thread_started) + if (!pthread_equal(current_thread, kbd_thread)) + pthread_kill(kbd_thread, signo); } @@ -1461,34 +1444,35 @@ void signal_all(int signo) * * @return Zero on success, -1 on error */ -int open_leds(void) +int +open_leds(void) { #ifdef __sparc__ - fail_if ((ledfd = open(SPARC_KBD, O_RDONLY)) < 0); - if (ioctl(ledfd, GET_LED, &saved_leds) < 0) - { - xclose(ledfd); - fail_if (1); - } - return 0; + fail_if ((ledfd = open(SPARC_KBD, O_RDONLY)) < 0); + if (ioctl(ledfd, GET_LED, &saved_leds) < 0) { + xclose(ledfd); + fail_if (1); + } + return 0; #else - fail_if (ioctl(ledfd, GET_LED, &saved_leds)); + fail_if (ioctl(ledfd, GET_LED, &saved_leds)); #endif - return 0; - fail: - return -1; + return 0; +fail: + return -1; } /** * Release access of the keyboard's LED:s */ -void close_leds(void) +void +close_leds(void) { - if (ioctl(ledfd, SET_LED, saved_leds) < 0) - xperror(*argv); + if (ioctl(ledfd, SET_LED, saved_leds) < 0) + xperror(*argv); #ifdef __sparc__ - xclose(ledfd); + xclose(ledfd); #endif } @@ -1498,16 +1482,17 @@ void close_leds(void) * * @return Active LED:s, -1 on error */ -int get_leds(void) +int +get_leds(void) { - int leds; - fail_if (ioctl(ledfd, GET_LED, &leds) < 0); + int leds; + fail_if (ioctl(ledfd, GET_LED, &leds) < 0); #ifdef __sparc__ - leds &= 15; + leds &= 15; #endif - return leds; - fail: - return -1; + return leds; +fail: + return -1; } @@ -1517,12 +1502,13 @@ int get_leds(void) * @param leds Active LED:s * @return Zero on success, -1 on error */ -int set_leds(int leds) +int +set_leds(int leds) { - fail_if (ioctl(ledfd, SET_LED, leds)); - return 0; - fail: - return -1; + fail_if (ioctl(ledfd, SET_LED, leds)); + return 0; +fail: + return -1; } @@ -1531,35 +1517,37 @@ int set_leds(int leds) * * @return Zero on success, -1 on error */ -int open_input(void) +int +open_input(void) { - struct termios stty; - if (tcgetattr(STDIN_FILENO, &saved_stty) < 0) - return -1; - stty = saved_stty; - stty.c_lflag &= (tcflag_t)~(ECHO | ICANON | ISIG); - stty.c_iflag = 0; - fail_if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty) < 0); - /* K_MEDIUMRAW: utilise keyboard drivers, but not layout */ - if ((ioctl(STDIN_FILENO, KDGKBMODE, &saved_kbd_mode) < 0) || - (ioctl(STDIN_FILENO, KDSKBMODE, K_MEDIUMRAW) < 0)) - fail_if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty)); - return 0; - fail: - xperror(*argv); - return -1; + struct termios stty; + if (tcgetattr(STDIN_FILENO, &saved_stty) < 0) + return -1; + stty = saved_stty; + stty.c_lflag &= (tcflag_t)~(ECHO | ICANON | ISIG); + stty.c_iflag = 0; + fail_if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty) < 0); + /* K_MEDIUMRAW: utilise keyboard drivers, but not layout */ + if ((ioctl(STDIN_FILENO, KDGKBMODE, &saved_kbd_mode) < 0) || + (ioctl(STDIN_FILENO, KDSKBMODE, K_MEDIUMRAW) < 0)) + fail_if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty)); + return 0; +fail: + xperror(*argv); + return -1; } /** * Release access of keyboard input */ -void close_input(void) +void +close_input(void) { - if (ioctl(STDIN_FILENO, KDSKBMODE, saved_kbd_mode) < 0) - xperror(*argv); - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty) < 0) - xperror(*argv); + if (ioctl(STDIN_FILENO, KDSKBMODE, saved_kbd_mode) < 0) + xperror(*argv); + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty) < 0) + xperror(*argv); } @@ -1570,60 +1558,61 @@ void close_input(void) * @param trio Whether the scancode has three integers rather than one * @return Zero on success, -1 on error */ -int send_key(int* restrict scancode, int trio) +int +send_key(int *restrict scancode, int trio) { - int r, keycode, released = (scancode[0] & 0x80) == 0x80; - uint32_t msgid; - scancode[0] &= 0x7F; - if (trio) - { - keycode = (scancode[1] &= 0x7F) << 7; - keycode |= (scancode[2] &= 0x7F); - } - else - keycode = scancode[0]; - - with_mutex (mapping_mutex, - if ((size_t)keycode < mapping_size) - keycode = mapping[keycode]; - ); - - with_mutex (send_mutex, - msgid = message_id; - message_id = message_id == INT32_MAX ? 0 : (message_id + 1); - ); - - if (trio) - sprintf(key_send_buffer, - "Command: key-sent\n" - "Scancode: %i %i %i\n" - "Keycode: %i\n" - "Released: %s\n" - "Keyboard: " KEYBOARD_ID "\n" - "Message ID: %" PRIu32 "\n" - "\n", - scancode[0], scancode[1], scancode[2], keycode, - released ? "yes" : "no", msgid); - else - sprintf(key_send_buffer, - "Command: key-sent\n" - "Scancode: %i\n" - "Keycode: %i\n" - "Released: %s\n" - "Keyboard: " KEYBOARD_ID "\n" - "Message ID: %" PRIu32 "\n" - "\n", - scancode[0], keycode, - released ? "yes" : "no", msgid); - - with_mutex (send_mutex, - r = full_send(key_send_buffer, strlen(key_send_buffer)); - if (r) r = errno ? errno : 0; - ); - fail_if (errno = (r == -1 ? 0 : r), r); - return 0; - fail: - return -1; + int r, keycode, released = (scancode[0] & 0x80) == 0x80; + uint32_t msgid; + scancode[0] &= 0x7F; + if (trio) { + keycode = (scancode[1] &= 0x7F) << 7; + keycode |= (scancode[2] &= 0x7F); + } else { + keycode = scancode[0]; + } + + with_mutex (mapping_mutex, + if ((size_t)keycode < mapping_size) + keycode = mapping[keycode]; + ); + + with_mutex (send_mutex, + msgid = message_id; + message_id = message_id == INT32_MAX ? 0 : (message_id + 1); + ); + + if (trio) { + sprintf(key_send_buffer, + "Command: key-sent\n" + "Scancode: %i %i %i\n" + "Keycode: %i\n" + "Released: %s\n" + "Keyboard: " KEYBOARD_ID "\n" + "Message ID: %" PRIu32 "\n" + "\n", + scancode[0], scancode[1], scancode[2], keycode, + released ? "yes" : "no", msgid); + } else { + sprintf(key_send_buffer, + "Command: key-sent\n" + "Scancode: %i\n" + "Keycode: %i\n" + "Released: %s\n" + "Keyboard: " KEYBOARD_ID "\n" + "Message ID: %" PRIu32 "\n" + "\n", + scancode[0], keycode, + released ? "yes" : "no", msgid); + } + + with_mutex (send_mutex, + r = full_send(key_send_buffer, strlen(key_send_buffer)); + if (r) r = errno ? errno : 0; + ); + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; +fail: + return -1; } @@ -1632,75 +1621,67 @@ int send_key(int* restrict scancode, int trio) * * @return Zero on success, -1 on error */ -int fetch_keys(void) +int +fetch_keys(void) { #ifdef DEBUG - int consecutive_escapes = 0; + int consecutive_escapes = 0; #endif - int c; - ssize_t r; - - for (;;) - { - r = read(STDIN_FILENO, &c, sizeof(int)); - if (r <= 0) - { - if (r == 0) - { - raise(SIGTERM); - errno = 0; - } - break; - } - + int c; + ssize_t r; + + for (;;) { + r = read(STDIN_FILENO, &c, sizeof(int)); + if (r <= 0) { + if (!r) { + raise(SIGTERM); + errno = 0; + } + break; + } + #ifdef DEBUG - if ((c & 0x7F) == 1) /* Exit with ESCAPE, ESCAPE, ESCAPE */ - { - if (++consecutive_escapes >= 2 * 3) - { - raise(SIGTERM); - errno = 0; - break; - } - } - else - consecutive_escapes = 0; + if ((c & 0x7F) == 1) { /* Exit with ESCAPE, ESCAPE, ESCAPE */ + if (++consecutive_escapes >= 2 * 3) { + raise(SIGTERM); + errno = 0; + break; + } + } else { + consecutive_escapes = 0; + } #endif - - redo: - scancode_buf[scancode_ptr] = c; - if (scancode_ptr == 0) - { - if ((c & 0x7F) == 0) - scancode_ptr++; - else - send_key(scancode_buf, 0); - } - else if (scancode_ptr == 1) - { - if ((c & 0x80) == 0) - { - scancode_ptr = 0; - goto redo; - } - scancode_ptr++; - } - else - { - scancode_ptr = 0; - if ((c & 0x80) == 0) - { - send_key(scancode_buf + 1, 0); - goto redo; - } - send_key(scancode_buf, 1); + + redo: + scancode_buf[scancode_ptr] = c; + switch (scancode_ptr) { + case 0: + if (!(c & 0x7F)) + scancode_ptr++; + else + send_key(scancode_buf, 0); + break; + case 1: + if (!(c & 0x80)) { + scancode_ptr = 0; + goto redo; + } + scancode_ptr++; + break; + default: + scancode_ptr = 0; + if (!(c & 0x80)) { + send_key(scancode_buf + 1, 0); + goto redo; + } + send_key(scancode_buf, 1); + } } - } - - fail_if (errno); - return 0; - fail: - return -1; + + fail_if (errno); + return 0; +fail: + return -1; } @@ -1712,56 +1693,54 @@ int fetch_keys(void) * @param recv_message_id The message ID of the message the client sent * @return Zero on success, -1 on error */ -int send_errno(int error, const char* recv_client_id, const char* recv_message_id) +int +send_errno(int error, const char *recv_client_id, const char *recv_message_id) { - int r; - with_mutex (send_mutex, - r = send_error(recv_client_id, recv_message_id, "get-keyboard-leds", - 0, error, NULL, &send_buffer, &send_buffer_size, - message_id, socket_fd); - message_id = message_id == INT32_MAX ? 0 : (message_id + 1); - if (r) r = errno ? errno : -1; - ); - fail_if (errno = (r == -1 ? 0 : r), r); - return 0; - fail: - return -1; + int r; + with_mutex (send_mutex, + r = send_error(recv_client_id, recv_message_id, "get-keyboard-leds", + 0, error, NULL, &send_buffer, &send_buffer_size, + message_id, socket_fd); + message_id = message_id == INT32_MAX ? 0 : (message_id + 1); + if (r) r = errno ? errno : -1; + ); + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; +fail: + return -1; } /** * Attempt to shrink `mapping` */ -void shrink_map(void) +void +shrink_map(void) { - size_t i, greatest_mapping = 0; - int* old; - - for (i = mapping_size; i > 0; i--) - if (mapping[i] != (int)i) - { - greatest_mapping = i; - break; - } - - if (greatest_mapping == 0) - { - if (mapping[0] == 0) - { - free(mapping); - mapping_size = 0; + size_t i, greatest_mapping = 0; + int* old; + + for (i = mapping_size; i > 0; i--) { + if (mapping[i] != (int)i) { + greatest_mapping = i; + break; + } } - } - else if (greatest_mapping + 1 < mapping_size) - { - if (old = mapping, xrealloc(mapping, greatest_mapping + 1, int)) - { - mapping = old; - xperror(*argv); + + if (!greatest_mapping) { + if (!*mapping) { + free(mapping); + mapping_size = 0; + } + } else if (greatest_mapping + 1 < mapping_size) { + old = mapping; + if (xrealloc(mapping, greatest_mapping + 1, int)) { + mapping = old; + xperror(*argv); + } else { + mapping_size = greatest_mapping + 1; + } } - else - mapping_size = greatest_mapping + 1; - } } /** @@ -1771,25 +1750,25 @@ void shrink_map(void) * * @param signo The signal that has been received */ -void received_info(int signo) +void +received_info(int signo) { - SIGHANDLER_START; - size_t i; - (void) signo; - iprintf("next message ID: %" PRIu32, message_id); - iprintf("connected: %s", connected ? "yes" : "no"); - iprintf("LED FD: %i", ledfd); - iprintf("saved LED:s: %i", saved_leds); - iprintf("scancode buffer: %i, %i, %i", scancode_buf[0], scancode_buf[1], scancode_buf[2]); - iprintf("scancode buffer pointer: %i", scancode_ptr); - iprintf("saved keyboard mode: %i", saved_kbd_mode); - iprintf("send buffer size: %zu bytes", send_buffer_size); - iprintf("keyboard thread started: %s", kbd_thread_started ? "yes" : "no"); - iprintf("keycode remapping tabel size: %zu", mapping_size); - iprint("keycode remapping tabel:"); - for (i = 0; i < mapping_size; i++) - if ((int)i != mapping[i]) - iprintf(" %zu -> %i", i, mapping[i]); - SIGHANDLER_END; + SIGHANDLER_START; + size_t i; + iprintf("next message ID: %" PRIu32, message_id); + iprintf("connected: %s", connected ? "yes" : "no"); + iprintf("LED FD: %i", ledfd); + iprintf("saved LED:s: %i", saved_leds); + iprintf("scancode buffer: %i, %i, %i", scancode_buf[0], scancode_buf[1], scancode_buf[2]); + iprintf("scancode buffer pointer: %i", scancode_ptr); + iprintf("saved keyboard mode: %i", saved_kbd_mode); + iprintf("send buffer size: %zu bytes", send_buffer_size); + iprintf("keyboard thread started: %s", kbd_thread_started ? "yes" : "no"); + iprintf("keycode remapping tabel size: %zu", mapping_size); + iprint("keycode remapping tabel:"); + for (i = 0; i < mapping_size; i++) + if ((int)i != mapping[i]) + iprintf(" %zu -> %i", i, mapping[i]); + SIGHANDLER_END; + (void) signo; } - |