#include #include #include "lx.h" #include "proto.h" #include "internal.h" typedef struct priv_ListFonts PRIV_ListFonts; struct priv_ListFonts { LX_STRLIST **slp; } ; static void done_ListFonts(LX_CONN *xc, const unsigned char *rep, void *pv) { PRIV_ListFonts *p; int n; LX_STRLIST *l; int i; int pl; int po; int rl; int ro; int sl; p = pv; do <"ret"> { n = r_card16(rep+8); do <"fail"> { do <"mem"> { if (p->slp) { l = malloc(sizeof(LX_STRLIST)); if (! l) break <"mem">; l->len = n; l->lens = 0; l->data = 0; l->alldata = 0; l->lens = malloc(n*sizeof(int)); if (! l->lens) break <"mem">; l->data = malloc(n*sizeof(char *)); if (! l->data) break <"mem">; rl = r_card32(rep+4) * 4; l->alldata = malloc(rl); if (! l->alldata) break <"mem">; pl = 32 + rl; po = 32; ro = 0; for (i=0;i pl) { lx__protoerr(xc,"ListFonts reply string overruns packet"); break <"fail">; } sl = rep[po]; if (po+1+sl > pl) { lx__protoerr(xc,"ListFonts reply string overruns packet"); break <"fail">; } l->lens[i] = sl; l->data[i] = l->alldata + ro; bcopy(rep+po+1,l->alldata+ro,sl); l->alldata[ro+sl] = '\0'; ro += sl + 1; po += 1 + sl; } if (po > pl) lx_abort(); if (pl-po > 3) { lx__protoerr(xc,"ListFonts reply is too long"); break <"fail">; } *p->slp = l; } break <"ret">; } while (0); lx__nomem_fail(xc); } while (0); if (l) { free(l->lens); free(l->data); free(l->alldata); free(l); } } while (0); free(p); } LX_OP *lx_ListFonts(LX_CONN *xc, const char *pattern, int max, LX_STRLIST **slp) { unsigned char reqhdr[8]; int patlen; PRIV_ListFonts *p; patlen = strlen(pattern); if ((xc->flags & XCF_FAIL) || (max < 0) || (max > 65535) || (patlen > 65535)) { lx__bad_call(xc,"lx_ListFonts"); return(0); } lx__nochain(xc); p = malloc(sizeof(PRIV_ListFonts)); if (! p) { lx__nomem_fail(xc); return(0); } p->slp = slp; reqhdr[0] = XP_REQ_ListFonts; reqhdr[1] = 0; w_card16(&reqhdr[2],2+((patlen+3)>>2)); w_card16(&reqhdr[4],max); w_card16(&reqhdr[6],patlen); lx__just_send(xc,&reqhdr[0],8); lx__just_send(xc,pattern,patlen); lx__send_padding(xc,patlen); return(lx__expect_reply(xc,0,0,&done_ListFonts,p)); }