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