| 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 | } |