#include #include "lx.h" #include "proto.h" #include "internal.h" typedef struct priv_QueryTree PRIV_QueryTree; struct priv_QueryTree { LX_XID *rootp; LX_XID *parentp; LX_XIDLIST **listp; } ; static void done_QueryTree(LX_OP *op, const unsigned char *rep) { PRIV_QueryTree *p; LX_XIDLIST *xl; int n; int i; p = op->reqpriv; do <"ret"> { n = r_card16(rep+16); if (r_card32(rep+4) != n) { lx__protoerr(op->conn,"QueryTree response length wrong (%u, expecting %d)",r_card32(rep+4),n); break <"ret">; } if (p->listp) { do <"good"> { do <"mem"> { xl = malloc(sizeof(LX_XIDLIST)); if (! xl) break <"mem">; xl->len = n; xl->ids = malloc(n*sizeof(LX_XID)); if (! xl->ids) break <"mem">; for (i=n-1;i>=0;i--) xl->ids[i] = r_card32(rep+32+(4*i)); *p->listp = xl; break <"good">; } while (0); lx__nomem_fail(op->conn); if (xl) { free(xl->ids); free(xl); } break <"ret">; } while (0); } if (p->rootp) *p->rootp = r_card32(rep+8); if (p->parentp) *p->parentp = r_card32(rep+12); } while (0); op->reqpriv = 0; free(p); } LX_OP *lx_QueryTree(LX_CONN *xc, LX_XID window, LX_XID *rootp, LX_XID *parentp, LX_XIDLIST **listp) { unsigned char req[8]; PRIV_QueryTree *p; if (xc->flags & XCF_FAIL) { lx__bad_call(xc,"lx_QueryTree"); return(0); } lx__nochain(xc); p = malloc(sizeof(PRIV_QueryTree)); if (! p) { lx__nomem_fail(xc); return(0); } p->rootp = rootp; p->parentp = parentp; p->listp = listp; req[0] = XP_REQ_QueryTree; req[1] = 0; w_card16(&req[2],2); w_card32(&req[4],window); return(lx__expect_reply(xc,&req[0],-1,&done_QueryTree,p)); }