File: | difs/dispatch.c |
Location: | line 652, column 29 |
Description: | Dereference of null pointer |
1 | /* | |||||
2 | * protocol dispatcher | |||||
3 | */ | |||||
4 | /* | |||||
5 | ||||||
6 | Copyright 1990, 1991, 1998 The Open Group | |||||
7 | ||||||
8 | Permission to use, copy, modify, distribute, and sell this software and its | |||||
9 | documentation for any purpose is hereby granted without fee, provided that | |||||
10 | the above copyright notice appear in all copies and that both that | |||||
11 | copyright notice and this permission notice appear in supporting | |||||
12 | documentation. | |||||
13 | ||||||
14 | The above copyright notice and this permission notice shall be included in | |||||
15 | all copies or substantial portions of the Software. | |||||
16 | ||||||
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
20 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||||
21 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||||
22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
23 | ||||||
24 | Except as contained in this notice, the name of The Open Group shall not be | |||||
25 | used in advertising or otherwise to promote the sale, use or other dealings | |||||
26 | in this Software without prior written authorization from The Open Group. | |||||
27 | ||||||
28 | * Copyright 1990, 1991 Network Computing Devices; | |||||
29 | * Portions Copyright 1987 by Digital Equipment Corporation | |||||
30 | * | |||||
31 | * Permission to use, copy, modify, distribute, and sell this software and | |||||
32 | * its documentation for any purpose is hereby granted without fee, provided | |||||
33 | * that the above copyright notice appear in all copies and that both that | |||||
34 | * copyright notice and this permission notice appear in supporting | |||||
35 | * documentation, and that the names of Network Computing Devices, or Digital | |||||
36 | * not be used in advertising or publicity pertaining to distribution | |||||
37 | * of the software without specific, written prior permission. | |||||
38 | * | |||||
39 | * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH | |||||
40 | * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF | |||||
41 | * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, | |||||
42 | * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | |||||
43 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | |||||
44 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | |||||
45 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||||
46 | * THIS SOFTWARE. | |||||
47 | */ | |||||
48 | ||||||
49 | #include "config.h" | |||||
50 | ||||||
51 | #include <stdlib.h> | |||||
52 | #include "dispatch.h" | |||||
53 | #include "swapreq.h" | |||||
54 | #include "swaprep.h" | |||||
55 | ||||||
56 | #include <X11/fonts/FS.h> | |||||
57 | #include <X11/fonts/FSproto.h> | |||||
58 | #include "clientstr.h" | |||||
59 | #include "authstr.h" | |||||
60 | #include "osstruct.h" | |||||
61 | #include "extentst.h" | |||||
62 | #include "globals.h" | |||||
63 | #include "fsresource.h" | |||||
64 | #include "difsfnst.h" | |||||
65 | #include <X11/fonts/fontstruct.h> | |||||
66 | #include "site.h" | |||||
67 | #include "fsevents.h" | |||||
68 | #include "globals.h" | |||||
69 | #include "difs.h" | |||||
70 | #include "access.h" | |||||
71 | ||||||
72 | static void kill_all_clients(void); | |||||
73 | ||||||
74 | volatile char dispatchException = 0; | |||||
75 | volatile char isItTimeToYield; | |||||
76 | ||||||
77 | ClientPtr currentClient; | |||||
78 | ||||||
79 | static int nClients = 0; | |||||
80 | static int nextFreeClientID; | |||||
81 | ||||||
82 | #define MAJOROP((fsReq *)client->requestBuffer)->reqType ((fsReq *)client->requestBuffer)->reqType | |||||
83 | ||||||
84 | #define ALL_FORMAT_BITS((1L << 0) | (1L << 1) | (3L << 12) | (3L << 8) | (3L << 2)) (BitmapFormatByteOrderMask(1L << 0) | \ | |||||
85 | BitmapFormatBitOrderMask(1L << 1) | \ | |||||
86 | BitmapFormatScanlineUnitMask(3L << 12) | \ | |||||
87 | BitmapFormatScanlinePadMask(3L << 8) | \ | |||||
88 | BitmapFormatImageRectMask(3L << 2)) | |||||
89 | ||||||
90 | #define ALL_FORMAT_MASK_BITS((1L << 0) | (1L << 1) | (1L << 2) | (1L << 3) | (1L << 4)) (BitmapFormatMaskByte(1L << 0) | \ | |||||
91 | BitmapFormatMaskBit(1L << 1) | \ | |||||
92 | BitmapFormatMaskImageRectangle(1L << 2) | \ | |||||
93 | BitmapFormatMaskScanLinePad(1L << 3) | \ | |||||
94 | BitmapFormatMaskScanLineUnit(1L << 4)) | |||||
95 | ||||||
96 | void | |||||
97 | Dispatch(void) | |||||
98 | { | |||||
99 | int nready, | |||||
100 | result; | |||||
101 | int *clientReady; | |||||
102 | ClientPtr client; | |||||
103 | int op; | |||||
104 | ||||||
105 | nextFreeClientID = MINCLIENT1; | |||||
106 | nClients = 0; | |||||
107 | ||||||
108 | clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients)__builtin_alloca((int)(sizeof(int) * MaxClients)); | |||||
109 | if (!clientReady) | |||||
110 | return; | |||||
111 | ||||||
112 | while (1) { | |||||
113 | /* wait for something */ | |||||
114 | nready = WaitForSomething(clientReady); | |||||
115 | ||||||
116 | while (!dispatchException && (--nready >= 0)) { | |||||
117 | client = currentClient = clients[clientReady[nready]]; | |||||
118 | ||||||
119 | /* Client can be NULL if CloseDownClient() is called during | |||||
120 | this dispatchException loop. */ | |||||
121 | if (client == (ClientPtr)NULL((void *)0)) continue; | |||||
122 | ||||||
123 | isItTimeToYield = FALSE0; | |||||
124 | ||||||
125 | while (!isItTimeToYield) { | |||||
126 | result = ReadRequest(client); | |||||
127 | if (result <= 0) { | |||||
128 | if (result < 0) | |||||
129 | CloseDownClientDoCloseDownClient(client); | |||||
130 | break; | |||||
131 | } | |||||
132 | client->sequence++; | |||||
133 | ||||||
134 | if (result > (MAX_REQUEST_SIZE8192 << 2)) | |||||
135 | result = FSBadLength10; | |||||
136 | else | |||||
137 | { | |||||
138 | op = MAJOROP((fsReq *)client->requestBuffer)->reqType; | |||||
139 | if (op >= NUM_PROC_VECTORS25) | |||||
140 | result = ProcBadRequest (client); | |||||
141 | else if (*client->requestVector[op] != NULL((void *)0)) | |||||
142 | result = (*client->requestVector[op]) (client); | |||||
143 | else | |||||
144 | result = FSBadRequest0; | |||||
145 | } | |||||
146 | if (result != FSSuccess-1) { | |||||
147 | if (client->noClientException != FSSuccess-1) | |||||
148 | CloseDownClientDoCloseDownClient(client); | |||||
149 | break; | |||||
150 | } | |||||
151 | } | |||||
152 | FlushAllOutput (); | |||||
153 | } | |||||
154 | /* reset if server is a drone and has run out of clients */ | |||||
155 | if (drone_server && nClients == 0) { | |||||
156 | dispatchException |= DE_RESET0x1; | |||||
157 | } | |||||
158 | if (dispatchException) { | |||||
159 | /* re-read the config file */ | |||||
160 | if (dispatchException & DE_RECONFIG0x4) { | |||||
161 | NoticeF("re-reading config file\n"); | |||||
162 | if (ReadConfigFile(configfilename) != FSSuccess-1) | |||||
163 | ErrorF("couldn't parse config file\n"); | |||||
164 | SetConfigValues(); | |||||
165 | dispatchException &= ~DE_RECONFIG0x4; | |||||
166 | } | |||||
167 | /* flush all the caches */ | |||||
168 | if (dispatchException & DE_FLUSH0x8) { | |||||
169 | NoticeF("flushing all caches\n"); | |||||
170 | dispatchException &= ~DE_FLUSH0x8; | |||||
171 | } | |||||
172 | /* reset */ | |||||
173 | if (dispatchException & DE_RESET0x1) { | |||||
174 | NoticeF("resetting\n"); | |||||
175 | break; | |||||
176 | } | |||||
177 | /* die *now* */ | |||||
178 | if (dispatchException & DE_TERMINATE0x2) { | |||||
179 | NoticeF("terminating\n"); | |||||
180 | kill_all_clients(); | |||||
181 | CloseSockets(); | |||||
182 | CloseErrors(); | |||||
183 | exit(0); | |||||
184 | break; | |||||
185 | } | |||||
186 | } | |||||
187 | } | |||||
188 | kill_all_clients(); | |||||
189 | dispatchException = 0; | |||||
190 | } | |||||
191 | ||||||
192 | int | |||||
193 | ProcInitialConnection(ClientPtr client) | |||||
194 | { | |||||
195 | REQUEST(fsFakeReq)fsFakeReq *stuff = (fsFakeReq *)client->requestBuffer; | |||||
196 | fsConnClientPrefix *prefix; | |||||
197 | int whichbyte = 1; | |||||
198 | ||||||
199 | prefix = (fsConnClientPrefix *) stuff+1; | |||||
200 | if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) | |||||
201 | return (client->noClientException = -2); | |||||
202 | if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || | |||||
203 | (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) { | |||||
204 | int status; | |||||
205 | ||||||
206 | client->swapped = TRUE1; | |||||
207 | status = SwapConnClientPrefix(client, prefix); | |||||
208 | if (status != FSSuccess-1) | |||||
209 | return (status); | |||||
210 | } | |||||
211 | client->major_version = prefix->major_version; | |||||
212 | client->minor_version = prefix->minor_version; | |||||
213 | stuff->reqType = 2; | |||||
214 | stuff->length += prefix->auth_len; | |||||
215 | if (client->swapped) { | |||||
216 | stuff->length = lswaps(stuff->length)((((stuff->length) & 0xff) << 8) | (((stuff-> length) >> 8) & 0xff)); | |||||
217 | } | |||||
218 | ResetCurrentRequest(client); | |||||
219 | return client->noClientException; | |||||
220 | } | |||||
221 | ||||||
222 | int | |||||
223 | ProcEstablishConnection(ClientPtr client) | |||||
224 | { | |||||
225 | fsConnClientPrefix *prefix; | |||||
226 | int ret; | |||||
227 | pointer auth_data; | |||||
228 | char *ad; | |||||
229 | char *server_auth_data; | |||||
230 | AuthPtr client_auth; | |||||
231 | int i, | |||||
232 | num_alts, | |||||
233 | altlen, | |||||
234 | auth_accept, | |||||
235 | auth_index, | |||||
236 | auth_len; | |||||
237 | AlternateServerPtr altservers; | |||||
238 | ||||||
239 | REQUEST(fsFakeReq)fsFakeReq *stuff = (fsFakeReq *)client->requestBuffer; | |||||
240 | ||||||
241 | prefix = (fsConnClientPrefix *) stuff+1; | |||||
242 | auth_data = prefix + sz_fsConnClientPrefix8; | |||||
243 | client_auth = (AuthPtr) ALLOCATE_LOCAL(prefix->num_auths * sizeof(AuthRec))__builtin_alloca((int)(prefix->num_auths * sizeof(AuthRec) )); | |||||
244 | if (!client_auth) { | |||||
245 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); | |||||
246 | return FSBadAlloc9; | |||||
247 | } | |||||
248 | /* XXXX -- this needs work for multiple auth replies */ | |||||
249 | ||||||
250 | /* build up a list of the stuff */ | |||||
251 | for (i = 0, ad = auth_data; i < (int)prefix->num_auths; i++) { | |||||
252 | if (ad - (char *)auth_data > (stuff->length << 2) - 4) { | |||||
253 | int lengthword = stuff->length; | |||||
254 | ||||||
255 | SendErrToClientDoSendErrToClient(client, FSBadLength10, (pointer)&lengthword); | |||||
256 | DEALLOCATE_LOCAL(client_auth)do {} while(0); | |||||
257 | return (FSBadLength10); | |||||
258 | } | |||||
259 | /* copy carefully in case wire data is not aligned */ | |||||
260 | client_auth[i].namelen = (((unsigned char *)ad)[0] << 8) + | |||||
261 | ((unsigned char *)ad)[1]; | |||||
262 | ad += 2; | |||||
263 | client_auth[i].datalen = (((unsigned char *)ad)[0] << 8) + | |||||
264 | ((unsigned char *)ad)[1]; | |||||
265 | ad += 2; | |||||
266 | client_auth[i].name = (char *) ad; | |||||
267 | ad += client_auth[i].namelen; | |||||
268 | client_auth[i].data = (char *) ad; | |||||
269 | ad += client_auth[i].datalen; | |||||
270 | } | |||||
271 | if (!(int)prefix->num_auths) | |||||
272 | ad += 4; | |||||
273 | if (ad - (char *)auth_data > (stuff->length << 2)) { | |||||
274 | int lengthword = stuff->length; | |||||
275 | ||||||
276 | SendErrToClientDoSendErrToClient(client, FSBadLength10, (pointer)&lengthword); | |||||
277 | DEALLOCATE_LOCAL(client_auth)do {} while(0); | |||||
278 | return (FSBadLength10); | |||||
279 | } | |||||
280 | ||||||
281 | num_alts = ListAlternateServers(&altservers); | |||||
282 | for (i = 0, altlen = 0; i < num_alts; i++) { | |||||
283 | /* subset + len + namelen + pad */ | |||||
284 | altlen += (2 + altservers[i].namelen + 3) >> 2; | |||||
285 | } | |||||
286 | ||||||
287 | auth_index = prefix->num_auths; | |||||
288 | client->auth_generation = 0; | |||||
289 | ret = CheckClientAuthorization(client, client_auth, | |||||
290 | &auth_accept, &auth_index, &auth_len, &server_auth_data); | |||||
291 | if (auth_index > 0) | |||||
292 | { | |||||
293 | AuthContextPtr authp; | |||||
294 | authp = (AuthContextPtr) fsalloc(sizeof(AuthContextRec))FSalloc((unsigned long)sizeof(AuthContextRec)); | |||||
295 | if (!authp) { | |||||
296 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); | |||||
297 | DEALLOCATE_LOCAL(client_auth)do {} while(0); | |||||
298 | return FSBadAlloc9; | |||||
299 | } | |||||
300 | authp->authname = | |||||
301 | (char *) fsalloc(client_auth[auth_index - 1].namelen + 1)FSalloc((unsigned long)client_auth[auth_index - 1].namelen + 1 ); | |||||
302 | authp->authdata = | |||||
303 | (char *) fsalloc(client_auth[auth_index - 1].datalen + 1)FSalloc((unsigned long)client_auth[auth_index - 1].datalen + 1 ); | |||||
304 | if (!authp->authname || !authp->authdata) { | |||||
305 | fsfree((char *) authp->authname)FSfree((pointer)(char *) authp->authname); | |||||
306 | fsfree((char *) authp->authdata)FSfree((pointer)(char *) authp->authdata); | |||||
307 | fsfree((char *) authp)FSfree((pointer)(char *) authp); | |||||
308 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); | |||||
309 | DEALLOCATE_LOCAL(client_auth)do {} while(0); | |||||
310 | return FSBadAlloc9; | |||||
311 | } | |||||
312 | memmove( authp->authname, client_auth[auth_index - 1].name,__builtin___memmove_chk (authp->authname, client_auth[auth_index - 1].name, client_auth[auth_index - 1].namelen, __builtin_object_size (authp->authname, 0)) | |||||
313 | client_auth[auth_index - 1].namelen)__builtin___memmove_chk (authp->authname, client_auth[auth_index - 1].name, client_auth[auth_index - 1].namelen, __builtin_object_size (authp->authname, 0)); | |||||
314 | memmove( authp->authdata, client_auth[auth_index - 1].data,__builtin___memmove_chk (authp->authdata, client_auth[auth_index - 1].data, client_auth[auth_index - 1].datalen, __builtin_object_size (authp->authdata, 0)) | |||||
315 | client_auth[auth_index - 1].datalen)__builtin___memmove_chk (authp->authdata, client_auth[auth_index - 1].data, client_auth[auth_index - 1].datalen, __builtin_object_size (authp->authdata, 0)); | |||||
316 | /* Save it with a zero resource id... subsequent | |||||
317 | SetAuthorizations of None will find it. And it will be freed | |||||
318 | by FreeClientResources when the connection closes. */ | |||||
319 | if (!AddResource(client->index, 0, RT_AUTHCONT((RESTYPE)2),(pointer) authp)) | |||||
320 | { | |||||
321 | fsfree((char *) authp->authname)FSfree((pointer)(char *) authp->authname); | |||||
322 | fsfree((char *) authp->authdata)FSfree((pointer)(char *) authp->authdata); | |||||
323 | fsfree((char *) authp)FSfree((pointer)(char *) authp); | |||||
324 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); | |||||
325 | DEALLOCATE_LOCAL(client_auth)do {} while(0); | |||||
326 | return FSBadAlloc9; | |||||
327 | } | |||||
328 | client->auth = client->default_auth = authp; | |||||
329 | } | |||||
330 | else | |||||
331 | client->auth = client->default_auth = (AuthContextPtr)0; | |||||
332 | ||||||
333 | DEALLOCATE_LOCAL(client_auth)do {} while(0); | |||||
334 | ||||||
335 | if (ret != FSSuccess-1) { | |||||
336 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); | |||||
337 | return FSBadAlloc9; | |||||
338 | } | |||||
339 | else { | |||||
340 | fsConnSetup csp = { | |||||
341 | .status = auth_accept, | |||||
342 | /* we implement backwards compatibility for version 1.0 */ | |||||
343 | .major_version = (client->major_version == 1) ? | |||||
344 | client->major_version : FS_PROTOCOL2, | |||||
345 | .minor_version = FS_PROTOCOL_MINOR0, | |||||
346 | .num_alternates = num_alts, | |||||
347 | .alternate_len = altlen, | |||||
348 | .auth_len = auth_len >> 2, | |||||
349 | .auth_index = auth_index | |||||
350 | }; | |||||
351 | if (client->swapped) { | |||||
352 | WriteSConnSetup(client, &csp); | |||||
353 | } else { | |||||
354 | (void) WriteToClient(client, SIZEOF(fsConnSetup)12, (char *) &csp); | |||||
355 | } | |||||
356 | } | |||||
357 | ||||||
358 | /* send the alternates info */ | |||||
359 | for (i = 0; i < num_alts; i++) { | |||||
360 | char tmp[258]; | |||||
361 | ||||||
362 | /* WriteToClient pads, so we have to fake some things */ | |||||
363 | tmp[0] = altservers[i].subset; | |||||
364 | tmp[1] = altservers[i].namelen; | |||||
365 | memmove( (char *) &tmp[2], altservers[i].name, altservers[i].namelen)__builtin___memmove_chk ((char *) &tmp[2], altservers[i]. name, altservers[i].namelen, __builtin_object_size ((char *) & tmp[2], 0)); | |||||
366 | (void) WriteToClient(client, altservers[i].namelen + 2, tmp); | |||||
367 | } | |||||
368 | ||||||
369 | if (auth_len) | |||||
370 | (void) WriteToClient(client, auth_len, (char *) server_auth_data); | |||||
371 | ||||||
372 | if (auth_accept != AuthSuccess0) { | |||||
373 | nClients--; | |||||
374 | return (client->noClientException = -2); | |||||
375 | } | |||||
376 | client->requestVector = client->swapped ? SwappedProcVector : ProcVector; | |||||
377 | client->sequence = 0; | |||||
378 | if (client->swapped) | |||||
379 | (void) WriteSConnectionInfo(client, ConnInfoLen, ConnectionInfo); | |||||
380 | else | |||||
381 | (void) WriteToClient(client, ConnInfoLen, ConnectionInfo); | |||||
382 | ||||||
383 | #ifdef DEBUG | |||||
384 | fprintf(stderr__stderrp, "Establishing new connection\n"); | |||||
385 | #endif | |||||
386 | ||||||
387 | return client->noClientException; | |||||
388 | } | |||||
389 | ||||||
390 | /* | |||||
391 | * NOTE -- the incoming data may be mangled | |||||
392 | */ | |||||
393 | ||||||
394 | void | |||||
395 | DoSendErrToClient( | |||||
396 | ClientPtr client, | |||||
397 | int error, | |||||
398 | pointer data) /* resource id, format, resolution, etc */ | |||||
399 | { | |||||
400 | fsError rep = { | |||||
401 | .type = FS_Error1, | |||||
402 | .request = error, | |||||
403 | .sequenceNumber = client->sequence, | |||||
404 | .timestamp = GetTimeInMillis(), | |||||
405 | .major_opcode = ((fsReq *) client->requestBuffer)->reqType, | |||||
406 | .minor_opcode = 0 | |||||
407 | }; | |||||
408 | int extralen = 0; | |||||
409 | ||||||
410 | switch (error) { | |||||
411 | case FSBadFormat1: | |||||
412 | extralen = SIZEOF(fsBitmapFormat)4; | |||||
413 | break; | |||||
414 | case FSBadFont2: | |||||
415 | case FSBadAccessContext5: | |||||
416 | case FSBadIDChoice6: | |||||
417 | case FSBadEventMask4: | |||||
418 | if (data) { | |||||
419 | if (client->swapped) | |||||
420 | SwapLongs((long *) data, 1); | |||||
421 | extralen = 4; | |||||
422 | } | |||||
423 | break; | |||||
424 | case FSBadRange3: | |||||
425 | extralen = SIZEOF(fsRange)4; | |||||
426 | break; | |||||
427 | case FSBadResolution8: | |||||
428 | if (data) { | |||||
429 | if (client->swapped) | |||||
430 | SwapShorts((short *) data, 1); | |||||
431 | /* note sneaky hack */ | |||||
432 | rep.pad = *(CARD16 *) data; | |||||
433 | data = (char *)data + 2; | |||||
434 | extralen = 4; | |||||
435 | } | |||||
436 | break; | |||||
437 | case FSBadLength10: | |||||
438 | if (data) { | |||||
439 | if (client->swapped) | |||||
440 | SwapLongs((long *) data, 1); | |||||
441 | extralen = 4; | |||||
442 | } | |||||
443 | break; | |||||
444 | default: | |||||
445 | /* nothing else to send */ | |||||
446 | break; | |||||
447 | } | |||||
448 | ||||||
449 | rep.length = (SIZEOF(fsError)16 + extralen) >> 2; | |||||
450 | ||||||
451 | WriteErrorToClient(client, &rep); | |||||
452 | ||||||
453 | if (extralen) | |||||
454 | WriteToClient(client, extralen, (char *) data); | |||||
455 | } | |||||
456 | ||||||
457 | /* ARGSUSED */ | |||||
458 | int | |||||
459 | ProcBadRequest(ClientPtr client) | |||||
460 | { | |||||
461 | SendErrToClientDoSendErrToClient(client, FSBadRequest0, NULL((void *)0)); | |||||
462 | return FSBadRequest0; | |||||
463 | } | |||||
464 | ||||||
465 | int | |||||
466 | ProcNoop(ClientPtr client) | |||||
467 | { | |||||
468 | REQUEST(fsReq)fsReq *stuff = (fsReq *)client->requestBuffer; | |||||
469 | REQUEST_AT_LEAST_SIZE(fsReq)if ((4 >> 2) > stuff->length) { int lengthword = stuff ->length; DoSendErrToClient(client, 10, (pointer)&lengthword ); return (10); }; | |||||
470 | ||||||
471 | return client->noClientException; | |||||
472 | } | |||||
473 | ||||||
474 | int | |||||
475 | ProcListCatalogues(ClientPtr client) | |||||
476 | { | |||||
477 | int len, | |||||
478 | num; | |||||
479 | char *catalogues; | |||||
480 | fsListCataloguesReply rep = { | |||||
481 | .type = FS_Reply0, | |||||
482 | .sequenceNumber = client->sequence, | |||||
483 | .num_replies = 0 | |||||
484 | }; | |||||
485 | ||||||
486 | REQUEST(fsListCataloguesReq)fsListCataloguesReq *stuff = (fsListCataloguesReq *)client-> requestBuffer; | |||||
487 | REQUEST_AT_LEAST_SIZE(fsListCataloguesReq)if ((12 >> 2) > stuff->length) { int lengthword = stuff->length; DoSendErrToClient(client, 10, (pointer)& lengthword); return (10); }; | |||||
488 | ||||||
489 | num = ListCatalogues((char *)stuff + SIZEOF(fsListCataloguesReq)12, | |||||
490 | stuff->nbytes, stuff->maxNames, | |||||
491 | &catalogues, &len); | |||||
492 | rep.num_catalogues = num; | |||||
493 | rep.length = (SIZEOF(fsListCataloguesReply)16 + len + 3) >> 2; | |||||
494 | ||||||
495 | WriteReplyToClient(client, SIZEOF(fsListCataloguesReply), &rep)if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)(16), &rep ); else (void)WriteToClient(client, (int)(16), (char *)(& rep));; | |||||
496 | (void) WriteToClient(client, len, (char *) catalogues); | |||||
497 | fsfree((char *) catalogues)FSfree((pointer)(char *) catalogues); | |||||
498 | return client->noClientException; | |||||
499 | } | |||||
500 | ||||||
501 | int | |||||
502 | ProcSetCatalogues(ClientPtr client) | |||||
503 | { | |||||
504 | char *new_cat; | |||||
505 | int err, | |||||
506 | len; | |||||
507 | int num; | |||||
508 | ||||||
509 | REQUEST(fsSetCataloguesReq)fsSetCataloguesReq *stuff = (fsSetCataloguesReq *)client-> requestBuffer; | |||||
510 | REQUEST_AT_LEAST_SIZE(fsSetCataloguesReq)if ((4 >> 2) > stuff->length) { int lengthword = stuff ->length; DoSendErrToClient(client, 10, (pointer)&lengthword ); return (10); }; | |||||
511 | ||||||
512 | if (stuff->num_catalogues == 0) { | |||||
513 | /* use the default */ | |||||
514 | num = ListCatalogues("*", 1, 10000, &new_cat, &len); | |||||
515 | } else { | |||||
516 | num = stuff->num_catalogues; | |||||
517 | err = ValidateCatalogues(&num, (char *)stuff + SIZEOF(fsSetCataloguesReq)4); | |||||
518 | if (err == FSSuccess-1) { | |||||
519 | len = (stuff->length << 2) - SIZEOF(fsSetCataloguesReq)4; | |||||
520 | new_cat = (char *) fsalloc(len)FSalloc((unsigned long)len); | |||||
521 | if (!new_cat) | |||||
522 | return FSBadAlloc9; | |||||
523 | memmove( new_cat, (char *)stuff + SIZEOF(fsSetCataloguesReq), len)__builtin___memmove_chk (new_cat, (char *)stuff + 4, len, __builtin_object_size (new_cat, 0)); | |||||
524 | } else { | |||||
525 | SendErrToClientDoSendErrToClient(client, err, (pointer) &num); | |||||
526 | return err; | |||||
527 | } | |||||
528 | } | |||||
529 | if (client->catalogues) | |||||
530 | fsfree((char *) client->catalogues)FSfree((pointer)(char *) client->catalogues); | |||||
531 | client->catalogues = new_cat; | |||||
532 | client->num_catalogues = num; | |||||
533 | return client->noClientException; | |||||
534 | } | |||||
535 | ||||||
536 | int | |||||
537 | ProcGetCatalogues(ClientPtr client) | |||||
538 | { | |||||
539 | int len, | |||||
540 | i, | |||||
541 | size; | |||||
542 | char *cp; | |||||
543 | ||||||
544 | REQUEST(fsGetCataloguesReq)fsGetCataloguesReq *stuff = (fsGetCataloguesReq *)client-> requestBuffer; | |||||
545 | REQUEST_AT_LEAST_SIZE(fsGetCataloguesReq)if ((4 >> 2) > stuff->length) { int lengthword = stuff ->length; DoSendErrToClient(client, 10, (pointer)&lengthword ); return (10); }; | |||||
546 | ||||||
547 | for (i = 0, len = 0, cp = client->catalogues; | |||||
548 | i < client->num_catalogues; i++) { | |||||
549 | size = *cp++; | |||||
550 | len += size + 1; /* str length + size byte */ | |||||
551 | cp += size; | |||||
552 | } | |||||
553 | ||||||
554 | { | |||||
555 | fsGetCataloguesReply rep = { | |||||
556 | .type = FS_Reply0, | |||||
557 | .num_catalogues = client->num_catalogues, | |||||
558 | .sequenceNumber = client->sequence, | |||||
559 | .length = (SIZEOF(fsGetCataloguesReply)8 + len + 3) >> 2 | |||||
560 | }; | |||||
561 | ||||||
562 | WriteReplyToClient(client, SIZEOF(fsGetCataloguesReply), &rep)if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)(8), &rep ); else (void)WriteToClient(client, (int)(8), (char *)(&rep ));; | |||||
563 | } | |||||
564 | (void) WriteToClient(client, len, client->catalogues); | |||||
565 | ||||||
566 | return client->noClientException; | |||||
567 | } | |||||
568 | ||||||
569 | int | |||||
570 | ProcCreateAC(ClientPtr client) | |||||
571 | { | |||||
572 | AuthPtr acp; | |||||
573 | AuthContextPtr authp; | |||||
574 | int accept, | |||||
575 | i, | |||||
576 | err, | |||||
577 | index, | |||||
578 | size; | |||||
579 | char *ad; | |||||
580 | char *auth_data; | |||||
581 | ||||||
582 | REQUEST(fsCreateACReq)fsCreateACReq *stuff = (fsCreateACReq *)client->requestBuffer; | |||||
583 | REQUEST_AT_LEAST_SIZE(fsCreateACReq)if ((8 >> 2) > stuff->length) { int lengthword = stuff ->length; DoSendErrToClient(client, 10, (pointer)&lengthword ); return (10); }; | |||||
584 | ||||||
585 | authp = (AuthContextPtr) LookupIDByType(client->index, stuff->acid, | |||||
586 | RT_AUTHCONT((RESTYPE)2)); | |||||
587 | if (authp) { | |||||
| ||||||
588 | int aligned_acid = stuff->acid; | |||||
589 | SendErrToClientDoSendErrToClient(client, FSBadIDChoice6, (pointer) &aligned_acid); | |||||
590 | return FSBadIDChoice6; | |||||
591 | } | |||||
592 | acp = NULL((void *)0); | |||||
593 | if (stuff->num_auths) | |||||
594 | { | |||||
595 | acp = (AuthPtr) ALLOCATE_LOCAL(stuff->num_auths * sizeof(AuthRec))__builtin_alloca((int)(stuff->num_auths * sizeof(AuthRec)) ); | |||||
596 | if (!acp) { | |||||
597 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) NULL((void *)0)); | |||||
598 | return FSBadAlloc9; | |||||
599 | } | |||||
600 | } | |||||
601 | /* build up a list of the stuff */ | |||||
602 | for (i = 0, ad = (char *)stuff + SIZEOF(fsCreateACReq)8; | |||||
603 | i < (int)stuff->num_auths; i++) { | |||||
604 | if (ad - (char *)stuff + SIZEOF(fsCreateACReq)8 > | |||||
605 | (stuff->length << 2) - 4) { | |||||
606 | int lengthword = stuff->length; | |||||
607 | ||||||
608 | SendErrToClientDoSendErrToClient(client, FSBadLength10, (pointer)&lengthword); | |||||
609 | DEALLOCATE_LOCAL(acp)do {} while(0); | |||||
610 | return (FSBadLength10); | |||||
611 | } | |||||
612 | /* copy carefully in case data is not aligned */ | |||||
613 | acp[i].namelen = (((unsigned char *)ad)[0] << 8) + | |||||
614 | ((unsigned char *)ad)[1]; | |||||
615 | ad += 2; | |||||
616 | acp[i].datalen = (((unsigned char *)ad)[0] << 8) + | |||||
617 | ((unsigned char *)ad)[1]; | |||||
618 | ad += 2; | |||||
619 | acp[i].name = (char *) ad; | |||||
620 | ad += acp[i].namelen; | |||||
621 | acp[i].data = (char *) ad; | |||||
622 | ad += acp[i].datalen; | |||||
623 | } | |||||
624 | if (ad - (char *)stuff > (stuff->length << 2)) { | |||||
625 | int lengthword = stuff->length; | |||||
626 | ||||||
627 | SendErrToClientDoSendErrToClient(client, FSBadLength10, (pointer)&lengthword); | |||||
628 | if (acp) | |||||
629 | DEALLOCATE_LOCAL(acp)do {} while(0); | |||||
630 | return (FSBadLength10); | |||||
631 | } | |||||
632 | ||||||
633 | /* XXX needs work for AuthContinue */ | |||||
634 | index = stuff->num_auths; | |||||
635 | err = CheckClientAuthorization(client, acp, &accept, &index, &size, | |||||
636 | &auth_data); | |||||
637 | ||||||
638 | if (err != FSSuccess-1) { | |||||
639 | SendErrToClientDoSendErrToClient(client, err, (pointer) 0); | |||||
640 | if (acp) | |||||
641 | DEALLOCATE_LOCAL(acp)do {} while(0); | |||||
642 | return err; | |||||
643 | } | |||||
644 | authp = (AuthContextPtr) fsalloc(sizeof(AuthContextRec))FSalloc((unsigned long)sizeof(AuthContextRec)); | |||||
645 | if (!authp) { | |||||
646 | goto alloc_failure; | |||||
647 | } | |||||
648 | authp->authname = NULL((void *)0); | |||||
649 | authp->authdata = NULL((void *)0); | |||||
650 | if (index > 0) | |||||
651 | { | |||||
652 | authp->authname = (char *) fsalloc(acp[index - 1].namelen + 1)FSalloc((unsigned long)acp[index - 1].namelen + 1); | |||||
| ||||||
653 | authp->authdata = (char *) fsalloc(acp[index - 1].datalen + 1)FSalloc((unsigned long)acp[index - 1].datalen + 1); | |||||
654 | if (!authp->authname || !authp->authdata) { | |||||
655 | fsfree((char *) authp->authname)FSfree((pointer)(char *) authp->authname); | |||||
656 | fsfree((char *) authp->authdata)FSfree((pointer)(char *) authp->authdata); | |||||
657 | fsfree((char *) authp)FSfree((pointer)(char *) authp); | |||||
658 | goto alloc_failure; | |||||
659 | } | |||||
660 | memmove( authp->authname, acp[index - 1].name, acp[index - 1].namelen)__builtin___memmove_chk (authp->authname, acp[index - 1].name , acp[index - 1].namelen, __builtin_object_size (authp->authname , 0)); | |||||
661 | memmove( authp->authdata, acp[index - 1].data, acp[index - 1].datalen)__builtin___memmove_chk (authp->authdata, acp[index - 1].data , acp[index - 1].datalen, __builtin_object_size (authp->authdata , 0)); | |||||
662 | } | |||||
663 | else | |||||
664 | size = 0; | |||||
665 | authp->acid = stuff->acid; | |||||
666 | if (!AddResource(client->index, stuff->acid, RT_AUTHCONT((RESTYPE)2),(pointer) authp)) | |||||
667 | { | |||||
668 | alloc_failure: | |||||
669 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); | |||||
670 | if (acp) | |||||
671 | DEALLOCATE_LOCAL(acp)do {} while(0); | |||||
672 | return FSBadAlloc9; | |||||
673 | } | |||||
674 | DEALLOCATE_LOCAL(acp)do {} while(0); | |||||
675 | { | |||||
676 | fsCreateACReply rep = { | |||||
677 | .type = FS_Reply0, | |||||
678 | .auth_index = index, | |||||
679 | .sequenceNumber = client->sequence, | |||||
680 | .status = accept, | |||||
681 | .length = (SIZEOF(fsCreateACReply)12 + size) >> 2 | |||||
682 | }; | |||||
683 | ||||||
684 | WriteReplyToClient(client, SIZEOF(fsCreateACReply), &rep)if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)(12), &rep ); else (void)WriteToClient(client, (int)(12), (char *)(& rep));; | |||||
685 | } | |||||
686 | if (size) | |||||
687 | (void) WriteToClient(client, size, auth_data); | |||||
688 | ||||||
689 | return client->noClientException; | |||||
690 | } | |||||
691 | ||||||
692 | /* ARGSUSED */ | |||||
693 | int | |||||
694 | DeleteAuthCont (pointer value, FSID id) | |||||
695 | { | |||||
696 | AuthContextPtr authp = (AuthContextPtr) value; | |||||
697 | ||||||
698 | if (authp->authname) | |||||
699 | fsfree (authp->authname)FSfree((pointer)authp->authname); | |||||
700 | if (authp->authdata) | |||||
701 | fsfree (authp->authdata)FSfree((pointer)authp->authdata); | |||||
702 | fsfree (authp)FSfree((pointer)authp); | |||||
703 | return 1; | |||||
704 | } | |||||
705 | ||||||
706 | int | |||||
707 | ProcFreeAC(ClientPtr client) | |||||
708 | { | |||||
709 | AuthContextPtr authp; | |||||
710 | ||||||
711 | REQUEST(fsFreeACReq)fsFreeACReq *stuff = (fsFreeACReq *)client->requestBuffer; | |||||
712 | REQUEST_AT_LEAST_SIZE(fsFreeACReq)if ((8 >> 2) > stuff->length) { int lengthword = stuff ->length; DoSendErrToClient(client, 10, (pointer)&lengthword ); return (10); }; | |||||
713 | authp = (AuthContextPtr) LookupIDByType(client->index, stuff->id, | |||||
714 | RT_AUTHCONT((RESTYPE)2)); | |||||
715 | if (!authp) { | |||||
716 | int aligned_id = stuff->id; | |||||
717 | SendErrToClientDoSendErrToClient(client, FSBadIDChoice6, (pointer) &aligned_id); | |||||
718 | return FSBadIDChoice6; | |||||
719 | } | |||||
720 | if (client->auth == authp) | |||||
721 | client->auth = client->default_auth; | |||||
722 | FreeResource(client->index, stuff->id, RT_NONE((RESTYPE)0)); | |||||
723 | return client->noClientException; | |||||
724 | } | |||||
725 | ||||||
726 | int | |||||
727 | ProcSetAuthorization(ClientPtr client) | |||||
728 | { | |||||
729 | AuthContextPtr acp; | |||||
730 | ||||||
731 | REQUEST(fsSetAuthorizationReq)fsSetAuthorizationReq *stuff = (fsSetAuthorizationReq *)client ->requestBuffer; | |||||
732 | REQUEST_AT_LEAST_SIZE(fsSetAuthorizationReq)if ((8 >> 2) > stuff->length) { int lengthword = stuff ->length; DoSendErrToClient(client, 10, (pointer)&lengthword ); return (10); }; | |||||
733 | acp = (AuthContextPtr) LookupIDByType(client->index, stuff->id, | |||||
734 | RT_AUTHCONT((RESTYPE)2)); | |||||
735 | if (!acp) { | |||||
736 | int aligned_id = stuff->id; | |||||
737 | SendErrToClientDoSendErrToClient(client, FSBadIDChoice6, (pointer) &aligned_id); | |||||
738 | return FSBadIDChoice6; | |||||
739 | } | |||||
740 | client->auth = acp; /* XXX does this need a refcount? */ | |||||
741 | return client->noClientException; | |||||
742 | } | |||||
743 | ||||||
744 | int | |||||
745 | ProcSetResolution(ClientPtr client) | |||||
746 | { | |||||
747 | fsResolution *new_res; | |||||
748 | ||||||
749 | REQUEST(fsSetResolutionReq)fsSetResolutionReq *stuff = (fsSetResolutionReq *)client-> requestBuffer; | |||||
750 | REQUEST_AT_LEAST_SIZE(fsSetResolutionReq)if ((4 >> 2) > stuff->length) { int lengthword = stuff ->length; DoSendErrToClient(client, 10, (pointer)&lengthword ); return (10); }; | |||||
751 | ||||||
752 | if ((stuff->length << 2) - SIZEOF(fsSetResolutionReq)4 < | |||||
753 | stuff->num_resolutions * SIZEOF(fsResolution)6) { | |||||
754 | int lengthword = stuff->length; | |||||
755 | ||||||
756 | SendErrToClientDoSendErrToClient(client, FSBadLength10, &lengthword); | |||||
757 | return FSBadLength10; | |||||
758 | } | |||||
759 | new_res = (fsResolution *) | |||||
760 | fsalloc(SIZEOF(fsResolution) * stuff->num_resolutions)FSalloc((unsigned long)6 * stuff->num_resolutions); | |||||
761 | if (!new_res) { | |||||
762 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, NULL((void *)0)); | |||||
763 | return FSBadAlloc9; | |||||
764 | } | |||||
765 | fsfree((char *) client->resolutions)FSfree((pointer)(char *) client->resolutions); | |||||
766 | memmove( (char *) new_res, (char *)stuff + SIZEOF(fsSetResolutionReq),__builtin___memmove_chk ((char *) new_res, (char *)stuff + 4, (stuff->num_resolutions * 6), __builtin_object_size ((char *) new_res, 0)) | |||||
767 | (stuff->num_resolutions * SIZEOF(fsResolution)))__builtin___memmove_chk ((char *) new_res, (char *)stuff + 4, (stuff->num_resolutions * 6), __builtin_object_size ((char *) new_res, 0)); | |||||
768 | client->resolutions = new_res; | |||||
769 | client->num_resolutions = stuff->num_resolutions; | |||||
770 | ||||||
771 | return client->noClientException; | |||||
772 | } | |||||
773 | ||||||
774 | int | |||||
775 | ProcGetResolution(ClientPtr client) | |||||
776 | { | |||||
777 | REQUEST(fsReq)fsReq *stuff = (fsReq *)client->requestBuffer; | |||||
778 | REQUEST_AT_LEAST_SIZE(fsReq)if ((4 >> 2) > stuff->length) { int lengthword = stuff ->length; DoSendErrToClient(client, 10, (pointer)&lengthword ); return (10); }; | |||||
779 | ||||||
780 | if ((stuff->length << 2) - SIZEOF(fsResolution)6 < client->num_resolutions * | |||||
781 | sizeof(fsResolution)) { | |||||
782 | int lengthword = stuff->length; | |||||
783 | ||||||
784 | SendErrToClientDoSendErrToClient(client, FSBadLength10, &lengthword); | |||||
785 | return FSBadLength10; | |||||
786 | } | |||||
787 | else { | |||||
788 | fsGetResolutionReply reply = { | |||||
789 | .type = FS_Reply0, | |||||
790 | .num_resolutions = client->num_resolutions, | |||||
791 | .sequenceNumber = client->sequence, | |||||
792 | .length = (SIZEOF(fsGetResolutionReply)8 + | |||||
793 | client->num_resolutions * SIZEOF(fsResolution)6) >> 2 | |||||
794 | }; | |||||
795 | ||||||
796 | WriteReplyToClient(client, SIZEOF(fsGetResolutionReply), &reply)if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)(8), &reply ); else (void)WriteToClient(client, (int)(8), (char *)(&reply ));; | |||||
797 | } | |||||
798 | if (client->swapped) | |||||
799 | client->pSwapReplyFunc = CopySwap16Write; | |||||
800 | ||||||
801 | WriteSwappedDataToClient(client,if ((client)->swapped) (*(client)->pSwapReplyFunc)(client , (int)((client->num_resolutions * 6)), (short *)client-> resolutions); else (void) WriteToClient(client, (int)((client ->num_resolutions * 6)), (char *)((short *)client->resolutions )); | |||||
802 | (client->num_resolutions * SIZEOF(fsResolution)), (short *)client->resolutions)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client , (int)((client->num_resolutions * 6)), (short *)client-> resolutions); else (void) WriteToClient(client, (int)((client ->num_resolutions * 6)), (char *)((short *)client->resolutions ));; | |||||
803 | ||||||
804 | return client->noClientException; | |||||
805 | } | |||||
806 | ||||||
807 | int | |||||
808 | ProcListFonts(ClientPtr client) | |||||
809 | { | |||||
810 | REQUEST(fsListFontsReq)fsListFontsReq *stuff = (fsListFontsReq *)client->requestBuffer; | |||||
811 | REQUEST_FIXED_SIZE(fsListFontsReq, stuff->nbytes)if (((12 >> 2) > stuff->length) || (((12 + (stuff ->nbytes) + 3) >> 2) != stuff->length)) { int lengthword = stuff->length; DoSendErrToClient(client, 10, (pointer)& lengthword); return (10); }; | |||||
812 | ||||||
813 | return ListFonts(client, stuff->nbytes, | |||||
814 | (unsigned char *)stuff + SIZEOF(fsListFontsReq)12, | |||||
815 | stuff->maxNames); | |||||
816 | } | |||||
817 | ||||||
818 | int | |||||
819 | ProcListFontsWithXInfo(ClientPtr client) | |||||
820 | { | |||||
821 | REQUEST(fsListFontsWithXInfoReq)fsListFontsWithXInfoReq *stuff = (fsListFontsWithXInfoReq *)client ->requestBuffer; | |||||
822 | REQUEST_FIXED_SIZE(fsListFontsWithXInfoReq, stuff->nbytes)if (((12 >> 2) > stuff->length) || (((12 + (stuff ->nbytes) + 3) >> 2) != stuff->length)) { int lengthword = stuff->length; DoSendErrToClient(client, 10, (pointer)& lengthword); return (10); }; | |||||
823 | ||||||
824 | return StartListFontsWithInfo(client, stuff->nbytes, | |||||
825 | (unsigned char *)stuff + SIZEOF(fsListFontsWithXInfoReq)12, stuff->maxNames); | |||||
826 | } | |||||
827 | ||||||
828 | int | |||||
829 | ProcOpenBitmapFont(ClientPtr client) | |||||
830 | { | |||||
831 | FontPtr pfont; | |||||
832 | int nbytes, | |||||
833 | err; | |||||
834 | unsigned char *fname; | |||||
835 | ||||||
836 | REQUEST(fsOpenBitmapFontReq)fsOpenBitmapFontReq *stuff = (fsOpenBitmapFontReq *)client-> requestBuffer; | |||||
837 | fname = (unsigned char *)stuff + SIZEOF(fsOpenBitmapFontReq)16; | |||||
838 | nbytes = *fname++; | |||||
839 | ||||||
840 | REQUEST_FIXED_SIZE(fsOpenBitmapFontReq, (nbytes + 1))if (((16 >> 2) > stuff->length) || (((16 + ((nbytes + 1)) + 3) >> 2) != stuff->length)) { int lengthword = stuff->length; DoSendErrToClient(client, 10, (pointer)& lengthword); return (10); }; | |||||
841 | ||||||
842 | pfont = (FontPtr) LookupIDByType(client->index, stuff->fid, RT_FONT((RESTYPE)1)); | |||||
843 | if (pfont) { | |||||
844 | int aligned_fid = stuff->fid; | |||||
845 | SendErrToClientDoSendErrToClient(client, FSBadIDChoice6, (pointer) &aligned_fid); | |||||
846 | return FSBadIDChoice6; | |||||
847 | } | |||||
848 | if (stuff->format_hint != 0 && | |||||
849 | stuff->format_hint & ~ALL_FORMAT_BITS((1L << 0) | (1L << 1) | (3L << 12) | (3L << 8) | (3L << 2))) { | |||||
850 | int aligned_format_hint = stuff->format_hint; | |||||
851 | SendErrToClientDoSendErrToClient(client, FSBadFormat1, (pointer) &aligned_format_hint); | |||||
852 | return FSBadFormat1; | |||||
853 | } | |||||
854 | if (stuff->format_mask & ~ALL_FORMAT_MASK_BITS((1L << 0) | (1L << 1) | (1L << 2) | (1L << 3) | (1L << 4))) { | |||||
855 | int aligned_format_mask = stuff->format_mask; | |||||
856 | SendErrToClientDoSendErrToClient(client, FSBadFormat1, (pointer) &aligned_format_mask); | |||||
857 | return FSBadFormat1; | |||||
858 | } | |||||
859 | err = OpenFont(client, stuff->fid, stuff->format_hint, stuff->format_mask, | |||||
860 | nbytes, (char *) fname); | |||||
861 | ||||||
862 | if (err == FSSuccess-1) { | |||||
863 | return client->noClientException; | |||||
864 | } else { | |||||
865 | return err; | |||||
866 | } | |||||
867 | } | |||||
868 | ||||||
869 | int | |||||
870 | ProcQueryXInfo(ClientPtr client) | |||||
871 | { | |||||
872 | ClientFontPtr cfp; | |||||
873 | int err, | |||||
874 | lendata; | |||||
875 | fsQueryXInfoReply reply = { | |||||
876 | .type = FS_Reply0, | |||||
877 | .sequenceNumber = client->sequence | |||||
878 | }; | |||||
879 | fsPropInfo *prop_info; | |||||
880 | ||||||
881 | REQUEST(fsQueryXInfoReq)fsQueryXInfoReq *stuff = (fsQueryXInfoReq *)client->requestBuffer; | |||||
882 | ||||||
883 | REQUEST_AT_LEAST_SIZE(fsQueryXInfoReq)if ((8 >> 2) > stuff->length) { int lengthword = stuff ->length; DoSendErrToClient(client, 10, (pointer)&lengthword ); return (10); }; | |||||
884 | ||||||
885 | cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->id, RT_FONT((RESTYPE)1)); | |||||
886 | if (!cfp) { | |||||
887 | int aligned_id = stuff->id; | |||||
888 | SendErrToClientDoSendErrToClient(client, FSBadFont2, (pointer) &aligned_id); | |||||
889 | return FSBadFont2; | |||||
890 | } | |||||
891 | ||||||
892 | /* get the header */ | |||||
893 | fsPack_XFontInfoHeader(&cfp->font->info, &reply, client->major_version)(&reply)->font_header_flags = ((&cfp->font-> info)->allExist) ? (1L << 0) : 0; (&reply)->font_header_draw_direction = ((&cfp->font->info)->drawDirection == 0) ? 0 : 1; if ((&cfp->font->info)->inkInside) (&reply )->font_header_flags |= (1L << 1); if (client->major_version > 1) { (&reply)->font_hdr_char_range_min_char_high = (&cfp->font->info)->firstRow; (&reply)-> font_hdr_char_range_min_char_low = (&cfp->font->info )->firstCol; (&reply)->font_hdr_char_range_max_char_high = (&cfp->font->info)->lastRow; (&reply)-> font_hdr_char_range_max_char_low = (&cfp->font->info )->lastCol; (&reply)->font_header_default_char_high = (&cfp->font->info)->defaultCh >> 8; (& reply)->font_header_default_char_low = (&cfp->font-> info)->defaultCh & 0xff; } else { (&reply)->font_hdr_char_range_min_char_high = (&cfp->font->info)->firstCol; (&reply)-> font_hdr_char_range_min_char_low = (&cfp->font->info )->firstRow; (&reply)->font_hdr_char_range_max_char_high = (&cfp->font->info)->lastCol; (&reply)-> font_hdr_char_range_max_char_low = (&cfp->font->info )->lastRow; (&reply)->font_header_default_char_high = (&cfp->font->info)->defaultCh & 0xff; (& reply)->font_header_default_char_low = (&cfp->font-> info)->defaultCh >> 8; } (&reply)->font_header_min_bounds_left = (&(&cfp->font->info)->ink_minbounds)-> leftSideBearing; (&reply)->font_header_min_bounds_right = (&(&cfp->font->info)->ink_minbounds)-> rightSideBearing; (&reply)->font_header_min_bounds_width = (&(&cfp->font->info)->ink_minbounds)-> characterWidth; (&reply)->font_header_min_bounds_ascent = (&(&cfp->font->info)->ink_minbounds)-> ascent; (&reply)->font_header_min_bounds_descent = (& (&cfp->font->info)->ink_minbounds)->descent; ( &reply)->font_header_min_bounds_attributes = (&(& cfp->font->info)->ink_minbounds)->attributes; (& reply)->font_header_max_bounds_left = (&(&cfp-> font->info)->ink_maxbounds)->leftSideBearing; (& reply)->font_header_max_bounds_right = (&(&cfp-> font->info)->ink_maxbounds)->rightSideBearing; (& reply)->font_header_max_bounds_width = (&(&cfp-> font->info)->ink_maxbounds)->characterWidth; (&reply )->font_header_max_bounds_ascent = (&(&cfp->font ->info)->ink_maxbounds)->ascent; (&reply)->font_header_max_bounds_descent = (&(&cfp->font->info)->ink_maxbounds)-> descent; (&reply)->font_header_max_bounds_attributes = (&(&cfp->font->info)->ink_maxbounds)->attributes ; (&reply)->font_header_font_ascent = (&cfp->font ->info)->fontAscent; (&reply)->font_header_font_descent = (&cfp->font->info)->fontDescent; | |||||
894 | err = convert_props(&cfp->font->info, &prop_info); | |||||
895 | ||||||
896 | switch (err) | |||||
897 | { | |||||
898 | case Successful85: | |||||
899 | break; | |||||
900 | case AllocError80: | |||||
901 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); | |||||
902 | return err; | |||||
903 | default: | |||||
904 | ErrorF("ProcQueryXInfo: unexpected return val %d from convert_props\n", | |||||
905 | err); | |||||
906 | SendErrToClientDoSendErrToClient(client, FSBadImplementation11, (pointer) 0); | |||||
907 | return err; | |||||
908 | } | |||||
909 | lendata = SIZEOF(fsPropInfo)8 + | |||||
910 | prop_info->num_offsets * SIZEOF(fsPropOffset)20 + | |||||
911 | prop_info->data_len; | |||||
912 | ||||||
913 | reply.length = (SIZEOF(fsQueryXInfoReply)(8 + 40) + lendata + 3) >> 2; | |||||
914 | WriteReplyToClient(client, SIZEOF(fsQueryXInfoReply), &reply)if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)((8 + 40)), & reply); else (void)WriteToClient(client, (int)((8 + 40)), (char *)(&reply));; | |||||
915 | ||||||
916 | if (client->swapped) | |||||
917 | SwapPropInfo(prop_info); | |||||
918 | (void) WriteToClient(client, lendata, (char *) prop_info); | |||||
919 | ||||||
920 | fsfree((char *) prop_info)FSfree((pointer)(char *) prop_info); | |||||
921 | return client->noClientException; | |||||
922 | } | |||||
923 | ||||||
924 | int | |||||
925 | ProcQueryXExtents(ClientPtr client) | |||||
926 | { | |||||
927 | ClientFontPtr cfp; | |||||
928 | int err; | |||||
929 | int item_size; | |||||
930 | ||||||
931 | REQUEST(fsQueryXExtents8Req)fsQueryXExtents8Req *stuff = (fsQueryXExtents8Req *)client-> requestBuffer; | |||||
932 | ||||||
933 | REQUEST_AT_LEAST_SIZE(fsQueryXExtents8Req)if ((12 >> 2) > stuff->length) { int lengthword = stuff->length; DoSendErrToClient(client, 10, (pointer)& lengthword); return (10); }; | |||||
934 | ||||||
935 | cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->fid, RT_FONT((RESTYPE)1)); | |||||
936 | if (!cfp) { | |||||
937 | int aligned_fid = stuff->fid; | |||||
938 | SendErrToClientDoSendErrToClient(client, FSBadFont2, (pointer) &aligned_fid); | |||||
939 | return FSBadFont2; | |||||
940 | } | |||||
941 | item_size = (stuff->reqType == FS_QueryXExtents817) ? 1 : 2; | |||||
942 | ||||||
943 | if (stuff->num_ranges > | |||||
944 | ((stuff->length << 2) - SIZEOF(fsQueryXExtents8Req)12)/item_size) { | |||||
945 | int num_ranges = stuff->num_ranges; | |||||
946 | SendErrToClientDoSendErrToClient(client, FSBadLength10, (pointer)&num_ranges); | |||||
947 | return FSBadLength10; | |||||
948 | } | |||||
949 | ||||||
950 | /* get the extents */ | |||||
951 | err = QueryExtents(client, cfp, item_size, | |||||
952 | stuff->num_ranges, stuff->range, | |||||
953 | (char *)stuff + SIZEOF(fsQueryXExtents8Req)12); | |||||
954 | ||||||
955 | if (err != FSSuccess-1) { | |||||
956 | return err; | |||||
957 | } else | |||||
958 | return client->noClientException; | |||||
959 | } | |||||
960 | ||||||
961 | int | |||||
962 | ProcQueryXBitmaps(ClientPtr client) | |||||
963 | { | |||||
964 | ClientFontPtr cfp; | |||||
965 | int err; | |||||
966 | int item_size; | |||||
967 | ||||||
968 | REQUEST(fsQueryXBitmaps8Req)fsQueryXBitmaps8Req *stuff = (fsQueryXBitmaps8Req *)client-> requestBuffer; | |||||
969 | ||||||
970 | REQUEST_AT_LEAST_SIZE(fsQueryXBitmaps8Req)if ((16 >> 2) > stuff->length) { int lengthword = stuff->length; DoSendErrToClient(client, 10, (pointer)& lengthword); return (10); }; | |||||
971 | ||||||
972 | cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->fid, RT_FONT((RESTYPE)1)); | |||||
973 | if (!cfp) { | |||||
974 | int aligned_fid = stuff->fid; | |||||
975 | SendErrToClientDoSendErrToClient(client, FSBadFont2, (pointer) &aligned_fid); | |||||
976 | return FSBadFont2; | |||||
977 | } | |||||
978 | if (stuff->format & ~ALL_FORMAT_BITS((1L << 0) | (1L << 1) | (3L << 12) | (3L << 8) | (3L << 2))) { | |||||
979 | int aligned_format = stuff->format; | |||||
980 | SendErrToClientDoSendErrToClient(client, FSBadFormat1, (pointer) &aligned_format); | |||||
981 | return FSBadFormat1; | |||||
982 | } | |||||
983 | assert((stuff->reqType == FS_QueryXBitmaps8) || (stuff->reqType == FS_QueryXBitmaps16))((void)0); | |||||
984 | item_size = (stuff->reqType == FS_QueryXBitmaps819) ? 1 : 2; | |||||
985 | ||||||
986 | if (stuff->num_ranges > | |||||
987 | ((stuff->length << 2) - SIZEOF(fsQueryXBitmaps8Req)16)/item_size) { | |||||
988 | int num_ranges = stuff->num_ranges; | |||||
989 | SendErrToClientDoSendErrToClient(client, FSBadLength10, (pointer)&num_ranges); | |||||
990 | return FSBadLength10; | |||||
991 | } | |||||
992 | /* get the glyphs */ | |||||
993 | err = QueryBitmaps(client, cfp, item_size, stuff->format, | |||||
994 | stuff->num_ranges, stuff->range, | |||||
995 | (char *)stuff + SIZEOF(fsQueryXBitmaps8Req)16); | |||||
996 | ||||||
997 | if (err != FSSuccess-1) { | |||||
998 | return err; | |||||
999 | } else { | |||||
1000 | return client->noClientException; | |||||
1001 | } | |||||
1002 | } | |||||
1003 | ||||||
1004 | int | |||||
1005 | ProcCloseFont(ClientPtr client) | |||||
1006 | { | |||||
1007 | ClientFontPtr cfp; | |||||
1008 | ||||||
1009 | REQUEST(fsResourceReq)fsResourceReq *stuff = (fsResourceReq *)client->requestBuffer; | |||||
1010 | ||||||
1011 | REQUEST_SIZE_MATCH(fsResourceReq)if ((8 >> 2) != stuff->length) { int lengthword = stuff ->length; DoSendErrToClient(client, 10, (pointer)&lengthword ); return (10); }; | |||||
1012 | cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->id, RT_FONT((RESTYPE)1)); | |||||
1013 | if (cfp) { | |||||
1014 | FreeResource(client->index, stuff->id, RT_NONE((RESTYPE)0)); | |||||
1015 | return client->noClientException; | |||||
1016 | } else { | |||||
1017 | int aligned_id = stuff->id; | |||||
1018 | SendErrToClientDoSendErrToClient(client, FSBadFont2, (pointer) &aligned_id); | |||||
1019 | return FSBadFont2; | |||||
1020 | } | |||||
1021 | } | |||||
1022 | ||||||
1023 | void | |||||
1024 | DoCloseDownClient(ClientPtr client) | |||||
1025 | { | |||||
1026 | if (client->clientGone != CLIENT_GONE1) { | |||||
1027 | DeleteClientFontStuff(client); | |||||
1028 | client->clientGone = CLIENT_GONE1; | |||||
1029 | CloseDownConnection(client); | |||||
1030 | --nClients; | |||||
1031 | } | |||||
1032 | ||||||
1033 | if (ClientIsAsleep(client)) | |||||
1034 | ClientSignal((pointer)client); | |||||
1035 | else | |||||
1036 | { | |||||
1037 | FreeClientResources(client); | |||||
1038 | if (client->index < nextFreeClientID) | |||||
1039 | nextFreeClientID = client->index; | |||||
1040 | clients[client->index] = NullClient((ClientPtr) ((void *)0)); | |||||
1041 | #ifdef DebugConnectionTranslation | |||||
1042 | CheckFileNumbers(); | |||||
1043 | #endif /* DebugConnectionTranslation */ | |||||
1044 | ||||||
1045 | ||||||
1046 | if (currentClient == client) | |||||
1047 | currentClient = serverClient; | |||||
1048 | fsfree(client)FSfree((pointer)client); | |||||
1049 | ||||||
1050 | #ifdef DEBUG | |||||
1051 | fprintf(stderr__stderrp, "Shut down client\n"); | |||||
1052 | #endif | |||||
1053 | ||||||
1054 | while (!clients[currentMaxClients - 1]) | |||||
1055 | currentMaxClients--; | |||||
1056 | } | |||||
1057 | } | |||||
1058 | ||||||
1059 | static void | |||||
1060 | kill_all_clients(void) | |||||
1061 | { | |||||
1062 | int i; | |||||
1063 | ||||||
1064 | for (i = MINCLIENT1; i < currentMaxClients; i++) { | |||||
1065 | if (clients[i]) | |||||
1066 | CloseDownClientDoCloseDownClient(clients[i]); | |||||
1067 | } | |||||
1068 | } | |||||
1069 | ||||||
1070 | void | |||||
1071 | InitProcVectors(void) | |||||
1072 | { | |||||
1073 | int i; | |||||
1074 | ||||||
1075 | for (i = 0; i < NUM_PROC_VECTORS25; i++) { | |||||
1076 | if (!ProcVector[i]) { | |||||
1077 | ProcVector[i] = SwappedProcVector[i] = ProcBadRequest; | |||||
1078 | ReplySwapVector[i] = (ReplySwapFunc)NotImplemented; | |||||
1079 | } | |||||
1080 | } | |||||
1081 | for (i = FSLASTEvent3; i < NUM_EVENT_VECTORS8; i++) { | |||||
1082 | EventSwapVector[i] = (EventSwapFunc)NotImplemented; | |||||
1083 | } | |||||
1084 | } | |||||
1085 | ||||||
1086 | void | |||||
1087 | InitClient( | |||||
1088 | ClientPtr client, | |||||
1089 | int i, | |||||
1090 | pointer ospriv) | |||||
1091 | { | |||||
1092 | if (i != SERVER_CLIENT0) { | |||||
1093 | nClients++; | |||||
1094 | } | |||||
1095 | client->index = i; | |||||
1096 | client->sequence = 0; | |||||
1097 | client->last_request_time = GetTimeInMillis(); | |||||
1098 | client->clientGone = CLIENT_ALIVE0; | |||||
1099 | client->noClientException = FSSuccess-1; | |||||
1100 | client->requestVector = InitialVector; | |||||
1101 | client->osPrivate = ospriv; | |||||
1102 | client->swapped = FALSE0; | |||||
1103 | ||||||
1104 | client->auth = (AuthContextPtr) 0; | |||||
1105 | client->catalogues = NULL((void *)0); | |||||
1106 | client->num_catalogues = 0; | |||||
1107 | client->num_resolutions = 0; | |||||
1108 | client->resolutions = (fsResolution *) 0; | |||||
1109 | client->eventmask = (Mask) 0; | |||||
1110 | } | |||||
1111 | ||||||
1112 | ClientPtr | |||||
1113 | NextAvailableClient(pointer ospriv) | |||||
1114 | { | |||||
1115 | int i; | |||||
1116 | ClientPtr client; | |||||
1117 | fsFakeReq data; | |||||
1118 | ||||||
1119 | i = nextFreeClientID; | |||||
1120 | if (i == MaxClients) | |||||
1121 | return NullClient((ClientPtr) ((void *)0)); | |||||
1122 | ||||||
1123 | clients[i] = client = (ClientPtr) fsalloc(sizeof(ClientRec))FSalloc((unsigned long)sizeof(ClientRec)); | |||||
1124 | if (!client) | |||||
1125 | return NullClient((ClientPtr) ((void *)0)); | |||||
1126 | ||||||
1127 | InitClient(client, i, ospriv); | |||||
1128 | ||||||
1129 | if (!InitClientResources(client)) { | |||||
1130 | fsfree(client)FSfree((pointer)client); | |||||
1131 | return NullClient((ClientPtr) ((void *)0)); | |||||
1132 | } | |||||
1133 | data.reqType = 1; | |||||
1134 | data.length = (sizeof(fsFakeReq) + SIZEOF(fsConnClientPrefix)8) >> 2; | |||||
1135 | if (!InsertFakeRequest(client, (char *) &data, sizeof(fsFakeReq))) { | |||||
1136 | FreeClientResources(client); | |||||
1137 | fsfree(client)FSfree((pointer)client); | |||||
1138 | return NullClient((ClientPtr) ((void *)0)); | |||||
1139 | } | |||||
1140 | if (i == currentMaxClients) | |||||
1141 | currentMaxClients++; | |||||
1142 | while ((nextFreeClientID < MAXCLIENTS128) && clients[nextFreeClientID]) | |||||
1143 | nextFreeClientID++; | |||||
1144 | ||||||
1145 | /* if we've maxed out, try to clone */ | |||||
1146 | if (nextFreeClientID == MaxClients) { | |||||
1147 | CloneMyself(); | |||||
1148 | } | |||||
1149 | return client; | |||||
1150 | } | |||||
1151 | ||||||
1152 | void | |||||
1153 | MarkClientException(ClientPtr client) | |||||
1154 | { | |||||
1155 | client->noClientException = -2; | |||||
1156 | } |