~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to dix/extension.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.11 2001/12/14 19:59:31 dawes Exp $ */
 
2
/***********************************************************
 
3
 
 
4
Copyright 1987, 1998  The Open Group
 
5
 
 
6
Permission to use, copy, modify, distribute, and sell this software and its
 
7
documentation for any purpose is hereby granted without fee, provided that
 
8
the above copyright notice appear in all copies and that both that
 
9
copyright notice and this permission notice appear in supporting
 
10
documentation.
 
11
 
 
12
The above copyright notice and this permission notice shall be included in
 
13
all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
21
 
 
22
Except as contained in this notice, the name of The Open Group shall not be
 
23
used in advertising or otherwise to promote the sale, use or other dealings
 
24
in this Software without prior written authorization from The Open Group.
 
25
 
 
26
 
 
27
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 
28
 
 
29
                        All Rights Reserved
 
30
 
 
31
Permission to use, copy, modify, and distribute this software and its 
 
32
documentation for any purpose and without fee is hereby granted, 
 
33
provided that the above copyright notice appear in all copies and that
 
34
both that copyright notice and this permission notice appear in 
 
35
supporting documentation, and that the name of Digital not be
 
36
used in advertising or publicity pertaining to distribution of the
 
37
software without specific, written prior permission.  
 
38
 
 
39
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
40
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
41
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
42
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
43
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
44
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
45
SOFTWARE.
 
46
 
 
47
******************************************************************/
 
