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