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