48
/* $Xorg: extension.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
 
49
 
 
50
#ifdef HAVE_DIX_CONFIG_H
 
51
#include <dix-config.h>
 
52
#endif
 
53
 
 
54
#include <X11/X.h>
 
55
#define NEED_EVENTS
 
56
#define NEED_REPLIES
 
57
#include <X11/Xproto.h>
 
58
#include "misc.h"
 
59
#include "dixstruct.h"
 
60
#include "extnsionst.h"
 
61
#include "gcstruct.h"
 
62
#include "scrnintstr.h"
 
63
#include "dispatch.h"
 
64
#ifdef XCSECURITY
 
65
#define _SECURITY_SERVER
 
66
#include <X11/extensions/security.h>
 
67
#endif
 
68
#ifdef LBX
 
69
#include "lbxserve.h"
 
70
#endif
 
71
 
 
72
#define EXTENSION_BASE  128
 
73
#define EXTENSION_EVENT_BASE  64
 
74
#define LAST_EVENT  128
 
75
#define LAST_ERROR 255
 
76
 
 
77
ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
 
78
 
 
79
static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
 
80
 
 
81
int lastEvent = EXTENSION_EVENT_BASE;
 
82
static int lastError = FirstExtensionError;
 
83
static unsigned int NumExtensions = 0;
 
84
 
 
85
ExtensionEntry *
 
86
AddExtension(char *name, int NumEvents, int NumErrors, 
 
87
             int (*MainProc)(ClientPtr c1), 
 
88
             int (*SwappedMainProc)(ClientPtr c2), 
 
89
             void (*CloseDownProc)(ExtensionEntry *e), 
 
90
             unsigned short (*MinorOpcodeProc)(ClientPtr c3))
 
91
{
 
92
    int i;
 
93
    register ExtensionEntry *ext, **newexts;
 
94
 
 
95
    if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
 
96
        return((ExtensionEntry *) NULL);
 
97
    if ((lastEvent + NumEvents > LAST_EVENT) || 
 
98
                (unsigned)(lastError + NumErrors > LAST_ERROR))
 
99
        return((ExtensionEntry *) NULL);
 
100
 
 
101
    ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
 
102
    if (!ext)
 
103
        return((ExtensionEntry *) NULL);
 
104
    ext->name = (char *)xalloc(strlen(name) + 1);
 
105
    ext->num_aliases = 0;
 
106
    ext->aliases = (char **)NULL;
 
107
    if (!ext->name)
 
108
    {
 
109
        xfree(ext);
 
110
        return((ExtensionEntry *) NULL);
 
111
    }
 
112
    strcpy(ext->name,  name);
 
113
    i = NumExtensions;
 
114
    newexts = (ExtensionEntry **) xrealloc(extensions,
 
115
                                           (i + 1) * sizeof(ExtensionEntry *));
 
116
    if (!newexts)
 
117
    {
 
118
        xfree(ext->name);
 
119
        xfree(ext);
 
120
        return((ExtensionEntry *) NULL);
 
121
    }
 
122
    NumExtensions++;
 
123
    extensions = newexts;
 
124
    extensions[i] = ext;
 
125
    ext->index = i;
 
126
    ext->base = i + EXTENSION_BASE;
 
127
    ext->CloseDown = CloseDownProc;
 
128
    ext->MinorOpcode = MinorOpcodeProc;
 
129
    ProcVector[i + EXTENSION_BASE] = MainProc;
 
130
    SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
 
131
    if (NumEvents)
 
132
    {
 
133
        ext->eventBase = lastEvent;
 
134
        ext->eventLast = lastEvent + NumEvents;
 
135
        lastEvent += NumEvents;
 
136
    }
 
137
    else
 
138
    {
 
139
        ext->eventBase = 0;
 
140
        ext->eventLast = 0;
 
141
    }
 
142
    if (NumErrors)
 
143
    {
 
144
        ext->errorBase = lastError;
 
145
        ext->errorLast = lastError + NumErrors;
 
146
        lastError += NumErrors;
 
147
    }
 
148
    else
 
149
    {
 
150
        ext->errorBase = 0;
 
151
        ext->errorLast = 0;
 
152
    }
 
153
#ifdef XCSECURITY
 
154
    ext->secure = FALSE;
 
155
#endif
 
156
 
 
157
#ifdef LBX
 
158
    (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
 
159
#endif
 
160
    return(ext);
 
161
}
 
162
 
 
163
Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
 
164
{
 
165
    char *name;
 
166
    char **aliases;
 
167
 
 
168
    aliases = (char **)xrealloc(ext->aliases,
 
169
                                (ext->num_aliases + 1) * sizeof(char *));
 
170
    if (!aliases)
 
171
        return FALSE;
 
172
    ext->aliases = aliases;
 
173
    name = (char *)xalloc(strlen(alias) + 1);
 
174
    if (!name)
 
175
        return FALSE;
 
176
    strcpy(name,  alias);
 
177
    ext->aliases[ext->num_aliases] = name;
 
178
    ext->num_aliases++;
 
179
#ifdef LBX
 
180
    return LbxAddExtensionAlias(ext->index, alias);
 
181
#else
 
182
    return TRUE;
 
183
#endif
 
184
}
 
185
 
 
186
static int
 
187
FindExtension(char *extname, int len)
 
188
{
 
189
    int i, j;
 
190
 
 
191
    for (i=0; i<NumExtensions; i++)
 
192
    {
 
193
        if ((strlen(extensions[i]->name) == len) &&
 
194
            !strncmp(extname, extensions[i]->name, len))
 
195
            break;
 
196
        for (j = extensions[i]->num_aliases; --j >= 0;)
 
197
        {
 
198
            if ((strlen(extensions[i]->aliases[j]) == len) &&
 
199
                !strncmp(extname, extensions[i]->aliases[j], len))
 
200
                break;
 
201
        }
 
202
        if (j >= 0) break;
 
203
    }
 
204
    return ((i == NumExtensions) ? -1 : i);
 
205
}
 
206
 
 
207
/*
 
208
 * CheckExtension returns the extensions[] entry for the requested
 
209
 * extension name.  Maybe this could just return a Bool instead?
 
210
 */
 
211
ExtensionEntry *
 
212
CheckExtension(const char *extname)
 
213
{
 
214
    int n;
 
215
 
 
216
    n = FindExtension((char*)extname, strlen(extname));
 
217
    if (n != -1)
 
218
        return extensions[n];
 
219
    else
 
220
        return NULL;
 
221
}
 
222
 
 
223
void
 
224
DeclareExtensionSecurity(char *extname, Bool secure)
 
225
{
 
226
#ifdef XCSECURITY
 
227
    int i = FindExtension(extname, strlen(extname));
 
228
    if (i >= 0)
 
229
    {
 
230
        int majorop = extensions[i]->base;
 
231
        extensions[i]->secure = secure;
 
232
        if (secure)
 
233
        {
 
234
            UntrustedProcVector[majorop] = ProcVector[majorop];
 
235
            SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
 
236
        }
 
237
        else
 
238
        {
 
239
            UntrustedProcVector[majorop]        = ProcBadRequest;
 
240
            SwappedUntrustedProcVector[majorop] = ProcBadRequest;
 
241
        }
 
242
    }
 
243
#endif
 
244
#ifdef LBX
 
245
    LbxDeclareExtensionSecurity(extname, secure);
 
246
#endif
 
247
}
 
