glibc/resolv/res_hconf.c
Ulrich Drepper c84142e8fe Update to 2.1.x development version
1997-02-15 02:41  Miles Bader  <miles@gnu.ai.mit.edu>

	* argp/argp-help.c: Gettextize sources.
	* argp/argp-parse.c: Likewise.

1997-02-13 22:32  Ulrich Drepper  <drepper@cygnus.com>

	* features.h (__GLIBC_MINOR__): Bump to 1.

	* xlocale.h: New file.  Wrapper around locale/xlocale.h.
	* Makefile (distribute): Add xlocale.h.
	* locale/Makefile (routines): Add ctype_l.
	* locale/ctype-extn.c: Update copyright. De-ANSI-declfy.
	Add __isblank_l, __toascii_l and __isascii_l.
	* ctype/ctype.h: Add definitions and declarations for *_l functions.
	* locale/Makefile (headers): Add xlocale.h.
	(routines): Add newlocale, duplocale, and freelocale.
	* locale/localeinfo.h (MAX_USAGE_COUNT): New macro.
	(struct locale_data): Add new fields mmaped and usage_count.
	Correct various declarations.
	* locale/C-collate.c: Define value for new fields mmaped and
	usage_count.
	* locale/C-ctype.c: Likewise.
	* locale/C-messages.c: Likewise.
	* locale/C-monetary.c: Likewise.
	* locale/C-numeric.c: Likewise.
	* locale/C-time.c: Likewise.
	* locale/loadlocale.c (_nl_load_locale): Initialize mmaped and
	usage_count fields.
	* locale/locale.h: Don't define locale_t here (moved to xlocale.h).
	Correct prototypes for __newlocale and __freelocale.
	Add prototype for __duplocale.
	* locale/findlocale.c (copy): Remove function.  Use __strdup instead.
	(_nl_remove_locale): New function.
	* locale/nl_langinfo.c: Don't declare locale_data objects as const.
	* locale/setlocale.c: Likewise.
	* locale/weight.h: Change for use with locale objects.
	* locale/xlocale.h: New file.  Define __locale_t type.
	* locale/newlocale.c: New file.  Create new locale object.
	* locale/freelocale.c: New file.  Destroy locale object.
	* locale/duplocale.c: New file.  Create copy of locale object.
	* stdlib/Makefile (routines): Add strfmon_l.
	* stdlib/monetary.h [__USE_GNU]: Declare __strfmon_l.
	* stdlib/strfmon.c: Add support for use in extended locale model.
	* stdlib/strfmon_l.c: New file.
	* string/Makefile (routines): Add strcoll_l and strxfrm_l.
	* string/strcoll.c: Change for use in extended locale model.
	* string/strxfrm.c: Likewise.
	* string/strcoll_l.c: New file.  Implement __strcoll_l function.
	* string/strxfrm_l.c: New file.  Implement __strxfrm_l function.
	* wcsmbs/Makefile (routines): Add wcscoll_l and wcsxfrm_l.
	* wcsmbs/wchar.h [__USE_GNU]: Declare wcscoll_l and wcsxfrm_l.
	* wcsmbs/wcscoll.c: Change for use in extended locale model.
	* wcsmbs/wcscoll_l.c: New file.  Implement __wcscoll_l function.
	* wcsmbs/wcsxfrm_l.c: New file.  Implement __wcsxfrm_l function.
	* wctype/Makefile (routines): Add wcextra, wcfuncs_l, iswctype_l,
	and towctrans_l.
	* wctype/cname-lookup.h: Prepare for use in extended locale model.
	* wctype/iswctype_l.c: New file.  Implement character classification
	functions for use with locale objects.
	* wctype/wctype.h: Declare functions for use with locale objects.
	* wctype/towctrans_l.c: New file.  Implement __towctrans_l function
	for use with locale objects.
	* wctype/wcfuncs_l.c: New file.  Implement wide character
	classification functions for use with locale objects.
	* wctype/wcextra.c: New file.  Implement real functions for
	non-standard classification functions.

	* elf/ldd.bash.in: Don't use --data-relocs and --function-relocs
	parameters to ld.so.  Use environment variables.
	* elf/ldd.sh.in: Likewise.
	* elf/rtld.c: Remove handling of --data-relocs and --function-relocs
	options.  Instead read environment variables.

	* elf/link.h (receiver_fct): Add new argument to take error code.
	* elf/dl-error.c (_dl_signal_error): Call receiver function with
	another argument.

	* elf/dl-object.c (_dl_new_object): Create new object with list of
	names in l_libname member.
	* elf/dl-load.c (_dl_map_object_from_fd): Add name which was used to
	find to object to the list in the link_map variable.
	(_dl_map_object): Use _dl_does_name_match_p to compare with all
	available names of the object.
	Optimize handling of LD_LIBRARY_PATH a bit.
	* elf/rtld.c: Initialize l_libname member of _dl_rtld_map.

	* elf/dl-lookup.c (_dl_elf_hash): Optimize function.

	* elf/Makefile (routines): Add dl-version.
	* elf/link.h (hash_name_pair): New type.  Group pointer to string
	and its hash value.
	(struct link_map): Change l_libname member to be a list of names,
	not a single pointer to a name.
	Add new members l_nversions and l_versions.
	(_dl_does_name_match_p): New function to test for all names of an
	object.
	Add prototypes for new lookup and versioning functions.
	* elf/dl-lookup.c (do_lookup): Add new argument and handle case
	when versioned symbol is requested.
	(_dl_lookup_symbol): Call do_lookup with another argument.
	(_dl_lookup_symbol_skip): Likewise.
	(_dl_lookup_versioned_symbol): New function.  Handle lookup of
	versioned symbol.
	(_dl_lookup_versioned_symbol_skip): Likewise, similar to
	_dl_lookup_symbol_skip.
	* elf/dl-reloc.c (RESOLVE): Call _dl_lookup_versioned_symbol or
	_dl_lookup_symbol depending on availability of version information.
	* elf/dl-runtime.c (RESOLVE): Likewise.
	(fixup): Call elf_machine_relplt with additional argument to point
	to versioning information if available.
	* elf/do-rel.h (elf_dynamic_do_rel): Likewise.
	* elf/dl-open.c (_dl_open): Call _dl_check_map_versions to check
	for correct versions.
	* elf/dl-version.c: New file.  Check library versions and extract
	version information for easier access.
	* elf/dlfcn.h [__USE_GNU]: Add prototype for dlvsym.
	* elf/dlvsym.c: New file.  Implementation of function similar to
	dlsym, but looks for versioned symbol.
	* elf/elf.h: Add types and macros for versioning.
	* elf/rtld.c (dl_main): Check availability of needed versions.
	* sysdeps/alpha/dl-machine.h (elf_machine_rela): Add additional
	argument for version information.  Call RESOLVE with additional
	argument.
	* sysdeps/i386/dl-machine.h: Likewise.
	* sysdeps/m68k/dl-machine.h: Likewise.
	* sysdeps/mips/dl-machine.h: Likewise.

	* elf/dlerror.c: Change comment to align with guidelines.
	* elf/dlopen.c: Likewise.
	* elf/dlsym.c: Likewise.

	* locale/programs/localedef.c: Implement --quiet option.
	* locale/programs/charset.h: Declare be_quiet variable.
	* locale/programs/locfile.h: Likewise.
	* locale/programs/charmap.c: Don't print warnings if quiet option
	was given.
	* locale/programs/ld-collate.c: Likewise.
	* locale/programs/ld-ctype.c: Likewise.
	* locale/programs/ld-messages.c: Likewise.
	* locale/programs/ld-monetary.c: Likewise.
	* locale/programs/ld-numeric.c: Likewise.
	* locale/programs/ld-time.c: Likewise.
	* locale/programs/locfile.c: Likewise.

	* Makefile (subdirs): Add argp.

	* catgets/catgets.c (catopen): Little code improvement.

	* posix/execl.c: Remove restriction to 1024 arguments.
	* posix/execle.c: Likewise.
	* posix/execlp.c: Likewise.

	* posix/getopt.c [_LIBC]: Define global objects with __ prefix
	and make regular names weak aliases.
	* posix/getopt1.c: Likewise.
	* posix/getopt.h [_LIBC]: Provide prototypes and declarations for
	__ protected forms.

	* posix/unistd.h: Add prototype for __sleep.
	* sysdeps/mach/sleep.c: Make sleep weak alias of __sleep.
	* sysdeps/posix/sleep.c: Likewise.
	* sysdeps/stub/sleep.c: Likewise.
	* sysdeps/unix/sysv/linux/sleep.c: Likewise.

	* ctype/ctype-info.c: Update copyright.
	* ctype/ctype.c: Likewise.
	* ctype/test_ctype.c: Likewise.
	* dirent/alphasort.c: Likewise.
	* dirent/list.c: Likewise.
	* gmon/bb_exit_func.c: Likewise.
	* grp/fgetgrent.c: Likewise.
	* grp/getgrent.c: Likewise.
	* grp/getgrent_r.c: Likewise.
	* grp/getgrgid.c: Likewise.
	* grp/getgrgid_r.c: Likewise.
	* grp/getgrnam.c: Likewise.
	* grp/getgrnam_r.c: Likewise.
	* hurd/alloc-fd.c: Likewise.
	* hurd/catch-exc.c: Likewise.
	* hurd/ctty-input.c: Likewise.
	* hurd/ctty-output.c: Likewise.
	* hurd/dtable.c: Likewise.
	* hurd/fchroot.c: Likewise.
	* hurd/fd-close.c: Likewise.
	* hurd/fd-read.c: Likewise.
	* hurd/fd-write.c: Likewise.
	* hurd/fopenport.c: Likewise.
	* hurd/get-host.c: Likewise.
	* hurd/getdport.c: Likewise.
	* hurd/getuids.c: Likewise.
	* hurd/getumask.c: Likewise.
	* hurd/hurd-raise.c: Likewise.
	* hurd/hurd.h: Likewise.
	* hurd/hurdauth.c: Likewise.
	* hurd/hurdexec.c: Likewise.
	* hurd/hurdhost.h: Likewise.
	* hurd/hurdid.c: Likewise.
	* hurd/hurdinit.c: Likewise.
	* hurd/hurdioctl.c: Likewise.
	* hurd/hurdkill.c: Likewise.
	* hurd/hurdlookup.c: Likewise.
	* hurd/hurdmsg.c: Likewise.
	* hurd/hurdpid.c: Likewise.
	* hurd/hurdports.c: Likewise.
	* hurd/hurdprio.c: Likewise.
	* hurd/hurdrlimit.c: Likewise.
	* hurd/hurdsock.c: Likewise.
	* hurd/hurdstartup.c: Likewise.
	* hurd/hurdstartup.h: Likewise.
	* hurd/intern-fd.c: Likewise.
	* hurd/intr-msg.c: Likewise.
	* hurd/intr-rpc.defs: Likewise.
	* hurd/intr-rpc.h: Likewise.
	* hurd/msgportdemux.c: Likewise.
	* hurd/new-fd.c: Likewise.
	* hurd/openport.c: Likewise.
	* hurd/pid2task.c: Likewise.
	* hurd/port-cleanup.c: Likewise.
	* hurd/port2fd.c: Likewise.
	* hurd/ports-get.c: Likewise.
	* hurd/ports-set.c: Likewise.
	* hurd/privports.c: Likewise.
	* hurd/report-wait.c: Likewise.
	* hurd/set-host.c: Likewise.
	* hurd/setauth.c: Likewise.
	* hurd/setuids.c: Likewise.
	* hurd/siginfo.c: Likewise.
	* hurd/sigunwind.c: Likewise.
	* hurd/task2pid.c: Likewise.
	* hurd/thread-cancel.c: Likewise.
	* hurd/thread-self.c: Likewise.
	* hurd/vpprintf.c: Likewise.
	* hurd/hurd/fd.h: Likewise.
	* hurd/hurd/id.h: Likewise.
	* hurd/hurd/ioctl.h: Likewise.
	* hurd/hurd/lookup.h: Likewise.
	* hurd/hurd/port.h: Likewise.
	* hurd/hurd/resource.h: Likewise.
	* hurd/hurd/threadvar.h: Likewise.
	* hurd/hurd/userlink.h: Likewise.
	* inet/ether_aton.c: Likewise.
	* inet/ether_aton_r.c: Likewise.
	* inet/ether_ntoa.c: Likewise.
	* inet/ether_ntoa_r.c: Likewise.
	* inet/gethstbyad.c: Likewise.
	* inet/gethstbyad_r.c: Likewise.
	* inet/gethstent.c: Likewise.
	* inet/getnetbyad.c: Likewise.
	* inet/getnetbyad_r.c: Likewise.
	* inet/getnetbynm.c: Likewise.
	* inet/getnetbynm_r.c: Likewise.
	* inet/getnetent.c: Likewise.
	* inet/getnetent_r.c: Likewise.
	* inet/getproto.c: Likewise.
	* inet/getproto_r.c: Likewise.
	* inet/getprtent.c: Likewise.
	* inet/getprtent_r.c: Likewise.
	* inet/getprtname.c: Likewise.
	* inet/getrpcbyname.c: Likewise.
	* inet/getrpcbyname_r.c: Likewise.
	* inet/getrpcbynumber.c: Likewise.
	* inet/getrpcbynumber_r.c: Likewise.
	* inet/getrpcent.c: Likewise.
	* inet/getrpcent_r.c: Likewise.
	* inet/getservent.c: Likewise.
	* inet/getservent_r.c: Likewise.
	* inet/getsrvbynm.c: Likewise.
	* inet/getsrvbynm_r.c: Likewise.
	* inet/getsrvbypt.c: Likewise.
	* inet/getsrvbypt_r.c: Likewise.
	* inet/herrno.c: Likewise.
	* inet/netgroup.h: Likewise.
	* ient/netinet/ether.h: Likewise.
	* intl/bindtextdom.c: Likewise.
	* intl/dcgettext.c: Likewise.
	* intl/dgettext.c: Likewise.
	* intl/gettext.c: Likewise.
	* intl/gettext.h: Likewise.
	* intl/gettextP.h: Likewise.
	* intl/hash-string.h: Likewise.
	* intl/loadmsgcat.c: Likewise.
	* intl/localealias.c: Likewise.
	* intl/textdomain.c: Likewise.
	* io/creat.c: Likewise.
	* io/getdirname.c: Likewise.
	* io/lockf.c: Likewise.
	* io/pwd.c: Likewise.
	* io/test-utime.c: Likewise.
	* locale/categories.def: Likewise.
	* locale/codeset_name.c: Likewise.
	* locale/lc-collate.c: Likewise.
	* locale/lc-ctype.c: Likewise.
	* locale/lc-messages.c: Likewise.
	* locale/lc-monetary.c: Likewise.
	* locale/lc-numeric.c: Likewise.
	* locale/lc-time.c: Likewise.
	* locale/loadlocale.c: Likewise.
	* locale/localeconv.c: Likewise.
	* locale/nl_langinfo.c: Likewise.
	* locale/setlocale.c: Likewise.
	* locale/strlen-hash.h: Likewise.
	* locale/programs/charmap-kw.gperf: Likewise.
	* locale/programs/charmap-kw.h: Likewise.
	* locale/programs/charset.c: Likewise.
	* locale/programs/ld-ctype.c: Likewise.
	* locale/programs/ld-messages.c: Likewise.
	* locale/programs/ld-monetary.c: Likewise.
	* locale/programs/linereader.h: Likewise.
	* locale/programs/locale-spec.c: Likewise.
	* locale/programs/locales.h: Likewise.
	* locale/programs/locfile-kw.gperf: Likewise.
	* locale/programs/locfile-kw.h: Likewise.
	* locale/programs/locfile-token.h: Likewise.
	* locale/programs/simple-hash.h: Likewise.
	* locale/programs/stringtrans.c: Likewise.
	* locale/programs/stringtrans.h: Likewise.
	* login/logout.c: Likewise.
	* mach/bootprivport.c: Likewise.
	* mach/devstream.c: Likewise.
	* mach/hello.c: Likewise.
	* mach/mach.h: Likewise.
	* mach/mach_init.c: Likewise.
	* mach/mach_init.h: Likewise.
	* mach/mig-alloc.c: Likewise.
	* mach/mig-dealloc.c: Likewise.
	* mach/mutex-init.c: Likewise.
	* mach/mutex-solid.c: Likewise.
	* mach/setup-thread.c: Likewise.
	* mach/spin-lock.h: Likewise.
	* mach/spin-solid.c: Likewise.
	* mach/mach/mig_support.h: Likewise.
	* md5-crypt/md5-crypt.c: Likewise.
	* misc/nlist.h: Likewise.
	* nss/nss_files/files-ether.c: Likewise.
	* posix/confstr.c: Likewise.
	* posix/execl.c: Likewise.
	* posix/execle.c: Likewise.
	* posix/execlp.c: Likewise.
	* posix/execv.c: Likewise.
	* posix/execvp.c: Likewise.
	* posix/fnmatch.c: Likewise.
	* posix/getopt.c: Likewise.
	* posix/getopt.h: Likewise.
	* posix/getopt1.c: Likewise.
	* posix/id.c: Likewise.
	* posix/regex.c: Likewise.
	* posix/setpgrp.c: Likewise.
	* posix/unistd.h: Likewise.
	* posix/wordexp.c: Likewise.
	* pwd/fgetpwent.c: Likewise.
	* pwd/getpwent.c: Likewise.
	* pwd/getpwent_r.c: Likewise.
	* pwd/getpwnam.c: Likewise.
	* pwd/getpwnam_r.c: Likewise.
	* pwd/getpwuid.c: Likewise.
	* pwd/getpwuid_r.c: Likewise.
	* pwd/putpwent.c: Likewise.
	* resolv/gethnamaddr.c: Likewise.
	* resolv/res_hconf.c: Likewise.
	* resolv/res_hconf.h: Likewise.
	* setjmp/longjmp.c: Likewise.
	* setjmp/sigjmp.c: Likewise.
	* setjmp/tst-setjmp.c: Likewise.
	* stdio/clearerr.c: Likewise.
	* stdio/ferror.c: Likewise.
	* stdio/fgetc.c: Likewise.
	* stdio/fgetpos.c: Likewise.
	* stdio/fgets.c: Likewise.
	* stdio/fileno.c: Likewise.
	* stdio/fmemopen.c: Likewise.
	* stdio/fopen.c: Likewise.
	* stdio/fopncook.c: Likewise.
	* stdio/fputc.c: Likewise.
	* stdio/fputs.c: Likewise.
	* stdio/fread.c: Likewise.
	* stdio/freopen.c: Likewise.
	* stdio/fseek.c: Likewise.
	* stdio/fsetpos.c: Likewise.
	* stdio/ftell.c: Likewise.
	* stdio/fwrite.c: Likewise.
	* stdio/getchar.c: Likewise.
	* stdio/getdelim.c: Likewise.
	* stdio/gets.c: Likewise.
	* stdio/glue.c: Likewise.
	* stdio/internals.c: Likewise.
	* stdio/linewrap.c: Likewise.
	* stdio/linewrap.h: Likewise.
	* stdio/memstream.c: Likewise.
	* stdio/newstream.c: Likewise.
	* stdio/putchar.c: Likewise.
	* stdio/puts.c: Likewise.
	* stdio/rewind.c: Likewise.
	* stdio/setbuf.c: Likewise.
	* stdio/setbuffer.c: Likewise.
	* stdio/setlinebuf.c: Likewise.
	* stdio/setvbuf.c: Likewise.
	* stdio/ungetc.c: Likewise.
	* stdio/vasprintf.c: Likewise.
	* stdio/vscanf.c: Likewise.
	* stdio/vsnprintf.c: Likewise.
	* stdio/vsprintf.c: Likewise.
	* stdio/vsscanf.c: Likewise.
	* stdio-common/asprintf.c: Likewise.
	* stdio-common/dprintf.c: Likewise.
	* stdio-common/errnobug.c: Likewise.
	* stdio-common/fprintf.c: Likewise.
	* stdio-common/getline.c: Likewise.
	* stdio-common/getw.c: Likewise.
	* stdio-common/perror.c: Likewise.
	* stdio-common/psignal.c: Likewise.
	* stdio-common/putw.c: Likewise.
	* stdio-common/reg-printf.c: Likewise.
	* stdio-common/scanf.c: Likewise.
	* stdio-common/snprintf.c: Likewise.
	* stdio-common/sprintf.c: Likewise.
	* stdio-common/tempnam.c: Likewise.
	* stdio-common/test_rdwr.c: Likewise.
	* stdio-common/tst-fileno.c: Likewise.
	* stdio-common/tst-printf.c: Likewise.
	* stdio-common/tstgetln.c: Likewise.
	* stdio-common/vprintf.c: Likewise.
	* stdlib/drand48.c: Likewise.
	* stdlib/drand48_r.c: Likewise.
	* stdlib/erand48.c: Likewise.
	* stdlib/erand48_r.c: Likewise.
	* stdlib/exit.h: Likewise.
	* stdlib/strtoq.c: Likewise.
	* stdlib/strtoul.c: Likewise.
	* stdlib/strtouq.c: Likewise.
	* stdlib/test-canon.c: Likewise.
	* stdlib/testdiv.c: Likewise.
	* stdlib/testrand.c: Likewise.
	* string/argz-append.c: Likewise.
	* string/argz-count.c: Likewise.
	* string/argz-create.c: Likewise.
	* string/argz-ctsep.c: Likewise.
	* string/argz-delete.c: Likewise.
	* string/argz-extract.c: Likewise.
	* string/argz-insert.c: Likewise.
	* string/argz-next.c: Likewise.
	* string/argz-stringify.c: Likewise.
	* string/basename.c: Likewise.
	* string/envz.c: Likewise.
	* string/memfrob.c: Likewise.
	* string/strcoll.c: Likewise.
	* string/strdup.c: Likewise.
	* string/string.h: Likewise.
	* string/strndup.c: Likewise.
	* string/strnlen.c: Likewise.
	* string/strsignal.c: Likewise.
	* string/strxfrm.c: Likewise.
	* string/test-ffs.c: Likewise.
	* string/testcopy.c: Likewise.
	* sysdeps/generic/enbl-secure.c: Likewise.
	* sysdeps/generic/memcopy.h: Likewise.
	* sysdeps/generic/stpncpy.c: Likewise.
	* sysdeps/generic/strcasecmp.c: Likewise.
	* sysdeps/generic/strcat.c: Likewise.
	* sysdeps/generic/strchr.c: Likewise.
	* sysdeps/generic/strcpy.c: Likewise.
	* sysdeps/generic/strcspn.c: Likewise.
	* sysdeps/generic/strlen.c: Likewise.
	* sysdeps/generic/strncase.c: Likewise.
	* sysdeps/generic/strncat.c: Likewise.
	* sysdeps/generic/strncpy.c: Likewise.
	* sysdeps/generic/strpbrk.c: Likewise.
	* sysdeps/generic/strsep.c: Likewise.
	* sysdeps/generic/strspn.c: Likewise.
	* sysdeps/generic/strstr.c: Likewise.
	* sysdeps/generic/strtok.c: Likewise.
	* sysdeps/generic/strtok_r.c: Likewise.
	* sysdeps/mach/sleep.c: Likewise.
	* sysdeps/posix/sleep.c: Likewise.
	* sysdeps/stub/sleep.c: Likewise.
	* time/date.c: Likewise.
	* time/test_time.c: Likewise.
	* wcsmbs/wmemcpy.c: Likewise.
	* wctye/test_wctype.c: Likewise.
	* wctye/towctrans.c: Likewise.
	* wctye/wcfuncs.c: Likewise.
	* wctye/wctrans.c: Likewise.

