dispatch.c revision e1db7cd1
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); 25640c5823bSmrg DEALLOCATE_LOCAL(client_auth); 257bbe1b32bSmrg return (FSBadLength); 258bbe1b32bSmrg } 259bbe1b32bSmrg /* copy carefully in case wire data is not aligned */ 260bbe1b32bSmrg client_auth[i].namelen = (((unsigned char *)ad)[0] << 8) + 261bbe1b32bSmrg ((unsigned char *)ad)[1]; 262bbe1b32bSmrg ad += 2; 263bbe1b32bSmrg client_auth[i].datalen = (((unsigned char *)ad)[0] << 8) + 264bbe1b32bSmrg ((unsigned char *)ad)[1]; 265bbe1b32bSmrg ad += 2; 266bbe1b32bSmrg client_auth[i].name = (char *) ad; 267bbe1b32bSmrg ad += client_auth[i].namelen; 268bbe1b32bSmrg client_auth[i].data = (char *) ad; 269bbe1b32bSmrg ad += client_auth[i].datalen; 270bbe1b32bSmrg } 271bbe1b32bSmrg if (!(int)prefix->num_auths) 272bbe1b32bSmrg ad += 4; 273bbe1b32bSmrg if (ad - (char *)auth_data > (stuff->length << 2)) { 274bbe1b32bSmrg int lengthword = stuff->length; 275bbe1b32bSmrg 276bbe1b32bSmrg SendErrToClient(client, FSBadLength, (pointer)&lengthword); 27740c5823bSmrg DEALLOCATE_LOCAL(client_auth); 278bbe1b32bSmrg return (FSBadLength); 279bbe1b32bSmrg } 280bbe1b32bSmrg 281bbe1b32bSmrg num_alts = ListAlternateServers(&altservers); 282bbe1b32bSmrg for (i = 0, altlen = 0; i < num_alts; i++) { 283bbe1b32bSmrg /* subset + len + namelen + pad */ 284bbe1b32bSmrg altlen += (2 + altservers[i].namelen + 3) >> 2; 285bbe1b32bSmrg } 286bbe1b32bSmrg 287bbe1b32bSmrg auth_index = prefix->num_auths; 288bbe1b32bSmrg client->auth_generation = 0; 289bbe1b32bSmrg ret = CheckClientAuthorization(client, client_auth, 290bbe1b32bSmrg &auth_accept, &auth_index, &auth_len, &server_auth_data); 291bbe1b32bSmrg if (auth_index > 0) 292bbe1b32bSmrg { 293bbe1b32bSmrg AuthContextPtr authp; 294e1db7cd1Smrg authp = (AuthContextPtr) FSalloc(sizeof(AuthContextRec)); 295bbe1b32bSmrg if (!authp) { 296bbe1b32bSmrg SendErrToClient(client, FSBadAlloc, (pointer) 0); 29740c5823bSmrg DEALLOCATE_LOCAL(client_auth); 298bbe1b32bSmrg return FSBadAlloc; 299bbe1b32bSmrg } 300bbe1b32bSmrg authp->authname = 301e1db7cd1Smrg (char *) FSalloc(client_auth[auth_index - 1].namelen + 1); 302bbe1b32bSmrg authp->authdata = 303e1db7cd1Smrg (char *) FSalloc(client_auth[auth_index - 1].datalen + 1); 304bbe1b32bSmrg if (!authp->authname || !authp->authdata) { 305e1db7cd1Smrg FSfree((char *) authp->authname); 306e1db7cd1Smrg FSfree((char *) authp->authdata); 307e1db7cd1Smrg FSfree((char *) authp); 308bbe1b32bSmrg SendErrToClient(client, FSBadAlloc, (pointer) 0); 30940c5823bSmrg DEALLOCATE_LOCAL(client_auth); 310bbe1b32bSmrg return FSBadAlloc; 311bbe1b32bSmrg } 31276028eb6Smrg memcpy(authp->authname, client_auth[auth_index - 1].name, 313bbe1b32bSmrg client_auth[auth_index - 1].namelen); 31476028eb6Smrg memcpy(authp->authdata, client_auth[auth_index - 1].data, 315bbe1b32bSmrg client_auth[auth_index - 1].datalen); 316bbe1b32bSmrg /* Save it with a zero resource id... subsequent 317bbe1b32bSmrg SetAuthorizations of None will find it. And it will be freed 318bbe1b32bSmrg by FreeClientResources when the connection closes. */ 319bbe1b32bSmrg if (!AddResource(client->index, 0, RT_AUTHCONT,(pointer) authp)) 320bbe1b32bSmrg { 321e1db7cd1Smrg FSfree((char *) authp->authname); 322e1db7cd1Smrg FSfree((char *) authp->authdata); 323e1db7cd1Smrg FSfree((char *) authp); 324bbe1b32bSmrg SendErrToClient(client, FSBadAlloc, (pointer) 0); 32540c5823bSmrg DEALLOCATE_LOCAL(client_auth); 326bbe1b32bSmrg return FSBadAlloc; 327bbe1b32bSmrg } 328bbe1b32bSmrg client->auth = client->default_auth = authp; 329bbe1b32bSmrg } 330bbe1b32bSmrg else 331bbe1b32bSmrg client->auth = client->default_auth = (AuthContextPtr)0; 332bbe1b32bSmrg 333bbe1b32bSmrg DEALLOCATE_LOCAL(client_auth); 334bbe1b32bSmrg 335bbe1b32bSmrg if (ret != FSSuccess) { 336bbe1b32bSmrg SendErrToClient(client, FSBadAlloc, (pointer) 0); 337bbe1b32bSmrg return FSBadAlloc; 338bbe1b32bSmrg } 33934f90d55Smrg else { 34034f90d55Smrg fsConnSetup csp = { 34134f90d55Smrg .status = auth_accept, 34234f90d55Smrg /* we implement backwards compatibility for version 1.0 */ 34334f90d55Smrg .major_version = (client->major_version == 1) ? 34434f90d55Smrg client->major_version : FS_PROTOCOL, 34534f90d55Smrg .minor_version = FS_PROTOCOL_MINOR, 34634f90d55Smrg .num_alternates = num_alts, 34734f90d55Smrg .alternate_len = altlen, 34834f90d55Smrg .auth_len = auth_len >> 2, 34934f90d55Smrg .auth_index = auth_index 35034f90d55Smrg }; 35134f90d55Smrg if (client->swapped) { 35234f90d55Smrg WriteSConnSetup(client, &csp); 35334f90d55Smrg } else { 35434f90d55Smrg (void) WriteToClient(client, SIZEOF(fsConnSetup), (char *) &csp); 35534f90d55Smrg } 356bbe1b32bSmrg } 357bbe1b32bSmrg 358bbe1b32bSmrg /* send the alternates info */ 359bbe1b32bSmrg for (i = 0; i < num_alts; i++) { 360bbe1b32bSmrg char tmp[258]; 361bbe1b32bSmrg 362bbe1b32bSmrg /* WriteToClient pads, so we have to fake some things */ 363bbe1b32bSmrg tmp[0] = altservers[i].subset; 364bbe1b32bSmrg tmp[1] = altservers[i].namelen; 36576028eb6Smrg memcpy(&tmp[2], altservers[i].name, altservers[i].namelen); 366bbe1b32bSmrg (void) WriteToClient(client, altservers[i].namelen + 2, tmp); 367bbe1b32bSmrg } 368bbe1b32bSmrg 369bbe1b32bSmrg if (auth_len) 370bbe1b32bSmrg (void) WriteToClient(client, auth_len, (char *) server_auth_data); 371bbe1b32bSmrg 372bbe1b32bSmrg if (auth_accept != AuthSuccess) { 373bbe1b32bSmrg nClients--; 374bbe1b32bSmrg return (client->noClientException = -2); 375bbe1b32bSmrg } 376bbe1b32bSmrg client->requestVector = client->swapped ? SwappedProcVector : ProcVector; 377bbe1b32bSmrg client->sequence = 0; 378bbe1b32bSmrg if (client->swapped) 379bbe1b32bSmrg (void) WriteSConnectionInfo(client, ConnInfoLen, ConnectionInfo); 380bbe1b32bSmrg else 381bbe1b32bSmrg (void) WriteToClient(client, ConnInfoLen, ConnectionInfo); 382bbe1b32bSmrg 383bbe1b32bSmrg#ifdef DEBUG 384bbe1b32bSmrg fprintf(stderr, "Establishing new connection\n"); 385bbe1b32bSmrg#endif 386bbe1b32bSmrg 387bbe1b32bSmrg return client->noClientException; 388bbe1b32bSmrg} 389bbe1b32bSmrg 390bbe1b32bSmrg/* 391bbe1b32bSmrg * NOTE -- the incoming data may be mangled 392bbe1b32bSmrg */ 393bbe1b32bSmrg 394bbe1b32bSmrgvoid 395bbe1b32bSmrgDoSendErrToClient( 396bbe1b32bSmrg ClientPtr client, 397bbe1b32bSmrg int error, 398bbe1b32bSmrg pointer data) /* resource id, format, resolution, etc */ 399bbe1b32bSmrg{ 40034f90d55Smrg fsError rep = { 40134f90d55Smrg .type = FS_Error, 40234f90d55Smrg .request = error, 40334f90d55Smrg .sequenceNumber = client->sequence, 40434f90d55Smrg .timestamp = GetTimeInMillis(), 40534f90d55Smrg .major_opcode = ((fsReq *) client->requestBuffer)->reqType, 4068f34cbf9Ssnj .minor_opcode = 0 40734f90d55Smrg }; 408bbe1b32bSmrg int extralen = 0; 409bbe1b32bSmrg 410bbe1b32bSmrg switch (error) { 411bbe1b32bSmrg case FSBadFormat: 412bbe1b32bSmrg extralen = SIZEOF(fsBitmapFormat); 413bbe1b32bSmrg break; 414bbe1b32bSmrg case FSBadFont: 415bbe1b32bSmrg case FSBadAccessContext: 416bbe1b32bSmrg case FSBadIDChoice: 417bbe1b32bSmrg case FSBadEventMask: 418bbe1b32bSmrg if (data) { 419bbe1b32bSmrg if (client->swapped) 420bbe1b32bSmrg SwapLongs((long *) data, 1); 421bbe1b32bSmrg extralen = 4; 422bbe1b32bSmrg } 423bbe1b32bSmrg break; 424bbe1b32bSmrg case FSBadRange: 425bbe1b32bSmrg extralen = SIZEOF(fsRange); 426bbe1b32bSmrg break; 427bbe1b32bSmrg case FSBadResolution: 428bbe1b32bSmrg if (data) { 429bbe1b32bSmrg if (client->swapped) 430bbe1b32bSmrg SwapShorts((short *) data, 1); 431bbe1b32bSmrg /* note sneaky hack */ 432bbe1b32bSmrg rep.pad = *(CARD16 *) data; 433bbe1b32bSmrg data = (char *)data + 2; 434bbe1b32bSmrg extralen = 4; 435bbe1b32bSmrg } 436bbe1b32bSmrg break; 437bbe1b32bSmrg case FSBadLength: 438bbe1b32bSmrg if (data) { 439bbe1b32bSmrg if (client->swapped) 440bbe1b32bSmrg SwapLongs((long *) data, 1); 441bbe1b32bSmrg extralen = 4; 442bbe1b32bSmrg } 443bbe1b32bSmrg break; 444bbe1b32bSmrg default: 445bbe1b32bSmrg /* nothing else to send */ 446bbe1b32bSmrg break; 447bbe1b32bSmrg } 448bbe1b32bSmrg 449bbe1b32bSmrg rep.length = (SIZEOF(fsError) + extralen) >> 2; 450bbe1b32bSmrg 451bbe1b32bSmrg WriteErrorToClient(client, &rep); 452bbe1b32bSmrg 453bbe1b32bSmrg if (extralen) 454bbe1b32bSmrg WriteToClient(client, extralen, (char *) data); 455bbe1b32bSmrg} 456bbe1b32bSmrg 457bbe1b32bSmrg/* ARGSUSED */ 458bbe1b32bSmrgint 459bbe1b32bSmrgProcBadRequest(ClientPtr client) 460bbe1b32bSmrg{ 461bbe1b32bSmrg SendErrToClient(client, FSBadRequest, NULL); 462bbe1b32bSmrg return FSBadRequest; 463bbe1b32bSmrg} 464bbe1b32bSmrg 465bbe1b32bSmrgint 466bbe1b32bSmrgProcNoop(ClientPtr client) 467bbe1b32bSmrg{ 468bbe1b32bSmrg REQUEST(fsReq); 469bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsReq); 470bbe1b32bSmrg 471bbe1b32bSmrg return client->noClientException; 472bbe1b32bSmrg} 473bbe1b32bSmrg 474bbe1b32bSmrgint 475bbe1b32bSmrgProcListCatalogues(ClientPtr client) 476bbe1b32bSmrg{ 477bbe1b32bSmrg int len, 478bbe1b32bSmrg num; 479bbe1b32bSmrg char *catalogues; 48034f90d55Smrg fsListCataloguesReply rep = { 48134f90d55Smrg .type = FS_Reply, 48234f90d55Smrg .sequenceNumber = client->sequence, 48334f90d55Smrg .num_replies = 0 48434f90d55Smrg }; 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.num_catalogues = num; 493bbe1b32bSmrg rep.length = (SIZEOF(fsListCataloguesReply) + len + 3) >> 2; 494bbe1b32bSmrg 495bbe1b32bSmrg WriteReplyToClient(client, SIZEOF(fsListCataloguesReply), &rep); 496bbe1b32bSmrg (void) WriteToClient(client, len, (char *) catalogues); 497e1db7cd1Smrg FSfree((char *) catalogues); 498bbe1b32bSmrg return client->noClientException; 499bbe1b32bSmrg} 500bbe1b32bSmrg 501bbe1b32bSmrgint 502bbe1b32bSmrgProcSetCatalogues(ClientPtr client) 503bbe1b32bSmrg{ 504bbe1b32bSmrg char *new_cat; 505bbe1b32bSmrg int err, 506bbe1b32bSmrg len; 507bbe1b32bSmrg int num; 508bbe1b32bSmrg 509bbe1b32bSmrg REQUEST(fsSetCataloguesReq); 510bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsSetCataloguesReq); 511bbe1b32bSmrg 512bbe1b32bSmrg if (stuff->num_catalogues == 0) { 513bbe1b32bSmrg /* use the default */ 514bbe1b32bSmrg num = ListCatalogues("*", 1, 10000, &new_cat, &len); 515bbe1b32bSmrg } else { 516bbe1b32bSmrg num = stuff->num_catalogues; 517bbe1b32bSmrg err = ValidateCatalogues(&num, (char *)stuff + SIZEOF(fsSetCataloguesReq)); 518bbe1b32bSmrg if (err == FSSuccess) { 519bbe1b32bSmrg len = (stuff->length << 2) - SIZEOF(fsSetCataloguesReq); 520e1db7cd1Smrg new_cat = (char *) FSalloc(len); 521bbe1b32bSmrg if (!new_cat) 522bbe1b32bSmrg return FSBadAlloc; 52376028eb6Smrg memcpy(new_cat, (char *)stuff + SIZEOF(fsSetCataloguesReq), len); 524bbe1b32bSmrg } else { 525bbe1b32bSmrg SendErrToClient(client, err, (pointer) &num); 526bbe1b32bSmrg return err; 527bbe1b32bSmrg } 528bbe1b32bSmrg } 529bbe1b32bSmrg if (client->catalogues) 530e1db7cd1Smrg FSfree((char *) client->catalogues); 531bbe1b32bSmrg client->catalogues = new_cat; 532bbe1b32bSmrg client->num_catalogues = num; 533bbe1b32bSmrg return client->noClientException; 534bbe1b32bSmrg} 535bbe1b32bSmrg 536bbe1b32bSmrgint 537bbe1b32bSmrgProcGetCatalogues(ClientPtr client) 538bbe1b32bSmrg{ 539bbe1b32bSmrg int len, 540bbe1b32bSmrg i, 541bbe1b32bSmrg size; 542bbe1b32bSmrg char *cp; 543bbe1b32bSmrg 544bbe1b32bSmrg REQUEST(fsGetCataloguesReq); 545bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsGetCataloguesReq); 546bbe1b32bSmrg 547bbe1b32bSmrg for (i = 0, len = 0, cp = client->catalogues; 548bbe1b32bSmrg i < client->num_catalogues; i++) { 549bbe1b32bSmrg size = *cp++; 550bbe1b32bSmrg len += size + 1; /* str length + size byte */ 551bbe1b32bSmrg cp += size; 552bbe1b32bSmrg } 553bbe1b32bSmrg 55434f90d55Smrg { 55534f90d55Smrg fsGetCataloguesReply rep = { 55634f90d55Smrg .type = FS_Reply, 55734f90d55Smrg .num_catalogues = client->num_catalogues, 55834f90d55Smrg .sequenceNumber = client->sequence, 55934f90d55Smrg .length = (SIZEOF(fsGetCataloguesReply) + len + 3) >> 2 56034f90d55Smrg }; 561bbe1b32bSmrg 56234f90d55Smrg WriteReplyToClient(client, SIZEOF(fsGetCataloguesReply), &rep); 56334f90d55Smrg } 564bbe1b32bSmrg (void) WriteToClient(client, len, client->catalogues); 565bbe1b32bSmrg 566bbe1b32bSmrg return client->noClientException; 567bbe1b32bSmrg} 568bbe1b32bSmrg 569bbe1b32bSmrgint 570bbe1b32bSmrgProcCreateAC(ClientPtr client) 571bbe1b32bSmrg{ 572bbe1b32bSmrg AuthPtr acp; 573bbe1b32bSmrg AuthContextPtr authp; 574bbe1b32bSmrg int accept, 575bbe1b32bSmrg i, 576bbe1b32bSmrg err, 577bbe1b32bSmrg index, 578bbe1b32bSmrg size; 579bbe1b32bSmrg char *ad; 580bbe1b32bSmrg char *auth_data; 581bbe1b32bSmrg 582bbe1b32bSmrg REQUEST(fsCreateACReq); 583bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsCreateACReq); 584bbe1b32bSmrg 585bbe1b32bSmrg authp = (AuthContextPtr) LookupIDByType(client->index, stuff->acid, 586bbe1b32bSmrg RT_AUTHCONT); 587bbe1b32bSmrg if (authp) { 588bbe1b32bSmrg int aligned_acid = stuff->acid; 589bbe1b32bSmrg SendErrToClient(client, FSBadIDChoice, (pointer) &aligned_acid); 590bbe1b32bSmrg return FSBadIDChoice; 591bbe1b32bSmrg } 592ce6676dbSmrg acp = NULL; 593bbe1b32bSmrg if (stuff->num_auths) 594bbe1b32bSmrg { 595bbe1b32bSmrg acp = (AuthPtr) ALLOCATE_LOCAL(stuff->num_auths * sizeof(AuthRec)); 596bbe1b32bSmrg if (!acp) { 597ce6676dbSmrg SendErrToClient(client, FSBadAlloc, (pointer) NULL); 598bbe1b32bSmrg return FSBadAlloc; 599bbe1b32bSmrg } 600bbe1b32bSmrg } 601bbe1b32bSmrg /* build up a list of the stuff */ 602bbe1b32bSmrg for (i = 0, ad = (char *)stuff + SIZEOF(fsCreateACReq); 603bbe1b32bSmrg i < (int)stuff->num_auths; i++) { 604bbe1b32bSmrg if (ad - (char *)stuff + SIZEOF(fsCreateACReq) > 605bbe1b32bSmrg (stuff->length << 2) - 4) { 606bbe1b32bSmrg int lengthword = stuff->length; 607bbe1b32bSmrg 608bbe1b32bSmrg SendErrToClient(client, FSBadLength, (pointer)&lengthword); 60940c5823bSmrg DEALLOCATE_LOCAL(acp); 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 (ad - (char *)stuff > (stuff->length << 2)) { 625bbe1b32bSmrg int lengthword = stuff->length; 626bbe1b32bSmrg 627bbe1b32bSmrg SendErrToClient(client, FSBadLength, (pointer)&lengthword); 62840c5823bSmrg if (acp) 62940c5823bSmrg DEALLOCATE_LOCAL(acp); 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 } 644e1db7cd1Smrg authp = (AuthContextPtr) FSalloc(sizeof(AuthContextRec)); 645bbe1b32bSmrg if (!authp) { 646bbe1b32bSmrg goto alloc_failure; 647bbe1b32bSmrg } 648ce6676dbSmrg authp->authname = NULL; 649ce6676dbSmrg authp->authdata = NULL; 650bbe1b32bSmrg if (index > 0) 651bbe1b32bSmrg { 652e1db7cd1Smrg authp->authname = (char *) FSalloc(acp[index - 1].namelen + 1); 653e1db7cd1Smrg authp->authdata = (char *) FSalloc(acp[index - 1].datalen + 1); 654bbe1b32bSmrg if (!authp->authname || !authp->authdata) { 655e1db7cd1Smrg FSfree((char *) authp->authname); 656e1db7cd1Smrg FSfree((char *) authp->authdata); 657e1db7cd1Smrg FSfree((char *) authp); 658bbe1b32bSmrg goto alloc_failure; 659bbe1b32bSmrg } 66076028eb6Smrg memcpy(authp->authname, acp[index - 1].name, acp[index - 1].namelen); 66176028eb6Smrg memcpy(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); 67534f90d55Smrg { 67634f90d55Smrg fsCreateACReply rep = { 67734f90d55Smrg .type = FS_Reply, 67834f90d55Smrg .auth_index = index, 67934f90d55Smrg .sequenceNumber = client->sequence, 68034f90d55Smrg .status = accept, 68134f90d55Smrg .length = (SIZEOF(fsCreateACReply) + size) >> 2 68234f90d55Smrg }; 683bbe1b32bSmrg 68434f90d55Smrg WriteReplyToClient(client, SIZEOF(fsCreateACReply), &rep); 68534f90d55Smrg } 686bbe1b32bSmrg if (size) 687bbe1b32bSmrg (void) WriteToClient(client, size, auth_data); 688bbe1b32bSmrg 689bbe1b32bSmrg return client->noClientException; 690bbe1b32bSmrg} 691bbe1b32bSmrg 692bbe1b32bSmrg/* ARGSUSED */ 693bbe1b32bSmrgint 694bbe1b32bSmrgDeleteAuthCont (pointer value, FSID id) 695bbe1b32bSmrg{ 696bbe1b32bSmrg AuthContextPtr authp = (AuthContextPtr) value; 697bbe1b32bSmrg 698bbe1b32bSmrg if (authp->authname) 699e1db7cd1Smrg FSfree (authp->authname); 700bbe1b32bSmrg if (authp->authdata) 701e1db7cd1Smrg FSfree (authp->authdata); 702e1db7cd1Smrg FSfree (authp); 703bbe1b32bSmrg return 1; 704bbe1b32bSmrg} 705bbe1b32bSmrg 706bbe1b32bSmrgint 707bbe1b32bSmrgProcFreeAC(ClientPtr client) 708bbe1b32bSmrg{ 709bbe1b32bSmrg AuthContextPtr authp; 710bbe1b32bSmrg 711bbe1b32bSmrg REQUEST(fsFreeACReq); 712bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsFreeACReq); 713bbe1b32bSmrg authp = (AuthContextPtr) LookupIDByType(client->index, stuff->id, 714bbe1b32bSmrg RT_AUTHCONT); 715bbe1b32bSmrg if (!authp) { 716bbe1b32bSmrg int aligned_id = stuff->id; 717bbe1b32bSmrg SendErrToClient(client, FSBadIDChoice, (pointer) &aligned_id); 718bbe1b32bSmrg return FSBadIDChoice; 719bbe1b32bSmrg } 720bbe1b32bSmrg if (client->auth == authp) 721bbe1b32bSmrg client->auth = client->default_auth; 722bbe1b32bSmrg FreeResource(client->index, stuff->id, RT_NONE); 723bbe1b32bSmrg return client->noClientException; 724bbe1b32bSmrg} 725bbe1b32bSmrg 726bbe1b32bSmrgint 727bbe1b32bSmrgProcSetAuthorization(ClientPtr client) 728bbe1b32bSmrg{ 729bbe1b32bSmrg AuthContextPtr acp; 730bbe1b32bSmrg 731bbe1b32bSmrg REQUEST(fsSetAuthorizationReq); 732bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsSetAuthorizationReq); 733bbe1b32bSmrg acp = (AuthContextPtr) LookupIDByType(client->index, stuff->id, 734bbe1b32bSmrg RT_AUTHCONT); 735bbe1b32bSmrg if (!acp) { 736bbe1b32bSmrg int aligned_id = stuff->id; 737bbe1b32bSmrg SendErrToClient(client, FSBadIDChoice, (pointer) &aligned_id); 738bbe1b32bSmrg return FSBadIDChoice; 739bbe1b32bSmrg } 740bbe1b32bSmrg client->auth = acp; /* XXX does this need a refcount? */ 741bbe1b32bSmrg return client->noClientException; 742bbe1b32bSmrg} 743bbe1b32bSmrg 744bbe1b32bSmrgint 745bbe1b32bSmrgProcSetResolution(ClientPtr client) 746bbe1b32bSmrg{ 747bbe1b32bSmrg fsResolution *new_res; 748bbe1b32bSmrg 749bbe1b32bSmrg REQUEST(fsSetResolutionReq); 750bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsSetResolutionReq); 751bbe1b32bSmrg 752bbe1b32bSmrg if ((stuff->length << 2) - SIZEOF(fsSetResolutionReq) < 753bbe1b32bSmrg stuff->num_resolutions * SIZEOF(fsResolution)) { 754bbe1b32bSmrg int lengthword = stuff->length; 755bbe1b32bSmrg 756bbe1b32bSmrg SendErrToClient(client, FSBadLength, &lengthword); 757bbe1b32bSmrg return FSBadLength; 758bbe1b32bSmrg } 759bbe1b32bSmrg new_res = (fsResolution *) 760e1db7cd1Smrg FSallocarray(stuff->num_resolutions, SIZEOF(fsResolution)); 761bbe1b32bSmrg if (!new_res) { 762bbe1b32bSmrg SendErrToClient(client, FSBadAlloc, NULL); 763bbe1b32bSmrg return FSBadAlloc; 764bbe1b32bSmrg } 765e1db7cd1Smrg FSfree((char *) client->resolutions); 76676028eb6Smrg memcpy(new_res, (char *)stuff + SIZEOF(fsSetResolutionReq), 767bbe1b32bSmrg (stuff->num_resolutions * SIZEOF(fsResolution))); 768bbe1b32bSmrg client->resolutions = new_res; 769bbe1b32bSmrg client->num_resolutions = stuff->num_resolutions; 770bbe1b32bSmrg 771bbe1b32bSmrg return client->noClientException; 772bbe1b32bSmrg} 773bbe1b32bSmrg 774bbe1b32bSmrgint 775bbe1b32bSmrgProcGetResolution(ClientPtr client) 776bbe1b32bSmrg{ 777bbe1b32bSmrg REQUEST(fsReq); 778bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsReq); 779bbe1b32bSmrg 780bbe1b32bSmrg if ((stuff->length << 2) - SIZEOF(fsResolution) < client->num_resolutions * 781bbe1b32bSmrg sizeof(fsResolution)) { 782bbe1b32bSmrg int lengthword = stuff->length; 783bbe1b32bSmrg 784bbe1b32bSmrg SendErrToClient(client, FSBadLength, &lengthword); 785bbe1b32bSmrg return FSBadLength; 786bbe1b32bSmrg } 78734f90d55Smrg else { 78834f90d55Smrg fsGetResolutionReply reply = { 78934f90d55Smrg .type = FS_Reply, 79034f90d55Smrg .num_resolutions = client->num_resolutions, 79134f90d55Smrg .sequenceNumber = client->sequence, 79234f90d55Smrg .length = (SIZEOF(fsGetResolutionReply) + 79334f90d55Smrg client->num_resolutions * SIZEOF(fsResolution)) >> 2 79434f90d55Smrg }; 795bbe1b32bSmrg 79634f90d55Smrg WriteReplyToClient(client, SIZEOF(fsGetResolutionReply), &reply); 79734f90d55Smrg } 798bbe1b32bSmrg if (client->swapped) 799bbe1b32bSmrg client->pSwapReplyFunc = CopySwap16Write; 800bbe1b32bSmrg 801bbe1b32bSmrg WriteSwappedDataToClient(client, 802bbe1b32bSmrg (client->num_resolutions * SIZEOF(fsResolution)), (short *)client->resolutions); 803bbe1b32bSmrg 804bbe1b32bSmrg return client->noClientException; 805bbe1b32bSmrg} 806bbe1b32bSmrg 807bbe1b32bSmrgint 808bbe1b32bSmrgProcListFonts(ClientPtr client) 809bbe1b32bSmrg{ 810bbe1b32bSmrg REQUEST(fsListFontsReq); 811bbe1b32bSmrg REQUEST_FIXED_SIZE(fsListFontsReq, stuff->nbytes); 812bbe1b32bSmrg 813bbe1b32bSmrg return ListFonts(client, stuff->nbytes, 814bbe1b32bSmrg (unsigned char *)stuff + SIZEOF(fsListFontsReq), 815bbe1b32bSmrg stuff->maxNames); 816bbe1b32bSmrg} 817bbe1b32bSmrg 818bbe1b32bSmrgint 819bbe1b32bSmrgProcListFontsWithXInfo(ClientPtr client) 820bbe1b32bSmrg{ 821bbe1b32bSmrg REQUEST(fsListFontsWithXInfoReq); 822bbe1b32bSmrg REQUEST_FIXED_SIZE(fsListFontsWithXInfoReq, stuff->nbytes); 823bbe1b32bSmrg 824bbe1b32bSmrg return StartListFontsWithInfo(client, stuff->nbytes, 825bbe1b32bSmrg (unsigned char *)stuff + SIZEOF(fsListFontsWithXInfoReq), stuff->maxNames); 826bbe1b32bSmrg} 827bbe1b32bSmrg 828bbe1b32bSmrgint 829bbe1b32bSmrgProcOpenBitmapFont(ClientPtr client) 830bbe1b32bSmrg{ 831bbe1b32bSmrg FontPtr pfont; 832bbe1b32bSmrg int nbytes, 833bbe1b32bSmrg err; 834bbe1b32bSmrg unsigned char *fname; 835bbe1b32bSmrg 836bbe1b32bSmrg REQUEST(fsOpenBitmapFontReq); 837bbe1b32bSmrg fname = (unsigned char *)stuff + SIZEOF(fsOpenBitmapFontReq); 838bbe1b32bSmrg nbytes = *fname++; 839bbe1b32bSmrg 840bbe1b32bSmrg REQUEST_FIXED_SIZE(fsOpenBitmapFontReq, (nbytes + 1)); 841bbe1b32bSmrg 842bbe1b32bSmrg pfont = (FontPtr) LookupIDByType(client->index, stuff->fid, RT_FONT); 843bbe1b32bSmrg if (pfont) { 844bbe1b32bSmrg int aligned_fid = stuff->fid; 845bbe1b32bSmrg SendErrToClient(client, FSBadIDChoice, (pointer) &aligned_fid); 846bbe1b32bSmrg return FSBadIDChoice; 847bbe1b32bSmrg } 848bbe1b32bSmrg if (stuff->format_hint != 0 && 849bbe1b32bSmrg stuff->format_hint & ~ALL_FORMAT_BITS) { 850bbe1b32bSmrg int aligned_format_hint = stuff->format_hint; 851bbe1b32bSmrg SendErrToClient(client, FSBadFormat, (pointer) &aligned_format_hint); 852bbe1b32bSmrg return FSBadFormat; 853bbe1b32bSmrg } 854bbe1b32bSmrg if (stuff->format_mask & ~ALL_FORMAT_MASK_BITS) { 855bbe1b32bSmrg int aligned_format_mask = stuff->format_mask; 856bbe1b32bSmrg SendErrToClient(client, FSBadFormat, (pointer) &aligned_format_mask); 857bbe1b32bSmrg return FSBadFormat; 858bbe1b32bSmrg } 859bbe1b32bSmrg err = OpenFont(client, stuff->fid, stuff->format_hint, stuff->format_mask, 860bbe1b32bSmrg nbytes, (char *) fname); 861bbe1b32bSmrg 862bbe1b32bSmrg if (err == FSSuccess) { 863bbe1b32bSmrg return client->noClientException; 864bbe1b32bSmrg } else { 865bbe1b32bSmrg return err; 866bbe1b32bSmrg } 867bbe1b32bSmrg} 868bbe1b32bSmrg 869bbe1b32bSmrgint 870bbe1b32bSmrgProcQueryXInfo(ClientPtr client) 871bbe1b32bSmrg{ 872bbe1b32bSmrg ClientFontPtr cfp; 873bbe1b32bSmrg int err, 874bbe1b32bSmrg lendata; 87534f90d55Smrg fsQueryXInfoReply reply = { 87634f90d55Smrg .type = FS_Reply, 87734f90d55Smrg .sequenceNumber = client->sequence 87834f90d55Smrg }; 879bbe1b32bSmrg fsPropInfo *prop_info; 880bbe1b32bSmrg 881bbe1b32bSmrg REQUEST(fsQueryXInfoReq); 882bbe1b32bSmrg 883bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsQueryXInfoReq); 884bbe1b32bSmrg 885bbe1b32bSmrg cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->id, RT_FONT); 886bbe1b32bSmrg if (!cfp) { 887bbe1b32bSmrg int aligned_id = stuff->id; 888bbe1b32bSmrg SendErrToClient(client, FSBadFont, (pointer) &aligned_id); 889bbe1b32bSmrg return FSBadFont; 890bbe1b32bSmrg } 891bbe1b32bSmrg 892bbe1b32bSmrg /* get the header */ 893bbe1b32bSmrg fsPack_XFontInfoHeader(&cfp->font->info, &reply, client->major_version); 894bbe1b32bSmrg err = convert_props(&cfp->font->info, &prop_info); 895bbe1b32bSmrg 896bbe1b32bSmrg switch (err) 897bbe1b32bSmrg { 898bbe1b32bSmrg case Successful: 899bbe1b32bSmrg break; 900bbe1b32bSmrg case AllocError: 901bbe1b32bSmrg SendErrToClient(client, FSBadAlloc, (pointer) 0); 902bbe1b32bSmrg return err; 903bbe1b32bSmrg default: 904bbe1b32bSmrg ErrorF("ProcQueryXInfo: unexpected return val %d from convert_props\n", 905bbe1b32bSmrg err); 906bbe1b32bSmrg SendErrToClient(client, FSBadImplementation, (pointer) 0); 907bbe1b32bSmrg return err; 908bbe1b32bSmrg } 909bbe1b32bSmrg lendata = SIZEOF(fsPropInfo) + 910bbe1b32bSmrg prop_info->num_offsets * SIZEOF(fsPropOffset) + 911bbe1b32bSmrg prop_info->data_len; 912bbe1b32bSmrg 913bbe1b32bSmrg reply.length = (SIZEOF(fsQueryXInfoReply) + lendata + 3) >> 2; 914bbe1b32bSmrg WriteReplyToClient(client, SIZEOF(fsQueryXInfoReply), &reply); 915bbe1b32bSmrg 916bbe1b32bSmrg if (client->swapped) 917bbe1b32bSmrg SwapPropInfo(prop_info); 918bbe1b32bSmrg (void) WriteToClient(client, lendata, (char *) prop_info); 919bbe1b32bSmrg 920e1db7cd1Smrg FSfree((char *) prop_info); 921bbe1b32bSmrg return client->noClientException; 922bbe1b32bSmrg} 923bbe1b32bSmrg 924bbe1b32bSmrgint 925bbe1b32bSmrgProcQueryXExtents(ClientPtr client) 926bbe1b32bSmrg{ 927bbe1b32bSmrg ClientFontPtr cfp; 928bbe1b32bSmrg int err; 929bbe1b32bSmrg int item_size; 930bbe1b32bSmrg 931bbe1b32bSmrg REQUEST(fsQueryXExtents8Req); 932bbe1b32bSmrg 933bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsQueryXExtents8Req); 934bbe1b32bSmrg 935bbe1b32bSmrg cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->fid, RT_FONT); 936bbe1b32bSmrg if (!cfp) { 937bbe1b32bSmrg int aligned_fid = stuff->fid; 938bbe1b32bSmrg SendErrToClient(client, FSBadFont, (pointer) &aligned_fid); 939bbe1b32bSmrg return FSBadFont; 940bbe1b32bSmrg } 941bbe1b32bSmrg item_size = (stuff->reqType == FS_QueryXExtents8) ? 1 : 2; 942bbe1b32bSmrg 943bbe1b32bSmrg if (stuff->num_ranges > 944bbe1b32bSmrg ((stuff->length << 2) - SIZEOF(fsQueryXExtents8Req))/item_size) { 945bbe1b32bSmrg int num_ranges = stuff->num_ranges; 946bbe1b32bSmrg SendErrToClient(client, FSBadLength, (pointer)&num_ranges); 947bbe1b32bSmrg return FSBadLength; 948bbe1b32bSmrg } 949bbe1b32bSmrg 950bbe1b32bSmrg /* get the extents */ 951bbe1b32bSmrg err = QueryExtents(client, cfp, item_size, 952bbe1b32bSmrg stuff->num_ranges, stuff->range, 953bbe1b32bSmrg (char *)stuff + SIZEOF(fsQueryXExtents8Req)); 954bbe1b32bSmrg 955bbe1b32bSmrg if (err != FSSuccess) { 956bbe1b32bSmrg return err; 957bbe1b32bSmrg } else 958bbe1b32bSmrg return client->noClientException; 959bbe1b32bSmrg} 960bbe1b32bSmrg 961bbe1b32bSmrgint 962bbe1b32bSmrgProcQueryXBitmaps(ClientPtr client) 963bbe1b32bSmrg{ 964bbe1b32bSmrg ClientFontPtr cfp; 965bbe1b32bSmrg int err; 966bbe1b32bSmrg int item_size; 967bbe1b32bSmrg 968bbe1b32bSmrg REQUEST(fsQueryXBitmaps8Req); 969bbe1b32bSmrg 970bbe1b32bSmrg REQUEST_AT_LEAST_SIZE(fsQueryXBitmaps8Req); 971bbe1b32bSmrg 972bbe1b32bSmrg cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->fid, RT_FONT); 973bbe1b32bSmrg if (!cfp) { 974bbe1b32bSmrg int aligned_fid = stuff->fid; 975bbe1b32bSmrg SendErrToClient(client, FSBadFont, (pointer) &aligned_fid); 976bbe1b32bSmrg return FSBadFont; 977bbe1b32bSmrg } 978bbe1b32bSmrg if (stuff->format & ~ALL_FORMAT_BITS) { 979bbe1b32bSmrg int aligned_format = stuff->format; 980bbe1b32bSmrg SendErrToClient(client, FSBadFormat, (pointer) &aligned_format); 981bbe1b32bSmrg return FSBadFormat; 982bbe1b32bSmrg } 983bbe1b32bSmrg assert((stuff->reqType == FS_QueryXBitmaps8) || (stuff->reqType == FS_QueryXBitmaps16)); 984bbe1b32bSmrg item_size = (stuff->reqType == FS_QueryXBitmaps8) ? 1 : 2; 985bbe1b32bSmrg 986bbe1b32bSmrg if (stuff->num_ranges > 987bbe1b32bSmrg ((stuff->length << 2) - SIZEOF(fsQueryXBitmaps8Req))/item_size) { 988bbe1b32bSmrg int num_ranges = stuff->num_ranges; 989bbe1b32bSmrg SendErrToClient(client, FSBadLength, (pointer)&num_ranges); 990bbe1b32bSmrg return FSBadLength; 991bbe1b32bSmrg } 992bbe1b32bSmrg /* get the glyphs */ 993bbe1b32bSmrg err = QueryBitmaps(client, cfp, item_size, stuff->format, 994bbe1b32bSmrg stuff->num_ranges, stuff->range, 995bbe1b32bSmrg (char *)stuff + SIZEOF(fsQueryXBitmaps8Req)); 996bbe1b32bSmrg 997bbe1b32bSmrg if (err != FSSuccess) { 998bbe1b32bSmrg return err; 999bbe1b32bSmrg } else { 1000bbe1b32bSmrg return client->noClientException; 1001bbe1b32bSmrg } 1002bbe1b32bSmrg} 1003bbe1b32bSmrg 1004bbe1b32bSmrgint 1005bbe1b32bSmrgProcCloseFont(ClientPtr client) 1006bbe1b32bSmrg{ 1007bbe1b32bSmrg ClientFontPtr cfp; 1008bbe1b32bSmrg 1009bbe1b32bSmrg REQUEST(fsResourceReq); 1010bbe1b32bSmrg 1011bbe1b32bSmrg REQUEST_SIZE_MATCH(fsResourceReq); 1012bbe1b32bSmrg cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->id, RT_FONT); 1013bbe1b32bSmrg if (cfp) { 1014bbe1b32bSmrg FreeResource(client->index, stuff->id, RT_NONE); 1015bbe1b32bSmrg return client->noClientException; 1016bbe1b32bSmrg } else { 1017bbe1b32bSmrg int aligned_id = stuff->id; 1018bbe1b32bSmrg SendErrToClient(client, FSBadFont, (pointer) &aligned_id); 1019bbe1b32bSmrg return FSBadFont; 1020bbe1b32bSmrg } 1021bbe1b32bSmrg} 1022bbe1b32bSmrg 1023bbe1b32bSmrgvoid 1024bbe1b32bSmrgDoCloseDownClient(ClientPtr client) 1025bbe1b32bSmrg{ 1026bbe1b32bSmrg if (client->clientGone != CLIENT_GONE) { 1027bbe1b32bSmrg DeleteClientFontStuff(client); 1028bbe1b32bSmrg client->clientGone = CLIENT_GONE; 1029bbe1b32bSmrg CloseDownConnection(client); 1030bbe1b32bSmrg --nClients; 1031bbe1b32bSmrg } 1032bbe1b32bSmrg 1033bbe1b32bSmrg if (ClientIsAsleep(client)) 1034bbe1b32bSmrg ClientSignal((pointer)client); 1035bbe1b32bSmrg else 1036bbe1b32bSmrg { 1037bbe1b32bSmrg FreeClientResources(client); 1038bbe1b32bSmrg if (client->index < nextFreeClientID) 1039bbe1b32bSmrg nextFreeClientID = client->index; 1040bbe1b32bSmrg clients[client->index] = NullClient; 1041bbe1b32bSmrg#ifdef DebugConnectionTranslation 1042bbe1b32bSmrg CheckFileNumbers(); 1043bbe1b32bSmrg#endif /* DebugConnectionTranslation */ 1044bbe1b32bSmrg 1045bbe1b32bSmrg 1046bbe1b32bSmrg if (currentClient == client) 1047bbe1b32bSmrg currentClient = serverClient; 1048e1db7cd1Smrg FSfree(client); 1049bbe1b32bSmrg 1050bbe1b32bSmrg#ifdef DEBUG 1051bbe1b32bSmrg fprintf(stderr, "Shut down client\n"); 1052bbe1b32bSmrg#endif 1053bbe1b32bSmrg 1054bbe1b32bSmrg while (!clients[currentMaxClients - 1]) 1055bbe1b32bSmrg currentMaxClients--; 1056bbe1b32bSmrg } 1057bbe1b32bSmrg} 1058bbe1b32bSmrg 1059bbe1b32bSmrgstatic void 1060bbe1b32bSmrgkill_all_clients(void) 1061bbe1b32bSmrg{ 1062bbe1b32bSmrg int i; 1063bbe1b32bSmrg 1064bbe1b32bSmrg for (i = MINCLIENT; i < currentMaxClients; i++) { 1065bbe1b32bSmrg if (clients[i]) 1066bbe1b32bSmrg CloseDownClient(clients[i]); 1067bbe1b32bSmrg } 1068bbe1b32bSmrg} 1069bbe1b32bSmrg 1070bbe1b32bSmrgvoid 1071bbe1b32bSmrgInitProcVectors(void) 1072bbe1b32bSmrg{ 1073bbe1b32bSmrg int i; 1074bbe1b32bSmrg 1075bbe1b32bSmrg for (i = 0; i < NUM_PROC_VECTORS; i++) { 1076bbe1b32bSmrg if (!ProcVector[i]) { 1077bbe1b32bSmrg ProcVector[i] = SwappedProcVector[i] = ProcBadRequest; 1078e1db7cd1Smrg ReplySwapVector[i] = ReplySwapNotImplemented; 1079bbe1b32bSmrg } 1080bbe1b32bSmrg } 1081bbe1b32bSmrg} 1082bbe1b32bSmrg 1083bbe1b32bSmrgvoid 1084bbe1b32bSmrgInitClient( 1085bbe1b32bSmrg ClientPtr client, 1086bbe1b32bSmrg int i, 1087bbe1b32bSmrg pointer ospriv) 1088bbe1b32bSmrg{ 1089ce6676dbSmrg if (i != SERVER_CLIENT) { 1090ce6676dbSmrg nClients++; 1091ce6676dbSmrg } 1092bbe1b32bSmrg client->index = i; 1093bbe1b32bSmrg client->sequence = 0; 1094bbe1b32bSmrg client->last_request_time = GetTimeInMillis(); 1095bbe1b32bSmrg client->clientGone = CLIENT_ALIVE; 1096bbe1b32bSmrg client->noClientException = FSSuccess; 1097bbe1b32bSmrg client->requestVector = InitialVector; 1098bbe1b32bSmrg client->osPrivate = ospriv; 1099bbe1b32bSmrg client->swapped = FALSE; 1100bbe1b32bSmrg 1101bbe1b32bSmrg client->auth = (AuthContextPtr) 0; 1102bbe1b32bSmrg client->catalogues = NULL; 1103bbe1b32bSmrg client->num_catalogues = 0; 1104bbe1b32bSmrg client->num_resolutions = 0; 1105bbe1b32bSmrg client->resolutions = (fsResolution *) 0; 1106bbe1b32bSmrg client->eventmask = (Mask) 0; 1107bbe1b32bSmrg} 1108bbe1b32bSmrg 1109bbe1b32bSmrgClientPtr 1110bbe1b32bSmrgNextAvailableClient(pointer ospriv) 1111bbe1b32bSmrg{ 1112bbe1b32bSmrg int i; 1113bbe1b32bSmrg ClientPtr client; 1114bbe1b32bSmrg fsFakeReq data; 1115bbe1b32bSmrg 1116bbe1b32bSmrg i = nextFreeClientID; 1117bbe1b32bSmrg if (i == MaxClients) 1118bbe1b32bSmrg return NullClient; 1119bbe1b32bSmrg 1120e1db7cd1Smrg clients[i] = client = (ClientPtr) FSalloc(sizeof(ClientRec)); 1121bbe1b32bSmrg if (!client) 1122bbe1b32bSmrg return NullClient; 1123bbe1b32bSmrg 1124bbe1b32bSmrg InitClient(client, i, ospriv); 1125bbe1b32bSmrg 1126bbe1b32bSmrg if (!InitClientResources(client)) { 1127e1db7cd1Smrg FSfree(client); 1128bbe1b32bSmrg return NullClient; 1129bbe1b32bSmrg } 1130bbe1b32bSmrg data.reqType = 1; 1131bbe1b32bSmrg data.length = (sizeof(fsFakeReq) + SIZEOF(fsConnClientPrefix)) >> 2; 1132bbe1b32bSmrg if (!InsertFakeRequest(client, (char *) &data, sizeof(fsFakeReq))) { 1133bbe1b32bSmrg FreeClientResources(client); 1134e1db7cd1Smrg FSfree(client); 1135bbe1b32bSmrg return NullClient; 1136bbe1b32bSmrg } 1137bbe1b32bSmrg if (i == currentMaxClients) 1138bbe1b32bSmrg currentMaxClients++; 1139bbe1b32bSmrg while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID]) 1140bbe1b32bSmrg nextFreeClientID++; 1141bbe1b32bSmrg 1142bbe1b32bSmrg /* if we've maxed out, try to clone */ 1143bbe1b32bSmrg if (nextFreeClientID == MaxClients) { 1144bbe1b32bSmrg CloneMyself(); 1145bbe1b32bSmrg } 1146bbe1b32bSmrg return client; 1147bbe1b32bSmrg} 1148bbe1b32bSmrg 1149bbe1b32bSmrgvoid 1150bbe1b32bSmrgMarkClientException(ClientPtr client) 1151bbe1b32bSmrg{ 1152bbe1b32bSmrg client->noClientException = -2; 1153bbe1b32bSmrg} 1154