248
 
 
249
unsigned short
 
250
StandardMinorOpcode(ClientPtr client)
 
251
{
 
252
    return ((xReq *)client->requestBuffer)->data;
 
253
}
 
254
 
 
255
unsigned short
 
256
MinorOpcodeOfRequest(ClientPtr client)
 
257
{
 
258
    unsigned char major;
 
259
 
 
260
    major = ((xReq *)client->requestBuffer)->reqType;
 
261
    if (major < EXTENSION_BASE)
 
262
        return 0;
 
263
    major -= EXTENSION_BASE;
 
264
    if (major >= NumExtensions)
 
265
        return 0;
 
266
    return (*extensions[major]->MinorOpcode)(client);
 
267
}
 
268
 
 
269
void
 
270
CloseDownExtensions()
 
271
{
 
272
    register int i,j;
 
273
 
 
274
#ifdef LBX
 
275
    LbxCloseDownExtensions();
 
276
#endif
 
277
 
 
278
    for (i = NumExtensions - 1; i >= 0; i--)
 
279
    {
 
280
        (* extensions[i]->CloseDown)(extensions[i]);
 
281
        NumExtensions = i;
 
282
        xfree(extensions[i]->name);
 
283
        for (j = extensions[i]->num_aliases; --j >= 0;)
 
284
            xfree(extensions[i]->aliases[j]);
 
285
        xfree(extensions[i]->aliases);
 
286
        xfree(extensions[i]);
 
287
    }
 
288
    xfree(extensions);
 
289
    extensions = (ExtensionEntry **)NULL;
 
290
    lastEvent = EXTENSION_EVENT_BASE;
 
291
    lastError = FirstExtensionError;
 
292
    for (i=0; i<MAXSCREENS; i++)
 
293
    {
 
294
        register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
 
295
 
 
296
        while (spentry->num)
 
297
        {
 
298
            spentry->num--;
 
299
            xfree(spentry->procList[spentry->num].name);
 
300
        }
 
301
        xfree(spentry->procList);
 
302
        spentry->procList = (ProcEntryPtr)NULL;
 
303
    }
 
304
}
 
305
 
 
306
 
 
307
int
 
308
ProcQueryExtension(ClientPtr client)
 
309
{
 
310
    xQueryExtensionReply reply;
 
311
    int i;
 
312
    REQUEST(xQueryExtensionReq);
 
313
 
 
314
    REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
 
315
    
 
316
    reply.type = X_Reply;
 
317
    reply.length = 0;
 
318
    reply.major_opcode = 0;
 
319
    reply.sequenceNumber = client->sequence;
 
320
 
 
321
    if ( ! NumExtensions )
 
322
        reply.present = xFalse;
 
323
    else
 
324
    {
 
325
        i = FindExtension((char *)&stuff[1], stuff->nbytes);
 
326
        if (i < 0
 
327
#ifdef XCSECURITY
 
328
            /* don't show insecure extensions to untrusted clients */
 
329
            || (client->trustLevel == XSecurityClientUntrusted &&
 
330
                !extensions[i]->secure)
 
331
#endif
 
332
            )
 
333
            reply.present = xFalse;
 
334
        else
 
335
        {            
 
336
            reply.present = xTrue;
 
337
            reply.major_opcode = extensions[i]->base;
 
338
            reply.first_event = extensions[i]->eventBase;
 
339
            reply.first_error = extensions[i]->errorBase;
 
340
        }
 
341
    }
 
342
    WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
 
343
    return(client->noClientException);
 
344
}
 
345
 
 
346
int
 
347
ProcListExtensions(ClientPtr client)
 