1997-02-13 22:15  Miles Bader  <miles@gnu.ai.mit.edu>

	* argp/Makefile: New file.
	* argp/argp.h: Likewise.
	* argp/argp-ba.c: Likewise.
	* argp/argp-fmtstream.c: Likewise.
	* argp/argp-fmtstream.h: Likewise.
	* argp/argp-fs-xinl.c: Likewise.
	* argp/argp-help.c: Likewise.
	* argp/argp-namefrob.h: Likewise.
	* argp/argp-parse.c: Likewise.
	* argp/argp-pv.c: Likewise.
	* argp/argp-pvh.c: Likewise.
	* argp/argp-test.c: Likewise.
	* argp/argp-xinl.c: Likewise.

	* libio/_G_config.h: Make sure wint_t is also defined for old gcc
1997-02-09 04:35  Ulrich Drepper  <drepper@cygnus.com>

	* stdio-common/_itoa.h: Update copyright.
1997-02-15 04:31:36 +00:00

549 lines
13 KiB
C

/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by David Mosberger (davidm@azstarnet.com).
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* This file provides a Linux /etc/host.conf compatible front end to
the various name resolvers (/etc/hosts, named, NIS server, etc.).
Though mostly compatibly, the following differences exist compared
to the original implementation:
- new command "spoof" takes an arguments like RESOLV_SPOOF_CHECK
environment variable (i.e., `off', `nowarn', or `warn').
- line comments can appear anywhere (not just at the beginning of
a line)
*/
#include <ctype.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "res_hconf.h"
#define _PATH_HOSTCONF "/etc/host.conf"
/* Environment vars that all user to override default behavior: */
#define ENV_HOSTCONF "RESOLV_HOST_CONF"
#define ENV_SERVORDER "RESOLV_SERV_ORDER"
#define ENV_SPOOF "RESOLV_SPOOF_CHECK"
#define ENV_TRIM_OVERR "RESOLV_OVERRIDE_TRIM_DOMAINS"
#define ENV_TRIM_ADD "RESOLV_ADD_TRIM_DOMAINS"
#define ENV_MULTI "RESOLV_MULTI"
#define ENV_REORDER "RESOLV_REORDER"
static const char * arg_service_list (const char *, int, const char *,
unsigned);
static const char * arg_trimdomain_list (const char *, int, const char *,
unsigned);
static const char * arg_spoof (const char *, int, const char *, unsigned);
static const char * arg_bool (const char *, int, const char *, unsigned);
static struct cmd {
const char * name;
const char * (*parse_args)(const char * filename, int line_num,
const char * args, unsigned arg);
unsigned arg;;
} cmd[] = {
{"order", arg_service_list, 0},
{"trim", arg_trimdomain_list, 0},
{"spoof", arg_spoof, 0},
{"multi", arg_bool, HCONF_FLAG_MULTI},
{"nospoof", arg_bool, HCONF_FLAG_SPOOF},
{"spoofalert", arg_bool, HCONF_FLAG_SPOOFALERT},
{"reorder", arg_bool, HCONF_FLAG_REORDER}
};
/* Skip white space. */
static const char *
skip_ws (const char * str)
{
while (isspace (*str)) ++str;
return str;
}
/* Skip until whitespace, comma, end of line, or comment character. */
static const char *
skip_string (const char * str)
{
while (*str && !isspace (*str) && *str != '#' && *str != ',') ++str;
return str;
}
static const char *
arg_service_list (const char * fname, int line_num, const char * args,
unsigned arg)
{
enum Name_Service service;
const char * start;
size_t len;
int i;
static struct {
const char * name;
enum Name_Service service;
} svcs[] = {
{"bind", SERVICE_BIND},
{"hosts", SERVICE_HOSTS},
{"nis", SERVICE_NIS},
};
do
{
start = args;
args = skip_string (args);
len = args - start;
service = SERVICE_NONE;
for (i = 0; i < sizeof (svcs) / sizeof (svcs[0]); ++i)
{
if (strncasecmp (start, svcs[i].name, len) == 0
&& len == strlen (svcs[i].name))
{
service = svcs[i].service;
break;
}
}
if (service == SERVICE_NONE)
{
fprintf (stderr, "%s: line %d: expected service, found `%s'\n",
fname, line_num, start);
return 0;
}
if (_res_hconf.num_services >= SERVICE_MAX)
{
fprintf (stderr, "%s: line %d: cannot specify more than %d services",
fname, line_num, SERVICE_MAX);
return 0;
}
_res_hconf.service[_res_hconf.num_services++] = service;
args = skip_ws (args);
switch (*args)
{
case ',': case ';': case ':':
args = skip_ws (++args);
if (!*args || *args == '#')
{
fprintf (stderr,
"%s: line %d: list delimiter not followed by keyword",
fname, line_num);
return 0;
}
default:
break;
}
}
while (*args && *args != '#');
return args;
}
static const char *
arg_trimdomain_list (const char * fname, int line_num, const char * args,
unsigned flag)
{
const char * start;
size_t len;
do
{
start = args;
args = skip_string (args);
len = args - start;
if (_res_hconf.num_trimdomains >= TRIMDOMAINS_MAX)
{
fprintf (stderr,
"%s: line %d: cannot specify more than %d trim domains",
fname, line_num, TRIMDOMAINS_MAX);
return 0;
}
_res_hconf.trimdomain[_res_hconf.num_trimdomains++] =
strndup (start, len);
args = skip_ws (args);
switch (*args)
{
case ',': case ';': case ':':
args = skip_ws (++args);
if (!*args || *args == '#')
{
fprintf (stderr,
"%s: line %d: list delimiter not followed by domain",
fname, line_num);
return 0;
}
default:
break;
}
}
while (*args && *args != '#');
return args;
}
static const char *
arg_spoof (const char * fname, int line_num, const char * args, unsigned flag)
{
const char * start = args;
size_t len;
args = skip_string (args);
len = args - start;
if (len == 3 && strncasecmp (start, "off", len) == 0)
_res_hconf.flags &= ~(HCONF_FLAG_SPOOF | HCONF_FLAG_SPOOFALERT);
else
{
_res_hconf.flags |= (HCONF_FLAG_SPOOF | HCONF_FLAG_SPOOFALERT);
if ((len == 6 && strncasecmp (start, "nowarn", len) == 0)
|| !(len == 4 && strncasecmp (start, "warn", len) == 0))
_res_hconf.flags &= ~HCONF_FLAG_SPOOFALERT;
}
return args;
}
static const char *
arg_bool (const char * fname, int line_num, const char * args, unsigned flag)
{
if (strncasecmp (args, "on", 2) == 0)
{
args += 2;
_res_hconf.flags |= flag;
}
else if (strncasecmp (args, "off", 3) == 0)
{
args += 3;
_res_hconf.flags &= ~flag;
}
else
{
fprintf (stderr, "%s: line %d: expected `on' or `off', found `%s'\n",
fname, line_num, args);
return 0;
}
return args;
}
static void
parse_line (const char * fname, int line_num, const char * str)
{
const char * start;
struct cmd * c = 0;
size_t len;
int i;
str = skip_ws (str);
if (*str == '#') return; /* skip line comment */
start = str;
str = skip_string (str);
len = str - start;
for (i = 0; i < sizeof (cmd) / sizeof (cmd[0]); ++i)
{
if (strncasecmp (start, cmd[i].name, len) == 0
&& strlen (cmd[i].name) == len)
{
c = &cmd[i];
break;
}
}
if (!c)
{
fprintf (stderr, "%s: line %d: bad command `%s'\n",
fname, line_num, start);
return;
}
/* process args: */
str = skip_ws (str);
str = (*c->parse_args) (fname, line_num, str, c->arg);
if (!str)
return;
/* rest of line must contain white space or comment only: */
while (*str)
{
if (!isspace (*str)) {
if (*str != '#')
fprintf (stderr, "%s: line %d: ignoring trailing garbage `%s'\n",
fname, line_num, str);
break;
}
++str;
}
}
/* Initialize hconf datastructure by reading host.conf file and
environment variables. */
void
_res_hconf_init (void)
{
const char * hconf_name;
int line_num = 0;
char buf[256], * end, * envval;
FILE * fp;
memset (&_res_hconf, 0, sizeof (_res_hconf));
hconf_name = getenv (ENV_HOSTCONF);
if (!hconf_name)
hconf_name = _PATH_HOSTCONF;
fp = fopen (hconf_name, "r");
if (!fp)
/* make up something reasonable: */
_res_hconf.service[_res_hconf.num_services++] = SERVICE_BIND;
else
{
while (fgets (buf, sizeof (buf), fp))
{
++line_num;
end = strchr (buf, '\n');
if (end)
*end = '\0';
parse_line (hconf_name, line_num, buf);
}
fclose (fp);
}
envval = getenv (ENV_SERVORDER);
if (envval)
{
_res_hconf.num_services = 0;
arg_service_list (ENV_SERVORDER, 1, envval, 0);
}
envval = getenv (ENV_SPOOF);
if (envval)
arg_spoof (ENV_SPOOF, 1, envval, 0);
envval = getenv (ENV_MULTI);
if (envval)
arg_bool (ENV_MULTI, 1, envval, HCONF_FLAG_MULTI);
envval = getenv (ENV_REORDER);
if (envval)
arg_bool (ENV_REORDER, 1, envval, HCONF_FLAG_REORDER);
envval = getenv (ENV_TRIM_ADD);
if (envval)
arg_trimdomain_list (ENV_TRIM_ADD, 1, envval, 0);
envval = getenv (ENV_TRIM_OVERR);
if (envval)
{
_res_hconf.num_trimdomains = 0;
arg_trimdomain_list (ENV_TRIM_OVERR, 1, envval, 0);
}
}
/* Reorder addresses returned in a hostent such that the first address
is an address on the local subnet, if there is such an address.
Otherwise, nothing is changed. */
void
_res_hconf_reorder_addrs (struct hostent * hp)
{
#if defined (SIOCGIFCONF) && defined (SIOCGIFNETMASK)
static int num_ifs = -1; /* number of interfaces */
static struct netaddr {
int addrtype;
union {
struct {
u_int32_t addr;
u_int32_t mask;
} ipv4
} u;
} * ifaddrs;
if (hp->h_addrtype != AF_INET)
return; /* can't deal with anything but IPv4 for now... */
if (num_ifs <= 0)
{
struct ifconf ifs;
struct ifreq * ifr;
size_t size, num;
int sd;
/* initialize interface table: */
num_ifs = 0;
sd = socket (AF_INET, SOCK_DGRAM, 0);
if (sd < 0)
return;
/* Now get list of interfaces. Since we don't know how many
interfaces there are, we keep increasing the buffer size
until we have at least sizeof(struct ifreq) too many bytes.
That implies that the ioctl() return because it ran out of
interfaces, not memory */
size = 0;
ifs.ifc_buf = 0;
do {
size += 4 * sizeof (struct ifreq);
ifs.ifc_buf = realloc (ifs.ifs_buf, size);
if (!ifs.ifc_buf)
{
close (sd);
return;
}
ifs.ifc_len = size;
if (ioctl (sd, SIOCGIFCONF, &ifs) < 0)
goto cleanup;
} while (size - ifs.ifc_len < sizeof (struct ifreq));
num = ifs.ifc_len / sizeof (struct ifreq);
ifaddrs = malloc (num * sizeof (ifaddrs[0]));
if (!ifaddrs)
goto cleanup;
ifr = ifs.ifc_req;
for (i = 0; i < num; ++i) {
if (ifr->ifr_addr.sa_family != AF_INET)
continue;
ifaddrs[num_ifs].addrtype = AF_INET;
memcpy (&ifaddrs[num_ifs].u.ipv4.addr,
&((struct sockaddr_in *)ifr->ifr_addr)->sin_addr, 4);
if (ioctl (sd, SIOCGIFNETMASK, if) < 0)
continue;
memcpy (&ifaddrs[num_ifs].u.ipv4.mask,
((struct sockaddr_in *)ifr->ifr_mask)->sin_addr, 4);
++num_ifs; /* now we're committed to this entry */
}
/* just keep enough memory to hold all the interfaces we want: */
ifaddrs = realloc (ifaddrs, num_ifs * sizeof (ifaddrs[0]));
cleanup:
close (sd);
free (ifs.ifc_buf);
}
if (num_ifs == 0)
return;
/* find an address for which we have a direct connection: */
for (i = 0; hp->h_addr_list[i]; ++i)
{
h_addr = (struct in_addr *) hp->h_addr_list[i];
for (j = 0; j < num_ifs; ++j)
{
if_addr = ifaddrs[j].u.ipv4.addr;
if_netmask = ifaddrs[j].u.ipv4.mask;
if (((h_addr->s_addr ^ if_addr) & if_netmask) == 0)
{
void * tmp;
tmp = hp->h_addr_list[i];
hp->h_addr_list[i] = hp->h_addr_list[0];
hp->h_addr_list[0] = tmp;
return;
}
}
}
#endif /* defined(SIOCGIFCONF) && ... */
}
/* If HOSTNAME has a postfix matching any of the trimdomains, trim away
that postfix. Notice that HOSTNAME is modified inplace. Also, the
original code applied all trimdomains in order, meaning that the
same domainname could be trimmed multiple times. I believe this
was unintentional. */
void
_res_hconf_trim_domain (char * hostname)
{
size_t hostname_len, trim_len;
int i;
hostname_len = strlen(hostname);
for (i = 0; i < _res_hconf.num_trimdomains; ++i)
{
const char * trim = _res_hconf.trimdomain[i];
trim_len = strlen(trim);
if (hostname_len > trim_len
&& strcasecmp(&hostname[hostname_len - trim_len], trim) == 0)
{
hostname[hostname_len - trim_len] = '\0';
break;
}
}
}
/* Trim all hostnames/aliases in HP according to the trimdomain list.
Notice that HP is modified inplace! */
void
_res_hconf_trim_domains (struct hostent * hp)
{
int i;
if (_res_hconf.num_trimdomains == 0)
return;
_res_hconf_trim_domain (hp->h_name);
for (i = 0; hp->h_aliases[i]; ++i)
_res_hconf_trim_domain (hp->h_aliases[i]);
}
#if 0
struct hostent *
_hconf_gethostent (void)
{
}
struct hostent *
_hconf_gethostbyname (const char * name)
{
}
struct hostent *
_hconf_gethostbyaddr (const char * addr, int len, int type)
{
}
struct hostent *
_hconf_gethtbyname (const char * name)
{
}
#endif