AuGetBest.c revision 313a12fd
1/* 2 3Copyright 1988, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25*/ 26 27#ifdef HAVE_CONFIG_H 28#include <config.h> 29#endif 30#include <X11/Xauth.h> 31#include <X11/Xos.h> 32#ifdef XTHREADS 33#include <X11/Xthreads.h> 34#endif 35#ifdef hpux 36#define X_INCLUDE_NETDB_H 37#define XOS_USE_NO_LOCKING 38#include <X11/Xos_r.h> 39#endif 40 41#define binaryEqual(a, b, len) (memcmp(a, b, len) == 0) 42 43Xauth * 44XauGetBestAuthByAddr ( 45#if NeedWidePrototypes 46 unsigned int family, 47 unsigned int address_length, 48#else 49 unsigned short family, 50 unsigned short address_length, 51#endif 52 _Xconst char* address, 53#if NeedWidePrototypes 54 unsigned int number_length, 55#else 56 unsigned short number_length, 57#endif 58 _Xconst char* number, 59 int types_length, 60 char** types, 61 _Xconst int* type_lengths) 62{ 63 FILE *auth_file; 64 char *auth_name; 65 Xauth *entry; 66 Xauth *best; 67 int best_type; 68 int type; 69#ifdef hpux 70 char *fully_qual_address; 71 unsigned short fully_qual_address_length; 72#endif 73 74 auth_name = XauFileName (); 75 if (!auth_name) 76 return NULL; 77 if (access (auth_name, R_OK) != 0) /* checks REAL id */ 78 return NULL; 79 auth_file = fopen (auth_name, "rb"); 80 if (!auth_file) 81 return NULL; 82 83#ifdef hpux 84 if (family == FamilyLocal) { 85#ifdef XTHREADS_NEEDS_BYNAMEPARAMS 86 _Xgethostbynameparams hparams; 87#endif 88 struct hostent *hostp; 89 90 /* make sure we try fully-qualified hostname */ 91 if ((hostp = _XGethostbyname(address,hparams)) != NULL) { 92 fully_qual_address = hostp->h_name; 93 fully_qual_address_length = strlen(fully_qual_address); 94 } 95 else 96 { 97 fully_qual_address = NULL; 98 fully_qual_address_length = 0; 99 } 100 } 101#endif /* hpux */ 102 103 best = NULL; 104 best_type = types_length; 105 for (;;) { 106 entry = XauReadAuth (auth_file); 107 if (!entry) 108 break; 109 /* 110 * Match when: 111 * either family or entry->family are FamilyWild or 112 * family and entry->family are the same and 113 * address and entry->address are the same 114 * and 115 * either number or entry->number are empty or 116 * number and entry->number are the same 117 * and 118 * either name or entry->name are empty or 119 * name and entry->name are the same 120 */ 121 122 if ((family == FamilyWild || entry->family == FamilyWild || 123 (entry->family == family && 124 ((address_length == entry->address_length && 125 binaryEqual (entry->address, address, address_length)) 126#ifdef hpux 127 || (family == FamilyLocal && 128 fully_qual_address_length == entry->address_length && 129 binaryEqual (entry->address, fully_qual_address, 130 fully_qual_address_length)) 131#endif 132 ))) && 133 (number_length == 0 || entry->number_length == 0 || 134 (number_length == entry->number_length && 135 binaryEqual (entry->number, number, number_length)))) 136 { 137 if (best_type == 0) 138 { 139 best = entry; 140 break; 141 } 142 for (type = 0; type < best_type; type++) 143 if (type_lengths[type] == entry->name_length && 144 !(strncmp (types[type], entry->name, entry->name_length))) 145 { 146 break; 147 } 148 if (type < best_type) 149 { 150 if (best) 151 XauDisposeAuth (best); 152 best = entry; 153 best_type = type; 154 if (type == 0) 155 break; 156 continue; 157 } 158 } 159 XauDisposeAuth (entry); 160 } 161 (void) fclose (auth_file); 162 return best; 163} 164