348
{
 
349
    xListExtensionsReply reply;
 
350
    char *bufptr, *buffer;
 
351
    int total_length = 0;
 
352
 
 
353
    REQUEST_SIZE_MATCH(xReq);
 
354
 
 
355
    reply.type = X_Reply;
 
356
    reply.nExtensions = 0;
 
357
    reply.length = 0;
 
358
    reply.sequenceNumber = client->sequence;
 
359
    buffer = NULL;
 
360
 
 
361
    if ( NumExtensions )
 
362
    {
 
363
        register int i, j;
 
364
 
 
365
        for (i=0;  i<NumExtensions; i++)
 
366
        {
 
367
#ifdef XCSECURITY
 
368
            /* don't show insecure extensions to untrusted clients */
 
369
            if (client->trustLevel == XSecurityClientUntrusted &&
 
370
                !extensions[i]->secure)
 
371
                continue;
 
372
#endif
 
373
            total_length += strlen(extensions[i]->name) + 1;
 
374
            reply.nExtensions += 1 + extensions[i]->num_aliases;
 
375
            for (j = extensions[i]->num_aliases; --j >= 0;)
 
376
                total_length += strlen(extensions[i]->aliases[j]) + 1;
 
377
        }
 
378
        reply.length = (total_length + 3) >> 2;
 
379
        buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
 
380
        if (!buffer)
 
381
            return(BadAlloc);
 
382
        for (i=0;  i<NumExtensions; i++)
 
383
        {
 
384
            int len;
 
385
#ifdef XCSECURITY
 
386
            if (client->trustLevel == XSecurityClientUntrusted &&
 
387
                !extensions[i]->secure)
 
388
                continue;
 
389
#endif
 
390
            *bufptr++ = len = strlen(extensions[i]->name);
 
391
            memmove(bufptr, extensions[i]->name,  len);
 
392
            bufptr += len;
 
393
            for (j = extensions[i]->num_aliases; --j >= 0;)
 
394
            {
 
395
                *bufptr++ = len = strlen(extensions[i]->aliases[j]);
 
396
                memmove(bufptr, extensions[i]->aliases[j],  len);
 
397
                bufptr += len;
 
398
            }
 
399
        }
 
400
    }
 
401
    WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
 
402
    if (reply.length)
 
403
    {
 
404
        WriteToClient(client, total_length, buffer);
 
405
        DEALLOCATE_LOCAL(buffer);
 
406
    }
 
407
    return(client->noClientException);
 
408
}
 
409
 
 
410
 
 
411
ExtensionLookupProc 
 
412
LookupProc(char *name, GCPtr pGC)
 
413
{
 
414
    register int i;
 
415
    register ScreenProcEntry *spentry;
 
416
    spentry  = &AuxillaryScreenProcs[pGC->pScreen->myNum];
 
417
    if (spentry->num)    
 
418
    {
 
419
        for (i = 0; i < spentry->num; i++)
 
420
            if (strcmp(name, spentry->procList[i].name) == 0)
 
421
                return(spentry->procList[i].proc);
 
422
    }
 
423
    return (ExtensionLookupProc)NULL;
 
424
}
 
425
 
 
426
Bool
 
427
RegisterProc(char *name, GC *pGC, ExtensionLookupProc proc)
 
428
{
 
429
    return RegisterScreenProc(name, pGC->pScreen, proc);
 
430
}
 
431
 
 
432
Bool
 
433
RegisterScreenProc(char *name, ScreenPtr pScreen, ExtensionLookupProc proc)
 
434
{
 
435
    register ScreenProcEntry *spentry;
 
436
    register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
 
437
    char *newname;
 
438
    int i;
 
439
 
 
440
    spentry = &AuxillaryScreenProcs[pScreen->myNum];
 
441
    /* first replace duplicates */
 
442
    if (spentry->num)
 
443
    {
 
444
        for (i = 0; i < spentry->num; i++)
 
445
            if (strcmp(name, spentry->procList[i].name) == 0)
 
446
            {
 
447
                procEntry = &spentry->procList[i];
 
448
                break;
 
449
            }
 
450
    }
 
451
    if (procEntry)
 
452
        procEntry->proc = proc;
 
453
    else
 
454
    {
 
455
        newname = (char *)xalloc(strlen(name)+1);
 
456
        if (!newname)
 
457
            return FALSE;
 
458
        procEntry = (ProcEntryPtr)
 
459
                            xrealloc(spentry->procList,
 
460
                                     sizeof(ProcEntryRec) * (spentry->num+1));
 
461
        if (!procEntry)
 
462
        {
 
463
            xfree(newname);
 
464
            return FALSE;
 
465
        }
 
466
        spentry->procList = procEntry;
 
467
        procEntry += spentry->num;
 
468
        procEntry->name = newname;
 
469
        strcpy(newname, name);
 
470
        procEntry->proc = proc;
 
471
        spentry->num++;        
 
472
    }
 
473
    return TRUE;
 
474
}