char	tmp_pattern[256];
char	tmp_pattern[XLFDMAXFONTNAMELEN];
doListFontsAndAliases(client, c)    ClientPtr   client;    LFclosurePtr c;#endif{    FontPathElementPtr fpe;    int         err = Successful;    FontNamesPtr names = NULL;    char       *name, *resolved=NULL;    int         namelen, resolvedlen;    int		nnames;    int         stringLens;    int         i;    xListFontsReply reply;    char	*bufptr;    char	*bufferStart;    int		aliascount;    if (client->clientGone)    {	if (c->current.current_fpe < c->num_fpes)	{	    fpe = c->fpe_list[c->current.current_fpe];	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);	}	err = Successful;	goto bail;    }    if (!c->current.patlen)	goto finish;    while (c->current.current_fpe < c->num_fpes) {	fpe = c->fpe_list[c->current.current_fpe];	err = Successful;	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)	{	    /* This FPE doesn't support/require list_fonts_and_aliases */	    err = (*fpe_functions[fpe->type].list_fonts)		((pointer) c->client, fpe, c->current.pattern,		 c->current.patlen, c->current.max_names - c->names->nnames,		 c->names);	    if (err == Suspended) {		if (!c->slept) {		    c->slept = TRUE;		    ClientSleep(client,			(ClientSleepProcPtr)doListFontsAndAliases,			(pointer) c);		}		return TRUE;	    }	    err = BadFontName;	}	else	{	    /* Start of list_fonts_and_aliases functionality.  Modeled	       after list_fonts_with_info in that it resolves aliases,	       except that the information collected from FPEs is just	       names, not font info.  Each list_next_font_or_alias()	       returns either a name into name/namelen or an alias into	       name/namelen and its target name into resolved/resolvedlen.	       The code at this level then resolves the alias by polling	       the FPEs.  */	    if (!c->current.list_started) {		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)		    ((pointer) c->client, fpe, c->current.pattern,		     c->current.patlen, c->current.max_names - c->names->nnames,		     &c->current.private);		if (err == Suspended) {		    if (!c->slept) {			ClientSleep(client,				    (ClientSleepProcPtr)doListFontsAndAliases,				    (pointer) c);			c->slept = TRUE;		    }		    return TRUE;		}		if (err == Successful)		    c->current.list_started = TRUE;	    }	    if (err == Successful) {		char    *tmpname;		name = 0;		err = (*fpe_functions[fpe->type].list_next_font_or_alias)		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,		     &resolvedlen, c->current.private);		if (err == Suspended) {		    if (!c->slept) {			ClientSleep(client,				    (ClientSleepProcPtr)doListFontsAndAliases,				    (pointer) c);			c->slept = TRUE;		    }		    return TRUE;		}		if (err == FontNameAlias) {		    if (resolved) xfree(resolved);		    resolved = (char *) xalloc(resolvedlen + 1);		    if (resolved)			memmove(resolved, tmpname, resolvedlen + 1);		}	    }	    if (err == Successful)	    {		if (c->haveSaved)		{		    if (c->savedName)			(void)AddFontNamesName(c->names, c->savedName,					       c->savedNameLen);		}		else		    (void)AddFontNamesName(c->names, name, namelen);	    }	    /*	     * When we get an alias back, save our state and reset back to	     * the start of the FPE looking for the specified name.  As	     * soon as a real font is found for the alias, pop back to the	     * old state	     */	    else if (err == FontNameAlias) {		char	tmp_pattern[256];		/*		 * when an alias recurses, we need to give		 * the last FPE a chance to clean up; so we call		 * it again, and assume that the error returned		 * is BadFontName, indicating the alias resolution		 * is complete.		 */		memmove(tmp_pattern, resolved, resolvedlen);		if (c->haveSaved)		{		    char    *tmpname;		    int     tmpnamelen;		    tmpname = 0;		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)			((pointer) c->client, fpe, &tmpname, &tmpnamelen,			 &tmpname, &tmpnamelen, c->current.private);		    if (--aliascount <= 0)		    {			err = BadFontName;			goto ContBadFontName;		    }		}		else		{		    c->saved = c->current;		    c->haveSaved = TRUE;		    if (c->savedName)			xfree(c->savedName);		    c->savedName = (char *)xalloc(namelen + 1);		    if (c->savedName)			memmove(c->savedName, name, namelen + 1);		    c->savedNameLen = namelen;		    aliascount = 20;		}		memmove(c->current.pattern, tmp_pattern, resolvedlen);		c->current.patlen = resolvedlen;		c->current.max_names = c->names->nnames + 1;		c->current.current_fpe = -1;		c->current.private = 0;		err = BadFontName;	    }	}	/*	 * At the end of this FPE, step to the next.  If we've finished	 * processing an alias, pop state back. If we've collected enough	 * font names, quit.	 */	if (err == BadFontName) {	  ContBadFontName: ;	    c->current.list_started = FALSE;	    c->current.current_fpe++;	    err = Successful;	    if (c->haveSaved)	    {		if (c->names->nnames == c->current.max_names ||			c->current.current_fpe == c->num_fpes) {		    c->haveSaved = FALSE;		    c->current = c->saved;		    /* Give the saved namelist a chance to clean itself up */		    continue;		}	    }	    if (c->names->nnames == c->current.max_names)		break;	}    }    /*     * send the reply     */    if (err != Successful) {	SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));	goto bail;    }finish:    names = c->names;    nnames = names->nnames;    client = c->client;    stringLens = 0;    for (i = 0; i < nnames; i++)	stringLens += (names->length[i] <= 255) ? names->length[i] : 0;    reply.type = X_Reply;    reply.length = (stringLens + nnames + 3) >> 2;    reply.nFonts = nnames;    reply.sequenceNumber = client->sequence;    bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);    if (!bufptr && reply.length) {	SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);	goto bail;    }    /*     * since WriteToClient long word aligns things, copy to temp buffer and     * write all at once     */    for (i = 0; i < nnames; i++) {	if (names->length[i] > 255)	    reply.nFonts--;	else	{	    *bufptr++ = names->length[i];	    memmove( bufptr, names->names[i], names->length[i]);	    bufptr += names->length[i];	}    }    nnames = reply.nFonts;    reply.length = (stringLens + nnames + 3) >> 2;    client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];    WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);    (void) WriteToClient(client, stringLens + nnames, bufferStart);    DEALLOCATE_LOCAL(bufferStart);bail:    if (c->slept)	ClientWakeup(client);    for (i = 0; i < c->num_fpes; i++)	FreeFPE(c->fpe_list[i]);    xfree(c->fpe_list);    if (c->savedName) xfree(c->savedName);    FreeFontNames(names);    xfree(c);    if (resolved) xfree(resolved);    return TRUE;}