AuGetBest.c revision 27702724
127702724Smrg/* $Xorg: AuGetBest.c,v 1.4 2001/02/09 02:03:42 xorgcvs Exp $ */
227702724Smrg
327702724Smrg/*
427702724Smrg
527702724SmrgCopyright 1988, 1998  The Open Group
627702724Smrg
727702724SmrgPermission to use, copy, modify, distribute, and sell this software and its
827702724Smrgdocumentation for any purpose is hereby granted without fee, provided that
927702724Smrgthe above copyright notice appear in all copies and that both that
1027702724Smrgcopyright notice and this permission notice appear in supporting
1127702724Smrgdocumentation.
1227702724Smrg
1327702724SmrgThe above copyright notice and this permission notice shall be included in
1427702724Smrgall copies or substantial portions of the Software.
1527702724Smrg
1627702724SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1727702724SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1827702724SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1927702724SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2027702724SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2127702724SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2227702724Smrg
2327702724SmrgExcept as contained in this notice, the name of The Open Group shall not be
2427702724Smrgused in advertising or otherwise to promote the sale, use or other dealings
2527702724Smrgin this Software without prior written authorization from The Open Group.
2627702724Smrg
2727702724Smrg*/
2827702724Smrg/* $XFree86: xc/lib/Xau/AuGetBest.c,v 1.7 2001/12/14 19:54:36 dawes Exp $ */
2927702724Smrg
3027702724Smrg#ifdef HAVE_CONFIG_H
3127702724Smrg#include <config.h>
3227702724Smrg#endif
3327702724Smrg#include <X11/Xauth.h>
3427702724Smrg#include <X11/Xos.h>
3527702724Smrg#ifdef XTHREADS
3627702724Smrg#include <X11/Xthreads.h>
3727702724Smrg#endif
3827702724Smrg#ifdef hpux
3927702724Smrg#define X_INCLUDE_NETDB_H
4027702724Smrg#define XOS_USE_NO_LOCKING
4127702724Smrg#include <X11/Xos_r.h>
4227702724Smrg#endif
4327702724Smrg
4427702724Smrgstatic int
4527702724SmrgbinaryEqual (_Xconst char *a, _Xconst char *b, int len)
4627702724Smrg{
4727702724Smrg    while (len--)
4827702724Smrg	if (*a++ != *b++)
4927702724Smrg	    return 0;
5027702724Smrg    return 1;
5127702724Smrg}
5227702724Smrg
5327702724SmrgXauth *
5427702724SmrgXauGetBestAuthByAddr (
5527702724Smrg#if NeedWidePrototypes
5627702724Smrg    unsigned int	family,
5727702724Smrg    unsigned int	address_length,
5827702724Smrg#else
5927702724Smrg    unsigned short	family,
6027702724Smrg    unsigned short	address_length,
6127702724Smrg#endif
6227702724Smrg    _Xconst char*	address,
6327702724Smrg#if NeedWidePrototypes
6427702724Smrg    unsigned int	number_length,
6527702724Smrg#else
6627702724Smrg    unsigned short	number_length,
6727702724Smrg#endif
6827702724Smrg    _Xconst char*	number,
6927702724Smrg    int			types_length,
7027702724Smrg    char**		types,
7127702724Smrg    _Xconst int*	type_lengths)
7227702724Smrg{
7327702724Smrg    FILE    *auth_file;
7427702724Smrg    char    *auth_name;
7527702724Smrg    Xauth   *entry;
7627702724Smrg    Xauth   *best;
7727702724Smrg    int	    best_type;
7827702724Smrg    int	    type;
7927702724Smrg#ifdef hpux
8027702724Smrg    char		*fully_qual_address;
8127702724Smrg    unsigned short	fully_qual_address_length;
8227702724Smrg#endif
8327702724Smrg
8427702724Smrg    auth_name = XauFileName ();
8527702724Smrg    if (!auth_name)
8627702724Smrg	return NULL;
8727702724Smrg    if (access (auth_name, R_OK) != 0)		/* checks REAL id */
8827702724Smrg	return NULL;
8927702724Smrg    auth_file = fopen (auth_name, "rb");
9027702724Smrg    if (!auth_file)
9127702724Smrg	return NULL;
9227702724Smrg
9327702724Smrg#ifdef hpux
9427702724Smrg    if (family == FamilyLocal) {
9527702724Smrg#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
9627702724Smrg	_Xgethostbynameparams hparams;
9727702724Smrg#endif
9827702724Smrg	struct hostent *hostp;
9927702724Smrg
10027702724Smrg	/* make sure we try fully-qualified hostname */
10127702724Smrg	if ((hostp = _XGethostbyname(address,hparams)) != NULL) {
10227702724Smrg	    fully_qual_address = hostp->h_name;
10327702724Smrg	    fully_qual_address_length = strlen(fully_qual_address);
10427702724Smrg	}
10527702724Smrg	else
10627702724Smrg	{
10727702724Smrg	    fully_qual_address = NULL;
10827702724Smrg	    fully_qual_address_length = 0;
10927702724Smrg	}
11027702724Smrg    }
11127702724Smrg#endif /* hpux */
11227702724Smrg
11327702724Smrg    best = NULL;
11427702724Smrg    best_type = types_length;
11527702724Smrg    for (;;) {
11627702724Smrg	entry = XauReadAuth (auth_file);
11727702724Smrg	if (!entry)
11827702724Smrg	    break;
11927702724Smrg	/*
12027702724Smrg	 * Match when:
12127702724Smrg	 *   either family or entry->family are FamilyWild or
12227702724Smrg	 *    family and entry->family are the same and
12327702724Smrg	 *     address and entry->address are the same
12427702724Smrg	 *  and
12527702724Smrg	 *   either number or entry->number are empty or
12627702724Smrg	 *    number and entry->number are the same
12727702724Smrg	 *  and
12827702724Smrg	 *   either name or entry->name are empty or
12927702724Smrg	 *    name and entry->name are the same
13027702724Smrg	 */
13127702724Smrg
13227702724Smrg	if ((family == FamilyWild || entry->family == FamilyWild ||
13327702724Smrg	     (entry->family == family &&
13427702724Smrg	     ((address_length == entry->address_length &&
13527702724Smrg	      binaryEqual (entry->address, address, (int)address_length))
13627702724Smrg#ifdef hpux
13727702724Smrg	     || (family == FamilyLocal &&
13827702724Smrg		fully_qual_address_length == entry->address_length &&
13927702724Smrg	     	binaryEqual (entry->address, fully_qual_address,
14027702724Smrg		    (int) fully_qual_address_length))
14127702724Smrg#endif
14227702724Smrg	    ))) &&
14327702724Smrg	    (number_length == 0 || entry->number_length == 0 ||
14427702724Smrg	     (number_length == entry->number_length &&
14527702724Smrg	      binaryEqual (entry->number, number, (int)number_length))))
14627702724Smrg	{
14727702724Smrg	    if (best_type == 0)
14827702724Smrg	    {
14927702724Smrg		best = entry;
15027702724Smrg		break;
15127702724Smrg	    }
15227702724Smrg	    for (type = 0; type < best_type; type++)
15327702724Smrg		if (type_lengths[type] == entry->name_length &&
15427702724Smrg		    !(strncmp (types[type], entry->name, entry->name_length)))
15527702724Smrg		{
15627702724Smrg		    break;
15727702724Smrg		}
15827702724Smrg	    if (type < best_type)
15927702724Smrg	    {
16027702724Smrg		if (best)
16127702724Smrg		    XauDisposeAuth (best);
16227702724Smrg		best = entry;
16327702724Smrg		best_type = type;
16427702724Smrg		if (type == 0)
16527702724Smrg		    break;
16627702724Smrg		continue;
16727702724Smrg	    }
16827702724Smrg	}
16927702724Smrg	XauDisposeAuth (entry);
17027702724Smrg    }
17127702724Smrg    (void) fclose (auth_file);
17227702724Smrg    return best;
17327702724Smrg}
174