aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common.h1
-rw-r--r--libaxl/consts.h30
-rw-r--r--libaxl/display-info.h2
-rw-r--r--libaxl/replies.h2
-rw-r--r--libaxl/requests.h10
-rw-r--r--libaxl/types.h2
-rw-r--r--libaxl_connect.c31
-rw-r--r--libaxl_connect_without_handshake.c44
-rw-r--r--libaxl_receive.c114
9 files changed, 179 insertions, 57 deletions
diff --git a/common.h b/common.h
index 5dae5a1..e0330cb 100644
--- a/common.h
+++ b/common.h
@@ -10,6 +10,7 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
+#include <pwd.h>
#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libaxl/consts.h b/libaxl/consts.h
index a378c73..8629651 100644
--- a/libaxl/consts.h
+++ b/libaxl/consts.h
@@ -274,21 +274,21 @@
#define LIBAXL_PARENT 2
/* window event mask */
-#define LIBAXL_EVENT_MASK_KEY_PRESS UINT32_C(0x00000001)
-#define LIBAXL_EVENT_MASK_KEY_RELEASE UINT32_C(0x00000002)
-#define LIBAXL_EVENT_MASK_BUTTON_PRESS UINT32_C(0x00000004)
-#define LIBAXL_EVENT_MASK_BUTTON_RELEASE UINT32_C(0x00000008)
-#define LIBAXL_EVENT_MASK_ENTER_WINDOW UINT32_C(0x00000010)
-#define LIBAXL_EVENT_MASK_LEAVE_WINDOW UINT32_C(0x00000020)
-#define LIBAXL_EVENT_MASK_POINTER_MOTION UINT32_C(0x00000040)
-#define LIBAXL_EVENT_MASK_POINTER_MOTION_HINT UINT32_C(0x00000080)
-#define LIBAXL_EVENT_MASK_BUTTON_1_MOTION UINT32_C(0x00000100)
-#define LIBAXL_EVENT_MASK_BUTTON_2_MOTION UINT32_C(0x00000200)
-#define LIBAXL_EVENT_MASK_BUTTON_3_MOTION UINT32_C(0x00000400)
-#define LIBAXL_EVENT_MASK_BUTTON_4_MOTION UINT32_C(0x00000800)
-#define LIBAXL_EVENT_MASK_BUTTON_5_MOTION UINT32_C(0x00001000)
-#define LIBAXL_EVENT_MASK_BUTTON_MOTION UINT32_C(0x00002000)
-#define LIBAXL_EVENT_MASK_KEYMAP_STATE UINT32_C(0x00004000)
+#define LIBAXL_EVENT_MASK_KEY_PRESS UINT32_C(0x00000001) /* in SETofDEVICEEVENT */
+#define LIBAXL_EVENT_MASK_KEY_RELEASE UINT32_C(0x00000002) /* in SETofDEVICEEVENT */
+#define LIBAXL_EVENT_MASK_BUTTON_PRESS UINT32_C(0x00000004) /* in SETofDEVICEEVENT and SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_BUTTON_RELEASE UINT32_C(0x00000008) /* in SETofDEVICEEVENT and SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_ENTER_WINDOW UINT32_C(0x00000010) /* in SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_LEAVE_WINDOW UINT32_C(0x00000020) /* in SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_POINTER_MOTION UINT32_C(0x00000040) /* in SETofDEVICEEVENT and SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_POINTER_MOTION_HINT UINT32_C(0x00000080) /* in SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_BUTTON_1_MOTION UINT32_C(0x00000100) /* in SETofDEVICEEVENT and SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_BUTTON_2_MOTION UINT32_C(0x00000200) /* in SETofDEVICEEVENT and SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_BUTTON_3_MOTION UINT32_C(0x00000400) /* in SETofDEVICEEVENT and SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_BUTTON_4_MOTION UINT32_C(0x00000800) /* in SETofDEVICEEVENT and SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_BUTTON_5_MOTION UINT32_C(0x00001000) /* in SETofDEVICEEVENT and SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_BUTTON_MOTION UINT32_C(0x00002000) /* in SETofDEVICEEVENT and SETofPOINTEREVENT */
+#define LIBAXL_EVENT_MASK_KEYMAP_STATE UINT32_C(0x00004000) /* in SETofPOINTEREVENT */
#define LIBAXL_EVENT_MASK_EXPOSURE UINT32_C(0x00008000)
#define LIBAXL_EVENT_MASK_VISIBILITY_CHANGE UINT32_C(0x00010000)
#define LIBAXL_EVENT_MASK_STRUCTURE_NOTIFY UINT32_C(0x00020000)
diff --git a/libaxl/display-info.h b/libaxl/display-info.h
index f01ade1..75285ac 100644
--- a/libaxl/display-info.h
+++ b/libaxl/display-info.h
@@ -113,7 +113,7 @@ struct libaxl_screen {
*/
uint32_t black_pixel;
- uint32_t current_input_masks; /* TODO SETofEVENTS */
+ uint32_t current_input_masks; /* See "window event mask" in "consts.h" */ /* TODO doc */
/**
* The width, in pixels, of the root window;
diff --git a/libaxl/replies.h b/libaxl/replies.h
index c8de403..8c48047 100644
--- a/libaxl/replies.h
+++ b/libaxl/replies.h
@@ -24,7 +24,7 @@ struct libaxl_reply_get_window_attributes {
libaxl_colormap_t colormap; /* Can be LIBAXL_NONE */
uint32_t all_event_masks; /* See "window event mask" in "consts.h" */
uint32_t your_event_mask; /* See "window event mask" in "consts.h" */
- uint16_t do_not_propagate_mask; /* TODO SETofDEVICEEVENT */
+ uint16_t do_not_propagate_mask; /* See SETofDEVICEEVENT in "consts.h" */
uint16_t __pad;
};
diff --git a/libaxl/requests.h b/libaxl/requests.h
index dffb904..27ba705 100644
--- a/libaxl/requests.h
+++ b/libaxl/requests.h
@@ -48,7 +48,7 @@ struct libaxl_request_create_window {
libaxl_bool_t save_under;
uint16_t __omitted2;
uint32_t event_mask; /* See "window event mask" in "consts.h" */
- uint32_t do_not_propagate_mask; /* TODO SETofDEVICEEVENT */
+ uint32_t do_not_propagate_mask; /* See SETofDEVICEEVENT in "consts.h" */
libaxl_colormap_t colormap; /* Can be LIBAXL_COPY_FROM_PARENT */
libaxl_cursor_t cursor; /* Can be LIBAXL_NONE */
};
@@ -89,7 +89,7 @@ struct libaxl_request_change_window_attributes {
libaxl_bool_t save_under;
uint16_t __omitted2;
uint32_t event_mask; /* See "window event mask" in "consts.h" */
- uint32_t do_not_propagate_mask; /* TODO SETofDEVICEEVENT */
+ uint32_t do_not_propagate_mask; /* See SETofDEVICEEVENT in "consts.h" */
libaxl_colormap_t colormap; /* Can be LIBAXL_COPY_FROM_PARENT */
libaxl_cursor_t cursor; /* Can be LIBAXL_NONE */
};
@@ -330,7 +330,7 @@ struct libaxl_request_grab_pointer {
libaxl_bool_t owner_events;
uint16_t _request_length; /* = 6 */
libaxl_window_t grab_window;
- uint16_t event_mask; /* TODO SETofPOINTEREVENT */
+ uint16_t event_mask; /* See SETofPOINTEREVENT in "consts.h" */
uint8_t pointer_mode; /* LIBAXL_{SYNCHRONOUS or ASYNCHRONOUS} */
uint8_t keyboard_mode; /* LIBAXL_{SYNCHRONOUS or ASYNCHRONOUS} */
libaxl_window_t confine_to; /* Can be LIBAXL_NONE */
@@ -352,7 +352,7 @@ struct libaxl_request_grab_button {
uint8_t __pad1;
uint16_t _request_length; /* = 6 */
libaxl_window_t grab_window;
- uint16_t event_mask; /* TODO SETofPOINTEREVENT */
+ uint16_t event_mask; /* See SETofPOINTEREVENT in "consts.h" */
uint8_t pointer_mode; /* LIBAXL_{SYNCHRONOUS or ASYNCHRONOUS} */
uint8_t keyboard_mode; /* LIBAXL_{SYNCHRONOUS or ASYNCHRONOUS} */
libaxl_window_t confine_to; /* Can be LIBAXL_NONE */
@@ -379,7 +379,7 @@ struct libaxl_request_change_active_pointer_grab {
uint16_t _request_length; /* = 4 */
libaxl_cursor_t cursor; /* Can be LIBAXL_NONE */
libaxl_timestamp_t time; /* Can be LIBAXL_CURRENT_TIME */
- uint16_t event_mask; /* TODO SETofPOINTEREVENT */
+ uint16_t event_mask; /* See SETofPOINTEREVENT in "consts.h" */
uint16_t __pad2;
};
diff --git a/libaxl/types.h b/libaxl/types.h
index f30c434..ad44576 100644
--- a/libaxl/types.h
+++ b/libaxl/types.h
@@ -105,7 +105,7 @@ struct libaxl_timecoord {
struct libaxl_fontprop {
libaxl_atom_t name;
- uint32_t value; /* <32-bits> */
+ uint32_t value; /* <32 bits> */
};
struct libaxl_charinfo {
diff --git a/libaxl_connect.c b/libaxl_connect.c
index ee4edd8..529295d 100644
--- a/libaxl_connect.c
+++ b/libaxl_connect.c
@@ -13,11 +13,36 @@ static char *
path_in_home(const char *filename)
{
const char *home;
- char *ret;
+ struct passwd *pwd, pwd_buf;
+ size_t buf_size;
+ char *buf, *ret;
+ int r;
home = getenv("HOME");
- if (!home || !*home) { /* TODO */
- abort();
+ if (!home || !*home) {
+ buf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+ buf_size = buf_size == -1 ? 16384 : buf_size;
+ buf = alloca(buf_size);
+ r = getpwuid_r(getuid(), &pwd_buf, buf, buf_size, &pwd);
+ if (!pwd) {
+ liberror_save_backtrace(NULL);
+ r = (r == ENOENT || r == ESRCH || r == EBADF || r == EPERM || r == EIO /* glibc bug */) ? 0 : r;
+ if (r) {
+ liberror_set_error_errno(strerror(r), "getpwuid_r", r);
+ } else {
+ liberror_set_error_errno("User does not exist", "getpwuid_r", "libaxl",
+ LIBAXL_ERROR_USER_DOES_NOT_EXIST);
+ }
+ return NULL;
+ } else {
+ home = pwd->pw_dir;
+ if (!home || !*home) {
+ liberror_save_backtrace(NULL);
+ liberror_set_error_errno("User does not have a home", "libaxl_connect", "libaxl",
+ LIBAXL_ERROR_USER_DOES_NOT_HAVE_A_HOME);
+ return NULL;
+ }
+ }
}
ret = liberror_malloc(strlen(home) + strlen(filename) + 2);
diff --git a/libaxl_connect_without_handshake.c b/libaxl_connect_without_handshake.c
index e05dd66..5a4d1d8 100644
--- a/libaxl_connect_without_handshake.c
+++ b/libaxl_connect_without_handshake.c
@@ -52,21 +52,51 @@ connect_unix(const char *path)
return fd;
}
+static int
+connect_unix_abstract(const char *path, size_t len)
+{
+ struct sockaddr_un addr;
+ int fd;
+
+ fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (fd < 0) {
+ liberror_save_backtrace(NULL);
+ liberror_set_error_errno(strerror(errno), "socket", errno);
+ return -1;
+ }
+
+ addr.sun_family = AF_LOCAL;
+ memcpy(addr.sun_path, path, len);
+ if (connect(fd, (void *)&addr, (socklen_t)len)) {
+ liberror_save_backtrace(NULL);
+ liberror_set_error_errno(strerror(errno), "connect", errno);
+ return -1;
+ }
+
+ return fd;
+}
+
LIBAXL_CONNECTION *
libaxl_connect_without_handshake(const char *host, const char *protocol, int display, int screen)
{
LIBAXL_CONNECTION *conn;
- char path[sizeof("/tmp/.X11-unix/X-") + 3 * sizeof(int)];
- int fd;
+ char path[sizeof("@/tmp/.X11-unix/X-") + 3 * sizeof(int)];
+ int fd, len;
if ((!protocol || !*protocol) && (!host || !*host)) {
- sprintf(path, "/tmp/.X11-unix/X%i", display);
- fd = connect_unix(path);
- /* TODO also try abstract address version with a NUL byte before it (truncate address to remove tailing NULs) */
+ len = sprintf(path, "%c/tmp/.X11-unix/X%i", 0, display);
+ fd = connect_unix(&path[1]);
if (fd < 0) {
- fd = connect_tcp_ip("localhost", display);
- if (fd >= 0)
+ fd = connect_unix_abstract(path, (size_t)len);
+ if (fd >= 0) {
liberror_pop_error();
+ } else {
+ fd = connect_tcp_ip("localhost", display);
+ if (fd >= 0) {
+ liberror_pop_error();
+ liberror_pop_error();
+ }
+ }
}
} else if (!protocol || !*protocol ||
diff --git a/libaxl_receive.c b/libaxl_receive.c
index 2e4fc20..227e149 100644
--- a/libaxl_receive.c
+++ b/libaxl_receive.c
@@ -60,12 +60,13 @@ static const char *const reply_formats[] = {
* $ = 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
+ * u = STRING8, align output to (void *) and enter (equivalent to "*1/")
+ * U = STRING16, align output to (void *) and enter (equivalent to "*2/")
* d = data, uses %, align output to (void *) and enter
* * = following are repeated, align output to (void *) and enter
* & = * but requires allocation
- * p = padding
+ * / = end of * or &
+ * p = padding, align input to byte-quad
*/
[0] = NULL,
[LIBAXL_REQUEST_CREATE_WINDOW] = NULL,
@@ -82,13 +83,13 @@ static const char *const reply_formats[] = {
[LIBAXL_REQUEST_CONFIGURE_WINDOW] = NULL,
[LIBAXL_REQUEST_CIRCULATE_WINDOW] = NULL,
[LIBAXL_REQUEST_GET_GEOMETRY] = "1244ss222",
- [LIBAXL_REQUEST_QUERY_TREE] = "1.24442$=-,*4",
+ [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_LIST_PROPERTIES] = "1.242$==-,*4/",
[LIBAXL_REQUEST_SET_SELECTION_OWNER] = NULL,
[LIBAXL_REQUEST_GET_SELECTION_OWNER] = "1.244",
[LIBAXL_REQUEST_CONVERT_SELECTION] = NULL,
@@ -106,7 +107,7 @@ static const char *const reply_formats[] = {
[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_GET_MOTION_EVENTS] = "1!244$==-*4ss/",
[LIBAXL_REQUEST_TRANSLATE_COORDINATES] = "1!244ss",
[LIBAXL_REQUEST_WARP_POINTER] = NULL,
[LIBAXL_REQUEST_SET_INPUT_FOCUS] = "11244",
@@ -114,12 +115,12 @@ static const char *const reply_formats[] = {
[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_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_LIST_FONTS] = "1.242$==-,&1$u/",
+ [LIBAXL_REQUEST_LIST_FONTS_WITH_INFO] = "11$24?sssss2-sssss2-2222$?111!ss4*44/u",
[LIBAXL_REQUEST_SET_FONT_PATH] = NULL,
- [LIBAXL_REQUEST_GET_FONT_PATH] = "1.242$==-,&1$u",
+ [LIBAXL_REQUEST_GET_FONT_PATH] = "1.242$==-,&1$u/",
[LIBAXL_REQUEST_CREATE_PIXMAP] = NULL,
[LIBAXL_REQUEST_FREE_PIXMAP] = NULL,
[LIBAXL_REQUEST_CREATE_GC] = NULL,
@@ -140,7 +141,7 @@ static const char *const reply_formats[] = {
[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_GET_IMAGE] = "11244==-@u",
[LIBAXL_REQUEST_POLY_TEXT8] = NULL,
[LIBAXL_REQUEST_POLY_TEXT16] = NULL,
[LIBAXL_REQUEST_IMAGE_TEXT8] = NULL,
@@ -150,15 +151,15 @@ static const char *const reply_formats[] = {
[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_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_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_QUERY_COLORS] = "1.242$==-,*222,/",
[LIBAXL_REQUEST_LOOKUP_COLOR] = "1.24222222",
[LIBAXL_REQUEST_CREATE_CURSOR] = NULL,
[LIBAXL_REQUEST_CREATE_GLYPH_CURSOR] = NULL,
@@ -166,9 +167,9 @@ static const char *const reply_formats[] = {
[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_LIST_EXTENSIONS] = "11$24===&1$u/",
[LIBAXL_REQUEST_CHANGE_KEYBOARD_MAPPING] = NULL,
- [LIBAXL_REQUEST_GET_KEYBOARD_MAPPING] = "1124$===*4",
+ [LIBAXL_REQUEST_GET_KEYBOARD_MAPPING] = "1124$===*4/",
[LIBAXL_REQUEST_CHANGE_KEYBOARD_CONTROL] = NULL,
[LIBAXL_REQUEST_GET_KEYBOARD_CONTROL] = "112441122,#",
[LIBAXL_REQUEST_BELL] = NULL,
@@ -177,16 +178,16 @@ static const char *const reply_formats[] = {
[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_LIST_HOSTS] = "1124$2==-,&1.2$up/",
[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_GET_POINTER_MAPPING] = "11$24===*1/",
[LIBAXL_REQUEST_SET_MODIFIER_MAPPING] = "1124",
- [LIBAXL_REQUEST_GET_MODIFIER_MAPPING] = "11$24===*11",
+ [LIBAXL_REQUEST_GET_MODIFIER_MAPPING] = "11$24===*11/",
[LIBAXL_REQUEST_NO_OPERATION] = NULL
};
@@ -194,11 +195,17 @@ static const char *const reply_formats[] = {
int
libaxl_receive(LIBAXL_CONTEXT *restrict ctx, union libaxl_input *restrict msgp, int flags)
{
+ struct {
+ const char *fmt;
+ char *msg;
+ size_t ic, oc, o, count;
+ } stack[3];
+ size_t si = 0;
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;
+ size_t format = 1, counts[] = {0, 0, 0}, count = 0;
ssize_t r;
uint64_t n, u64;
uint8_t code;
@@ -418,7 +425,7 @@ received_reply:
return LIBAXL_ERROR_INVALID_REPLY_OPCODE;
}
- for (i = o = 0; i < n; fmt++) {
+ for (i = o = 0; i < n || *fmt == '@' || *fmt == '$' || *fmt == '%' || *fmt == '/'; fmt++) {
switch (*fmt) {
case '\0':
goto end_of_fmt;
@@ -575,10 +582,19 @@ received_reply:
case '*':
ALIGN(&o, void *);
*(void **)&msg[o] = data = &inbuf[i];
+ o += sizeof(void *);
+ stack[si].fmt = fmt;
+ stack[si].msg = msg;
+ stack[si].ic = ic;
+ stack[si].oc = oc + 1;
+ stack[si].o = o;
+ stack[si].count = count;
+ si += 1;
count = counts[oc++];
- /* TODO */
- fprintf(stderr, "libaxl_receive: function not fully implemented: '*' case\n");
- abort();
+ o = 0;
+ msg = data;
+ if (!count)
+ goto jump_to_end_of_repeat;
break;
case '&': /* TODO */
@@ -592,6 +608,32 @@ received_reply:
*/
break;
+ case '/':
+ if (--count) {
+ fmt = stack[si - 1].fmt;
+ } else {
+ if (0) {
+ jump_to_end_of_repeat:
+ for (j = 0;; fmt++) {
+ if (*fmt == '*' || *fmt == '&') {
+ j += 1;
+ } else if (*fmt == '/') {
+ if (!j--)
+ break;
+ } else if (!*fmt) {
+ abort();
+ }
+ }
+ }
+ si -= 1;
+ msg = stack[si].msg;
+ ic = stack[si].ic;
+ oc = stack[si].oc;
+ o = stack[si].o;
+ count = stack[si].count;
+ }
+ break;
+
case '?':
/* We know that code == LIBAXL_REQUEST_LIST_FONTS_WITH_INFO */
if (!qc++) {
@@ -609,6 +651,30 @@ received_reply:
}
}
+ for (; *fmt && oc < ic && !counts[oc++]; fmt++) {
+ if (*fmt == '*' || *fmt == '&') {
+ ALIGN(&o, void *);
+ *(void **)&msg[o] = NULL;
+ o += sizeof(void *);
+ for (j = 0;; fmt++) {
+ if (*fmt == '*' || *fmt == '&') {
+ j += 1;
+ } else if (*fmt == '/') {
+ if (!--j)
+ break;
+ } else if (!*fmt) {
+ abort();
+ }
+ }
+ } else if (*fmt == 'u' || *fmt == 'U' || *fmt == 'd') {
+ ALIGN(&o, void *);
+ *(void **)&msg[o] = NULL;
+ o += sizeof(void *);
+ } else {
+ break;
+ }
+ }
+
if (*fmt) {
liberror_save_backtrace(NULL);
short_msg: