]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Wed May 22 22:10:01 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
authorRoland McGrath <roland@gnu.org>
Thu, 23 May 1996 03:15:42 +0000 (03:15 +0000)
committerRoland McGrath <roland@gnu.org>
Thu, 23 May 1996 03:15:42 +0000 (03:15 +0000)
* stdlib/canonicalize.c: New file.
* stdlib/stdlib.h: Declare canonicalize_file_name, realpath.
* stdlib/Makefile (routines): Add canonicalize.

* posix/unistd.h: Declare __canonicalize_directory_name_internal.

Thu May 23 00:01:10 1996  Ulrich Drepper  <drepper@cygnus.com>

* db/recno/rec_seq.c: Prevent `sccsid' definition by using the
same #if condition as in the other db files.

* intl/Makefile: Add -Wno-unused CFLAGS for compilation of
bindtextdom.c, finddomain.c, and localealias.c.

* intl/dcgettext.c: Don't define prototype for getcwd() when
compiling in glibc.

* libio/cleanup.c: Add prototype for _IO_register_cleanup.

* libio/filedoalloc.c, libio/fileops.c, libio/iopopen.c: Don't
        define _POSIX_SOURCE unconditionally.

* libio/filedoalloc.c, libio/iopopen.c: Include <unistd.h> if
        compiling in glibc.

* libio/fileops.c (_IO_file_close_it): Don't sync file, call
flush instead.  This relaxes the rules from POSIX.1 about
changing the active handle a bit.

* libio/iofopncook.c (struct _IO_cookie_file): Move definition
into <libio.h>.
Add prototypes for local functions to prevent warnings.

* libio/iopopen.c: Change prototypes for _IO_fork, _IO_pipe, and
        _IO_DUP2 to contain complete parameter list.

* libio/libio.h: Add definition of struct _IO_cookie_file.

* libio/libioP.h: Add prototypes for _IO_vasprintf, _IO_vdprintf,
        and _IO_vsnprintf.

* libio/memstream.c: Include <stdio.h>.

* libio/stdio.h: Add prototypes for fopencookie,
        __stdio_gen_tempname, __vfscanf, __vsscanf, and __vsnprintf.

* libio/strops.c: Avoid useless expression in `for' initializer.

* locale/findlocale.c: Add some casts to prevent warnings.

* locale/programs/locfile.c (write_locale_data): Don't use
double `/' in locale binary file.

* posix/unistd.h: Remove prototype for `reboot'.

Update from bind-4.9.4-T1A.
* resolv/Makefile (routines): Add inet_ntop and inet_pton.
* resolv/arpa/nameser.h: Add definition of IN6ADDRSZ.
* resolv/gethnamaddr.c, resolv/getnetnamadr.c, resolv/res_comp.c,
resolv/res_debug.c, resolv/res_init.c

* resolv/inet_ntop.c, resolv/inet_pton.c: New files.

* resolv/resolv.h: Add RES_USE_INET6 flag.
(__dn_isvalid): Renamed to __res_dnok.
Add prototypes for __res_ownok and __res_mailok.

* stdio-common/Makefile: Add -Wno-unused to CFLAGS for _itoa.c.

* stdio-common/getline.c, stdio-common/vfscanf.c,
        sysdeps/posix/tempname.c: Don't use <ansidecl.h> anymore.

* sysdeps/unix/sysv/linux/Makefile [$subdir == misc]
        (sysdep_routines): Add s_reboot.
(install-others): Add $(includedir)/sys/syscall.h.
New rule for $(includedir)/sys/syscall.h to produce from
<asm/unistd.h>.

* sysdeps/unix/sysv/linux/reboot.c: New file.  Make single
        argument function call 3 argument system call.

* sysdeps/unix/sysv/linux/sys/reboot.h: New file.  Linux specific
definition for reboot function.

* sysdeps/unix/sysv/linux/syscall.h: Remove old and obsolete
        comment.

* sysdeps/unix/sysv/linux/syscalls.list: Rename function for
reboot syscall to __syscall_reboot.

* wcsmbs/wchar.h: Protect prototypes for wcstof and wcstold by
__USE_GNU, not USE_GNU.

Tue May 21 21:55:49 1996  David Mosberger-Tang  <davidm@AZStarNet.com>

* locale/programs/charset.c, locale/programs/ld-collate.c:
Add casts to prevent warnings on 64-bit machines.

* locale/programs/ld-monetary.c: Don't do unnecessary tests for
int_frac_digits and frac_digits which only produce warnings.

Mon May 13 23:45:29 1996  David Mosberger-Tang  <davidm@AZStarNet.com>

* inet/arpa/inet.h: Backup return type of inet_addr to u_long.
* resolv/inet_addr.c: Likewise.

* resolv/Makefile (distribute): Add res_hconf.h
(routines): Add res_hconf.

* resolv/gethnamaddr.c: Add support for /etc/host.conf.

* resolv/res_init.c: Initialize /etc/host.conf reader.

* resolv/res_hconf.c, resolv/res_hconf.h: New files.
        Implementation of reading /etc/host.conf.

Wed May 22 21:21:15 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>

* Rules (%.out rules): Prepend $($*-ENV) to the command.

* sysdeps/unix/sysv/linux/i386/brk.c (___brk_addr): Define as weak
alias for __curbrk.

Wed May 22 19:37:27 1996  Miles Bader  <miles@gnu.ai.mit.edu>

* hurd/hurdexec.c (_hurd_exec): Pass INIT_TRACEMASK.
* hurd/hurdmsg.c (set_int): Support INIT_TRACEMASK.

Wed May 22 18:47:31 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>

* sysdeps/mach/hurd/getcwd.c
(_hurd_canonicalize_directory_name_internal): New function, broken out
of __getcwd.
(__getcwd): Use it.
(__canonicalize_directory_name_internal): New function using it.

* sysdeps/posix/getcwd.c (__canonicalize_directory_name_internal): New
function, broken out of __getcwd.
(__getcwd): Use it.

Wed May 22 18:14:05 1996  Miles Bader  <miles@gnu.ai.mit.edu>

* string/argz-create.c (__argz_create): Correctly calculate length.

* string/argz-extract.c (__argz_extract): Add terminating 0 entry.
* hurd/hurdstartup.c (_hurd_startup): ... and don't so here.

[HAVE_VMSDIR_H]: Include "vmsdir.h".
(glob) [VMS]: Don't grok ~.

51 files changed:
ChangeLog
Rules
db/recno/rec_seq.c
inet/arpa/inet.h
intl/Makefile
intl/dcgettext.c
libio/cleanup.c
libio/filedoalloc.c
libio/fileops.c
libio/iofopncook.c
libio/iopopen.c
libio/libio.h
libio/libioP.h
libio/memstream.c
libio/stdio.h
libio/strops.c
locale/findlocale.c
locale/programs/charset.c
locale/programs/ld-collate.c
locale/programs/ld-monetary.c
locale/programs/locfile.c
manual/errno.texi
posix/unistd.h
resolv/Makefile
resolv/arpa/nameser.h
resolv/gethnamaddr.c
resolv/getnetnamadr.c
resolv/inet_addr.c
resolv/inet_ntop.c [new file with mode: 0644]
resolv/inet_pton.c [new file with mode: 0644]
resolv/res_comp.c
resolv/res_debug.c
resolv/res_hconf.c [new file with mode: 0644]
resolv/res_hconf.h [new file with mode: 0644]
resolv/res_init.c
resolv/resolv.h
stdio-common/Makefile
stdio-common/getline.c
stdio-common/vfscanf.c
stdlib/Makefile
stdlib/canonicalize.c [new file with mode: 0644]
stdlib/stdlib.h
sysdeps/mach/hurd/getcwd.c
sysdeps/posix/getcwd.c
sysdeps/posix/tempname.c
sysdeps/unix/sysv/linux/Makefile
sysdeps/unix/sysv/linux/reboot.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/sys/reboot.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/syscall.h
sysdeps/unix/sysv/linux/syscalls.list
wcsmbs/wchar.h

index 1f057025e7641bb3be122754cbd8edf42e68ef14..03542f6aca0d312a29acafa4f45bcb747cd8e276 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,157 @@
+Wed May 22 22:10:01 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
+
+       * stdlib/canonicalize.c: New file.
+       * stdlib/stdlib.h: Declare canonicalize_file_name, realpath.
+       * stdlib/Makefile (routines): Add canonicalize.
+
+       * posix/unistd.h: Declare __canonicalize_directory_name_internal.
+
+Thu May 23 00:01:10 1996  Ulrich Drepper  <drepper@cygnus.com>
+
+       * db/recno/rec_seq.c: Prevent `sccsid' definition by using the
+       same #if condition as in the other db files.
+
+       * intl/Makefile: Add -Wno-unused CFLAGS for compilation of
+       bindtextdom.c, finddomain.c, and localealias.c.
+
+       * intl/dcgettext.c: Don't define prototype for getcwd() when
+       compiling in glibc.
+
+       * libio/cleanup.c: Add prototype for _IO_register_cleanup.
+
+       * libio/filedoalloc.c, libio/fileops.c, libio/iopopen.c: Don't
+        define _POSIX_SOURCE unconditionally.
+
+       * libio/filedoalloc.c, libio/iopopen.c: Include <unistd.h> if
+        compiling in glibc.
+
+       * libio/fileops.c (_IO_file_close_it): Don't sync file, call
+       flush instead.  This relaxes the rules from POSIX.1 about
+       changing the active handle a bit.
+
+       * libio/iofopncook.c (struct _IO_cookie_file): Move definition
+       into <libio.h>.
+       Add prototypes for local functions to prevent warnings.
+
+       * libio/iopopen.c: Change prototypes for _IO_fork, _IO_pipe, and
+        _IO_DUP2 to contain complete parameter list.
+
+       * libio/libio.h: Add definition of struct _IO_cookie_file.
+
+       * libio/libioP.h: Add prototypes for _IO_vasprintf, _IO_vdprintf,
+        and _IO_vsnprintf.
+
+       * libio/memstream.c: Include <stdio.h>.
+
+       * libio/stdio.h: Add prototypes for fopencookie,
+        __stdio_gen_tempname, __vfscanf, __vsscanf, and __vsnprintf.
+
+       * libio/strops.c: Avoid useless expression in `for' initializer.
+
+       * locale/findlocale.c: Add some casts to prevent warnings.
+
+       * locale/programs/locfile.c (write_locale_data): Don't use
+       double `/' in locale binary file.
+
+       * posix/unistd.h: Remove prototype for `reboot'.
+
+       Update from bind-4.9.4-T1A.
+       * resolv/Makefile (routines): Add inet_ntop and inet_pton.
+       * resolv/arpa/nameser.h: Add definition of IN6ADDRSZ.
+       * resolv/gethnamaddr.c, resolv/getnetnamadr.c, resolv/res_comp.c,
+       resolv/res_debug.c, resolv/res_init.c
+
+       * resolv/inet_ntop.c, resolv/inet_pton.c: New files.
+
+       * resolv/resolv.h: Add RES_USE_INET6 flag.
+       (__dn_isvalid): Renamed to __res_dnok.
+       Add prototypes for __res_ownok and __res_mailok.
+
+       * stdio-common/Makefile: Add -Wno-unused to CFLAGS for _itoa.c.
+
+       * stdio-common/getline.c, stdio-common/vfscanf.c,
+        sysdeps/posix/tempname.c: Don't use <ansidecl.h> anymore.
+
+       * sysdeps/unix/sysv/linux/Makefile [$subdir == misc]
+        (sysdep_routines): Add s_reboot.
+       (install-others): Add $(includedir)/sys/syscall.h.
+       New rule for $(includedir)/sys/syscall.h to produce from
+       <asm/unistd.h>.
+
+       * sysdeps/unix/sysv/linux/reboot.c: New file.  Make single
+        argument function call 3 argument system call.
+
+       * sysdeps/unix/sysv/linux/sys/reboot.h: New file.  Linux specific
+       definition for reboot function.
+
+       * sysdeps/unix/sysv/linux/syscall.h: Remove old and obsolete
+        comment.
+
+       * sysdeps/unix/sysv/linux/syscalls.list: Rename function for
+       reboot syscall to __syscall_reboot.
+
+       * wcsmbs/wchar.h: Protect prototypes for wcstof and wcstold by
+       __USE_GNU, not USE_GNU.
+
+Tue May 21 21:55:49 1996  David Mosberger-Tang  <davidm@AZStarNet.com>
+
+       * locale/programs/charset.c, locale/programs/ld-collate.c:
+       Add casts to prevent warnings on 64-bit machines.
+
+       * locale/programs/ld-monetary.c: Don't do unnecessary tests for
+       int_frac_digits and frac_digits which only produce warnings.
+
+Mon May 13 23:45:29 1996  David Mosberger-Tang  <davidm@AZStarNet.com>
+
+       * inet/arpa/inet.h: Backup return type of inet_addr to u_long.
+       * resolv/inet_addr.c: Likewise.
+
+       * resolv/Makefile (distribute): Add res_hconf.h
+       (routines): Add res_hconf.
+
+       * resolv/gethnamaddr.c: Add support for /etc/host.conf.
+
+       * resolv/res_init.c: Initialize /etc/host.conf reader.
+
+       * resolv/res_hconf.c, resolv/res_hconf.h: New files.
+        Implementation of reading /etc/host.conf.
+
+Wed May 22 21:21:15 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
+
+       * Rules (%.out rules): Prepend $($*-ENV) to the command.
+
+       * sysdeps/unix/sysv/linux/i386/brk.c (___brk_addr): Define as weak
+       alias for __curbrk.
+
+Wed May 22 19:37:27 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+       * hurd/hurdexec.c (_hurd_exec): Pass INIT_TRACEMASK.
+       * hurd/hurdmsg.c (set_int): Support INIT_TRACEMASK.
+
+Wed May 22 18:47:31 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
+
+       * sysdeps/mach/hurd/getcwd.c
+       (_hurd_canonicalize_directory_name_internal): New function, broken out
+       of __getcwd.
+       (__getcwd): Use it.
+       (__canonicalize_directory_name_internal): New function using it.
+
+       * sysdeps/posix/getcwd.c (__canonicalize_directory_name_internal): New
+       function, broken out of __getcwd.
+       (__getcwd): Use it.
+
+Wed May 22 18:14:05 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+       * string/argz-create.c (__argz_create): Correctly calculate length.
+
+       * string/argz-extract.c (__argz_extract): Add terminating 0 entry.
+       * hurd/hurdstartup.c (_hurd_startup): ... and don't so here.
+
 Wed May 22 17:22:14 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
 
        * posix/glob.c [VMS]: Don't include <pwd.h>.
+       [HAVE_VMSDIR_H]: Include "vmsdir.h".
+       (glob) [VMS]: Don't grok ~.
 
 Wed May 22 14:46:53 1996  Miles Bader  <miles@gnu.ai.mit.edu>
 
diff --git a/Rules b/Rules
index 517c3a65464ad58af4bbd4a1ef9f5a96d373e242..2eddd6ecff883721141a1bb07ce690a9d85c2547 100644 (file)
--- a/Rules
+++ b/Rules
@@ -96,13 +96,13 @@ ifneq "$(strip $(tests))" ""
 # These are the implicit rules for making test outputs
 # from the test programs and whatever input files are present.
 $(objpfx)%.out: %.args $(objpfx)% %.input
-       $(built-program-cmd) `cat $(word 1,$^)` < $(word 3,$^) > $@
+       $($*-ENV) $(built-program-cmd) `cat $(word 1,$^)` < $(word 3,$^) > $@
 $(objpfx)%.out: %.args $(objpfx)%
-       $(built-program-cmd) `cat $(word 1,$^)` > $@
+       $($*-ENV) $(built-program-cmd) `cat $(word 1,$^)` > $@
 $(objpfx)%.out: %.input $(objpfx)%
-       $(built-program-cmd) < $(word 1,$^) > $@
+       $($*-ENV) $(built-program-cmd) < $(word 1,$^) > $@
 $(objpfx)%.out: /dev/null $(objpfx)%   # Make it 2nd arg for canned sequence.
-       $(built-program-cmd) > $@
+       $($*-ENV) $(built-program-cmd) > $@
 endif  # tests
 \f
 .PHONY: distclean realclean subdir_distclean subdir_realclean \
index f80992c5982d6fd2f2f9e2a63999927da9e268e9..2f8c7695c5d316c38fc4eb8fbfc46816eafcb798 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
-#ifndef lint
+#if defined(LIBC_SCCS) && !defined(lint)
 static char sccsid[] = "@(#)rec_seq.c  8.3 (Berkeley) 7/14/94";
 #endif /* not lint */
 
index 2413dcf76e91379d539904bd5cf2acee3c979d5d..6cb672f336615d84faa3aded827dc2e1fef45d35 100644 (file)
@@ -42,7 +42,7 @@
 #include <sys/types.h>
 
 __BEGIN_DECLS
-u_int32_t       inet_addr __P((const char *));
+u_long          inet_addr __P((const char *));
 int             inet_aton __P((const char *, struct in_addr *));
 u_int32_t       inet_lnaof __P((struct in_addr));
 struct in_addr  inet_makeaddr __P((u_int32_t , u_int32_t));
index 9d97088d4ac37d5fa393f0279a9e379934dba6cc..01e1383cb83a9fd3befec150e30b0da519037304 100644 (file)
@@ -50,3 +50,7 @@ test ! -d CVS || cvs commit -m'Updated from $<' $@
 endef
 
 endif
+
+CFLAGS-bindtextdom.c = -Wno-unused
+CFLAGS-finddomain.c = -Wno-unused
+CFLAGS-localealias.c = -Wno-unused
index 6c8963f720682443a04890521e57de26c336f013..a18be16631ace6b1032cf86a7415154f3f2882f0 100644 (file)
@@ -87,13 +87,13 @@ void free ();
    file and the name space must not be polluted.  */
 # define getcwd __getcwd
 # define stpcpy __stpcpy
-#endif
-
-#if !defined HAVE_GETCWD && !defined _LIBC
-char *getwd ();
-# define getcwd(buf, max) getwd (buf)
 #else
+# if !defined HAVE_GETCWD
+char *getwd ();
+#  define getcwd(buf, max) getwd (buf)
+# else
 char *getcwd ();
+# endif
 #endif
 
 /* Amount to increase buffer size by in each try.  */
index a0c5052d39588e3ac648c9974e8944b92805bed7..1f316ebb3365e7593be85fcd4342a98760eb7f79 100644 (file)
@@ -4,6 +4,9 @@
 
 typedef void (*voidfunc) __P((void));
 
+/* Prototype.  */
+static void DEFUN_VOID (_IO_register_cleanup);
+
 static void
 DEFUN_VOID(_IO_register_cleanup)
 {
index 0ebb75d9c5724d40d3ace94b9afddfb752636d86..f71656478c7c1c0e99b4585b337d8ff970f369aa 100644 (file)
@@ -41,13 +41,18 @@ the executable file might be covered by the GNU General Public License. */
 
 /* Modified for GNU iostream by Per Bothner 1991, 1992. */
 
-#define _POSIX_SOURCE
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
 #include "libioP.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #ifdef __STDC__
 #include <stdlib.h>
 #endif
+#ifdef _LIBC
+# include <unistd.h>
+#endif
 
 /*
  * Allocate a file buffer, or switch to unbuffered I/O.
index 89381ec699777ed9a3adfb431d8a03086028e0a5..828f99db96571a684ccd15f79d03f618792b7853 100644 (file)
@@ -24,7 +24,9 @@ the executable file might be covered by the GNU General Public License. */
 
 /*  written by Per Bothner (bothner@cygnus.com) */
 
-#define _POSIX_SOURCE
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
 #include "libioP.h"
 #include <fcntl.h>
 #include <sys/types.h>
@@ -102,11 +104,11 @@ int
 DEFUN(_IO_file_close_it, (fp),
       register _IO_FILE* fp)
 {
-  int sync_status, close_status;
+  int write_status, close_status;
   if (!_IO_file_is_open(fp))
     return EOF;
 
-  sync_status = _IO_file_sync (fp);
+  write_status = _IO_do_flush (fp);
 
   _IO_unsave_markers(fp);
 
@@ -122,7 +124,7 @@ DEFUN(_IO_file_close_it, (fp),
   fp->_fileno = EOF;
   fp->_offset = _IO_pos_BAD;
 
-  return close_status ? close_status : sync_status;
+  return close_status ? close_status : write_status;
 }
 
 void
index 0b57ecd344d89c0e57af58e004d910cb0a8ce97c..989f6d6fe74fb9c39c53fa56850e1471d3b71afa 100644 (file)
@@ -23,14 +23,18 @@ This exception does not however invalidate any other reasons why
 the executable file might be covered by the GNU General Public License. */
 
 #include <libioP.h>
+#include <stdio.h>
 #include <stdlib.h>
 
-struct _IO_cookie_file {
-  struct _IO_FILE file;
-  const void *vtable;
-  void *cookie;
-  _IO_cookie_io_functions_t io_functions;
-};
+
+/* Prototyped for local functions.  */
+static _IO_ssize_t _IO_cookie_read __P ((register _IO_FILE* fp, void* buf,
+                                        _IO_ssize_t size));
+static _IO_ssize_t _IO_cookie_write __P ((register _IO_FILE* fp,
+                                         const void* buf, _IO_ssize_t size));
+static _IO_fpos_t _IO_cookie_seek __P ((_IO_FILE *fp, _IO_off_t offset,
+                                       int dir));
+static int _IO_cookie_close __P ((_IO_FILE* fp));
 
 
 static _IO_ssize_t
index 349a4cc8d60b9de1979cc1b897575f600dc749ef..b9ee737502f1ec07926ea46b843f4a3a657b38ce 100644 (file)
@@ -24,7 +24,9 @@ the executable file might be covered by the GNU General Public License. */
 
 /*  written by Per Bothner (bothner@cygnus.com) */
 
-#define _POSIX_SOURCE
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
 #include "libioP.h"
 #if _IO_HAVE_SYS_WAIT
 #include <signal.h>
@@ -32,24 +34,27 @@ the executable file might be covered by the GNU General Public License. */
 #ifdef __STDC__
 #include <stdlib.h>
 #endif
+#ifdef _LIBC
+# include <unistd.h>
+#endif
 #include <sys/types.h>
 #include <sys/wait.h>
 
 #ifndef _IO_fork
 #define _IO_fork vfork /* defined in libiberty, if needed */
-_IO_pid_t _IO_fork();
+extern _IO_pid_t _IO_fork __P ((void));
 #endif
 
 #endif /* _IO_HAVE_SYS_WAIT */
 
 #ifndef _IO_pipe
 #define _IO_pipe pipe
-extern int _IO_pipe();
+extern int _IO_pipe __P ((int des[2]));
 #endif
 
 #ifndef _IO_dup2
 #define _IO_dup2 dup2
-extern int _IO_dup2();
+extern int _IO_dup2 __P ((int fd, int fd2));
 #endif
 
 #ifndef _IO_waitpid
index fce8a77bf72cf802cdab39783a063401d8b7f066..b498f125ebd7fb2ed984c6274fbfc31f5261f5bd 100644 (file)
@@ -228,6 +228,16 @@ extern struct _IO_FILE_plus _IO_stdin_, _IO_stdout_, _IO_stderr_;
 #define _IO_stdout ((_IO_FILE*)(&_IO_stdout_))
 #define _IO_stderr ((_IO_FILE*)(&_IO_stderr_))
 
+
+/* Special file type for fopencookie function.  */
+struct _IO_cookie_file {
+  struct _IO_FILE file;
+  const void *vtable;
+  void *cookie;
+  _IO_cookie_io_functions_t io_functions;
+};
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
index a955151ade03f017f5a2e4e6443dd98da7dda517..173e75b86f8f1b5e5a6bcfa0d924b67c062fee79 100644 (file)
@@ -266,6 +266,13 @@ extern void _IO_str_init_static __P((_IO_FILE *, char*, int, char*));
 extern void _IO_str_init_readonly __P((_IO_FILE *, const char*, int));
 extern _IO_ssize_t _IO_str_count __P ((_IO_FILE*));
 
+extern int _IO_vasprintf __P ((char **result_ptr, __const char *format,
+                              _IO_va_list args));
+extern int _IO_vdprintf __P ((int d, __const char *format, _IO_va_list arg));
+extern int _IO_vsnprintf __P ((char *string, _IO_size_t maxlen,
+                              __const char *format, _IO_va_list args));
+
+
 extern _IO_size_t _IO_getline __P((_IO_FILE*,char*,_IO_size_t,int,int));
 extern _IO_ssize_t _IO_getdelim __P((char**, _IO_size_t*, int, _IO_FILE*));
 extern double _IO_strtod __P((const char *, char **));
index 71519a51906ac210cd86f199d19ee1f576e06f25..a2fe8447cb40649c78d6a1267870c23cb3c5d91d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -18,6 +18,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include "strfile.h"
 #include "libioP.h"
+#include <stdio.h>
 #include <stdlib.h>
 
 
index bd271ce1fb9bd614b3f964151a1f45317ba09e1e..70728ed8d9e090efb80aafd6388a8f6ee1e96c77 100644 (file)
@@ -108,6 +108,8 @@ extern int fgetc __P ((FILE *));
 extern int fgetpos __P ((FILE* fp, fpos_t *pos));
 extern char* fgets __P ((char*, int, FILE*));
 extern FILE* fopen __P ((__const char*, __const char*));
+extern FILE* fopencookie __P ((void *cookie, __const char *mode, 
+                              _IO_cookie_io_functions_t io_functions));
 extern int fprintf __P ((FILE*, __const char* format, ...));
 extern int fputc __P ((int, FILE*));
 extern int fputs __P ((__const char *str, FILE *fp));
@@ -138,6 +140,9 @@ extern int sprintf __P ((char*, __const char* format, ...));
 extern int sscanf __P ((__const char* string, __const char* format, ...));
 extern FILE* tmpfile __P ((void));
 extern char* tmpnam __P ((char*));
+extern char *__stdio_gen_tempname __P ((__const char *dir, __const char *pfx,
+                                       int dir_search, size_t *lenptr,
+                                       FILE **streamptr));
 extern int ungetc __P ((int c, FILE* fp));
 extern int vfprintf __P ((FILE *fp, char __const *fmt0, _G_va_list));
 extern int vprintf __P ((char __const *fmt, _G_va_list));
@@ -147,8 +152,10 @@ extern int vsprintf __P ((char* string, __const char* format, _G_va_list));
 extern int dprintf __P ((int, __const char *, ...));
 extern int vdprintf __P ((int, __const char *, _G_va_list));
 extern int vfscanf __P ((FILE*, __const char *, _G_va_list));
+extern int __vfscanf __P ((FILE*, __const char *, _G_va_list));
 extern int vscanf __P ((__const char *, _G_va_list));
 extern int vsscanf __P ((__const char *, __const char *, _G_va_list));
+extern int __vsscanf __P ((__const char *, __const char *, _G_va_list));
 #endif
 
 #if !defined(__STRICT_ANSI__) || defined(_POSIX_SOURCE)
@@ -166,6 +173,7 @@ extern _IO_ssize_t __getline __P ((char **, size_t *, FILE *));
 extern int snprintf __P ((char *, size_t, __const char *, ...));
 extern int __snprintf __P ((char *, size_t, __const char *, ...));
 extern int vsnprintf __P ((char *, size_t, __const char *, _G_va_list));
+extern int __vsnprintf __P ((char *, size_t, __const char *, _G_va_list));
 
 extern int asprintf __P ((char **, const char *, ...));
 extern int vasprintf __P ((char **, const char *, _G_va_list));
index f4f45259fb32dd05f4d5be82740e0d764291b203..98c5b263d5ee3ca01adffe09ea1f9cc9950a15f8 100644 (file)
@@ -51,7 +51,7 @@ DEFUN(_IO_str_init_static, (fp, ptr, size, pstart),
         This can lose in pathological cases (ptr near the end
         of the address space).  A better solution might be to
         adjust the size on underflow/overflow.  FIXME. */
-      for (s; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
+      for ( ; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
        size = s;
       size = s;
 #else
index 35b1971aa9a3a708e0f60f85d752c627ce204391..5e87a338862f374c8a1814f9f417665c160297bd 100644 (file)
@@ -85,7 +85,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
   /* We really have to load some data.  First see whether the name is
      an alias.  Please note that this makes it impossible to have "C"
      or "POSIX" as aliases.  */
-  loc_name = _nl_expand_alias (*name);
+  loc_name = (char *) _nl_expand_alias (*name);
   if (loc_name == NULL)
     /* It is no alias.  */
     loc_name = *name;
@@ -144,7 +144,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
     /* If the addressed locale is already available it should be freed.
        If we would not do this switching back and force between two
        locales would slowly eat up all memory.*/
-    free (loc_name);
+    free ((void *) loc_name);
 
   if (locale_file->decided == 0)
     _nl_load_locale (locale_file, category);
index 2e2f63bd9a7963f892b799f8434a8a8da92498bb..a7f988d3a5b725b0de400d810aee7823bf634479 100644 (file)
@@ -66,7 +66,7 @@ charset_find_value (const struct charset_t *cs, const char *name, size_t len)
   if (find_entry ((hash_table *) &cs->char_table, name, len, &result) < 0)
     return ILLEGAL_CHAR_VALUE;
 
-  return (unsigned int) result;
+  return (unsigned int) ((unsigned long int) result);
 }
 
 
@@ -81,7 +81,8 @@ insert_char (struct linereader *lr, struct charset_t *cs, int bytes,
 
   if (to == NULL)
     {
-      if (insert_entry (&cs->char_table, from, strlen (from), (void *) value)
+      if (insert_entry (&cs->char_table, from, strlen (from),
+                       (void *) (unsigned long int) value)
          < 0)
        lr_error (lr, _("duplicate character name `%s'"), from);
 
@@ -126,7 +127,8 @@ insert_char (struct linereader *lr, struct charset_t *cs, int bytes,
     {
       sprintf (&buf[prefix_len], "%0d", cnt);
 
-      if (insert_entry (&cs->char_table, buf, len1, (void *) cnt) < 0)
+      if (insert_entry (&cs->char_table, buf, len1,
+                       (void *) (unsigned long int) cnt) < 0)
        lr_error (lr, _("duplicate character name `%s'"), buf);
     }
 }
index 629df90ced1dec8fa17f16b810bc9c103e141d43..4bdf0b22563709c988cb0166b58f351f9aa4a4c0 100644 (file)
@@ -233,7 +233,7 @@ collate_finish (struct localedef_t *locale, struct charset_t *charset)
       else if (find_entry (&collate->symbols, patch->token, toklen, &ptmp)
               >= 0)
        {
-         value = (unsigned int) ptmp;
+         value = (unsigned long int) ptmp;
        }
       else
        value = 0;
index a717377a8b430714f829f8147b663780e6424131..5efa969baa94797474153cd9b337d03375627c08 100644 (file)
@@ -164,8 +164,12 @@ value for field `%s' in category `%s' must not be the empty string"),
 value for field `%s' in category `%s' must be in range %d...%d"),            \
           #cat, "LC_MONETARY", min, max)
 
+#if 0
+                                                                               /* The following two test are not really necessary because all values
+    the variable could have are valid.  */
   TEST_ELEM (int_frac_digits, -128, 127);      /* No range check.  */
   TEST_ELEM (frac_digits, -128, 127);          /* No range check.  */
+#endif
   TEST_ELEM (p_cs_precedes, -1, 1);
   TEST_ELEM (p_sep_by_space, -1, 2);
   TEST_ELEM (n_cs_precedes, -1, 1);
index 89dc6bb539a39da40cedd1a47a05d512d51fb85e..3bbe47901754636645c395f164399003cabeb580 100644 (file)
@@ -935,7 +935,7 @@ write_locale_data (const char *output_path, const char *category,
   int fd;
   char *fname;
 
-  asprintf (&fname, "%s/%s", output_path, category);
+  asprintf (&fname, "%s%s", output_path, category);
   fd = creat (fname, 0666);
   if (fd == -1)
     {
@@ -944,7 +944,7 @@ write_locale_data (const char *output_path, const char *category,
       if (errno == EISDIR)
        {
          free (fname);
-         asprintf (&fname, "%1$s/%2$s/SYS_%2$s", output_path, category);
+         asprintf (&fname, "%1$s%2$s/SYS_%2$s", output_path, category);
          fd = creat (fname, 0666);
          if (fd == -1)
            save_err = errno;
index a00ac7859dbe0e8c1e973b1f00a23c8576276e5d..6b8b9834ef93a9c5c5447b9537a5e4fdb39d2439 100644 (file)
@@ -836,7 +836,7 @@ of error you get if you request them and they are not supported.
 @end deftypevr
 
 @comment errno.h
-@comment ISO C: Invalid or incomplete multibyte or wide character
+@comment ISO: Invalid or incomplete multibyte or wide character
 @deftypevr Macro int EILSEQ
 @comment errno 106 @c DO NOT REMOVE
 While decoding a multibyte character the function came along an invalid
index 15c40c434d79fb83cac78f4c5ae9575353c22215..89c8fd4db9b1e8729b9fd58a815bf83dfce2e6f8 100644 (file)
@@ -252,6 +252,16 @@ extern char *getcwd __P ((char *__buf, size_t __size));
    If the environment variable `PWD' is set, and its value is correct,
    that value is used.  */
 extern char *get_current_dir_name __P ((void));
+
+/* Get the canonical absolute name of the named directory, and put it in SIZE
+   bytes of BUF.  Returns NULL if the directory couldn't be determined or
+   SIZE was too small.  If successful, returns BUF.  In GNU, if BUF is
+   NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
+   unless SIZE <= 0, in which case it is as big as necessary.  */
+
+char *__canonicalize_directory_name_internal __P ((const char *__thisdir,
+                                                  char *__buf,
+                                                  size_t __size));
 #endif
 
 #ifdef __USE_BSD
@@ -653,9 +663,6 @@ extern int swapon __P ((__const char *__path));
 /* Stop using block special device PATH for swapping.  */
 extern int swapoff __P ((__const char *__path));
 
-/* Reboot or halt the system.  */
-extern int reboot __P ((int __howto));
-
 
 /* Successive calls return the shells listed in `/etc/shells'.  */
 extern char *getusershell __P ((void));
index ebb8967155051f86625e9048c4630ada6898d941..58f32821fe2392bfb5102982ab0a25552740d1ce 100644 (file)
 subdir := resolv
 
 headers        := resolv.h netdb.h arpa/nameser.h sys/bitypes.h
-distribute := ../conf/portability.h
+distribute := ../conf/portability.h res_hconf.h
 
 routines := gethnamaddr getnetbyaddr getnetbyname getnetent getnetnamadr \
            herror nsap_addr res_comp res_debug res_data res_init res_mkquery \
-           res_query res_send sethostent inet_addr
+           res_query res_send sethostent inet_addr inet_ntop inet_pton \
+           res_hconf
 
 include ../Rules
 
index 3792b7963c6ab8bbd831528c2371a0c55857e319..0fb04a1a02fe53844ba14e75b0a8aec13b4a2edb 100644 (file)
@@ -3,7 +3,7 @@
  * -
  * Copyright (c) 1983, 1989, 1993
  *    The Regents of the University of California.  All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -19,7 +19,7 @@
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * SUCH DAMAGE.
  * -
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
+ *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -97,7 +97,8 @@
 #define RRFIXEDSZ      10              /* #/bytes of fixed data in r record */
 #define        INT32SZ         4               /* for systems without 32-bit ints */
 #define        INT16SZ         2               /* for systems without 16-bit ints */
-#define        INADDRSZ        4               /* for sizeof(struct inaddr) != 4 */
+#define        INADDRSZ        4               /* IPv4 T_A */
+#define IN6ADDRSZ      16              /* IPv6 T_AAAA */
 
 /*
  * Internet nameserver port number
 #define QUERY          0x0             /* standard query */
 #define IQUERY         0x1             /* inverse query */
 #define STATUS         0x2             /* nameserver status query */
-/*#define xxx          0x3             /* 0x3 reserved */
+/*#define xxx          0x3*/           /* 0x3 reserved */
 #define        NS_NOTIFY_OP    0x4             /* notify secondary of SOA change */
 #ifdef ALLOW_UPDATES
        /* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */
index f108f2778f487fba2b30540e20ebfc34ca22a9fc..b80595b7d51ef7bc06dcfa6503fba916bdfcbbf6 100644 (file)
@@ -3,7 +3,7 @@
  * -
  * Copyright (c) 1985, 1988, 1993
  *    The Regents of the University of California.  All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -19,7 +19,7 @@
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * SUCH DAMAGE.
  * -
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
+ *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -71,13 +71,15 @@ static char rcsid[] = "$Id$";
 #include <errno.h>
 #include <syslog.h>
 
+#include "res_hconf.h"
+
 #ifndef LOG_AUTH
 # define LOG_AUTH 0
 #endif
 
 #define MULTI_PTRS_ARE_ALIASES 1       /* XXX - experimental */
 
-#if defined(BSD) && (BSD >= 199103)
+#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
 # include <string.h>
 #else
 # include "../conf/portability.h"
@@ -88,6 +90,7 @@ static char rcsid[] = "$Id$";
 
 #define        MAXALIASES      35
 #define        MAXADDRS        35
+#define        MAXADDRBUFSIZE  8192
 
 static const char AskedForGot[] =
                          "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
@@ -97,11 +100,14 @@ static struct hostent *gethostbyname_ipv4 __P((const char *));
 
 static struct hostent host;
 static char *host_aliases[MAXALIASES];
-static char hostbuf[8*1024];
-static struct in_addr host_addr;
+static char hostbuf[MAXADDRBUFSIZE];
+static u_char host_addr[16];   /* IPv4 or IPv6 */
 static FILE *hostf = NULL;
 static int stayopen = 0;
 
+static void map_v4v6_address __P((const char *src, char *dst));
+static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len));
+
 #ifdef RESOLVSORT
 static void addrsort __P((char **, int));
 #endif
@@ -142,11 +148,11 @@ dprintf(msg, num)
 #endif
 
 static struct hostent *
-getanswer(answer, anslen, qname, qclass, qtype)
+getanswer(answer, anslen, qname, qtype)
        const querybuf *answer;
        int anslen;
        const char *qname;
-       int qclass, qtype;
+       int qtype;
 {
        register const HEADER *hp;
        register const u_char *cp;
@@ -165,13 +171,14 @@ getanswer(answer, anslen, qname, qclass, qtype)
        eom = answer->buf + anslen;
        switch (qtype) {
        case T_A:
+       case T_AAAA:
                name_ok = res_hnok;
                break;
        case T_PTR:
-               name_ok = dn_isvalid;
+               name_ok = res_dnok;
                break;
        default:
-               abort();
+               return (NULL);  /* XXX should be abort(); */
        }
        /*
         * find first satisfactory answer
@@ -192,7 +199,7 @@ getanswer(answer, anslen, qname, qclass, qtype)
                return (NULL);
        }
        cp += n + QFIXEDSZ;
-       if (qtype == T_A) {
+       if (qtype == T_A || qtype == T_AAAA) {
                /* res_send() has already verified that the query name is the
                 * same as the one we sent; this just gets the expanded name
                 * (i.e., with the succeeding search-domain tacked on).
@@ -209,9 +216,7 @@ getanswer(answer, anslen, qname, qclass, qtype)
        host.h_aliases = host_aliases;
        hap = h_addr_ptrs;
        *hap = NULL;
-#if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
        host.h_addr_list = h_addr_ptrs;
-#endif
        haveanswer = 0;
        had_error = 0;
        while (ancount-- > 0 && cp < eom && !had_error) {
@@ -227,12 +232,12 @@ getanswer(answer, anslen, qname, qclass, qtype)
                cp += INT16SZ + INT32SZ;        /* class, TTL */
                n = _getshort(cp);
                cp += INT16SZ;                  /* len */
-               if (class != qclass) {
+               if (class != C_IN) {
                        /* XXX - debug? syslog? */
                        cp += n;
                        continue;               /* XXX - had_error++ ? */
                }
-               if (qtype == T_A && type == T_CNAME) {
+               if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
                        if (ap >= &host_aliases[MAXALIASES-1])
                                continue;
                        n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
@@ -241,12 +246,6 @@ getanswer(answer, anslen, qname, qclass, qtype)
                                continue;
                        }
                        cp += n;
-                       if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
-                               syslog(LOG_NOTICE|LOG_AUTH,
-               "gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"",
-                                      host.h_name, bp);
-                               continue;       /* XXX - had_error++ ? */
-                       }
                        /* Store alias. */
                        *ap++ = bp;
                        n = strlen(bp) + 1;     /* for the \0 */
@@ -286,7 +285,7 @@ getanswer(answer, anslen, qname, qclass, qtype)
                if (type != qtype) {
                        syslog(LOG_NOTICE|LOG_AUTH,
               "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
-                              qname, p_class(qclass), p_type(qtype),
+                              qname, p_class(C_IN), p_type(qtype),
                               p_type(type));
                        cp += n;
                        continue;               /* XXX - had_error++ ? */
@@ -320,10 +319,17 @@ getanswer(answer, anslen, qname, qclass, qtype)
                        break;
 #else
                        host.h_name = bp;
+                       if (_res.options & RES_USE_INET6) {
+                               n = strlen(bp) + 1;     /* for the \0 */
+                               bp += n;
+                               buflen -= n;
+                               map_v4v6_hostent(&host, &bp, &buflen);
+                       }
                        h_errno = NETDB_SUCCESS;
                        return (&host);
 #endif
                case T_A:
+               case T_AAAA:
                        if (strcasecmp(host.h_name, bp) != 0) {
                                syslog(LOG_NOTICE|LOG_AUTH,
                                       AskedForGot, host.h_name, bp);
@@ -338,10 +344,6 @@ getanswer(answer, anslen, qname, qclass, qtype)
                        } else {
                                register int nn;
 
-                               host.h_length = n;
-                               host.h_addrtype = (class == C_IN)
-                                                 ? AF_INET
-                                                 : AF_UNSPEC;
                                host.h_name = bp;
                                nn = strlen(bp) + 1;    /* for the \0 */
                                bp += nn;
@@ -367,13 +369,11 @@ getanswer(answer, anslen, qname, qclass, qtype)
                        cp += n;
                        break;
                default:
-                       dprintf("Impossible condition (type=%d)\n", type);
-                       h_errno = NO_RECOVERY;
-                       return (NULL);
-               } /*switch*/
+                       abort();
+               }
                if (!had_error)
                        haveanswer++;
-       } /*while*/
+       }
        if (haveanswer) {
                *ap = NULL;
                *hap = NULL;
@@ -383,44 +383,39 @@ getanswer(answer, anslen, qname, qclass, qtype)
                 * in its return structures - should give it the "best"
                 * address in that case, not some random one
                 */
-               if (_res.nsort && haveanswer > 1 &&
-                   qclass == C_IN && qtype == T_A)
+               if (_res.nsort && haveanswer > 1 && qtype == T_A)
                        addrsort(h_addr_ptrs, haveanswer);
 # endif /*RESOLVSORT*/
-#if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
-               /* nothing */
-#else
-               host.h_addr = h_addr_ptrs[0];
-#endif /*BSD*/
                if (!host.h_name) {
                        n = strlen(qname) + 1;  /* for the \0 */
+                       if (n > buflen)
+                               goto try_again;
                        strcpy(bp, qname);
                        host.h_name = bp;
+                       bp += n;
+                       buflen -= n;
                }
+               if (_res.options & RES_USE_INET6)
+                       map_v4v6_hostent(&host, &bp, &buflen);
                h_errno = NETDB_SUCCESS;
                return (&host);
-       } else {
-               h_errno = TRY_AGAIN;
-               return (NULL);
        }
+ try_again:
+       h_errno = TRY_AGAIN;
+       return (NULL);
 }
 
 struct hostent *
 gethostbyname(name)
        const char *name;
 {
-  /* Moved #if line to here because declaring HP would lead to a
-     warning.  --drepper@gnu  */
-#if defined(AF_INET6) && defined(RES_TRY_INET6)
        struct hostent *hp;
 
-/* #if defined(AF_INET6) && defined(RES_TRY_INET6) */
-       if (_res.options & RES_TRY_INET6) {
+       if (_res.options & RES_USE_INET6) {
                hp = gethostbyname2(name, AF_INET6);
                if (hp)
                        return (hp);
        }
-#endif
        return (gethostbyname2(name, AF_INET));
 }
 
@@ -428,30 +423,36 @@ struct hostent *
 gethostbyname2(name, af)
        const char *name;
        int af;
-{
-       switch (af) {
-       case AF_INET:
-               return (gethostbyname_ipv4(name));
-       }
-       errno = EAFNOSUPPORT;
-       h_errno = NETDB_INTERNAL;
-       return (NULL);
-}
-
-static struct hostent *
-gethostbyname_ipv4(name)
-       const char *name;
 {
        querybuf buf;
        register const char *cp;
-       int n;
-       extern struct hostent *_gethtbyname();
+       char *bp;
+       int i, n, size, type, len;
+       extern struct hostent *_gethtbyname2();
 
        if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
                h_errno = NETDB_INTERNAL;
                return (NULL);
        }
 
+       switch (af) {
+       case AF_INET:
+               size = INADDRSZ;
+               type = T_A;
+               break;
+       case AF_INET6:
+               size = IN6ADDRSZ;
+               type = T_AAAA;
+               break;
+       default:
+               h_errno = NETDB_INTERNAL;
+               errno = EAFNOSUPPORT;
+               return (NULL);
+       }
+
+       host.h_addrtype = af;
+       host.h_length = size;
+
        /*
         * if there aren't any dots, it could be a user-level alias.
         * this is also done in res_query() since we are not the only
@@ -474,117 +475,254 @@ gethostbyname_ipv4(name)
                                 * Fake up a hostent as if we'd actually
                                 * done a lookup.
                                 */
-                               if (!inet_aton(name, &host_addr)) {
+                               if (inet_pton(af, name, host_addr,
+                                              sizeof host_addr) <= 0) {
                                        h_errno = HOST_NOT_FOUND;
                                        return (NULL);
                                }
                                strncpy(hostbuf, name, MAXDNAME);
                                hostbuf[MAXDNAME] = '\0';
+                               bp = hostbuf + MAXDNAME;
+                               len = sizeof hostbuf - MAXDNAME;
                                host.h_name = hostbuf;
                                host.h_aliases = host_aliases;
                                host_aliases[0] = NULL;
-                               host.h_addrtype = AF_INET;
-                               host.h_length = INT32SZ;
                                h_addr_ptrs[0] = (char *)&host_addr;
                                h_addr_ptrs[1] = NULL;
-#if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
                                host.h_addr_list = h_addr_ptrs;
-#else
-                               host.h_addr = h_addr_ptrs[0];
-#endif
+                               if (_res.options & RES_USE_INET6)
+                                       map_v4v6_hostent(&host, &bp, &len);
                                h_errno = NETDB_SUCCESS;
                                return (&host);
                        }
-                       if (!isdigit(*cp) && *cp != '.') 
+                       if (!isdigit(*cp) && *cp != '.')
                                break;
                }
 
-       if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
-               dprintf("res_search failed (%d)\n", n);
-               if (errno == ECONNREFUSED)
-                       return (_gethtbyname(name));
-               return (NULL);
+       h_errno = HOST_NOT_FOUND;
+       for (i = 0; i < _res_hconf.num_services; ++i) {
+               struct hostent * hp;
+               char * cp = (char *) name;
+
+               if (_res_hconf.num_trimdomains > 0) {
+                       size_t name_len = strlen(name);
+
+                       cp = malloc(name_len + 1);
+                       memcpy(cp, name, name_len + 1);
+                       _res_hconf_trim_domain(cp);
+               }
+
+               hp = NULL;
+               switch (_res_hconf.service[i]) {
+                     case SERVICE_BIND:
+                       if ((n = res_search(cp, C_IN, type,
+                                           buf.buf, sizeof(buf))) < 0)
+                       {
+                               dprintf("res_search failed (%d)\n", n);
+                               break;
+                       }
+                       hp = getanswer(&buf, n, cp, type);
+                       break;
+
+                     case SERVICE_HOSTS:
+                       hp = _gethtbyname2(cp, af);
+                       break;
+#ifdef HAVE_NYS
+                     case SERVICE_NIS:
+                       hp = _getnishost(cp, "hosts.byname");
+                       break;
+#endif
+                     default:
+                       break;
+               }
+               if (cp != name)
+                       free(cp);
+               if (hp) {
+                       if ((_res_hconf.flags & HCONF_FLAG_REORDER)
+                           && hp->h_addr_list[0] && hp->h_addr_list[1])
+                               _res_hconf_reorder_addrs(hp);
+                       _res_hconf_trim_domains(hp);
+                       return hp;
+               }
        }
-       return (getanswer(&buf, n, name, C_IN, T_A));
+       if (h_errno == NETDB_SUCCESS)
+               h_errno = HOST_NOT_FOUND;
+       return NULL;
 }
 
 struct hostent *
-gethostbyaddr(addr, len, type)
-       const char *addr;
-       int len, type;
+gethostbyaddr(addr, len, af)
+       const char *addr;       /* XXX should have been def'd as u_char! */
+       int len, af;
 {
-       int n;
+       const u_char *uaddr = (const u_char *)addr;
+       static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
+       static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
+       int n, size;
        querybuf buf;
        register struct hostent *hp;
-       char qbuf[MAXDNAME+1];
-#ifdef SUNSECURITY
+       char qbuf[MAXDNAME+1], *qp;
        register struct hostent *rhp;
        char **haddr;
        u_long old_options;
        char hname2[MAXDNAME+1];
-#endif /*SUNSECURITY*/
+       int i, old_num_trimdomains;
        extern struct hostent *_gethtbyaddr();
-       
+
        if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
                h_errno = NETDB_INTERNAL;
                return (NULL);
        }
-       if (type != AF_INET || len != INADDRSZ) {
+       if (af == AF_INET6 && len == IN6ADDRSZ &&
+           (!bcmp(uaddr, mapped, sizeof mapped) ||
+            !bcmp(uaddr, tunnelled, sizeof tunnelled))) {
+               /* Unmap. */
+               addr += sizeof mapped;
+               uaddr += sizeof mapped;
+               af = AF_INET;
+               len = INADDRSZ;
+       }
+       switch (af) {
+       case AF_INET:
+               size = INADDRSZ;
+               break;
+       case AF_INET6:
+               size = IN6ADDRSZ;
+               break;
+       default:
                errno = EAFNOSUPPORT;
                h_errno = NETDB_INTERNAL;
                return (NULL);
        }
-       (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
-               ((unsigned)addr[3] & 0xff),
-               ((unsigned)addr[2] & 0xff),
-               ((unsigned)addr[1] & 0xff),
-               ((unsigned)addr[0] & 0xff));
-       n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
-       if (n < 0) {
-               dprintf("res_query failed (%d)\n", n);
-               if (errno == ECONNREFUSED)
-                       return (_gethtbyaddr(addr, len, type));
-               return (NULL);
-       }
-       if (!(hp = getanswer(&buf, n, qbuf, C_IN, T_PTR)))
-               return (NULL);  /* h_errno was set by getanswer() */
-#ifdef SUNSECURITY
-       /*
-        * turn off search as the name should be absolute,
-        * 'localhost' should be matched by defnames
-        */
-       strncpy(hname2, hp->h_name, MAXDNAME);
-       hname2[MAXDNAME] = '\0';
-       old_options = _res.options;
-       _res.options &= ~RES_DNSRCH;
-       _res.options |= RES_DEFNAMES;
-       if (!(rhp = gethostbyname(hname2))) {
-               syslog(LOG_NOTICE|LOG_AUTH,
-                      "gethostbyaddr: No A record for %s (verifying [%s])",
-                      hname2, inet_ntoa(*((struct in_addr *)addr)));
-               _res.options = old_options;
-               h_errno = HOST_NOT_FOUND;
+       if (size != len) {
+               errno = EINVAL;
+               h_errno = NETDB_INTERNAL;
                return (NULL);
        }
-       _res.options = old_options;
-       for (haddr = rhp->h_addr_list; *haddr; haddr++)
-               if (!memcmp(*haddr, addr, INADDRSZ))
+
+       h_errno = NETDB_SUCCESS;
+       for (i = 0; i < _res_hconf.num_services; ++i) {
+               hp = NULL;
+               switch (_res_hconf.service[i]) {
+               case SERVICE_BIND:
+                       switch (af) {
+                       case AF_INET:
+                               (void) sprintf(qbuf,
+                                              "%u.%u.%u.%u.in-addr.arpa",
+                                              (uaddr[3] & 0xff),
+                                              (uaddr[2] & 0xff),
+                                              (uaddr[1] & 0xff),
+                                              (uaddr[0] & 0xff));
+                               break;
+                       case AF_INET6:
+                               qp = qbuf;
+                               for (n = IN6ADDRSZ - 1; n >= 0; n--) {
+                                       qp += sprintf(qp, "%x.%x.",
+                                                     uaddr[n] & 0xf,
+                                                     (uaddr[n] >> 4) & 0xf);
+                               }
+                               strcpy(qp, "ip6.int");
+                               break;
+                       default:
+                               abort();
+                       }
+                       n = res_query(qbuf, C_IN, T_PTR,
+                                     (u_char *)buf.buf, sizeof buf.buf);
+                       if (n < 0) {
+                               dprintf("res_query failed (%d)\n", n);
+                               break;
+                       }
+                       hp = getanswer(&buf, n, qbuf, T_PTR);
+                       if (!hp)
+                               break;  /* h_errno was set by getanswer() */
+                       if (af == AF_INET
+                           && (_res_hconf.flags & HCONF_FLAG_SPOOF)) {
+                               /*
+                                * Turn off search as the name should
+                                * be absolute, 'localhost' should be
+                                * matched by defnames
+                                */
+                               strncpy(hname2, hp->h_name, MAXDNAME);
+                               hname2[MAXDNAME] = '\0';
+                               old_options = _res.options;
+                               /*
+                                * Also turn off domain trimming to prevent it
+                                * from causing the name comparison to fail.
+                                */
+                               old_num_trimdomains =
+                                       _res_hconf.num_trimdomains;
+                               _res.options &= ~RES_DNSRCH;
+                               _res.options |= RES_DEFNAMES;
+                               rhp = gethostbyname(hname2);
+                               _res.options = old_options;
+                               /* There must be an A record and
+                                  the names must match.  */
+                               if (!rhp || strcmp(hname2, rhp->h_name)) {
+                                       syslog(LOG_NOTICE|LOG_AUTH,
+                                              "gethostbyaddr: No A record for"
+                                              " %s (verifying [%s])",
+                                              hname2,
+                                              inet_ntoa(*((struct in_addr *)
+                                                          addr)));
+                                       h_errno = HOST_NOT_FOUND;
+                                       break;
+                               }
+                               for (haddr = rhp->h_addr_list; *haddr; haddr++)
+                                       if (!memcmp(*haddr, addr, INADDRSZ))
+                                               break;
+                               if (!*haddr) {
+                                       syslog(LOG_NOTICE|LOG_AUTH,
+                                              "gethostbyaddr: A record of %s"
+                                              " != PTR record [%s]",
+                                              hname2,
+                                              inet_ntoa(*((struct in_addr *)
+                                                          addr)));
+                                       h_errno = HOST_NOT_FOUND;
+                                       break;
+                               }
+                       }
+                       hp->h_addrtype = af;
+                       hp->h_length = len;
+                       bcopy(addr, host_addr, len);
+                       h_addr_ptrs[0] = (char *)host_addr;
+                       h_addr_ptrs[1] = NULL;
+                       if (af == AF_INET && (_res.options & RES_USE_INET6)) {
+                               map_v4v6_address((char*)host_addr,
+                                                (char*)host_addr);
+                               hp->h_addrtype = AF_INET6;
+                               hp->h_length = IN6ADDRSZ;
+                       }
+                       h_errno = NETDB_SUCCESS;
                        break;
-       if (!*haddr) {
-               syslog(LOG_NOTICE|LOG_AUTH,
-                      "gethostbyaddr: A record of %s != PTR record [%s]",
-                      hname2, inet_ntoa(*((struct in_addr *)addr)));
-               h_errno = HOST_NOT_FOUND;
-               return (NULL);
+
+               case SERVICE_HOSTS:
+                       hp = _gethtbyaddr(addr, len, af);
+                       break;
+
+#ifdef HAVE_NYS
+               case SERVICE_NIS:
+                       if (af == AF_INET) {
+                               sprintf(qbuf, "%u.%u.%u.%u",
+                                       (unsigned)addr[0] & 0xff,
+                                       (unsigned)addr[1] & 0xff,
+                                       (unsigned)addr[2] & 0xff,
+                                       (unsigned)addr[3] & 0xff);
+                               hp = _getnishost(qbuf, "hosts.byaddr");
+                       }
+                       break;
+#endif
+
+               default:
+                       break;
+               }
+               if (hp) {
+                       _res_hconf_trim_domains(hp);
+                       return hp;
+               }
        }
-#endif /*SUNSECURITY*/
-       hp->h_addrtype = type;
-       hp->h_length = len;
-       h_addr_ptrs[0] = (char *)&host_addr;
-       h_addr_ptrs[1] = NULL;
-       host_addr = *(struct in_addr *)addr;
-       h_errno = NETDB_SUCCESS;
-       return (hp);
+       if (h_errno == NETDB_SUCCESS)
+               h_errno = HOST_NOT_FOUND;
+       return NULL;
 }
 
 void
@@ -612,12 +750,13 @@ _gethtent()
 {
        char *p;
        register char *cp, **q;
+       int af, len;
 
        if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
                h_errno = NETDB_INTERNAL;
                return (NULL);
        }
-again:
+ again:
        if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) {
                h_errno = HOST_NOT_FOUND;
                return (NULL);
@@ -630,18 +769,27 @@ again:
        if (!(cp = strpbrk(p, " \t")))
                goto again;
        *cp++ = '\0';
-       /* THIS STUFF IS INTERNET SPECIFIC */
-       if (!inet_aton(p, &host_addr))
+       if ((_res.options & RES_USE_INET6) &&
+           inet_pton(AF_INET6, p, host_addr, sizeof host_addr) > 0) {
+               af = AF_INET6;
+               len = IN6ADDRSZ;
+       } else if (inet_pton(AF_INET, p, host_addr, sizeof host_addr) > 0) {
+               if (_res.options & RES_USE_INET6) {
+                       map_v4v6_address((char*)&host_addr, (char*)&host_addr);
+                       af = AF_INET6;
+                       len = IN6ADDRSZ;
+               } else {
+                       af = AF_INET;
+                       len = INADDRSZ;
+               }
+       } else {
                goto again;
+       }
        h_addr_ptrs[0] = (char *)&host_addr;
        h_addr_ptrs[1] = NULL;
-#if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
        host.h_addr_list = h_addr_ptrs;
-#else
-       host.h_addr = h_addr_ptrs[0];
-#endif
-       host.h_length = INT32SZ;
-       host.h_addrtype = AF_INET;
+       host.h_length = len;
+       host.h_addrtype = af;
        while (*cp == ' ' || *cp == '\t')
                cp++;
        host.h_name = cp;
@@ -659,45 +807,275 @@ again:
                        *cp++ = '\0';
        }
        *q = NULL;
+       if (_res.options & RES_USE_INET6) {
+               char *bp = hostbuf;
+               int buflen = sizeof hostbuf;
+
+               map_v4v6_hostent(&host, &bp, &buflen);
+       }
        h_errno = NETDB_SUCCESS;
        return (&host);
 }
 
+struct hstorage {
+       char    name[MAXHOSTNAMELEN + 1];       /* canonical name */
+       char ** alp;                            /* address list pointer */
+       char *  abp;                            /* address buffer pointer */
+       char *  addr_list[MAXADDRS + 1];        /* address list storage */
+       char    addr_buf[MAXADDRBUFSIZE];       /* addresses storage */
+};
+
+static void
+append_addr (struct hstorage * hs, struct hostent *p)
+{
+       if (hs->alp < hs->addr_list + MAXADDRS
+           && hs->abp + p->h_length < hs->addr_buf + MAXADDRBUFSIZE)
+       {
+               hs->alp[0] = hs->abp;
+               hs->alp[1] = 0;
+               memcpy(hs->abp, p->h_addr_list[0], p->h_length);
+               hs->abp += p->h_length;
+               ++hs->alp;
+       }
+}
+
+/*
+ * Lookup IP address and aliases for host NAME.  If multiaddress mode
+ * is enabled, the entire /etc/hosts file is searched and the union of
+ * all addresses found for NAME is returned (this may be slow with
+ * large /etc/hosts files, but is convenient for smallish sites that
+ * don't want to go through the complexity of running named locally).
+ * If multiaddress mode is enabled, the address returned in
+ * h_addr_list[0] is one that is on the same net as one of the host's
+ * local addresses (if such an address exists).  For compatibility
+ * with the BIND version of gethostbyname(), the alias field is empty
+ * unless the name being looked up is an alias itself.  In the latter
+ * case, the name field contains the canonical name and the alias
+ * field the name that is being looked up.  A difference from the BIND
+ * version is that this is true even if the alias applies only to one
+ * of the interfaces on the target host.o
+ */
 struct hostent *
 _gethtbyname(name)
-       char *name;
+       const char *name;
+{
+       extern struct hostent *_gethtbyname2 __P((const char *, int));
+       struct hostent *hp;
+
+       if (_res.options & RES_USE_INET6) {
+               hp = _gethtbyname2(name, AF_INET6);
+               if (hp)
+                       return (hp);
+       }
+       return (_gethtbyname2(name, AF_INET));
+}
+
+struct hostent *
+_gethtbyname2(name, af)
+       const char *name;
+       int af;
 {
        register struct hostent *p;
        register char **cp;
-       
+
        _sethtent(0);
-       while (p = _gethtent()) {
-               if (strcasecmp(p->h_name, name) == 0)
-                       break;
-               for (cp = p->h_aliases; *cp != 0; cp++)
-                       if (strcasecmp(*cp, name) == 0)
-                               goto found;
+
+       if (_res_hconf.flags & HCONF_FLAG_MULTI) {
+               /*
+                * More statics; not pretty, but it would require
+                * interface changes to make these functions
+                * reentrant.
+                */
+               static char * aliases[2];
+               static char alias[MAXHOSTNAMELEN + 1];
+               static struct hstorage self, target;
+               static struct hostent ht;
+               int found;
+
+               aliases[0] = aliases[1] = 0;
+
+               gethostname(self.name, sizeof(self.name));
+               self.alp = self.addr_list;
+               self.abp = self.addr_buf;
+
+               strncpy(target.name, name, MAXHOSTNAMELEN);
+               target.name[MAXHOSTNAMELEN] = '\0';
+               target.alp = target.addr_list;
+               target.abp = target.addr_buf;
+
+               _sethtent(0);
+               while ((p = _gethtent()) != 0) {
+                       found = 1;
+
+                       if (p->h_addrtype != af)
+                               continue;
+                       if (strcasecmp(p->h_name, name) != 0) {
+                               found = 0;
+                               for (cp = p->h_aliases; *cp; ++cp)
+                                       if (strcasecmp(*cp, name) == 0) {
+                                               found = 1;
+                                               if (!aliases[0]) {
+                                                       strcpy(target.name,
+                                                              p->h_name);
+                                                       strncpy(alias, name,
+                                                               MAXHOSTNAMELEN);
+                                                       alias[MAXHOSTNAMELEN]
+                                                               = '\0';
+                                                       aliases[0] = alias;
+                                               }
+                                               break;
+                                       }
+                       }
+                       if (found) {
+                               /* they better be all the same type and length! */
+                               ht.h_addrtype = p->h_addrtype;
+                               ht.h_length = p->h_length;
+                               append_addr(&target, p);
+                               /*
+                                * If the current hostentry is for the target host, we don't
+                                * check for the local host name.  This nicely optimizes the
+                                * case where NAME is a local name since address ordering
+                                * doesn't matter in that case.
+                                */
+                               continue;
+                       }
+                       found = 1;
+                       if (strcasecmp(p->h_name, self.name) != 0) {
+                               found = 0;
+                               for (cp = p->h_aliases; *cp; ++cp)
+                                       if (strcasecmp(*cp, self.name) == 0) {
+                                               found = 1;
+                                               break;
+                                       }
+                       }
+                       if (found) {
+                               append_addr(&self, p);
+                       }
+               }
+               _endhtent();
+
+               if (target.alp == target.addr_list)
+                       return NULL;            /* found nothing */
+
+               ht.h_aliases   = aliases;
+               ht.h_name      = target.name;
+               ht.h_addr_list = target.addr_list;
+               /*
+                * XXX (davidm) Isn't this subsumed by REORDER???
+                *
+                * Finding the `best' address is necessarily address
+                * specific.  For now, we do IPv4 addresses only.
+                */
+               if (af == AF_INET) {
+                       u_int32_t a1, a2, diff, mindiff = ~0;
+                       int i, j, bestaddr = 0;
+
+                       for (i = 0; self.addr_list[i]; ++i) {
+                               for (j = 0; target.addr_list[j]; ++j) {
+                                       memcpy(&a1, self.addr_list[i], 4);
+                                       memcpy(&a2, target.addr_list[j], 4);
+                                       a1 = ntohl(a1);
+                                       a2 = ntohl(a2);
+                                       diff = a1 ^ a2;
+                                       if (diff < mindiff) {
+                                               bestaddr = j;
+                                               mindiff = diff;
+                                       }
+                               }
+                       }
+                       if (bestaddr > 0) {
+                               char * tmp;
+
+                               tmp = target.addr_list[0];
+                               target.addr_list[0] = target.addr_list[bestaddr];
+                               target.addr_list[bestaddr] = tmp;
+                       }
+               } else if (af == AF_INET6) {
+                       /* XXX To do!!! */
+               }
+               ht.h_addr_list = target.addr_list;
+               return &ht;
+       } else {
+               _sethtent(0);
+               while (p = _gethtent()) {
+                       if (p->h_addrtype != af)
+                               continue;
+                       if (strcasecmp(p->h_name, name) == 0)
+                               break;
+                       for (cp = p->h_aliases; *cp != 0; cp++)
+                               if (strcasecmp(*cp, name) == 0)
+                                       goto found;
+               }
        }
-found:
+ found:
        _endhtent();
        return (p);
 }
 
 struct hostent *
-_gethtbyaddr(addr, len, type)
+_gethtbyaddr(addr, len, af)
        const char *addr;
-       int len, type;
+       int len, af;
 {
        register struct hostent *p;
 
        _sethtent(0);
        while (p = _gethtent())
-               if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
+               if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
                        break;
        _endhtent();
        return (p);
 }
 
+static void
+map_v4v6_address(src, dst)
+       const char *src;
+       char *dst;
+{
+       u_char *p = (u_char *)dst;
+       char tmp[INADDRSZ];
+       int i;
+
+       /* Stash a temporary copy so our caller can update in place. */
+       bcopy(src, tmp, INADDRSZ);
+       /* Mark this ipv6 addr as a mapped ipv4. */
+       for (i = 0; i < 10; i++)
+               *p++ = 0x00;
+       *p++ = 0xff;
+       *p++ = 0xff;
+       /* Retrieve the saved copy and we're done. */
+       bcopy(tmp, (void*)p, INADDRSZ);
+}
+
+static void
+map_v4v6_hostent(hp, bpp, lenp)
+       struct hostent *hp;
+       char **bpp;
+       int *lenp;
+{
+       char **ap;
+
+       if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
+               return;
+       hp->h_addrtype = AF_INET6;
+       hp->h_length = IN6ADDRSZ;
+       for (ap = hp->h_addr_list; *ap; ap++) {
+               int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
+
+               if (*lenp < (i + IN6ADDRSZ)) {
+                       /* Out of memory.  Truncate address list here.  XXX */
+                       *ap = NULL;
+                       return;
+               }
+               *bpp += i;
+               *lenp -= i;
+               map_v4v6_address(*ap, *bpp);
+               *ap = *bpp;
+               *bpp += IN6ADDRSZ;
+               *lenp -= IN6ADDRSZ;
+       }
+}
+
 #ifdef RESOLVSORT
 static void
 addrsort(ap, num)
@@ -712,7 +1090,7 @@ addrsort(ap, num)
        p = ap;
        for (i = 0; i < num; i++, p++) {
            for (j = 0 ; (unsigned)j < _res.nsort; j++)
-               if (_res.sort_list[j].addr.s_addr == 
+               if (_res.sort_list[j].addr.s_addr ==
                    (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
                        break;
            aval[i] = j;
@@ -766,17 +1144,57 @@ ht_gethostbyname(name)
 }
 
 struct hostent *
-ht_gethostbyaddr(addr, len, type)
+ht_gethostbyaddr(addr, len, af)
        const char *addr;
-       int len, type;
+       int len, af;
 {
-       return (_gethtbyaddr(addr, len, type));
+       return (_gethtbyaddr(addr, len, af));
 }
 
 struct hostent *
 gethostent()
 {
-       return (_gethtent());
+       struct hostent * hp;
+       int i;
+
+       if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+               h_errno = NETDB_INTERNAL;
+               return (NULL);
+       }
+
+       /*
+        * This doesn't look quite right.  Shouldn't we read one
+        * service until it returns 0, then move on to the next
+        * service?  If so, it requires adding some state and
+        * initializing that state in sethostent().
+        * (davidm@azstarnet.com)
+        */
+       for (i = 0; i < _res_hconf.num_services; ++i) {
+               hp = NULL;
+               switch (_res_hconf.service[i]) {
+                     case SERVICE_HOSTS:
+                       hp = _gethtent ();
+                       break;
+
+#ifdef HAVE_NYS
+                     case SERVICE_NIS:
+                       hp = _getnishost (NULL, "hosts.byname");
+                       break;
+#endif
+
+                     case SERVICE_BIND:
+                     default:
+                       break;
+               }
+               if (hp) {
+                       if ((_res_hconf.flags & HCONF_FLAG_REORDER)
+                           && hp->h_addr_list[0] && hp->h_addr_list[1])
+                               _res_hconf_reorder_addrs (hp);
+                       return hp;
+               }
+       }
+       h_errno = HOST_NOT_FOUND;
+       return NULL;
 }
 
 void
index fad2b8c0cdefbba39e323faa5dda4a75d5ca8047..9739995e36cdc38b99a3c856b3001d4c2b0fc9fe 100644 (file)
@@ -139,7 +139,7 @@ static      char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
        haveanswer = 0;
        while (--ancount >= 0 && cp < eom) {
                n = dn_expand(answer->buf, eom, cp, bp, buflen);
-               if ((n < 0) || !dn_isvalid(bp))
+               if ((n < 0) || !res_dnok(bp))
                        break;
                cp += n;
                ans[0] = '\0';
@@ -209,7 +209,7 @@ getnetbyaddr(net, net_type)
        int nn, anslen;
        querybuf buf;
        char qbuf[MAXDNAME];
-       u_int32_t net2;
+       u_int32_t net2;         /* Changed from unsigned long --roland */
        struct netent *net_entry;
 
        if (net_type != AF_INET)
index bcf7f0d336270550d8777770793cb5bfb6f192c7..2caf747acf0eecc802123632dc669e2b202454a2 100644 (file)
@@ -3,7 +3,7 @@
  * -
  * Copyright (c) 1983, 1990, 1993
  *    The Regents of the University of California.  All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -19,7 +19,7 @@
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * SUCH DAMAGE.
  * -
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
+ *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -70,7 +70,7 @@ static char rcsid[] = "$Id$";
  * Ascii internet address interpretation routine.
  * The value returned is in network order.
  */
-u_int32_t
+u_long
 inet_addr(cp)
        register const char *cp;
 {
@@ -81,7 +81,7 @@ inet_addr(cp)
        return (INADDR_NONE);
 }
 
-/* 
+/*
  * Check whether "cp" is a valid ascii representation
  * of an Internet address and convert to a binary address.
  * Returns 1 if the address is valid, 0 if not.
@@ -93,7 +93,7 @@ inet_aton(cp, addr)
        register const char *cp;
        struct in_addr *addr;
 {
-       register u_int32_t val;
+       register u_int32_t val; /* changed from u_long --david */
        register int base, n;
        register char c;
        u_int parts[4];
diff --git a/resolv/inet_ntop.c b/resolv/inet_ntop.c
new file mode 100644 (file)
index 0000000..71db06d
--- /dev/null
@@ -0,0 +1,189 @@
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include "../conf/portability.h"
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size));
+static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
+
+/* char *
+ * inet_ntop(af, src, dst, size)
+ *     convert a network format address to presentation format.
+ * return:
+ *     pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ *     Paul Vixie, 1996.
+ */
+const char *
+inet_ntop(af, src, dst, size)
+       int af;
+       const void *src;
+       char *dst;
+       size_t size;
+{
+       switch (af) {
+       case AF_INET:
+               return (inet_ntop4(src, dst, size));
+       case AF_INET6:
+               return (inet_ntop6(src, dst, size));
+       default:
+               errno = EAFNOSUPPORT;
+               return (NULL);
+       }
+       /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ *     format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ *     `dst' (as a const)
+ * notes:
+ *     (1) uses no statics
+ *     (2) takes a u_char* not an in_addr as input
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(src, dst, size)
+       const u_char *src;
+       char *dst;
+       size_t size;
+{
+       static const char fmt[] = "%u.%u.%u.%u";
+       char tmp[sizeof "255.255.255.255"];
+
+       if (sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) > size) {
+               errno = ENOSPC;
+               return (NULL);
+       }
+       strcpy(dst, tmp);
+       return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ *     convert IPv6 binary address into presentation (printable) format
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(src, dst, size)
+       const u_char *src;
+       char *dst;
+       size_t size;
+{
+       /*
+        * Note that int32_t and int16_t need only be "at least" large enough
+        * to contain a value of the specified size.  On some systems, like
+        * Crays, there is no such thing as an integer variable with 16 bits.
+        * Keep this in mind if you think this function should have been coded
+        * to use pointer overlays.  All the world's not a VAX.
+        */
+       char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+       struct { int base, len; } best, cur;
+       u_int words[IN6ADDRSZ / INT16SZ];
+       int i;
+
+       /*
+        * Preprocess:
+        *      Copy the input (bytewise) array into a wordwise array.
+        *      Find the longest run of 0x00's in src[] for :: shorthanding.
+        */
+       bzero(words, sizeof words);
+       for (i = 0; i < IN6ADDRSZ; i++)
+               words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+       best.base = -1;
+       cur.base = -1;
+       for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+               if (words[i] == 0) {
+                       if (cur.base == -1)
+                               cur.base = i, cur.len = 1;
+                       else
+                               cur.len++;
+               } else {
+                       if (cur.base != -1) {
+                               if (best.base == -1 || cur.len > best.len)
+                                       best = cur;
+                               cur.base = -1;
+                       }
+               }
+       }
+       if (cur.base != -1) {
+               if (best.base == -1 || cur.len > best.len)
+                       best = cur;
+       }
+       if (best.base != -1 && best.len < 2)
+               best.base = -1;
+
+       /*
+        * Format the result.
+        */
+       tp = tmp;
+       for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+               /* Are we inside the best run of 0x00's? */
+               if (best.base != -1 && i >= best.base &&
+                   i < (best.base + best.len)) {
+                       if (i == best.base)
+                               *tp++ = ':';
+                       continue;
+               }
+               /* Are we following an initial run of 0x00s or any real hex? */
+               if (i != 0)
+                       *tp++ = ':';
+               /* Is this address an encapsulated IPv4? */
+               if (i == 6 && best.base == 0 &&
+                   (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+                       if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
+                               return (NULL);
+                       tp += strlen(tp);
+                       break;
+               }
+               tp += sprintf(tp, "%x", words[i]);
+       }
+       /* Was it a trailing run of 0x00's? */
+       if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+               *tp++ = ':';
+       *tp++ = '\0';
+
+       /*
+        * Check for overflow, copy, and we're done.
+        */
+       if ((tp - tmp) > size) {
+               errno = ENOSPC;
+               return (NULL);
+       }
+       strcpy(dst, tmp);
+       return (dst);
+}
diff --git a/resolv/inet_pton.c b/resolv/inet_pton.c
new file mode 100644 (file)
index 0000000..385dc25
--- /dev/null
@@ -0,0 +1,223 @@
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <errno.h>
+#include "../conf/portability.h"
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int     inet_pton4 __P((const char *src, u_char *dst));
+static int     inet_pton6 __P((const char *src, u_char *dst));
+
+/* int
+ * inet_pton(af, src, dst, size)
+ *     convert from presentation format (which usually means ASCII printable)
+ *     to network format (which is usually some kind of binary format).
+ * return:
+ *     1 if the address was valid for the specified address family
+ *     0 if the address wasn't valid (`dst' is untouched in this case)
+ *     -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ *     Paul Vixie, 1996.
+ */
+int
+inet_pton(af, src, dst, size)
+       int af;
+       const char *src;
+       void *dst;
+       size_t size;
+{
+       switch (af) {
+       case AF_INET:
+               if (size < INADDRSZ) {
+                       errno = ENOSPC;
+                       return (-1);
+               }
+               return (inet_pton4(src, dst));
+       case AF_INET6:
+               if (size < IN6ADDRSZ) {
+                       errno = ENOSPC;
+                       return (-1);
+               }
+               return (inet_pton6(src, dst));
+       default:
+               errno = EINVAL;
+               return (-1);
+       }
+       /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *     like inet_pton() but without all the hexadecimal and shorthand.
+ * return:
+ *     1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *     does not touch `dst' unless it's returning 1.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton4(src, dst)
+       const char *src;
+       u_char *dst;
+{
+       static const char digits[] = "0123456789";
+       int saw_digit, octets, ch;
+       u_char tmp[INADDRSZ], *tp;
+
+       saw_digit = 0;
+       octets = 0;
+       *(tp = tmp) = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               if ((pch = strchr(digits, ch)) != NULL) {
+                       u_int new = *tp * 10 + (pch - digits);
+
+                       if (new > 255)
+                               return (0);
+                       *tp = new;
+                       if (! saw_digit) {
+                               if (++octets > 4)
+                                       return (0);
+                               saw_digit = 1;
+                       }
+               } else if (ch == '.' && saw_digit) {
+                       if (octets == 4)
+                               return (0);
+                       *++tp = 0;
+                       saw_digit = 0;
+               } else
+                       return (0);
+       }
+       if (octets < 4)
+               return (0);
+       bcopy(tmp, dst, INADDRSZ);
+       return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ *     convert presentation level address to network order binary form.
+ * return:
+ *     1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *     (1) does not touch `dst' unless it's returning 1.
+ *     (2) :: in a full address is silently ignored.
+ * credit:
+ *     inspired by Mark Andrews.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton6(src, dst)
+       const char *src;
+       u_char *dst;
+{
+       static const char xdigits_l[] = "0123456789abcdef",
+                         xdigits_u[] = "0123456789ABCDEF";
+       u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+       const char *xdigits, *curtok;
+       int ch, saw_xdigit;
+       u_int val;
+
+       bzero((tp = tmp), IN6ADDRSZ);
+       endp = tp + IN6ADDRSZ;
+       colonp = NULL;
+       /* Leading :: requires some special handling. */
+       if (*src == ':')
+               if (*++src != ':')
+                       return (0);
+       curtok = src;
+       saw_xdigit = 0;
+       val = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+                       pch = strchr((xdigits = xdigits_u), ch);
+               if (pch != NULL) {
+                       val <<= 4;
+                       val |= (pch - xdigits);
+                       if (val > 0xffff)
+                               return (0);
+                       saw_xdigit = 1;
+                       continue;
+               }
+               if (ch == ':') {
+                       curtok = src;
+                       if (!saw_xdigit) {
+                               if (colonp)
+                                       return (0);
+                               colonp = tp;
+                               continue;
+                       }
+                       if (tp + INT16SZ > endp)
+                               return (0);
+                       *tp++ = (u_char) (val >> 8) & 0xff;
+                       *tp++ = (u_char) val & 0xff;
+                       saw_xdigit = 0;
+                       val = 0;
+                       continue;
+               }
+               if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+                   inet_pton4(curtok, tp) > 0) {
+                       tp += INADDRSZ;
+                       saw_xdigit = 0;
+                       break;  /* '\0' was seen by inet_pton4(). */
+               }
+               return (0);
+       }
+       if (saw_xdigit) {
+               if (tp + INT16SZ > endp)
+                       return (0);
+               *tp++ = (u_char) (val >> 8) & 0xff;
+               *tp++ = (u_char) val & 0xff;
+       }
+       if (colonp != NULL) {
+               /*
+                * Since some memmove()'s erroneously fail to handle
+                * overlapping regions, we'll do the shift by hand.
+                */
+               const howmany = tp - colonp;
+               int i;
+
+               for (i = 1; i <= howmany; i++) {
+                       endp[- i] = colonp[howmany - i];
+                       colonp[howmany - i] = 0;
+               }
+               tp = endp;
+       }
+       if (tp != endp)
+               return (0);
+       bcopy(tmp, dst, IN6ADDRSZ);
+       return (1);
+}
index f234772e4139174da14448f73dbd01c2efb439a1..e105dbb0b6eea825ad0adbf013a85c85d1696113 100644 (file)
@@ -3,7 +3,7 @@
  * -
  * Copyright (c) 1985, 1993
  *    The Regents of the University of California.  All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -19,7 +19,7 @@
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * SUCH DAMAGE.
  * -
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
+ *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -343,7 +343,7 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
 /****
 To: "Lawrence R. Rogers" <lrr@cert.org>
 cc: cert@cert.org, pvm@home.net
-Subject: Re: VU#14542 
+Subject: Re: VU#14542
 In-reply-to: Your message of "Mon, 19 Feb 1996 17:16:27 PST."
 Date: Tue, 20 Feb 1996 22:37:21 -0800
 From: Paul A Vixie <vixie@wisdom.home.vix.com>
@@ -359,7 +359,7 @@ in retrospect,
 should have been
 
        hostname = label ( "." label )+
-       firstchar = [a-zA-Z0-9_]
+       firstchar = [a-zA-Z0-9]
        otherchar = [a-zA-Z0-9_-]
        label = firstchar otherchar*
 
@@ -368,53 +368,98 @@ earlier.  since i'm only trying to bend the spec to fit actual known uses,
 i should not have widened the rules as far as i did earlier.
 ****/
 
-#define firstchar(c) ((isascii(c) && isalnum(c)) || (c) == '_')
-#define otherchar(c) (firstchar(c) || (c) == '-')
-#define        wildlabel(firstlabel, ch, nch) \
-       ((firstlabel) && (ch) == '*' && ((nch) == '.' || (nch) == '\0'))
+/*
+ * Note the conspicuous absence of ctype macros in these definitions.  On
+ * non-ASCII hosts, we can't depend on string literals or ctype macros to
+ * tell us anything about network-format data.  The rest of the BIND system
+ * is not careful about this, but for some reason, we're doing it right here.
+ */
+#define PERIOD 0x2e
+#define        hyphenchar(c) ((c) == 0x2d)
+#define bslashchar(c) ((c) == 0x5c)
+#define periodchar(c) ((c) == PERIOD)
+#define asterchar(c) ((c) == 0x2a)
+#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
+                  || ((c) >= 0x61 && (c) <= 0x7a))
+#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
+
+#define borderchar(c) (alphachar(c) || digitchar(c))
+#define middlechar(c) (borderchar(c) || hyphenchar(c))
+#define        domainchar(c) ((c) > 0x20 && (c) < 0x7f)
 
 int
 res_hnok(dn)
        const char *dn;
 {
-       int ppch = '\0', pch = '.', ch = *dn++, firstlabel = 1;
+       int ppch = '\0', pch = PERIOD, ch = *dn++;
 
        while (ch != '\0') {
                int nch = *dn++;
 
-               if (ch == '.' || (ch == '\\' && nch == '.')) {
+               if (periodchar(ch)) {
                        NULL;
-               } else if (pch == '.' && ppch != '\\') {
-                       if (!firstchar(ch) && !wildlabel(firstlabel, ch, nch))
+               } else if (periodchar(pch)) {
+                       if (!borderchar(ch))
+                               return (0);
+               } else if (periodchar(nch) || nch == '\0') {
+                       if (!borderchar(ch))
                                return (0);
                } else {
-                       if (!otherchar(ch))
+                       if (!middlechar(ch))
                                return (0);
                }
                ppch = pch, pch = ch, ch = nch;
-               firstlabel = 0;
        }
        return (1);
 }
 
+/*
+ * hostname-like (A, MX, WKS) owners can have "*" as their first label
+ * but must otherwise be as a host name.
+ */
+int
+res_ownok(dn)
+       const char *dn;
+{
+       if (asterchar(dn[0]) && periodchar(dn[1]))
+               dn += 2;
+       return (res_hnok(dn));
+}
+
+/*
+ * SOA RNAMEs and RP RNAMEs can have any printable character in their first
+ * label, but the rest of the name has to look like a host name.
+ */
+int
+res_mailok(dn)
+       const char *dn;
+{
+       int ch, pch;
+
+       pch = '\0';
+       while ((ch = *dn++) != '\0') {
+               if (!domainchar(ch))
+                       return (0);
+               if (periodchar(ch) && !bslashchar(pch))
+                       break;
+               pch = ch;
+       }
+       return (res_hnok(dn));
+}
+
 /*
  * This function is quite liberal, since RFC 1034's character sets are only
  * recommendations.
- *
- * Note that some char's are signed, so we have to cast to unsigned.
  */
 int
-dn_isvalid(dn)
+res_dnok(dn)
        const char *dn;
 {
-       unsigned char *t = (unsigned char *)dn;
        int ch;
 
-       while ((ch = *t++) != '\0')
-               if (ch <= 0x1f || ch >= 0x7f) {
-                       /* Unprintable in ASCII. */
+       while ((ch = *dn++) != '\0')
+               if (!domainchar(ch))
                        return (0);
-               }
        return (1);
 }
 
@@ -498,7 +543,7 @@ putlong(l, msgp)
 {
        __putlong(l, msgp);
 }
+
 #undef dn_skipname
 dn_skipname(comp_dn, eom)
        const u_char *comp_dn, *eom;
index 85ec628b8970611f35d9da83cd507ba195326cfd..4f5580449725d819e828ea0d9d433afaee3a887e 100644 (file)
@@ -3,7 +3,7 @@
  * -
  * Copyright (c) 1985, 1990, 1993
  *    The Regents of the University of California.  All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -19,7 +19,7 @@
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * SUCH DAMAGE.
  * -
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
+ *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -59,6 +59,8 @@ static char rcsid[] = "$Id$";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
@@ -66,7 +68,7 @@ static char rcsid[] = "$Id$";
 #include <stdio.h>
 #include <netdb.h>
 #include <resolv.h>
-#if defined(BSD) && (BSD >= 199103)
+#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
 # include <string.h>
 #else
 # include "../conf/portability.h"
@@ -295,7 +297,7 @@ __fp_nquery(msg, len, file)
                fprintf(file, ", Auth: %d", ntohs(hp->nscount));
                fprintf(file, ", Addit: %d", ntohs(hp->arcount));
        }
-       if ((!_res.pfcode) || (_res.pfcode & 
+       if ((!_res.pfcode) || (_res.pfcode &
                (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
                putc('\n',file);
        }
@@ -590,6 +592,13 @@ __p_rr(cp, msg, file)
                cp += dlen;
                break;
 
+       case T_AAAA: {
+               char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+
+               fprintf(file, "\t%s\n", inet_ntop(AF_INET6, cp, t, sizeof t));
+               break;
+       }
+
        case T_MINFO:
        case T_RP:
                putc('\t', file);
diff --git a/resolv/res_hconf.c b/resolv/res_hconf.c
new file mode 100644 (file)
index 0000000..b08dd3c
--- /dev/null
@@ -0,0 +1,566 @@
+/* Copyright (C) 1993, 1995, 1996 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., 675 Mass Ave,
+Cambridge, MA 02139, 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}
+};
+
+
+/*
+ * Why isn't this in stdlib?
+ */
+char *
+strndup (const char * s, size_t n)
+{
+  char * retval;
+
+  retval = malloc (n + 1);
+  if (!retval)
+    return retval;
+
+  memcpy (retval, s, n);
+  retval[n] = '\0';            /* ensure return value is terminated */
+  return retval;
+}
+
+
+/* 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
diff --git a/resolv/res_hconf.h b/resolv/res_hconf.h
new file mode 100644 (file)
index 0000000..2165e40
--- /dev/null
@@ -0,0 +1,50 @@
+/* Copyright (C) 1993, 1995, 1996 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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef _RES_HCONF_H_
+#define _RES_HCONF_H_
+
+#include <netdb.h>
+
+#define TRIMDOMAINS_MAX        4
+
+enum Name_Service {
+  SERVICE_NONE = 0,
+  SERVICE_BIND, SERVICE_HOSTS, SERVICE_NIS,
+  SERVICE_MAX
+};
+
+struct hconf {
+  int                  num_services;
+  enum Name_Service    service[SERVICE_MAX];
+  int                  num_trimdomains;
+  const char *         trimdomain[TRIMDOMAINS_MAX];
+  unsigned             flags;
+#  define HCONF_FLAG_INITED    (1 << 0) /* initialized? */
+#  define HCONF_FLAG_SPOOF     (1 << 1) /* refuse spoofed addresses */
+#  define HCONF_FLAG_SPOOFALERT        (1 << 2) /* syslog warning of spoofed */
+#  define HCONF_FLAG_REORDER   (1 << 3) /* list best address first */
+#  define HCONF_FLAG_MULTI     (1 << 4) /* see comments for gethtbyname() */
+} _res_hconf;
+
+extern void    _res_hconf_init (void);
+extern void    _res_hconf_trim_domain (char * domain);
+extern void    _res_hconf_trim_domains (struct hostent * hp);
+extern void    _res_hconf_reorder_addrs (struct hostent * hp);
+
+#endif /* _RES_HCONF_H_ */
index 42c7c2ef8cd1a5e33b43813877b541e85a06c648..4e8af680c1c6096935441fabccb70b32357c063b 100644 (file)
@@ -3,7 +3,7 @@
  * -
  * Copyright (c) 1985, 1989, 1993
  *    The Regents of the University of California.  All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -19,7 +19,7 @@
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * SUCH DAMAGE.
  * -
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
+ *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -76,6 +76,8 @@ static char rcsid[] = "$Id$";
 # include "../conf/portability.h"
 #endif
 
+#include "res_hconf.h"
+
 /*-------------------------------------- info about "sortlist" --------------
  * Marc Majka          1994/04/16
  * Allan Nathanson     1994/10/29 (BIND 4.9.3.x)
@@ -137,7 +139,7 @@ struct __res_state _res;
  * since it was noted that INADDR_ANY actually meant ``the first interface
  * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
  * it had to be "up" in order for you to reach your own name server.  It
- * was later decided that since the recommended practice is to always 
+ * was later decided that since the recommended practice is to always
  * install local static routes through 127.0.0.1 for all your network
  * interfaces, that we could solve this problem without a code change.
  *
@@ -354,11 +356,11 @@ res_init()
                                if (inet_aton(net, &a)) {
                                    _res.sort_list[nsort].mask = a.s_addr;
                                } else {
-                                   _res.sort_list[nsort].mask = 
+                                   _res.sort_list[nsort].mask =
                                        net_mask(_res.sort_list[nsort].addr);
                                }
                            } else {
-                               _res.sort_list[nsort].mask = 
+                               _res.sort_list[nsort].mask =
                                    net_mask(_res.sort_list[nsort].addr);
                            }
                            nsort++;
@@ -373,7 +375,7 @@ res_init()
                    continue;
                }
            }
-           if (nserv > 1) 
+           if (nserv > 1)
                _res.nscount = nserv;
 #ifdef RESOLVSORT
            _res.nsort = nsort;
@@ -419,6 +421,8 @@ res_init()
        if ((cp = getenv("RES_OPTIONS")) != NULL)
                res_setoptions(cp, "env");
        _res.options |= RES_INIT;
+
+       _res_hconf_init ();
        return (0);
 }
 
@@ -458,6 +462,8 @@ res_setoptions(options, source)
                        }
                        printf(";;\tdebug\n");
 #endif
+               } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
+                       _res.options |= RES_USE_INET6;
                } else {
                        /* XXX - print a warning here? */
                }
@@ -562,7 +568,7 @@ netinfo_res_init(haveenv, havesearch)
                    }
                    ni_namelist_free(&nl);
                }
-               
+
                if (nserv > 1)
                    _res.nscount = nserv;
 
index 1a4a0dec892ccab23b3fa84d6cc194615187e150..0f5d5b855b7782268deb165830d2c6d511ce4dff 100644 (file)
@@ -3,7 +3,7 @@
  * -
  * Copyright (c) 1983, 1987, 1989, 1993
  *    The Regents of the University of California.  All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -19,7 +19,7 @@
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * SUCH DAMAGE.
  * -
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
+ *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -140,6 +140,7 @@ struct __res_state {
 #define        RES_INSECURE1   0x00000400      /* type 1 security disabled */
 #define        RES_INSECURE2   0x00000800      /* type 2 security disabled */
 #define        RES_NOALIASES   0x00001000      /* shuts off HOSTALIASES feature */
+#define        RES_USE_INET6   0x00002000      /* use/map IPv6 in gethostbyname() */
 
 #define RES_DEFAULT    (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
 
@@ -185,7 +186,9 @@ extern struct __res_state _res;
 
 /* Private routines shared between libc/net, named, nslookup and others. */
 #define        res_hnok        __res_hnok
-#define        dn_isvalid      __dn_isvalid
+#define        res_ownok       __res_ownok
+#define        res_mailok      __res_mailok
+#define        res_dnok        __res_dnok
 #define        dn_skipname     __dn_skipname
 #define        fp_query        __fp_query
 #define        fp_nquery       __fp_nquery
@@ -206,7 +209,9 @@ extern struct __res_state _res;
 #define        res_queriesmatch __res_queriesmatch
 __BEGIN_DECLS
 int     __res_hnok __P((const char *));
-int     __dn_isvalid __P((const char *));
+int     __res_ownok __P((const char *));
+int     __res_mailok __P((const char *));
+int     __res_dnok __P((const char *));
 int     __dn_skipname __P((const u_char *, const u_char *));
 void    __fp_resstat __P((struct __res_state *, FILE *));
 void    __fp_query __P((const u_char *, FILE *));
index 2970dd3db02476e90e9d76e79e71a6f9679281b9..00e34c520e91fde3a4ed1dc97c7cf8a741ddce77 100644 (file)
@@ -46,4 +46,5 @@ tests := tst-printf tstscanf test_rdwr test-popen tstgetln test-fseek \
 
 include ../Rules
 
+CFLAGS-_itoa.c = -Wno-unused
 CFLAGS-tst-printf.c = -Wno-format
index f103979333f6a32daab109662d8b8d3460ead5c6..7e78547c90a9a1dcb972eb0a01b3d40cb34e97ba 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -16,21 +16,20 @@ License along with the GNU C Library; see the file COPYING.LIB.  If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <ansidecl.h>
 #include <stddef.h>
 #include <stdio.h>
 
 #undef __getline
 
 #ifdef USE_IN_LIBIO
+# include "../libio/libioP.h"
 # define ssize_t _IO_ssize_t
 # define __getdelim _IO_getdelim
 #endif
 
 /* Like getdelim, but always looks for a newline.  */
 ssize_t
-DEFUN(__getline, (lineptr, n, stream),
-      char **lineptr AND size_t *n AND FILE *stream)
+__getline (char **lineptr, size_t *n, FILE *stream)
 {
   return __getdelim (lineptr, n, '\n', stream);
 }
index d133ef1a02b14bb59d3e013ee40d353cae8ce10e..badaa2f93d31a28dfef7cfe95ca892b5d96f9443 100644 (file)
@@ -16,7 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB.  If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <ansidecl.h>
 #include "../locale/localeinfo.h"
 #include <errno.h>
 #include <limits.h>
index ddcc385ab9704934693e00732586484ed93d6066..d30a0f2a0652fd4315ab668eb693b70f2e7de092 100644 (file)
@@ -40,7 +40,7 @@ routines      :=                                                            \
        drand48-iter                                                          \
        strtol strtoul strtoq strtouq                                         \
        strtof strtod strtold                                                 \
-       system realpath                                                       \
+       system canonicalize                                                   \
        a64l l64a                                                             \
        rpmatch strfmon
 
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
new file mode 100644 (file)
index 0000000..55ac1bc
--- /dev/null
@@ -0,0 +1,196 @@
+/* Return the canonical absolute name of a given file.
+Copyright (C) 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+/* Return the canonical absolute name of file NAME.  The last file name
+   component need not exist, and may be a symlink to a nonexistent file.
+   If RESOLVED is null, the result is malloc'd; otherwise, if the canonical
+   name is PATH_MAX chars or more, returns null with `errno' set to
+   ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, returns the
+   name in RESOLVED.  */
+
+static char *
+canonicalize (const char *name, char *resolved)
+{
+  struct stat st;
+  const char *p;
+  long int path_max;
+  char *result, *dir, *end;
+  size_t namelen;
+
+  if (! resolved)
+    path_max = 0;
+  else
+    {
+#ifdef PATH_MAX
+      path_max = PATH_MAX;
+#else
+      path_max = sysconf (_SC_PATH_MAX);
+      if (path_max <= 0)
+       path_max = 1024;
+#endif
+    }
+
+  p = strrchr (name, '/');
+  if (!p)
+    {
+      dir = (char *) ".";
+      p = name;
+    }
+  else
+    {
+      if (p++ == name)
+       dir = (char *) "/";
+      else
+       {
+         dir = __alloca (p - name);
+         memcpy (dir, name, p - name - 1);
+         dir[p - name] = '\0';
+       }
+    }
+
+  result = __canonicalize_directory_name_internal (dir, resolved, path_max);
+  if (!result)
+    return NULL;
+
+  /* Reconstruct the file name in the canonicalized directory.  */
+  namelen = strlen (name);
+  end = strchr (result, '\0');
+  if (resolved)
+    {
+      /* Make sure the name is not too long.  */
+      if (end - result + namelen > path_max)
+       {
+         errno = ENAMETOOLONG;
+         return NULL;
+       }
+    }
+  else
+    {
+      /* The name is dynamically allocated.  Extend it.  */
+      char *new = realloc (result, end - result + namelen + 1);
+      if (! new)
+       {
+         free (result);
+         return NULL;
+       }
+      end = new + (end - result);
+      result = new;
+    }
+  memcpy (end, name, namelen + 1);
+
+  while (__lstat (result, &st) == 0 && S_ISLNK (st.st_mode))
+    {
+      /* The file is a symlink.  Read its contents.  */
+      ssize_t n;
+    read_link_contents:
+      n = readlink (result, end,
+                   resolved ? result + path_max - end : namelen + 1);
+      if (n < 0)
+       /* Error reading the link contents.  */
+       return NULL;
+
+      if (end[0] == '/')
+       {
+         /* Absolute symlink.  */
+         if (resolved ? (end + n < result + path_max) : (n < namelen + 1))
+           {
+             /* It fit in our buffer, so we have the whole thing.  */
+             memcpy (result, end, n);
+             result[n] = '\0';
+           }
+         else if (resolved)
+           {
+             /* It didn't fit in the remainder of the buffer.  Either it
+                fits in the entire buffer, or it doesn't.  Copy back the
+                unresolved name onto the canonical directory and try once
+                more.  */
+             memcpy (end, name, namelen + 1);
+             n = readlink (result, result, path_max);
+             if (n < 0)
+               return NULL;
+             if (n == path_max)
+               {
+                 errno = ENAMETOOLONG;
+                 return NULL;
+               }
+             result[n] = '\0';
+           }
+         else
+           /* Try again with a bigger buffer.  */
+           goto extend_buffer;
+
+         /* Check the resolved name for being a symlink too.  */
+         continue;
+       }
+
+      if (resolved)
+       {
+         if (end + n == result + path_max)
+           {
+             /* The link contents we read fill the buffer completely.
+                There may be even more to read, and there is certainly no
+                space for the null terminator.  */
+             errno = ENAMETOOLONG;
+             return NULL;
+           }
+       }
+      else if (n == namelen + 1)
+      extend_buffer:
+       {
+         /* The name buffer is dynamically allocated.  Extend it.  */
+         char *new;
+
+         /* Copy back the unresolved name onto the canonical directory.  */
+         memcpy (end, name, namelen + 1);
+
+         /* Make more space for readlink.  */
+         namelen *= 2;
+         new = realloc (result, end - result + namelen + 1);
+         if (! new)
+           {
+             free (result);
+             return NULL;
+           }
+         end = new + (end - result);
+         result = new;
+
+         goto read_link_contents;
+       }
+
+      /* Terminate the string; readlink does not.  */
+      end[n] = '\0';
+    }
+
+  return result;
+}
+
+weak_alias (canonicalize, realpath)
+
+char *
+canonicalize_file_name (const char *name)
+{
+  return canonicalize (name, NULL);
+}
index 2fde1c806f71593df47031b9f4bc68c93ff0cfb7..1853c5babb9ab07d2dd49ed61a89215f143c8489 100644 (file)
@@ -364,6 +364,24 @@ extern void unsetenv __P ((__const char *__name));
 extern int system __P ((__const char *__command));
 
 
+#ifdef __USE_GNU
+/* Return a malloc'd string containing the canonical absolute name of the
+   named file.  The last file name component need not exist, and may be a
+   symlink to a nonexistent file.  */
+extern char *canonicalize_file_name __P ((__const char *__name));
+#endif
+
+#ifdef __USE_BSD
+/* Return the canonical absolute name of file NAME.  The last file name
+   component need not exist, and may be a symlink to a nonexistent file.
+   If RESOLVED is null, the result is malloc'd; otherwise, if the canonical
+   name is PATH_MAX chars or more, returns null with `errno' set to
+   ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, returns the
+   name in RESOLVED.  */
+extern char *realpath __P ((__const char *__name, char *__resolved));
+#endif
+
+
 /* Shorthand for type of comparison functions.  */
 #ifndef __COMPAR_FN_T
 #define __COMPAR_FN_T
index ed8ed966972103928199b7dfc93d2f05eaf4d324..463b28ce2908786d15754dfd3da5fa1b3c16f143 100644 (file)
@@ -29,14 +29,16 @@ Cambridge, MA 02139, USA.  */
 #include <fcntl.h>
 
 
-/* Get the pathname of the current working directory, and put it in SIZE
-   bytes of BUF.  Returns NULL if the directory couldn't be determined or
-   SIZE was too small.  If successful, returns BUF.  In GNU, if BUF is
-   NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
-   unless SIZE <= 0, in which case it is as big as necessary.  */
+/* Get the canonical absolute name of the given directory port, and put it
+   in SIZE bytes of BUF.  Returns NULL if the directory couldn't be
+   determined or SIZE was too small.  If successful, returns BUF.  In GNU,
+   if BUF is NULL, an array is allocated with `malloc'; the array is SIZE
+   bytes long, unless SIZE <= 0, in which case it is as big as necessary.  */
 
 char *
-__getcwd (char *buf, size_t size)
+_hurd_canonicalize_directory_name_internal (file_t thisdir,
+                                           char *buf,
+                                           size_t size)
 {
   error_t err;
   mach_port_t rootid, thisid, rootdevid, thisdevid;
@@ -91,10 +93,9 @@ __getcwd (char *buf, size_t size)
     return __hurd_fail (err), NULL;
   __mach_port_deallocate (__mach_task_self (), rootdevid);
 
-  /* Get a port to our current working directory and stat it.  */
+  /* Stat the port to the directory of interest.  */
 
-  if (err = __USEPORT (CRDIR, __io_identity (port,
-                                            &thisid, &thisdevid, &thisino)))
+  if (err = __io_identity (thisdir, &thisid, &thisdevid, &thisino))
     {
       __mach_port_deallocate (__mach_task_self (), rootid);
       return __hurd_fail (err), NULL;
@@ -255,4 +256,32 @@ __getcwd (char *buf, size_t size)
   cleanup ();
   return NULL;
 }
+
+char *
+__canonicalize_directory_name_internal (thisdir, buf, size)
+     const char *thisdir;
+     char *buf;
+     size_t size;
+{
+  char *result;
+  file_t port = __file_name_lookup (thisdir, 0, 0);
+  if (port == MACH_PORT_NULL)
+    return NULL;
+  result = _hurd_canonicalize_directory_name_internal (port, buf, size);
+  __mach_port_deallocate (__mach_task_self (), port);
+  return result;
+}
+\f
+/* Get the pathname of the current working directory, and put it in SIZE
+   bytes of BUF.  Returns NULL if the directory couldn't be determined or
+   SIZE was too small.  If successful, returns BUF.  In GNU, if BUF is
+   NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
+   unless SIZE <= 0, in which case it is as big as necessary.  */
+char *
+__getcwd (char *buf, size_t size)
+{
+  return __USEPORT (CWDIR,
+                   _hurd_canonicalize_directory_name_internal (port,
+                                                               buf, size));
+}
 weak_alias (__getcwd, getcwd)
index af858a26439f121199ce80704a17f0b2e799628b..05f626f869dee6b61729e296c1b6c6b69f94dd17 100644 (file)
@@ -180,18 +180,15 @@ extern char *alloca ();
 #define        __lstat stat
 #endif
 \f
-#ifndef _LIBC
-#define __getcwd getcwd
-#endif
-
-/* Get the pathname of the current working directory, and put it in SIZE
+/* Get the canonical absolute name of the named directory, and put it in SIZE
    bytes of BUF.  Returns NULL if the directory couldn't be determined or
    SIZE was too small.  If successful, returns BUF.  In GNU, if BUF is
    NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
    unless SIZE <= 0, in which case it is as big as necessary.  */
 
 char *
-__getcwd (buf, size)
+__canonicalize_directory_name_internal (thisdir, buf, size)
+     const char *thisdir;
      char *buf;
      size_t size;
 {
@@ -230,7 +227,7 @@ __getcwd (buf, size)
   pathp = path + size;
   *--pathp = '\0';
 
-  if (__lstat (".", &st) < 0)
+  if (__lstat (thisdir, &st) < 0)
     return NULL;
   thisdev = st.st_dev;
   thisino = st.st_ino;
@@ -369,6 +366,24 @@ __getcwd (buf, size)
     free ((__ptr_t) dotlist);
   return NULL;
 }
+\f
+/* Get the pathname of the current working directory, and put it in SIZE
+   bytes of BUF.  Returns NULL if the directory couldn't be determined or
+   SIZE was too small.  If successful, returns BUF.  In GNU, if BUF is
+   NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
+   unless SIZE <= 0, in which case it is as big as necessary.  */
+
+#ifndef _LIBC
+#define __getcwd getcwd
+#endif
+
+char *
+__getcwd (buf, size)
+     char *buf;
+     size_t size;
+{
+  return __canonicalize_directory_name_internal (".", buf, size);
+}
 
 #ifdef _LIBC
 weak_alias (__getcwd, getcwd)
index c70a6e8d3588a182d5139fc4590fe39c4568bdae..fdddae2d0c4015530f0ac83176ae0227dabd9981 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -16,7 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB.  If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <ansidecl.h>
 #include <errno.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -34,7 +33,7 @@ Cambridge, MA 02139, USA.  */
 
 /* Return nonzero if DIR is an existent directory.  */
 static int
-DEFUN(diraccess, (dir), CONST char *dir)
+diraccess (const char *dir)
 {
   struct stat buf;
   return __stat (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
@@ -42,7 +41,7 @@ DEFUN(diraccess, (dir), CONST char *dir)
 
 /* Return nonzero if FILE exists.  */
 static int
-DEFUN(exists, (file), CONST char *file)
+exists (const char *file)
 {
   /* We can stat the file even if we can't read its data.  */
   struct stat st;
@@ -64,7 +63,7 @@ DEFUN(exists, (file), CONST char *file)
 
 
 /* These are the characters used in temporary filenames.  */
-static CONST char letters[] =
+static const char letters[] =
   "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 
 /* Generate a temporary filename and return it (in a static buffer).  If
@@ -82,13 +81,11 @@ static CONST char letters[] =
    existing file will be returned.  When the cycle reaches its end
    (12345ZZZ), NULL is returned.  */
 char *
-DEFUN(__stdio_gen_tempname, (dir, pfx, dir_search, lenptr, streamptr),
-      CONST char *dir AND CONST char *pfx AND
-      int dir_search AND size_t *lenptr AND
-      FILE **streamptr)
+__stdio_gen_tempname (const char *dir, const char *pfx, int dir_search,
+                     size_t *lenptr, FILE **streamptr)
 {
   int saverrno = errno;
-  static CONST char tmpdir[] = P_tmpdir;
+  static const char tmpdir[] = P_tmpdir;
   static size_t indices[2];
   size_t *idx;
   static char buf[FILENAME_MAX];
@@ -98,7 +95,7 @@ DEFUN(__stdio_gen_tempname, (dir, pfx, dir_search, lenptr, streamptr),
 
   if (dir_search)
     {
-      register CONST char *d = getenv ("TMPDIR");
+      register const char *d = getenv ("TMPDIR");
       if (d != NULL && !diraccess (d))
        d = NULL;
       if (d == NULL && dir != NULL && diraccess (dir))
index d25e0525caab47a2a2716f5fa329c0a2e3b37648..8c9fcfe934a59371e2497e3f288cfe77eea8d82d 100644 (file)
@@ -16,8 +16,29 @@ endif
 
 ifeq ($(subdir), misc)
 sysdep_routines += mount umount xmknod s_ptrace s_sysctl sysctl llseek \
-setfsgid setfsuid sysinfo uselib
+setfsgid setfsuid sysinfo uselib s_reboot
 headers += sys/mount.h sys/sysinfo.h sys/acct.h sys/sysctl.h
+
+install-others += $(includedir)/sys/syscall.h
+
+$(includedir)/sys/syscall.h::
+       @rm -f $(objpfx)syscall.h $(objpfx)syscall.sed
+       @(os=`uname -sr`; \
+         echo -e '1i\\\n#ifndef _SYS_SYSCALL_H\\'; \
+         echo -e '#define _SYS_SYSCALL_H\t1\\\n\\'; \
+         echo -e -n '/* This file is automatically generated as part of '; \
+         echo -e 'GNU libc-$(version)\\'; \
+         echo -e "   on a system running $$os.  */\\"; echo; \
+         echo -e -n 's/#define __NR_\\([A-Za-z0-9_]*\\)[ \t]*__NR_\\(.*\\)/';\
+         echo -e '#define SYS_\\1 SYS_\\2/p'; \
+         echo -e -n 's/#define __NR_\\([A-Za-z0-9_]*\\)[ \t]*\\(.*\\)/';\
+         echo -e '#define SYS_\\1 \\2/p'; \
+         echo -e '$$i\\\n\\\n#endif\t/* sys/syscall.h */\nd') \
+           >  $(objpfx)syscall.sed
+       set -- `echo '#include <asm/unistd.h>'|$(CC) -M -E -`; \
+       sed -f $(objpfx)syscall.sed $$2 > $(objpfx)syscall.h
+       $(INSTALL_DATA) $(objpfx)syscall.h $@
+       rm -f $(objpfx)syscall.h $(objpfx)syscall.sed
 endif
 
 ifeq ($(subdir), time)
diff --git a/sysdeps/unix/sysv/linux/reboot.c b/sysdeps/unix/sysv/linux/reboot.c
new file mode 100644 (file)
index 0000000..ecda522
--- /dev/null
@@ -0,0 +1,28 @@
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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.  */
+
+#include <unistd.h>
+
+extern int __syscall_reboot (int magic, int magic_too, int flag);
+
+/* Call kernel with additional two arguments the syscall requires.  */
+int
+reboot (int howto)
+{
+  return __syscall_reboot (0xfee1dead, 672274793, howto);
+}
diff --git a/sysdeps/unix/sysv/linux/sys/reboot.h b/sysdeps/unix/sysv/linux/sys/reboot.h
new file mode 100644 (file)
index 0000000..a7b86fa
--- /dev/null
@@ -0,0 +1,43 @@
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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 should define RB_* macros to be used as flag
+   bits in the argument to the `reboot' system call.  */
+
+#ifndef _SYS_REBOOT_H
+
+#define _SYS_REBOOT_H  1
+#include <features.h>
+
+/* Perform a hard reset now.  */
+#define RB_AUTOBOOT    0x01234567
+
+/* Halt the system.  */
+#define RB_HALT_SYSTEM 0xcdef0123
+
+/* Enable reboot using Ctrl-Alt-Delete keystroke.  */
+#define RB_ENABLE_CAD  0x89abcdef
+
+/* Disable reboot using Ctrl-Alt-Delete keystroke.  */
+#define RB_DISABLE_CAD 0
+
+
+/* Reboot or halt the system.  */
+extern int reboot __P ((int __howto));
+
+#endif /* sys/reboot.h */
index efe285c1fe8ab55face3b6df77b266eb261797c8..62fca57d70da3645444c9ea61cfb0174e4113397 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -24,12 +24,4 @@ Cambridge, MA 02139, USA.  */
    from the kernel sources.  */
 #include <asm/unistd.h>
 
-/* Among the system calls defined there are
-       _setdomainname  
-       _fchdir 
-       _readv  
-       _writev 
-   (This is a hack for the autoconf mechanism.  Don't change a single
-    character, esp white spaces, unless you know what you are doing!)  */
-
 #endif
index 019d746a7319cdbc6fc97f5c8041baa862d64c67..f401bc8c602f7d95071e4df505075e100c7debcf 100644 (file)
@@ -23,7 +23,7 @@ munlockall    -       munlockall      0       __munlockall    munlockall
 nanosleep      -       nanosleep       2       nanosleep
 personality    init-first personality  1       __personality   personality
 pipe           -       pipe            1       __pipe          pipe
-reboot         -       reboot          3       reboot
+s_reboot       -       reboot          3       __syscall_reboot
 s_getpriority  getpriority getpriority 2       __syscall_getpriority
 s_ptrace       ptrace  ptrace          4       __syscall_ptrace
 s_sigsuspend   sigsuspend sigsuspend   3       __syscall_sigsuspend
index 2292bd84b6ff3ca3f36e775877b7100909e54b12..3b15d9f38ad85cd9ce4ed03eab61ae8b129d1705 100644 (file)
@@ -192,7 +192,7 @@ extern int wcswidth __P ((__const wchar_t *__s, size_t __n));
    representation.  */
 extern double wcstod __P ((__const wchar_t *__nptr, wchar_t **__endptr));
 
-#ifdef USE_GNU
+#ifdef __USE_GNU
 /* Likewise for `float' and `long double' sizes of floating-point numbers.  */
 extern float wcstof __P ((__const wchar_t *__nptr, wchar_t **__endptr));
 extern __long_double_t wcstold __P ((__const wchar_t *__nptr,