difsutils.c revision bbe1b32b
1/* $Xorg: difsutils.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */ 2/* 3 * misc utility routines 4 */ 5/* 6 7Copyright 1990, 1991, 1998 The Open Group 8 9Permission to use, copy, modify, distribute, and sell this software and its 10documentation for any purpose is hereby granted without fee, provided that 11the above copyright notice appear in all copies and that both that 12copyright notice and this permission notice appear in supporting 13documentation. 14 15The above copyright notice and this permission notice shall be included in 16all copies or substantial portions of the Software. 17 18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25Except as contained in this notice, the name of The Open Group shall not be 26used in advertising or otherwise to promote the sale, use or other dealings 27in this Software without prior written authorization from The Open Group. 28 29 * Copyright 1990, 1991 Network Computing Devices; 30 * Portions Copyright 1987 by Digital Equipment Corporation 31 * 32 * Permission to use, copy, modify, distribute, and sell this software and 33 * its documentation for any purpose is hereby granted without fee, provided 34 * that the above copyright notice appear in all copies and that both that 35 * copyright notice and this permission notice appear in supporting 36 * documentation, and that the names of Network Computing Devices, or Digital 37 * not be used in advertising or publicity pertaining to distribution 38 * of the software without specific, written prior permission. 39 * 40 * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH 41 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 42 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, 43 * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 44 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 45 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 46 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 47 * THIS SOFTWARE. 48 */ 49/* $XFree86: xc/programs/xfs/difs/difsutils.c,v 1.6 2001/01/17 23:45:28 dawes Exp $ */ 50 51#define XK_LATIN1 52 53#include <difsutils.h> 54 55#include <stdio.h> 56#include <ctype.h> 57#include "misc.h" 58#include "globals.h" 59#include "clientstr.h" 60#include "accstr.h" 61#include <X11/fonts/fontstruct.h> 62#include <X11/keysymdef.h> 63 64#include "authstr.h" 65#include "auth.h" 66#include "client.h" 67 68extern ClientPtr currentClient; 69static FontResolutionPtr default_resolutions; 70static int num_resolutions; 71static int default_point_size = 120; 72 73AuthContextPtr 74GetClientAuthorization(void) 75{ 76 return currentClient->auth; 77} 78 79void 80SetDefaultPointSize(int ps) 81{ 82 int i; 83 84 default_point_size = ps; 85 for (i = 0; i < num_resolutions; i++) 86 default_resolutions[i].point_size = ps; 87} 88 89int 90SetDefaultResolutions(char *str) 91{ 92 int num, 93 numr = 0, 94 n; 95 char *s; 96 FontResolutionPtr new, 97 nr; 98 int state; 99 100 s = str; 101 while (*s) { /* count commas */ 102 if (*s == ',') 103 numr++; 104 s++; 105 } 106 107 if ((numr % 2) != 1) { /* must be multiple of 2 + 1 */ 108 return FSBadResolution; 109 } 110 numr = (numr + 1) / 2; 111 nr = new = (FontResolutionPtr) fsalloc(sizeof(FontResolutionRec) 112 * numr); 113 if (!new) 114 return FSBadAlloc; 115 s = str; 116 num = 0; 117 state = 0; 118 while (*s) { 119 if (*s == ',') { 120 if (state == 0) { 121 nr->x_resolution = num; 122 state++; 123 } else { 124 state = 0; 125 nr->y_resolution = num; 126 nr->point_size = default_point_size; 127 nr++; 128 } 129 num = 0; 130 s++; 131 continue; 132 } 133 if (!isdigit(*s)) { 134 fsfree((char *) new); 135 return FSBadResolution; 136 } 137 n = *s - '0'; 138 num = num * 10 + n; 139 s++; 140 } 141 142 /* do the last one */ 143 assert(state == 1); 144 nr->y_resolution = num; 145 nr->point_size = default_point_size; 146 147 if (default_resolutions) { 148 fsfree((char *) default_resolutions); 149 } 150 default_resolutions = new; 151 num_resolutions = numr; 152 return FSSuccess; 153} 154 155FontResolutionPtr 156GetClientResolutions(int *num) 157{ 158 /* return the client's if it has them, otherwise the default values */ 159 if (currentClient->num_resolutions) { 160 *num = currentClient->num_resolutions; 161 return (FontResolutionPtr) currentClient->resolutions; 162 } else { 163 *num = num_resolutions; 164 return default_resolutions; 165 } 166} 167 168int 169GetDefaultPointSize(void) 170{ 171 FontResolutionPtr res; 172 int num; 173 174 res = GetClientResolutions(&num); 175 if (res) 176 return res->point_size; 177 else 178 return default_point_size; 179} 180 181Bool 182XpClientIsBitmapClient(ClientPtr client) 183{ 184 return TRUE; 185} 186 187Bool 188XpClientIsPrintClient(ClientPtr client, FontPathElementPtr fpe) 189{ 190 return FALSE; 191} 192 193void 194CopyISOLatin1Lowered(unsigned char *dest, unsigned char *source, int length) 195{ 196 register int i; 197 198 for (i = 0; i < length; i++, source++, dest++) { 199 if ((*source >= XK_A) && (*source <= XK_Z)) 200 *dest = *source + (XK_a - XK_A); 201 else if ((*source >= XK_Agrave) && (*source <= XK_Odiaeresis)) 202 *dest = *source + (XK_agrave - XK_Agrave); 203 else if ((*source >= XK_Ooblique) && (*source <= XK_Thorn)) 204 *dest = *source + (XK_oslash - XK_Ooblique); 205 else 206 *dest = *source; 207 } 208 *dest = '\0'; 209} 210 211int 212strncmpnocase( 213 char *first, 214 char *second, 215 int n) 216{ 217 register unsigned char *ap, 218 *bp; 219 220 for (ap = (unsigned char *) first, 221 bp = (unsigned char *) second; 222 /* SUPPRESS 112 */ 223 n > 0 && *ap && *bp; n--, ap++, bp++) { 224 register unsigned char a, 225 b; 226 227 /* SUPPRESS 112 */ 228 if ((a = *ap) != (b = *bp)) { 229 /* try lowercasing and try again */ 230 231 if ((a >= XK_A) && (a <= XK_Z)) 232 a += (XK_a - XK_A); 233 else if ((a >= XK_Agrave) && (a <= XK_Odiaeresis)) 234 a += (XK_agrave - XK_Agrave); 235 else if ((a >= XK_Ooblique) && (a <= XK_Thorn)) 236 a += (XK_oslash - XK_Ooblique); 237 238 if ((b >= XK_A) && (b <= XK_Z)) 239 b += (XK_a - XK_A); 240 else if ((b >= XK_Agrave) && (b <= XK_Odiaeresis)) 241 b += (XK_agrave - XK_Agrave); 242 else if ((b >= XK_Ooblique) && (b <= XK_Thorn)) 243 b += (XK_oslash - XK_Ooblique); 244 245 if (a != b) 246 break; 247 } 248 } 249 /* SUPPRESS 112 */ 250 return (n ? (((int) *ap) - ((int) *bp)) : 0); 251} 252 253void 254NoopDDA(void) 255{ 256} 257 258/* host list manipulation */ 259int 260AddHost( 261 HostList *list, 262 HostAddress *addr) 263{ 264 HostAddress *new; 265 266 new = (HostAddress *) fsalloc(sizeof(HostAddress)); 267 if (!new) 268 return FSBadAlloc; 269 new->address = (pointer) fsalloc(addr->addr_len); 270 if (!new->address) { 271 fsfree((char *) addr); 272 return FSBadAlloc; 273 } 274 new->type = addr->type; 275 new->addr_len = addr->addr_len; 276 memmove( (char *) new->address, (char *) addr->address, new->addr_len); 277 278 new->next = *list; 279 *list = new; 280 return FSSuccess; 281} 282 283int 284RemoveHost( 285 HostList *list, 286 HostAddress *addr) 287{ 288 HostAddress *t, 289 *last; 290 291 last = (HostAddress *) 0; 292 t = *list; 293 while (t) { 294 if (t->type == addr->type && 295 t->addr_len == addr->addr_len && 296 memcmp((char *) t->address, (char *) addr->address, 297 min(t->addr_len, addr->addr_len)) == 0) { 298 if (last) { 299 last->next = t->next; 300 } else { 301 *list = t->next; 302 } 303 fsfree((char *) t->address); 304 fsfree((char *) t); 305 return FSSuccess; 306 } 307 last = t; 308 t = t->next; 309 } 310 return FSBadName; /* bad host name */ 311} 312 313Bool 314ValidHost( 315 HostList list, 316 HostAddress *addr) 317{ 318 HostAddress *t; 319 320 t = list; 321 while (t) { 322 if (t->type == addr->type && 323 t->addr_len == addr->addr_len && 324 memcmp((char *) t->address, (char *) addr->address, 325 min(t->addr_len, addr->addr_len)) == 0) { 326 return TRUE; 327 } 328 } 329 return FALSE; 330} 331 332/* block & wakeup handlers */ 333 334typedef struct _BlockHandler { 335 BlockHandlerProcPtr BlockHandler; 336 DifsWakeupFunc WakeupHandler; 337 pointer blockData; 338 Bool deleted; 339} BlockHandlerRec, *BlockHandlerPtr; 340 341static BlockHandlerPtr handlers; 342static int numHandlers; 343static int sizeHandlers; 344static Bool inHandler; 345static Bool handlerDeleted; 346 347/* called from the OS layer */ 348void 349BlockHandler( 350 OSTimePtr pTimeout, /* DIX doesn't want to know how OS represents 351 * time */ 352 pointer pReadmask) /* nor how it represents the set of 353 * descriptors */ 354{ 355 register int i, 356 j; 357 358 ++inHandler; 359 for (i = 0; i < numHandlers; i++) 360 (*handlers[i].BlockHandler) (handlers[i].blockData, 361 pTimeout, pReadmask); 362 if (handlerDeleted) { 363 for (i = 0; i < numHandlers;) 364 if (handlers[i].deleted) { 365 for (j = i; j < numHandlers - 1; j++) 366 handlers[j] = handlers[j + 1]; 367 numHandlers--; 368 } else 369 i++; 370 } 371 --inHandler; 372} 373 374 375void 376WakeupHandler( 377 int result, /* result from the wait */ 378 unsigned long * pReadmask) /* the resulting descriptor mask */ 379{ 380 register int i, 381 j; 382 383 ++inHandler; 384 for (i = numHandlers - 1; i >= 0; i--) 385 (*handlers[i].WakeupHandler) (handlers[i].blockData, 386 result, pReadmask); 387 if (handlerDeleted) { 388 for (i = 0; i < numHandlers;) 389 if (handlers[i].deleted) { 390 for (j = i; j < numHandlers - 1; j++) 391 handlers[j] = handlers[j + 1]; 392 numHandlers--; 393 } else 394 i++; 395 } 396 --inHandler; 397} 398 399/* Reentrant with BlockHandler and WakeupHandler, except wakeup won't 400 * get called until next time 401 */ 402 403Bool 404RegisterBlockAndWakeupHandlers( 405 BlockHandlerProcPtr blockHandler, 406 DifsWakeupFunc wakeupHandler, 407 pointer blockData) 408{ 409 BlockHandlerPtr new; 410 411 if (numHandlers >= sizeHandlers) { 412 new = (BlockHandlerPtr) fsrealloc(handlers, (numHandlers + 1) * 413 sizeof(BlockHandlerRec)); 414 if (!new) 415 return FALSE; 416 handlers = new; 417 sizeHandlers = numHandlers + 1; 418 } 419 handlers[numHandlers].BlockHandler = blockHandler; 420 handlers[numHandlers].WakeupHandler = wakeupHandler; 421 handlers[numHandlers].blockData = blockData; 422 numHandlers = numHandlers + 1; 423 return TRUE; 424} 425 426void 427RemoveBlockAndWakeupHandlers( 428 BlockHandlerProcPtr blockHandler, 429 DifsWakeupFunc wakeupHandler, 430 pointer blockData) 431{ 432 int i; 433 434 for (i = 0; i < numHandlers; i++) 435 if (handlers[i].BlockHandler == blockHandler && 436 handlers[i].WakeupHandler == wakeupHandler && 437 handlers[i].blockData == blockData) { 438 if (inHandler) { 439 handlerDeleted = TRUE; 440 handlers[i].deleted = TRUE; 441 } else { 442 for (; i < numHandlers - 1; i++) 443 handlers[i] = handlers[i + 1]; 444 numHandlers--; 445 } 446 break; 447 } 448} 449 450void 451InitBlockAndWakeupHandlers(void) 452{ 453 fsfree(handlers); 454 handlers = (BlockHandlerPtr) 0; 455 numHandlers = 0; 456 sizeHandlers = 0; 457} 458 459/* 460 * A general work queue. Perform some task before the server 461 * sleeps for input. 462 */ 463 464WorkQueuePtr workQueue; 465static WorkQueuePtr *workQueueLast = &workQueue; 466 467/* ARGSUSED */ 468void 469ProcessWorkQueue(void) 470{ 471 WorkQueuePtr q, 472 n, 473 p; 474 475 p = NULL; 476 /* 477 * Scan the work queue once, calling each function. Those which return 478 * TRUE are removed from the queue, otherwise they will be called again. 479 * This must be reentrant with QueueWorkProc, hence the crufty usage of 480 * variables. 481 */ 482 for (q = workQueue; q; q = n) { 483 if ((*q->function) (q->client, q->closure)) { 484 /* remove q from the list */ 485 n = q->next; /* don't fetch until after func called */ 486 if (p) 487 p->next = n; 488 else 489 workQueue = n; 490 fsfree(q); 491 } else { 492 n = q->next; /* don't fetch until after func called */ 493 p = q; 494 } 495 } 496 if (p) 497 workQueueLast = &p->next; 498 else { 499 workQueueLast = &workQueue; 500 } 501} 502 503Bool 504QueueWorkProc( 505 Bool (*function) (ClientPtr, pointer), 506 ClientPtr client, 507 pointer data) 508{ 509 WorkQueuePtr q; 510 511 q = (WorkQueuePtr) fsalloc(sizeof *q); 512 if (!q) 513 return FALSE; 514 q->function = function; 515 q->client = client; 516 q->closure = data; 517 q->next = NULL; 518 *workQueueLast = q; 519 workQueueLast = &q->next; 520 return TRUE; 521} 522 523/* 524 * Manage a queue of sleeping clients, awakening them 525 * when requested, by using the OS functions IgnoreClient 526 * and AttendClient. Note that this *ignores* the troubles 527 * with request data interleaving itself with events, but 528 * we'll leave that until a later time. 529 */ 530 531typedef struct _SleepQueue { 532 struct _SleepQueue *next; 533 ClientPtr client; 534 Bool (*function) (ClientPtr, pointer); 535 pointer closure; 536} SleepQueueRec, *SleepQueuePtr; 537 538static SleepQueuePtr sleepQueue = NULL; 539 540Bool 541ClientSleep( 542 ClientPtr client, 543 Bool (*function) (ClientPtr, pointer), 544 pointer data) 545{ 546 SleepQueuePtr q; 547 548 q = (SleepQueuePtr) fsalloc(sizeof *q); 549 if (!q) 550 return FALSE; 551 552 IgnoreClient(client); 553 q->next = sleepQueue; 554 q->client = client; 555 q->function = function; 556 q->closure = data; 557 sleepQueue = q; 558 return TRUE; 559} 560 561Bool 562ClientSignal(ClientPtr client) 563{ 564 SleepQueuePtr q; 565 566 for (q = sleepQueue; q; q = q->next) 567 if (q->client == client) { 568 return QueueWorkProc(q->function, q->client, q->closure); 569 } 570 return FALSE; 571} 572 573void 574ClientWakeup(ClientPtr client) 575{ 576 SleepQueuePtr q, 577 *prev; 578 579 prev = &sleepQueue; 580 while ((q = *prev) != (SleepQueuePtr) 0) { 581 if (q->client == client) { 582 *prev = q->next; 583 fsfree(q); 584 if (client->clientGone == CLIENT_GONE) 585 CloseDownClient(client); 586 else 587 AttendClient(client); 588 break; 589 } 590 prev = &q->next; 591 } 592} 593 594Bool 595ClientIsAsleep(ClientPtr client) 596{ 597 SleepQueuePtr q; 598 599 for (q = sleepQueue; q; q = q->next) 600 if (q->client == client) 601 return TRUE; 602 return FALSE; 603} 604 605pointer 606Xalloc(unsigned long m) 607{ 608 return fsalloc(m); 609} 610 611pointer 612Xrealloc(pointer n, unsigned long m) 613{ 614 return fsrealloc(n, m); 615} 616 617void 618Xfree(unsigned long *n) 619{ 620 fsfree(n); 621} 622 623pointer 624Xcalloc(unsigned long n) 625{ 626 pointer ret; 627 628 ret = fsalloc(n); 629 if (ret && n) 630 bzero(ret, n); 631 return ret; 632} 633 634int 635set_font_authorizations(char **authorizations, int *authlen, ClientPtr client) 636{ 637#define AUTH1_NAME "hp-hostname-1" 638#define AUTH2_NAME "hp-printername-1" 639 static char result[1024]; 640 char *p; 641 AuthContextPtr acp = client->auth; 642 int len1, len2; 643 644 if (acp != NULL && acp->authname != NULL && acp->authdata != NULL && 645 (!strcmp(AUTH1_NAME, acp->authname) || 646 !strcmp(AUTH2_NAME, acp->authname)) && 647 (len1 = strlen(acp->authname) + 1) + 648 (len2 = strlen(acp->authdata) + 1) + 2 * sizeof(short) <= 1024) 649 { 650 p = result; 651 *p++ = len1 >> 8; 652 *p++ = len1 &0xff; 653 *p++ = len2 >> 8; 654 *p++ = len2 & 0xff; 655 memmove( p, acp->authname, len1); 656 p += len1; 657 memmove( p, acp->authdata, len2); 658 p += len2; 659 *authlen = p - result; 660 *authorizations = result; 661 return 1; 662 } 663 664 *authlen = 0; 665 return 0; 666} 667 668int 669client_auth_generation(ClientPtr client) 670{ 671 return client->auth_generation; 672} 673