48
48
********************************************************/
50
#include <audio/audio.h>
51
#include <audio/Aproto.h>
50
#include <audio/audio.h>
51
#include <audio/Aproto.h>
52
53
#include "dixstruct.h"
54
55
#include "opaque.h"
57
extern void ProcessAudioEvents(), SendAuErrorToClient(),
58
SwapConnClientPrefix(), ResetCurrentRequest(), WriteToClient();
59
extern int CompareTimeStamps(), WaitForSomething(), AuSendInitResponse();
60
extern Bool ClientIsAsleep(), ClientSignal();
57
extern void ProcessAudioEvents(), SendAuErrorToClient(),
58
SwapConnClientPrefix(), ResetCurrentRequest(), WriteToClient();
59
extern int CompareTimeStamps(), WaitForSomething(), AuSendInitResponse();
62
61
#define mskcnt ((MAXCLIENTS + 31) / 32)
63
62
#define BITMASK(i) (1 << ((i) & 31))
70
69
extern void NotImplemented();
71
70
extern Bool InitClientResources();
73
extern int (* InitialVector[3]) ();
74
extern void Swap32Write(), WriteSConnectionInfo();
72
extern int (*InitialVector[3]) ();
75
73
extern void WriteSConnSetupPrefix();
76
74
extern char *ClientAuthorized();
77
75
extern Bool InsertFakeRequest();
78
static void KillAllClients();
79
extern void ProcessWorkQueue();
81
extern int (* AuProcVector[256]) ();
82
extern int (* AuSwappedProcVector[256]) ();
83
extern void (* AuEventSwapVector[256]) ();
84
extern void (* AuReplySwapVector[256]) ();
86
static int nextFreeClientID; /* always MIN free client ID */
88
static int nClients; /* number active clients */
76
static void KillAllClients(void);
78
extern int (*AuProcVector[256]) ();
79
extern int (*AuSwappedProcVector[256]) ();
80
extern void (*AuEventSwapVector[256]) ();
81
extern void (*AuReplySwapVector[256]) ();
83
static int nextFreeClientID; /* always MIN free client ID */
85
static int nClients; /* number active clients */
90
87
char dispatchException = 0;
91
88
char isItTimeToYield;
95
92
* Rather than changing interfaces and breaking untold code we introduce
96
93
* a new global that dispatch can use.
98
AuID clientErrorValue; /* XXX this is a kludge */
105
/* To avoid time running backwards, we must call GetTimeInMillis before
106
* calling ProcessInputEvents.
108
systime.months = currentTime.months;
109
systime.milliseconds = GetTimeInMillis();
110
if (systime.milliseconds < currentTime.milliseconds)
112
ProcessAudioEvents();
113
if (CompareTimeStamps(systime, currentTime) == LATER)
114
currentTime = systime;
95
AuID clientErrorValue; /* XXX this is a kludge */
117
97
/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
119
UpdateCurrentTimeIf()
99
UpdateCurrentTimeIf(void)
121
101
TimeStamp systime;
123
103
systime.months = currentTime.months;
124
104
systime.milliseconds = GetTimeInMillis();
125
105
if (systime.milliseconds < currentTime.milliseconds)
128
108
currentTime = systime;
136
register int *clientReady; /* array of request ready clients */
138
register ClientPtr client;
116
int *clientReady; /* array of request ready clients */
141
121
nextFreeClientID = 1;
144
124
clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
145
125
if (!clientReady)
148
while (!dispatchException)
150
FlushIfCriticalOutputPending();
152
ProcessAudioEvents();
154
nready = WaitForSomething(clientReady);
128
while (!dispatchException) {
129
FlushIfCriticalOutputPending();
131
ProcessAudioEvents();
133
nready = WaitForSomething(clientReady);
156
135
/*****************
157
* Handle events in round robin fashion, doing input between
161
while (!dispatchException && (--nready >= 0))
163
client = clients[clientReady[nready]];
166
/* KillClient can cause this to happen */
169
isItTimeToYield = FALSE;
171
while (!isItTimeToYield)
173
FlushIfCriticalOutputPending();
175
ProcessAudioEvents();
177
/* now, finally, deal with client requests */
179
result = ReadRequestFromClient(client);
183
CloseDownClient(client);
136
* Handle events in round robin fashion, doing input between
140
while (!dispatchException && (--nready >= 0)) {
141
client = clients[clientReady[nready]];
143
/* KillClient can cause this to happen */
146
isItTimeToYield = FALSE;
148
while (!isItTimeToYield) {
149
FlushIfCriticalOutputPending();
151
ProcessAudioEvents();
153
/* now, finally, deal with client requests */
155
result = ReadRequestFromClient(client);
158
CloseDownClient(client);
189
if (client->requestLogIndex == MAX_REQUEST_LOG)
190
client->requestLogIndex = 0;
191
client->requestLog[client->requestLogIndex] = MAJOROP;
192
client->requestLogIndex++;
164
if (client->requestLogIndex == MAX_REQUEST_LOG)
165
client->requestLogIndex = 0;
166
client->requestLog[client->requestLogIndex] = MAJOROP;
167
client->requestLogIndex++;
194
if (result > (MAX_BIG_REQUEST_SIZE << 2))
195
result = AuBadLength;
197
result = (* client->requestVector[MAJOROP])(client);
199
if (result != AuSuccess)
201
if (client->noClientException != AuSuccess)
169
if (result > (MAX_BIG_REQUEST_SIZE << 2))
170
result = AuBadLength;
172
result = (*client->requestVector[MAJOROP]) (client);
174
if (result != AuSuccess) {
175
if (client->noClientException != AuSuccess)
202
176
CloseDownClient(client);
204
SendAuErrorToClient(client, MAJOROP,
205
0, client->errorValue, result);
178
SendAuErrorToClient(client, MAJOROP,
179
0, client->errorValue, result);
212
186
KillAllClients();
213
187
DEALLOCATE_LOCAL(clientReady);
254
224
Bool terminateAtReset = FALSE;
257
CloseDownClient(client)
258
register ClientPtr client;
227
CloseDownClient(ClientPtr client)
260
if (!client->clientGone)
262
client->clientGone = TRUE; /* so events aren't sent to client */
263
CloseDownConnection(client);
265
if (client->closeDownMode == AuCloseDownDestroy)
267
FreeClientResources(client);
268
if (ClientIsAsleep (client))
269
ClientSignal (client);
270
if (client->index < nextFreeClientID)
271
nextFreeClientID = client->index;
272
clients[client->index] = NullClient;
274
/* Pebl: decrease first as the compiler might skip the second test
275
* if first fails, then check if client was idle. BUG: if a
276
* persistent client is running flows all flows are killed if
277
* there is no more clients, except if it was the only client. */
278
if ((--nClients == 0) &&
279
(client->requestVector != InitialVector))
281
if (terminateAtReset)
282
dispatchException |= DE_TERMINATE;
284
dispatchException |= DE_RESET;
295
/* really kill resources this time */
229
if (!client->clientGone) {
230
client->clientGone = TRUE; /* so events aren't sent to client */
231
CloseDownConnection(client);
233
if (client->closeDownMode == AuCloseDownDestroy) {
234
FreeClientResources(client);
235
if (client->index < nextFreeClientID)
236
nextFreeClientID = client->index;
237
clients[client->index] = NullClient;
239
/* Pebl: decrease first as the compiler might skip the second test
240
* if first fails, then check if client was idle. BUG: if a
241
* persistent client is running flows all flows are killed if
242
* there is no more clients, except if it was the only client. */
243
if ((--nClients == 0) &&
244
(client->requestVector != InitialVector)) {
245
if (terminateAtReset)
246
dispatchException |= DE_TERMINATE;
248
dispatchException |= DE_RESET;
255
/* really kill resources this time */
296
256
FreeClientResources(client);
297
if (ClientIsAsleep (client))
298
ClientSignal (client);
299
if (client->index < nextFreeClientID)
300
nextFreeClientID = client->index;
301
clients[client->index] = NullClient;
257
if (client->index < nextFreeClientID)
258
nextFreeClientID = client->index;
259
clients[client->index] = NullClient;
305
while (!clients[currentMaxClients-1])
263
while (!clients[currentMaxClients - 1])
313
for (i=1; i<currentMaxClients; i++)
271
for (i = 1; i < currentMaxClients; i++)
315
CloseDownClient(clients[i]);
273
CloseDownClient(clients[i]);
318
276
/*********************
366
321
*************************/
369
NextAvailableClient(ospriv)
324
NextAvailableClient(pointer ospriv)
373
register ClientPtr client;
376
330
i = nextFreeClientID;
377
331
if (i == MAXCLIENTS)
378
return (ClientPtr)NULL;
379
clients[i] = client = (ClientPtr)xalloc(sizeof(ClientRec));
332
return (ClientPtr) NULL;
333
clients[i] = client = (ClientPtr) xalloc(sizeof(ClientRec));
381
return (ClientPtr)NULL;
335
return (ClientPtr) NULL;
382
336
InitClient(client, i, ospriv);
383
if (!InitClientResources(client))
386
return (ClientPtr)NULL;
337
if (!InitClientResources(client)) {
339
return (ClientPtr) NULL;
388
341
data.reqType = 1;
389
342
data.length = (sz_auReq + sz_auConnClientPrefix) >> 2;
390
if (!InsertFakeRequest(client, (char *)&data, sz_auReq))
392
FreeClientResources(client);
394
return (ClientPtr)NULL;
343
if (!InsertFakeRequest(client, (char *) &data, sz_auReq)) {
344
FreeClientResources(client);
346
return (ClientPtr) NULL;
396
348
if (i == currentMaxClients)
398
350
while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
404
ProcInitialConnection(client)
405
register ClientPtr client;
356
ProcInitialConnection(ClientPtr client)
408
register auConnClientPrefix *prefix;
359
auConnClientPrefix *prefix;
409
360
int whichbyte = 1;
411
prefix = (auConnClientPrefix *)((char *)stuff + sz_auReq);
362
prefix = (auConnClientPrefix *) ((char *) stuff + sz_auReq);
412
363
if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
413
return (client->noClientException = -1);
364
return (client->noClientException = -1);
414
365
if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
415
(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
417
client->swapped = TRUE;
418
SwapConnClientPrefix(prefix);
366
(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) {
367
client->swapped = TRUE;
368
SwapConnClientPrefix(prefix);
420
370
stuff->reqType = 2;
421
371
stuff->length += (((int) prefix->nbytesAuthProto + 3) >> 2) +
422
(((int) prefix->nbytesAuthString + 3) >> 2);
425
swaps(&stuff->length, whichbyte);
372
(((int) prefix->nbytesAuthString + 3) >> 2);
373
if (client->swapped) {
374
swaps(&stuff->length, whichbyte);
427
376
ResetCurrentRequest(client);
428
377
return (client->noClientException);
432
ProcEstablishConnection(client)
433
register ClientPtr client;
381
ProcEstablishConnection(ClientPtr client)
435
383
char *reason, *auth_proto, *auth_string;
436
register auConnClientPrefix *prefix;
384
auConnClientPrefix *prefix;
439
prefix = (auConnClientPrefix *)((char *)stuff + sz_auReq);
440
auth_proto = (char *)prefix + sz_auConnClientPrefix;
387
prefix = (auConnClientPrefix *) ((char *) stuff + sz_auReq);
388
auth_proto = (char *) prefix + sz_auConnClientPrefix;
441
389
auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
442
390
if (prefix->majorVersion != AuProtocolMajorVersion)
443
reason = "Protocol version mismatch";
391
reason = "Protocol version mismatch";
445
reason = ClientAuthorized(client,
446
(unsigned short)prefix->nbytesAuthProto,
448
(unsigned short)prefix->nbytesAuthString,
452
auConnSetupPrefix csp;
393
reason = ClientAuthorized(client,
394
(unsigned short) prefix->nbytesAuthProto,
396
(unsigned short) prefix->
397
nbytesAuthString, auth_string);
399
auConnSetupPrefix csp;
455
csp.success = auFalse;
456
csp.lengthReason = strlen(reason);
457
csp.length = ((int) csp.lengthReason + 3) >> 2;
458
csp.majorVersion = AuProtocolMajorVersion;
459
csp.minorVersion = AuProtocolMinorVersion;
461
WriteSConnSetupPrefix(client, &csp);
463
(void)WriteToClient(client, sz_auConnSetupPrefix, (char *) &csp);
464
(void)WriteToClient(client, (int)csp.lengthReason, reason);
465
if (csp.lengthReason & 3)
466
(void)WriteToClient(client, (int)(4 - (csp.lengthReason & 3)),
468
return (client->noClientException = -1);
402
csp.success = auFalse;
403
csp.lengthReason = strlen(reason);
404
csp.length = ((int) csp.lengthReason + 3) >> 2;
405
csp.majorVersion = AuProtocolMajorVersion;
406
csp.minorVersion = AuProtocolMinorVersion;
408
WriteSConnSetupPrefix(client, &csp);
410
(void) WriteToClient(client, sz_auConnSetupPrefix,
412
(void) WriteToClient(client, (int) csp.lengthReason, reason);
413
if (csp.lengthReason & 3)
414
(void) WriteToClient(client,
415
(int) (4 - (csp.lengthReason & 3)), pad);
416
return (client->noClientException = -1);
472
420
client->sequence = 0;
473
client->requestVector =
474
client->swapped ? AuSwappedProcVector : AuProcVector;
421
client->requestVector =
422
client->swapped ? AuSwappedProcVector : AuProcVector;
475
423
return AuSendInitResponse(client);
479
MarkClientException(client)
427
MarkClientException(ClientPtr client)
482
429
client->noClientException = -1;