diff options
Diffstat (limited to '')
-rw-r--r-- | libaxl_receive.c | 621 |
1 files changed, 621 insertions, 0 deletions
diff --git a/libaxl_receive.c b/libaxl_receive.c new file mode 100644 index 0000000..bb4af68 --- /dev/null +++ b/libaxl_receive.c @@ -0,0 +1,621 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +static const char *const event_formats[] = { + /* + * . = 1 unused byte + * , = 2 unused bytes + * _ = 3 unused bytes + * - = 4 unused bytes + * # = 32 uint8_t + * ! = libaxl_bool_t + * 1 = uint8_t + * 2 = uint16_t + * 4 = uint32_t + * z = int8_t + * s = int16_t + * S = int32_t + * ? = special encoding + */ + [LIBAXL_ERROR] = "112421", + [LIBAXL_REPLY] = "?", + [LIBAXL_EVENT_KEY_PRESS] = "1124444ssss2!", + [LIBAXL_EVENT_KEY_RELEASE] = "1124444ssss2!", + [LIBAXL_EVENT_BUTTON_PRESS] = "1124444ssss2!", + [LIBAXL_EVENT_BUTTON_RELEASE] = "1124444ssss2!", + [LIBAXL_EVENT_MOTION_NOTIFY] = "1124444ssss2!", + [LIBAXL_EVENT_ENTER_NOTIFY] = "1124444ssss211", + [LIBAXL_EVENT_LEAVE_NOTIFY] = "1124444ssss211", + [LIBAXL_EVENT_FOCUS_IN] = "112411", + [LIBAXL_EVENT_FOCUS_OUT] = "112411", + [LIBAXL_EVENT_KEYMAP_NOTIFY] = "#", + [LIBAXL_EVENT_EXPOSE] = "1.2422222", + [LIBAXL_EVENT_GRAPHICS_EXPOSURE] = "1.242222221", + [LIBAXL_EVENT_NO_EXPOSURE] = "1.242", + [LIBAXL_EVENT_VISIBILITY_NOTIFY] = "1.241", + [LIBAXL_EVENT_CREATE_NOTIFY] = "1.244sssss!", + [LIBAXL_EVENT_DESTROY_NOTIFY] = "1.244", + [LIBAXL_EVENT_UNMAP_NOTIFY] = "1.244!", + [LIBAXL_EVENT_MAP_NOTIFY] = "1.244!", + [LIBAXL_EVENT_MAP_REQUEST] = "1.244", + [LIBAXL_EVENT_REPARENT_NOTIFY] = "1.2444ss!", + [LIBAXL_EVENT_CONFIGURE_NOTIFY] = "1.2444ss222!", + [LIBAXL_EVENT_CONFIGURE_REQUEST] = "112444ss2222", + [LIBAXL_EVENT_GRAVITY_NOTIFY] = "1.244ss", + [LIBAXL_EVENT_RESIZE_REQUEST] = "1.2422", + [LIBAXL_EVENT_CIRCULATE_NOTIFY] = "1.244-1", + [LIBAXL_EVENT_CIRCULATE_REQUEST] = "1.244-1", + [LIBAXL_EVENT_PROPERTY_NOTIFY] = "1.2441", + [LIBAXL_EVENT_SELECTION_CLEAR] = "1.2444", + [LIBAXL_EVENT_SELECTION_REQUEST] = "1.2444444", + [LIBAXL_EVENT_SELECTION_NOTIFY] = "1.244444", + [LIBAXL_EVENT_COLORMAP_NOTIFY] = "1.244!1", + [LIBAXL_EVENT_CLIENT_MESSAGE] = "11244", + [LIBAXL_EVENT_MAPPING_NOTIFY] = "1.2111" +}; + +static const char *const reply_formats[] = { + /* + * = = 8 unused bytes + * $ = previous marked length, in units + * % = previous marked format, in bits + * @ = non-encoded size_t length marked, align output to (size_t) + * u = STRING8, align output to (void *) and enter + * U = STRING16, align output to (void *) and enter + * d = data, uses %, align output to (void *) and enter + * * = following are repeated, align output to (void *) and enter + * & = * but requires allocation + * p = padding + */ + [0] = NULL, + [LIBAXL_REQUEST_CREATE_WINDOW] = NULL, + [LIBAXL_REQUEST_CHANGE_WINDOW_ATTRIBUTES] = NULL, + [LIBAXL_REQUEST_GET_WINDOW_ATTRIBUTES] = "1124421144!!1!4442", + [LIBAXL_REQUEST_DESTROY_WINDOW] = NULL, + [LIBAXL_REQUEST_DESTROY_SUBWINDOWS] = NULL, + [LIBAXL_REQUEST_CHANGE_SAVE_SET] = NULL, + [LIBAXL_REQUEST_REPARENT_WINDOW] = NULL, + [LIBAXL_REQUEST_MAP_WINDOW] = NULL, + [LIBAXL_REQUEST_MAP_SUBWINDOWS] = NULL, + [LIBAXL_REQUEST_UNMAP_WINDOW] = NULL, + [LIBAXL_REQUEST_UNMAP_SUBWINDOWS] = NULL, + [LIBAXL_REQUEST_CONFIGURE_WINDOW] = NULL, + [LIBAXL_REQUEST_CIRCULATE_WINDOW] = NULL, + [LIBAXL_REQUEST_GET_GEOMETRY] = "1244ss222", + [LIBAXL_REQUEST_QUERY_TREE] = "1.24442$=-,*4", + [LIBAXL_REQUEST_INTERN_ATOM] = "1.244", + [LIBAXL_REQUEST_GET_ATOM_NAME] = "1.242$==-,u", + [LIBAXL_REQUEST_CHANGE_PROPERTY] = NULL, + [LIBAXL_REQUEST_DELETE_PROPERTY] = NULL, + [LIBAXL_REQUEST_GET_PROPERTY] = "11%24444$=-d", + [LIBAXL_REQUEST_LIST_PROPERTIES] = "1.242$==-,*4", + [LIBAXL_REQUEST_SET_SELECTION_OWNER] = NULL, + [LIBAXL_REQUEST_GET_SELECTION_OWNER] = "1.244", + [LIBAXL_REQUEST_CONVERT_SELECTION] = NULL, + [LIBAXL_REQUEST_SEND_EVENT] = NULL, + [LIBAXL_REQUEST_GRAB_POINTER] = "1124", + [LIBAXL_REQUEST_UNGRAB_POINTER] = NULL, + [LIBAXL_REQUEST_GRAB_BUTTON] = NULL, + [LIBAXL_REQUEST_UNGRAB_BUTTON] = NULL, + [LIBAXL_REQUEST_CHANGE_ACTIVE_POINTER_GRAB] = NULL, + [LIBAXL_REQUEST_GRAB_KEYBOARD] = "1124", + [LIBAXL_REQUEST_UNGRAB_KEYBOARD] = NULL, + [LIBAXL_REQUEST_GRAB_KEY] = NULL, + [LIBAXL_REQUEST_UNGRAB_KEY] = NULL, + [LIBAXL_REQUEST_ALLOW_EVENTS] = NULL, + [LIBAXL_REQUEST_GRAB_SERVER] = NULL, + [LIBAXL_REQUEST_UNGRAB_SERVER] = NULL, + [LIBAXL_REQUEST_QUERY_POINTER] = ".!2444ssss2", + [LIBAXL_REQUEST_GET_MOTION_EVENTS] = "1!244$==-*4ss", + [LIBAXL_REQUEST_TRANSLATE_COORDINATES] = "1!244ss", + [LIBAXL_REQUEST_WARP_POINTER] = NULL, + [LIBAXL_REQUEST_SET_INPUT_FOCUS] = "11244", + [LIBAXL_REQUEST_GET_INPUT_FOCUS] = NULL, + [LIBAXL_REQUEST_QUERY_KEYMAP] = "1.24#", + [LIBAXL_REQUEST_OPEN_FONT] = NULL, + [LIBAXL_REQUEST_CLOSE_FONT] = NULL, + [LIBAXL_REQUEST_QUERY_FONT] = "1.24sssss2-sssss2-2222$111!ss4$*44*sssss2", + [LIBAXL_REQUEST_QUERY_TEXT_EXTENTS] = "1124ssssSSS", + [LIBAXL_REQUEST_LIST_FONTS] = "1.242$==-,&1$u", + [LIBAXL_REQUEST_LIST_FONTS_WITH_INFO] = "11$24?sssss2-sssss2-2222$?111!ss4*44u", + [LIBAXL_REQUEST_SET_FONT_PATH] = NULL, + [LIBAXL_REQUEST_GET_FONT_PATH] = "1.242$==-,&1$u", + [LIBAXL_REQUEST_CREATE_PIXMAP] = NULL, + [LIBAXL_REQUEST_FREE_PIXMAP] = NULL, + [LIBAXL_REQUEST_CREATE_GC] = NULL, + [LIBAXL_REQUEST_CHANGE_GC] = NULL, + [LIBAXL_REQUEST_COPY_GC] = NULL, + [LIBAXL_REQUEST_SET_DASHES] = NULL, + [LIBAXL_REQUEST_SET_CLIP_RECTANGLES] = NULL, + [LIBAXL_REQUEST_FREE_GC] = NULL, + [LIBAXL_REQUEST_CLEAR_AREA] = NULL, + [LIBAXL_REQUEST_COPY_AREA] = NULL, + [LIBAXL_REQUEST_COPY_PLANE] = NULL, + [LIBAXL_REQUEST_POLY_POINT] = NULL, + [LIBAXL_REQUEST_POLY_LINE] = NULL, + [LIBAXL_REQUEST_POLY_SEGMENT] = NULL, + [LIBAXL_REQUEST_POLY_RECTANGLE] = NULL, + [LIBAXL_REQUEST_POLY_ARC] = NULL, + [LIBAXL_REQUEST_FILL_POLY] = NULL, + [LIBAXL_REQUEST_POLY_FILL_RECTANGLE] = NULL, + [LIBAXL_REQUEST_POLY_FILL_ARC] = NULL, + [LIBAXL_REQUEST_PUT_IMAGE] = NULL, + [LIBAXL_REQUEST_GET_IMAGE] = "11244==-@u", /* "u" is actually "*1" */ + [LIBAXL_REQUEST_POLY_TEXT8] = NULL, + [LIBAXL_REQUEST_POLY_TEXT16] = NULL, + [LIBAXL_REQUEST_IMAGE_TEXT8] = NULL, + [LIBAXL_REQUEST_IMAGE_TEXT16] = NULL, + [LIBAXL_REQUEST_CREATE_COLORMAP] = NULL, + [LIBAXL_REQUEST_FREE_COLORMAP] = NULL, + [LIBAXL_REQUEST_COPY_COLORMAP_AND_FREE] = NULL, + [LIBAXL_REQUEST_INSTALL_COLORMAP] = NULL, + [LIBAXL_REQUEST_UNINSTALL_COLORMAP] = NULL, + [LIBAXL_REQUEST_LIST_INSTALLED_COLORMAPS] = "1.242$==-,*4", + [LIBAXL_REQUEST_ALLOC_COLOR] = "1.24222,4", + [LIBAXL_REQUEST_ALLOC_NAMED_COLOR] = "1.244222222", + [LIBAXL_REQUEST_ALLOC_COLOR_CELLS] = "1.242$2$==-*4*4", + [LIBAXL_REQUEST_ALLOC_COLOR_PLANES] = "1.242$,444=*4", + [LIBAXL_REQUEST_FREE_COLORS] = NULL, + [LIBAXL_REQUEST_STORE_COLORS] = NULL, + [LIBAXL_REQUEST_STORE_NAMED_COLOR] = NULL, + [LIBAXL_REQUEST_QUERY_COLORS] = "1.242$==-,*222,", + [LIBAXL_REQUEST_LOOKUP_COLOR] = "1.24222222", + [LIBAXL_REQUEST_CREATE_CURSOR] = NULL, + [LIBAXL_REQUEST_CREATE_GLYPH_CURSOR] = NULL, + [LIBAXL_REQUEST_FREE_CURSOR] = NULL, + [LIBAXL_REQUEST_RECOLOR_CURSOR] = NULL, + [LIBAXL_REQUEST_QUERY_BEST_SIZE] = "1.2422", + [LIBAXL_REQUEST_QUERY_EXTENSION] = "1.24!1111", + [LIBAXL_REQUEST_LIST_EXTENSIONS] = "11$24===&1$u", + [LIBAXL_REQUEST_CHANGE_KEYBOARD_MAPPING] = NULL, + [LIBAXL_REQUEST_GET_KEYBOARD_MAPPING] = "1124$===*4", + [LIBAXL_REQUEST_CHANGE_KEYBOARD_CONTROL] = NULL, + [LIBAXL_REQUEST_GET_KEYBOARD_CONTROL] = "112441122,#", + [LIBAXL_REQUEST_BELL] = NULL, + [LIBAXL_REQUEST_CHANGE_POINTER_CONTROL] = NULL, + [LIBAXL_REQUEST_GET_POINTER_CONTROL] = "1.24222", + [LIBAXL_REQUEST_SET_SCREEN_SAVER] = NULL, + [LIBAXL_REQUEST_GET_SCREEN_SAVER] = "1.242211", + [LIBAXL_REQUEST_CHANGE_HOSTS] = NULL, + [LIBAXL_REQUEST_LIST_HOSTS] = "1124$2==-,&1.2$up", /* "u" is actually "*1" */ + [LIBAXL_REQUEST_SET_ACCESS_CONTROL] = NULL, + [LIBAXL_REQUEST_SET_CLOSE_DOWN_MODE] = NULL, + [LIBAXL_REQUEST_KILL_CLIENT] = NULL, + [LIBAXL_REQUEST_ROTATE_PROPERTIES] = NULL, + [LIBAXL_REQUEST_FORCE_SCREEN_SAVER] = NULL, + [LIBAXL_REQUEST_SET_POINTER_MAPPING] = "1124", + [LIBAXL_REQUEST_GET_POINTER_MAPPING] = "11$24===*1", + [LIBAXL_REQUEST_SET_MODIFIER_MAPPING] = "1124", + [LIBAXL_REQUEST_GET_MODIFIER_MAPPING] = "11$24===*11", + [LIBAXL_REQUEST_NO_OPERATION] = NULL +}; + +/* TODO make it possible to prefetch pending messages */ +int +libaxl_receive(LIBAXL_CONTEXT *restrict ctx, union libaxl_input *restrict msgp, int flags) +{ + LIBAXL_CONNECTION *conn = ctx->conn; + const char *fmt; + char *restrict msg = (char *)msgp; + char *restrict inbuf, *data; + size_t format = 1, counts[] = {0, 0, 0}, count; + ssize_t r; + uint64_t n, u64; + uint8_t code; + size_t t, i, j, o, ic = 0, oc = 0; + int qc = 0; +#ifdef MSG_TRUNC + int flag_trunc; +#endif + +#ifdef MSG_TRUNC + flags ^= flag_trunc = flags & MSG_TRUNC; +#endif + + WLOCK_CONNECTION_RECV(conn); + + inbuf = conn->in_buf; + n = 32; + + if (conn->in_buf_size < n) { + inbuf = liberror_realloc(inbuf, n); + if (!inbuf) { + WUNLOCK_CONNECTION_RECV(conn); + return LIBAXL_ERROR_SYSTEM; + } + conn->in_buf = inbuf; + conn->in_buf_size = n; + } + + while (conn->in_progress < n) { + r = recv(conn->fd, &inbuf[conn->in_progress], n - conn->in_progress, flags); + if (r <= 0) { + WUNLOCK_CONNECTION_RECV(conn); + liberror_save_backtrace(NULL); + if (!r) { + liberror_set_error("The connection to the display server has been closed", + "libaxl_receive", "libaxl", LIBAXL_ERROR_CONNECTION_CLOSED); + return LIBAXL_ERROR_CONNECTION_CLOSED; + } + liberror_recv_failed(conn->fd, &inbuf[conn->in_progress], n - conn->in_progress, flags, "<display server>"); + return LIBAXL_ERROR_SYSTEM; + } + conn->in_progress += (size_t)r; + } + + code = *(uint8_t *)inbuf; + + if (code == LIBAXL_REPLY) { + n = (uint64_t)ntohl(*(uint32_t *)&inbuf[4]); + n = 4 * n + 32; + if (n > SIZE_MAX) { + WUNLOCK_CONNECTION_RECV(conn); + liberror_save_backtrace(NULL); + liberror_set_error("Received message is too large to allocate", + "libaxl_receive", "libaxl", LIBAXL_ERROR_SYSTEM); + errno = ENOMEM; + return LIBAXL_ERROR_SYSTEM; + } + if (conn->in_buf_size < n) { + inbuf = liberror_realloc(inbuf, n); + if (!inbuf) { + WUNLOCK_CONNECTION_RECV(conn); + return LIBAXL_ERROR_SYSTEM; + } + conn->in_buf = inbuf; + conn->in_buf_size = n; + } + while (conn->in_progress < n) { + r = recv(conn->fd, &inbuf[conn->in_progress], n - conn->in_progress, flags); + if (r <= 0) { + WUNLOCK_CONNECTION_RECV(conn); + liberror_save_backtrace(NULL); + if (!r) { + liberror_set_error("The connection to the display server has been closed", + "libaxl_receive", "libaxl", LIBAXL_ERROR_CONNECTION_CLOSED); + return LIBAXL_ERROR_CONNECTION_CLOSED; + } + liberror_recv_failed(conn->fd, &inbuf[conn->in_progress], n - conn->in_progress, + flags, "<display server>"); + return LIBAXL_ERROR_SYSTEM; + } + conn->in_progress += (size_t)r; + } + } + + conn->in_progress = 0; + +#ifdef MSG_TRUNC + if (flag_trunc) { + WUNLOCK_CONNECTION_RECV(conn); + return 0; + } +#endif + + t = conn->in_buf_size; + conn->in_buf_size = ctx->in_buf_size; + ctx->in_buf_size = t; + + conn->in_buf = ctx->in_buf; + ctx->in_buf = inbuf; + + WUNLOCK_CONNECTION_RECV(conn); + + if (code > sizeof(event_formats) / sizeof(*event_formats) || + !(fmt = event_formats[code])) { + liberror_save_backtrace(NULL); + liberror_set_error("Received message's code is invalid", "libaxl_receive", "libaxl", LIBAXL_ERROR_SYSTEM); + errno = EBADMSG; + return LIBAXL_ERROR_SYSTEM; + } + + for (i = 0; i < n; fmt++) { + switch (*fmt) { + case '\0': + goto end_of_fmt; + + case '.': + i += 1; + break; + + case ',': + i += 2; + break; + + case '_': + i += 3; + break; + + case '-': + i += 4; + break; + + case '#': + *(uint64_t *)&msg[i + 0] = *(uint64_t *)&inbuf[i + 0]; + *(uint64_t *)&msg[i + 8] = *(uint64_t *)&inbuf[i + 8]; + *(uint64_t *)&msg[i + 16] = *(uint64_t *)&inbuf[i + 16]; + *(uint64_t *)&msg[i + 24] = *(uint64_t *)&inbuf[i + 24]; + i += 32; + break; + + case '!': + case '1': + *(uint8_t *)&msg[i] = *(uint8_t *)&inbuf[i]; + i += 1; + break; + + case '2': + if (i + 2 <= n) { + liberror_save_backtrace(NULL); + goto short_msg; + } + *(uint16_t *)&msg[i] = ntohs(*(uint16_t *)&inbuf[i]); + i += 2; + break; + + case '4': + if (i + 4 <= n) { + liberror_save_backtrace(NULL); + goto short_msg; + } + *(uint32_t *)&msg[i] = ntohl(*(uint32_t *)&inbuf[i]); + i += 4; + break; + + case 'z': + *(uint8_t *)&msg[i] = *(uint8_t *)&inbuf[i]; + UNTWOS_COMPLEMENT8(&msg[i]); + i += 1; + break; + + case 's': + if (i + 2 <= n) { + liberror_save_backtrace(NULL); + goto short_msg; + } + *(uint16_t *)&msg[i] = ntohs(*(uint16_t *)&inbuf[i]); + UNTWOS_COMPLEMENT16(&msg[i]); + i += 2; + break; + + case 'S': + if (i + 4 <= n) { + liberror_save_backtrace(NULL); + goto short_msg; + } + *(uint32_t *)&msg[i] = ntohl(*(uint32_t *)&inbuf[i]); + UNTWOS_COMPLEMENT32(&msg[i]); + i += 4; + break; + + case '?': + /* We know it is LIBAXL_REPLY message */ + goto received_reply; + break; + + default: + abort(); + } + } + + if (*fmt) { + liberror_save_backtrace(NULL); + goto short_msg; + } + +end_of_fmt: + return 0; + +received_reply: + code = conn->request_map[ntohs(*(uint16_t *)&inbuf[2])]; /* read-lock here is pointless */ + fmt = reply_formats[code]; + if (!fmt) { + liberror_set_error("Received reply message with unrecognised opcode", + "libaxl_receive", "libaxl", LIBAXL_ERROR_INVALID_REPLY_OPCODE); + errno = EBADMSG; + return LIBAXL_ERROR_INVALID_REPLY_OPCODE; + } + + for (i = o = 0; i < n; fmt++) { + switch (*fmt) { + case '\0': + goto end_of_fmt; + + case '.': + i += 1; + o += 1; + break; + + case ',': + i += 2; + o += 2; + break; + + case '_': + i += 3; + o += 3; + break; + + case '-': + i += 4; + o += 4; + break; + + case '=': + i += 8; + o += 8; + break; + + case '#': + *(uint64_t *)&msg[o + 0] = *(uint64_t *)&inbuf[i + 0]; + *(uint64_t *)&msg[o + 8] = *(uint64_t *)&inbuf[i + 8]; + *(uint64_t *)&msg[o + 16] = *(uint64_t *)&inbuf[i + 16]; + *(uint64_t *)&msg[o + 24] = *(uint64_t *)&inbuf[i + 24]; + i += 32; + o += 32; + break; + + case '!': + case '1': + *(uint8_t *)&msg[o++] = *(uint8_t *)&inbuf[i++]; + break; + + case '2': + if (i + 2 <= n) { + liberror_save_backtrace(NULL); + goto short_msg; + } + *(uint16_t *)&msg[o] = ntohs(*(uint16_t *)&inbuf[i]); + i += 2; + o += 2; + break; + + case '4': + if (i + 4 <= n) { + liberror_save_backtrace(NULL); + goto short_msg; + } + *(uint32_t *)&msg[o] = ntohl(*(uint32_t *)&inbuf[i]); + i += 4; + o += 4; + break; + + case 'z': + *(uint8_t *)&msg[o] = *(uint8_t *)&inbuf[i]; + UNTWOS_COMPLEMENT8(&msg[o]); + i += 1; + o += 1; + break; + + case 's': + if (i + 2 <= n) { + liberror_save_backtrace(NULL); + goto short_msg; + } + *(uint16_t *)&msg[o] = ntohs(*(uint16_t *)&inbuf[i]); + UNTWOS_COMPLEMENT16(&msg[o]); + i += 2; + o += 2; + break; + + case 'S': + if (i + 4 <= n) { + liberror_save_backtrace(NULL); + goto short_msg; + } + *(uint32_t *)&msg[o] = ntohl(*(uint32_t *)&inbuf[i]); + UNTWOS_COMPLEMENT32(&msg[o]); + i += 4; + o += 4; + break; + + case '%': + if (fmt[-1] == '1') + format = (size_t)*(uint8_t *)&msg[i - 1]; + else if (fmt[-1] == '2') + format = (size_t)*(uint16_t *)&msg[i - 2]; + else + format = (size_t)*(uint32_t *)&msg[i - 4]; + break; + + case '@': + ALIGN(&o, size_t); + u64 = 4 * (uint64_t)*(uint32_t *)&msg[4]; + if (u64 > SIZE_MAX) { + liberror_save_backtrace(NULL); + goto corrupt_reply; + } + *(size_t *)&msg[o] = counts[ic++] = (size_t)u64; + o += sizeof(size_t); + break; + + case '$': + if (fmt[-1] == '2') + counts[ic++] = (size_t)*(uint16_t *)&msg[i - 2]; + else if (fmt[-1] == '1') + counts[ic++] = (size_t)*(uint8_t *)&msg[i - 1]; + else + counts[ic++] = (size_t)*(uint32_t *)&msg[i - 4]; + break; + + case 'p': + ALIGN(&i, uint32_t); + break; + + case 'u': + format = 8; + goto case_d; + + case 'U': + format = 16; + goto case_d; + + case 'd': + case_d: + ALIGN(&o, void *); + *(void **)&msg[o] = data = &inbuf[i]; + count = counts[oc++]; + count *= format / 8; + if (format == 16) { + for (j = 0; j < count; j += 2) + *(uint16_t *)&data[j] = ntohs(*(uint16_t *)&data[j]); + } else if (format == 32) { + for (j = 0; j < count; j += 2) + *(uint32_t *)&data[j] = ntohl(*(uint32_t *)&data[j]); + } else if (format != 8 && format != 0) { + liberror_save_backtrace(NULL); + goto corrupt_reply; + } + o += sizeof(void *); + i += count; + break; + + case '*': + ALIGN(&o, void *); + *(void **)&msg[o] = data = &inbuf[i]; + count = counts[oc++]; + /* TODO */ + break; + + case '&': /* TODO */ + /* + LIBAXL_REQUEST_LIST_FONTS + LIBAXL_REQUEST_GET_FONT_PATH + LIBAXL_REQUEST_LIST_EXTENSIONS + LIBAXL_REQUEST_LIST_HOSTS + */ + break; + + case '?': + /* We know that code == LIBAXL_REQUEST_LIST_FONTS_WITH_INFO */ + if (!qc++) { + if (!counts[0]) + goto done; + } else { + count = counts[0]; + counts[0] = counts[1]; + counts[1] = count; + } + break; + + default: + abort(); + } + } + + if (*fmt) { + liberror_save_backtrace(NULL); + short_msg: + liberror_set_error("Received message's is shorter than expected", "libaxl_receive", "libaxl", LIBAXL_ERROR_SYSTEM); + errno = EBADMSG; + return LIBAXL_ERROR_SYSTEM; + } + +done: + return 0; + +corrupt_reply: + liberror_set_error("Corrupt reply message received", "libaxl_receive", "libaxl", LIBAXL_ERROR_SYSTEM); + errno = EBADMSG; + return LIBAXL_ERROR_SYSTEM; +} |