FSFontInfo.c revision 2d8abe4f
1/*
2 * Copyright 1990 Network Computing Devices;
3 * Portions Copyright 1987 by Digital Equipment Corporation
4 *
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without fee,
7 * provided that the above copyright notice appear in all copies and
8 * that both that copyright notice and this permission notice appear
9 * in supporting documentation, and that the names of Network Computing
10 * Devices or Digital not be used in advertising or publicity pertaining
11 * to distribution of the software without specific, written prior
12 * permission. Network Computing Devices or Digital make no representations
13 * about the suitability of this software for any purpose.  It is provided
14 * "as is" without express or implied warranty.
15 *
16 * NETWORK COMPUTING DEVICES AND  DIGITAL DISCLAIM ALL WARRANTIES WITH
17 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES
19 * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
23 * SOFTWARE.
24 */
25
26/*
27
28Copyright 1987, 1998  The Open Group
29
30Permission to use, copy, modify, distribute, and sell this software and its
31documentation for any purpose is hereby granted without fee, provided that
32the above copyright notice appear in all copies and that both that
33copyright notice and this permission notice appear in supporting
34documentation.
35
36The above copyright notice and this permission notice shall be included in
37all copies or substantial portions of the Software.
38
39THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
42OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
43AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
44CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45
46Except as contained in this notice, the name of The Open Group shall not be
47used in advertising or otherwise to promote the sale, use or other dealings
48in this Software without prior written authorization from The Open Group.
49
50*/
51#ifdef HAVE_CONFIG_H
52#include <config.h>
53#endif
54#include	"FSlibint.h"
55
56char      **
57FSListFontsWithXInfo(
58    FSServer		  *svr,
59    char		  *pattern,
60    int			   maxNames,
61    int			  *count,
62    FSXFontInfoHeader	***info,
63    FSPropInfo		***pprops,
64    FSPropOffset	***offsets,
65    unsigned char	***prop_data)
66{
67    long        nbytes;
68    int         i,
69                j;
70    size_t      size = 0;
71    FSXFontInfoHeader **fhdr = (FSXFontInfoHeader **) 0;
72    FSPropInfo **pi = (FSPropInfo **) 0;
73    FSPropOffset **po = (FSPropOffset **) 0;
74    unsigned char **pd = (unsigned char **) 0;
75    char      **flist = NULL;
76    fsListFontsWithXInfoReply reply;
77    fsListFontsWithXInfoReq *req;
78    fsPropInfo local_pi;
79    fsPropOffset local_po;
80    Status status;
81
82    GetReq(ListFontsWithXInfo, req);
83    req->maxNames = maxNames;
84    nbytes = req->nbytes = pattern ? strlen(pattern) : 0;
85    req->length += (nbytes + 3) >> 2;
86    _FSSend(svr, pattern, nbytes);
87
88    for (i = 0;; i++) {
89	if (FSProtocolVersion(svr) > 1)
90	{
91	    status = _FSReply(svr, (fsReply *) &reply, 0, fsFalse);
92	    if (status != 0  &&  reply.nameLength == 0)	/* got last reply */
93		break;
94	    if (status)
95		_FSRead(svr, ((char *) &reply) + SIZEOF(fsGenericReply),
96			SIZEOF(fsListFontsWithXInfoReply) -
97			SIZEOF(fsGenericReply));
98	} else {
99	    status = _FSReply(svr, (fsReply *) & reply,
100			      ((SIZEOF(fsListFontsWithXInfoReply) -
101				SIZEOF(fsGenericReply)) >> 2), fsFalse);
102	}
103	if (!status) {
104	    for (j = (i - 1); j >= 0; j--) {
105		FSfree((char *) fhdr[j]);
106		FSfree((char *) pi[j]);
107		FSfree((char *) po[j]);
108		FSfree((char *) pd[j]);
109		FSfree(flist[j]);
110	    }
111	    if (flist)
112		FSfree((char *) flist);
113	    if (fhdr)
114		FSfree((char *) fhdr);
115	    if (pi)
116		FSfree((char *) pi);
117	    if (po)
118		FSfree((char *) po);
119	    if (pd)
120		FSfree((char *) pd);
121
122	    SyncHandle();
123	    return (char **) NULL;
124	}
125	if (reply.nameLength == 0)	/* got last reply in version 1 */
126	    break;
127	if ((i + reply.nReplies) >= size) {
128
129	    if (reply.nReplies > SIZE_MAX - i - 1)
130		goto badmem;
131	    size = i + reply.nReplies + 1;
132
133	    if (size > SIZE_MAX / sizeof(char *))
134		goto badmem;
135
136	    if (fhdr) {
137		FSXFontInfoHeader **tmp_fhdr = (FSXFontInfoHeader **)
138		FSrealloc((char *) fhdr,
139			  (unsigned) (sizeof(FSXFontInfoHeader *) * size));
140		char      **tmp_flist = (char **) FSrealloc((char *) flist,
141					 (unsigned) (sizeof(char *) * size));
142		FSPropInfo **tmp_pi = (FSPropInfo **)
143		FSrealloc((char *) pi,
144			  (unsigned) (sizeof(FSPropInfo *) * size));
145		FSPropOffset **tmp_po = (FSPropOffset **)
146		FSrealloc((char *) po,
147			  (unsigned) (sizeof(FSPropOffset *) * size));
148		unsigned char **tmp_pd = (unsigned char **)
149		FSrealloc((char *) pd,
150			  (unsigned) (sizeof(unsigned char *) * size));
151
152		if (!tmp_fhdr || !tmp_flist || !tmp_pi || !tmp_po || !tmp_pd) {
153		    for (j = (i - 1); j >= 0; j--) {
154			FSfree((char *) flist[j]);
155			FSfree((char *) fhdr[j]);
156			FSfree((char *) pi[j]);
157			FSfree((char *) po[j]);
158			FSfree((char *) pd[j]);
159		    }
160		    if (tmp_flist)
161			FSfree((char *) tmp_flist);
162		    else
163			FSfree((char *) flist);
164		    if (tmp_fhdr)
165			FSfree((char *) tmp_fhdr);
166		    else
167			FSfree((char *) fhdr);
168		    if (tmp_pi)
169			FSfree((char *) tmp_pi);
170		    else
171			FSfree((char *) pi);
172		    if (tmp_po)
173			FSfree((char *) tmp_po);
174		    else
175			FSfree((char *) po);
176		    if (tmp_pd)
177			FSfree((char *) tmp_pd);
178		    else
179			FSfree((char *) pd);
180		    goto clearwire;
181		}
182		fhdr = tmp_fhdr;
183		flist = tmp_flist;
184		pi = tmp_pi;
185		po = tmp_po;
186		pd = tmp_pd;
187	    } else {
188		if (!(fhdr = (FSXFontInfoHeader **)
189		      FSmalloc((unsigned) (sizeof(FSXFontInfoHeader *) * size))))
190		    goto clearwire;
191		if (!(flist = (char **)
192		      FSmalloc((unsigned) (sizeof(char *) * size)))) {
193		    FSfree((char *) fhdr);
194		    goto clearwire;
195		}
196		if (!(pi = (FSPropInfo **)
197		      FSmalloc((unsigned) (sizeof(FSPropInfo *) * size)))) {
198		    FSfree((char *) fhdr);
199		    FSfree((char *) flist);
200		    goto clearwire;
201		}
202		if (!(po = (FSPropOffset **)
203		      FSmalloc((unsigned) (sizeof(FSPropOffset *) * size)))) {
204		    FSfree((char *) fhdr);
205		    FSfree((char *) flist);
206		    FSfree((char *) pi);
207		    goto clearwire;
208		}
209		if (!(pd = (unsigned char **)
210		    FSmalloc((unsigned) (sizeof(unsigned char *) * size)))) {
211		    FSfree((char *) fhdr);
212		    FSfree((char *) flist);
213		    FSfree((char *) pi);
214		    FSfree((char *) po);
215		    goto clearwire;
216		}
217	    }
218	}
219	fhdr[i] = (FSXFontInfoHeader *) FSmalloc(sizeof(FSXFontInfoHeader));
220	if (!fhdr[i]) {
221	    goto badmem;
222	}
223	FSUnpack_XFontInfoHeader(&reply, fhdr[i], FSProtocolVersion(svr));
224
225	/* alloc space for the name */
226	flist[i] = (char *) FSmalloc((unsigned int) (reply.nameLength + 1));
227	if (FSProtocolVersion(svr) == 1)
228	{
229	    /* get the name */
230	    if (!flist[i]) {
231		nbytes = (reply.nameLength + 3) & ~3;
232		_FSEatData(svr, (unsigned long) nbytes);
233		goto badmem;
234	    }
235	    _FSReadPad(svr, flist[i], (long) reply.nameLength);
236	    flist[i][reply.nameLength] = '\0';
237	}
238
239	pi[i] = (FSPropInfo *) FSmalloc(sizeof(FSPropInfo));
240	if (!pi[i]) {
241	    FSfree((char *) fhdr[i]);
242	    goto badmem;
243	}
244	_FSReadPad(svr, (char *) &local_pi, SIZEOF(fsPropInfo));
245	pi[i]->num_offsets = local_pi.num_offsets;
246	pi[i]->data_len = local_pi.data_len;
247
248#if SIZE_MAX <= UINT_MAX
249	if (pi[i]->num_offsets > SIZE_MAX / sizeof(FSPropOffset))
250	    goto badmem;
251#endif
252
253	po[i] = (FSPropOffset *)
254	    FSmalloc(pi[i]->num_offsets * sizeof(FSPropOffset));
255	if (!po[i]) {
256	    FSfree((char *) fhdr[i]);
257	    FSfree((char *) pi[i]);
258	    goto badmem;
259	}
260	pd[i] = (unsigned char *) FSmalloc(pi[i]->data_len);
261	if (!pd[i]) {
262	    FSfree((char *) fhdr[i]);
263	    FSfree((char *) pi[i]);
264	    FSfree((char *) po[i]);
265	    goto badmem;
266	}
267	/* get offsets */
268	for (j=0; j<pi[i]->num_offsets; j++)
269	{
270	    _FSReadPad(svr, (char *) &local_po, SIZEOF(fsPropOffset));
271	    po[i][j].name.position = local_po.name.position;
272	    po[i][j].name.length = local_po.name.length;
273	    po[i][j].value.position = local_po.value.position;
274	    po[i][j].value.length = local_po.value.length;
275	    po[i][j].type = local_po.type;
276	}
277
278	/* get prop data */
279	if (FSProtocolVersion(svr) == 1)
280	    _FSReadPad(svr, (char *) pd[i], pi[i]->data_len);
281	else
282	    _FSRead(svr, (char *) pd[i], pi[i]->data_len);
283
284	if (FSProtocolVersion(svr) != 1)
285	{
286	    /* get the name */
287	    if (!flist[i]) {
288		nbytes = (reply.nameLength + 3) & ~3;
289		_FSEatData(svr, (unsigned long) nbytes);
290		goto badmem;
291	    }
292	    _FSRead(svr, flist[i], (long) reply.nameLength);
293	    flist[i][reply.nameLength] = '\0';
294
295	    nbytes = pi[i]->data_len + reply.nameLength;
296	    _FSEatData(svr, (unsigned long) (((nbytes+3)&~3) - nbytes));
297	}
298	/* avoid integer overflow */
299	if (i > INT_MAX - 1) {
300	    goto badmem;
301	}
302    }
303    *info = fhdr;
304    *count = i;
305    *pprops = pi;
306    *offsets = po;
307    *prop_data = pd;
308    SyncHandle();
309    return flist;
310
311badmem:
312    for (j = (i - 1); j >= 0; j--) {
313	FSfree((char *) pi[j]);
314	FSfree((char *) po[j]);
315	FSfree((char *) pd[j]);
316	FSfree(flist[j]);
317	FSfree((char *) fhdr[j]);
318    }
319    if (flist)
320	FSfree((char *) flist);
321    if (fhdr)
322	FSfree((char *) fhdr);
323    if (pi)
324	FSfree((char *) pi);
325    if (po)
326	FSfree((char *) po);
327    if (pd)
328	FSfree((char *) pd);
329
330
331clearwire:
332    do {
333	fsPropInfo  ti;
334
335	_FSEatData(svr, (reply.nameLength + 3) & ~3);
336	_FSReadPad(svr, (char *) &ti, SIZEOF(fsPropInfo));
337	_FSEatData(svr, (SIZEOF(fsPropOffset) * ti.num_offsets));
338	_FSEatData(svr, ti.data_len);
339    } while (_FSReply(svr, (fsReply *) & reply,
340		      ((SIZEOF(fsListFontsWithXInfoReply)
341       - SIZEOF(fsGenericReply)) >> 2), fsFalse) && (reply.nameLength != 0));
342    SyncHandle();
343    return (char **) NULL;
344}
345