1 /***********************************************************
3 Copyright (c) 1987 X Consortium
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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 X CONSORTIUM 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.
22 Except as contained in this notice, the name of the X Consortium 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 X Consortium.
27 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
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.
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
47 ******************************************************************/
48 /* $XConsortium: extension.c /main/36 1996/09/28 11:23:27 rws $ */
49 /* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.5 1996/12/23 06:29:44 dawes Exp $ */
56 #include "dixstruct.h"
57 #include "extnsionst.h"
59 #include "scrnintstr.h"
62 #define _SECURITY_SERVER
63 #include "extensions/security.h"
66 #define EXTENSION_BASE 128
67 #define EXTENSION_EVENT_BASE 64
68 #define LAST_EVENT 128
69 #define LAST_ERROR 255
71 ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
73 static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
75 int lastEvent = EXTENSION_EVENT_BASE;
76 static int lastError = FirstExtensionError;
77 static unsigned int NumExtensions = 0;
79 ExtensionEntry *AddExtension(name, NumEvents, NumErrors, MainProc,
80 SwappedMainProc, CloseDownProc, MinorOpcodeProc)
85 int (* SwappedMainProc)();
86 void (* CloseDownProc)();
87 unsigned short (* MinorOpcodeProc)();
90 register ExtensionEntry *ext, **newexts;
92 if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
93 return((ExtensionEntry *) NULL);
94 if ((lastEvent + NumEvents > LAST_EVENT) ||
95 (unsigned)(lastError + NumErrors > LAST_ERROR))
96 return((ExtensionEntry *) NULL);
98 ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
100 return((ExtensionEntry *) NULL);
101 ext->name = (char *)xalloc(strlen(name) + 1);
102 ext->num_aliases = 0;
103 ext->aliases = (char **)NULL;
107 return((ExtensionEntry *) NULL);
109 strcpy(ext->name, name);
111 newexts = (ExtensionEntry **) xrealloc(extensions,
112 (i + 1) * sizeof(ExtensionEntry *));
117 return((ExtensionEntry *) NULL);
120 extensions = newexts;
123 ext->base = i + EXTENSION_BASE;
124 ext->CloseDown = CloseDownProc;
125 ext->MinorOpcode = MinorOpcodeProc;
126 ProcVector[i + EXTENSION_BASE] = MainProc;
127 SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
130 ext->eventBase = lastEvent;
131 ext->eventLast = lastEvent + NumEvents;
132 lastEvent += NumEvents;
141 ext->errorBase = lastError;
142 ext->errorLast = lastError + NumErrors;
143 lastError += NumErrors;
155 (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
160 Bool AddExtensionAlias(alias, ext)
167 aliases = (char **)xrealloc(ext->aliases,
168 (ext->num_aliases + 1) * sizeof(char *));
171 ext->aliases = aliases;
172 name = (char *)xalloc(strlen(alias) + 1);
176 ext->aliases[ext->num_aliases] = name;
179 return LbxAddExtensionAlias(ext->index, alias);
186 FindExtension(extname, len)
192 for (i=0; i<NumExtensions; i++)
194 if ((strlen(extensions[i]->name) == len) &&
195 !strncmp(extname, extensions[i]->name, len))
197 for (j = extensions[i]->num_aliases; --j >= 0;)
199 if ((strlen(extensions[i]->aliases[j]) == len) &&
200 !strncmp(extname, extensions[i]->aliases[j], len))
205 return ((i == NumExtensions) ? -1 : i);
209 DeclareExtensionSecurity(extname, secure)
214 int i = FindExtension(extname, strlen(extname));
217 int majorop = extensions[i]->base;
218 extensions[i]->secure = secure;
221 UntrustedProcVector[majorop] = ProcVector[majorop];
222 SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
226 UntrustedProcVector[majorop] = ProcBadRequest;
227 SwappedUntrustedProcVector[majorop] = ProcBadRequest;
232 LbxDeclareExtensionSecurity(extname, secure);
237 StandardMinorOpcode(client)
240 return ((xReq *)client->requestBuffer)->data;
244 MinorOpcodeOfRequest(client)
249 major = ((xReq *)client->requestBuffer)->reqType;
250 if (major < EXTENSION_BASE)
252 major -= EXTENSION_BASE;
253 if (major >= NumExtensions)
255 return (*extensions[major]->MinorOpcode)(client);
259 CloseDownExtensions()
264 LbxCloseDownExtensions();
267 for (i = NumExtensions - 1; i >= 0; i--)
269 (* extensions[i]->CloseDown)(extensions[i]);
271 xfree(extensions[i]->name);
272 for (j = extensions[i]->num_aliases; --j >= 0;)
273 xfree(extensions[i]->aliases[j]);
274 xfree(extensions[i]->aliases);
275 xfree(extensions[i]);
278 extensions = (ExtensionEntry **)NULL;
279 lastEvent = EXTENSION_EVENT_BASE;
280 lastError = FirstExtensionError;
281 for (i=0; i<MAXSCREENS; i++)
283 register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
288 xfree(spentry->procList[spentry->num].name);
290 xfree(spentry->procList);
291 spentry->procList = (ProcEntryPtr)NULL;
297 ProcQueryExtension(client)
300 xQueryExtensionReply reply;
302 REQUEST(xQueryExtensionReq);
304 REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
306 reply.type = X_Reply;
308 reply.major_opcode = 0;
309 reply.sequenceNumber = client->sequence;
311 if ( ! NumExtensions )
312 reply.present = xFalse;
315 i = FindExtension((char *)&stuff[1], stuff->nbytes);
318 /* don't show insecure extensions to untrusted clients */
319 || (client->trustLevel == XSecurityClientUntrusted &&
320 !extensions[i]->secure)
323 reply.present = xFalse;
326 reply.present = xTrue;
327 reply.major_opcode = extensions[i]->base;
328 reply.first_event = extensions[i]->eventBase;
329 reply.first_error = extensions[i]->errorBase;
332 WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
333 return(client->noClientException);
337 ProcListExtensions(client)
340 xListExtensionsReply reply;
341 char *bufptr, *buffer;
342 int total_length = 0;
344 REQUEST_SIZE_MATCH(xReq);
346 reply.type = X_Reply;
347 reply.nExtensions = 0;
349 reply.sequenceNumber = client->sequence;
356 for (i=0; i<NumExtensions; i++)
359 /* don't show insecure extensions to untrusted clients */
360 if (client->trustLevel == XSecurityClientUntrusted &&
361 !extensions[i]->secure)
364 total_length += strlen(extensions[i]->name) + 1;
365 reply.nExtensions += 1 + extensions[i]->num_aliases;
366 for (j = extensions[i]->num_aliases; --j >= 0;)
367 total_length += strlen(extensions[i]->aliases[j]) + 1;
369 reply.length = (total_length + 3) >> 2;
370 buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
373 for (i=0; i<NumExtensions; i++)
377 if (client->trustLevel == XSecurityClientUntrusted &&
378 !extensions[i]->secure)
381 *bufptr++ = len = strlen(extensions[i]->name);
382 memmove(bufptr, extensions[i]->name, len);
384 for (j = extensions[i]->num_aliases; --j >= 0;)
386 *bufptr++ = len = strlen(extensions[i]->aliases[j]);
387 memmove(bufptr, extensions[i]->aliases[j], len);
392 WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
395 WriteToClient(client, total_length, buffer);
396 DEALLOCATE_LOCAL(buffer);
398 return(client->noClientException);
403 LookupProc(name, pGC)
408 register ScreenProcEntry *spentry;
409 spentry = &AuxillaryScreenProcs[pGC->pScreen->myNum];
412 for (i = 0; i < spentry->num; i++)
413 if (strcmp(name, spentry->procList[i].name) == 0)
414 return(spentry->procList[i].proc);
416 return (ExtensionLookupProc)NULL;
420 RegisterProc(name, pGC, proc)
423 ExtensionLookupProc proc;
425 return RegisterScreenProc(name, pGC->pScreen, proc);
429 RegisterScreenProc(name, pScreen, proc)
432 ExtensionLookupProc proc;
434 register ScreenProcEntry *spentry;
435 register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
439 spentry = &AuxillaryScreenProcs[pScreen->myNum];
440 /* first replace duplicates */
443 for (i = 0; i < spentry->num; i++)
444 if (strcmp(name, spentry->procList[i].name) == 0)
446 procEntry = &spentry->procList[i];
451 procEntry->proc = proc;
454 newname = (char *)xalloc(strlen(name)+1);
457 procEntry = (ProcEntryPtr)
458 xrealloc(spentry->procList,
459 sizeof(ProcEntryRec) * (spentry->num+1));
465 spentry->procList = procEntry;
466 procEntry += spentry->num;
467 procEntry->name = newname;
468 strcpy(newname, name);
469 procEntry->proc = proc;