OSDN Git Service

Initial revision
authorErik Andersen <andersen@codepoet.org>
Sun, 14 May 2000 04:16:35 +0000 (04:16 -0000)
committerErik Andersen <andersen@codepoet.org>
Sun, 14 May 2000 04:16:35 +0000 (04:16 -0000)
202 files changed:
COPYING.LIB [new file with mode: 0644]
Makefile [new file with mode: 0644]
include/a.out.h [new file with mode: 0644]
include/ar.h [new file with mode: 0644]
include/arpa/inet.h [new file with mode: 0644]
include/arpa/nameser.h [new file with mode: 0644]
include/arpa/telnet.h [new file with mode: 0644]
include/arpa/tftp.h [new file with mode: 0644]
include/assert.h [new file with mode: 0644]
include/cfgfile.h [new file with mode: 0644]
include/ctype.h [new file with mode: 0644]
include/dirent.h [new file with mode: 0644]
include/endian.h [new file with mode: 0644]
include/err.h [new file with mode: 0644]
include/errno.h [new file with mode: 0644]
include/fcntl.h [new file with mode: 0644]
include/features.h [new file with mode: 0644]
include/getopt.h [new file with mode: 0644]
include/grp.h [new file with mode: 0644]
include/limits.h [new file with mode: 0644]
include/malloc.h [new file with mode: 0644]
include/math.h [new file with mode: 0644]
include/memory.h [new file with mode: 0644]
include/mntent.h [new file with mode: 0644]
include/netdb.h [new file with mode: 0644]
include/netinet/igmp.h [new file with mode: 0644]
include/netinet/in.h [new file with mode: 0644]
include/netinet/in_systm.h [new file with mode: 0644]
include/netinet/ip.h [new file with mode: 0644]
include/netinet/ip_fw.h [new file with mode: 0644]
include/netinet/ip_icmp.h [new file with mode: 0644]
include/netinet/ip_tcp.h [new file with mode: 0644]
include/netinet/ip_udp.h [new file with mode: 0644]
include/netinet/protocols.h [new file with mode: 0644]
include/netinet/tcp.h [new file with mode: 0644]
include/netinet/udp.h [new file with mode: 0644]
include/paths.h [new file with mode: 0644]
include/pwd.h [new file with mode: 0644]
include/regexp.h [new file with mode: 0644]
include/resolv.h [new file with mode: 0644]
include/rpc/auth.h [new file with mode: 0644]
include/rpc/auth_des.h [new file with mode: 0644]
include/rpc/auth_unix.h [new file with mode: 0644]
include/rpc/clnt.h [new file with mode: 0644]
include/rpc/pmap_clnt.h [new file with mode: 0644]
include/rpc/pmap_prot.h [new file with mode: 0644]
include/rpc/pmap_rmt.h [new file with mode: 0644]
include/rpc/rpc.h [new file with mode: 0644]
include/rpc/rpc_msg.h [new file with mode: 0644]
include/rpc/svc.h [new file with mode: 0644]
include/rpc/svc_auth.h [new file with mode: 0644]
include/rpc/types.h [new file with mode: 0644]
include/rpc/xdr.h [new file with mode: 0644]
include/search.h [new file with mode: 0644]
include/setjmp.h [new file with mode: 0644]
include/signal.h [new file with mode: 0644]
include/stdarg.h [new file with mode: 0644]
include/stdio.h [new file with mode: 0644]
include/stdlib.h [new file with mode: 0644]
include/string.h [new file with mode: 0644]
include/strings.h [new file with mode: 0644]
include/sys/bitypes.h [new file with mode: 0644]
include/sys/cdefs.h [new file with mode: 0644]
include/sys/dir.h [new file with mode: 0644]
include/sys/errno.h [new file with mode: 0644]
include/sys/fcntl.h [new file with mode: 0644]
include/sys/file.h [new file with mode: 0644]
include/sys/ioctl.h [new file with mode: 0644]
include/sys/mman.h [new file with mode: 0644]
include/sys/mount.h [new file with mode: 0644]
include/sys/param.h [new file with mode: 0644]
include/sys/resource.h [new file with mode: 0644]
include/sys/signal.h [new file with mode: 0644]
include/sys/socket.h [new file with mode: 0644]
include/sys/socketcall.h [new file with mode: 0644]
include/sys/socketio.h [new file with mode: 0644]
include/sys/socketvar.h [new file with mode: 0644]
include/sys/stat.h [new file with mode: 0644]
include/sys/syscall.h [new file with mode: 0644]
include/sys/syslog.h [new file with mode: 0644]
include/sys/termios.h [new file with mode: 0644]
include/sys/time.h [new file with mode: 0644]
include/sys/times.h [new file with mode: 0644]
include/sys/types.h [new file with mode: 0644]
include/sys/uio.h [new file with mode: 0644]
include/sys/un.h [new file with mode: 0644]
include/sys/utsname.h [new file with mode: 0644]
include/sys/vfs.h [new file with mode: 0644]
include/sys/vm86.h [new file with mode: 0644]
include/sys/wait.h [new file with mode: 0644]
include/syscall.h [new file with mode: 0644]
include/syslog.h [new file with mode: 0644]
include/termcap.h [new file with mode: 0644]
include/termio.h [new file with mode: 0644]
include/termios.h [new file with mode: 0644]
include/time.h [new file with mode: 0644]
include/unistd.h [new file with mode: 0644]
include/utime.h [new file with mode: 0644]
include/utmp.h [new file with mode: 0644]
include/wait.h [new file with mode: 0644]
libc/inet/Makefile [new file with mode: 0644]
libc/inet/addr.c [new file with mode: 0644]
libc/inet/resolv.c [new file with mode: 0644]
libc/inet/rpc/Makefile [new file with mode: 0644]
libc/inet/rpc/auth_none.c [new file with mode: 0644]
libc/inet/rpc/auth_unix.c [new file with mode: 0644]
libc/inet/rpc/authunix_prot.c [new file with mode: 0644]
libc/inet/rpc/bindresvport.c [new file with mode: 0644]
libc/inet/rpc/clnt_generic.c [new file with mode: 0644]
libc/inet/rpc/clnt_perror.c [new file with mode: 0644]
libc/inet/rpc/clnt_raw.c [new file with mode: 0644]
libc/inet/rpc/clnt_simple.c [new file with mode: 0644]
libc/inet/rpc/clnt_tcp.c [new file with mode: 0644]
libc/inet/rpc/clnt_udp.c [new file with mode: 0644]
libc/inet/rpc/get_myaddress.c [new file with mode: 0644]
libc/inet/rpc/getrpcent.c [new file with mode: 0644]
libc/inet/rpc/getrpcport.c [new file with mode: 0644]
libc/inet/rpc/pmap_clnt.c [new file with mode: 0644]
libc/inet/rpc/pmap_getmaps.c [new file with mode: 0644]
libc/inet/rpc/pmap_getport.c [new file with mode: 0644]
libc/inet/rpc/pmap_prot.c [new file with mode: 0644]
libc/inet/rpc/pmap_prot2.c [new file with mode: 0644]
libc/inet/rpc/pmap_rmt.c [new file with mode: 0644]
libc/inet/rpc/rpc_callmsg.c [new file with mode: 0644]
libc/inet/rpc/rpc_commondata.c [new file with mode: 0644]
libc/inet/rpc/rpc_dtablesize.c [new file with mode: 0644]
libc/inet/rpc/rpc_prot.c [new file with mode: 0644]
libc/inet/rpc/svc.c [new file with mode: 0644]
libc/inet/rpc/svc_auth.c [new file with mode: 0644]
libc/inet/rpc/svc_auth_unix.c [new file with mode: 0644]
libc/inet/rpc/svc_raw.c [new file with mode: 0644]
libc/inet/rpc/svc_run.c [new file with mode: 0644]
libc/inet/rpc/svc_simple.c [new file with mode: 0644]
libc/inet/rpc/svc_tcp.c [new file with mode: 0644]
libc/inet/rpc/svc_udp.c [new file with mode: 0644]
libc/inet/rpc/xdr.c [new file with mode: 0644]
libc/inet/rpc/xdr_array.c [new file with mode: 0644]
libc/inet/rpc/xdr_float.c [new file with mode: 0644]
libc/inet/rpc/xdr_mem.c [new file with mode: 0644]
libc/inet/rpc/xdr_rec.c [new file with mode: 0644]
libc/inet/rpc/xdr_reference.c [new file with mode: 0644]
libc/inet/rpc/xdr_stdio.c [new file with mode: 0644]
libc/misc/time/Makefile [new file with mode: 0644]
libc/misc/time/README [new file with mode: 0644]
libc/misc/time/asc_conv.c [new file with mode: 0644]
libc/misc/time/asctime.c [new file with mode: 0644]
libc/misc/time/asctime_r.c [new file with mode: 0644]
libc/misc/time/ctime.c [new file with mode: 0644]
libc/misc/time/ctime_r.c [new file with mode: 0644]
libc/misc/time/gmtime.c [new file with mode: 0644]
libc/misc/time/gmtime_r.c [new file with mode: 0644]
libc/misc/time/localtime.c [new file with mode: 0644]
libc/misc/time/localtime_r.c [new file with mode: 0644]
libc/misc/time/mktime.c [new file with mode: 0644]
libc/misc/time/tm_conv.c [new file with mode: 0644]
libc/pwd_grp/Makefile [new file with mode: 0644]
libc/pwd_grp/__getgrent.c [new file with mode: 0644]
libc/pwd_grp/config.h [new file with mode: 0644]
libc/pwd_grp/fgetgrent.c [new file with mode: 0644]
libc/pwd_grp/fgetpwent.c [new file with mode: 0644]
libc/pwd_grp/getgrgid.c [new file with mode: 0644]
libc/pwd_grp/getgrnam.c [new file with mode: 0644]
libc/pwd_grp/getpw.c [new file with mode: 0644]
libc/pwd_grp/getpwnam.c [new file with mode: 0644]
libc/pwd_grp/getpwuid.c [new file with mode: 0644]
libc/pwd_grp/grent.c [new file with mode: 0644]
libc/pwd_grp/initgroups.c [new file with mode: 0644]
libc/pwd_grp/putpwent.c [new file with mode: 0644]
libc/pwd_grp/pwent.c [new file with mode: 0644]
libc/stdio/Makefile [new file with mode: 0644]
libc/stdio/printf.c [new file with mode: 0644]
libc/stdio/scanf.c [new file with mode: 0644]
libc/stdio/stdio.c [new file with mode: 0644]
libc/stdlib/Makefile [new file with mode: 0644]
libc/stdlib/atexit.c [new file with mode: 0644]
libc/stdlib/bsearch.c [new file with mode: 0644]
libc/stdlib/getenv.c [new file with mode: 0644]
libc/stdlib/malloc/Makefile [new file with mode: 0644]
libc/stdlib/malloc/alloc.c [new file with mode: 0644]
libc/stdlib/mkstemp.c [new file with mode: 0644]
libc/stdlib/mktemp.c [new file with mode: 0644]
libc/stdlib/putenv.c [new file with mode: 0644]
libc/stdlib/qsort.c [new file with mode: 0644]
libc/stdlib/rand.c [new file with mode: 0644]
libc/stdlib/setenv.c [new file with mode: 0644]
libc/stdlib/strtod.c [new file with mode: 0644]
libc/stdlib/system.c [new file with mode: 0644]
libc/string/Makefile [new file with mode: 0644]
libc/string/config.c [new file with mode: 0644]
libc/string/strcasecmp.c [new file with mode: 0644]
libc/string/strcspn.c [new file with mode: 0644]
libc/string/string.c [new file with mode: 0644]
libc/string/strncasecmp.c [new file with mode: 0644]
libc/string/strpbrk.c [new file with mode: 0644]
libc/string/strsep.c [new file with mode: 0644]
libc/string/strspn.c [new file with mode: 0644]
libc/string/strstr.c [new file with mode: 0644]
libc/string/strtok.c [new file with mode: 0644]
libc/sysdeps/linux/i386/bits/setjmp.h [new file with mode: 0644]
libc/termios/Makefile [new file with mode: 0644]
libc/termios/termios.c [new file with mode: 0644]
libc/termios/ttyname.c [new file with mode: 0644]

diff --git a/COPYING.LIB b/COPYING.LIB
new file mode 100644 (file)
index 0000000..eb685a5
--- /dev/null
@@ -0,0 +1,481 @@
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+                    675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+\f
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+\f
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+     Appendix: How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This 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.
+
+    This 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 this library; if not, write to the Free
+    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..bfde995
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,63 @@
+DIRS = headers error gtermcap misc stdio2 time getent regexp string termios sysdeps \
+malloc-simple net rpc
+
+all: libc.a crt0.o
+
+libc.a: $(DIRS) dummy
+       m68k-pic-coff-ranlib $@
+
+crt0.o: crt
+
+headers: dummy
+       if [ ! -L "include/asm" ]; then ln -s ../../linux/include/asm include/asm ; fi
+       if [ ! -L "include/net" ]; then ln -s ../../linux/include/net include/net ; fi
+       if [ ! -L "include/linux" ]; then ln -s ../../linux/include/linux include/linux ; fi
+
+error: dummy
+       make -C error
+
+gtermcap: dummy
+       make -C gtermcap
+
+misc: dummy
+       make -C misc
+
+stdio2: dummy
+       make -C stdio2
+
+time: dummy
+       make -C time
+
+getent: dummy
+       make -C getent
+
+regexp: dummy
+       make -C regexp
+
+string: dummy
+       make -C string
+
+termios: dummy
+       make -C termios
+
+sysdeps: dummy
+       make -C sysdeps
+
+malloc-simple: dummy
+       make -C malloc-simple
+
+net: dummy
+       make -C net
+
+rpc: dummy
+       make -C rpc
+
+crt: dummy
+       make -C crt
+
+dummy:
+
+clean:
+       -rm `find -name \*.[oa]` `find -name \*~` core
+       -rm include/asm include/net include/linux
+
diff --git a/include/a.out.h b/include/a.out.h
new file mode 100644 (file)
index 0000000..bd58346
--- /dev/null
@@ -0,0 +1,115 @@
+/* Copyright (C) 1990-1996 
+ * This file is part of the ld86 command for Linux-86 
+ * It is distributed under the GNU Library General Public License.
+ *
+ * - This may actually be BSD or Minix code, can someone clarify please. -RDB
+ */
+
+#ifndef __AOUT_H
+#define __AOUT_H
+
+struct exec {                  /* a.out header */
+  unsigned char        a_magic[2];     /* magic number */
+  unsigned char        a_flags;        /* flags, see below */
+  unsigned char        a_cpu;          /* cpu id */
+  unsigned char        a_hdrlen;       /* length of header */
+  unsigned char        a_unused;       /* reserved for future use */
+  unsigned short a_version;    /* version stamp (not used at present) */
+  long         a_text;         /* size of text segement in bytes */
+  long         a_data;         /* size of data segment in bytes */
+  long         a_bss;          /* size of bss segment in bytes */
+  long         a_entry;        /* entry point */
+  long         a_total;        /* total memory allocated */
+  long         a_syms;         /* size of symbol table */
+
+  /* SHORT FORM ENDS HERE */
+  long         a_trsize;       /* text relocation size */
+  long         a_drsize;       /* data relocation size */
+  long         a_tbase;        /* text relocation base */
+  long         a_dbase;        /* data relocation base */
+};
+
+#define A_MAGIC0      (unsigned char) 0x01
+#define A_MAGIC1      (unsigned char) 0x03
+#define BADMAG(X)     ((X).a_magic[0] != A_MAGIC0 ||(X).a_magic[1] != A_MAGIC1)
+
+/* CPU Id of TARGET machine (byte order coded in low order two bits) */
+#define A_NONE 0x00    /* unknown */
+#define A_I8086        0x04    /* intel i8086/8088 */
+#define A_M68K 0x0B    /* motorola m68000 */
+#define A_NS16K        0x0C    /* national semiconductor 16032 */
+#define A_I80386 0x10  /* intel i80386 */
+#define A_SPARC        0x17    /* Sun SPARC */
+
+#define A_BLR(cputype) ((cputype&0x01)!=0) /* TRUE if bytes left-to-right */
+#define A_WLR(cputype) ((cputype&0x02)!=0) /* TRUE if words left-to-right */
+
+/* Flags. */
+#define A_UZP  0x01    /* unmapped zero page (pages) */
+#define A_PAL  0x02    /* page aligned executable */
+#define A_NSYM 0x04    /* new style symbol table */
+#define A_EXEC 0x10    /* executable */
+#define A_SEP  0x20    /* separate I/D */
+#define A_PURE 0x40    /* pure text */
+#define A_TOVLY        0x80    /* text overlay */
+
+/* Offsets of various things. */
+#define A_MINHDR       32
+#define        A_TEXTPOS(X)    ((long)(X).a_hdrlen)
+#define A_DATAPOS(X)   (A_TEXTPOS(X) + (X).a_text)
+#define        A_HASRELS(X)    ((X).a_hdrlen > (unsigned char) A_MINHDR)
+#define A_HASEXT(X)    ((X).a_hdrlen > (unsigned char) (A_MINHDR +  8))
+#define A_HASLNS(X)    ((X).a_hdrlen > (unsigned char) (A_MINHDR + 16))
+#define A_HASTOFF(X)   ((X).a_hdrlen > (unsigned char) (A_MINHDR + 24))
+#define A_TRELPOS(X)   (A_DATAPOS(X) + (X).a_data)
+#define A_DRELPOS(X)   (A_TRELPOS(X) + (X).a_trsize)
+#define A_SYMPOS(X)    (A_TRELPOS(X) + (A_HASRELS(X) ? \
+                       ((X).a_trsize + (X).a_drsize) : 0))
+
+struct reloc {
+  long r_vaddr;                        /* virtual address of reference */
+  unsigned short r_symndx;     /* internal segnum or extern symbol num */
+  unsigned short r_type;       /* relocation type */
+};
+
+/* r_tyep values: */
+#define R_ABBS         0
+#define R_RELLBYTE     2
+#define R_PCRBYTE      3
+#define R_RELWORD      4
+#define R_PCRWORD      5
+#define R_RELLONG      6
+#define R_PCRLONG      7
+#define R_REL3BYTE     8
+#define R_KBRANCHE     9
+
+/* r_symndx for internal segments */
+#define S_ABS          ((unsigned short)-1)
+#define S_TEXT         ((unsigned short)-2)
+#define S_DATA         ((unsigned short)-3)
+#define S_BSS          ((unsigned short)-4)
+
+struct nlist {                 /* symbol table entry */
+  char n_name[8];              /* symbol name */
+  long n_value;                        /* value */
+  unsigned char        n_sclass;       /* storage class */
+  unsigned char        n_numaux;       /* number of auxiliary entries (not used) */
+  unsigned short n_type;       /* language base and derived type (not used) */
+};
+
+/* Low bits of storage class (section). */
+#define        N_SECT            07    /* section mask */
+#define N_UNDF           00    /* undefined */
+#define N_ABS            01    /* absolute */
+#define N_TEXT           02    /* text */
+#define N_DATA           03    /* data */
+#define        N_BSS             04    /* bss */
+#define N_COMM           05    /* (common) */
+
+/* High bits of storage class. */
+#define N_CLASS                0370    /* storage class mask */
+#define C_NULL
+#define C_EXT          0020    /* external symbol */
+#define C_STAT         0030    /* static */
+
+#endif /* _AOUT_H */
diff --git a/include/ar.h b/include/ar.h
new file mode 100644 (file)
index 0000000..c608371
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __AR_H
+#define __AR_H
+
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+#define ARFMAG "`\n"
+
+struct ar_hdr {
+       char    ar_name[16],
+               ar_date[12],
+               ar_uid[6],
+               ar_gid[6],
+               ar_mode[8],
+               ar_size[10],
+               ar_fmag[2];
+};
+
+#endif /* __AR_H */
diff --git a/include/arpa/inet.h b/include/arpa/inet.h
new file mode 100644 (file)
index 0000000..cf4cd32
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __ARPA_INET_H
+#define __ARPA_INET_H
+
+#include <netinet/in.h>
+
+int inet_aton(const char *cp, struct in_addr *inp);
+      
+unsigned long int inet_addr(const char *cp);
+
+char *inet_ntoa(struct in_addr in);
+       
+#endif
diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
new file mode 100644 (file)
index 0000000..ba60142
--- /dev/null
@@ -0,0 +1,392 @@
+/*
+ * ++Copyright++ 1983, 1989, 1993
+ * -
+ * 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 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
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * 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
+ * CORPORATION 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.
+ * -
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * --Copyright--
+ */
+
+/*
+ *      @(#)nameser.h  8.1 (Berkeley) 6/2/93
+ *     $Id: nameser.h,v 1.1 2000/05/14 04:16:36 erik Exp $
+ */
+
+#ifndef _NAMESER_H_
+#define        _NAMESER_H_
+
+#include <sys/param.h>
+#if (!defined(BSD)) || (BSD < 199306)
+# include <sys/bitypes.h>
+#else
+# include <sys/types.h>
+#endif
+#include <sys/cdefs.h>
+
+#ifdef _AUX_SOURCE
+# include <sys/types.h>
+#endif
+
+/*
+ * revision information.  this is the release date in YYYYMMDD format.
+ * it can change every day so the right thing to do with it is use it
+ * in preprocessor commands such as "#if (__BIND > 19931104)".  do not
+ * compare for equality; rather, use it to determine whether your resolver
+ * is new enough to contain a certain feature.
+ */
+
+#define __BIND         19960801        /* interface version stamp */
+
+/*
+ * Define constants based on rfc883
+ */
+#define PACKETSZ       512             /* maximum packet size */
+#define MAXDNAME       1025            /* maximum domain name */
+#define MAXCDNAME      255             /* maximum compressed domain name */
+#define MAXLABEL       63              /* maximum length of domain label */
+#define HFIXEDSZ       12              /* #/bytes of fixed data in header */
+#define QFIXEDSZ       4               /* #/bytes of fixed data in query */
+#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               /* IPv4 T_A */
+#define IN6ADDRSZ      16              /* IPv6 T_AAAA */
+
+/*
+ * Internet nameserver port number
+ */
+#define NAMESERVER_PORT        53
+
+/*
+ * Currently defined opcodes
+ */
+#define QUERY          0x0             /* standard query */
+#define IQUERY         0x1             /* inverse query */
+#define STATUS         0x2             /* nameserver status query */
+/*#define xxx          0x3*/           /* 0x3 reserved */
+#define NS_NOTIFY_OP   0x4             /* notify secondary of SOA change */
+/*
+ * Currently defined response codes
+ */
+#define NOERROR                0               /* no error */
+#define FORMERR                1               /* format error */
+#define SERVFAIL       2               /* server failure */
+#define NXDOMAIN       3               /* non existent domain */
+#define NOTIMP         4               /* not implemented */
+#define REFUSED                5               /* query refused */
+
+/*
+ * Type values for resources and queries
+ */
+#define T_A            1               /* host address */
+#define T_NS           2               /* authoritative server */
+#define T_MD           3               /* mail destination */
+#define T_MF           4               /* mail forwarder */
+#define T_CNAME                5               /* canonical name */
+#define T_SOA          6               /* start of authority zone */
+#define T_MB           7               /* mailbox domain name */
+#define T_MG           8               /* mail group member */
+#define T_MR           9               /* mail rename name */
+#define T_NULL         10              /* null resource record */
+#define T_WKS          11              /* well known service */
+#define T_PTR          12              /* domain name pointer */
+#define T_HINFO                13              /* host information */
+#define T_MINFO                14              /* mailbox information */
+#define T_MX           15              /* mail routing information */
+#define T_TXT          16              /* text strings */
+#define T_RP           17              /* responsible person */
+#define T_AFSDB                18              /* AFS cell database */
+#define T_X25          19              /* X_25 calling address */
+#define T_ISDN         20              /* ISDN calling address */
+#define T_RT           21              /* router */
+#define T_NSAP         22              /* NSAP address */
+#define T_NSAP_PTR     23              /* reverse NSAP lookup (deprecated) */
+#define T_SIG          24              /* security signature */
+#define T_KEY          25              /* security key */
+#define T_PX           26              /* X.400 mail mapping */
+#define T_GPOS         27              /* geographical position (withdrawn) */
+#define T_AAAA         28              /* IP6 Address */
+#define T_LOC          29              /* Location Information */
+#define T_NXT          30              /* Next Valid Name in Zone */
+#define T_EID          31              /* Endpoint identifier */
+#define T_NIMLOC       32              /* Nimrod locator */
+#define T_SRV          33              /* Server selection */
+#define T_ATMA         34              /* ATM Address */
+#define T_NAPTR                35              /* Naming Authority PoinTeR */
+       /* non standard */
+#define T_UINFO                100             /* user (finger) information */
+#define T_UID          101             /* user ID */
+#define T_GID          102             /* group ID */
+#define T_UNSPEC       103             /* Unspecified format (binary data) */
+       /* Query type values which do not appear in resource records */
+#define        T_IXFR          251             /* incremental zone transfer */
+#define T_AXFR         252             /* transfer zone of authority */
+#define T_MAILB                253             /* transfer mailbox records */
+#define T_MAILA                254             /* transfer mail agent records */
+#define T_ANY          255             /* wildcard match */
+
+/*
+ * Values for class field
+ */
+
+#define C_IN           1               /* the arpa internet */
+#define C_CHAOS                3               /* for chaos net (MIT) */
+#define C_HS           4               /* for Hesiod name server (MIT) (XXX) */
+       /* Query class values which do not appear in resource records */
+#define C_ANY          255             /* wildcard match */
+
+/*
+ * Flags field of the KEY RR rdata
+ */
+#define        KEYFLAG_TYPEMASK        0xC000  /* Mask for "type" bits */
+#define        KEYFLAG_TYPE_AUTH_CONF  0x0000  /* Key usable for both */
+#define        KEYFLAG_TYPE_CONF_ONLY  0x8000  /* Key usable for confidentiality */
+#define        KEYFLAG_TYPE_AUTH_ONLY  0x4000  /* Key usable for authentication */
+#define        KEYFLAG_TYPE_NO_KEY     0xC000  /* No key usable for either; no key */
+/* The type bits can also be interpreted independently, as single bits: */
+#define        KEYFLAG_NO_AUTH         0x8000  /* Key not usable for authentication */
+#define        KEYFLAG_NO_CONF         0x4000  /* Key not usable for confidentiality */
+
+#define        KEYFLAG_EXPERIMENTAL    0x2000  /* Security is *mandatory* if bit=0 */
+#define        KEYFLAG_RESERVED3       0x1000  /* reserved - must be zero */
+#define        KEYFLAG_RESERVED4       0x0800  /* reserved - must be zero */
+#define        KEYFLAG_USERACCOUNT     0x0400  /* key is assoc. with a user acct */
+#define        KEYFLAG_ENTITY          0x0200  /* key is assoc. with entity eg host */
+#define        KEYFLAG_ZONEKEY         0x0100  /* key is zone key for the zone named */
+#define        KEYFLAG_IPSEC           0x0080  /* key is for IPSEC use (host or user)*/
+#define        KEYFLAG_EMAIL           0x0040  /* key is for email (MIME security) */
+#define        KEYFLAG_RESERVED10      0x0020  /* reserved - must be zero */
+#define        KEYFLAG_RESERVED11      0x0010  /* reserved - must be zero */
+#define        KEYFLAG_SIGNATORYMASK   0x000F  /* key can sign DNS RR's of same name */
+
+#define  KEYFLAG_RESERVED_BITMASK ( KEYFLAG_RESERVED3 | \
+                                   KEYFLAG_RESERVED4 | \
+                                   KEYFLAG_RESERVED10| KEYFLAG_RESERVED11)
+
+/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
+#define        ALGORITHM_MD5RSA        1       /* MD5 with RSA */
+#define        ALGORITHM_EXPIRE_ONLY   253     /* No alg, no security */
+#define        ALGORITHM_PRIVATE_OID   254     /* Key begins with OID indicating alg */
+
+/* Signatures */
+                                       /* Size of a mod or exp in bits */
+#define        MIN_MD5RSA_KEY_PART_BITS         512
+#define        MAX_MD5RSA_KEY_PART_BITS        2552
+                                       /* Total of binary mod and exp, bytes */
+#define        MAX_MD5RSA_KEY_BYTES            ((MAX_MD5RSA_KEY_PART_BITS+7/8)*2+3)
+                                       /* Max length of text sig block */
+#define        MAX_KEY_BASE64                  (((MAX_MD5RSA_KEY_BYTES+2)/3)*4)
+
+/*
+ * Status return codes for T_UNSPEC conversion routines
+ */
+#define CONV_SUCCESS   0
+#define CONV_OVERFLOW  (-1)
+#define CONV_BADFMT    (-2)
+#define CONV_BADCKSUM  (-3)
+#define CONV_BADBUFLEN (-4)
+
+#ifndef BYTE_ORDER
+#if (BSD >= 199103)
+# include <machine/endian.h>
+#else
+#ifdef linux
+# include <endian.h>
+#else
+#define LITTLE_ENDIAN  1234    /* least-significant byte first (vax, pc) */
+#define BIG_ENDIAN     4321    /* most-significant byte first (IBM, net) */
+#define PDP_ENDIAN     3412    /* LSB first in word, MSW first in long (pdp)*/
+
+#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
+    defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
+    defined(__alpha__) || defined(__alpha)
+#define BYTE_ORDER     LITTLE_ENDIAN
+#endif
+
+#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
+    defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
+    defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
+    defined(apollo) || defined(__convex__) || defined(_CRAY) || \
+    defined(__hppa) || defined(__hp9000) || \
+    defined(__hp9000s300) || defined(__hp9000s700) || \
+    defined (BIT_ZERO_ON_LEFT) || defined(m68k)
+#define BYTE_ORDER     BIG_ENDIAN
+#endif
+#endif /* linux */
+#endif /* BSD */
+#endif /* BYTE_ORDER */
+
+#if !defined(BYTE_ORDER) || \
+    (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
+    BYTE_ORDER != PDP_ENDIAN)
+       /* you must determine what the correct bit order is for
+        * your compiler - the next line is an intentional error
+        * which will force your compiles to bomb until you fix
+        * the above macros.
+        */
+  error "Undefined or invalid BYTE_ORDER";
+#endif
+
+/*
+ * Structure for query header.  The order of the fields is machine- and
+ * compiler-dependent, depending on the byte/bit order and the layout
+ * of bit fields.  We use bit fields only in int variables, as this
+ * is all ANSI requires.  This requires a somewhat confusing rearrangement.
+ */
+
+typedef struct {
+       unsigned        id :16;         /* query identification number */
+#if BYTE_ORDER == BIG_ENDIAN
+                       /* fields in third byte */
+       unsigned        qr: 1;          /* response flag */
+       unsigned        opcode: 4;      /* purpose of message */
+       unsigned        aa: 1;          /* authoritative answer */
+       unsigned        tc: 1;          /* truncated message */
+       unsigned        rd: 1;          /* recursion desired */
+                       /* fields in fourth byte */
+       unsigned        ra: 1;          /* recursion available */
+       unsigned        unused :1;      /* unused bits (MBZ as of 4.9.3a3) */
+       unsigned        ad: 1;          /* authentic data from named */
+       unsigned        cd: 1;          /* checking disabled by resolver */
+       unsigned        rcode :4;       /* response code */
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+                       /* fields in third byte */
+       unsigned        rd :1;          /* recursion desired */
+       unsigned        tc :1;          /* truncated message */
+       unsigned        aa :1;          /* authoritative answer */
+       unsigned        opcode :4;      /* purpose of message */
+       unsigned        qr :1;          /* response flag */
+                       /* fields in fourth byte */
+       unsigned        rcode :4;       /* response code */
+       unsigned        cd: 1;          /* checking disabled by resolver */
+       unsigned        ad: 1;          /* authentic data from named */
+       unsigned        unused :1;      /* unused bits (MBZ as of 4.9.3a3) */
+       unsigned        ra :1;          /* recursion available */
+#endif
+                       /* remaining bytes */
+       unsigned        qdcount :16;    /* number of question entries */
+       unsigned        ancount :16;    /* number of answer entries */
+       unsigned        nscount :16;    /* number of authority entries */
+       unsigned        arcount :16;    /* number of resource entries */
+} HEADER;
+
+/*
+ * Defines for handling compressed domain names
+ */
+#define INDIR_MASK     0xc0
+
+extern u_int16_t       _getshort __P((const u_char *));
+extern u_int32_t       _getlong __P((const u_char *));
+
+/*
+ * Inline versions of get/put short/long.  Pointer is advanced.
+ *
+ * These macros demonstrate the property of C whereby it can be
+ * portable or it can be elegant but rarely both.
+ */
+#define GETSHORT(s, cp) { \
+       register u_char *t_cp = (u_char *)(cp); \
+       (s) = ((u_int16_t)t_cp[0] << 8) \
+           | ((u_int16_t)t_cp[1]) \
+           ; \
+       (cp) += INT16SZ; \
+}
+
+#define GETLONG(l, cp) { \
+       register u_char *t_cp = (u_char *)(cp); \
+       (l) = ((u_int32_t)t_cp[0] << 24) \
+           | ((u_int32_t)t_cp[1] << 16) \
+           | ((u_int32_t)t_cp[2] << 8) \
+           | ((u_int32_t)t_cp[3]) \
+           ; \
+       (cp) += INT32SZ; \
+}
+
+#define PUTSHORT(s, cp) { \
+       register u_int16_t t_s = (u_int16_t)(s); \
+       register u_char *t_cp = (u_char *)(cp); \
+       *t_cp++ = t_s >> 8; \
+       *t_cp   = t_s; \
+       (cp) += INT16SZ; \
+}
+
+#define PUTLONG(l, cp) { \
+       register u_int32_t t_l = (u_int32_t)(l); \
+       register u_char *t_cp = (u_char *)(cp); \
+       *t_cp++ = t_l >> 24; \
+       *t_cp++ = t_l >> 16; \
+       *t_cp++ = t_l >> 8; \
+       *t_cp   = t_l; \
+       (cp) += INT32SZ; \
+}
+
+#endif /* !_NAMESER_H_ */
diff --git a/include/arpa/telnet.h b/include/arpa/telnet.h
new file mode 100644 (file)
index 0000000..25085b8
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 1983, 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 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
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)telnet.h    8.2 (Berkeley) 12/15/93
+ */
+
+#ifndef _ARPA_TELNET_H
+#define _ARPA_TELNET_H
+
+/*
+ * Definitions for the TELNET protocol.
+ */
+#define        IAC     255             /* interpret as command: */
+#define        DONT    254             /* you are not to use option */
+#define        DO      253             /* please, you use option */
+#define        WONT    252             /* I won't use option */
+#define        WILL    251             /* I will use option */
+#define        SB      250             /* interpret as subnegotiation */
+#define        GA      249             /* you may reverse the line */
+#define        EL      248             /* erase the current line */
+#define        EC      247             /* erase the current character */
+#define        AYT     246             /* are you there */
+#define        AO      245             /* abort output--but let prog finish */
+#define        IP      244             /* interrupt process--permanently */
+#define        BREAK   243             /* break */
+#define        DM      242             /* data mark--for connect. cleaning */
+#define        NOP     241             /* nop */
+#define        SE      240             /* end sub negotiation */
+#define EOR     239             /* end of record (transparent mode) */
+#define        ABORT   238             /* Abort process */
+#define        SUSP    237             /* Suspend process */
+#define        xEOF    236             /* End of file: EOF is already used... */
+
+#define SYNCH  242             /* for telfunc calls */
+
+#ifdef TELCMDS
+char *telcmds[] = {
+       "EOF", "SUSP", "ABORT", "EOR",
+       "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
+       "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
+};
+#else
+extern char *telcmds[];
+#endif
+
+#define        TELCMD_FIRST    xEOF
+#define        TELCMD_LAST     IAC
+#define        TELCMD_OK(x)    ((unsigned int)(x) <= TELCMD_LAST && \
+                        (unsigned int)(x) >= TELCMD_FIRST)
+#define        TELCMD(x)       telcmds[(x)-TELCMD_FIRST]
+
+/* telnet options */
+#define TELOPT_BINARY  0       /* 8-bit data path */
+#define TELOPT_ECHO    1       /* echo */
+#define        TELOPT_RCP      2       /* prepare to reconnect */
+#define        TELOPT_SGA      3       /* suppress go ahead */
+#define        TELOPT_NAMS     4       /* approximate message size */
+#define        TELOPT_STATUS   5       /* give status */
+#define        TELOPT_TM       6       /* timing mark */
+#define        TELOPT_RCTE     7       /* remote controlled transmission and echo */
+#define TELOPT_NAOL    8       /* negotiate about output line width */
+#define TELOPT_NAOP    9       /* negotiate about output page size */
+#define TELOPT_NAOCRD  10      /* negotiate about CR disposition */
+#define TELOPT_NAOHTS  11      /* negotiate about horizontal tabstops */
+#define TELOPT_NAOHTD  12      /* negotiate about horizontal tab disposition */
+#define TELOPT_NAOFFD  13      /* negotiate about formfeed disposition */
+#define TELOPT_NAOVTS  14      /* negotiate about vertical tab stops */
+#define TELOPT_NAOVTD  15      /* negotiate about vertical tab disposition */
+#define TELOPT_NAOLFD  16      /* negotiate about output LF disposition */
+#define TELOPT_XASCII  17      /* extended ascic character set */
+#define        TELOPT_LOGOUT   18      /* force logout */
+#define        TELOPT_BM       19      /* byte macro */
+#define        TELOPT_DET      20      /* data entry terminal */
+#define        TELOPT_SUPDUP   21      /* supdup protocol */
+#define        TELOPT_SUPDUPOUTPUT 22  /* supdup output */
+#define        TELOPT_SNDLOC   23      /* send location */
+#define        TELOPT_TTYPE    24      /* terminal type */
+#define        TELOPT_EOR      25      /* end or record */
+#define        TELOPT_TUID     26      /* TACACS user identification */
+#define        TELOPT_OUTMRK   27      /* output marking */
+#define        TELOPT_TTYLOC   28      /* terminal location number */
+#define        TELOPT_3270REGIME 29    /* 3270 regime */
+#define        TELOPT_X3PAD    30      /* X.3 PAD */
+#define        TELOPT_NAWS     31      /* window size */
+#define        TELOPT_TSPEED   32      /* terminal speed */
+#define        TELOPT_LFLOW    33      /* remote flow control */
+#define TELOPT_LINEMODE        34      /* Linemode option */
+#define TELOPT_XDISPLOC        35      /* X Display Location */
+#define TELOPT_OLD_ENVIRON 36  /* Old - Environment variables */
+#define        TELOPT_AUTHENTICATION 37/* Authenticate */
+#define        TELOPT_ENCRYPT  38      /* Encryption option */
+#define TELOPT_NEW_ENVIRON 39  /* New - Environment variables */
+#define        TELOPT_EXOPL    255     /* extended-options-list */
+
+
+#define        NTELOPTS        (1+TELOPT_NEW_ENVIRON)
+#ifdef TELOPTS
+char *telopts[NTELOPTS+1] = {
+       "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
+       "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
+       "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
+       "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
+       "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
+       "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
+       "TACACS UID", "OUTPUT MARKING", "TTYLOC",
+       "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
+       "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
+       "ENCRYPT", "NEW-ENVIRON",
+       0,
+};
+#define        TELOPT_FIRST    TELOPT_BINARY
+#define        TELOPT_LAST     TELOPT_NEW_ENVIRON
+#define        TELOPT_OK(x)    ((unsigned int)(x) <= TELOPT_LAST)
+#define        TELOPT(x)       telopts[(x)-TELOPT_FIRST]
+#endif
+
+/* sub-option qualifiers */
+#define        TELQUAL_IS      0       /* option is... */
+#define        TELQUAL_SEND    1       /* send option */
+#define        TELQUAL_INFO    2       /* ENVIRON: informational version of IS */
+#define        TELQUAL_REPLY   2       /* AUTHENTICATION: client version of IS */
+#define        TELQUAL_NAME    3       /* AUTHENTICATION: client version of IS */
+
+#define        LFLOW_OFF               0       /* Disable remote flow control */
+#define        LFLOW_ON                1       /* Enable remote flow control */
+#define        LFLOW_RESTART_ANY       2       /* Restart output on any char */
+#define        LFLOW_RESTART_XON       3       /* Restart output only on XON */
+
+/*
+ * LINEMODE suboptions
+ */
+
+#define        LM_MODE         1
+#define        LM_FORWARDMASK  2
+#define        LM_SLC          3
+
+#define        MODE_EDIT       0x01
+#define        MODE_TRAPSIG    0x02
+#define        MODE_ACK        0x04
+#define MODE_SOFT_TAB  0x08
+#define MODE_LIT_ECHO  0x10
+
+#define        MODE_MASK       0x1f
+
+/* Not part of protocol, but needed to simplify things... */
+#define MODE_FLOW              0x0100
+#define MODE_ECHO              0x0200
+#define MODE_INBIN             0x0400
+#define MODE_OUTBIN            0x0800
+#define MODE_FORCE             0x1000
+
+#define        SLC_SYNCH       1
+#define        SLC_BRK         2
+#define        SLC_IP          3
+#define        SLC_AO          4
+#define        SLC_AYT         5
+#define        SLC_EOR         6
+#define        SLC_ABORT       7
+#define        SLC_EOF         8
+#define        SLC_SUSP        9
+#define        SLC_EC          10
+#define        SLC_EL          11
+#define        SLC_EW          12
+#define        SLC_RP          13
+#define        SLC_LNEXT       14
+#define        SLC_XON         15
+#define        SLC_XOFF        16
+#define        SLC_FORW1       17
+#define        SLC_FORW2       18
+
+#define        NSLC            18
+
+/*
+ * For backwards compatability, we define SLC_NAMES to be the
+ * list of names if SLC_NAMES is not defined.
+ */
+#define        SLC_NAMELIST    "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
+                       "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
+                       "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
+#ifdef SLC_NAMES
+char *slc_names[] = {
+       SLC_NAMELIST
+};
+#else
+extern char *slc_names[];
+#define        SLC_NAMES SLC_NAMELIST
+#endif
+
+#define        SLC_NAME_OK(x)  ((unsigned int)(x) <= NSLC)
+#define SLC_NAME(x)    slc_names[x]
+
+#define        SLC_NOSUPPORT   0
+#define        SLC_CANTCHANGE  1
+#define        SLC_VARIABLE    2
+#define        SLC_DEFAULT     3
+#define        SLC_LEVELBITS   0x03
+
+#define        SLC_FUNC        0
+#define        SLC_FLAGS       1
+#define        SLC_VALUE       2
+
+#define        SLC_ACK         0x80
+#define        SLC_FLUSHIN     0x40
+#define        SLC_FLUSHOUT    0x20
+
+#define        OLD_ENV_VAR     1
+#define        OLD_ENV_VALUE   0
+#define        NEW_ENV_VAR     0
+#define        NEW_ENV_VALUE   1
+#define        ENV_ESC         2
+#define        ENV_USERVAR     3
+
+/*
+ * AUTHENTICATION suboptions
+ */
+
+/*
+ * Who is authenticating who ...
+ */
+#define        AUTH_WHO_CLIENT         0       /* Client authenticating server */
+#define        AUTH_WHO_SERVER         1       /* Server authenticating client */
+#define        AUTH_WHO_MASK           1
+
+/*
+ * amount of authentication done
+ */
+#define        AUTH_HOW_ONE_WAY        0
+#define        AUTH_HOW_MUTUAL         2
+#define        AUTH_HOW_MASK           2
+
+#define        AUTHTYPE_NULL           0
+#define        AUTHTYPE_KERBEROS_V4    1
+#define        AUTHTYPE_KERBEROS_V5    2
+#define        AUTHTYPE_SPX            3
+#define        AUTHTYPE_MINK           4
+#define        AUTHTYPE_CNT            5
+
+#define        AUTHTYPE_TEST           99
+
+#ifdef AUTH_NAMES
+char *authtype_names[] = {
+       "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
+};
+#else
+extern char *authtype_names[];
+#endif
+
+#define        AUTHTYPE_NAME_OK(x)     ((unsigned int)(x) < AUTHTYPE_CNT)
+#define        AUTHTYPE_NAME(x)        authtype_names[x]
+
+/*
+ * ENCRYPTion suboptions
+ */
+#define        ENCRYPT_IS              0       /* I pick encryption type ... */
+#define        ENCRYPT_SUPPORT         1       /* I support encryption types ... */
+#define        ENCRYPT_REPLY           2       /* Initial setup response */
+#define        ENCRYPT_START           3       /* Am starting to send encrypted */
+#define        ENCRYPT_END             4       /* Am ending encrypted */
+#define        ENCRYPT_REQSTART        5       /* Request you start encrypting */
+#define        ENCRYPT_REQEND          6       /* Request you send encrypting */
+#define        ENCRYPT_ENC_KEYID       7
+#define        ENCRYPT_DEC_KEYID       8
+#define        ENCRYPT_CNT             9
+
+#define        ENCTYPE_ANY             0
+#define        ENCTYPE_DES_CFB64       1
+#define        ENCTYPE_DES_OFB64       2
+#define        ENCTYPE_CNT             3
+
+#ifdef ENCRYPT_NAMES
+char *encrypt_names[] = {
+       "IS", "SUPPORT", "REPLY", "START", "END",
+       "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
+       0,
+};
+char *enctype_names[] = {
+       "ANY", "DES_CFB64",  "DES_OFB64",  0,
+};
+#else
+extern char *encrypt_names[];
+extern char *enctype_names[];
+#endif
+
+
+#define        ENCRYPT_NAME_OK(x)      ((unsigned int)(x) < ENCRYPT_CNT)
+#define        ENCRYPT_NAME(x)         encrypt_names[x]
+
+#define        ENCTYPE_NAME_OK(x)      ((unsigned int)(x) < ENCTYPE_CNT)
+#define        ENCTYPE_NAME(x)         enctype_names[x]
+#endif /* _ARPA_TELNET_H */
diff --git a/include/arpa/tftp.h b/include/arpa/tftp.h
new file mode 100644 (file)
index 0000000..0904407
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1983, 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 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
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)tftp.h      8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _ARPA_TFTP_H
+#define        _ARPA_TFTP_H 1
+
+/*
+ * Trivial File Transfer Protocol (IEN-133)
+ */
+#define        SEGSIZE         512             /* data segment size */
+
+/*
+ * Packet types.
+ */
+#define        RRQ     01                              /* read request */
+#define        WRQ     02                              /* write request */
+#define        DATA    03                              /* data packet */
+#define        ACK     04                              /* acknowledgement */
+#define        ERROR   05                              /* error code */
+
+struct tftphdr {
+       short   th_opcode;                      /* packet type */
+       union {
+               unsigned short  tu_block;       /* block # */
+               short   tu_code;                /* error code */
+               char    tu_stuff[1];            /* request packet stuff */
+       } th_u;
+       char    th_data[1];                     /* data or error string */
+};
+
+#define        th_block        th_u.tu_block
+#define        th_code         th_u.tu_code
+#define        th_stuff        th_u.tu_stuff
+#define        th_msg          th_data
+
+/*
+ * Error codes.
+ */
+#define        EUNDEF          0               /* not defined */
+#define        ENOTFOUND       1               /* file not found */
+#define        EACCESS         2               /* access violation */
+#define        ENOSPACE        3               /* disk full or allocation exceeded */
+#define        EBADOP          4               /* illegal TFTP operation */
+#define        EBADID          5               /* unknown transfer ID */
+#define        EEXISTS         6               /* file already exists */
+#define        ENOUSER         7               /* no such user */
+
+#endif /* arpa/tftp.h */
diff --git a/include/assert.h b/include/assert.h
new file mode 100644 (file)
index 0000000..aef6cdf
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef        __ASSERT_H
+#define        __ASSERT_H
+#include <features.h>
+
+/* If NDEBUG is defined, do nothing.
+   If not, and EXPRESSION is zero, print an error message and abort.  */
+
+#ifdef NDEBUG
+
+#define        assert(expr)            ((void) 0)
+
+#else /* Not NDEBUG.  */
+
+extern void __assert __P((const char *, const char *, int));
+
+#define        assert(expr)                                                          \
+  ((void) ((expr) ||                                                         \
+          (__assert (__STRING(expr),                                 \
+                          __FILE__, __LINE__), 0)))
+
+#endif /* NDEBUG.  */
+
+#endif /* __ASSERT_H */
diff --git a/include/cfgfile.h b/include/cfgfile.h
new file mode 100644 (file)
index 0000000..1eae1bc
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __CFGFILE_H__
+#define __CFGFILE_H__
+
+#include <stdio.h>
+char ** cfgread(FILE *fp);
+char ** cfgfind(FILE *fp, char *var);
+
+#endif /* __CFGFILE_H__ */
diff --git a/include/ctype.h b/include/ctype.h
new file mode 100644 (file)
index 0000000..ed22ef7
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *     ctype.h         Character classification and conversion
+ */
+
+#ifndef __CTYPE_H
+#define __CTYPE_H
+
+extern unsigned char   __ctype[];
+
+#define        __CT_d  0x01            /* numeric digit */
+#define        __CT_u  0x02            /* upper case */
+#define        __CT_l  0x04            /* lower case */
+#define        __CT_c  0x08            /* control character */
+#define        __CT_s  0x10            /* whitespace */
+#define        __CT_p  0x20            /* punctuation */
+#define        __CT_x  0x40            /* hexadecimal */
+
+#define        toupper(c)      (islower(c) ? (c)^0x20 : (c))
+#define        tolower(c)      (isupper(c) ? (c)^0x20 : (c))
+#define        _toupper(c)     ((c)^0x20)
+#define        _tolower(c)     ((c)^0x20)
+#define        toascii(c)      ((c)&0x7F)
+
+/* Note the '!!' is a cast to 'bool' and even BCC deletes it in an if()  */
+#define        isalnum(c)      (!!(__ctype[(int) c]&(__CT_u|__CT_l|__CT_d)))
+#define        isalpha(c)      (!!(__ctype[(int) c]&(__CT_u|__CT_l)))
+#define        isascii(c)      (!((c)&~0x7F))
+#define        iscntrl(c)      (!!(__ctype[(int) c]&__CT_c))
+#define        isdigit(c)      (!!(__ctype[(int) c]&__CT_d))
+#define        isgraph(c)      (!(__ctype[(int) c]&(__CT_c|__CT_s)))
+#define        islower(c)      (!!(__ctype[(int) c]&__CT_l))
+#define        isprint(c)      (!(__ctype[(int) c]&__CT_c))
+#define        ispunct(c)      (!!(__ctype[(int) c]&__CT_p))
+#define        isspace(c)      (!!(__ctype[(int) c]&__CT_s))
+#define        isupper(c)      (!!(__ctype[(int) c]&__CT_u))
+#define        isxdigit(c)     (!!(__ctype[(int) c]&__CT_x))
+
+#endif /* __CTYPE_H */
diff --git a/include/dirent.h b/include/dirent.h
new file mode 100644 (file)
index 0000000..460ba0c
--- /dev/null
@@ -0,0 +1,155 @@
+/* Copyright (C) 1991, 1992 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, 1992 Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/*
+ *     POSIX Standard: 5.1.2 Directory Operations      <dirent.h>
+ */
+
+#ifndef        _DIRENT_H
+
+#define        _DIRENT_H       1
+#include <features.h>
+
+__BEGIN_DECLS
+
+#include <gnu/types.h>
+
+#define        __need_size_t
+#include <stddef.h>
+
+#include <sys/types.h>
+#include <linux/limits.h>
+#include <linux/dirent.h>
+
+#if defined(__USE_GNU)
+#define        d_fileno        d_ino           /* glibc compatibility.  */
+#if 0
+#define        d_namlen        d_reclen        /* glibc compatibility.  */
+#endif
+#endif
+
+#if defined(DIRENT_ILLEGAL_ACCESS) || \
+       (defined(__SVR4_I386_ABI_L1__) && !defined(INTERNAL_LINUX_C_LIB))
+
+/* Use it at your own risk. */
+typedef struct DIR
+{
+  /* file descriptor */
+  int dd_fd;
+
+  /* offset of the next dir entry in buffer */
+  off_t dd_loc;
+
+  /* bytes of valid entries in buffer */
+  size_t dd_size;
+
+  /* -> directory buffer */
+  struct dirent *dd_buf;
+} DIR;
+
+#else
+
+/* The internal is hidden from the user. */
+typedef struct DIR DIR;
+
+#endif
+
+
+/* Open a directory stream on NAME.
+   Return a DIR stream on the directory, or NULL if it could not be opened.  */
+extern DIR *opendir __P ((__const char *__name));
+
+/* Close the directory stream DIRP.
+   Return 0 if successful, -1 if not.  */
+extern int closedir __P ((DIR * __dirp));
+
+/* Read a directory entry from DIRP.
+   Return a pointer to a `struct dirent' describing the entry,
+   or NULL for EOF or error.  The storage returned may be overwritten
+   by a later readdir call on the same DIR stream.  */
+extern struct dirent *readdir __P ((DIR * __dirp));
+
+/* Rewind DIRP to the beginning of the directory.  */
+extern void rewinddir __P ((DIR * __dirp));
+
+#if defined(__USE_BSD) || defined(__USE_MISC)
+
+#ifndef        MAXNAMLEN
+/* Get the definitions of the POSIX.1 limits.  */
+#include <posix1_lim.h>
+
+/* `MAXNAMLEN' is the BSD name for what POSIX calls `NAME_MAX'.  */
+#ifdef NAME_MAX
+#define        MAXNAMLEN       NAME_MAX
+#else
+#define        MAXNAMLEN       255
+#endif
+#endif
+
+#include <gnu/types.h>
+
+/* Seek to position POS on DIRP.  */
+extern void seekdir __P ((DIR * __dirp, __off_t __pos));
+
+/* Return the current position of DIRP.  */
+extern __off_t telldir __P ((DIR * __dirp));
+
+typedef int (*__dir_select_fn_t) __P ((__const struct dirent *));
+
+typedef int (*__dir_compar_fn_t) __P ((
+               __const struct dirent * __const *,
+               __const struct dirent * __const *
+               ));
+
+/* Scan the directory DIR, calling SELECT on each directory entry.
+   Entries for which SELECT returns nonzero are individually malloc'd,
+   sorted using qsort with CMP, and collected in a malloc'd array in
+   *NAMELIST.  Returns the number of entries selected, or -1 on error.  */
+extern int scandir __P ((__const char *__dir,
+                        struct dirent ***__namelist,
+                        __dir_select_fn_t __dir_select_fn,
+                        __dir_compar_fn_t __dir_compar_fn));
+
+/* Function to compare two `struct dirent's alphabetically.  */
+extern int alphasort __P ((
+               __const struct dirent * __const *,
+               __const struct dirent * __const *
+               ));
+
+
+/* Read directory entries from FD into BUF, reading at most NBYTES.
+   Reading starts at offset *BASEP, and *BASEP is updated with the new
+   position after reading.  Returns the number of bytes read; zero when at
+   end of directory; or -1 for errors.  */
+extern __ssize_t __getdirentries __P ((int __fd, char *__buf,
+                                      size_t __nbytes, __off_t *__basep));
+extern __ssize_t getdirentries __P ((int __fd, char *__buf,
+                                    size_t __nbytes, __off_t *__basep));
+
+extern int dirfd __P ((DIR *__dirp));
+
+#endif /* Use BSD or misc.  */
+
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT)
+extern int readdir_r __P((DIR *__dirp, struct dirent *__entry,
+               struct dirent **__result));
+#endif
+
+__END_DECLS
+
+#endif /* dirent.h  */
diff --git a/include/endian.h b/include/endian.h
new file mode 100644 (file)
index 0000000..593b419
--- /dev/null
@@ -0,0 +1,43 @@
+/* Copyright (C) 1992, 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.  */
+
+#ifndef        _ENDIAN_H
+#define        _ENDIAN_H       1
+#include <features.h>
+
+/* Definitions for byte order, according to significance of bytes, from low
+   addresses to high addresses.  The value is what you get by putting '4'
+   in the most significant byte, '3' in the second most significant byte,
+   '2' in the second least significant byte, and '1' in the least
+   significant byte.  */
+
+#define        __LITTLE_ENDIAN 1234
+#define        __BIG_ENDIAN    4321
+#define        __PDP_ENDIAN    3412
+
+/* This file defines `__BYTE_ORDER' for the particular machine.  */
+#include <bytesex.h>
+
+#ifdef __USE_BSD
+#define        LITTLE_ENDIAN   __LITTLE_ENDIAN
+#define        BIG_ENDIAN      __BIG_ENDIAN
+#define        PDP_ENDIAN      __PDP_ENDIAN
+#define        BYTE_ORDER      __BYTE_ORDER
+#endif
+
+#endif /* endian.h */
diff --git a/include/err.h b/include/err.h
new file mode 100644 (file)
index 0000000..5bd51ea
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __ERR_H__
+#define __ERR_H__
+
+#define warn(X,args...) ({char _buf[128]; sprintf(_buf, X,args); perror(_buf);})
+#define err(X,Y,args...) ({char _buf[128]; sprintf(_buf, Y,##args); perror(_buf); exit(X);})
+
+#endif /* __ERR_H__ */
diff --git a/include/errno.h b/include/errno.h
new file mode 100644 (file)
index 0000000..871c95b
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __ERRNO_H
+#define __ERRNO_H
+
+#include <features.h>
+#include <linux/errno.h>
+
+#ifdef  __USE_BSD
+extern int sys_nerr;
+extern char *sys_errlist[];
+#endif
+#ifdef  __USE_GNU
+extern int _sys_nerr;
+extern char *_sys_errlist[];
+#endif
+
+extern int     errno;
+
+__BEGIN_DECLS
+
+extern void    perror __P ((__const char* __s));
+extern char*   strerror __P ((int __errno));
+
+__END_DECLS
+
+#endif
diff --git a/include/fcntl.h b/include/fcntl.h
new file mode 100644 (file)
index 0000000..b9f7272
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __FCNTL_H
+#define __FCNTL_H
+
+#include <features.h>
+#include <sys/types.h>
+#include <linux/fcntl.h>
+
+#ifndef FNDELAY
+#define FNDELAY        O_NDELAY
+#endif
+
+__BEGIN_DECLS
+
+extern int creat __P ((__const char * __filename, mode_t __mode));
+extern int fcntl __P ((int __fildes,int __cmd, ...));
+extern int open __P ((__const char * __filename, int __flags, ...));
+
+__END_DECLS
+
+#endif
diff --git a/include/features.h b/include/features.h
new file mode 100644 (file)
index 0000000..60ecc0a
--- /dev/null
@@ -0,0 +1,39 @@
+
+#ifndef __FEATURES_H
+#define __FEATURES_H
+
+#ifdef __STDC__
+
+#define __P(x) x
+#define __const const
+
+/* Almost ansi */
+#if __STDC__ != 1
+#define const
+#define volatile
+#endif
+
+#else /* K&R */
+
+#define __P(x) ()
+#define __const
+#define const
+#define volatile
+
+#endif
+
+/* No C++ */
+#define __BEGIN_DECLS
+#define __END_DECLS
+
+/* GNUish things */
+#define __CONSTVALUE
+#define __CONSTVALUE2
+
+#define _POSIX_THREAD_SAFE_FUNCTIONS
+
+#include <sys/cdefs.h>
+
+
+#endif
+
diff --git a/include/getopt.h b/include/getopt.h
new file mode 100644 (file)
index 0000000..0d71ff6
--- /dev/null
@@ -0,0 +1,17 @@
+/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+#ifndef __GETOPT_H
+#define __GETOPT_H
+
+#include <features.h>
+
+extern char *optarg;
+extern int opterr;
+extern int optind;
+
+extern int getopt __P((int argc, char *const *argv, const char *shortopts));
+
+#endif /* __GETOPT_H */
diff --git a/include/grp.h b/include/grp.h
new file mode 100644 (file)
index 0000000..96b2b4b
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef        __GRP_H
+#define        __GRP_H
+
+#include <sys/types.h>
+#include <features.h>
+#include <stdio.h>
+
+/* The group structure */
+struct group
+{
+  char *gr_name;               /* Group name.  */
+  char *gr_passwd;             /* Password.    */
+  gid_t gr_gid;                        /* Group ID.    */
+  char **gr_mem;               /* Member list. */
+};
+
+extern void setgrent __P ((void));
+extern void endgrent __P ((void));
+extern struct group * getgrent __P ((void));
+
+extern struct group * getgrgid __P ((__const gid_t gid));
+extern struct group * getgrnam __P ((__const char * name));
+
+extern struct group * fgetgrent __P ((FILE * file));
+
+extern int setgroups __P ((size_t n, __const gid_t * groups));
+extern int initgroups __P ((__const char * user, gid_t gid));
+
+
+#ifdef __LIBC__
+extern struct group * __getgrent __P ((int grp_fd));
+#endif
+
+#endif /* _GRP_H */
+
+
+
diff --git a/include/limits.h b/include/limits.h
new file mode 100644 (file)
index 0000000..8b59c82
--- /dev/null
@@ -0,0 +1,140 @@
+/* Copyright (C) 1991, 1992 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.  */
+
+/*
+ *     ANSI Standard: 4.14/2.2.4.2 Limits of integral types    <limits.h>
+ */
+
+#ifndef        _LIMITS_H
+
+#define        _LIMITS_H       1
+#include <features.h>
+
+#ifdef __USE_POSIX
+/* POSIX adds things to <limits.h>.  */
+#include <posix1_lim.h>
+#endif
+
+#ifdef __USE_POSIX2
+#include <posix2_lim.h>
+#endif
+
+
+/* Only if gcc 2.x is used and -traditional is not used, we can use
+ * #include_next.
+#if    __GNUC__ >= 2 && __STDC__
+ */
+#if    __GNUC__ >= 2
+
+ /* Have we done that? */
+# if !defined(_GCC_LIMITS_H_) && !defined(_GCC_LIMITS_H)
+  /* Get the compiler's limits.h, which defines all the ANSI
+   * constants.
+   */
+  /* This tells it not to look for another.  */
+# define _LIBC_LIMITS_H
+# define _LIBC_LIMITS_H_
+# include_next <limits.h>
+# endif
+
+#else  /* Not GCC 2.  */
+
+/* We don't have #include_next.
+   Define ANSI <limits.h> for standard 32-bit words.  */
+
+/* These assume 8-bit `char's, 16-bit `short int's,
+   and 32-bit `int's and `long int's.  */
+
+/* Number of bits in a `char'. */
+#define        CHAR_BIT        8
+
+/* Maximum length of any multibyte character in any locale.
+   Locale-writers should change this as necessary.  */
+#define        MB_LEN_MAX      1
+
+/* Minimum and maximum values a `signed char' can hold.  */
+#define        SCHAR_MIN       (-128)
+#define        SCHAR_MAX       127
+
+/* Maximum value an `unsigned char' can hold.  (Minimum is 0.)  */
+#ifdef __STDC__
+#define        UCHAR_MAX       255U
+#else
+#define        UCHAR_MAX       255
+#endif
+
+/* Minimum and maximum values a `char' can hold.  */
+#ifdef __CHAR_UNSIGNED__
+#define        CHAR_MIN        0
+#define        CHAR_MAX        UCHAR_MAX
+#else
+#define        CHAR_MIN        SCHAR_MIN
+#define        CHAR_MAX        SCHAR_MAX
+#endif
+
+/* Minimum and maximum values a `signed short int' can hold.  */
+#define        SHRT_MIN        (-32768)
+#define        SHRT_MAX        32767
+
+/* Maximum value an `unsigned short int' can hold.  (Minimum is 0.)  */
+#define        USHRT_MAX       65535
+
+/* Minimum and maximum values a `signed int' can hold.  */
+#define        INT_MIN (- INT_MAX - 1)
+#define        INT_MAX 2147483647
+
+/* Maximum value an `unsigned int' can hold.  (Minimum is 0.)  */
+#ifdef __STDC__
+#define        UINT_MAX        4294967295U
+#else
+#define        UINT_MAX        4294967295
+#endif
+
+/* Minimum and maximum values a `signed long int' can hold.  */
+#define        LONG_MIN        INT_MIN
+#define        LONG_MAX        INT_MAX
+
+/* Maximum value an `unsigned long int' can hold.  (Minimum is 0.)  */
+#define        ULONG_MAX       UINT_MAX
+
+#endif /* GCC 2.  */
+
+
+#ifndef RAND_MAX
+/* The largest number rand will return (same as INT_MAX).  */
+#define RAND_MAX       INT_MAX
+#endif
+
+#ifdef __SVR4_I386_ABI_L1__
+
+#define NL_ARGMAX      9
+#define NL_LANGMAX     14
+#define NL_MSGMAX      32767
+#define NL_NMAX                1
+#define NL_SETMAX      255
+#define NL_TEXTMAX     255
+#define NZERO          20
+
+#define WORD_BIT       32
+#define LONG_BIT       32
+
+#define FCHR_MAX       1048576
+
+#endif /* __SVR4_I386_ABI_L1__ */
+
+#endif /* limits.h  */
diff --git a/include/malloc.h b/include/malloc.h
new file mode 100644 (file)
index 0000000..e8fdb0a
--- /dev/null
@@ -0,0 +1,30 @@
+
+#ifndef __MALLOC_H
+#define __MALLOC_H
+#include <features.h>
+#include <sys/types.h>
+
+/*
+ * Mini malloc allows you to use a less efficient but smaller malloc the
+ * cost is about 100 bytes of code in free but malloc (700bytes) doesn't
+ * have to be linked. Unfortunatly memory can only be reused if everything
+ * above it has been freed
+ * 
+ */
+
+extern void free __P((void *));
+extern void *malloc __P((size_t));
+extern void *realloc __P((void *, size_t));
+extern void *alloca __P((size_t));
+
+extern void *(*__alloca_alloc) __P((size_t));
+
+#ifdef __LIBC__
+#define __MINI_MALLOC__
+#endif
+
+#ifdef __MINI_MALLOC__
+#define malloc(x) ((*__alloca_alloc)(x))
+#endif
+
+#endif
diff --git a/include/math.h b/include/math.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/include/memory.h b/include/memory.h
new file mode 100644 (file)
index 0000000..3b2f590
--- /dev/null
@@ -0,0 +1 @@
+#include <string.h>
diff --git a/include/mntent.h b/include/mntent.h
new file mode 100644 (file)
index 0000000..b4c6a8f
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef _MNTENT_H
+#define _MNTENT_H
+
+#include <features.h>
+
+#define MNTTAB "/etc/fstab"
+#define MOUNTED "/etc/mtab"
+
+#define MNTMAXSTR      512
+
+#define MNTTYPE_COHERENT       "coherent"      /* Coherent file system */
+#define MNTTYPE_EXT            "ext"           /* Extended file system */
+#define MNTTYPE_EXT2           "ext2"          /* Second Extended file system */
+#define MNTTYPE_HPFS           "hpfs"          /* OS/2's high performance file system */
+#define MNTTYPE_ISO9660                "iso9660"       /* ISO CDROM file system */
+#define MNTTYPE_MINIX          "minix"         /* MINIX file system */
+#define MNTTYPE_MSDOS          "msdos"         /* MS-DOS file system */
+#define        MNTTYPE_VFAT            "vfat"          /* VFAT (Win95) file system */
+#define MNTTYPE_SYSV           "sysv"          /* System V file system */
+#define MNTTYPE_UMSDOS         "umsdos"        /* U MS-DOS file system */
+#define MNTTYPE_XENIX          "xenix"         /* Xenix file system */
+#define MNTTYPE_XIAFS          "xiafs"         /* Frank Xia's file system */
+#define MNTTYPE_NFS            "nfs"           /* Network file system */
+#define MNTTYPE_PROC           "proc"          /* Linux process file system */
+#define MNTTYPE_IGNORE         "ignore"        /* Ignore this entry */
+#define MNTTYPE_SWAP           "swap"          /* Swap device */
+
+/* generic mount options */
+#define MNTOPT_DEFAULTS                "defaults"      /* use all default opts */
+#define MNTOPT_RO              "ro"            /* read only */
+#define MNTOPT_RW              "rw"            /* read/write */
+#define MNTOPT_SUID            "suid"          /* set uid allowed */
+#define MNTOPT_NOSUID          "nosuid"        /* no set uid allowed */
+#define MNTOPT_NOAUTO          "noauto"        /* don't auto mount */
+
+/* ext2 and msdos options */
+#define        MNTOPT_CHECK            "check"         /* filesystem check level */
+
+/* ext2 specific options */
+#define        MNTOPT_BSDDF            "bsddf"         /* disable MINIX compatibility disk free counting */
+#define        MNTOPT_BSDGROUPS        "bsdgroups"     /* set BSD group usage */
+#define        MNTOPT_ERRORS           "errors"        /* set behaviour on error */
+#define        MNTOPT_GRPID            "grpid"         /* set BSD group usage */
+#define        MNTOPT_MINIXDF          "minixdf"       /* enable MINIX compatibility disk free counting */
+#define        MNTOPT_NOCHECK          "nocheck"       /* reset filesystem checks */
+#define        MNTOPT_NOGRPID          "nogrpid"       /* set SYSV group usage */
+#define        MNTOPT_RESGID           "resgid"        /* group to consider like root for reserved blocks */
+#define        MNTOPT_RESUID           "resuid"        /* user to consider like root for reserved blocks */
+#define        MNTOPT_SB               "sb"            /* set used super block */
+#define        MNTOPT_SYSVGROUPS       "sysvgroups"    /* set SYSV group usage */
+
+/* options common to hpfs, isofs, and msdos */
+#define        MNTOPT_CONV             "conv"          /* convert specified types of data */
+#define        MNTOPT_GID              "gid"           /* use given gid */
+#define        MNTOPT_UID              "uid"           /* use given uid */
+#define        MNTOPT_UMASK            "umask"         /* use given umask, not isofs */
+
+/* hpfs specific options */
+#define        MNTOPT_CASE             "case"          /* case conversation */
+
+/* isofs specific options */
+#define        MNTOPT_BLOCK            "block"         /* use given block size */
+#define        MNTOPT_CRUFT            "cruft"         /* ??? */
+#define        MNTOPT_MAP              "map"           /* ??? */
+#define        MNTOPT_NOROCK           "norock"        /* not rockwell format ??? */
+
+/* msdos specific options */
+#define        MNTOPT_FAT              "fat"           /* set FAT size */
+#define        MNTOPT_QUIET            "quiet"         /* ??? */
+
+/* swap specific options */
+
+/* options common to ext, ext2, minix, xiafs, sysv, xenix, coherent */
+#define MNTOPT_NOQUOTA         "noquota"       /* don't use any quota on this partition */
+#define MNTOPT_USRQUOTA                "usrquota"      /* use userquota on this partition */
+#define MNTOPT_GRPQUOTA                "grpquota"      /* use groupquota on this partition */
+
+/* none defined yet */
+
+__BEGIN_DECLS
+
+struct mntent{
+       char *mnt_fsname;
+       char *mnt_dir;
+       char *mnt_type;
+       char *mnt_opts;
+       int  mnt_freq;
+       int  mnt_passno;
+};
+
+__END_DECLS
+
+#define __need_file
+#include <stdio.h>
+
+__BEGIN_DECLS
+
+extern FILE    *setmntent __P ((__const char *__filep,
+                       __const char *__type));
+extern struct mntent
+               *getmntent __P ((FILE *__filep));
+extern int     addmntent __P ((FILE *__filep,
+                       __const struct mntent *__mnt));
+extern char    *hasmntopt __P ((__const struct mntent *__mnt,
+                       __const char *__opt));
+extern int     endmntent __P ((FILE *__filep));
+
+__END_DECLS
+
+#endif /* _MNTENT_H */
diff --git a/include/netdb.h b/include/netdb.h
new file mode 100644 (file)
index 0000000..f332a7c
--- /dev/null
@@ -0,0 +1,215 @@
+/*-
+ * Copyright (c) 1980, 1983, 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 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
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)netdb.h     8.1 (Berkeley) 6/2/93
+ *      netdb.h,v 1.4 1995/08/14 04:05:04 hjl Exp
+ * -
+ * 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
+ * CORPORATION 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.
+ * -
+ * --Copyright--
+ */
+
+#ifndef _NETDB_H_
+#define _NETDB_H_
+
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT)
+#include <stdio.h>
+#include <netinet/in.h>
+#endif
+
+#include <paths.h>
+
+#define _PATH_HEQUIV   __PATH_ETC_INET"/hosts.equiv"
+#define _PATH_HOSTS    __PATH_ETC_INET"/hosts"
+#define _PATH_NETWORKS __PATH_ETC_INET"/networks"
+#define _PATH_PROTOCOLS        __PATH_ETC_INET"/protocols"
+#define _PATH_SERVICES __PATH_ETC_INET"/services"
+#define _PATH_RESCONF  __PATH_ETC_INET"/resolv.conf"
+#define _PATH_RPC      __PATH_ETC_INET"/rpc"
+
+
+/*
+ * Structures returned by network data base library.  All addresses are
+ * supplied in host order, and returned in network order (suitable for
+ * use in system calls).
+ */
+struct hostent {
+       char    *h_name;        /* official name of host */
+       char    **h_aliases;    /* alias list */
+       int     h_addrtype;     /* host address type */
+       int     h_length;       /* length of address */
+       char    **h_addr_list;  /* list of addresses from name server */
+#define        h_addr  h_addr_list[0]  /* address, for backward compatiblity */
+};
+
+/*
+ * Assumption here is that a network number
+ * fits in an unsigned long -- probably a poor one.
+ */
+struct netent {
+       char            *n_name;        /* official name of net */
+       char            **n_aliases;    /* alias list */
+       int             n_addrtype;     /* net address type */
+       unsigned long   n_net;          /* network # */
+};
+
+struct servent {
+       char    *s_name;        /* official service name */
+       char    **s_aliases;    /* alias list */
+       int     s_port;         /* port # */
+       char    *s_proto;       /* protocol to use */
+};
+
+struct protoent {
+       char    *p_name;        /* official protocol name */
+       char    **p_aliases;    /* alias list */
+       int     p_proto;        /* protocol # */
+};
+
+struct rpcent {
+       char    *r_name;        /* name of server for this rpc program */
+       char    **r_aliases;    /* alias list */
+       int     r_number;       /* rpc program number */
+};
+
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT)
+
+#define __NETDB_MAXALIASES     35
+#define __NETDB_MAXADDRS       35
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in extern int h_errno).
+ */
+#define h_errno                (*__h_errno_location ())
+#else
+extern int h_errno;
+#endif
+
+#define        NETDB_INTERNAL -1 /* see errno */
+#define        NETDB_SUCCESS   0 /* no problem */
+#define        HOST_NOT_FOUND  1 /* Authoritative Answer Host not found */
+#define        TRY_AGAIN       2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define        NO_RECOVERY     3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define        NO_DATA         4 /* Valid name, no data record of requested type */
+#define        NO_ADDRESS      NO_DATA         /* no address, look for MX record */
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+void           endhostent __P((void));
+void           endnetent __P((void));
+void           endprotoent __P((void));
+void           endservent __P((void));
+void           endrpcent __P ((void));
+struct hostent *gethostbyaddr __P((__const char *, int, int));
+struct hostent *gethostbyname __P((__const char *));
+struct hostent *gethostent __P((void));
+struct netent  *getnetbyaddr __P((long, int)); /* u_long? */
+struct netent  *getnetbyname __P((__const char *));
+struct netent  *getnetent __P((void));
+struct protoent        *getprotobyname __P((__const char *));
+struct protoent        *getprotobynumber __P((int));
+struct protoent        *getprotoent __P((void));
+struct servent *getservbyname __P((__const char *, __const char *));
+struct servent *getservbyport __P((int, __const char *));
+struct servent *getservent __P((void));
+struct rpcent  *getrpcent __P((void));
+struct rpcent  *getrpcbyname __P((__const char *));
+struct rpcent  *getrpcbynumber __P((int));
+void           herror __P((__const char *));
+void           sethostent __P((int));
+/* void                sethostfile __P((__const char *)); */
+void           setnetent __P((int));
+void           setprotoent __P((int));
+void           setservent __P((int));
+void           setrpcent __P((int));
+
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT)
+struct hostent *gethostbyaddr_r __P((const char *__addr,
+                       int __length, int __type,
+                       struct hostent *__result,
+                       char *__buffer, int __buflen, int *__h_errnop));
+struct hostent *gethostbyname_r __P((const char * __name,
+                       struct hostent *__result, char *__buffer,
+                       int __buflen, int *__h_errnop));
+struct hostent *gethostent_r __P((struct hostent *__result,
+                       char *__buffer, int __buflen, int *__h_errnop));
+struct netent  *getnetbyaddr_r __P((long __net, int __type,
+                       struct netent *__result, char *__buffer,
+                       int __buflen));
+struct netent  *getnetbyname_r __P((const char * __name,
+                       struct netent *__result, char *__buffer,
+                       int __buflen));
+struct netent  *getnetent_r __P((struct netent *__result,
+                       char *__buffer, int __buflen));
+struct protoent        *getprotobyname_r __P((const char * __name,
+                       struct protoent *__result, char *__buffer,
+                       int __buflen));
+struct protoent        *getprotobynumber_r __P((int __proto,
+                       struct protoent *__result, char *__buffer,
+                       int __buflen));
+struct protoent        *getprotoent_r __P((struct protoent *__result,
+                       char *__buffer, int __buflen));
+struct servent *getservbyname_r __P((const char * __name,
+                       const char *__proto, struct servent *__result,
+                       char *__buffer, int __buflen));
+struct servent *getservbyport_r __P((int __port,
+                       const char *__proto, struct servent *__result,
+                       char *__buffer, int __buflen));
+struct servent *getservent_r __P((struct servent *__result,
+                       char *__buffer, int __buflen));
+
+int *__h_errno_location __P((void));
+
+#endif
+
+__END_DECLS
+
+#endif /* !_NETDB_H_ */
diff --git a/include/netinet/igmp.h b/include/netinet/igmp.h
new file mode 100644 (file)
index 0000000..4525630
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _NETINET_IGMP_H
+#define _NETINET_IGMP_H
+
+#include <linux/igmp.h>
+
+#ifdef __BSD_SOURCE
+
+struct igmp
+{
+       __u8 igmp_type;
+       __u8 igmp_code;
+       __u16 igmp_cksum;
+       struct in_addr igmp_group;
+};
+
+#define IGMP_MINLEN                    8
+#define IGMP_MAX_HOST_REPORT_DELAY     10
+#define IGMP_TIMER_SCALE               10
+
+#define IGMP_AGE_THRESHOLD             540
+
+#endif
+
+#endif /* _NETINET_IGMP_H */
diff --git a/include/netinet/in.h b/include/netinet/in.h
new file mode 100644 (file)
index 0000000..d666c67
--- /dev/null
@@ -0,0 +1,88 @@
+/* Copyright (C) 1991 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 General Public License as published by
+the Free Software Foundation; either version 1, 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the GNU C Library; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef        _NETINET_IN_H
+
+#define        _NETINET_IN_H   1
+#include <features.h>
+
+#include <sys/socket.h>
+
+__BEGIN_DECLS
+
+/* Standard well-known ports.  */
+enum
+  {
+    IPPORT_ECHO = 7,           /* Echo service.  */
+    IPPORT_DISCARD = 9,                /* Discard transmissions service.  */
+    IPPORT_SYSTAT = 11,                /* System status service.  */
+    IPPORT_DAYTIME = 13,       /* Time of day service.  */
+    IPPORT_NETSTAT = 15,       /* Network status service.  */
+    IPPORT_FTP = 21,           /* File Transfer Protocol.  */
+    IPPORT_TELNET = 23,                /* Telnet protocol.  */
+    IPPORT_SMTP = 25,          /* Simple Mail Transfer Protocol.  */
+    IPPORT_TIMESERVER = 37,    /* Timeserver service.  */
+    IPPORT_NAMESERVER = 42,    /* Domain Name Service.  */
+    IPPORT_WHOIS = 43,         /* Internet Whois service.  */
+    IPPORT_MTP = 57,
+
+    IPPORT_TFTP = 69,          /* Trivial File Transfer Protocol.  */
+    IPPORT_RJE = 77,
+    IPPORT_FINGER = 79,                /* Finger service.  */
+    IPPORT_TTYLINK = 87,
+    IPPORT_SUPDUP = 95,                /* SUPDUP protocol.  */
+
+
+    IPPORT_EXECSERVER = 512,   /* execd service.  */
+    IPPORT_LOGINSERVER = 513,  /* rlogind service.  */
+    IPPORT_CMDSERVER = 514,
+    IPPORT_EFSSERVER = 520,
+
+    /* UDP ports.  */
+    IPPORT_BIFFUDP = 512,
+    IPPORT_WHOSERVER = 513,
+    IPPORT_ROUTESERVER = 520,
+
+    /* Ports less than this value are reserved for privileged processes.  */
+    IPPORT_RESERVED = 1024,
+
+    /* Ports greater this value are reserved for (non-privileged) servers.  */
+    IPPORT_USERRESERVED = 5000
+  };
+
+
+/* Link numbers.  */
+#define        IMPLINK_IP              155
+#define        IMPLINK_LOWEXPER        156
+#define        IMPLINK_HIGHEXPER       158
+
+
+/*
+ * Many other definitions have been moved to <linux/in.h>,
+ * because several parts of the kernel need them. -FvK
+ */
+#include <linux/in.h>
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+extern int bindresvport __P ((int __sockfd,
+               struct sockaddr_in * __sin));
+
+__END_DECLS
+
+#endif /* netinet/in.h */
diff --git a/include/netinet/in_systm.h b/include/netinet/in_systm.h
new file mode 100644 (file)
index 0000000..f481c55
--- /dev/null
@@ -0,0 +1 @@
+#include <linux/in_systm.h>
diff --git a/include/netinet/ip.h b/include/netinet/ip.h
new file mode 100644 (file)
index 0000000..a6c49b6
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _NETINET_IP_H
+#define _NETINET_IP_H
+
+#include <features.h>
+#include <netinet/in.h>
+#include <linux/ip.h>
+
+#ifdef _BSD_SOURCE
+
+/*
+ *     BSD has the following structure
+ */
+struct ip
+{
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+       __u8    ip_hl:4,
+               ip_v:4;
+#else
+       __u8    ip_v:4,
+               ip_hl:4;
+#endif
+#define IPVERSION      4
+       __u8    ip_tos;
+       __u16   ip_len;
+       __u16   ip_id;
+       __u16   ip_off;
+       __u8    ip_ttl;
+       __u8    ip_p;
+       __u16   ip_csum;
+       struct  in_addr ip_src,ip_dst;
+};
+
+#define        IP_DF   0x4000          /* dont fragment flag */
+#define        IP_MF   0x2000          /* more fragments flag */
+
+#endif
+
+#endif /* _NETINET_IP_H */
diff --git a/include/netinet/ip_fw.h b/include/netinet/ip_fw.h
new file mode 100644 (file)
index 0000000..278a039
--- /dev/null
@@ -0,0 +1 @@
+#include <linux/ip_fw.h>
diff --git a/include/netinet/ip_icmp.h b/include/netinet/ip_icmp.h
new file mode 100644 (file)
index 0000000..1662e3f
--- /dev/null
@@ -0,0 +1 @@
+#include <linux/icmp.h>
diff --git a/include/netinet/ip_tcp.h b/include/netinet/ip_tcp.h
new file mode 100644 (file)
index 0000000..39111f2
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *     @(#)tcp.h       7.5 (Berkeley) 6/29/88
+ */
+
+#ifndef _NETINET_IP_TCP_H
+#define _NETINET_IP_TCP_H
+
+#include <endian.h>
+#include <linux/socket.h>
+#include <sys/types.h>
+
+typedef        u_long  tcp_seq;
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr {
+       u_short th_sport;               /* source port */
+       u_short th_dport;               /* destination port */
+       tcp_seq th_seq;                 /* sequence number */
+       tcp_seq th_ack;                 /* acknowledgement number */
+#if __BYTE_ORDER == __LITTLE_ENDIAN 
+       u_char  th_x2:4,                /* (unused) */
+               th_off:4;               /* data offset */
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN 
+       u_char  th_off:4,               /* data offset */
+               th_x2:4;                /* (unused) */
+#endif
+       u_char  th_flags;
+#define        TH_FIN  0x01
+#define        TH_SYN  0x02
+#define        TH_RST  0x04
+#define        TH_PUSH 0x08
+#define        TH_ACK  0x10
+#define        TH_URG  0x20
+       u_short th_win;                 /* window */
+       u_short th_sum;                 /* checksum */
+       u_short th_urp;                 /* urgent pointer */
+};
+
+#define        TCPOPT_EOL      0
+#define        TCPOPT_NOP      1
+#define        TCPOPT_MAXSEG   2
+
+/*
+ * Default maximum segment size for TCP.
+ * With an IP MSS of 576, this is 536,
+ * but 512 is probably more convenient.
+ */
+#ifdef lint
+#define        TCP_MSS 536
+#else
+#define        TCP_MSS MIN(512, IP_MSS - sizeof (struct tcpiphdr))
+#endif
+
+#endif /* _NETINET_TCP_H */
diff --git a/include/netinet/ip_udp.h b/include/netinet/ip_udp.h
new file mode 100644 (file)
index 0000000..3f0d8ef
--- /dev/null
@@ -0,0 +1 @@
+#include <linux/udp.h>
diff --git a/include/netinet/protocols.h b/include/netinet/protocols.h
new file mode 100644 (file)
index 0000000..1a619c4
--- /dev/null
@@ -0,0 +1,62 @@
+/* protocols.h */
+#ifndef _NETINET_PROTOCOLS_H
+#define _NETINET_PROTOCOLS_H
+
+#define IP_ICMP                  1
+#define IP_IGMP                  2
+#define IP_GGP                   3
+#define IP_ST                    5
+#define IP_TCP                   6
+#define IP_UCL                   7
+#define IP_EGP                   8
+#define IP_IGP                   9
+#define IP_BBN_RCC_MON  10
+#define IP_NVP_II       11
+#define IP_PUP          12
+#define IP_ARGUS        13
+#define IP_EMCON        14
+#define IP_XNET                 15
+#define IP_CHAOS        16
+#define IP_UDP          17
+#define IP_MUX          18
+#define IP_DCN_MEAS     19
+#define IP_HMP          20
+#define IP_PRM          21
+#define IP_XNS_IDP      22
+#define IP_TRUNK1       23
+#define IP_TRUNK2       24
+#define IP_LEAF1        25
+#define IP_LEAF2        26
+#define IP_RDP          27
+#define IP_IRTP                 28
+#define IP_ISO_TP4      29
+#define IP_NETBLT       30
+#define IP_MFE_NSP      31
+#define IP_MERIT_INP    32
+#define IP_SEP          33
+#define IP_3PC          34
+#define IP_CFTP                 62
+#define SAT_EXPAK       64
+#define IP_RVD          66
+#define IP_IPPC                 67
+#define IP_SAT_MON      69
+#define IP_VISA                 70
+#define IP_IPCV                 71
+#define IP_BR_SAT_MON   76
+#define IP_SUN_ND       77
+#define IP_WB_MON       78
+#define IP_WB_EXPAK     79
+#define IP_ISO_IP       80
+#define IP_VMTP                 81
+#define IP_SECURE_VMTP  82
+#define IP_VINES        83
+#define IP_TTP          84
+#define NSFNET_IGP      85
+#define IP_DGP          86
+#define IP_TCF          87
+#define IP_IGRP                 88
+#define IP_OSPFIGP      89
+#define IP_SPRITE_RPG   90
+#define IP_LARP                 91
+
+#endif /*  _NETINET_PROTOCOLS_H*/
diff --git a/include/netinet/tcp.h b/include/netinet/tcp.h
new file mode 100644 (file)
index 0000000..8636ec7
--- /dev/null
@@ -0,0 +1 @@
+#include <netinet/ip_tcp.h>
diff --git a/include/netinet/udp.h b/include/netinet/udp.h
new file mode 100644 (file)
index 0000000..39a57a3
--- /dev/null
@@ -0,0 +1 @@
+#include <netinet/ip_udp.h>
diff --git a/include/paths.h b/include/paths.h
new file mode 100644 (file)
index 0000000..2af8a57
--- /dev/null
@@ -0,0 +1,22 @@
+/* paths.h <ndf@linux.mit.edu> */
+
+#ifndef ___PATHS_H
+#define        ___PATHS_H
+
+
+#define        _PATH_CONSOLE   "/dev/console"
+#define        _PATH_TTY       "/dev/tty"
+#define        _PATH_NOLOGIN   "/etc/nologin"
+#define        _PATH_LOGIN     "/bin/login"
+#define        _PATH_BSHELL    "/bin/sh"
+#define _PATH_UTMP     "/var/run/utmp"
+#define _PATH_WTMP     "/var/log/wtmp"
+#define        _PATH_DEFPATH   "/bin:/usr/bin:/usr/local/bin:."
+#define        _PATH_DEV       "/dev/"
+#define _PATH_DEVNULL  "/dev/null"
+#define        _PATH_TMP       "/tmp/"
+#define _PATH_LASTLOG  "/var/log/lastlog"
+#define _PATH_LOCALE   "/usr/lib/locale"
+#define _PATH_VARRUN   "/var/log/"
+
+#endif /* __PATHS_H */
diff --git a/include/pwd.h b/include/pwd.h
new file mode 100644 (file)
index 0000000..1b48c6a
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef        __PWD_H
+#define        __PWD_H
+
+#include <sys/types.h>
+#include <features.h>
+#include <stdio.h>
+
+/* The passwd structure.  */
+struct passwd
+{
+  char *pw_name;               /* Username.  */
+  char *pw_passwd;             /* Password.  */
+  uid_t pw_uid;                        /* User ID.  */
+  gid_t pw_gid;                        /* Group ID.  */
+  char *pw_gecos;              /* Real name.  */
+  char *pw_dir;                        /* Home directory.  */
+  char *pw_shell;              /* Shell program.  */
+};
+
+
+extern void setpwent __P ((void));
+extern void endpwent __P ((void));
+extern struct passwd * getpwent __P ((void));
+
+extern int putpwent __P ((__const struct passwd * __p, FILE * __f));
+extern int getpw __P ((uid_t uid, char *buf));
+
+extern struct passwd * fgetpwent __P ((FILE * file));
+
+extern struct passwd * getpwuid __P ((__const uid_t));
+extern struct passwd * getpwnam __P ((__const char *));
+
+#ifdef __LIBC__
+extern struct passwd * __getpwent __P ((__const int passwd_fd));
+#endif
+
+#endif /* pwd.h  */
+
+
+
diff --git a/include/regexp.h b/include/regexp.h
new file mode 100644 (file)
index 0000000..73d6bf4
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Definitions etc. for regexp(3) routines.
+ *
+ * Caveat:  this is V8 regexp(3) [actually, a reimplementation thereof],
+ * not the System V one.
+ */
+#define NSUBEXP  10
+typedef struct regexp {
+       char *startp[NSUBEXP];
+       char *endp[NSUBEXP];
+       char regstart;          /* Internal use only. */
+       char reganch;           /* Internal use only. */
+       char *regmust;          /* Internal use only. */
+       int regmlen;            /* Internal use only. */
+       char program[1];        /* Unwarranted chumminess with compiler. */
+} regexp;
+
+extern regexp *regcomp();
+extern int regexec();
+extern void regsub();
+extern void regerror();
diff --git a/include/resolv.h b/include/resolv.h
new file mode 100644 (file)
index 0000000..53ee2f2
--- /dev/null
@@ -0,0 +1,85 @@
+/* resolv.h: DNS Resolver
+ *
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * This 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.
+ */
+
+#ifndef _RESOLV_H_
+#define _RESOLV_H_
+
+#include <netdb.h>
+#include <netinet/in.h>
+
+struct resolv_header {
+       int id;
+       int qr,opcode,aa,tc,rd,ra,rcode;
+       int qdcount;
+       int ancount;
+       int nscount;
+       int arcount;
+};
+
+struct resolv_question {
+       char * dotted;
+       int qtype;
+       int qclass;
+};
+
+struct resolv_answer {
+       char * dotted;
+       int atype;
+       int aclass;
+       int ttl;
+       int rdlength;
+       unsigned char * rdata;
+       int rdoffset;
+};
+
+int encode_header(struct resolv_header * h, unsigned char * dest, int maxlen);
+int decode_header(unsigned char * data, struct resolv_header * h);
+int encode_dotted(const char * dotted, unsigned char * dest, int maxlen);
+int decode_dotted(const unsigned char * message, int offset, 
+       char * dest, int maxlen);
+int length_dotted(const unsigned char * message, int offset);
+int encode_question(struct resolv_question * q,
+       unsigned char * dest, int maxlen);
+int decode_question(unsigned char * message, int offset,
+       struct resolv_question * q);
+int length_question(unsigned char * message, int offset);
+int encode_answer(struct resolv_answer * a,
+       unsigned char * dest, int maxlen);
+int decode_answer(unsigned char * message, int offset,
+       struct resolv_answer * a);
+char * resolve_name(const char * name, int mailbox);
+
+int encode_packet(struct resolv_header * h,
+       struct resolv_question ** q,
+       struct resolv_question ** an,
+       struct resolv_question ** ns,
+       struct resolv_question ** ar,
+       unsigned char * dest, int maxlen);
+int decode_packet(unsigned char * data, struct resolv_header * h);
+
+int dns_lookup(const char * name, int type, int nscount, const char ** nsip,
+       unsigned char ** outpacket, struct resolv_answer * a);
+
+int resolve_address(const char * address, 
+       int nscount, const char ** nsip, 
+       struct in_addr * in);
+
+int resolve_mailbox(const char * address, 
+       int nscount, const char ** nsip, 
+       struct in_addr * in);
+
+extern int open_nameservers(void);
+extern void close_nameservers(void);
+
+extern struct hostent * gethostbyname(const char * name);
+extern struct hostent * gethostbyaddr(const char * addr, int len, int type);
+
+#endif /*_RESOLV_H_*/
diff --git a/include/rpc/auth.h b/include/rpc/auth.h
new file mode 100644 (file)
index 0000000..33cb429
--- /dev/null
@@ -0,0 +1,166 @@
+/* @(#)auth.h  2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * auth.h, Authentication interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The data structures are completely opaque to the client.  The client
+ * is required to pass a AUTH * to routines that create rpc
+ * "sessions".
+ */
+
+
+#define MAX_AUTH_BYTES 400
+#define MAXNETNAMELEN  255     /* maximum length of network user's name */
+
+/*
+ * Status returned from authentication check
+ */
+enum auth_stat {
+       AUTH_OK=0,
+       /*
+        * failed at remote end
+        */
+       AUTH_BADCRED=1,                 /* bogus credentials (seal broken) */
+       AUTH_REJECTEDCRED=2,            /* client should begin new session */
+       AUTH_BADVERF=3,                 /* bogus verifier (seal broken) */
+       AUTH_REJECTEDVERF=4,            /* verifier expired or was replayed */
+       AUTH_TOOWEAK=5,                 /* rejected due to security reasons */
+       /*
+        * failed locally
+       */
+       AUTH_INVALIDRESP=6,             /* bogus response verifier */
+       AUTH_FAILED=7                   /* some unknown reason */
+};
+
+#if (mc68000 || sparc || vax || i386)
+typedef u_long u_int32;        /* 32-bit unsigned integers */
+#endif
+
+union des_block {
+       struct {
+               u_int32 high;
+               u_int32 low;
+       } key;
+       char c[8];
+};
+typedef union des_block des_block;
+extern bool_t xdr_des_block();
+
+/*
+ * Authentication info.  Opaque to client.
+ */
+struct opaque_auth {
+       enum_t  oa_flavor;              /* flavor of auth */
+       caddr_t oa_base;                /* address of more auth stuff */
+       u_int   oa_length;              /* not to exceed MAX_AUTH_BYTES */
+};
+
+
+/*
+ * Auth handle, interface to client side authenticators.
+ */
+typedef struct {
+       struct  opaque_auth     ah_cred;
+       struct  opaque_auth     ah_verf;
+       union   des_block       ah_key;
+       struct auth_ops {
+               void    (*ah_nextverf)();
+               int     (*ah_marshal)();        /* nextverf & serialize */
+               int     (*ah_validate)();       /* validate varifier */
+               int     (*ah_refresh)();        /* refresh credentials */
+               void    (*ah_destroy)();        /* destroy this structure */
+       } *ah_ops;
+       caddr_t ah_private;
+} AUTH;
+
+
+/*
+ * Authentication ops.
+ * The ops and the auth handle provide the interface to the authenticators.
+ *
+ * AUTH        *auth;
+ * XDR *xdrs;
+ * struct opaque_auth verf;
+ */
+#define AUTH_NEXTVERF(auth)            \
+               ((*((auth)->ah_ops->ah_nextverf))(auth))
+#define auth_nextverf(auth)            \
+               ((*((auth)->ah_ops->ah_nextverf))(auth))
+
+#define AUTH_MARSHALL(auth, xdrs)      \
+               ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+#define auth_marshall(auth, xdrs)      \
+               ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+
+#define AUTH_VALIDATE(auth, verfp)     \
+               ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+#define auth_validate(auth, verfp)     \
+               ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+
+#define AUTH_REFRESH(auth)             \
+               ((*((auth)->ah_ops->ah_refresh))(auth))
+#define auth_refresh(auth)             \
+               ((*((auth)->ah_ops->ah_refresh))(auth))
+
+#define AUTH_DESTROY(auth)             \
+               ((*((auth)->ah_ops->ah_destroy))(auth))
+#define auth_destroy(auth)             \
+               ((*((auth)->ah_ops->ah_destroy))(auth))
+
+
+extern struct opaque_auth _null_auth;
+
+
+/*
+ * These are the various implementations of client side authenticators.
+ */
+
+/*
+ * Unix style authentication
+ * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
+ *     char *machname;
+ *     int uid;
+ *     int gid;
+ *     int len;
+ *     int *aup_gids;
+ */
+extern AUTH *authunix_create();
+extern AUTH *authunix_create_default();        /* takes no parameters */
+extern AUTH *authnone_create();                /* takes no parameters */
+extern AUTH *authdes_create();
+
+#define AUTH_NONE      0               /* no authentication */
+#define        AUTH_NULL       0               /* backward compatibility */
+#define        AUTH_UNIX       1               /* unix style (uid, gids) */
+#define        AUTH_SHORT      2               /* short hand unix style */
+#define AUTH_DES       3               /* des style (encrypted timestamps) */
diff --git a/include/rpc/auth_des.h b/include/rpc/auth_des.h
new file mode 100644 (file)
index 0000000..8c2f794
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (C) 1996, 1997 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.  */
+
+#ifndef _RPC_AUTH_DES_H
+
+#define _RPC_AUTH_DES_H        1
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/* This is no complete version of this header.  More definitions with
+   the real authentication stuff will come in 1997.  For now we only
+   need to define the function for handling public keys.  */
+
+
+/* Get the public key for NAME and place it in KEY.  NAME can only be
+   up to MAXNETNAMELEN bytes long and the destination buffer KEY should
+   have HEXKEYBATES + 1 bytes long to fit all characters from the key.  */
+extern int getpublickey __P ((__const char *__name, char *__key));
+
+/* Get the secret key for NAME and place it in KEY.  PASSWD is used to
+   decrypt the encrypted key stored in the database.  NAME can only be
+   up to MAXNETNAMELEN bytes long and the destination buffer KEY
+   should have HEXKEYBATES + 1 bytes long to fit all characters from
+   the key.  */
+extern int getsecretkey __P ((__const char *__name, char *__key,
+                             __const char *__passwd));
+
+__END_DECLS
+
+#endif /* rpc/auth_des.h */
diff --git a/include/rpc/auth_unix.h b/include/rpc/auth_unix.h
new file mode 100644 (file)
index 0000000..705741e
--- /dev/null
@@ -0,0 +1,72 @@
+/* @(#)auth_unix.h     2.2 88/07/29 4.0 RPCSRC; from 1.8 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)auth_unix.h 1.5 86/07/16 SMI      */
+
+/*
+ * auth_unix.h, Protocol for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * The system is very weak.  The client uses no encryption for  it
+ * credentials and only sends null verifiers.  The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ */
+
+/* The machine name is part of a credential; it may not exceed 255 bytes */
+#define MAX_MACHINE_NAME 255
+
+/* gids compose part of a credential; there may not be more than 16 of them */
+#define NGRPS 16
+
+/*
+ * Unix style credentials.
+ */
+struct authunix_parms {
+       u_long   aup_time;
+       char    *aup_machname;
+       int      aup_uid;
+       int      aup_gid;
+       u_int    aup_len;
+       int     *aup_gids;
+};
+
+extern bool_t xdr_authunix_parms();
+
+/* 
+ * If a response verifier has flavor AUTH_SHORT, 
+ * then the body of the response verifier encapsulates the following structure;
+ * again it is serialized in the obvious fashion.
+ */
+struct short_hand_verf {
+       struct opaque_auth new_cred;
+};
diff --git a/include/rpc/clnt.h b/include/rpc/clnt.h
new file mode 100644 (file)
index 0000000..8c002a1
--- /dev/null
@@ -0,0 +1,331 @@
+/* @(#)clnt.h  2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * clnt.h - Client side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _CLNT_
+#define _CLNT_
+
+/*
+ * Rpc calls return an enum clnt_stat.  This should be looked at more,
+ * since each implementation is required to live with this (implementation
+ * independent) list of errors.
+ */
+enum clnt_stat {
+       RPC_SUCCESS=0,                  /* call succeeded */
+       /*
+        * local errors
+        */
+       RPC_CANTENCODEARGS=1,           /* can't encode arguments */
+       RPC_CANTDECODERES=2,            /* can't decode results */
+       RPC_CANTSEND=3,                 /* failure in sending call */
+       RPC_CANTRECV=4,                 /* failure in receiving result */
+       RPC_TIMEDOUT=5,                 /* call timed out */
+       /*
+        * remote errors
+        */
+       RPC_VERSMISMATCH=6,             /* rpc versions not compatible */
+       RPC_AUTHERROR=7,                /* authentication error */
+       RPC_PROGUNAVAIL=8,              /* program not available */
+       RPC_PROGVERSMISMATCH=9,         /* program version mismatched */
+       RPC_PROCUNAVAIL=10,             /* procedure unavailable */
+       RPC_CANTDECODEARGS=11,          /* decode arguments error */
+       RPC_SYSTEMERROR=12,             /* generic "other problem" */
+
+       /*
+        * callrpc & clnt_create errors
+        */
+       RPC_UNKNOWNHOST=13,             /* unknown host name */
+       RPC_UNKNOWNPROTO=17,            /* unkown protocol */
+
+       /*
+        * _ create errors
+        */
+       RPC_PMAPFAILURE=14,             /* the pmapper failed in its call */
+       RPC_PROGNOTREGISTERED=15,       /* remote program is not registered */
+       /*
+        * unspecified error
+        */
+       RPC_FAILED=16
+};
+
+
+/*
+ * Error info.
+ */
+struct rpc_err {
+       enum clnt_stat re_status;
+       union {
+               int RE_errno;           /* realated system error */
+               enum auth_stat RE_why;  /* why the auth error occurred */
+               struct {
+                       u_long low;     /* lowest verion supported */
+                       u_long high;    /* highest verion supported */
+               } RE_vers;
+               struct {                /* maybe meaningful if RPC_FAILED */
+                       long s1;
+                       long s2;
+               } RE_lb;                /* life boot & debugging only */
+       } ru;
+#define        re_errno        ru.RE_errno
+#define        re_why          ru.RE_why
+#define        re_vers         ru.RE_vers
+#define        re_lb           ru.RE_lb
+};
+
+
+/*
+ * Client rpc handle.
+ * Created by individual implementations, see e.g. rpc_udp.c.
+ * Client is responsible for initializing auth, see e.g. auth_none.c.
+ */
+typedef struct {
+       AUTH    *cl_auth;                       /* authenticator */
+       struct clnt_ops {
+               enum clnt_stat  (*cl_call)();   /* call remote procedure */
+               void            (*cl_abort)();  /* abort a call */
+               void            (*cl_geterr)(); /* get specific error code */
+               bool_t          (*cl_freeres)(); /* frees results */
+               void            (*cl_destroy)();/* destroy this structure */
+               bool_t          (*cl_control)();/* the ioctl() of rpc */
+       } *cl_ops;
+       caddr_t                 cl_private;     /* private stuff */
+} CLIENT;
+
+
+/*
+ * client side rpc interface ops
+ *
+ * Parameter types are:
+ *
+ */
+
+/*
+ * enum clnt_stat
+ * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
+ *     CLIENT *rh;
+ *     u_long proc;
+ *     xdrproc_t xargs;
+ *     caddr_t argsp;
+ *     xdrproc_t xres;
+ *     caddr_t resp;
+ *     struct timeval timeout;
+ */
+#define        CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)     \
+       ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+#define        clnt_call(rh, proc, xargs, argsp, xres, resp, secs)     \
+       ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+
+/*
+ * void
+ * CLNT_ABORT(rh);
+ *     CLIENT *rh;
+ */
+#define        CLNT_ABORT(rh)  ((*(rh)->cl_ops->cl_abort)(rh))
+#define        clnt_abort(rh)  ((*(rh)->cl_ops->cl_abort)(rh))
+
+/*
+ * struct rpc_err
+ * CLNT_GETERR(rh);
+ *     CLIENT *rh;
+ */
+#define        CLNT_GETERR(rh,errp)    ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+#define        clnt_geterr(rh,errp)    ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+
+
+/*
+ * bool_t
+ * CLNT_FREERES(rh, xres, resp);
+ *     CLIENT *rh;
+ *     xdrproc_t xres;
+ *     caddr_t resp;
+ */
+#define        CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+#define        clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+
+/*
+ * bool_t
+ * CLNT_CONTROL(cl, request, info)
+ *      CLIENT *cl;
+ *      u_int request;
+ *      char *info;
+ */
+#define        CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+#define        clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+
+/*
+ * control operations that apply to both udp and tcp transports
+ */
+#define CLSET_TIMEOUT       1   /* set timeout (timeval) */
+#define CLGET_TIMEOUT       2   /* get timeout (timeval) */
+#define CLGET_SERVER_ADDR   3   /* get server's address (sockaddr) */
+/*
+ * udp only control operations
+ */
+#define CLSET_RETRY_TIMEOUT 4   /* set retry timeout (timeval) */
+#define CLGET_RETRY_TIMEOUT 5   /* get retry timeout (timeval) */
+
+/*
+ * void
+ * CLNT_DESTROY(rh);
+ *     CLIENT *rh;
+ */
+#define        CLNT_DESTROY(rh)        ((*(rh)->cl_ops->cl_destroy)(rh))
+#define        clnt_destroy(rh)        ((*(rh)->cl_ops->cl_destroy)(rh))
+
+
+/*
+ * RPCTEST is a test program which is accessable on every rpc
+ * transport/port.  It is used for testing, performance evaluation,
+ * and network administration.
+ */
+
+#define RPCTEST_PROGRAM                ((u_long)1)
+#define RPCTEST_VERSION                ((u_long)1)
+#define RPCTEST_NULL_PROC      ((u_long)2)
+#define RPCTEST_NULL_BATCH_PROC        ((u_long)3)
+
+/*
+ * By convention, procedure 0 takes null arguments and returns them
+ */
+
+#define NULLPROC ((u_long)0)
+
+/*
+ * Below are the client handle creation routines for the various
+ * implementations of client side rpc.  They can return NULL if a 
+ * creation failure occurs.
+ */
+
+/*
+ * Memory based rpc (for speed check and testing)
+ * CLIENT *
+ * clntraw_create(prog, vers)
+ *     u_long prog;
+ *     u_long vers;
+ */
+extern CLIENT *clntraw_create();
+
+
+/*
+ * Generic client creation routine. Supported protocols are "udp" and "tcp"
+ */
+extern CLIENT *
+clnt_create(/*host, prog, vers, prot*/); /*
+       char *host;     -- hostname
+       u_long prog;    -- program number
+       u_long vers;    -- version number
+       char *prot;     -- protocol
+*/
+
+
+
+
+/*
+ * TCP based rpc
+ * CLIENT *
+ * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ *     struct sockaddr_in *raddr;
+ *     u_long prog;
+ *     u_long version;
+ *     register int *sockp;
+ *     u_int sendsz;
+ *     u_int recvsz;
+ */
+extern CLIENT *clnttcp_create();
+
+/*
+ * UDP based rpc.
+ * CLIENT *
+ * clntudp_create(raddr, program, version, wait, sockp)
+ *     struct sockaddr_in *raddr;
+ *     u_long program;
+ *     u_long version;
+ *     struct timeval wait;
+ *     int *sockp;
+ *
+ * Same as above, but you specify max packet sizes.
+ * CLIENT *
+ * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+ *     struct sockaddr_in *raddr;
+ *     u_long program;
+ *     u_long version;
+ *     struct timeval wait;
+ *     int *sockp;
+ *     u_int sendsz;
+ *     u_int recvsz;
+ */
+extern CLIENT *clntudp_create();
+extern CLIENT *clntudp_bufcreate();
+
+/*
+ * Print why creation failed
+ */
+void clnt_pcreateerror(/* char *msg */);       /* stderr */
+char *clnt_spcreateerror(/* char *msg */);     /* string */
+
+/*
+ * Like clnt_perror(), but is more verbose in its output
+ */ 
+void clnt_perrno(/* enum clnt_stat num */);    /* stderr */
+
+/*
+ * Print an English error message, given the client error code
+ */
+void clnt_perror(/* CLIENT *clnt, char *msg */);       /* stderr */
+char *clnt_sperror(/* CLIENT *clnt, char *msg */);     /* string */
+
+/* 
+ * If a creation fails, the following allows the user to figure out why.
+ */
+struct rpc_createerr {
+       enum clnt_stat cf_stat;
+       struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
+};
+
+extern struct rpc_createerr rpc_createerr;
+
+
+
+/*
+ * Copy error message to buffer.
+ */
+char *clnt_sperrno(/* enum clnt_stat num */);  /* string */
+
+
+
+#define UDPMSGSIZE     8800    /* rpc imposed limit on udp msg size */
+#define RPCSMALLMSGSIZE        400     /* a more reasonable packet size */
+
+#endif /*!_CLNT_*/
diff --git a/include/rpc/pmap_clnt.h b/include/rpc/pmap_clnt.h
new file mode 100644 (file)
index 0000000..d2ea2a8
--- /dev/null
@@ -0,0 +1,65 @@
+/* @(#)pmap_clnt.h     2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * pmap_clnt.h
+ * Supplies C routines to get to portmap services.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * Usage:
+ *     success = pmap_set(program, version, protocol, port);
+ *     success = pmap_unset(program, version);
+ *     port = pmap_getport(address, program, version, protocol);
+ *     head = pmap_getmaps(address);
+ *     clnt_stat = pmap_rmtcall(address, program, version, procedure,
+ *             xdrargs, argsp, xdrres, resp, tout, port_ptr)
+ *             (works for udp only.) 
+ *     clnt_stat = clnt_broadcast(program, version, procedure,
+ *             xdrargs, argsp, xdrres, resp, eachresult)
+ *             (like pmap_rmtcall, except the call is broadcasted to all
+ *             locally connected nets.  For each valid response received,
+ *             the procedure eachresult is called.  Its form is:
+ *     done = eachresult(resp, raddr)
+ *             bool_t done;
+ *             caddr_t resp;
+ *             struct sockaddr_in raddr;
+ *             where resp points to the results of the call and raddr is the
+ *             address if the responder to the broadcast.
+ */
+
+extern bool_t          pmap_set();
+extern bool_t          pmap_unset();
+extern struct pmaplist *pmap_getmaps();
+enum clnt_stat         pmap_rmtcall();
+enum clnt_stat         clnt_broadcast();
+extern u_short         pmap_getport();
diff --git a/include/rpc/pmap_prot.h b/include/rpc/pmap_prot.h
new file mode 100644 (file)
index 0000000..ccf7a77
--- /dev/null
@@ -0,0 +1,94 @@
+/* @(#)pmap_prot.h     2.1 88/07/29 4.0 RPCSRC; from 1.14 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * pmap_prot.h
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The following procedures are supported by the protocol:
+ *
+ * PMAPPROC_NULL() returns ()
+ *     takes nothing, returns nothing
+ *
+ * PMAPPROC_SET(struct pmap) returns (bool_t)
+ *     TRUE is success, FALSE is failure.  Registers the tuple
+ *     [prog, vers, prot, port].
+ *
+ * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+ *     TRUE is success, FALSE is failure.  Un-registers pair
+ *     [prog, vers].  prot and port are ignored.
+ *
+ * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+ *     0 is failure.  Otherwise returns the port number where the pair
+ *     [prog, vers] is registered.  It may lie!
+ *
+ * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
+ *
+ * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+ *     RETURNS (port, string<>);
+ * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
+ *     Calls the procedure on the local machine.  If it is not registered,
+ *     this procedure is quite; ie it does not return error information!!!
+ *     This procedure only is supported on rpc/udp and calls via
+ *     rpc/udp.  This routine only passes null authentication parameters.
+ *     This file has no interface to xdr routines for PMAPPROC_CALLIT.
+ *
+ * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+ */
+
+#define PMAPPORT               ((u_short)111)
+#define PMAPPROG               ((u_long)100000)
+#define PMAPVERS               ((u_long)2)
+#define PMAPVERS_PROTO         ((u_long)2)
+#define PMAPVERS_ORIG          ((u_long)1)
+#define PMAPPROC_NULL          ((u_long)0)
+#define PMAPPROC_SET           ((u_long)1)
+#define PMAPPROC_UNSET         ((u_long)2)
+#define PMAPPROC_GETPORT       ((u_long)3)
+#define PMAPPROC_DUMP          ((u_long)4)
+#define PMAPPROC_CALLIT                ((u_long)5)
+
+struct pmap {
+       long unsigned pm_prog;
+       long unsigned pm_vers;
+       long unsigned pm_prot;
+       long unsigned pm_port;
+};
+
+extern bool_t xdr_pmap();
+
+struct pmaplist {
+       struct pmap     pml_map;
+       struct pmaplist *pml_next;
+};
+
+extern bool_t xdr_pmaplist();
diff --git a/include/rpc/pmap_rmt.h b/include/rpc/pmap_rmt.h
new file mode 100644 (file)
index 0000000..ee68ceb
--- /dev/null
@@ -0,0 +1,53 @@
+/* @(#)pmap_rmt.h      2.1 88/07/29 4.0 RPCSRC; from 1.2 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Structures and XDR routines for parameters to and replies from
+ * the portmapper remote-call-service.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+struct rmtcallargs {
+       u_long prog, vers, proc, arglen;
+       caddr_t args_ptr;
+       xdrproc_t xdr_args;
+};
+
+bool_t xdr_rmtcall_args();
+
+struct rmtcallres {
+       u_long *port_ptr;
+       u_long resultslen;
+       caddr_t results_ptr;
+       xdrproc_t xdr_results;
+};
+
+bool_t xdr_rmtcallres();
diff --git a/include/rpc/rpc.h b/include/rpc/rpc.h
new file mode 100644 (file)
index 0000000..b7d50d2
--- /dev/null
@@ -0,0 +1,79 @@
+/* @(#)rpc.h   2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * rpc.h, Just includes the billions of rpc header files necessary to
+ * do remote procedure calling.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+#ifndef __RPC_HEADER__
+#define __RPC_HEADER__
+
+#ifdef linux
+#include <sys/time.h>
+#endif
+
+#include <rpc/types.h>         /* some typedefs */
+#include <netinet/in.h>
+
+/* external data representation interfaces */
+#include <rpc/xdr.h>           /* generic (de)serializer */
+
+/* Client side only authentication */
+#include <rpc/auth.h>          /* generic authenticator (client side) */
+
+/* Client side (mostly) remote procedure call */
+#include <rpc/clnt.h>          /* generic rpc stuff */
+
+/* semi-private protocol headers */
+#include <rpc/rpc_msg.h>       /* protocol for rpc messages */
+#include <rpc/auth_unix.h>     /* protocol for unix style cred */
+/*
+ *  Uncomment-out the next line if you are building the rpc library with    
+ *  DES Authentication (see the README file in the secure_rpc/ directory).
+ */
+/*#include <rpc/auth_des.h>    /* protocol for des style cred */
+
+/* Server side only remote procedure callee */
+#include <rpc/svc.h>           /* service manager and multiplexer */
+#include <rpc/svc_auth.h>      /* service side authenticator */
+
+/*
+ * COMMENT OUT THE NEXT INCLUDE IF RUNNING ON SUN OS OR ON A VERSION
+ * OF UNIX BASED ON NFSSRC.  These systems will already have the structures
+ * defined by <rpc/netdb.h> included in <netdb.h>.
+ */
+/* routines for parsing /etc/rpc */
+#if 0
+#include <rpc/netdb.h>         /* structures and routines to parse /etc/rpc */
+#endif
+
+#endif /* ndef __RPC_HEADER__ */
diff --git a/include/rpc/rpc_msg.h b/include/rpc/rpc_msg.h
new file mode 100644 (file)
index 0000000..b78872b
--- /dev/null
@@ -0,0 +1,187 @@
+/* @(#)rpc_msg.h       2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)rpc_msg.h 1.7 86/07/16 SMI      */
+
+/*
+ * rpc_msg.h
+ * rpc message definition
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#define RPC_MSG_VERSION                ((u_long) 2)
+#define RPC_SERVICE_PORT       ((u_short) 2048)
+
+/*
+ * Bottom up definition of an rpc message.
+ * NOTE: call and reply use the same overall stuct but
+ * different parts of unions within it.
+ */
+
+enum msg_type {
+       CALL=0,
+       REPLY=1
+};
+
+enum reply_stat {
+       MSG_ACCEPTED=0,
+       MSG_DENIED=1
+};
+
+enum accept_stat {
+       SUCCESS=0,
+       PROG_UNAVAIL=1,
+       PROG_MISMATCH=2,
+       PROC_UNAVAIL=3,
+       GARBAGE_ARGS=4,
+       SYSTEM_ERR=5
+};
+
+enum reject_stat {
+       RPC_MISMATCH=0,
+       AUTH_ERROR=1
+};
+
+/*
+ * Reply part of an rpc exchange
+ */
+
+/*
+ * Reply to an rpc request that was accepted by the server.
+ * Note: there could be an error even though the request was
+ * accepted.
+ */
+struct accepted_reply {
+       struct opaque_auth      ar_verf;
+       enum accept_stat        ar_stat;
+       union {
+               struct {
+                       u_long  low;
+                       u_long  high;
+               } AR_versions;
+               struct {
+                       caddr_t where;
+                       xdrproc_t proc;
+               } AR_results;
+               /* and many other null cases */
+       } ru;
+#define        ar_results      ru.AR_results
+#define        ar_vers         ru.AR_versions
+};
+
+/*
+ * Reply to an rpc request that was rejected by the server.
+ */
+struct rejected_reply {
+       enum reject_stat rj_stat;
+       union {
+               struct {
+                       u_long low;
+                       u_long high;
+               } RJ_versions;
+               enum auth_stat RJ_why;  /* why authentication did not work */
+       } ru;
+#define        rj_vers ru.RJ_versions
+#define        rj_why  ru.RJ_why
+};
+
+/*
+ * Body of a reply to an rpc request.
+ */
+struct reply_body {
+       enum reply_stat rp_stat;
+       union {
+               struct accepted_reply RP_ar;
+               struct rejected_reply RP_dr;
+       } ru;
+#define        rp_acpt ru.RP_ar
+#define        rp_rjct ru.RP_dr
+};
+
+/*
+ * Body of an rpc request call.
+ */
+struct call_body {
+       u_long cb_rpcvers;      /* must be equal to two */
+       u_long cb_prog;
+       u_long cb_vers;
+       u_long cb_proc;
+       struct opaque_auth cb_cred;
+       struct opaque_auth cb_verf; /* protocol specific - provided by client */
+};
+
+/*
+ * The rpc message
+ */
+struct rpc_msg {
+       u_long                  rm_xid;
+       enum msg_type           rm_direction;
+       union {
+               struct call_body RM_cmb;
+               struct reply_body RM_rmb;
+       } ru;
+#define        rm_call         ru.RM_cmb
+#define        rm_reply        ru.RM_rmb
+};
+#define        acpted_rply     ru.RM_rmb.ru.RP_ar
+#define        rjcted_rply     ru.RM_rmb.ru.RP_dr
+
+
+/*
+ * XDR routine to handle a rpc message.
+ * xdr_callmsg(xdrs, cmsg)
+ *     XDR *xdrs;
+ *     struct rpc_msg *cmsg;
+ */
+extern bool_t  xdr_callmsg();
+
+/*
+ * XDR routine to pre-serialize the static part of a rpc message.
+ * xdr_callhdr(xdrs, cmsg)
+ *     XDR *xdrs;
+ *     struct rpc_msg *cmsg;
+ */
+extern bool_t  xdr_callhdr();
+
+/*
+ * XDR routine to handle a rpc reply.
+ * xdr_replymsg(xdrs, rmsg)
+ *     XDR *xdrs;
+ *     struct rpc_msg *rmsg;
+ */
+extern bool_t  xdr_replymsg();
+
+/*
+ * Fills in the error part of a reply message.
+ * _seterr_reply(msg, error)
+ *     struct rpc_msg *msg;
+ *     struct rpc_err *error;
+ */
+extern void    _seterr_reply();
diff --git a/include/rpc/svc.h b/include/rpc/svc.h
new file mode 100644 (file)
index 0000000..3cb07ef
--- /dev/null
@@ -0,0 +1,280 @@
+/* @(#)svc.h   2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * svc.h, Server-side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef __SVC_HEADER__
+#define __SVC_HEADER__
+
+/*
+ * This interface must manage two items concerning remote procedure calling:
+ *
+ * 1) An arbitrary number of transport connections upon which rpc requests
+ * are received.  The two most notable transports are TCP and UDP;  they are
+ * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
+ * they in turn call xprt_register and xprt_unregister.
+ *
+ * 2) An arbitrary number of locally registered services.  Services are
+ * described by the following four data: program number, version number,
+ * "service dispatch" function, a transport handle, and a boolean that
+ * indicates whether or not the exported program should be registered with a
+ * local binder service;  if true the program's number and version and the
+ * port number from the transport handle are registered with the binder.
+ * These data are registered with the rpc svc system via svc_register.
+ *
+ * A service's dispatch function is called whenever an rpc request comes in
+ * on a transport.  The request's program and version numbers must match
+ * those of the registered service.  The dispatch function is passed two
+ * parameters, struct svc_req * and SVCXPRT *, defined below.
+ */
+
+enum xprt_stat {
+       XPRT_DIED,
+       XPRT_MOREREQS,
+       XPRT_IDLE
+};
+
+/*
+ * Server side transport handle
+ */
+typedef struct {
+       int             xp_sock;
+       u_short         xp_port;         /* associated port number */
+       struct xp_ops {
+           bool_t      (*xp_recv)();    /* receive incomming requests */
+           enum xprt_stat (*xp_stat)(); /* get transport status */
+           bool_t      (*xp_getargs)(); /* get arguments */
+           bool_t      (*xp_reply)();   /* send reply */
+           bool_t      (*xp_freeargs)();/* free mem allocated for args */
+           void        (*xp_destroy)(); /* destroy this struct */
+       } *xp_ops;
+       int             xp_addrlen;      /* length of remote address */
+       struct sockaddr_in xp_raddr;     /* remote address */
+       struct opaque_auth xp_verf;      /* raw response verifier */
+       caddr_t         xp_p1;           /* private */
+       caddr_t         xp_p2;           /* private */
+} SVCXPRT;
+
+/*
+ *  Approved way of getting address of caller
+ */
+#define svc_getcaller(x) (&(x)->xp_raddr)
+
+/*
+ * Operations defined on an SVCXPRT handle
+ *
+ * SVCXPRT             *xprt;
+ * struct rpc_msg      *msg;
+ * xdrproc_t            xargs;
+ * caddr_t              argsp;
+ */
+#define SVC_RECV(xprt, msg)                            \
+       (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+#define svc_recv(xprt, msg)                            \
+       (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+
+#define SVC_STAT(xprt)                                 \
+       (*(xprt)->xp_ops->xp_stat)(xprt)
+#define svc_stat(xprt)                                 \
+       (*(xprt)->xp_ops->xp_stat)(xprt)
+
+#define SVC_GETARGS(xprt, xargs, argsp)                        \
+       (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+#define svc_getargs(xprt, xargs, argsp)                        \
+       (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+
+#define SVC_REPLY(xprt, msg)                           \
+       (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+#define svc_reply(xprt, msg)                           \
+       (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+
+#define SVC_FREEARGS(xprt, xargs, argsp)               \
+       (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+#define svc_freeargs(xprt, xargs, argsp)               \
+       (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+
+#define SVC_DESTROY(xprt)                              \
+       (*(xprt)->xp_ops->xp_destroy)(xprt)
+#define svc_destroy(xprt)                              \
+       (*(xprt)->xp_ops->xp_destroy)(xprt)
+
+
+/*
+ * Service request
+ */
+struct svc_req {
+       u_long          rq_prog;        /* service program number */
+       u_long          rq_vers;        /* service protocol version */
+       u_long          rq_proc;        /* the desired procedure */
+       struct opaque_auth rq_cred;     /* raw creds from the wire */
+       caddr_t         rq_clntcred;    /* read only cooked cred */
+       SVCXPRT *rq_xprt;               /* associated transport */
+};
+
+
+/*
+ * Service registration
+ *
+ * svc_register(xprt, prog, vers, dispatch, protocol)
+ *     SVCXPRT *xprt;
+ *     u_long prog;
+ *     u_long vers;
+ *     void (*dispatch)();
+ *     int protocol;  /* like TCP or UDP, zero means do not register 
+ */
+extern bool_t  svc_register();
+
+/*
+ * Service un-registration
+ *
+ * svc_unregister(prog, vers)
+ *     u_long prog;
+ *     u_long vers;
+ */
+extern void    svc_unregister();
+
+/*
+ * Transport registration.
+ *
+ * xprt_register(xprt)
+ *     SVCXPRT *xprt;
+ */
+extern void    xprt_register();
+
+/*
+ * Transport un-register
+ *
+ * xprt_unregister(xprt)
+ *     SVCXPRT *xprt;
+ */
+extern void    xprt_unregister();
+
+
+
+
+/*
+ * When the service routine is called, it must first check to see if it
+ * knows about the procedure;  if not, it should call svcerr_noproc
+ * and return.  If so, it should deserialize its arguments via 
+ * SVC_GETARGS (defined above).  If the deserialization does not work,
+ * svcerr_decode should be called followed by a return.  Successful
+ * decoding of the arguments should be followed the execution of the
+ * procedure's code and a call to svc_sendreply.
+ *
+ * Also, if the service refuses to execute the procedure due to too-
+ * weak authentication parameters, svcerr_weakauth should be called.
+ * Note: do not confuse access-control failure with weak authentication!
+ *
+ * NB: In pure implementations of rpc, the caller always waits for a reply
+ * msg.  This message is sent when svc_sendreply is called.  
+ * Therefore pure service implementations should always call
+ * svc_sendreply even if the function logically returns void;  use
+ * xdr.h - xdr_void for the xdr routine.  HOWEVER, tcp based rpc allows
+ * for the abuse of pure rpc via batched calling or pipelining.  In the
+ * case of a batched call, svc_sendreply should NOT be called since
+ * this would send a return message, which is what batching tries to avoid.
+ * It is the service/protocol writer's responsibility to know which calls are
+ * batched and which are not.  Warning: responding to batch calls may
+ * deadlock the caller and server processes!
+ */
+
+extern bool_t  svc_sendreply();
+extern void    svcerr_decode();
+extern void    svcerr_weakauth();
+extern void    svcerr_noproc();
+extern void    svcerr_progvers();
+extern void    svcerr_auth();
+extern void    svcerr_noprog();
+extern void    svcerr_systemerr();
+    
+/*
+ * Lowest level dispatching -OR- who owns this process anyway.
+ * Somebody has to wait for incoming requests and then call the correct
+ * service routine.  The routine svc_run does infinite waiting; i.e.,
+ * svc_run never returns.
+ * Since another (co-existant) package may wish to selectively wait for
+ * incoming calls or other events outside of the rpc architecture, the
+ * routine svc_getreq is provided.  It must be passed readfds, the
+ * "in-place" results of a select system call (see select, section 2).
+ */
+
+/*
+ * Global keeper of rpc service descriptors in use
+ * dynamic; must be inspected before each call to select 
+ */
+#ifdef FD_SETSIZE
+extern fd_set svc_fdset;
+#define svc_fds svc_fdset.fds_bits[0]  /* compatibility */
+#else
+extern int svc_fds;
+#endif /* def FD_SETSIZE */
+
+/*
+ * a small program implemented by the svc_rpc implementation itself;
+ * also see clnt.h for protocol numbers.
+ */
+extern void rpctest_service();
+
+extern void    svc_getreq();
+extern void    svc_getreqset();        /* takes fdset instead of int */
+extern void    svc_run();       /* never returns */
+
+/*
+ * Socket to use on svcxxx_create call to get default socket
+ */
+#define        RPC_ANYSOCK     -1
+
+/*
+ * These are the existing service side transport implementations
+ */
+
+/*
+ * Memory based rpc for testing and timing.
+ */
+extern SVCXPRT *svcraw_create();
+
+/*
+ * Udp based rpc.
+ */
+extern SVCXPRT *svcudp_create();
+extern SVCXPRT *svcudp_bufcreate();
+
+/*
+ * Tcp based rpc.
+ */
+extern SVCXPRT *svctcp_create();
+
+
+
+#endif !__SVC_HEADER__
diff --git a/include/rpc/svc_auth.h b/include/rpc/svc_auth.h
new file mode 100644 (file)
index 0000000..a36a01a
--- /dev/null
@@ -0,0 +1,42 @@
+/* @(#)svc_auth.h      2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)svc_auth.h 1.6 86/07/16 SMI      */
+
+/*
+ * svc_auth.h, Service side of rpc authentication.
+ * 
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+
+/*
+ * Server side authenticator
+ */
+extern enum auth_stat _authenticate();
diff --git a/include/rpc/types.h b/include/rpc/types.h
new file mode 100644 (file)
index 0000000..96d9242
--- /dev/null
@@ -0,0 +1,65 @@
+/* @(#)types.h 2.3 88/08/15 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)types.h 1.18 87/07/24 SMI      */
+
+/*
+ * Rpc additions to <sys/types.h>
+ */
+#ifndef __TYPES_RPC_HEADER__
+#define __TYPES_RPC_HEADER__
+
+#define        bool_t  int
+#define        enum_t  int
+#define        FALSE   (0)
+#define        TRUE    (1)
+#define __dontcare__   -1
+#ifndef NULL
+#      define NULL 0
+#endif
+
+#include <stdlib.h>
+#define mem_alloc(bsize)       malloc(bsize)
+#define mem_free(ptr, bsize)   free(ptr)
+
+#ifndef makedev /* ie, we haven't already included it */
+#include <sys/types.h>
+#endif
+#include <sys/time.h>
+
+#ifndef linux
+#ifndef INADDR_LOOPBACK
+#define       INADDR_LOOPBACK         (u_long)0x7F000001
+#endif
+#endif
+#ifndef MAXHOSTNAMELEN
+#define        MAXHOSTNAMELEN  64
+#endif
+
+#endif /* ndef __TYPES_RPC_HEADER__ */
diff --git a/include/rpc/xdr.h b/include/rpc/xdr.h
new file mode 100644 (file)
index 0000000..6cd3e6f
--- /dev/null
@@ -0,0 +1,270 @@
+/* @(#)xdr.h   2.2 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)xdr.h 1.19 87/04/22 SMI      */
+
+/*
+ * xdr.h, External Data Representation Serialization Routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef __XDR_HEADER__
+#define __XDR_HEADER__
+
+/*
+ * XDR provides a conventional way for converting between C data
+ * types and an external bit-string representation.  Library supplied
+ * routines provide for the conversion on built-in C data types.  These
+ * routines and utility routines defined here are used to help implement
+ * a type encode/decode routine for each user-defined type.
+ *
+ * Each data type provides a single procedure which takes two arguments:
+ *
+ *     bool_t
+ *     xdrproc(xdrs, argresp)
+ *             XDR *xdrs;
+ *             <type> *argresp;
+ *
+ * xdrs is an instance of a XDR handle, to which or from which the data
+ * type is to be converted.  argresp is a pointer to the structure to be
+ * converted.  The XDR handle contains an operation field which indicates
+ * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
+ *
+ * XDR_DECODE may allocate space if the pointer argresp is null.  This
+ * data can be freed with the XDR_FREE operation.
+ *
+ * We write only one procedure per data type to make it easy
+ * to keep the encode and decode procedures for a data type consistent.
+ * In many cases the same code performs all operations on a user defined type,
+ * because all the hard work is done in the component type routines.
+ * decode as a series of calls on the nested data types.
+ */
+
+/*
+ * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
+ * stream.  XDR_DECODE causes the type to be extracted from the stream.
+ * XDR_FREE can be used to release the space allocated by an XDR_DECODE
+ * request.
+ */
+enum xdr_op {
+       XDR_ENCODE=0,
+       XDR_DECODE=1,
+       XDR_FREE=2
+};
+
+/*
+ * This is the number of bytes per unit of external data.
+ */
+#define BYTES_PER_XDR_UNIT     (4)
+#define RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
+                   * BYTES_PER_XDR_UNIT)
+
+/*
+ * A xdrproc_t exists for each data type which is to be encoded or decoded.
+ *
+ * The second argument to the xdrproc_t is a pointer to an opaque pointer.
+ * The opaque pointer generally points to a structure of the data type
+ * to be decoded.  If this pointer is 0, then the type routines should
+ * allocate dynamic storage of the appropriate size and return it.
+ * bool_t      (*xdrproc_t)(XDR *, caddr_t *);
+ */
+typedef        bool_t (*xdrproc_t)();
+
+/*
+ * The XDR handle.
+ * Contains operation which is being applied to the stream,
+ * an operations vector for the paticular implementation (e.g. see xdr_mem.c),
+ * and two private fields for the use of the particular impelementation.
+ */
+typedef struct {
+       enum xdr_op     x_op;           /* operation; fast additional param */
+       struct xdr_ops {
+               bool_t  (*x_getlong)(); /* get a long from underlying stream */
+               bool_t  (*x_putlong)(); /* put a long to " */
+               bool_t  (*x_getbytes)();/* get some bytes from " */
+               bool_t  (*x_putbytes)();/* put some bytes to " */
+               u_int   (*x_getpostn)();/* returns bytes off from beginning */
+               bool_t  (*x_setpostn)();/* lets you reposition the stream */
+               long *  (*x_inline)();  /* buf quick ptr to buffered data */
+               void    (*x_destroy)(); /* free privates of this xdr_stream */
+       } *x_ops;
+       caddr_t         x_public;       /* users' data */
+       caddr_t         x_private;      /* pointer to private data */
+       caddr_t         x_base;         /* private used for position info */
+       int             x_handy;        /* extra private word */
+} XDR;
+
+/*
+ * Operations defined on a XDR handle
+ *
+ * XDR         *xdrs;
+ * long                *longp;
+ * caddr_t      addr;
+ * u_int        len;
+ * u_int        pos;
+ */
+#define XDR_GETLONG(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+#define xdr_getlong(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+
+#define XDR_PUTLONG(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+#define xdr_putlong(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+
+#define XDR_GETBYTES(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+#define xdr_getbytes(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+
+#define XDR_PUTBYTES(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+#define xdr_putbytes(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+
+#define XDR_GETPOS(xdrs)                               \
+       (*(xdrs)->x_ops->x_getpostn)(xdrs)
+#define xdr_getpos(xdrs)                               \
+       (*(xdrs)->x_ops->x_getpostn)(xdrs)
+
+#define XDR_SETPOS(xdrs, pos)                          \
+       (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+#define xdr_setpos(xdrs, pos)                          \
+       (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+
+#define        XDR_INLINE(xdrs, len)                           \
+       (*(xdrs)->x_ops->x_inline)(xdrs, len)
+#define        xdr_inline(xdrs, len)                           \
+       (*(xdrs)->x_ops->x_inline)(xdrs, len)
+
+#define        XDR_DESTROY(xdrs)                               \
+       if ((xdrs)->x_ops->x_destroy)                   \
+               (*(xdrs)->x_ops->x_destroy)(xdrs)
+#define        xdr_destroy(xdrs)                               \
+       if ((xdrs)->x_ops->x_destroy)                   \
+               (*(xdrs)->x_ops->x_destroy)(xdrs)
+
+/*
+ * Support struct for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * a entry with a null procedure pointer.  The xdr_union routine gets
+ * the discriminant value and then searches the array of structures
+ * for a matching value.  If a match is found the associated xdr routine
+ * is called to handle that part of the union.  If there is
+ * no match, then a default routine may be called.
+ * If there is no match and no default routine it is an error.
+ */
+#define NULL_xdrproc_t ((xdrproc_t)0)
+struct xdr_discrim {
+       int     value;
+       xdrproc_t proc;
+};
+
+/*
+ * In-line routines for fast encode/decode of primitve data types.
+ * Caveat emptor: these use single memory cycles to get the
+ * data from the underlying buffer, and will fail to operate
+ * properly if the data is not aligned.  The standard way to use these
+ * is to say:
+ *     if ((buf = XDR_INLINE(xdrs, count)) == NULL)
+ *             return (FALSE);
+ *     <<< macro calls >>>
+ * where ``count'' is the number of bytes of data occupied
+ * by the primitive data types.
+ *
+ * N.B. and frozen for all time: each data type here uses 4 bytes
+ * of external representation.
+ */
+#define IXDR_GET_LONG(buf)             ((long)ntohl((u_long)*(buf)++))
+#define IXDR_PUT_LONG(buf, v)          (*(buf)++ = (long)htonl((u_long)v))
+
+#define IXDR_GET_BOOL(buf)             ((bool_t)IXDR_GET_LONG(buf))
+#define IXDR_GET_ENUM(buf, t)          ((t)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_LONG(buf)           ((u_long)IXDR_GET_LONG(buf))
+#define IXDR_GET_SHORT(buf)            ((short)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_SHORT(buf)          ((u_short)IXDR_GET_LONG(buf))
+
+#define IXDR_PUT_BOOL(buf, v)          IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_ENUM(buf, v)          IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_U_LONG(buf, v)                IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_SHORT(buf, v)         IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_U_SHORT(buf, v)       IXDR_PUT_LONG((buf), ((long)(v)))
+
+/*
+ * These are the "generic" xdr routines.
+ */
+extern bool_t  xdr_void();
+extern bool_t  xdr_int();
+extern bool_t  xdr_u_int();
+extern bool_t  xdr_long();
+extern bool_t  xdr_u_long();
+extern bool_t  xdr_short();
+extern bool_t  xdr_u_short();
+extern bool_t  xdr_bool();
+extern bool_t  xdr_enum();
+extern bool_t  xdr_array();
+extern bool_t  xdr_bytes();
+extern bool_t  xdr_opaque();
+extern bool_t  xdr_string();
+extern bool_t  xdr_union();
+extern bool_t  xdr_char();
+extern bool_t  xdr_u_char();
+extern bool_t  xdr_vector();
+extern bool_t  xdr_float();
+extern bool_t  xdr_double();
+extern bool_t  xdr_reference();
+extern bool_t  xdr_pointer();
+extern bool_t  xdr_wrapstring();
+
+/*
+ * Common opaque bytes objects used by many rpc protocols;
+ * declared here due to commonality.
+ */
+#define MAX_NETOBJ_SZ 1024 
+struct netobj {
+       u_int   n_len;
+       char    *n_bytes;
+};
+typedef struct netobj netobj;
+extern bool_t   xdr_netobj();
+
+/*
+ * These are the public routines for the various implementations of
+ * xdr streams.
+ */
+extern void   xdrmem_create();         /* XDR using memory buffers */
+extern void   xdrstdio_create();       /* XDR using stdio library */
+extern void   xdrrec_create();         /* XDR pseudo records for tcp */
+extern bool_t xdrrec_endofrecord();    /* make end of xdr record */
+extern bool_t xdrrec_skiprecord();     /* move to beginning of next record */
+extern bool_t xdrrec_eof();            /* true if no more input */
+
+#endif !__XDR_HEADER__
diff --git a/include/search.h b/include/search.h
new file mode 100644 (file)
index 0000000..b9c8a17
--- /dev/null
@@ -0,0 +1,94 @@
+/* Copyright (C) 1993 Ulrich Drepper
+
+This file is intended to be included in the GNU C Library and the
+Linux C Library. So the copyright notice will be:
+
+
+Copyright (C) 1993 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.
+
+
+For now the file can be distributed under the LGPL.  */
+
+#ifndef _SEARCH_H
+#define _SEARCH_H
+
+#include <features.h>
+
+#define __need_size_t
+#define __need_NULL
+#include <stddef.h>
+
+__BEGIN_DECLS
+
+#ifndef __COMPAR_FN_T
+#define __COMPAR_FN_T
+typedef int (*__compar_fn_t) __P ((__const __ptr_t, __const __ptr_t));
+#endif
+
+/* for use with hsearch(3) */
+
+typedef struct entry { char *key; char *data; } ENTRY;
+typedef enum { FIND, ENTER } ACTION;
+
+extern ENTRY * hsearch __P((ENTRY __item, ACTION __action));
+extern int     hcreate __P((unsigned __nel));
+extern void    hdestroy __P((void));
+
+
+/* The tsearch routines are very interesting. They make many
+ * assumptions about the compiler. It assumpts that the first field
+ * in node must be the "key" field, which points to the datum.
+ * Everything depends on that. It is a very tricky stuff. H.J.
+ */
+/* For tsearch */
+typedef enum { preorder, postorder, endorder, leaf } VISIT;
+
+extern void *tsearch __P((__const void * __key, void **__rootp,
+               __compar_fn_t compar));
+
+extern void *tfind __P((__const void * __key, __const void ** __rootp,
+               __compar_fn_t compar));
+
+extern void *tdelete __P((__const void * __key, void ** __rootp,
+               __compar_fn_t compar));
+
+#ifndef __ACTION_FN_T
+#define __ACTION_FN_T
+/* FYI, the first argument should be a pointer to "key".
+ * Please read the man page for details.
+ */
+typedef void (*__action_fn_t) __P((__const void *__nodep,
+                                  __const VISIT __value,
+                                  __const int __level));
+#endif
+
+extern void twalk __P((__const void * __root, __action_fn_t action));
+
+
+extern void * lfind __P((__const void * __key, __const void * __base,
+                         size_t * __nmemb, size_t __size,
+                         __compar_fn_t __compar));
+
+extern void * lsearch __P((__const void * __key, __const void * __base,
+                         size_t * __nmemb, size_t __size,
+                         __compar_fn_t __compar));
+
+__END_DECLS
+
+#endif /* search.h */
diff --git a/include/setjmp.h b/include/setjmp.h
new file mode 100644 (file)
index 0000000..53d0223
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+       setjmp.h
+       stubs for future use.
+*/
+
+#ifndef _SETJMP_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define _SETJMP_H_
+
+#include "_ansi.h"
+#include <machine/setjmp.h>
+
+void   _EXFUN(longjmp,(jmp_buf __jmpb, int __retval));
+int    _EXFUN(setjmp,(jmp_buf __jmpb));
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _SETJMP_H_ */
+
diff --git a/include/signal.h b/include/signal.h
new file mode 100644 (file)
index 0000000..9daf0c0
--- /dev/null
@@ -0,0 +1,166 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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, 1992 Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/*
+ *     ANSI Standard: 4.7 SIGNAL HANDLING <signal.h>
+ */
+
+#ifndef _SIGNAL_H
+#define _SIGNAL_H
+
+#include <features.h>
+#include <sys/types.h>
+#include <linux/signal.h>
+
+#ifndef SIGCLD
+#define SIGCLD         SIGCHLD
+#endif
+
+/* SVR4 */
+#ifndef SA_RESETHAND
+#define SA_RESETHAND SA_ONESHOT
+#endif
+
+/* SVR4 */
+#ifndef SA_NODEFER
+#define SA_NODEFER SA_NOMASK
+#endif
+
+typedef int sig_atomic_t;
+
+typedef __sighandler_t SignalHandler;
+
+#ifndef BADSIG
+#define BADSIG         SIG_ERR
+#endif
+
+/* The Interviews version also has these ... */
+
+#define SignalBad      ((SignalHandler)-1)
+#define SignalDefault  ((SignalHandler)0)
+#define SignalIgnore   ((SignalHandler)1)
+
+__BEGIN_DECLS
+
+extern __const char * __const sys_siglist[];
+extern __const char * __const _sys_siglist[];
+
+extern __sighandler_t
+               signal __P ((int __sig, __sighandler_t));
+extern __sighandler_t
+               __signal __P ((int __sig, __sighandler_t, int flags));
+extern int     raise __P ((int __sig));
+extern int     __kill __P ((pid_t __pid, int __sig));
+extern int     kill __P ((pid_t __pid, int __sig));
+extern int     killpg __P ((int __pgrp, int __sig));
+extern int     sigaddset __P ((sigset_t *__mask, int __sig));
+extern int     sigdelset __P ((sigset_t *__mask, int __sig));
+extern int     sigemptyset __P ((sigset_t *__mask));
+extern int     sigfillset __P ((sigset_t *__mask));
+extern int     sigismember __P ((__const sigset_t *__mask, int __sig));
+extern int     sigpending __P ((sigset_t *__set));
+
+extern int     __sigprocmask __P ((int __how, __const sigset_t *__set,
+                       sigset_t *__oldset));
+extern int     sigprocmask __P ((int __how, __const sigset_t *__set,
+                       sigset_t *__oldset));
+
+extern int     sigsuspend __P ((__const sigset_t *sigmask));
+
+extern int     __sigaction __P ((int __sig, struct sigaction *__act,
+                       struct sigaction *__oldact));
+extern int     sigaction __P ((int __sig, struct sigaction *__act,
+                       struct sigaction *__oldact));
+
+#define __sigemptyset(set)     ((*(set) = 0L), 0)
+#define __sigfillset(set)       ((*(set) = -1L), 0)
+#define __sigaddset(set, sig)   ((*(set) |= __sigmask (sig)), 0)
+#define __sigdelset(set, sig)   ((*(set) &= ~__sigmask (sig)), 0)
+#define __sigismember(set, sig) ((*(set) & __sigmask (sig)) ? 1 : 0)
+
+
+#if 1
+#define sigemptyset    __sigemptyset
+#define sigfillset     __sigfillset
+
+/* We don't do that any more since it causes problems due to
+ * "sig" > _NSIG and "sig" < 1. It isn't worth the touble to make
+ * them inline and static. Use __sigxxxxx if you want speed with
+ * correct "sig".
+ */
+#if 1
+#define sigaddset      __sigaddset
+#define sigdelset      __sigdelset
+#define sigismember    __sigismember
+#endif
+
+#endif
+
+
+/* Return a mask that includes SIG only.  */
+#define __sigmask(sig) (1 << ((sig) - 1))
+
+extern int __sigsetmask __P ((int __mask));
+extern int __siggetmask __P ((void));
+extern int __sigblock __P ((int __mask));
+extern int __sigpause __P ((int __mask));
+
+#ifdef  __USE_SVID
+/* SVID names for the same things.  */
+extern __sighandler_t ssignal __P ((int __sig, __sighandler_t __handler));
+extern int gsignal __P ((int __sig));
+
+#endif /* Use SVID.  */
+/* BSD */
+#ifdef __USE_BSD
+#define sigmask                __sigmask
+
+extern int     sigblock __P ((int __mask));
+extern int     sigpause __P ((int __mask));
+extern int     sigsetmask __P ((int __mask));
+extern int     siggetmask __P ((void));
+extern void    psignal __P ((int __sig, __const char *__str));
+
+extern int     siginterrupt __P ((int __sig, int __flag));
+
+/* The `sig' bit is set if the interrupt on it
+ * is enabled via siginterrupt (). */
+extern sigset_t _sigintr;
+
+#endif  /* Use BSD.  */
+
+#ifdef __USE_BSD_SIGNAL
+
+extern __sighandler_t
+               __bsd_signal __P ((int __sig, __sighandler_t));
+#define signal __bsd_signal
+
+#endif /* __USE_BSD_SIGNAL */
+
+__END_DECLS
+
+#if _MIT_POSIX_THREADS
+#define __SIGFILLSET           0xffffffff
+#define __SIGEMPTYSET          0
+#define __SIGADDSET(s,n)       ((*s) |= (1 << ((n) - 1)))
+#define __SIGDELSET(s,n)       ((*s) &= ~(1 << ((n) - 1)))
+#define __SIGISMEMBER(s,n)     ((*s) & (1 << ((n) - 1)))
+#endif
+
+#endif /* _SIGNAL_H */
diff --git a/include/stdarg.h b/include/stdarg.h
new file mode 100644 (file)
index 0000000..321e664
--- /dev/null
@@ -0,0 +1,47 @@
+ /*
+  * @(#) stdarg.h 1.2 91/11/30 21:10:39
+  * 
+  * Sample stdarg.h file for use with the unproto filter.
+  * 
+  * This file serves two purposes.
+  * 
+  * 1 - As an include file for use with ANSI-style C source that implements
+  * variadic functions.
+  * 
+  * 2 - To configure the unproto filter itself. If the _VA_ALIST_ macro is
+  * defined, its value will appear in the place of the "..." in argument
+  * lists of variadic function *definitions* (not declarations).
+  * 
+  * Compilers that pass arguments via the stack can use the default code at the
+  * end of this file (this usually applies for the VAX, MC68k and 80*86
+  * architectures).
+  * 
+  * RISC-based systems often need special tricks. An example of the latter is
+  * given for the SPARC architecture. Read your /usr/include/varargs.h for
+  * more information.
+  * 
+  * You can use the varargs.c program provided with the unproto package to
+  * verify that the stdarg.h file has been set up correctly.
+  */
+
+#ifndef __STDARG_H
+#define __STDARG_H
+
+#ifdef sparc
+#  define _VA_ALIST_           "__builtin_va_alist"
+   typedef char *va_list;
+#  define va_start(ap, p)      (ap = (char *) &__builtin_va_alist)
+#  define va_arg(ap, type)     ((type *) __builtin_va_arg_incr((type *) ap))[0]
+#  define va_end(ap)
+#else /* vax, mc68k, 80*86 */
+   typedef char *va_list;
+#  define va_start(ap, p)      (ap = (char *) (&(p)+1))
+#  define va_arg(ap, type)     ((type *) (ap += sizeof(type)))[-1]
+#  define va_end(ap)
+#endif
+
+#endif /* __STDARG_H */
+
+#if __FIRST_ARG_IN_AX__
+#error First arg is in a register, stdarg.h cannot take its address
+#endif
diff --git a/include/stdio.h b/include/stdio.h
new file mode 100644 (file)
index 0000000..1f63f60
--- /dev/null
@@ -0,0 +1,118 @@
+
+#ifndef __STDIO_H
+#define __STDIO_H
+
+#include <features.h>
+#include <sys/types.h>
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+
+#define _IOFBF         0x00    /* full buffering */
+#define _IOLBF         0x01    /* line buffering */
+#define _IONBF         0x02    /* no buffering */
+#define __MODE_BUF     0x03    /* Modal buffering dependent on isatty */
+
+#define __MODE_FREEBUF 0x04    /* Buffer allocated with malloc, can free */
+#define __MODE_FREEFIL 0x08    /* FILE allocated with malloc, can free */
+
+#define __MODE_READ    0x10    /* Opened in read only */
+#define __MODE_WRITE   0x20    /* Opened in write only */
+#define __MODE_RDWR    0x30    /* Opened in read/write */
+
+#define __MODE_READING 0x40    /* Buffer has pending read data */
+#define __MODE_WRITING 0x80    /* Buffer has pending write data */
+
+#define __MODE_EOF     0x100   /* EOF status */
+#define __MODE_ERR     0x200   /* Error status */
+#define __MODE_UNGOT   0x400   /* Buffer has been polluted by ungetc */
+
+#define __MODE_IOTRAN  0
+
+/* when you add or change fields here, be sure to change the initialization
+ * in stdio_init and fopen */
+struct __stdio_file {
+  unsigned char *bufpos;   /* the next byte to write to or read from */
+  unsigned char *bufread;  /* the end of data returned by last read() */
+  unsigned char *bufwrite; /* highest address writable by macro */
+  unsigned char *bufstart; /* the start of the buffer */
+  unsigned char *bufend;   /* the end of the buffer; ie the byte after the last
+                              malloc()ed byte */
+
+  int fd; /* the file descriptor associated with the stream */
+  int mode;
+
+  char unbuf[8];          /* The buffer for 'unbuffered' streams */
+
+  struct __stdio_file * next;
+};
+
+#define EOF    (-1)
+#ifndef NULL
+#define NULL   (0)
+#endif
+
+typedef struct __stdio_file FILE;
+
+#define BUFSIZ (500) /*(508) should get us a fully used kmalloc bucket */
+
+extern FILE stdin[1];
+extern FILE stdout[1];
+extern FILE stderr[1];
+
+
+#define putc(c, stream)        \
+    (((stream)->bufpos >= (stream)->bufwrite) ? fputc((c), (stream))   \
+                          : (unsigned char) (*(stream)->bufpos++ = (c))        )
+
+#define getc(stream)   \
+  (((stream)->bufpos >= (stream)->bufread) ? fgetc(stream):            \
+    (*(stream)->bufpos++))
+
+#define putchar(c) putc((c), stdout)  
+#define getchar() getc(stdin)
+
+#define ferror(fp)     (((fp)->mode&__MODE_ERR) != 0)
+#define feof(fp)       (((fp)->mode&__MODE_EOF) != 0)
+#define clearerr(fp)   ((fp)->mode &= ~(__MODE_EOF|__MODE_ERR),0)
+#define fileno(fp)     ((fp)->fd)
+
+/* These two call malloc */
+#define setlinebuf(__fp)             setvbuf((__fp), (char*)0, _IOLBF, 0)
+extern int setvbuf __P((FILE*, char*, int, size_t));
+
+/* These don't */
+#define setbuf(__fp, __buf) setbuffer((__fp), (__buf), BUFSIZ)
+extern void setbuffer __P((FILE*, char*, int));
+
+extern int fgetc __P((FILE*));
+extern int fputc __P((int, FILE*));
+
+extern int fclose __P((FILE*));
+extern int fflush __P((FILE*));
+extern char *fgets __P((char*, size_t, FILE*));
+extern FILE *__fopen __P((char*, int, FILE*, char*));
+
+#define fopen(__file, __mode)         __fopen((__file), -1, (FILE*)0, (__mode))
+#define freopen(__file, __mode, __fp) __fopen((__file), -1, (__fp), (__mode))
+#define fdopen(__file, __mode)  __fopen((char*)0, (__file), (FILE*)0, (__mode))
+
+extern int fseek __P((FILE*, long, int));
+extern long ftell __P((FILE*));
+extern void rewind __P((FILE*));
+
+extern int fputs __P((char*, FILE*));
+extern int puts __P((char*));
+
+extern int printf __P ((__const char*, ...));
+extern int fprintf __P ((FILE*, __const char*, ...));
+extern int sprintf __P ((char*, __const char*, ...));
+
+extern int ungetc __P ((int c, FILE * stream));
+
+#define stdio_pending(fp) ((fp)->bufread>(fp)->bufpos)
+
+#endif /* __STDIO_H */
diff --git a/include/stdlib.h b/include/stdlib.h
new file mode 100644 (file)
index 0000000..27c0a58
--- /dev/null
@@ -0,0 +1,75 @@
+/* stdlib.h  <ndf@linux.mit.edu> */
+#include <features.h>
+#include <sys/types.h>
+
+#ifndef __STDLIB_H
+#define __STDLIB_H
+
+/* Don't overwrite user definitions of NULL */
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+/* For program termination */
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+extern void * malloc __P ((size_t));
+extern void * calloc __P ((size_t, size_t));
+extern void free __P ((void *));
+extern void * realloc __P ((void *, size_t));
+
+#ifdef DEBUG_MALLOC
+
+extern void * malloc_dbg __P ((size_t, char* func, char* file, int line));
+extern void * calloc_dbg __P ((size_t, size_t, char* func, char* file, int line));
+extern void free_dbg __P ((void *, char* func, char* file, int line));
+extern void * realloc_dbg __P ((void *, size_t, char* func, char* file, int line));
+
+#define malloc(x) malloc_dbg((x),__FUNCTION__,__FILE__,__LINE__)
+#define calloc(x,y) calloc_dbg((x),(y),__FUNCTION__,__FILE__,__LINE__)
+#define free(x) free_dbg((x),__FUNCTION__,__FILE__,__LINE__)
+#define realloc(x) realloc((x),__FUNCTION__,__FILE__,__LINE__)
+
+#endif
+
+extern int rand __P ((void));
+extern void srand __P ((unsigned int seed));
+
+extern long strtol __P ((const char * nptr, char ** endptr, int base));
+extern unsigned long strtoul __P ((const char * nptr,
+                                  char ** endptr, int base));
+#ifndef __HAS_NO_FLOATS__
+extern float strtod __P ((const char * nptr, char ** endptr));
+#endif
+
+extern char *getenv __P ((__const char *__name));
+
+extern int putenv __P ((__const char *__string));
+
+extern int setenv __P ((__const char *__name, __const char *__value,
+                        int __replace));
+
+extern int system __P ((__const char *__command));
+
+extern int qsort __P ((char *base, int num, int size, int (*cmp)()));
+
+extern char * gcvt __P ((float number, size_t ndigit, char * buf));
+
+#define atof(x) strtod((x),(char**)0)
+
+/* Returned by `div'.  */
+typedef struct
+  {
+    int quot;                  /* Quotient.  */
+    int rem;                   /* Remainder.  */
+  } div_t;
+
+/* Returned by `ldiv'.  */
+typedef struct
+  {
+    long int quot;             /* Quotient.  */
+    long int rem;              /* Remainder.  */
+  } ldiv_t;
+
+#endif /* __STDLIB_H */
diff --git a/include/string.h b/include/string.h
new file mode 100644 (file)
index 0000000..eb44849
--- /dev/null
@@ -0,0 +1,56 @@
+
+#ifndef __STRING_H
+#define __STRING_H
+#include <features.h>
+#include <sys/types.h>
+#include <stddef.h>
+
+/* Basic string functions */
+extern size_t strlen __P ((__const char* __str));
+
+extern char * strcat __P ((char*, __const char*));
+extern char * strcpy __P ((char*, __const char*));
+extern int strcmp __P ((__const char*, __const char*));
+
+extern char * strncat __P ((char*, __const char*, size_t));
+extern char * strncpy __P ((char*, __const char*, size_t));
+extern int strncmp __P ((__const char*, __const char*, size_t));
+
+extern char * strchr __P ((char*, int));
+extern char * strrchr __P ((char*, int));
+extern char * strdup __P ((__const char*));
+
+/* Basic mem functions */
+extern void * memcpy __P ((void*, __const void*, size_t));
+extern void * memccpy __P ((void*, void*, int, size_t));
+extern void * memchr __P ((__const void*, __const int, size_t));
+extern void * memset __P ((void*, int, size_t));
+extern int memcmp __P ((__const void*, __const void*, size_t));
+
+extern void * memmove __P ((void*, void*, size_t));
+
+/* Minimal (very!) locale support */
+#define strcoll strcmp
+#define strxfrm strncpy
+
+/* BSDisms */
+#define index strchr
+#define rindex strrchr
+
+/* Other common BSD functions */
+extern int strcasecmp __P ((char*, char*));
+extern int strncasecmp __P ((char*, char*, size_t));
+char *strpbrk __P ((char *, char *));
+char *strsep __P ((char **, char *));
+char *strstr __P ((char *, char *));
+char *strtok __P ((char *, char *));
+size_t strcspn __P ((char *, char *));
+size_t strspn __P ((char *, char *));
+
+/* More BSD compatabilty */
+#define bcmp   memcmp
+
+/* Linux silly hour */
+char *strfry __P ((char *));
+
+#endif
diff --git a/include/strings.h b/include/strings.h
new file mode 100644 (file)
index 0000000..3b2f590
--- /dev/null
@@ -0,0 +1 @@
+#include <string.h>
diff --git a/include/sys/bitypes.h b/include/sys/bitypes.h
new file mode 100644 (file)
index 0000000..e2ac0ab
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * bitypes.h,v 1.4 1995/08/24 01:58:54 hjl Exp
+ */
+
+/*
+ * ++Copyright++ 1993
+ * -
+ * Copyright (c) 1993 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 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
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * 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
+ * CORPORATION 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.
+ * -
+ * --Copyright--
+ */
+
+/*
+#ifdef __USE_BSD
+*/
+
+/*
+#ifndef __BIT_TYPES_DEFINED__
+# if (defined(BSD) && (BSD >= 199306)) || \
+     (defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199312)) 
+#  define __BIT_TYPES_DEFINED__
+# endif
+#endif
+*/
+
+#ifndef __BIT_TYPES_DEFINED__
+#define __BIT_TYPES_DEFINED__
+
+       /*
+        * Basic integral types.  Omit the typedef if
+        * not possible for a machine/compiler combination.
+        */
+       typedef /*signed*/ char            int8_t;
+       typedef unsigned char            u_int8_t;
+       typedef short                     int16_t;
+       typedef unsigned short          u_int16_t;
+       typedef int                       int32_t;
+       typedef unsigned int            u_int32_t;
+
+# if __GNUC__ >= 2 && !defined(__STRICT_ANSI__)
+       typedef long long                 int64_t;
+       typedef unsigned long long      u_int64_t;
+# endif
+
+#endif /* __BIT_TYPES_DEFINED__ */
+
+/* #endif  __USE_BSD */
diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h
new file mode 100644 (file)
index 0000000..0afc883
--- /dev/null
@@ -0,0 +1,36 @@
+
+#ifndef __SYS_CDEFS_H
+#define __SYS_CDEFS_H
+#include <features.h>
+
+#if defined (__STDC__) && __STDC__
+
+#define        __CONCAT(x,y)   x ## y
+#define        __STRING(x)     #x
+
+/* This is not a typedef so `const __ptr_t' does the right thing.  */
+#define __ptr_t void *
+typedef long double __long_double_t;
+
+#else
+
+#define        __CONCAT(x,y)   x/**/y
+#define        __STRING(x)     "x"
+
+#define __ptr_t char *
+
+#ifndef __HAS_NO_FLOATS__
+typedef double __long_double_t;
+#endif
+
+#endif
+
+/* No C++ */
+#define __BEGIN_DECLS
+#define __END_DECLS
+
+/* GNUish things */
+#define __CONSTVALUE
+#define __CONSTVALUE2
+
+#endif
diff --git a/include/sys/dir.h b/include/sys/dir.h
new file mode 100644 (file)
index 0000000..1c2cea7
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef _SYS_DIRENT_H
+#error "Can't include both sys/dir.h and sys/dirent.h"
+#define _SYS_DIR_H
+#endif
+
+#ifndef _SYS_DIR_H
+#define _SYS_DIR_H
+
+#include <dirent.h>
+
+#define direct dirent
+
+#undef DIRSIZ
+#define DIRSIZ(dp)     ((sizeof (struct direct) - (MAXNAMLEN+1)) + \
+                        (((dp)->d_namlen+1 + 3) &~ 3))
+
+#endif
diff --git a/include/sys/errno.h b/include/sys/errno.h
new file mode 100644 (file)
index 0000000..339f4fc
--- /dev/null
@@ -0,0 +1 @@
+#include <errno.h>
diff --git a/include/sys/fcntl.h b/include/sys/fcntl.h
new file mode 100644 (file)
index 0000000..cd30455
--- /dev/null
@@ -0,0 +1 @@
+#include <fcntl.h>
diff --git a/include/sys/file.h b/include/sys/file.h
new file mode 100644 (file)
index 0000000..2401b15
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _SYS_FILE_H
+#define _SYS_FILE_H
+
+#include <features.h>
+#include <fcntl.h>
+
+#ifndef L_SET
+
+#define L_SET           0       /* absolute offset */
+#define L_INCR          1       /* relative to current offset */
+#define L_XTND          2       /* relative to end of file */
+
+#endif
+
+#ifndef LOCK_SH
+
+/* Operations for the `flock' call.  */
+#define LOCK_SH       1    /* Shared lock.  */
+#define LOCK_EX       2    /* Exclusive lock.  */
+#define LOCK_UN       8    /* Unlock.  */
+
+/* Can be OR'd in to one of the above.  */
+#define LOCK_NB       4    /* Don't block when locking.  */
+
+#endif
+
+__BEGIN_DECLS
+
+/* Apply or remove an advisory lock, according to OPERATION,
+   on the file FD refers to.  */
+extern int flock __P ((int __fd, int __operation));
+
+__END_DECLS
+
+#endif
diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h
new file mode 100644 (file)
index 0000000..11dd06e
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _SYS_IOCTL_H
+#define _SYS_IOCTL_H
+
+#include <linux/ioctl.h>
+#include <features.h>
+#include <termios.h>
+#include <sys/socketio.h>
+
+__BEGIN_DECLS
+
+extern int     ioctl __P ((int __fildes, int __cmd, ...));
+extern int     __ioctl __P ((int __fildes, int __cmd, ...));
+
+__END_DECLS
+
+
+#endif
diff --git a/include/sys/mman.h b/include/sys/mman.h
new file mode 100644 (file)
index 0000000..8dc79d9
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _SYS_MMAN_H
+#define _SYS_MMAN_H
+
+#include <features.h>
+#include <sys/types.h>
+#include <linux/mman.h>
+
+#ifndef MAP_ANON
+#define MAP_ANON       MAP_ANONYMOUS      /* idem */
+#endif
+#ifndef MAP_FILE
+#define MAP_FILE       0x00       /* The 'normal' way: mapped from file */
+#endif
+
+__BEGIN_DECLS
+
+extern __ptr_t mmap __P((__ptr_t __addr, size_t __len,
+               int __prot, int __flags, int __fd, off_t __off));
+extern int munmap __P((__ptr_t __addr, size_t __len));
+extern int mprotect __P ((__const __ptr_t __addr, size_t __len, int __prot));
+
+extern int msync __P((__ptr_t __addr, size_t __len, int __flags));
+
+extern int mlock __P((__const __ptr_t __addr, size_t __len));
+extern int munlock __P((__const __ptr_t __addr, size_t __len));
+
+extern int mlockall __P((int __flags));
+extern int munlockall __P((void));
+
+extern __ptr_t mremap __P((__ptr_t __addr, size_t __old_len,
+               size_t __new_len, int __may_move));
+
+__END_DECLS
+
+#endif /* _SYS_MMAN_H */
diff --git a/include/sys/mount.h b/include/sys/mount.h
new file mode 100644 (file)
index 0000000..a0765e2
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _SYS_MOUNT_H
+#define _SYS_MOUNT_H
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+extern int      mount __P ((__const char* __specialfile,
+                __const char* __dir,__const char* __filesystemype,
+                unsigned long __rwflag,__const void *__data));
+
+extern int      umount __P ((__const char* __specialfile));
+                                        
+                                        
+__END_DECLS
+
+#endif
diff --git a/include/sys/param.h b/include/sys/param.h
new file mode 100644 (file)
index 0000000..906a0a2
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+#ifndef _PARAM_H
+#define _PARAM_H
+
+#include <features.h>
+#include <limits.h>
+#include <linux/limits.h>
+#include <linux/param.h>
+
+#include <sys/types.h>
+
+#define MAXPATHLEN PATH_MAX
+
+#ifndef NR_OPEN
+#define NR_OPEN 32
+#endif
+#ifndef NR_FILE
+#define NR_FILE 32
+#endif
+
+/* Bit map related macros.  */
+#define        setbit(a,i)     ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define        clrbit(a,i)     ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define        isset(a,i)      ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define        isclr(a,i)      (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+
+/* Macros for counting and rounding.  */
+#ifndef howmany
+#define        howmany(x, y)   (((x)+((y)-1))/(y))
+#endif
+#define        roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
+#define powerof2(x)    ((((x)-1)&(x))==0)
+
+/* Macros for min/max.  */
+#define        MIN(a,b) (((a)<(b))?(a):(b))
+#define        MAX(a,b) (((a)>(b))?(a):(b))
+
+
+/* Unit of `st_blocks'.  */
+#define DEV_BSIZE       512 
+
+#endif /* _PARAM_H */
diff --git a/include/sys/resource.h b/include/sys/resource.h
new file mode 100644 (file)
index 0000000..19ed06f
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Resource control/accounting header file for linux-86
+ */
+
+#ifndef _SYS_RESOURCE_H
+#define _SYS_RESOURCE_H
+
+#include <features.h>
+#include <sys/time.h>
+#include <limits.h>
+
+#define        RUSAGE_SELF     0
+#define        RUSAGE_CHILDREN (-1)
+#define RUSAGE_BOTH    (-2)            /* sys_wait4() uses this */
+
+struct rusage {
+       struct timeval ru_utime;        /* user time used */
+       struct timeval ru_stime;        /* system time used */
+       long    ru_maxrss;              /* maximum resident set size */
+       long    ru_ixrss;               /* integral shared memory size */
+       long    ru_idrss;               /* integral unshared data size */
+       long    ru_isrss;               /* integral unshared stack size */
+       long    ru_minflt;              /* page reclaims */
+       long    ru_majflt;              /* page faults */
+       long    ru_nswap;               /* swaps */
+       long    ru_inblock;             /* block input operations */
+       long    ru_oublock;             /* block output operations */
+       long    ru_msgsnd;              /* messages sent */
+       long    ru_msgrcv;              /* messages received */
+       long    ru_nsignals;            /* signals received */
+       long    ru_nvcsw;               /* voluntary context switches */
+       long    ru_nivcsw;              /* involuntary " */
+};
+
+#define RLIM_INFINITY  ((long)(~0UL>>1))
+
+struct rlimit {
+       long    rlim_cur;
+       long    rlim_max;
+};
+
+#define        PRIO_MIN        (-20)
+#define        PRIO_MAX        20
+
+#define        PRIO_PROCESS    0
+#define        PRIO_PGRP       1
+#define        PRIO_USER       2
+
+#define RLIMIT_CPU     0               /* CPU time in ms */
+#define RLIMIT_FSIZE   1               /* Maximum filesize */
+#define RLIMIT_DATA    2               /* max data size */
+#define RLIMIT_STACK   3               /* max stack size */
+#define RLIMIT_CORE    4               /* max core file size */
+#define RLIMIT_RSS     5               /* max resident set size */
+#define RLIMIT_NPROC   6               /* max number of processes */
+#define RLIMIT_NOFILE  7               /* max number of open files */
+#define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
+
+#define RLIM_NLIMITS   9
+
+extern int     getrlimit __P ((int __resource,
+                       struct rlimit *__rlp));
+extern int     setrlimit __P ((int __resource,
+                       __const struct rlimit *__rlp));
+
+extern int      getpriority __P((int __which, int __who));
+extern int      setpriority __P((int __which, int __who,
+                       int __prio));
+
+extern int     __getrusage __P ((int __who, struct rusage *__rusage));
+extern int     getrusage __P ((int __who, struct rusage *__rusage));
+
+#endif /* _SYS_RESOURCE_H */
diff --git a/include/sys/signal.h b/include/sys/signal.h
new file mode 100644 (file)
index 0000000..2e602da
--- /dev/null
@@ -0,0 +1 @@
+#include <signal.h>
diff --git a/include/sys/socket.h b/include/sys/socket.h
new file mode 100644 (file)
index 0000000..5dcef2d
--- /dev/null
@@ -0,0 +1,135 @@
+#ifndef _SYS_SOCKET_H
+#define _SYS_SOCKET_H
+
+#include <features.h>
+#include <sys/types.h>
+#include <linux/socket.h>
+
+#ifdef _MIT_POSIX_THREADS
+#include <pthread/mit/posix.h>
+#endif
+
+__BEGIN_DECLS
+
+/* struct msghdr is not defined in linux 1.2.  This will allow sendmsg
+   and recvmsg in libc 5.2.9 to compile under 1.2.x and shouldn't cause
+   any problem for 1.3.x */
+struct msghdr;
+
+/* Create a new socket of type TYPE in domain DOMAIN, using
+   protocol PROTOCOL.  If PROTOCOL is zero, one is chosen
+   automatically.  Returns a file descriptor for the new socket,
+   or -1 for errors.  */
+int socket __P ((int __family, int __type, int __protocol));
+
+/* Create two new sockets, of type TYPE in domain DOMAIN and using
+   protocol PROTOCOL, which are connected to each other, and put file
+   descriptors for them in FDS[0] and FDS[1].  If PROTOCOL is zero,
+   one will be chosen automatically.  Returns 0 on success, -1
+   for errors.  */
+int socketpair __P ((int __family, int __type, int __protocol,
+               int __sockvec[2]));
+
+/* Give the socket FD the local address ADDR (which is LEN bytes
+   long).  */
+int bind __P ((int __sockfd, __const struct sockaddr *__my_addr,
+               int __addrlen));
+
+/* Open a connection on socket FD to peer at ADDR (which LEN bytes
+   long). For connectionless socket types, just set the default
+   address to send to and the only address from which to accept
+   transmissions.  Return 0 on success, -1 for errors.  */
+int connect __P ((int __sockfd, __const struct sockaddr *__serv_addr,
+               int __addrlen));
+
+/* Prepare to accept connections on socket FD.
+   N connection requests will be queued before further requests are
+   refused. Returns 0 on success, -1 for errors.  */
+int listen __P ((int __sockfd, int __n));
+
+/* Await a connection on socket FD.
+   When a connection arrives, open a new socket to communicate with it,
+   set *ADDR (which is *ADDR_LEN bytes long) to the address of the
+   connecting peer and *ADDR_LEN to the address's actual length, and
+   return the new socket's descriptor, or -1 for errors.  */
+int accept __P ((int __sockfd, __const struct sockaddr *__peer,
+               int *__paddrlen));
+
+/* Put the current value for socket FD's option OPTNAME at protocol
+   level LEVEL into OPTVAL (which is *OPTLEN bytes long), and set
+   *OPTLEN to the value's actual length. Returns 0 on success, -1 for
+   errors.  */
+int getsockopt __P ((int __s, int __level, int __optname,
+               void *__optval, int *__optlen));
+
+/* Set socket FD's option OPTNAME at protocol level LEVEL
+   to *OPTVAL (which is OPTLEN bytes long).
+   Returns 0 on success, -1 for errors.  */
+int setsockopt __P ((int __s, int __level, int __optname,
+               __const void *__optval, int optlen));
+
+/* Put the local address of FD into *ADDR and its length in *LEN.  */
+int getsockname __P ((int __sockfd, struct sockaddr *__addr,
+               int *__paddrlen));
+
+/* Put the address of the peer connected to socket FD into *ADDR
+   (which is *LEN bytes long), and its actual length into *LEN.  */
+int getpeername __P ((int __sockfd, struct sockaddr *__peer,
+               int *__paddrlen));
+
+/* Send N bytes of BUF to socket FD.  Returns the number sent or -1. */
+int send __P ((int __sockfd, __const void *__buff, size_t __len,
+                unsigned int __flags));
+
+/* Read N bytes into BUF from socket FD.
+   Returns the number read or -1 for errors.  */
+int recv __P ((int __sockfd, void *__buff, size_t __len,
+                unsigned int __flags));
+
+/* Send N bytes of BUF on socket FD to peer at address ADDR (which is
+   ADDR_LEN bytes long).  Returns the number sent, or -1 for errors. */
+int sendto __P ((int __sockfd, __const void *__buff, size_t __len,
+                unsigned int __flags, __const struct sockaddr *__to,
+                int __tolen));
+
+/* Read N bytes into BUF through socket FD.
+   If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address
+   of the sender, and store the actual size of the address in
+   *ADDR_LEN. Returns the number of bytes read or -1 for errors. */
+int recvfrom __P ((int __sockfd, void *__buff, size_t __len,
+                unsigned int __flags, struct sockaddr *__from,
+                int *__fromlen));
+
+/* Send a message described MESSAGE on socket FD.
+   Returns the number of bytes sent, or -1 for errors.  */
+extern int sendmsg __P ((int __fd, __const struct msghdr *__message,
+                       unsigned int __flags));
+
+/* Receive a message as described by MESSAGE from socket FD.
+   Returns the number of bytes read or -1 for errors.  */
+extern int recvmsg __P ((int __fd, struct msghdr *__message,
+                       unsigned int __flags));
+/* Shut down all or part of the connection open on socket FD.
+   HOW determines what to shut down:
+       0 = No more receptions;
+       1 = No more transmissions;
+       2 = No more receptions or transmissions.
+   Returns 0 on success, -1 for errors.  */
+int shutdown __P ((int __sockfd, int __how));
+
+
+/* belongs here or elsewhere? */
+int rcmd __P ((char **__ahost, unsigned short __inport,
+               __const char *__locuser, __const char *__remuser,
+               __const char *__cmd, int *__fd2p));
+int rresvport __P ((int *__port));
+int ruserok __P ((__const char *__rhost, int __superuser,
+               __const char *__ruser, __const char *__luser));
+int rexec __P ((char **__ahost, int __inport, __const char *__user,
+                __const char *__passwd, __const char *__cmd,
+                int *__fd2p));
+
+__END_DECLS
+
+#endif /* _SYS_SOCKET_H */
diff --git a/include/sys/socketcall.h b/include/sys/socketcall.h
new file mode 100644 (file)
index 0000000..52e9583
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _SYS_SOCKETCALL_H
+#define _SYS_SOCKETCALL_H
+
+#define SYS_SOCKET     1
+#define SYS_BIND       2
+#define SYS_CONNECT    3
+#define SYS_LISTEN     4
+#define SYS_ACCEPT     5
+#define SYS_GETSOCKNAME        6
+#define SYS_GETPEERNAME        7
+#define SYS_SOCKETPAIR 8
+#define SYS_SEND       9
+#define SYS_RECV       10
+#define SYS_SENDTO     11
+#define SYS_RECVFROM   12
+#define SYS_SHUTDOWN   13
+#define SYS_SETSOCKOPT 14
+#define SYS_GETSOCKOPT 15
+#define SYS_SENDMSG    16
+#define SYS_RECVMSG    17
+
+#endif _SYS_SOCKETCALL_H
diff --git a/include/sys/socketio.h b/include/sys/socketio.h
new file mode 100644 (file)
index 0000000..332bcf0
--- /dev/null
@@ -0,0 +1 @@
+#include <linux/sockios.h>
diff --git a/include/sys/socketvar.h b/include/sys/socketvar.h
new file mode 100644 (file)
index 0000000..2833565
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ *     This seems the best way to handle this. sys/socket.h already has
+ *     all the right bits in it. In fact there isn't a single useful thing
+ *     in the BSD net-2 sys/socketvar.h anyway but people persist in including
+ *     it...
+ *             Alan
+ */
+#include <sys/socket.h>
diff --git a/include/sys/stat.h b/include/sys/stat.h
new file mode 100644 (file)
index 0000000..e486d75
--- /dev/null
@@ -0,0 +1,192 @@
+#ifndef _SYS_STAT_H
+#define _SYS_STAT_H
+
+#include <features.h>
+#include <sys/types.h>
+#undef __NOT_KERNEL
+#define __NOT_KERNEL
+#include <linux/stat.h>
+#undef __NOT_KERNEL
+
+#ifdef __SVR4_I386_ABI_L1__
+#include <sys/time.h>          /* For timestruc_t */
+#endif /* __SVR4_I386_ABI_L1__ */
+
+__BEGIN_DECLS
+
+struct stat {
+       dev_t           st_dev;
+
+#ifdef __SVR4_I386_ABI_L1__
+       long st_pad1[3];
+#else
+       unsigned short __pad1;
+#endif
+
+       ino_t           st_ino;
+       umode_t         st_mode;
+       nlink_t         st_nlink;
+       uid_t           st_uid;
+       gid_t           st_gid;
+       dev_t           st_rdev;
+
+#ifdef __SVR4_I386_ABI_L1__
+       long st_pad2[2];
+#else
+       unsigned short __pad2;
+#endif
+
+       off_t           st_size;
+
+#ifdef __SVR4_I386_ABI_L1__
+       timestruc_t     st_atim;
+       timestruc_t     st_mtim;
+       timestruc_t     st_ctim;
+       long            st_blksize;
+       long            st_blocks;
+
+#define        FSTYPSZ         16
+
+        char            st_fstype[FSTYPSZ];
+        long           st_pad4[8];
+
+#define st_atime       st_atim.tv_sec
+#define st_mtime       st_mtim.tv_sec
+#define st_ctime       st_ctim.tv_sec
+
+#else /*! __SVR4_I386_ABI_L1__*/
+       unsigned long   st_blksize;
+       unsigned long   st_blocks;
+       time_t          st_atime;
+       unsigned long   __unused1;
+       time_t          st_mtime;
+       unsigned long   __unused2;
+       time_t          st_ctime;
+       unsigned long   __unused3;
+       unsigned long   __unused4;
+       unsigned long   __unused5;
+#endif /*! __SVR4_I386_ABI_L1__*/
+};
+
+
+#define LINUX_MKNOD_VERSION 1     /* SVr4 */
+#define LINUX_STAT_VERSION 1      /* SVr4 */
+
+extern int _fxstat __P ((int __ver, int __fildes,
+                       struct stat *__stat_buf));
+
+extern int _xstat __P ((int __ver, __const char *__filename,
+                       struct stat *__stat_buf));
+
+extern int _lxstat __P ((int __ver, __const char *__filename,
+                       struct stat *__stat_buf));
+
+#ifdef _MIT_POSIX_THREADS
+extern int __machdep_sys__fxstat __P ((int __ver, int __fd,
+                       struct stat *__stat_buf));
+#endif
+
+extern int _xmknod __P ((int __ver, __const char *__path,
+                       mode_t __mode, dev_t *__dev));
+
+/* Some synonyms used historically in the kernel and elsewhere */
+#define S_IREAD                S_IRUSR /* read permission, owner */
+#define S_IWRITE       S_IWUSR /* write permission, owner */
+#define S_IEXEC                S_IXUSR /* execute/search permission, owner */
+
+extern int     __chmod __P ((__const char *__path, mode_t __mode));
+extern int     chmod __P ((__const char *__path, mode_t __mode));
+
+extern int     __fchmod __P ((int __fildes, mode_t __mode));
+extern int     fchmod __P ((int __fildes, mode_t __mode));
+
+extern int     __mkdir __P ((__const char *__path, mode_t __mode));
+extern int     mkdir __P ((__const char *__path, mode_t __mode));
+
+extern int     mkfifo __P ((__const char *__path, mode_t __mode));
+
+#if 1
+
+extern int     __fstat __P ((int __fildes, struct stat *__stat_buf));
+extern int     fstat __P ((int __fildes, struct stat *__stat_buf));
+
+extern int     __stat __P ((__const char *__filename,
+                       struct stat *__stat_buf));
+extern int     stat __P ((__const char *__filename,
+                       struct stat *__stat_buf));
+
+extern int     __lstat __P ((__const char *__filename,
+                       struct stat *__stat_buf));
+extern int     lstat __P ((__const char *__filename,
+                       struct stat *__stat_buf));
+
+extern int     __mknod __P ((__const char *__path, mode_t __mode,
+                       dev_t __dev));
+extern int     mknod __P ((__const char *__path, mode_t __mode,
+                       dev_t __dev));
+#endif         /* #if 0 */
+
+extern mode_t  __umask __P ((mode_t __mask));
+extern mode_t  umask __P ((mode_t __mask));
+
+__END_DECLS
+
+#if 0
+
+static __inline__ int __stat(__const char * __path, struct stat * __statbuf)
+{
+  return _xstat(LINUX_STAT_VERSION, __path, __statbuf);
+}
+
+static __inline__ int stat(__const char * __path, struct stat * __statbuf)
+{
+  return _xstat(LINUX_STAT_VERSION, __path, __statbuf);
+}
+
+static __inline__ int __lstat(__const char * __path, struct stat * __statbuf)
+{
+  return _lxstat(LINUX_STAT_VERSION, __path, __statbuf);
+}
+
+static __inline__ int lstat(__const char * __path, struct stat * __statbuf)
+{
+  return _lxstat(LINUX_STAT_VERSION, __path, __statbuf);
+}
+
+static __inline__ int __fstat(int __fd, struct stat * __statbuf)
+{
+  return _fxstat(LINUX_STAT_VERSION, __fd, __statbuf);
+}
+
+static __inline__ int fstat(int __fd, struct stat * __statbuf)
+{
+  return _fxstat(LINUX_STAT_VERSION, __fd, __statbuf);
+}
+
+static __inline__ int __mknod(__const char * __path, mode_t __mode, dev_t __dev)
+{
+  return _xmknod(LINUX_MKNOD_VERSION, __path, __mode, &__dev);
+}
+
+static __inline__ int mknod(__const char * __path, mode_t __mode, dev_t __dev)
+{
+  return _xmknod(LINUX_MKNOD_VERSION, __path, __mode, &__dev);
+}
+
+#ifdef _MIT_POSIX_THREADS
+
+static __inline__ int __machdep_sys_fstat(int __fd, struct stat * __statbuf)
+{
+  return __machdep_sys__fxstat(LINUX_STAT_VERSION, __fd, __statbuf);
+}
+
+static __inline__ int machdep_sys_fstat(int __fd, struct stat * __statbuf)
+{
+  return __machdep_sys__fxstat(LINUX_STAT_VERSION, __fd, __statbuf);
+}
+
+#endif
+
+#endif
+
+#endif
diff --git a/include/sys/syscall.h b/include/sys/syscall.h
new file mode 100644 (file)
index 0000000..f4ca99f
--- /dev/null
@@ -0,0 +1,182 @@
+#ifndef        _SYS_SYSCALL_H
+#define        _SYS_SYSCALL_H
+
+#define        SYS_setup               0 /* Used only by init, to get system going. */
+#define SYS_exit               1
+#define SYS_fork               2
+#define SYS_read               3
+#define SYS_write              4
+#define SYS_open               5
+#define SYS_close              6
+#define SYS_waitpid            7
+#define SYS_creat              8
+#define SYS_link               9
+#define SYS_unlink             10
+#define SYS_execve             11
+#define SYS_chdir              12
+#define SYS_time               13
+#define SYS_mknod              14
+#define SYS_prev_mknod         14
+#define SYS_chmod              15
+#define SYS_chown              16
+#define SYS_break              17
+#define SYS_oldstat            18
+#define SYS_lseek              19
+#define SYS_getpid             20
+#define SYS_mount              21
+#define SYS_umount             22
+#define SYS_setuid             23
+#define SYS_getuid             24
+#define SYS_stime              25
+#define SYS_ptrace             26
+#define SYS_alarm              27
+#define SYS_oldfstat           28
+#define SYS_pause              29
+#define SYS_utime              30
+#define SYS_stty               31
+#define SYS_gtty               32
+#define SYS_access             33
+#define SYS_nice               34
+#define SYS_ftime              35
+#define SYS_sync               36
+#define SYS_kill               37
+#define SYS_rename             38
+#define SYS_mkdir              39
+#define SYS_rmdir              40
+#define SYS_dup                        41
+#define SYS_pipe               42
+#define SYS_times              43
+#define SYS_prof               44
+#define SYS_brk                        45
+#define SYS_setgid             46
+#define SYS_getgid             47
+#define SYS_signal             48
+#define SYS_geteuid            49
+#define SYS_getegid            50
+#define SYS_acct               51
+#define SYS_phys               52
+#define SYS_lock               53
+#define SYS_ioctl              54
+#define SYS_fcntl              55
+#define SYS_mpx                        56
+#define SYS_setpgid            57
+#define SYS_ulimit             58
+#define SYS_oldolduname                59
+#define SYS_umask              60
+#define SYS_chroot             61
+#define SYS_prev_ustat         62
+#define SYS_dup2               63
+#define SYS_getppid            64
+#define SYS_getpgrp            65
+#define SYS_setsid             66
+#define SYS_sigaction          67
+#define SYS_siggetmask         68
+#define SYS_sigsetmask         69
+#define SYS_setreuid           70
+#define SYS_setregid           71
+#define SYS_sigsuspend         72
+#define SYS_sigpending         73
+#define SYS_sethostname                74
+#define SYS_setrlimit          75
+#define SYS_getrlimit          76
+#define SYS_getrusage          77
+#define SYS_gettimeofday       78
+#define SYS_settimeofday       79
+#define SYS_getgroups          80
+#define SYS_setgroups          81
+#define SYS_select             82
+#define SYS_symlink            83
+#define SYS_oldlstat           84
+#define SYS_readlink           85
+#define SYS_uselib             86
+#define SYS_swapon             87
+#define SYS_reboot             88
+#define SYS_readdir            89
+#define SYS_mmap               90
+#define SYS_munmap             91
+#define SYS_truncate           92
+#define SYS_ftruncate          93
+#define SYS_fchmod             94
+#define SYS_fchown             95
+#define SYS_getpriority                96
+#define SYS_setpriority                97
+#define SYS_profil             98
+#define SYS_statfs             99
+#define SYS_fstatfs            100
+#define SYS_ioperm             101
+#define SYS_socketcall         102
+#define SYS_klog               103
+#define SYS_setitimer          104
+#define SYS_getitimer          105
+#define SYS_prev_stat          106
+#define SYS_prev_lstat         107
+#define SYS_prev_fstat         108
+#define SYS_stat               106
+#define SYS_lstat              107
+#define SYS_fstat              108
+#define SYS_olduname           109
+#define SYS_iopl               110
+#define SYS_vhangup            111
+#define SYS_idle               112
+#define SYS_vm86old            113
+#define SYS_wait4              114
+#define SYS_swapoff            115
+#define SYS_sysinfo            116
+#define SYS_ipc                        117
+#define SYS_fsync              118
+#define SYS_sigreturn          119
+#define SYS_clone              120
+#define SYS_setdomainname      121
+#define SYS_uname              122
+#define SYS_modify_ldt         123
+#define SYS_adjtimex           124
+#define SYS_mprotect           125
+#define SYS_sigprocmask                126
+#define SYS_create_module      127
+#define SYS_init_module                128
+#define SYS_delete_module      129
+#define SYS_get_kernel_syms    130
+#define SYS_quotactl           131
+#define SYS_getpgid            132
+#define SYS_fchdir             133
+#define SYS_bdflush            134
+#define SYS_sysfs              135
+#define SYS_personality                136
+#define SYS_afs_syscall                137 /* Syscall for Andrew File System */
+#define        SYS_setfsuid            138
+#define        SYS_setfsgid            139
+#define        SYS__llseek             140
+#define SYS_getdents           141
+#define SYS__newselect         142
+#define SYS_flock              143
+#define SYS_syscall_flock      SYS_flock
+#define SYS_msync              144
+#define SYS_readv              145
+#define SYS_syscall_readv      SYS_readv
+#define SYS_writev             146
+#define SYS_syscall_writev     SYS_writev
+#define SYS_getsid             147
+#define SYS_fdatasync          148
+#define SYS__sysctl            149
+#define SYS_mlock              150
+#define SYS_munlock            151
+#define SYS_mlockall           152
+#define SYS_munlockall         153
+#define SYS_sched_setparam     154
+#define SYS_sched_getparam     155
+#define SYS_sched_setscheduler 156
+#define SYS_sched_getscheduler 157
+#define SYS_sched_yield                158
+#define SYS_sched_get_priority_max     159
+#define SYS_sched_get_priority_min     160
+#define SYS_sched_rr_get_interval      161
+#define SYS_nanosleep          162
+#define SYS_mremap             163
+#define SYS_setresuid          164
+#define SYS_getresuid          165
+#define SYS_vm86               166
+#define SYS_query_module       167
+#define SYS_poll               168
+#define SYS_syscall_poll       SYS_poll
+
+#endif /* <sys/syscall.h> */
diff --git a/include/sys/syslog.h b/include/sys/syslog.h
new file mode 100644 (file)
index 0000000..38d74a0
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 1982, 1986, 1988 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 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
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)syslog.h    7.20 (Berkeley) 2/23/91
+ */
+
+#ifndef _SYS_LOG_H
+#define        _SYS_LOG_H
+
+#include <features.h>
+
+#define        _PATH_LOG       "/dev/log"
+
+/*
+ * priorities/facilities are encoded into a single 32-bit quantity, where the
+ * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
+ * (0-big number).  Both the priorities and the facilities map roughly
+ * one-to-one to strings in the syslogd(8) source code.  This mapping is
+ * included in this file.
+ *
+ * priorities (these are ordered)
+ */
+#define        LOG_EMERG       0       /* system is unusable */
+#define        LOG_ALERT       1       /* action must be taken immediately */
+#define        LOG_CRIT        2       /* critical conditions */
+#define        LOG_ERR         3       /* error conditions */
+#define        LOG_WARNING     4       /* warning conditions */
+#define        LOG_NOTICE      5       /* normal but significant condition */
+#define        LOG_INFO        6       /* informational */
+#define        LOG_DEBUG       7       /* debug-level messages */
+
+#define        LOG_PRIMASK     0x07    /* mask to extract priority part (internal) */
+                               /* extract priority */
+#define        LOG_PRI(p)      ((p) & LOG_PRIMASK)
+#define        LOG_MAKEPRI(fac, pri)   (((fac) << 3) | (pri))
+
+#ifdef SYSLOG_NAMES
+#define        INTERNAL_NOPRI  0x10    /* the "no priority" priority */
+                               /* mark "facility" */
+#define        INTERNAL_MARK   LOG_MAKEPRI(LOG_NFACILITIES, 0)
+typedef struct _code {
+       char    *c_name;
+       int     c_val;
+} CODE;
+
+CODE prioritynames[] = {
+       { "alert",      LOG_ALERT },
+       { "crit",       LOG_CRIT },
+       { "debug",      LOG_DEBUG },
+       { "emerg",      LOG_EMERG },
+       { "err",        LOG_ERR },
+       { "error",      LOG_ERR },              /* DEPRECATED */
+       { "info",       LOG_INFO },
+       { "none",       INTERNAL_NOPRI },       /* INTERNAL */
+       { "notice",     LOG_NOTICE },
+       { "panic",      LOG_EMERG },            /* DEPRECATED */
+       { "warn",       LOG_WARNING },          /* DEPRECATED */
+       { "warning",    LOG_WARNING },
+       { NULL,         -1 }
+};
+#endif
+
+/* facility codes */
+#define        LOG_KERN        (0<<3)  /* kernel messages */
+#define        LOG_USER        (1<<3)  /* random user-level messages */
+#define        LOG_MAIL        (2<<3)  /* mail system */
+#define        LOG_DAEMON      (3<<3)  /* system daemons */
+#define        LOG_AUTH        (4<<3)  /* security/authorization messages */
+#define        LOG_SYSLOG      (5<<3)  /* messages generated internally by syslogd */
+#define        LOG_LPR         (6<<3)  /* line printer subsystem */
+#define        LOG_NEWS        (7<<3)  /* network news subsystem */
+#define        LOG_UUCP        (8<<3)  /* UUCP subsystem */
+#define        LOG_CRON        (9<<3)  /* clock daemon */
+#define        LOG_AUTHPRIV    (10<<3) /* security/authorization messages (private) */
+
+       /* other codes through 15 reserved for system use */
+#define        LOG_LOCAL0      (16<<3) /* reserved for local use */
+#define        LOG_LOCAL1      (17<<3) /* reserved for local use */
+#define        LOG_LOCAL2      (18<<3) /* reserved for local use */
+#define        LOG_LOCAL3      (19<<3) /* reserved for local use */
+#define        LOG_LOCAL4      (20<<3) /* reserved for local use */
+#define        LOG_LOCAL5      (21<<3) /* reserved for local use */
+#define        LOG_LOCAL6      (22<<3) /* reserved for local use */
+#define        LOG_LOCAL7      (23<<3) /* reserved for local use */
+
+#define        LOG_NFACILITIES 24      /* current number of facilities */
+#define        LOG_FACMASK     0x03f8  /* mask to extract facility part */
+                               /* facility of pri */
+#define        LOG_FAC(p)      (((p) & LOG_FACMASK) >> 3)
+
+#ifdef SYSLOG_NAMES
+CODE facilitynames[] = {
+       { "auth",       LOG_AUTH },
+       { "authpriv",   LOG_AUTHPRIV },
+       { "cron",       LOG_CRON },
+       { "daemon",     LOG_DAEMON },
+       { "kern",       LOG_KERN },
+       { "lpr",        LOG_LPR },
+       { "mail",       LOG_MAIL },
+       { "mark",       INTERNAL_MARK },        /* INTERNAL */
+       { "news",       LOG_NEWS },
+       { "security",   LOG_AUTH },             /* DEPRECATED */
+       { "syslog",     LOG_SYSLOG },
+       { "user",       LOG_USER },
+       { "uucp",       LOG_UUCP },
+       { "local0",     LOG_LOCAL0 },
+       { "local1",     LOG_LOCAL1 },
+       { "local2",     LOG_LOCAL2 },
+       { "local3",     LOG_LOCAL3 },
+       { "local4",     LOG_LOCAL4 },
+       { "local5",     LOG_LOCAL5 },
+       { "local6",     LOG_LOCAL6 },
+       { "local7",     LOG_LOCAL7 },
+       { NULL,         -1 }
+};
+#endif
+
+#ifdef KERNEL
+#define        LOG_PRINTF      -1      /* pseudo-priority to indicate use of printf */
+#endif
+
+/*
+ * arguments to setlogmask.
+ */
+#define        LOG_MASK(pri)   (1 << (pri))            /* mask for one priority */
+#define        LOG_UPTO(pri)   ((1 << ((pri)+1)) - 1)  /* all priorities through pri */
+
+/*
+ * Option flags for openlog.
+ *
+ * LOG_ODELAY no longer does anything.
+ * LOG_NDELAY is the inverse of what it used to be.
+ */
+#define        LOG_PID         0x01    /* log the pid with each message */
+#define        LOG_CONS        0x02    /* log on the console if errors in sending */
+#define        LOG_ODELAY      0x04    /* delay open until first syslog() (default) */
+#define        LOG_NDELAY      0x08    /* don't delay open */
+#define        LOG_NOWAIT      0x10    /* don't wait for console forks: DEPRECATED */
+#define        LOG_PERROR      0x20    /* log to stderr as well */
+
+#ifndef KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#ifdef __GNUC__
+/* This define avoids name pollution if we're using GNU stdarg.h */
+#define __need___va_list
+#include <stdarg.h>
+#endif
+
+void   closelog __P((void));
+void   openlog __P((__const char *, int, int));
+int    setlogmask __P((int));
+void   syslog __P((int, __const char *, ...))
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)
+       __attribute__ ((format (printf, 2, 0)))
+#endif
+       ;
+#ifdef __GNUC_VA_LIST
+void   vsyslog __P((int, __const char *, __gnuc_va_list));
+#else
+void   vsyslog __P(());
+#endif
+
+__END_DECLS
+
+#endif /* !KERNEL */
+
+#endif /* _SYS_LOG_H */
diff --git a/include/sys/termios.h b/include/sys/termios.h
new file mode 100644 (file)
index 0000000..3e18805
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef _SYS_TERMIOS_H
+#define _SYS_TERMIOS_H
+#include <termios.h>
+#endif
diff --git a/include/sys/time.h b/include/sys/time.h
new file mode 100644 (file)
index 0000000..98e51c0
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef _SYS_TIME_H
+#define _SYS_TIME_H
+
+#include <features.h>
+#include <linux/types.h>
+#include <linux/time.h>
+
+#define        DST_NONE        0       /* not on dst */
+#define        DST_USA         1       /* USA style dst */
+#define        DST_AUST        2       /* Australian style dst */
+#define        DST_WET         3       /* Western European dst */
+#define        DST_MET         4       /* Middle European dst */
+#define        DST_EET         5       /* Eastern European dst */
+#define        DST_CAN         6       /* Canada */
+#define        DST_GB          7       /* Great Britain and Eire */
+#define        DST_RUM         8       /* Rumania */
+#define        DST_TUR         9       /* Turkey */
+#define        DST_AUSTALT     10      /* Australian style with shift in 1986 */
+
+#ifdef __SVR4_I386_ABI_L1__
+typedef struct timestruc {
+    time_t tv_sec;
+    long   tv_nsec;
+} timestruc_t;
+#endif /* __SVR4_I386_ABI_L1__ */
+
+/*
+ * Operations on timevals.
+ *
+ * NB: timercmp does not work for >= or <=.
+ * 
+ */
+#define        timerisset(tvp)         ((tvp)->tv_sec || (tvp)->tv_usec)
+#define        timercmp(tvp, uvp, cmp) \
+       (((tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec) \
+       || (tvp)->tv_sec cmp (uvp)->tv_sec)
+#define        timerclear(tvp)         ((tvp)->tv_sec = (tvp)->tv_usec = 0)
+
+#include <time.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+extern int     __gettimeofday __P ((struct timeval * __tp,
+                       struct timezone * __tz));
+extern int     gettimeofday __P ((struct timeval * __tp,
+                       struct timezone * __tz));
+extern int     __settimeofday __P ((__const struct timeval *__tv,
+                       __const struct timezone *__tz));
+extern int     settimeofday __P ((__const struct timeval *__tv,
+                       __const struct timezone *__tz));
+
+extern int     __select __P ((int __width, fd_set * __readfds,
+                       fd_set * __writefds, fd_set * __exceptfds,
+                       struct timeval * __timeout));
+extern int     select __P ((int __width, fd_set * __readfds,
+                       fd_set * __writefds, fd_set * __exceptfds,
+                       struct timeval * __timeout));
+
+extern int     __getitimer __P ((int __which,
+                       struct itimerval *__value));
+extern int     getitimer __P ((int __which,
+                       struct itimerval *__value));
+extern int     __setitimer __P ((int __which,
+                       __const struct itimerval *__value,
+                       struct itimerval *__ovalue));
+extern int     setitimer __P ((int __which,
+                       __const struct itimerval *__value,
+                       struct itimerval *__ovalue));
+
+extern int     __adjtime __P ((struct timeval * __itv,
+                       struct timeval * __otv));
+extern int     adjtime __P ((struct timeval * __itv,
+                       struct timeval * __otv));
+
+extern int     __utimes __P((char *__path, struct timeval *tvp));
+extern int     utimes __P((char *__path, struct timeval *tvp));
+
+__END_DECLS
+
+#endif /*_SYS_TIME_H*/
diff --git a/include/sys/times.h b/include/sys/times.h
new file mode 100644 (file)
index 0000000..b6defa8
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _SYS_TIMES_H
+#define _SYS_TIMES_H
+
+#include <features.h>
+#include <sys/types.h>
+#include <time.h>
+
+struct tms {
+       clock_t tms_utime;
+       clock_t tms_stime;
+       clock_t tms_cutime;
+       clock_t tms_cstime;
+};
+
+__BEGIN_DECLS
+
+extern clock_t times __P ((struct tms * __tp));
+
+__END_DECLS
+
+#endif
diff --git a/include/sys/types.h b/include/sys/types.h
new file mode 100644 (file)
index 0000000..4a5cdfa
--- /dev/null
@@ -0,0 +1,4 @@
+#include <stddef.h>
+#include <sys/bitypes.h>
+#include <linux/types.h>
+#include <gnu/types.h>
diff --git a/include/sys/uio.h b/include/sys/uio.h
new file mode 100644 (file)
index 0000000..87120e6
--- /dev/null
@@ -0,0 +1,65 @@
+/* Copyright (C) 1991, 1992 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, 1992 Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef _SYS_UIO_H
+
+#define _SYS_UIO_H     1
+#include <features.h>
+
+__BEGIN_DECLS
+
+#define        __need_size_t
+#include <stddef.h>
+
+/* That is a klude for Linux. */
+#ifdef __linux__
+#include <linux/socket.h>
+#endif
+
+#ifndef __LINUX_UIO_H
+
+/* Structure describing a section of memory.  */
+
+struct iovec
+{
+  /* Starting address.  */
+  __ptr_t iov_base;
+  /* Length in bytes.  */
+  size_t iov_len;
+};
+
+#endif
+
+/* Read data from file descriptor FD, and put the result in the
+   buffers described by VECTOR, which is a vector of COUNT `struct iovec's.
+   The buffers are filled in the order specified.
+   Operates just like `read' (see <unistd.h>) except that data are
+   put in VECTOR instead of a contiguous buffer.  */
+int readv __P ((int __fd, __const struct iovec * __vector, size_t __count));
+
+/* Write data pointed by the buffers described by VECTOR, which
+   is a vector of COUNT `struct iovec's, to file descriptor FD.
+   The data is written in the order specified.
+   Operates just like `write' (see <unistd.h>) except that the data
+   are taken from VECTOR instead of a contiguous buffer.  */
+int writev __P ((int __fd, __const struct iovec * __vector, size_t __count));
+
+
+__END_DECLS
+
+#endif /* sys/uio.h */
diff --git a/include/sys/un.h b/include/sys/un.h
new file mode 100644 (file)
index 0000000..efb674c
--- /dev/null
@@ -0,0 +1 @@
+#include <linux/un.h>
diff --git a/include/sys/utsname.h b/include/sys/utsname.h
new file mode 100644 (file)
index 0000000..0cbc37f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __SYS_UTSNAME_H
+#define __SYS_UTSNAME_H
+
+#include <features.h>
+#include <sys/param.h>
+
+struct utsname {
+       char sysname[65];
+       char nodename[65];
+       char release[65];
+       char version[65];
+       char machine[65];
+       char domainname[65];
+};
+
+extern int uname __P ((struct utsname * __utsbuf));
+
+#endif
diff --git a/include/sys/vfs.h b/include/sys/vfs.h
new file mode 100644 (file)
index 0000000..1018591
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _SYS_VFS_H
+#define _SYS_VFS_H
+
+#include <features.h>
+#include <linux/vfs.h>
+
+__BEGIN_DECLS
+
+extern int __statfs __P ((__const char *__path, struct statfs *__buf));
+extern int statfs __P ((__const char *__path, struct statfs *__buf));
+
+extern int __fstatfs __P ((int __fildes, struct statfs *__buf));
+extern int fstatfs __P ((int __fildes, struct statfs *__buf));
+
+__END_DECLS
+
+#endif /*_SYS_VFS_H */
diff --git a/include/sys/vm86.h b/include/sys/vm86.h
new file mode 100644 (file)
index 0000000..851814e
--- /dev/null
@@ -0,0 +1,125 @@
+#if !__AS386_16__
+
+#ifndef _SYS_VM86_H
+#define _SYS_VM86_H
+
+#include <features.h>
+#ifndef _LINUX_VM86_H
+#define _LINUX_VM86_H
+
+/*
+ * I'm guessing at the VIF/VIP flag usage, but hope that this is how
+ * the Pentium uses them. Linux will return from vm86 mode when both
+ * VIF and VIP is set.
+ *
+ * On a Pentium, we could probably optimize the virtual flags directly
+ * in the eflags register instead of doing it "by hand" in vflags...
+ *
+ * Linus
+ */
+
+#define TF_MASK                0x00000100
+#define IF_MASK                0x00000200
+#define IOPL_MASK      0x00003000
+#define NT_MASK                0x00004000
+#define VM_MASK                0x00020000
+#define AC_MASK                0x00040000
+#define VIF_MASK       0x00080000      /* virtual interrupt flag */
+#define VIP_MASK       0x00100000      /* virtual interrupt pending */
+#define ID_MASK                0x00200000
+
+#define BIOSSEG                0x0f000
+
+#define CPU_086                0
+#define CPU_186                1
+#define CPU_286                2
+#define CPU_386                3
+#define CPU_486                4
+#define CPU_586                5
+
+/*
+ * Return values for the 'vm86()' system call
+ */
+#define VM86_TYPE(retval)      ((retval) & 0xff)
+#define VM86_ARG(retval)       ((retval) >> 8)
+
+#define VM86_SIGNAL    0       /* return due to signal */
+#define VM86_UNKNOWN   1       /* unhandled GP fault - IO-instruction or similar */
+#define VM86_INTx      2       /* int3/int x instruction (ARG = x) */
+#define VM86_STI       3       /* sti/popf/iret instruction enabled virtual interrupts */
+
+/*
+ * This is the stack-layout when we have done a "SAVE_ALL" from vm86
+ * mode - the main change is that the old segment descriptors aren't
+ * useful any more and are forced to be zero by the kernel (and the
+ * hardware when a trap occurs), and the real segment descriptors are
+ * at the end of the structure. Look at ptrace.h to see the "normal"
+ * setup.
+ */
+
+struct vm86_regs {
+/*
+ * normal regs, with special meaning for the segment descriptors..
+ */
+       long ebx;
+       long ecx;
+       long edx;
+       long esi;
+       long edi;
+       long ebp;
+       long eax;
+       long __null_ds;
+       long __null_es;
+       long __null_fs;
+       long __null_gs;
+       long orig_eax;
+       long eip;
+       unsigned short cs, __csh;
+       long eflags;
+       long esp;
+       unsigned short ss, __ssh;
+/*
+ * these are specific to v86 mode:
+ */
+       unsigned short es, __esh;
+       unsigned short ds, __dsh;
+       unsigned short fs, __fsh;
+       unsigned short gs, __gsh;
+};
+
+struct revectored_struct {
+       unsigned long __map[8];                 /* 256 bits */
+};
+
+struct vm86_struct {
+       struct vm86_regs regs;
+       unsigned long flags;
+       unsigned long screen_bitmap;
+       unsigned long cpu_type;
+       struct revectored_struct int_revectored;
+       struct revectored_struct int21_revectored;
+};
+
+/*
+ * flags masks
+ */
+#define VM86_SCREEN_BITMAP     0x0001
+
+#ifdef __KERNEL__
+
+void handle_vm86_fault(struct vm86_regs *, long);
+void handle_vm86_debug(struct vm86_regs *, long);
+
+#endif
+
+#endif
+
+__BEGIN_DECLS
+
+extern vm86(struct vm86_struct * __info);
+
+__END_DECLS
+
+#endif /*_SYS_VM86_H */
+
+#endif
diff --git a/include/sys/wait.h b/include/sys/wait.h
new file mode 100644 (file)
index 0000000..95f1b2e
--- /dev/null
@@ -0,0 +1,146 @@
+/* Copyright (C) 1991, 1992 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, 1992 Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/*
+ *     POSIX Standard: 3.2.1 Wait for Process Termination      <sys/wait.h>
+ */
+
+#ifndef        _SYS_WAIT_H
+
+#define        _SYS_WAIT_H     1
+#include <features.h>
+
+__BEGIN_DECLS
+
+#include <gnu/types.h>
+
+/* This will define the `W*' macros for the flag
+   bits to `waitpid', `wait3', and `wait4'.  */
+#include <waitflags.h>
+
+#ifdef __USE_BSD
+
+/* Lots of hair to allow traditional BSD use of `union wait'
+   as well as POSIX.1 use of `int' for the status word.  */
+
+#ifdef __GNUC__
+#define        __WAIT_INT(status)                                                    \
+  (__extension__ ({ union { __typeof(status) __in; int __i; } __u;           \
+                   __u.__in = (status); __u.__i; }))
+#else
+#define        __WAIT_INT(status)      (*(int *) &(status))
+#endif
+
+/* This is the type of the argument to `wait'.  With GCC 2.6.1 and later,
+   the funky union causes redeclarations with either `int *' or `union wait
+   *' to be allowed without complaint.  __WAIT_STATUS_DEFN is the type used
+   in the actual function definitions. */
+
+/* g++ in gcc 2.6.1 doesn't work. Maybe 2.7.x. H.J. */
+#if !defined (__GNUC__) || defined (__cplusplus) || \
+        __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || \
+        (defined(_MIT_POSIX_THREADS) && _MIT_POSIX_THREADS > 0)
+#define        __WAIT_STATUS   __ptr_t
+#define        __WAIT_STATUS_DEFN      __ptr_t
+#else
+/* This works in GCC 2.6.1 and later.  */
+typedef union
+  {
+    union wait *__uptr;
+    int *__iptr;
+  } __WAIT_STATUS __attribute__ ((transparent_union));
+#define        __WAIT_STATUS_DEFN      int *
+#endif
+
+#else /* Don't use BSD.  */
+
+#define        __WAIT_INT(status)      (status)
+#define        __WAIT_STATUS           int *
+
+#endif /* Use BSD.  */
+
+/* This will define all the `__W*' macros.  */
+#include <waitstatus.h>
+
+#define        WEXITSTATUS(status)     __WEXITSTATUS(__WAIT_INT(status))
+#define        WTERMSIG(status)        __WTERMSIG(__WAIT_INT(status))
+#define        WSTOPSIG(status)        __WSTOPSIG(__WAIT_INT(status))
+#define        WIFEXITED(status)       __WIFEXITED(__WAIT_INT(status))
+#define        WIFSIGNALED(status)     __WIFSIGNALED(__WAIT_INT(status))
+#define        WIFSTOPPED(status)      __WIFSTOPPED(__WAIT_INT(status))
+
+#ifdef __USE_BSD
+#define        WCOREDUMP(status)       __WCOREDUMP(__WAIT_INT(status))
+#define        W_EXITCODE(ret, sig)    __W_EXITCODE(ret, sig)
+#define        W_STOPCODE(sig)         __W_STOPCODE(sig)
+#endif
+
+
+/* Wait for a child to die.  When one does, put its status in *STAT_LOC
+   and return its process ID.  For errors, return (pid_t) -1.  */
+extern __pid_t __wait __P ((__WAIT_STATUS __stat_loc));
+extern __pid_t wait __P ((__WAIT_STATUS __stat_loc));
+
+#ifdef __USE_BSD
+/* Special values for the PID argument to `waitpid' and `wait4'.  */
+#define        WAIT_ANY        (-1)    /* Any process.  */
+#define        WAIT_MYPGRP     0       /* Any process in my process group.  */
+#endif
+
+/* Wait for a child matching PID to die.
+   If PID is greater than 0, match any process whose process ID is PID.
+   If PID is (pid_t) -1, match any process.
+   If PID is (pid_t) 0, match any process with the
+   same process group as the current process.
+   If PID is less than -1, match any process whose
+   process group is the absolute value of PID.
+   If the WNOHANG bit is set in OPTIONS, and that child
+   is not already dead, return (pid_t) 0.  If successful,
+   return PID and store the dead child's status in STAT_LOC.
+   Return (pid_t) -1 for errors.  If the WUNTRACED bit is
+   set in OPTIONS, return status for stopped children; otherwise don't.  */
+extern __pid_t __waitpid __P ((__pid_t __pid, int *__stat_loc,
+                              int __options));
+extern __pid_t waitpid __P ((__pid_t __pid, int *__stat_loc,
+                            int __options));
+#ifdef __USE_BSD
+/* This being here makes the prototypes valid whether or not
+   we have already included <sys/resource.h> to define `struct rusage'.  */
+struct rusage;
+
+/* Wait for a child to exit.  When one does, put its status in *STAT_LOC and
+   return its process ID.  For errors return (pid_t) -1.  If USAGE is not
+   nil, store information about the child's resource usage there.  If the
+   WUNTRACED bit is set in OPTIONS, return status for stopped children;
+   otherwise don't.  */
+extern __pid_t __wait3 __P ((__WAIT_STATUS __stat_loc,
+                            int __options, struct rusage * __usage));
+extern __pid_t wait3 __P ((__WAIT_STATUS __stat_loc,
+                          int __options, struct rusage * __usage));
+
+/* PID is like waitpid.  Other args are like wait3.  */
+extern __pid_t __wait4 __P ((__pid_t __pid, __WAIT_STATUS __stat_loc,
+                            int __options, struct rusage *__usage));
+extern __pid_t wait4 __P ((__pid_t __pid, __WAIT_STATUS __stat_loc,
+                          int __options, struct rusage *__usage));
+#endif /* Use BSD.  */
+
+
+__END_DECLS
+
+#endif /* sys/wait.h  */
diff --git a/include/syscall.h b/include/syscall.h
new file mode 100644 (file)
index 0000000..fa08654
--- /dev/null
@@ -0,0 +1,6 @@
+#include <errno.h>
+
+#define __check_errno(__res)    ((__res) >= 0)
+
+#include <m68k/syscall.h>
+#include <sys/syscall.h>
diff --git a/include/syslog.h b/include/syslog.h
new file mode 100644 (file)
index 0000000..830b492
--- /dev/null
@@ -0,0 +1 @@
+#include <sys/syslog.h>
diff --git a/include/termcap.h b/include/termcap.h
new file mode 100644 (file)
index 0000000..a7ae37b
--- /dev/null
@@ -0,0 +1,21 @@
+
+#ifndef _TERMCAP_H
+#define _TERMCAP_H
+
+#include <features.h>
+#include <sys/types.h>
+
+extern char PC;
+extern char *UP;
+extern char *BC;
+extern int ospeed;
+
+extern int tgetent __P((char *, const char *));
+extern int tgetflag __P((const char *));
+extern int tgetnum __P((const char *));
+extern char *tgetstr __P((const char *, char **));
+
+extern int tputs __P((const char *, int, int (*)(int)));
+extern char *tgoto __P((const char *, int, int));
+
+#endif /* _TERMCAP_H */
diff --git a/include/termio.h b/include/termio.h
new file mode 100644 (file)
index 0000000..9e26956
--- /dev/null
@@ -0,0 +1 @@
+#include <termios.h>
diff --git a/include/termios.h b/include/termios.h
new file mode 100644 (file)
index 0000000..8dcb5bc
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef __TERMIOS_H
+#define __TERMIOS_H
+
+#include <features.h>
+#include <sys/types.h>
+#include <linux/termios.h>
+
+extern speed_t cfgetispeed __P ((struct termios *__termios_p));
+extern speed_t cfgetospeed __P ((struct termios *__termios_p));
+extern int cfsetispeed __P ((struct termios *__termios_p, speed_t __speed));
+extern int cfsetospeed __P ((struct termios *__termios_p, speed_t __speed));
+
+extern int tcspeed_to_number __P ((speed_t __speed));
+extern speed_t tcspeed_from_number __P ((int number));
+
+extern int cfgetispeedn __P ((struct termios *__termios_p));
+extern int cfgetospeedn __P ((struct termios *__termios_p));
+extern int cfsetispeedn __P ((struct termios *__termios_p, int __speed));
+extern int cfsetospeedn __P ((struct termios *__termios_p, int __speed));
+
+extern void cfmakeraw  __P ((struct termios *__t));
+
+extern int tcsetattr __P ((int __fd, int __opt, struct termios *__termios_p));
+extern int tcgetattr __P ((int __fildes, struct termios *__termios_p));
+extern int tcdrain __P ((int __fildes));
+extern int tcflow __P ((int __fildes, int __action));
+extern int tcflush __P ((int __fildes, int __queue_selector));
+extern int tcsendbreak __P ((int __fildes, int __duration));
+extern pid_t tcgetpgrp __P ((int __fildes));
+extern int tcsetpgrp __P ((int __fildes, pid_t __pgrp_id));
+
+#endif
diff --git a/include/time.h b/include/time.h
new file mode 100644 (file)
index 0000000..9bbcd8b
--- /dev/null
@@ -0,0 +1,128 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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, 1992 Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/*
+ *     ANSI Standard: 4.12 DATE and TIME       <time.h>
+ */
+
+#ifndef _TIME_H
+#define _TIME_H
+
+#include <features.h>
+#include <sys/time.h>
+
+#ifndef _TIME_T
+#define _TIME_T
+typedef long time_t;
+#endif
+
+#ifndef _CLOCK_T
+#define _CLOCK_T
+typedef long clock_t;
+#endif
+
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef unsigned int size_t;
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL   0
+#else
+#define NULL   ((void *) 0)
+#endif
+#endif
+
+#define CLOCKS_PER_SEC 100
+#define CLK_TCK                100     /* That must be the same as HZ ???? */
+
+struct tm {
+       int tm_sec;
+       int tm_min;
+       int tm_hour;
+       int tm_mday;
+       int tm_mon;
+       int tm_year;
+       int tm_wday;
+       int tm_yday;
+       int tm_isdst;
+       /* Those are for future use. */
+       long int __tm_gmtoff__;
+       __const char *__tm_zone__;
+};
+
+#define        __isleap(year)  \
+  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+
+extern char *tzname[2];
+extern int daylight;
+extern long int timezone;
+
+__BEGIN_DECLS
+
+extern int     stime __P ((time_t* __tptr));
+
+extern clock_t clock __P ((void));
+extern time_t  time __P ((time_t * __tp));
+extern __CONSTVALUE double difftime __P ((time_t __time2,
+                                         time_t __time1)) __CONSTVALUE2;
+extern time_t  mktime __P ((struct tm * __tp));
+
+extern char *  asctime __P ((__const struct tm * __tp));
+extern char *  ctime __P ((__const time_t * __tp));
+extern size_t  strftime __P ((char * __s, size_t __smax,
+                       __const char * __fmt, __const struct tm * __tp));
+extern char *  strptime __P ((__const char * __s, __const char * __fmt,
+                       struct tm * __tm));
+
+extern void    tzset __P ((void));
+
+extern struct tm*      gmtime __P ((__const time_t *__tp));
+extern struct tm*      localtime __P ((__const time_t * __tp));
+
+#ifdef __USE_MISC
+/* Miscellaneous functions many Unices inherited from the public domain
+  localtime package.  These are included only for compatibility.  */
+
+/* Like `mktime', but for TP represents Universal Time, not local time.  */
+extern time_t timegm __P ((struct tm *__tp));
+    
+/* Another name for `mktime'.  */
+extern time_t timelocal __P ((struct tm *__tp));
+
+#endif
+
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT)
+
+extern char    * asctime_r     __P((__const struct tm *, char *));
+extern char    * ctime_r       __P((__const time_t *, char *));
+extern struct tm* gmtime_r     __P((__const time_t *, struct tm *));
+extern struct tm* localtime_r  __P((__const time_t *, struct tm *));
+
+#endif
+
+struct timespec;
+
+/* IEEE Std 1003.1b-1993. */
+extern int nanosleep __P((__const struct timespec *__rqtp,
+               struct timespec *__rmtp));
+
+__END_DECLS
+
+#endif
diff --git a/include/unistd.h b/include/unistd.h
new file mode 100644 (file)
index 0000000..6c39b42
--- /dev/null
@@ -0,0 +1,108 @@
+/* unistd.h <ndf@linux.mit.edu> */
+#include <features.h>
+#include <sys/types.h>
+
+#ifndef __UNISTD_H
+#define __UNISTD_H
+
+#include <errno.h>
+#include <asm/unistd.h>
+
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+
+
+extern int close __P ((int));
+extern size_t read __P ((int __fd, char * __buf, size_t __nbytes));
+extern size_t write __P ((int __fd, __const char * __buf, size_t __n));
+extern off_t lseek __P ((int __fd, off_t __n, int __whence));
+extern int pipe __P ((int __pipedes[2]));
+extern unsigned int alarm __P ((unsigned int __seconds));
+extern int sleep __P ((unsigned int __seconds));
+extern void usleep __P ((unsigned long __microseconds));
+extern int pause __P ((void));
+extern char*    crypt __P((__const char *__key, __const char *__salt));
+extern int isatty __P ((int __fd));
+extern int readlink __P ((__const char *__path, char *__buf, size_t __len));
+extern int link __P ((__const char *__from, __const char *__to));
+extern int symlink __P ((__const char *__from, __const char *__to));
+extern int readlink __P ((__const char *__path, char *__buf, size_t __len));
+extern int unlink __P ((__const char *__name));
+extern char *getcwd __P ((char *__buf, size_t __size));
+extern int fchdir __P ((int __fd));
+extern int chdir __P ((__const char *__path));
+extern int chown __P ((__const char *__file,
+                       uid_t __owner, gid_t __group));
+
+extern int fchown __P ((int __fd,
+                       uid_t __owner, gid_t __group));
+
+extern int fsync __P ((int __fd));
+
+extern int sync __P ((void));
+
+extern int rmdir __P ((__const char *__path));
+
+extern int rename __P((__const char* _old, __const char* _new));
+
+extern int access __P ((__const char *__name, int __type));
+
+extern int      reboot __P ((int __magic, int __magic_too, int __flag));
+
+extern int mkstemp __P ((char * __template));
+extern char * mktemp __P ((char * __template));
+
+extern int _clone __P ((int (*fn)(void *arg), void *child_stack, int flags, void *arg));
+
+
+#if 0                                                                         
+#ifndef SYS_fork
+#define SYS_fork 2
+#endif
+
+#define vfork() ({ \
+register long __res __asm__ ("%d0"); \
+__asm__ __volatile__ ("trap  #0" \
+                      : "=g" (__res) \
+                      : "0" (SYS_fork) \
+                      : "%d0"); \
+__res; \
+})
+#endif
+
+#define vfork() ({                                             \
+register unsigned long __res __asm__ ("%d0") = __NR_fork;      \
+__asm__ __volatile__ ("trap  #0"                               \
+                      : "=g" (__res)                           \
+                      : "0" (__res)                            \
+                      : "%d0");                                        \
+if (__res >= (unsigned long)-4096) {                           \
+       errno = -__res;                                         \
+       __res = (pid_t)-1;                                      \
+}                                                              \
+(pid_t)__res;                                                  \
+})
+
+
+#define fork fork_not_available_use_vfork
+#define clone clone_not_available_use__clone
+               
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+
+#ifndef R_OK
+#define        R_OK    4               /* Test for read permission.  */
+#define        W_OK    2               /* Test for write permission.  */
+#define        X_OK    1               /* Test for execute permission.  */
+#define        F_OK    0               /* Test for existence.  */
+#endif
+
+#endif /* __UNISTD_H */
+
+
diff --git a/include/utime.h b/include/utime.h
new file mode 100644 (file)
index 0000000..7f82b9f
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __UTIME_H
+#define __UTIME_H
+
+#include <features.h>
+#include <sys/types.h>
+
+struct utimbuf {
+       time_t actime;
+       time_t modtime;
+};
+
+extern int utime __P ((char *__filename, struct utimbuf *__utimebuf));
+
+#endif
+
diff --git a/include/utmp.h b/include/utmp.h
new file mode 100644 (file)
index 0000000..9fe0e87
--- /dev/null
@@ -0,0 +1,52 @@
+/* utmp.h */
+
+#ifndef __UTMP_H
+#define __UTMP_H
+
+#include <features.h>
+#include <sys/types.h>
+#include <paths.h>
+#include <time.h>
+
+#define UT_UNKNOWN 0
+#define UT_LINESIZE 12
+#define UT_NAMESIZE 8
+#define UT_HOSTSIZE 16
+
+#define RUN_LVL 1
+#define BOOT_TIME 2
+#define NEW_TIME 3
+#define OLD_TIME 4
+
+#define INIT_PROCESS 5
+#define LOGIN_PROCESS 6
+#define USER_PROCESS 7
+#define DEAD_PROCESS 8
+
+struct utmp
+{
+  short   ut_type;                 /* type of login */
+  pid_t   ut_pid;                  /* pid of login-process */
+  char    ut_line[UT_LINESIZE];    /* devicename of tty -"/dev/", null-term */
+  char    ut_id[2];                /* abbrev. ttyname, as 01, s1 etc. */
+  time_t  ut_time;                 /* login time */
+  char    ut_user[UT_NAMESIZE];    /* username, not null-term */
+  char    ut_host[UT_HOSTSIZE];    /* hostname for remote login... */
+  long    ut_addr;                 /* IP addr of remote host */
+
+};
+
+extern void             setutent __P ((void));
+extern void             utmpname __P ((__const char *));
+extern struct utmp *    getutent __P ((void));
+extern struct utmp *    getutid __P ((struct utmp *));
+extern struct utmp *    getutline __P ((struct utmp *));
+extern struct utmp *    pututline __P ((struct utmp *));
+extern void             endutent __P ((void));
+
+#ifdef __LIBC__
+struct utmp *           __getutent __P ((int));
+#endif
+
+#endif /* __UTMP_H */
+
diff --git a/include/wait.h b/include/wait.h
new file mode 100644 (file)
index 0000000..cdb7714
--- /dev/null
@@ -0,0 +1,3 @@
+/* SVR4 ABI requires <wait.h> rather than <sys/wait.h> */
+
+#include <sys/wait.h>
diff --git a/libc/inet/Makefile b/libc/inet/Makefile
new file mode 100644 (file)
index 0000000..28565ce
--- /dev/null
@@ -0,0 +1,43 @@
+# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+# Copyright (C) 1998-1999 D. Jeff Dionne <jeff@rt-control.com>
+# Copyright (C) 1998      Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1999      D. Jeff Dionne <jeff@rt-control.com>
+# under the GNU Library General Public License.
+
+LIBC=../libc.a
+
+CC=m68k-pic-coff-gcc
+AR=m68k-pic-coff-ar
+RANLIB=m68k-pic-coff-ranlib
+
+CCFLAGS= -O2 -m68000 -msoft-float -fno-builtin -I../include
+
+ASRC=addr.c
+AOBJ=inet_aton.o inet_addr.o inet_ntoa.o
+
+RSRC=resolv.c
+ROBJ= encodeh.o decodeh.o encoded.o decoded.o lengthd.o encodeq.o \
+decodeq.o lengthq.o encodea.o decodea.o encodep.o decodep.o \
+formquery.o dnslookup.o resolveaddress.o resolvemailbox.o \
+opennameservers.o closenameservers.o resolvename.o gethostbyname.o\
+gethostbyaddr.o
+
+OBJ=$(AOBJ) $(ROBJ)
+
+CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
+
+all: $(LIBC)
+       @$(RM) $(OBJ)
+
+$(LIBC): $(LIBC)($(OBJ))
+
+$(LIBC)($(AOBJ)): $(ASRC)
+       $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+       $(AR) $(ARFLAGS) $@ $*.o
+
+$(LIBC)($(ROBJ)): $(RSRC)
+       $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+       $(AR) $(ARFLAGS) $@ $*.o
+
+clean:
+       rm -f *.o libc.a
diff --git a/libc/inet/addr.c b/libc/inet/addr.c
new file mode 100644 (file)
index 0000000..bb27753
--- /dev/null
@@ -0,0 +1,85 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include <netinet/in.h>
+
+
+#ifdef L_inet_aton
+int
+inet_aton(cp, inp)
+const char *cp;
+struct in_addr *inp;
+{
+  unsigned long addr;
+  int value;
+  int part;
+
+  if (!inp)
+    return 0;
+  
+  addr = 0;
+  for (part=1;part<=4;part++) {
+
+    if (!isdigit(*cp))
+      return 0;
+        
+    value = 0;
+    while (isdigit(*cp)) {
+      value *= 10;
+      value += *cp++ - '0';
+      if (value > 255)
+        return 0;
+    }
+    
+    if (*cp++ != ((part == 4) ? '\0' : '.'))
+      return 0;
+    
+    addr <<= 8;
+    addr |= value;
+  }
+  
+  inp->s_addr = htonl(addr);
+
+  return 1;
+}
+#endif
+
+#ifdef L_inet_addr
+unsigned long
+inet_addr(cp)
+const char *cp;
+{
+  struct in_addr a;
+  if (!inet_aton(cp, &a))
+    return -1;
+  else
+    return a.s_addr;
+}
+#endif
+
+#ifdef L_inet_ntoa
+
+extern char * itoa(int);  
+
+char *
+inet_ntoa(in)
+struct in_addr in;
+{
+  static char buf[18];
+  unsigned long addr = ntohl(in.s_addr);
+  
+  strcpy(buf, itoa((addr >> 24) & 0xff));
+  strcat(buf, ".");
+  strcat(buf, itoa((addr >> 16) & 0xff));
+  strcat(buf, ".");
+  strcat(buf, itoa((addr >> 8) & 0xff));
+  strcat(buf, ".");
+  strcat(buf, itoa(addr & 0xff));
+  
+  return buf;
+}
+#endif
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
new file mode 100644 (file)
index 0000000..b4cfab1
--- /dev/null
@@ -0,0 +1,892 @@
+/* resolv.c: DNS Resolver
+ *
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * This 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.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <cfgfile.h>
+#include <resolv.h>
+
+#define DNS_SERVICE 53
+#define MAX_RECURSE 5
+#define REPLY_TIMEOUT 10
+#define MAX_RETRIES 15
+
+#undef DEBUG
+#ifdef DEBUG
+#define DPRINTF(X,args...) printf(X,args...)
+#else
+#define DPRINTF(X,args...)
+#endif /* DEBUG */
+
+#ifdef L_encodeh
+int encode_header(struct resolv_header * h, unsigned char * dest, int maxlen)
+{
+       if (maxlen < 12)
+               return -1;
+
+       dest[0] = (h->id & 0xff00) >> 8;
+       dest[1] = (h->id & 0x00ff) >> 0;
+       dest[2] = (h->qr ? 0x80 : 0) |
+                 ((h->opcode & 0x0f) << 3) |
+                 (h->aa ? 0x04 : 0) |
+                 (h->tc ? 0x02 : 0) |
+                 (h->rd ? 0x01 : 0);
+       dest[3] = (h->ra ? 0x80 : 0) |
+                 (h->rcode & 0x0f);
+       dest[4] = (h->qdcount & 0xff00) >> 8;
+       dest[5] = (h->qdcount & 0x00ff) >> 0;
+       dest[6] = (h->ancount & 0xff00) >> 8;
+       dest[7] = (h->ancount & 0x00ff) >> 0;
+       dest[8] = (h->nscount & 0xff00) >> 8;
+       dest[9] = (h->nscount & 0x00ff) >> 0;
+       dest[10] = (h->arcount & 0xff00) >> 8;
+       dest[11] = (h->arcount & 0x00ff) >> 0;
+       
+       return 12;
+}
+#endif
+
+#ifdef L_decodeh
+int decode_header(unsigned char * data, struct resolv_header * h)
+{
+       h->id = (data[0] << 8) | data[1];
+       h->qr = (data[2] & 0x80) ? 1 : 0;
+       h->opcode = (data[2] >> 3) & 0x0f;
+       h->aa = (data[2] & 0x04) ? 1 : 0;
+       h->tc = (data[2] & 0x02) ? 1 : 0;
+       h->rd = (data[2] & 0x01) ? 1 : 0;
+       h->ra = (data[3] & 0x80) ? 1 : 0;
+       h->rcode = data[3] & 0x0f;
+       h->qdcount = (data[4] << 8) | data[5];
+       h->ancount = (data[6] << 8) | data[7];
+       h->nscount = (data[8] << 8) | data[9];
+       h->arcount = (data[10] << 8) | data[11];
+       
+       return 12;
+}
+#endif
+
+#ifdef L_encoded
+/* Encode a dotted string into nameserver transport-level encoding.
+   This routine is fairly dumb, and doesn't attempt to compress
+   the data */
+   
+int encode_dotted(const char * dotted, unsigned char * dest, int maxlen)
+{
+       int used=0;
+
+       while(dotted && *dotted) {
+               char * c = strchr(dotted, '.');
+               int l = c ? c - dotted : strlen(dotted);
+               
+               if (l >= (maxlen-used-1))
+                       return -1;
+               
+               dest[used++] = l;
+               memcpy(dest+used, dotted, l);
+               used += l;
+               
+               if (c)
+                       dotted = c+1;
+               else
+                       break;
+       }
+       
+       if (maxlen < 1)
+               return -1;
+               
+       dest[used++] = 0;
+       
+       return used;
+}
+#endif
+
+#ifdef L_decoded
+/* Decode a dotted string from nameserver transport-level encoding.
+   This routine understands compressed data. */
+
+int decode_dotted(const unsigned char * data, int offset, 
+       char * dest, int maxlen)
+{
+       int l;
+       int measure=1;
+       int total = 0;
+       int used=0;
+       
+       if (!data)
+               return -1;
+       
+       while ((measure && total++), (l=data[offset++])) {
+               
+               if ((l & 0xc0) == (0xc0)) {
+                       if (measure)
+                               total++;
+                       /* compressed item, redirect */
+                       offset = ((l & 0x3f) << 8) | data[offset];
+                       measure = 0;
+                       continue;
+               }
+       
+               if ((used+l+1) >= maxlen)
+                       return -1;
+                       
+               memcpy(dest+used, data+offset, l);
+               offset += l;
+               used += l;
+               if (measure)
+                       total += l;
+               
+               if (data[offset] != 0)
+                       dest[used++] = '.';
+               else
+                       dest[used++] = '\0';
+       }
+       
+       DPRINTF("Total decode len = %d\n", total);
+       
+       return total;
+}
+#endif
+
+#ifdef L_lengthd
+
+int length_dotted(const unsigned char * data, int offset)
+{
+       int orig_offset = offset;
+       int l;
+       
+       if (!data)
+               return -1;
+       
+       while ((l=data[offset++])) {
+               
+               if ((l & 0xc0) == (0xc0)) {
+                       offset++;
+                       break;
+               }
+               
+               offset += l;
+       }
+       
+       return offset-orig_offset;
+}
+#endif
+
+#ifdef L_encodeq
+int encode_question(struct resolv_question * q,
+       unsigned char * dest, int maxlen)
+{
+       int i;
+
+       i = encode_dotted(q->dotted, dest, maxlen);
+       if (i < 0)
+               return i;
+       
+       dest += i;
+       maxlen -= i;
+       
+       if (maxlen < 4)
+               return -1;
+       
+       dest[0] = (q->qtype & 0xff00) >> 8;
+       dest[1] = (q->qtype & 0x00ff) >> 0;
+       dest[2] = (q->qclass & 0xff00) >> 8;
+       dest[3] = (q->qclass & 0x00ff) >> 0;
+       
+       return i+4;
+}
+#endif
+
+#ifdef L_decodeq
+int decode_question(unsigned char * message, int offset,
+       struct resolv_question * q)
+{
+       char temp[256];
+       int i;
+
+       i = decode_dotted(message, offset, temp, 256);
+       if (i < 0)
+               return i;
+               
+       offset += i;
+       
+       q->dotted = strdup(temp);
+       q->qtype  = (message[offset+0] << 8) | message[offset+1];
+       q->qclass = (message[offset+2] << 8) | message[offset+3];
+       
+       return i+4;
+}
+#endif
+
+#ifdef L_lengthq
+int length_question(unsigned char * message, int offset)
+{
+       int i;
+
+       i = length_dotted(message, offset);
+       if (i < 0)
+               return i;
+       
+       return i+4;
+}
+#endif
+
+#ifdef L_encodea
+int encode_answer(struct resolv_answer * a,
+       unsigned char * dest, int maxlen)
+{
+       int i;
+
+       i = encode_dotted(a->dotted, dest, maxlen);
+       if (i < 0)
+               return i;
+       
+       dest += i;
+       maxlen -= i;
+       
+       if (maxlen < (10+a->rdlength))
+               return -1;
+       
+       *dest++ = (a->atype & 0xff00) >> 8;
+       *dest++ = (a->atype & 0x00ff) >> 0;
+       *dest++ = (a->aclass & 0xff00) >> 8;
+       *dest++ = (a->aclass & 0x00ff) >> 0;
+       *dest++ = (a->ttl & 0xff000000) >> 24;
+       *dest++ = (a->ttl & 0x00ff0000) >> 16;
+       *dest++ = (a->ttl & 0x0000ff00) >> 8;
+       *dest++ = (a->ttl & 0x000000ff) >> 0;
+       *dest++ = (a->rdlength & 0xff00) >> 8;
+       *dest++ = (a->rdlength & 0x00ff) >> 0;
+       memcpy(dest, a->rdata, a->rdlength);
+       
+       return i+10+a->rdlength;
+}
+#endif
+
+#ifdef L_decodea
+int decode_answer(unsigned char * message, int offset,
+       struct resolv_answer * a)
+{
+       char temp[256];
+       int i;
+
+       i = decode_dotted(message, offset, temp, 256);
+       if (i < 0)
+               return i;
+       
+       message += offset+i;
+       
+       a->dotted = strdup(temp);
+       a->atype  = (message[0] << 8) | message[1]; message += 2;
+       a->aclass = (message[0] << 8) | message[1]; message += 2;
+       a->ttl = (message[0] << 24) |
+                (message[1] << 16) |
+                (message[2] << 8) |
+                (message[3] << 0);
+       message += 4;
+       a->rdlength = (message[0] << 8) | message[1]; message += 2;
+       a->rdata = message;
+       a->rdoffset = offset+i+10;
+       
+       DPRINTF("i=%d,rdlength=%d\n", i, a->rdlength);
+       
+       return i+10+a->rdlength;
+}
+#endif
+
+#ifdef L_encodep
+int encode_packet(struct resolv_header * h,
+       struct resolv_question ** q,
+       struct resolv_question ** an,
+       struct resolv_question ** ns,
+       struct resolv_question ** ar,
+       unsigned char * dest, int maxlen)
+{
+       int i, total=0;
+       int j;
+
+       i = encode_header(h, dest, maxlen);
+       if (i < 0)
+               return i;
+       
+       dest += i;
+       maxlen -= i;
+       total += i;
+       
+       for(j=0;j<h->qdcount;j++) {
+               i = encode_question(q[j], dest, maxlen);
+               if (i < 0)
+                       return i;
+               dest += i;
+               maxlen -= i;
+               total += i;
+       }
+
+       for(j=0;j<h->ancount;j++) {
+               i = encode_answer(an[j], dest, maxlen);
+               if (i < 0)
+                       return i;
+               dest += i;
+               maxlen -= i;
+               total += i;
+       }
+       for(j=0;j<h->nscount;j++) {
+               i = encode_answer(ns[j], dest, maxlen);
+               if (i < 0)
+                       return i;
+               dest += i;
+               maxlen -= i;
+               total += i;
+       }
+       for(j=0;j<h->arcount;j++) {
+               i = encode_answer(ar[j], dest, maxlen);
+               if (i < 0)
+                       return i;
+               dest += i;
+               maxlen -= i;
+               total += i;
+       }
+       
+       return total;
+}
+#endif
+
+#ifdef L_decodep
+int decode_packet(unsigned char * data, struct resolv_header * h)
+{
+       return decode_header(data, h);
+}
+#endif
+
+#ifdef L_formquery
+int form_query(int id, const char * name, int type, unsigned char * packet, int maxlen)
+{
+       struct resolv_header h;
+       struct resolv_question q;
+       int i,j;
+       
+       memset(&h, 0, sizeof(h));
+       h.id = id;
+       h.qdcount = 1;
+       
+       q.dotted = (char*)name;
+       q.qtype = type;
+       q.qclass = 1 /*CLASS_IN*/;
+       
+       i = encode_header(&h, packet, maxlen);
+       if (i < 0)
+               return i;
+       
+       j = encode_question(&q, packet+i, maxlen-i);
+       if (j < 0)
+               return j;
+
+       return i+j;
+}
+#endif
+
+#ifdef L_dnslookup
+
+int dns_caught_signal = 0;
+void dns_catch_signal(int signo) {
+       dns_caught_signal = 1;
+}      
+
+int dns_lookup(const char * name, int type, int nscount, const char ** nsip,
+       unsigned char ** outpacket, struct resolv_answer * a)
+{
+       static int id=1;
+       int i,j,len;
+       int fd;
+       int pos;
+       static int ns = 0;
+       struct sockaddr_in sa;
+       int oldalarm;
+       __sighandler_t oldhandler;
+       struct resolv_header h;
+       struct resolv_question q;
+       int retries = 0;
+       unsigned char * packet = malloc(512);
+       
+       if (!packet)
+               goto fail1;
+               
+       DPRINTF("Looking up type %d answer for '%s'\n", type, name);
+
+       
+       if (!nscount)
+               goto fail1;
+               
+       ns %= nscount;
+       
+       fd = -1;
+       
+       while (retries++ < MAX_RETRIES) {
+       
+               if (fd != -1)
+                       close(fd);
+
+               fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+       
+               if (fd==-1)
+                       goto fail2;
+               
+       
+               memset(packet, 0, 512);
+
+               memset(&h, 0, sizeof(h));
+               h.id = ++id;
+               h.qdcount = 1;
+               h.rd = 1;
+               
+               DPRINTF("encoding header\n");
+
+               i = encode_header(&h, packet, 512);
+               if (i < 0)
+                       goto fail3;
+
+               q.dotted = (char*)name;
+               q.qtype = type;
+               q.qclass = 1 /*CLASS_IN*/;
+       
+               j = encode_question(&q, packet+i, 512-i);
+               if (j < 0)
+                       goto fail3;
+       
+               len = i+j;
+
+               DPRINTF("On try %d, sending query to port %d of machine %s\n",
+                       retries, DNS_SERVICE, nsip[ns]);
+
+               sa.sin_family = AF_INET;
+               sa.sin_port = htons(DNS_SERVICE);
+               sa.sin_addr.s_addr = inet_addr(nsip[ns]);
+
+               if (connect(fd, (struct sockaddr*)&sa, sizeof(sa))==-1) {
+                       if (errno == ENETUNREACH) {
+                               /* routing error, presume not transient */
+                               goto tryall;
+                       } else
+                               /* retry */
+                               break;
+               }
+               
+               DPRINTF("Transmitting packet of length %d, id=%d, qr=%d\n", 
+                       len, h.id, h.qr);
+
+               send(fd, packet, len, 0);
+
+               dns_caught_signal = 0;
+               oldalarm = alarm(REPLY_TIMEOUT);
+               oldhandler = signal(SIGALRM, dns_catch_signal);
+       
+               i = recv(fd, packet, 512, 0);
+               
+               alarm(0);
+               signal(SIGALRM, oldhandler);
+               alarm(oldalarm);
+               
+               DPRINTF("Timeout=%d, len=%d\n",
+                       dns_caught_signal, i);
+               
+               if (dns_caught_signal)
+                       /* timed out, so retry send and receive,
+                          to next nameserver on queue */
+                       goto again;
+               
+               if (i < 12)
+                       /* too short ! */
+                       goto again;
+               
+               decode_header(packet, &h);
+               
+               DPRINTF("id = %d, qr = %d\n",
+                       h.id, h.qr);
+               
+               if ((h.id != id) || (!h.qr))
+                       /* unsolicited */
+                       goto again;
+               
+               DPRINTF("Got response (i think)!\n");
+               DPRINTF("qrcount=%d,ancount=%d,nscount=%d,arcount=%d\n",
+                       h.qdcount, h.ancount, h.nscount, h.arcount);
+               DPRINTF("opcode=%d,aa=%d,tc=%d,rd=%d,ra=%d,rcode=%d\n",
+                       h.opcode,h.aa,h.tc,h.rd,h.ra,h.rcode);
+               
+               if ((h.rcode) || (h.ancount < 1)) {
+                       /* negative result, not present */
+                       goto tryall;
+               }
+                       
+               pos = 12;
+
+               for(j=0;j<h.qdcount;j++) {
+                       DPRINTF("Skipping question %d at %d\n", j, pos);
+                       i = length_question(packet, pos);
+                       DPRINTF("Length of question %d is %d\n", j, i);
+                       if (i < 0)
+                               goto again;
+                       pos += i;
+               }
+               DPRINTF("Decoding answer at pos %d\n", pos);
+               
+               i = decode_answer(packet, pos, a);
+               
+               if (i<0) {
+                       DPRINTF("failed decode %d\n", i);
+                       goto again;
+               }
+               
+               DPRINTF("Answer name = |%s|\n", a->dotted);
+               DPRINTF("Answer type = |%d|\n", a->atype);
+               
+               close(fd);
+               
+               if (outpacket)
+                       *outpacket = packet;
+               else
+                       free(packet);
+               return (0); /* success! */
+
+       tryall:
+               /* if there are other nameservers, give them a go,
+                  otherwise return with error */
+               if (retries >= nscount)
+                       break;
+       again:
+               ns = (ns + 1) % nscount;
+               continue;
+       }
+       
+       
+
+fail3: 
+       close(fd);
+fail2:
+       free(packet);
+fail1:
+       return -1;
+}
+#endif
+
+#ifdef L_resolveaddress
+
+int resolve_address(const char * address, 
+       int nscount, const char ** nsip, 
+       struct in_addr * in)
+{
+       unsigned char * packet;
+       struct resolv_answer a;
+       char temp[256];
+       int i;
+       int nest=0;
+       
+       if (!address || !in)
+               return -1;
+               
+       strcpy(temp, address);
+       
+       for(;;) {
+       
+               i = dns_lookup(temp, 1, nscount, nsip, &packet, &a);
+       
+               if (i<0)
+                       return -1;
+       
+               free(a.dotted);
+               
+               if (a.atype == 5) { /* CNAME*/
+                       i = decode_dotted(packet, a.rdoffset, temp, 256);
+                       free(packet);
+                       
+                       if (i <0)
+                               return -1;
+                       if (++nest > MAX_RECURSE)
+                               return -1;
+                       continue;
+               } else if (a.atype == 1) { /* ADDRESS */
+                       free(packet);
+                       break;
+               } else {
+                       free(packet);
+                       return -1;
+               }
+       }
+       
+       if (in)
+               memcpy(in, a.rdata, 4);
+               
+       return 0;
+}
+#endif
+
+#ifdef L_resolvemailbox
+
+int resolve_mailbox(const char * address, 
+       int nscount, const char ** nsip, 
+       struct in_addr * in)
+{
+       struct resolv_answer a;
+       unsigned char * packet;
+       char temp[256];
+       int nest=0;
+       int i;
+       
+       if (!address || !in)
+               return -1;
+       
+       /* look up mail exchange */
+       i = dns_lookup(address, 15, nscount, nsip, &packet, &a);
+       
+       strcpy(temp, address);
+       
+       if (i>=0) {
+               i = decode_dotted(packet, a.rdoffset+2, temp, 256);
+               free(packet);
+       }
+       
+       for(;;) {
+       
+               i = dns_lookup(temp, 1, nscount, nsip, &packet, &a);
+       
+               if (i<0)
+                       return -1;
+       
+               free(a.dotted);
+               
+               if (a.atype == 5) { /* CNAME*/
+                       i = decode_dotted(packet, a.rdoffset, temp, 256);
+                       free(packet);
+                       if (i<0)
+                               return i;
+                       if (++nest > MAX_RECURSE)
+                               return -1;
+                       continue;
+               } else if (a.atype == 1) { /* ADDRESS */
+                       free(packet);
+                       break;
+               } else {
+                       free(packet);
+                       return -1;
+               }
+       }
+
+       if (in)
+               memcpy(in, a.rdata, 4);
+               
+       return 0;
+}
+#endif
+
+extern int nameservers;
+extern const char * nameserver[3];
+
+#ifdef L_opennameservers
+
+int nameservers;
+const char * nameserver[3];
+
+int open_nameservers()
+{
+       FILE *fp;
+       char **arg;
+       int i;
+
+       if (fp = fopen("/etc/resolv.conf", "r")) {
+               if (arg = cfgfind(fp, "nameserver")) {
+                       for (i=1; arg[i]; i++) {
+                               nameserver[nameservers++] = strdup(arg[i]);
+                       }
+               }
+               fclose(fp);
+       }
+       return 0;
+}
+#endif
+
+#ifdef L_closenameservers
+void close_nameservers(void) {
+
+       while(nameservers>0)
+               free(nameserver[--nameservers]);
+}
+#endif
+
+
+#ifdef L_resolvename
+
+char * resolve_name(const char * name, int mailbox)
+{
+       struct in_addr in;
+       int i;
+       
+       /* shortcut: is it a valid IP address to begin with? */
+       if (inet_aton(name, &in))
+               return name;
+               
+       open_nameservers();
+       
+       DPRINTF("looking up '%s', mailbox=%d, nameservers=%d\n",
+               name, mailbox, nameservers);
+       
+       if (mailbox)
+               i = resolve_mailbox(name, nameservers, nameserver, &in);
+       else
+               i = resolve_address(name, nameservers, nameserver, &in);
+       
+       if (i<0)
+               return 0;
+       
+       DPRINTF("success = '%s'\n", inet_ntoa(in));
+               
+       return inet_ntoa(in);
+}
+#endif
+
+#ifdef L_gethostbyname
+
+struct hostent * gethostbyname(const char * name)
+{
+       static struct hostent h;
+       static char namebuf[256];
+       static struct in_addr in;
+       static struct in_addr *addr_list[2];
+       unsigned char * packet;
+       struct resolv_answer a;
+       int i;
+       int nest=0;
+
+       open_nameservers();
+       
+       if (!name)
+               return 0;
+               
+       memset(&h, 0, sizeof(h));
+       
+       addr_list[0] = &in;
+       addr_list[1] = 0;
+       
+       strcpy(namebuf, name);
+       
+       for(;;) {
+       
+               i = dns_lookup(namebuf, 1, nameservers, nameserver, &packet, &a);
+       
+               if (i<0)
+                       return 0;
+                       
+               strcpy(namebuf, a.dotted);
+               free(a.dotted);
+               
+               
+               if (a.atype == 5) { /* CNAME*/
+                       i = decode_dotted(packet, a.rdoffset, namebuf, 256);
+                       free(packet);
+                       
+                       if (i <0)
+                               return 0;
+                       if (++nest > MAX_RECURSE)
+                               return 0;
+                       continue;
+               } else if (a.atype == 1) { /* ADDRESS */
+                       memcpy(&in, a.rdata, sizeof(in));
+                       h.h_name = namebuf;
+                       h.h_addrtype = AF_INET;
+                       h.h_length = sizeof(in);
+                       h.h_addr_list = (char**)addr_list;
+                       free(packet);
+                       break;
+               } else {
+                       free(packet);
+                       return 0;
+               }
+       }
+               
+       return &h;
+}
+#endif
+
+#ifdef L_gethostbyaddr
+
+struct hostent * gethostbyaddr(const char * addr, int len, int type)
+{
+       static struct hostent h;
+       static char namebuf[256];
+       static struct in_addr in;
+       static struct in_addr *addr_list[2];
+       unsigned char * packet;
+       struct resolv_answer a;
+       int i;
+       int nest=0;
+       
+       if (!addr || (len != sizeof(in)) || (type != AF_INET))
+               return 0;
+               
+       memcpy(&in.s_addr, addr, len);
+
+       open_nameservers();
+               
+       memset(&h, 0, sizeof(h));
+       
+       addr_list[0] = &in;
+       addr_list[1] = 0;
+       
+       sprintf(namebuf, "%d.%d.%d.%d.in-addr.arpa",
+               (in.s_addr >> 24) & 0xff,
+               (in.s_addr >> 16) & 0xff,
+               (in.s_addr >> 8) & 0xff,
+               (in.s_addr >> 0) & 0xff
+               );
+       
+       for(;;) {
+       
+               i = dns_lookup(namebuf, 12, nameservers, nameserver, &packet, &a);
+       
+               if (i<0)
+                       return 0;
+                       
+               strcpy(namebuf, a.dotted);
+               free(a.dotted);
+               
+               if (a.atype == 5) { /* CNAME*/
+                       i = decode_dotted(packet, a.rdoffset, namebuf, 256);
+                       free(packet);
+                       
+                       if (i <0)
+                               return 0;
+                       if (++nest > MAX_RECURSE)
+                               return 0;
+                       continue;
+               } else if (a.atype == 12) { /* ADDRESS */
+                       i = decode_dotted(packet, a.rdoffset, namebuf, 256);
+                       free(packet);
+                       
+                       h.h_name = namebuf;
+                       h.h_addrtype = AF_INET;
+                       h.h_length = sizeof(in);
+                       h.h_addr_list = (char**)addr_list;
+                       break;
+               } else {
+                       free(packet);
+                       return 0;
+               }
+       }
+               
+       return &h;
+}
+#endif
diff --git a/libc/inet/rpc/Makefile b/libc/inet/rpc/Makefile
new file mode 100644 (file)
index 0000000..3884341
--- /dev/null
@@ -0,0 +1,27 @@
+CC=m68k-pic-coff-gcc
+AR=m68k-pic-coff-ar
+RANLIB=m68k-pic-coff-ranlib
+
+CFLAGS= -O2 -fomit-frame-pointer -Dlinux -I../include
+
+OBJS = auth_none.o auth_unix.o authunix_prot.o \
+       bindresvport.o clnt_generic.o clnt_perror.o \
+       clnt_raw.o clnt_simple.o clnt_tcp.o clnt_udp.o \
+       get_myaddress.o getrpcent.o getrpcport.o pmap_clnt.o \
+       pmap_getmaps.o pmap_getport.o pmap_prot.o pmap_prot2.o \
+       pmap_rmt.o rpc_callmsg.o rpc_commondata.o \
+       rpc_dtablesize.o rpc_prot.o svc.o svc_auth.o \
+       svc_auth_unix.o svc_raw.o svc_run.o svc_simple.o \
+       svc_tcp.o svc_udp.o xdr.o xdr_array.o xdr_float.o \
+       xdr_mem.o xdr_rec.o xdr_reference.o xdr_stdio.o
+
+LIBC = ../libc.a
+
+all: $(LIBC)
+
+$(LIBC): $(LIBC)($(OBJS))
+
+clean:
+       rm -f *.[oa] *~ core
+
+
diff --git a/libc/inet/rpc/auth_none.c b/libc/inet/rpc/auth_none.c
new file mode 100644 (file)
index 0000000..630037f
--- /dev/null
@@ -0,0 +1,133 @@
+/* @(#)auth_none.c     2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * auth_none.c
+ * Creates a client authentication handle for passing "null" 
+ * credentials and verifiers to remote systems. 
+ * 
+ * Copyright (C) 1984, Sun Microsystems, Inc. 
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#define MAX_MARSHEL_SIZE 20
+
+/*
+ * Authenticator operations routines
+ */
+static void    authnone_verf();
+static void    authnone_destroy();
+static bool_t  authnone_marshal();
+static bool_t  authnone_validate();
+static bool_t  authnone_refresh();
+
+static struct auth_ops ops = {
+       authnone_verf,
+       authnone_marshal,
+       authnone_validate,
+       authnone_refresh,
+       authnone_destroy
+};
+
+static struct authnone_private {
+       AUTH    no_client;
+       char    marshalled_client[MAX_MARSHEL_SIZE];
+       u_int   mcnt;
+} *authnone_private;
+
+AUTH *
+authnone_create()
+{
+       register struct authnone_private *ap = authnone_private;
+       XDR xdr_stream;
+       register XDR *xdrs;
+
+       if (ap == 0) {
+               ap = (struct authnone_private *)calloc(1, sizeof (*ap));
+               if (ap == 0)
+                       return (0);
+               authnone_private = ap;
+       }
+       if (!ap->mcnt) {
+               ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
+               ap->no_client.ah_ops = &ops;
+               xdrs = &xdr_stream;
+               xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE,
+                   XDR_ENCODE);
+               (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
+               (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
+               ap->mcnt = XDR_GETPOS(xdrs);
+               XDR_DESTROY(xdrs);
+       }
+       return (&ap->no_client);
+}
+
+/*ARGSUSED*/
+static bool_t
+authnone_marshal(client, xdrs)
+       AUTH *client;
+       XDR *xdrs;
+{
+       register struct authnone_private *ap = authnone_private;
+
+       if (ap == 0)
+               return (0);
+       return ((*xdrs->x_ops->x_putbytes)(xdrs,
+           ap->marshalled_client, ap->mcnt));
+}
+
+static void 
+authnone_verf()
+{
+}
+
+static bool_t
+authnone_validate()
+{
+
+       return (TRUE);
+}
+
+static bool_t
+authnone_refresh()
+{
+
+       return (FALSE);
+}
+
+static void
+authnone_destroy()
+{
+}
diff --git a/libc/inet/rpc/auth_unix.c b/libc/inet/rpc/auth_unix.c
new file mode 100644 (file)
index 0000000..87ff2b6
--- /dev/null
@@ -0,0 +1,319 @@
+/* @(#)auth_unix.c     2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * auth_unix.c, Implements UNIX style authentication parameters. 
+ *  
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The system is very weak.  The client uses no encryption for it's
+ * credentials and only sends null verifiers.  The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ *
+ */
+
+#include <stdio.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * Unix authenticator operations vector
+ */
+static void    authunix_nextverf();
+static bool_t  authunix_marshal();
+static bool_t  authunix_validate();
+static bool_t  authunix_refresh();
+static void    authunix_destroy();
+
+static struct auth_ops auth_unix_ops = {
+       authunix_nextverf,
+       authunix_marshal,
+       authunix_validate,
+       authunix_refresh,
+       authunix_destroy
+};
+
+/*
+ * This struct is pointed to by the ah_private field of an auth_handle.
+ */
+struct audata {
+       struct opaque_auth      au_origcred;    /* original credentials */
+       struct opaque_auth      au_shcred;      /* short hand cred */
+       u_long                  au_shfaults;    /* short hand cache faults */
+       char                    au_marshed[MAX_AUTH_BYTES];
+       u_int                   au_mpos;        /* xdr pos at end of marshed */
+};
+#define        AUTH_PRIVATE(auth)      ((struct audata *)auth->ah_private)
+
+static bool_t marshal_new_auth();
+
+
+/*
+ * Create a unix style authenticator.
+ * Returns an auth handle with the given stuff in it.
+ */
+AUTH *
+authunix_create(machname, uid, gid, len, aup_gids)
+       char *machname;
+       int uid;
+       int gid;
+       register int len;
+       int *aup_gids;
+{
+       struct authunix_parms aup;
+       char mymem[MAX_AUTH_BYTES];
+       struct timeval now;
+       XDR xdrs;
+       register AUTH *auth;
+       register struct audata *au;
+
+       /*
+        * Allocate and set up auth handle
+        */
+       auth = (AUTH *)mem_alloc(sizeof(*auth));
+#ifndef KERNEL
+       if (auth == NULL) {
+               (void)fprintf(stderr, "authunix_create: out of memory\n");
+               return (NULL);
+       }
+#endif
+       au = (struct audata *)mem_alloc(sizeof(*au));
+#ifndef KERNEL
+       if (au == NULL) {
+               (void)fprintf(stderr, "authunix_create: out of memory\n");
+               return (NULL);
+       }
+#endif
+       auth->ah_ops = &auth_unix_ops;
+       auth->ah_private = (caddr_t)au;
+       auth->ah_verf = au->au_shcred = _null_auth;
+       au->au_shfaults = 0;
+
+       /*
+        * fill in param struct from the given params
+        */
+       (void)gettimeofday(&now,  (struct timezone *)0);
+       aup.aup_time = now.tv_sec;
+       aup.aup_machname = machname;
+       aup.aup_uid = uid;
+       aup.aup_gid = gid;
+       aup.aup_len = (u_int)len;
+       aup.aup_gids = aup_gids;
+
+       /*
+        * Serialize the parameters into origcred
+        */
+       xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
+       if (! xdr_authunix_parms(&xdrs, &aup)) 
+               abort();
+       au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
+       au->au_origcred.oa_flavor = AUTH_UNIX;
+#ifdef KERNEL
+       au->au_origcred.oa_base = mem_alloc((u_int) len);
+#else
+       if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
+               (void)fprintf(stderr, "authunix_create: out of memory\n");
+               return (NULL);
+       }
+#endif
+       bcopy(mymem, au->au_origcred.oa_base, (u_int)len);
+
+       /*
+        * set auth handle to reflect new cred.
+        */
+       auth->ah_cred = au->au_origcred;
+       marshal_new_auth(auth);
+       return (auth);
+}
+
+/*
+ * Returns an auth handle with parameters determined by doing lots of
+ * syscalls.
+ */
+AUTH *
+authunix_create_default()
+{
+       register int len;
+       char machname[MAX_MACHINE_NAME + 1];
+       register int uid;
+       register int gid;
+       int gids[NGRPS];
+
+       if (gethostname(machname, MAX_MACHINE_NAME) == -1)
+               abort();
+       machname[MAX_MACHINE_NAME] = 0;
+       uid = geteuid();
+       gid = getegid();
+       if ((len = getgroups(NGRPS, gids)) < 0)
+               abort();
+       return (authunix_create(machname, uid, gid, len, gids));
+}
+
+/*
+ * authunix operations
+ */
+
+static void
+authunix_nextverf(auth)
+       AUTH *auth;
+{
+       /* no action necessary */
+}
+
+static bool_t
+authunix_marshal(auth, xdrs)
+       AUTH *auth;
+       XDR *xdrs;
+{
+       register struct audata *au = AUTH_PRIVATE(auth);
+
+       return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
+}
+
+static bool_t
+authunix_validate(auth, verf)
+       register AUTH *auth;
+       struct opaque_auth verf;
+{
+       register struct audata *au;
+       XDR xdrs;
+
+       if (verf.oa_flavor == AUTH_SHORT) {
+               au = AUTH_PRIVATE(auth);
+               xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE);
+
+               if (au->au_shcred.oa_base != NULL) {
+                       mem_free(au->au_shcred.oa_base,
+                           au->au_shcred.oa_length);
+                       au->au_shcred.oa_base = NULL;
+               }
+               if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
+                       auth->ah_cred = au->au_shcred;
+               } else {
+                       xdrs.x_op = XDR_FREE;
+                       (void)xdr_opaque_auth(&xdrs, &au->au_shcred);
+                       au->au_shcred.oa_base = NULL;
+                       auth->ah_cred = au->au_origcred;
+               }
+               marshal_new_auth(auth);
+       }
+       return (TRUE);
+}
+
+static bool_t
+authunix_refresh(auth)
+       register AUTH *auth;
+{
+       register struct audata *au = AUTH_PRIVATE(auth);
+       struct authunix_parms aup;
+       struct timeval now;
+       XDR xdrs;
+       register int stat;
+
+       if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
+               /* there is no hope.  Punt */
+               return (FALSE);
+       }
+       au->au_shfaults ++;
+
+       /* first deserialize the creds back into a struct authunix_parms */
+       aup.aup_machname = NULL;
+       aup.aup_gids = (int *)NULL;
+       xdrmem_create(&xdrs, au->au_origcred.oa_base,
+           au->au_origcred.oa_length, XDR_DECODE);
+       stat = xdr_authunix_parms(&xdrs, &aup);
+       if (! stat) 
+               goto done;
+
+       /* update the time and serialize in place */
+       (void)gettimeofday(&now, (struct timezone *)0);
+       aup.aup_time = now.tv_sec;
+       xdrs.x_op = XDR_ENCODE;
+       XDR_SETPOS(&xdrs, 0);
+       stat = xdr_authunix_parms(&xdrs, &aup);
+       if (! stat)
+               goto done;
+       auth->ah_cred = au->au_origcred;
+       marshal_new_auth(auth);
+done:
+       /* free the struct authunix_parms created by deserializing */
+       xdrs.x_op = XDR_FREE;
+       (void)xdr_authunix_parms(&xdrs, &aup);
+       XDR_DESTROY(&xdrs);
+       return (stat);
+}
+
+static void
+authunix_destroy(auth)
+       register AUTH *auth;
+{
+       register struct audata *au = AUTH_PRIVATE(auth);
+
+       mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
+
+       if (au->au_shcred.oa_base != NULL)
+               mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
+
+       mem_free(auth->ah_private, sizeof(struct audata));
+
+       if (auth->ah_verf.oa_base != NULL)
+               mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
+
+       mem_free((caddr_t)auth, sizeof(*auth));
+}
+
+/*
+ * Marshals (pre-serializes) an auth struct.
+ * sets private data, au_marshed and au_mpos
+ */
+static bool_t
+marshal_new_auth(auth)
+       register AUTH *auth;
+{
+       XDR             xdr_stream;
+       register XDR    *xdrs = &xdr_stream;
+       register struct audata *au = AUTH_PRIVATE(auth);
+
+       xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
+       if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
+           (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
+               perror("auth_none.c - Fatal marshalling problem");
+       } else {
+               au->au_mpos = XDR_GETPOS(xdrs);
+       }
+       XDR_DESTROY(xdrs);
+}
diff --git a/libc/inet/rpc/authunix_prot.c b/libc/inet/rpc/authunix_prot.c
new file mode 100644 (file)
index 0000000..a60d99a
--- /dev/null
@@ -0,0 +1,66 @@
+/* @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * authunix_prot.c
+ * XDR for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * XDR for unix authentication parameters.
+ */
+bool_t
+xdr_authunix_parms(xdrs, p)
+       register XDR *xdrs;
+       register struct authunix_parms *p;
+{
+
+       if (xdr_u_long(xdrs, &(p->aup_time))
+           && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
+           && xdr_int(xdrs, &(p->aup_uid))
+           && xdr_int(xdrs, &(p->aup_gid))
+           && xdr_array(xdrs, (caddr_t *)&(p->aup_gids),
+                   &(p->aup_len), NGRPS, sizeof(int), xdr_int) ) {
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
diff --git a/libc/inet/rpc/bindresvport.c b/libc/inet/rpc/bindresvport.c
new file mode 100644 (file)
index 0000000..71803dd
--- /dev/null
@@ -0,0 +1,78 @@
+static  char sccsid[] = "@(#)bindresvport.c    2.2 88/07/29 4.0 RPCSRC 1.8 88/02/08 SMI";
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1987 by Sun Microsystems, Inc.
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+bindresvport(sd, sin)
+       int sd;
+       struct sockaddr_in *sin;
+{
+       int res;
+       static short port;
+       struct sockaddr_in myaddr;
+       extern int errno;
+       int i;
+
+#define STARTPORT 600
+#define ENDPORT (IPPORT_RESERVED - 1)
+#define NPORTS (ENDPORT - STARTPORT + 1)
+
+       if (sin == (struct sockaddr_in *)0) {
+               sin = &myaddr;
+               bzero(sin, sizeof (*sin));
+               sin->sin_family = AF_INET;
+       } else if (sin->sin_family != AF_INET) {
+               errno = EPFNOSUPPORT;
+               return (-1);
+       }
+       if (port == 0) {
+               port = (getpid() % NPORTS) + STARTPORT;
+       }
+       res = -1;
+       errno = EADDRINUSE;
+       for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) {
+               sin->sin_port = htons(port++);
+               if (port > ENDPORT) {
+                       port = STARTPORT;
+               }
+               res = bind(sd, sin, sizeof(struct sockaddr_in));
+       }
+       return (res);
+}
diff --git a/libc/inet/rpc/clnt_generic.c b/libc/inet/rpc/clnt_generic.c
new file mode 100644 (file)
index 0000000..9124ccf
--- /dev/null
@@ -0,0 +1,115 @@
+/* @(#)clnt_generic.c  2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";
+#endif
+/*
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netdb.h>
+
+/*
+ * Generic client creation: takes (hostname, program-number, protocol) and
+ * returns client handle. Default options are set, which the user can 
+ * change using the rpc equivalent of ioctl()'s.
+ */
+CLIENT *
+clnt_create(hostname, prog, vers, proto)
+       char *hostname;
+       unsigned prog;
+       unsigned vers;
+       char *proto;
+{
+       struct hostent *h;
+       struct protoent *p;
+       struct sockaddr_in sin;
+       int sock;
+       struct timeval tv;
+       CLIENT *client;
+
+       h = gethostbyname(hostname);
+       if (h == NULL) {
+               rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
+               return (NULL);
+       }
+       if (h->h_addrtype != AF_INET) {
+               /*
+                * Only support INET for now
+                */
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = EAFNOSUPPORT; 
+               return (NULL);
+       }
+#ifdef linux
+       bzero((char *) &sin, sizeof(sin));
+#endif
+       sin.sin_family = h->h_addrtype;
+       sin.sin_port = 0;
+#ifndef linux
+       bzero(sin.sin_zero, sizeof(sin.sin_zero));
+#endif
+       bcopy(h->h_addr, (char*)&sin.sin_addr, h->h_length);
+       p = getprotobyname(proto);
+       if (p == NULL) {
+               rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
+               rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; 
+               return (NULL);
+       }
+       sock = RPC_ANYSOCK;
+       switch (p->p_proto) {
+       case IPPROTO_UDP:
+               tv.tv_sec = 5;
+               tv.tv_usec = 0;
+               client = clntudp_create(&sin, prog, vers, tv, &sock);
+               if (client == NULL) {
+                       return (NULL);
+               }
+               tv.tv_sec = 25;
+               clnt_control(client, CLSET_TIMEOUT, &tv);
+               break;
+       case IPPROTO_TCP:
+               client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
+               if (client == NULL) {
+                       return (NULL);
+               }
+               tv.tv_sec = 25;
+               tv.tv_usec = 0;
+               clnt_control(client, CLSET_TIMEOUT, &tv);
+               break;
+       default:
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; 
+               return (NULL);
+       }
+       return (client);
+}
diff --git a/libc/inet/rpc/clnt_perror.c b/libc/inet/rpc/clnt_perror.c
new file mode 100644 (file)
index 0000000..80f51aa
--- /dev/null
@@ -0,0 +1,310 @@
+/* @(#)clnt_perror.c   2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_perror.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+#include <stdio.h>
+
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/clnt.h>
+
+extern char *sys_errlist[];
+static char *auth_errmsg();
+
+extern char *strcpy();
+
+static char *buf;
+
+static char *
+_buf()
+{
+
+       if (buf == 0)
+               buf = (char *)malloc(256);
+       return (buf);
+}
+
+/*
+ * Print reply error info
+ */
+char *
+clnt_sperror(rpch, s)
+       CLIENT *rpch;
+       char *s;
+{
+#if 0
+       struct rpc_err e;
+       void clnt_perrno();
+       char *err;
+       char *str = _buf();
+       char *strstart = str;
+
+       if (str == 0)
+               return (0);
+       CLNT_GETERR(rpch, &e);
+
+       (void) sprintf(str, "%s: ", s);  
+       str += strlen(str);
+
+       (void) strcpy(str, clnt_sperrno(e.re_status));  
+       str += strlen(str);
+
+       switch (e.re_status) {
+       case RPC_SUCCESS:
+       case RPC_CANTENCODEARGS:
+       case RPC_CANTDECODERES:
+       case RPC_TIMEDOUT:     
+       case RPC_PROGUNAVAIL:
+       case RPC_PROCUNAVAIL:
+       case RPC_CANTDECODEARGS:
+       case RPC_SYSTEMERROR:
+       case RPC_UNKNOWNHOST:
+       case RPC_UNKNOWNPROTO:
+       case RPC_PMAPFAILURE:
+       case RPC_PROGNOTREGISTERED:
+       case RPC_FAILED:
+               break;
+
+       case RPC_CANTSEND:
+       case RPC_CANTRECV:
+               (void) sprintf(str, "; errno = %s",
+                   sys_errlist[e.re_errno]); 
+               str += strlen(str);
+               break;
+
+       case RPC_VERSMISMATCH:
+               (void) sprintf(str,
+                       "; low version = %lu, high version = %lu", 
+                       e.re_vers.low, e.re_vers.high);
+               str += strlen(str);
+               break;
+
+       case RPC_AUTHERROR:
+               err = auth_errmsg(e.re_why);
+               (void) sprintf(str,"; why = ");
+               str += strlen(str);
+               if (err != NULL) {
+                       (void) sprintf(str, "%s",err);
+               } else {
+                       (void) sprintf(str,
+                               "(unknown authentication error - %d)",
+                               (int) e.re_why);
+               }
+               str += strlen(str);
+               break;
+
+       case RPC_PROGVERSMISMATCH:
+               (void) sprintf(str, 
+                       "; low version = %lu, high version = %lu", 
+                       e.re_vers.low, e.re_vers.high);
+               str += strlen(str);
+               break;
+
+       default:        /* unknown */
+               (void) sprintf(str, 
+                       "; s1 = %lu, s2 = %lu", 
+                       e.re_lb.s1, e.re_lb.s2);
+               str += strlen(str);
+               break;
+       }
+       (void) sprintf(str, "\n");
+       return(strstart) ;
+#endif
+}
+
+void
+clnt_perror(rpch, s)
+       CLIENT *rpch;
+       char *s;
+{
+       (void) fprintf(stderr,"%s",clnt_sperror(rpch,s));
+}
+
+
+struct rpc_errtab {
+       enum clnt_stat status;
+       char *message;
+};
+#if 0
+static struct rpc_errtab  rpc_errlist[] = {
+       { RPC_SUCCESS, 
+               "RPC: Success" }, 
+       { RPC_CANTENCODEARGS, 
+               "RPC: Can't encode arguments" },
+       { RPC_CANTDECODERES, 
+               "RPC: Can't decode result" },
+       { RPC_CANTSEND, 
+               "RPC: Unable to send" },
+       { RPC_CANTRECV, 
+               "RPC: Unable to receive" },
+       { RPC_TIMEDOUT, 
+               "RPC: Timed out" },
+       { RPC_VERSMISMATCH, 
+               "RPC: Incompatible versions of RPC" },
+       { RPC_AUTHERROR, 
+               "RPC: Authentication error" },
+       { RPC_PROGUNAVAIL, 
+               "RPC: Program unavailable" },
+       { RPC_PROGVERSMISMATCH, 
+               "RPC: Program/version mismatch" },
+       { RPC_PROCUNAVAIL, 
+               "RPC: Procedure unavailable" },
+       { RPC_CANTDECODEARGS, 
+               "RPC: Server can't decode arguments" },
+       { RPC_SYSTEMERROR, 
+               "RPC: Remote system error" },
+       { RPC_UNKNOWNHOST, 
+               "RPC: Unknown host" },
+       { RPC_UNKNOWNPROTO,
+               "RPC: Unknown protocol" },
+       { RPC_PMAPFAILURE, 
+               "RPC: Port mapper failure" },
+       { RPC_PROGNOTREGISTERED, 
+               "RPC: Program not registered"},
+       { RPC_FAILED, 
+               "RPC: Failed (unspecified error)"}
+};
+#endif
+
+/*
+ * This interface for use by clntrpc
+ */
+char *
+clnt_sperrno(stat)
+       enum clnt_stat stat;
+{
+#if 0
+       int i;
+
+       for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) {
+               if (rpc_errlist[i].status == stat) {
+                       return (rpc_errlist[i].message);
+               }
+       }
+#endif
+       return ("RPC: (unknown error code)");
+}
+
+void
+clnt_perrno(num)
+       enum clnt_stat num;
+{
+       (void) fprintf(stderr,"%s",clnt_sperrno(num));
+}
+
+
+char *
+clnt_spcreateerror(s)
+       char *s;
+{
+#if 0
+       extern int sys_nerr;
+       extern char *sys_errlist[];
+       char *str = _buf();
+
+       if (str == 0)
+               return(0);
+       (void) sprintf(str, "%s: ", s);
+       (void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat));
+       switch (rpc_createerr.cf_stat) {
+       case RPC_PMAPFAILURE:
+               (void) strcat(str, " - ");
+               (void) strcat(str,
+                   clnt_sperrno(rpc_createerr.cf_error.re_status));
+               break;
+
+       case RPC_SYSTEMERROR:
+               (void) strcat(str, " - ");
+               if (rpc_createerr.cf_error.re_errno > 0
+                   && rpc_createerr.cf_error.re_errno < sys_nerr)
+                       (void) strcat(str,
+                           sys_errlist[rpc_createerr.cf_error.re_errno]);
+               else
+                       (void) sprintf(&str[strlen(str)], "Error %d",
+                           rpc_createerr.cf_error.re_errno);
+               break;
+       }
+       (void) strcat(str, "\n");
+       return (str);
+#endif
+}
+
+void
+clnt_pcreateerror(s)
+       char *s;
+{
+       (void) fprintf(stderr,"%s",clnt_spcreateerror(s));
+}
+
+struct auth_errtab {
+       enum auth_stat status;  
+       char *message;
+};
+
+static struct auth_errtab auth_errlist[] = {
+       { AUTH_OK,
+               "Authentication OK" },
+       { AUTH_BADCRED,
+               "Invalid client credential" },
+       { AUTH_REJECTEDCRED,
+               "Server rejected credential" },
+       { AUTH_BADVERF,
+               "Invalid client verifier" },
+       { AUTH_REJECTEDVERF,
+               "Server rejected verifier" },
+       { AUTH_TOOWEAK,
+               "Client credential too weak" },
+       { AUTH_INVALIDRESP,
+               "Invalid server verifier" },
+       { AUTH_FAILED,
+               "Failed (unspecified error)" },
+};
+
+static char *
+auth_errmsg(stat)
+       enum auth_stat stat;
+{
+       int i;
+
+       for (i = 0; i < sizeof(auth_errlist)/sizeof(struct auth_errtab); i++) {
+               if (auth_errlist[i].status == stat) {
+                       return(auth_errlist[i].message);
+               }
+       }
+       return(NULL);
+}
diff --git a/libc/inet/rpc/clnt_raw.c b/libc/inet/rpc/clnt_raw.c
new file mode 100644 (file)
index 0000000..89059ae
--- /dev/null
@@ -0,0 +1,238 @@
+/* @(#)clnt_raw.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_raw.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Memory based rpc for simple testing and timing.
+ * Interface to create an rpc client and server in the same process.
+ * This lets us similate rpc and get round trip overhead, without
+ * any interference from the kernal.
+ */
+
+#include <rpc/rpc.h>
+
+#define MCALL_MSG_SIZE 24
+
+/*
+ * This is the "network" we will be moving stuff over.
+ */
+static struct clntraw_private {
+       CLIENT  client_object;
+       XDR     xdr_stream;
+       char    _raw_buf[UDPMSGSIZE];
+       char    mashl_callmsg[MCALL_MSG_SIZE];
+       u_int   mcnt;
+} *clntraw_private;
+
+static enum clnt_stat  clntraw_call();
+static void            clntraw_abort();
+static void            clntraw_geterr();
+static bool_t          clntraw_freeres();
+static bool_t          clntraw_control();
+static void            clntraw_destroy();
+
+static struct clnt_ops client_ops = {
+       clntraw_call,
+       clntraw_abort,
+       clntraw_geterr,
+       clntraw_freeres,
+       clntraw_destroy,
+       clntraw_control
+};
+
+void   svc_getreq();
+
+/*
+ * Create a client handle for memory based rpc.
+ */
+CLIENT *
+clntraw_create(prog, vers)
+       u_long prog;
+       u_long vers;
+{
+       register struct clntraw_private *clp = clntraw_private;
+       struct rpc_msg call_msg;
+       XDR *xdrs = &clp->xdr_stream;
+       CLIENT  *client = &clp->client_object;
+
+       if (clp == 0) {
+               clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
+               if (clp == 0)
+                       return (0);
+               clntraw_private = clp;
+       }
+       /*
+        * pre-serialize the staic part of the call msg and stash it away
+        */
+       call_msg.rm_direction = CALL;
+       call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+       call_msg.rm_call.cb_prog = prog;
+       call_msg.rm_call.cb_vers = vers;
+       xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); 
+       if (! xdr_callhdr(xdrs, &call_msg)) {
+               perror("clnt_raw.c - Fatal header serialization error.");
+       }
+       clp->mcnt = XDR_GETPOS(xdrs);
+       XDR_DESTROY(xdrs);
+
+       /*
+        * Set xdrmem for client/server shared buffer
+        */
+       xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+
+       /*
+        * create client handle
+        */
+       client->cl_ops = &client_ops;
+       client->cl_auth = authnone_create();
+       return (client);
+}
+
+static enum clnt_stat 
+clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
+       CLIENT *h;
+       u_long proc;
+       xdrproc_t xargs;
+       caddr_t argsp;
+       xdrproc_t xresults;
+       caddr_t resultsp;
+       struct timeval timeout;
+{
+       register struct clntraw_private *clp = clntraw_private;
+       register XDR *xdrs = &clp->xdr_stream;
+       struct rpc_msg msg;
+       enum clnt_stat status;
+       struct rpc_err error;
+
+       if (clp == 0)
+               return (RPC_FAILED);
+call_again:
+       /*
+        * send request
+        */
+       xdrs->x_op = XDR_ENCODE;
+       XDR_SETPOS(xdrs, 0);
+       ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
+       if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
+           (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+           (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+           (! (*xargs)(xdrs, argsp))) {
+               return (RPC_CANTENCODEARGS);
+       }
+       (void)XDR_GETPOS(xdrs);  /* called just to cause overhead */
+
+       /*
+        * We have to call server input routine here because this is
+        * all going on in one process. Yuk.
+        */
+       svc_getreq(1);
+
+       /*
+        * get results
+        */
+       xdrs->x_op = XDR_DECODE;
+       XDR_SETPOS(xdrs, 0);
+       msg.acpted_rply.ar_verf = _null_auth;
+       msg.acpted_rply.ar_results.where = resultsp;
+       msg.acpted_rply.ar_results.proc = xresults;
+       if (! xdr_replymsg(xdrs, &msg))
+               return (RPC_CANTDECODERES);
+       _seterr_reply(&msg, &error);
+       status = error.re_status;
+
+       if (status == RPC_SUCCESS) {
+               if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+                       status = RPC_AUTHERROR;
+               }
+       }  /* end successful completion */
+       else {
+               if (AUTH_REFRESH(h->cl_auth))
+                       goto call_again;
+       }  /* end of unsuccessful completion */
+
+       if (status == RPC_SUCCESS) {
+               if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+                       status = RPC_AUTHERROR;
+               }
+               if (msg.acpted_rply.ar_verf.oa_base != NULL) {
+                       xdrs->x_op = XDR_FREE;
+                       (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
+               }
+       }
+
+       return (status);
+}
+
+static void
+clntraw_geterr()
+{
+}
+
+
+static bool_t
+clntraw_freeres(cl, xdr_res, res_ptr)
+       CLIENT *cl;
+       xdrproc_t xdr_res;
+       caddr_t res_ptr;
+{
+       register struct clntraw_private *clp = clntraw_private;
+       register XDR *xdrs = &clp->xdr_stream;
+       bool_t rval;
+
+       if (clp == 0)
+       {
+               rval = (bool_t) RPC_FAILED;
+               return (rval);
+       }
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntraw_abort()
+{
+}
+
+static bool_t
+clntraw_control()
+{
+       return (FALSE);
+}
+
+static void
+clntraw_destroy()
+{
+}
diff --git a/libc/inet/rpc/clnt_simple.c b/libc/inet/rpc/clnt_simple.c
new file mode 100644 (file)
index 0000000..043ce0a
--- /dev/null
@@ -0,0 +1,112 @@
+/* @(#)clnt_simple.c   2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/* 
+ * clnt_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <strings.h>
+
+static struct callrpc_private {
+       CLIENT  *client;
+       int     socket;
+       int     oldprognum, oldversnum, valid;
+       char    *oldhost;
+} *callrpc_private;
+
+callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+       char *host;
+       xdrproc_t inproc, outproc;
+       char *in, *out;
+{
+       register struct callrpc_private *crp = callrpc_private;
+       struct sockaddr_in server_addr;
+       enum clnt_stat clnt_stat;
+       struct hostent *hp;
+       struct timeval timeout, tottimeout;
+
+       if (crp == 0) {
+               crp = (struct callrpc_private *)calloc(1, sizeof (*crp));
+               if (crp == 0)
+                       return (0);
+               callrpc_private = crp;
+       }
+       if (crp->oldhost == NULL) {
+               crp->oldhost = malloc(256);
+               crp->oldhost[0] = 0;
+               crp->socket = RPC_ANYSOCK;
+       }
+       if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
+               && strcmp(crp->oldhost, host) == 0) {
+               /* reuse old client */          
+       } else {
+               crp->valid = 0;
+               (void)close(crp->socket);
+               crp->socket = RPC_ANYSOCK;
+               if (crp->client) {
+                       clnt_destroy(crp->client);
+                       crp->client = NULL;
+               }
+               if ((hp = gethostbyname(host)) == NULL)
+                       return ((int) RPC_UNKNOWNHOST);
+               timeout.tv_usec = 0;
+               timeout.tv_sec = 5;
+               bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length);
+               server_addr.sin_family = AF_INET;
+               server_addr.sin_port =  0;
+               if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
+                   (u_long)versnum, timeout, &crp->socket)) == NULL)
+                       return ((int) rpc_createerr.cf_stat);
+               crp->valid = 1;
+               crp->oldprognum = prognum;
+               crp->oldversnum = versnum;
+               (void) strcpy(crp->oldhost, host);
+       }
+       tottimeout.tv_sec = 25;
+       tottimeout.tv_usec = 0;
+       clnt_stat = clnt_call(crp->client, procnum, inproc, in,
+           outproc, out, tottimeout);
+       /* 
+        * if call failed, empty cache
+        */
+       if (clnt_stat != RPC_SUCCESS)
+               crp->valid = 0;
+       return ((int) clnt_stat);
+}
diff --git a/libc/inet/rpc/clnt_tcp.c b/libc/inet/rpc/clnt_tcp.c
new file mode 100644 (file)
index 0000000..2222bc6
--- /dev/null
@@ -0,0 +1,466 @@
+/* @(#)clnt_tcp.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
+#endif
+/*
+ * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * TCP based RPC supports 'batched calls'.
+ * A sequence of calls may be batched-up in a send buffer.  The rpc call
+ * return immediately to the client even though the call was not necessarily
+ * sent.  The batching occurs if the results' xdr routine is NULL (0) AND
+ * the rpc timeout value is zero (see clnt.h, rpc).
+ *
+ * Clients should NOT casually batch calls that in fact return results; that is,
+ * the server side should be aware that a call is batched and not produce any
+ * return message.  Batched calls that produce many result messages can
+ * deadlock (netlock) the client and the server....
+ *
+ * Now go hang yourself.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+
+#define MCALL_MSG_SIZE 24
+
+extern int errno;
+
+static int     readtcp();
+static int     writetcp();
+
+static enum clnt_stat  clnttcp_call();
+static void            clnttcp_abort();
+static void            clnttcp_geterr();
+static bool_t          clnttcp_freeres();
+static bool_t           clnttcp_control();
+static void            clnttcp_destroy();
+
+static struct clnt_ops tcp_ops = {
+       clnttcp_call,
+       clnttcp_abort,
+       clnttcp_geterr,
+       clnttcp_freeres,
+       clnttcp_destroy,
+       clnttcp_control
+};
+
+struct ct_data {
+       int             ct_sock;
+       bool_t          ct_closeit;
+       struct timeval  ct_wait;
+       bool_t          ct_waitset;       /* wait set by clnt_control? */
+       struct sockaddr_in ct_addr; 
+       struct rpc_err  ct_error;
+       char            ct_mcall[MCALL_MSG_SIZE];       /* marshalled callmsg */
+       u_int           ct_mpos;                        /* pos after marshal */
+       XDR             ct_xdrs;
+};
+
+/*
+ * Create a client handle for a tcp/ip connection.
+ * If *sockp<0, *sockp is set to a newly created TCP socket and it is
+ * connected to raddr.  If *sockp non-negative then
+ * raddr is ignored.  The rpc/tcp package does buffering
+ * similar to stdio, so the client must pick send and receive buffer sizes,];
+ * 0 => use the default.
+ * If raddr->sin_port is 0, then a binder on the remote machine is
+ * consulted for the right port number.
+ * NB: *sockp is copied into a private area.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is set null authentication.  Caller may wish to set this
+ * something more useful.
+ */
+CLIENT *
+clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+       struct sockaddr_in *raddr;
+       u_long prog;
+       u_long vers;
+       register int *sockp;
+       u_int sendsz;
+       u_int recvsz;
+{
+       CLIENT *h;
+       register struct ct_data *ct;
+       struct timeval now;
+       struct rpc_msg call_msg;
+
+       h  = (CLIENT *)mem_alloc(sizeof(*h));
+       if (h == NULL) {
+               (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = errno;
+               goto fooy;
+       }
+       ct = (struct ct_data *)mem_alloc(sizeof(*ct));
+       if (ct == NULL) {
+               (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = errno;
+               goto fooy;
+       }
+
+       /*
+        * If no port number given ask the pmap for one
+        */
+       if (raddr->sin_port == 0) {
+               u_short port;
+               if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) {
+                       mem_free((caddr_t)ct, sizeof(struct ct_data));
+                       mem_free((caddr_t)h, sizeof(CLIENT));
+                       return ((CLIENT *)NULL);
+               }
+               raddr->sin_port = htons(port);
+       }
+
+       /*
+        * If no socket given, open one
+        */
+       if (*sockp < 0) {
+               *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+               (void)bindresvport(*sockp, (struct sockaddr_in *)0);
+               if ((*sockp < 0)
+                   || (connect(*sockp, (struct sockaddr *)raddr,
+                   sizeof(*raddr)) < 0)) {
+                       rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+                       rpc_createerr.cf_error.re_errno = errno;
+                       (void)close(*sockp);
+                       goto fooy;
+               }
+               ct->ct_closeit = TRUE;
+       } else {
+               ct->ct_closeit = FALSE;
+       }
+
+       /*
+        * Set up private data struct
+        */
+       ct->ct_sock = *sockp;
+       ct->ct_wait.tv_usec = 0;
+       ct->ct_waitset = FALSE;
+       ct->ct_addr = *raddr;
+
+       /*
+        * Initialize call message
+        */
+       (void)gettimeofday(&now, (struct timezone *)0);
+       call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
+       call_msg.rm_direction = CALL;
+       call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+       call_msg.rm_call.cb_prog = prog;
+       call_msg.rm_call.cb_vers = vers;
+
+       /*
+        * pre-serialize the staic part of the call msg and stash it away
+        */
+       xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
+           XDR_ENCODE);
+       if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
+               if (ct->ct_closeit) {
+                       (void)close(*sockp);
+               }
+               goto fooy;
+       }
+       ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
+       XDR_DESTROY(&(ct->ct_xdrs));
+
+       /*
+        * Create a client handle which uses xdrrec for serialization
+        * and authnone for authentication.
+        */
+       xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
+           (caddr_t)ct, readtcp, writetcp);
+       h->cl_ops = &tcp_ops;
+       h->cl_private = (caddr_t) ct;
+       h->cl_auth = authnone_create();
+       return (h);
+
+fooy:
+       /*
+        * Something goofed, free stuff and barf
+        */
+       mem_free((caddr_t)ct, sizeof(struct ct_data));
+       mem_free((caddr_t)h, sizeof(CLIENT));
+       return ((CLIENT *)NULL);
+}
+
+static enum clnt_stat
+clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
+       register CLIENT *h;
+       u_long proc;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+       xdrproc_t xdr_results;
+       caddr_t results_ptr;
+       struct timeval timeout;
+{
+       register struct ct_data *ct = (struct ct_data *) h->cl_private;
+       register XDR *xdrs = &(ct->ct_xdrs);
+       struct rpc_msg reply_msg;
+       u_long x_id;
+       u_long *msg_x_id = (u_long *)(ct->ct_mcall);    /* yuk */
+       register bool_t shipnow;
+       int refreshes = 2;
+
+       if (!ct->ct_waitset) {
+               ct->ct_wait = timeout;
+       }
+
+       shipnow =
+           (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
+           && timeout.tv_usec == 0) ? FALSE : TRUE;
+
+call_again:
+       xdrs->x_op = XDR_ENCODE;
+       ct->ct_error.re_status = RPC_SUCCESS;
+       x_id = ntohl(--(*msg_x_id));
+       if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
+           (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+           (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+           (! (*xdr_args)(xdrs, args_ptr))) {
+               if (ct->ct_error.re_status == RPC_SUCCESS)
+                       ct->ct_error.re_status = RPC_CANTENCODEARGS;
+               (void)xdrrec_endofrecord(xdrs, TRUE);
+               return (ct->ct_error.re_status);
+       }
+       if (! xdrrec_endofrecord(xdrs, shipnow))
+               return (ct->ct_error.re_status = RPC_CANTSEND);
+       if (! shipnow)
+               return (RPC_SUCCESS);
+       /*
+        * Hack to provide rpc-based message passing
+        */
+       if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+               return(ct->ct_error.re_status = RPC_TIMEDOUT);
+       }
+
+
+       /*
+        * Keep receiving until we get a valid transaction id
+        */
+       xdrs->x_op = XDR_DECODE;
+       while (TRUE) {
+               reply_msg.acpted_rply.ar_verf = _null_auth;
+               reply_msg.acpted_rply.ar_results.where = NULL;
+               reply_msg.acpted_rply.ar_results.proc = xdr_void;
+               if (! xdrrec_skiprecord(xdrs))
+                       return (ct->ct_error.re_status);
+               /* now decode and validate the response header */
+               if (! xdr_replymsg(xdrs, &reply_msg)) {
+                       if (ct->ct_error.re_status == RPC_SUCCESS)
+                               continue;
+                       return (ct->ct_error.re_status);
+               }
+               if (reply_msg.rm_xid == x_id)
+                       break;
+       }
+
+       /*
+        * process header
+        */
+       _seterr_reply(&reply_msg, &(ct->ct_error));
+       if (ct->ct_error.re_status == RPC_SUCCESS) {
+               if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
+                       ct->ct_error.re_status = RPC_AUTHERROR;
+                       ct->ct_error.re_why = AUTH_INVALIDRESP;
+               } else if (! (*xdr_results)(xdrs, results_ptr)) {
+                       if (ct->ct_error.re_status == RPC_SUCCESS)
+                               ct->ct_error.re_status = RPC_CANTDECODERES;
+               }
+               /* free verifier ... */
+               if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+                       xdrs->x_op = XDR_FREE;
+                       (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
+               }
+       }  /* end successful completion */
+       else {
+               /* maybe our credentials need to be refreshed ... */
+               if (refreshes-- && AUTH_REFRESH(h->cl_auth))
+                       goto call_again;
+       }  /* end of unsuccessful completion */
+       return (ct->ct_error.re_status);
+}
+
+static void
+clnttcp_geterr(h, errp)
+       CLIENT *h;
+       struct rpc_err *errp;
+{
+       register struct ct_data *ct =
+           (struct ct_data *) h->cl_private;
+
+       *errp = ct->ct_error;
+}
+
+static bool_t
+clnttcp_freeres(cl, xdr_res, res_ptr)
+       CLIENT *cl;
+       xdrproc_t xdr_res;
+       caddr_t res_ptr;
+{
+       register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+       register XDR *xdrs = &(ct->ct_xdrs);
+
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clnttcp_abort()
+{
+}
+
+static bool_t
+clnttcp_control(cl, request, info)
+       CLIENT *cl;
+       int request;
+       char *info;
+{
+       register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+
+       switch (request) {
+       case CLSET_TIMEOUT:
+               ct->ct_wait = *(struct timeval *)info;
+               ct->ct_waitset = TRUE;
+               break;
+       case CLGET_TIMEOUT:
+               *(struct timeval *)info = ct->ct_wait;
+               break;
+       case CLGET_SERVER_ADDR:
+               *(struct sockaddr_in *)info = ct->ct_addr;
+               break;
+       default:
+               return (FALSE);
+       }
+       return (TRUE);
+}
+
+
+static void
+clnttcp_destroy(h)
+       CLIENT *h;
+{
+       register struct ct_data *ct =
+           (struct ct_data *) h->cl_private;
+
+       if (ct->ct_closeit) {
+               (void)close(ct->ct_sock);
+       }
+       XDR_DESTROY(&(ct->ct_xdrs));
+       mem_free((caddr_t)ct, sizeof(struct ct_data));
+       mem_free((caddr_t)h, sizeof(CLIENT));
+}
+
+/*
+ * Interface between xdr serializer and tcp connection.
+ * Behaves like the system calls, read & write, but keeps some error state
+ * around for the rpc level.
+ */
+static int
+readtcp(ct, buf, len)
+       register struct ct_data *ct;
+       caddr_t buf;
+       register int len;
+{
+#ifdef FD_SETSIZE
+       fd_set mask;
+       fd_set readfds;
+
+       if (len == 0)
+               return (0);
+       FD_ZERO(&mask);
+       FD_SET(ct->ct_sock, &mask);
+#else
+       register int mask = 1 << (ct->ct_sock);
+       int readfds;
+
+       if (len == 0)
+               return (0);
+
+#endif /* def FD_SETSIZE */
+       while (TRUE) {
+               readfds = mask;
+               switch (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL,
+                              &(ct->ct_wait))) {
+               case 0:
+                       ct->ct_error.re_status = RPC_TIMEDOUT;
+                       return (-1);
+
+               case -1:
+                       if (errno == EINTR)
+                               continue;
+                       ct->ct_error.re_status = RPC_CANTRECV;
+                       ct->ct_error.re_errno = errno;
+                       return (-1);
+               }
+               break;
+       }
+       switch (len = read(ct->ct_sock, buf, len)) {
+
+       case 0:
+               /* premature eof */
+               ct->ct_error.re_errno = ECONNRESET;
+               ct->ct_error.re_status = RPC_CANTRECV;
+               len = -1;  /* it's really an error */
+               break;
+
+       case -1:
+               ct->ct_error.re_errno = errno;
+               ct->ct_error.re_status = RPC_CANTRECV;
+               break;
+       }
+       return (len);
+}
+
+static int
+writetcp(ct, buf, len)
+       struct ct_data *ct;
+       caddr_t buf;
+       int len;
+{
+       register int i, cnt;
+
+       for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+               if ((i = write(ct->ct_sock, buf, cnt)) == -1) {
+                       ct->ct_error.re_errno = errno;
+                       ct->ct_error.re_status = RPC_CANTSEND;
+                       return (-1);
+               }
+       }
+       return (len);
+}
diff --git a/libc/inet/rpc/clnt_udp.c b/libc/inet/rpc/clnt_udp.c
new file mode 100644 (file)
index 0000000..815cbb4
--- /dev/null
@@ -0,0 +1,442 @@
+/* @(#)clnt_udp.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_udp.c, Implements a UDP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+
+extern int errno;
+
+/*
+ * UDP bases client side rpc operations
+ */
+static enum clnt_stat  clntudp_call();
+static void            clntudp_abort();
+static void            clntudp_geterr();
+static bool_t          clntudp_freeres();
+static bool_t           clntudp_control();
+static void            clntudp_destroy();
+
+static struct clnt_ops udp_ops = {
+       clntudp_call,
+       clntudp_abort,
+       clntudp_geterr,
+       clntudp_freeres,
+       clntudp_destroy,
+       clntudp_control
+};
+
+/* 
+ * Private data kept per client handle
+ */
+struct cu_data {
+       int                cu_sock;
+       bool_t             cu_closeit;
+       struct sockaddr_in cu_raddr;
+       int                cu_rlen;
+       struct timeval     cu_wait;
+       struct timeval     cu_total;
+       struct rpc_err     cu_error;
+       XDR                cu_outxdrs;
+       u_int              cu_xdrpos;
+       u_int              cu_sendsz;
+       char               *cu_outbuf;
+       u_int              cu_recvsz;
+       char               cu_inbuf[1];
+};
+
+/*
+ * Create a UDP based client handle.
+ * If *sockp<0, *sockp is set to a newly created UPD socket.
+ * If raddr->sin_port is 0 a binder on the remote machine
+ * is consulted for the correct port number.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is initialized to null authentication.
+ *     Caller may wish to set this something more useful.
+ *
+ * wait is the amount of time used between retransmitting a call if
+ * no response has been heard;  retransmition occurs until the actual
+ * rpc call times out.
+ *
+ * sendsz and recvsz are the maximum allowable packet sizes that can be
+ * sent and received.
+ */
+CLIENT *
+clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+       struct sockaddr_in *raddr;
+       u_long program;
+       u_long version;
+       struct timeval wait;
+       register int *sockp;
+       u_int sendsz;
+       u_int recvsz;
+{
+       CLIENT *cl;
+       register struct cu_data *cu;
+       struct timeval now;
+       struct rpc_msg call_msg;
+
+       cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
+       if (cl == NULL) {
+               (void) fprintf(stderr, "clntudp_create: out of memory\n");
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = errno;
+               goto fooy;
+       }
+       sendsz = ((sendsz + 3) / 4) * 4;
+       recvsz = ((recvsz + 3) / 4) * 4;
+       cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz);
+       if (cu == NULL) {
+               (void) fprintf(stderr, "clntudp_create: out of memory\n");
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = errno;
+               goto fooy;
+       }
+       cu->cu_outbuf = &cu->cu_inbuf[recvsz];
+
+       (void)gettimeofday(&now, (struct timezone *)0);
+       if (raddr->sin_port == 0) {
+               u_short port;
+               if ((port =
+                   pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
+                       goto fooy;
+               }
+               raddr->sin_port = htons(port);
+       }
+       cl->cl_ops = &udp_ops;
+       cl->cl_private = (caddr_t)cu;
+       cu->cu_raddr = *raddr;
+       cu->cu_rlen = sizeof (cu->cu_raddr);
+       cu->cu_wait = wait;
+       cu->cu_total.tv_sec = -1;
+       cu->cu_total.tv_usec = -1;
+       cu->cu_sendsz = sendsz;
+       cu->cu_recvsz = recvsz;
+       call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
+       call_msg.rm_direction = CALL;
+       call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+       call_msg.rm_call.cb_prog = program;
+       call_msg.rm_call.cb_vers = version;
+       xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,
+           sendsz, XDR_ENCODE);
+       if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
+               goto fooy;
+       }
+       cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
+       if (*sockp < 0) {
+               int dontblock = 1;
+
+               *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+               if (*sockp < 0) {
+                       rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+                       rpc_createerr.cf_error.re_errno = errno;
+                       goto fooy;
+               }
+               /* attempt to bind to prov port */
+               (void)bindresvport(*sockp, (struct sockaddr_in *)0);
+               /* the sockets rpc controls are non-blocking */
+               (void)ioctl(*sockp, FIONBIO, (char *) &dontblock);
+               cu->cu_closeit = TRUE;
+       } else {
+               cu->cu_closeit = FALSE;
+       }
+       cu->cu_sock = *sockp;
+       cl->cl_auth = authnone_create();
+       return (cl);
+fooy:
+       if (cu)
+               mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);
+       if (cl)
+               mem_free((caddr_t)cl, sizeof(CLIENT));
+       return ((CLIENT *)NULL);
+}
+
+CLIENT *
+clntudp_create(raddr, program, version, wait, sockp)
+       struct sockaddr_in *raddr;
+       u_long program;
+       u_long version;
+       struct timeval wait;
+       register int *sockp;
+{
+
+       return(clntudp_bufcreate(raddr, program, version, wait, sockp,
+           UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum clnt_stat 
+clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
+       register CLIENT *cl;            /* client handle */
+       u_long          proc;           /* procedure number */
+       xdrproc_t       xargs;          /* xdr routine for args */
+       caddr_t         argsp;          /* pointer to args */
+       xdrproc_t       xresults;       /* xdr routine for results */
+       caddr_t         resultsp;       /* pointer to results */
+       struct timeval  utimeout;       /* seconds to wait before giving up */
+{
+       register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+       register XDR *xdrs;
+       register int outlen;
+       register int inlen;
+       int fromlen;
+#ifdef FD_SETSIZE
+       fd_set readfds;
+       fd_set mask;
+#else
+       int readfds;
+       register int mask;
+#endif /* def FD_SETSIZE */
+       struct sockaddr_in from;
+       struct rpc_msg reply_msg;
+       XDR reply_xdrs;
+       struct timeval time_waited;
+       bool_t ok;
+       int nrefreshes = 2;     /* number of times to refresh cred */
+       struct timeval timeout;
+
+       if (cu->cu_total.tv_usec == -1) {
+               timeout = utimeout;     /* use supplied timeout */
+       } else {
+               timeout = cu->cu_total; /* use default timeout */
+       }
+
+       time_waited.tv_sec = 0;
+       time_waited.tv_usec = 0;
+call_again:
+       xdrs = &(cu->cu_outxdrs);
+       xdrs->x_op = XDR_ENCODE;
+       XDR_SETPOS(xdrs, cu->cu_xdrpos);
+       /*
+        * the transaction is the first thing in the out buffer
+        */
+       (*(u_short *)(cu->cu_outbuf))++;
+       if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+           (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
+           (! (*xargs)(xdrs, argsp)))
+               return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+       outlen = (int)XDR_GETPOS(xdrs);
+
+send_again:
+       if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
+           (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen)
+           != outlen) {
+               cu->cu_error.re_errno = errno;
+               return (cu->cu_error.re_status = RPC_CANTSEND);
+       }
+
+       /*
+        * Hack to provide rpc-based message passing
+        */
+       if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+               return (cu->cu_error.re_status = RPC_TIMEDOUT);
+       }
+       /*
+        * sub-optimal code appears here because we have
+        * some clock time to spare while the packets are in flight.
+        * (We assume that this is actually only executed once.)
+        */
+       reply_msg.acpted_rply.ar_verf = _null_auth;
+       reply_msg.acpted_rply.ar_results.where = resultsp;
+       reply_msg.acpted_rply.ar_results.proc = xresults;
+#ifdef FD_SETSIZE
+       FD_ZERO(&mask);
+       FD_SET(cu->cu_sock, &mask);
+#else
+       mask = 1 << cu->cu_sock;
+#endif /* def FD_SETSIZE */
+       for (;;) {
+               readfds = mask;
+               switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, 
+                              (int *)NULL, &(cu->cu_wait))) {
+
+               case 0:
+                       time_waited.tv_sec += cu->cu_wait.tv_sec;
+                       time_waited.tv_usec += cu->cu_wait.tv_usec;
+                       while (time_waited.tv_usec >= 1000000) {
+                               time_waited.tv_sec++;
+                               time_waited.tv_usec -= 1000000;
+                       }
+                       if ((time_waited.tv_sec < timeout.tv_sec) ||
+                               ((time_waited.tv_sec == timeout.tv_sec) &&
+                               (time_waited.tv_usec < timeout.tv_usec)))
+                               goto send_again;        
+                       return (cu->cu_error.re_status = RPC_TIMEDOUT);
+
+               /*
+                * buggy in other cases because time_waited is not being
+                * updated.
+                */
+               case -1:
+                       if (errno == EINTR)
+                               continue;       
+                       cu->cu_error.re_errno = errno;
+                       return (cu->cu_error.re_status = RPC_CANTRECV);
+               }
+               do {
+                       fromlen = sizeof(struct sockaddr);
+                       inlen = recvfrom(cu->cu_sock, cu->cu_inbuf, 
+                               (int) cu->cu_recvsz, 0,
+                               (struct sockaddr *)&from, &fromlen);
+               } while (inlen < 0 && errno == EINTR);
+               if (inlen < 0) {
+                       if (errno == EWOULDBLOCK)
+                               continue;       
+                       cu->cu_error.re_errno = errno;
+                       return (cu->cu_error.re_status = RPC_CANTRECV);
+               }
+               if (inlen < sizeof(u_long))
+                       continue;       
+               /* see if reply transaction id matches sent id */
+               if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf)))
+                       continue;       
+               /* we now assume we have the proper reply */
+               break;
+       }
+
+       /*
+        * now decode and validate the response
+        */
+       xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
+       ok = xdr_replymsg(&reply_xdrs, &reply_msg);
+       /* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */
+       if (ok) {
+               _seterr_reply(&reply_msg, &(cu->cu_error));
+               if (cu->cu_error.re_status == RPC_SUCCESS) {
+                       if (! AUTH_VALIDATE(cl->cl_auth,
+                               &reply_msg.acpted_rply.ar_verf)) {
+                               cu->cu_error.re_status = RPC_AUTHERROR;
+                               cu->cu_error.re_why = AUTH_INVALIDRESP;
+                       }
+                       if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+                               xdrs->x_op = XDR_FREE;
+                               (void)xdr_opaque_auth(xdrs,
+                                   &(reply_msg.acpted_rply.ar_verf));
+                       } 
+               }  /* end successful completion */
+               else {
+                       /* maybe our credentials need to be refreshed ... */
+                       if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) {
+                               nrefreshes--;
+                               goto call_again;
+                       }
+               }  /* end of unsuccessful completion */
+       }  /* end of valid reply message */
+       else {
+               cu->cu_error.re_status = RPC_CANTDECODERES;
+       }
+       return (cu->cu_error.re_status);
+}
+
+static void
+clntudp_geterr(cl, errp)
+       CLIENT *cl;
+       struct rpc_err *errp;
+{
+       register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+       *errp = cu->cu_error;
+}
+
+
+static bool_t
+clntudp_freeres(cl, xdr_res, res_ptr)
+       CLIENT *cl;
+       xdrproc_t xdr_res;
+       caddr_t res_ptr;
+{
+       register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+       register XDR *xdrs = &(cu->cu_outxdrs);
+
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void 
+clntudp_abort(/*h*/)
+       /*CLIENT *h;*/
+{
+}
+
+static bool_t
+clntudp_control(cl, request, info)
+       CLIENT *cl;
+       int request;
+       char *info;
+{
+       register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+       switch (request) {
+       case CLSET_TIMEOUT:
+               cu->cu_total = *(struct timeval *)info;
+               break;
+       case CLGET_TIMEOUT:
+               *(struct timeval *)info = cu->cu_total;
+               break;
+       case CLSET_RETRY_TIMEOUT:
+               cu->cu_wait = *(struct timeval *)info;
+               break;
+       case CLGET_RETRY_TIMEOUT:
+               *(struct timeval *)info = cu->cu_wait;
+               break;
+       case CLGET_SERVER_ADDR:
+               *(struct sockaddr_in *)info = cu->cu_raddr;
+               break;
+       default:
+               return (FALSE);
+       }
+       return (TRUE);
+}
+       
+static void
+clntudp_destroy(cl)
+       CLIENT *cl;
+{
+       register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+       if (cu->cu_closeit) {
+               (void)close(cu->cu_sock);
+       }
+       XDR_DESTROY(&(cu->cu_outxdrs));
+       mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz));
+       mem_free((caddr_t)cl, sizeof(CLIENT));
+}
diff --git a/libc/inet/rpc/get_myaddress.c b/libc/inet/rpc/get_myaddress.c
new file mode 100644 (file)
index 0000000..44a6eb3
--- /dev/null
@@ -0,0 +1,108 @@
+/* @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * get_myaddress.c
+ *
+ * Get client's IP address via ioctl.  This avoids using the yellowpages.
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/pmap_prot.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#ifdef linux
+/* DO use gethostbyname because it's portable */
+#include <netdb.h>
+get_myaddress(addr)
+       struct sockaddr_in *addr;
+{
+       char localhost[256 + 1];
+       struct hostent *hp;
+
+       gethostname(localhost, 256);
+       if ((hp = gethostbyname(localhost)) == NULL) {
+               perror("get_myaddress: gethostbyname");
+               exit(1);
+       }
+       addr->sin_family = AF_INET;
+       bcopy((char *) hp->h_addr, (char *) &addr->sin_addr, hp->h_length);
+       addr->sin_port = htons(PMAPPORT);
+}
+#else
+/* 
+ * don't use gethostbyname, which would invoke yellow pages
+ */
+get_myaddress(addr)
+       struct sockaddr_in *addr;
+{
+       int s;
+       char buf[BUFSIZ];
+       struct ifconf ifc;
+       struct ifreq ifreq, *ifr;
+       int len;
+
+       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+           perror("get_myaddress: socket");
+           exit(1);
+       }
+       ifc.ifc_len = sizeof (buf);
+       ifc.ifc_buf = buf;
+       if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+               perror("get_myaddress: ioctl (get interface configuration)");
+               exit(1);
+       }
+       ifr = ifc.ifc_req;
+       for (len = ifc.ifc_len; len; len -= sizeof ifreq) {
+               ifreq = *ifr;
+               if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+                       perror("get_myaddress: ioctl");
+                       exit(1);
+               }
+               if ((ifreq.ifr_flags & IFF_UP) &&
+                   ifr->ifr_addr.sa_family == AF_INET) {
+                       *addr = *((struct sockaddr_in *)&ifr->ifr_addr);
+                       addr->sin_port = htons(PMAPPORT);
+                       break;
+               }
+               ifr++;
+       }
+       (void) close(s);
+}
+#endif
diff --git a/libc/inet/rpc/getrpcent.c b/libc/inet/rpc/getrpcent.c
new file mode 100644 (file)
index 0000000..e0b7342
--- /dev/null
@@ -0,0 +1,286 @@
+/* @(#)getrpcent.c     2.2 88/07/29 4.0 RPCSRC */
+#if !defined(lint) && defined(SCCSIDS)
+static  char sccsid[] = "@(#)getrpcent.c 1.9 87/08/11  Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <rpc/rpc.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+/*
+ * Internet version.
+ */
+struct rpcdata {
+       FILE    *rpcf;
+       char    *current;
+       int     currentlen;
+       int     stayopen;
+#define        MAXALIASES      35
+       char    *rpc_aliases[MAXALIASES];
+       struct  rpcent rpc;
+       char    line[BUFSIZ+1];
+       char    *domain;
+} *rpcdata, *_rpcdata();
+
+static struct rpcent *interpret();
+struct hostent *gethostent();
+char   *inet_ntoa();
+#ifndef linux
+static char *index();
+#else
+char *index();
+#endif
+
+static char RPCDB[] = "/etc/rpc";
+
+static struct rpcdata *
+_rpcdata()
+{
+       register struct rpcdata *d = rpcdata;
+
+       if (d == 0) {
+               d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
+               rpcdata = d;
+       }
+       return (d);
+}
+
+struct rpcent *
+getrpcbynumber(number)
+       register int number;
+{
+       register struct rpcdata *d = _rpcdata();
+       register struct rpcent *p;
+       int reason;
+       char adrstr[16], *val = NULL;
+       int vallen;
+
+       if (d == 0)
+               return (0);
+       setrpcent(0);
+       while (p = getrpcent()) {
+               if (p->r_number == number)
+                       break;
+       }
+       endrpcent();
+       return (p);
+}
+
+struct rpcent *
+#ifdef linux
+getrpcbyname(const char *name)
+#else
+getrpcbyname(name)
+       char *name;
+#endif
+{
+       struct rpcent *rpc;
+       char **rp;
+
+       setrpcent(0);
+       while(rpc = getrpcent()) {
+               if (strcmp(rpc->r_name, name) == 0)
+                       return (rpc);
+               for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+                       if (strcmp(*rp, name) == 0)
+                               return (rpc);
+               }
+       }
+       endrpcent();
+       return (NULL);
+}
+
+#ifdef linux
+void
+#endif
+setrpcent(f)
+       int f;
+{
+       register struct rpcdata *d = _rpcdata();
+
+       if (d == 0)
+               return;
+       if (d->rpcf == NULL)
+               d->rpcf = fopen(RPCDB, "r");
+       else
+               rewind(d->rpcf);
+       if (d->current)
+               free(d->current);
+       d->current = NULL;
+       d->stayopen |= f;
+}
+
+#ifdef linux
+void
+#endif
+endrpcent()
+{
+       register struct rpcdata *d = _rpcdata();
+
+       if (d == 0)
+               return;
+       if (d->current && !d->stayopen) {
+               free(d->current);
+               d->current = NULL;
+       }
+       if (d->rpcf && !d->stayopen) {
+               fclose(d->rpcf);
+               d->rpcf = NULL;
+       }
+}
+
+struct rpcent *
+getrpcent()
+{
+       struct rpcent *hp;
+       int reason;
+       char *key = NULL, *val = NULL;
+       int keylen, vallen;
+       register struct rpcdata *d = _rpcdata();
+
+       if (d == 0)
+               return(NULL);
+       if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
+               return (NULL);
+    if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
+               return (NULL);
+       return interpret(d->line, strlen(d->line));
+}
+
+#ifdef linux
+static char *
+firstwhite(s)
+char *s;
+{
+       char *s1, *s2;
+
+       s1 = index(s, ' ');
+       s2 = index(s, '\t');
+       if (s1) {
+               if (s2)
+                       return (s1 < s2) ? s1 : s2;
+               else
+                       return s1;
+       }
+       else
+               return s2;
+}
+#endif
+
+static struct rpcent *
+interpret(val, len)
+{
+       register struct rpcdata *d = _rpcdata();
+       char *p;
+       register char *cp, **q;
+
+       if (d == 0)
+               return;
+       strncpy(d->line, val, len);
+       p = d->line;
+       d->line[len] = '\n';
+       if (*p == '#')
+               return (getrpcent());
+       cp = index(p, '#');
+       if (cp == NULL)
+    {
+               cp = index(p, '\n');
+               if (cp == NULL)
+                       return (getrpcent());
+       }
+       *cp = '\0';
+#ifdef linux
+       if ((cp = firstwhite(p)))
+               *cp++ = 0;
+       else
+               return (getrpcent());
+#else
+       cp = index(p, ' ');
+       if (cp == NULL)
+    {
+               cp = index(p, '\t');
+               if (cp == NULL)
+                       return (getrpcent());
+       }
+       *cp++ = '\0';
+#endif
+       /* THIS STUFF IS INTERNET SPECIFIC */
+       d->rpc.r_name = d->line;
+       while (*cp == ' ' || *cp == '\t')
+               cp++;
+       d->rpc.r_number = atoi(cp);
+       q = d->rpc.r_aliases = d->rpc_aliases;
+#ifdef linux
+       if ((cp = firstwhite(cp)))
+               *cp++ = '\0';
+#else
+       cp = index(p, ' ');
+       if (cp != NULL)
+               *cp++ = '\0';
+       else
+    {
+               cp = index(p, '\t');
+               if (cp != NULL)
+                       *cp++ = '\0';
+       }
+#endif
+       while (cp && *cp) {
+               if (*cp == ' ' || *cp == '\t') {
+                       cp++;
+                       continue;
+               }
+               if (q < &(d->rpc_aliases[MAXALIASES - 1]))
+                       *q++ = cp;
+#ifdef linux
+               if ((cp = firstwhite(cp)))
+                       *cp++ = '\0';
+#else
+               cp = index(p, ' ');
+               if (cp != NULL)
+                       *cp++ = '\0';
+               else
+           {
+                       cp = index(p, '\t');
+                       if (cp != NULL)
+                               *cp++ = '\0';
+               }
+#endif
+       }
+       *q = NULL;
+       return (&d->rpc);
+}
diff --git a/libc/inet/rpc/getrpcport.c b/libc/inet/rpc/getrpcport.c
new file mode 100644 (file)
index 0000000..9b13bac
--- /dev/null
@@ -0,0 +1,55 @@
+/* @(#)getrpcport.c    2.1 88/07/29 4.0 RPCSRC */
+#if !defined(lint) && defined(SCCSIDS)
+static  char sccsid[] = "@(#)getrpcport.c 1.3 87/08/11 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+getrpcport(host, prognum, versnum, proto)
+       char *host;
+{
+       struct sockaddr_in addr;
+       struct hostent *hp;
+
+       if ((hp = gethostbyname(host)) == NULL)
+               return (0);
+       bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length);
+       addr.sin_family = AF_INET;
+       addr.sin_port =  0;
+       return (pmap_getport(&addr, prognum, versnum, proto));
+}
diff --git a/libc/inet/rpc/pmap_clnt.c b/libc/inet/rpc/pmap_clnt.c
new file mode 100644 (file)
index 0000000..09220e7
--- /dev/null
@@ -0,0 +1,115 @@
+/* @(#)pmap_clnt.c     2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_clnt.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+void clnt_perror();
+
+
+/*
+ * Set a mapping between program,version and port.
+ * Calls the pmap service remotely to do the mapping.
+ */
+bool_t
+pmap_set(program, version, protocol, port)
+       u_long program;
+       u_long version;
+       int protocol;
+       u_short port;
+{
+       struct sockaddr_in myaddress;
+       int socket = -1;
+       register CLIENT *client;
+       struct pmap parms;
+       bool_t rslt;
+
+       get_myaddress(&myaddress);
+       client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+           timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+       if (client == (CLIENT *)NULL)
+               return (FALSE);
+       parms.pm_prog = program;
+       parms.pm_vers = version;
+       parms.pm_prot = protocol;
+       parms.pm_port = port;
+       if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
+           tottimeout) != RPC_SUCCESS) {
+               clnt_perror(client, "Cannot register service");
+               return (FALSE);
+       }
+       CLNT_DESTROY(client);
+       (void)close(socket);
+       return (rslt);
+}
+
+/*
+ * Remove the mapping between program,version and port.
+ * Calls the pmap service remotely to do the un-mapping.
+ */
+bool_t
+pmap_unset(program, version)
+       u_long program;
+       u_long version;
+{
+       struct sockaddr_in myaddress;
+       int socket = -1;
+       register CLIENT *client;
+       struct pmap parms;
+       bool_t rslt;
+
+       get_myaddress(&myaddress);
+       client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+           timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+       if (client == (CLIENT *)NULL)
+               return (FALSE);
+       parms.pm_prog = program;
+       parms.pm_vers = version;
+       parms.pm_port = parms.pm_prot = 0;
+       CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
+           tottimeout);
+       CLNT_DESTROY(client);
+       (void)close(socket);
+       return (rslt);
+}
diff --git a/libc/inet/rpc/pmap_getmaps.c b/libc/inet/rpc/pmap_getmaps.c
new file mode 100644 (file)
index 0000000..e4a9c49
--- /dev/null
@@ -0,0 +1,84 @@
+/* @(#)pmap_getmaps.c  2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#define NAMELEN 255
+#define MAX_BROADCAST_SIZE 1400
+
+extern int errno;
+
+/*
+ * Get a copy of the current port maps.
+ * Calls the pmap service remotely to do get the maps.
+ */
+struct pmaplist *
+pmap_getmaps(address)
+        struct sockaddr_in *address;
+{
+       struct pmaplist *head = (struct pmaplist *)NULL;
+       int socket = -1;
+       struct timeval minutetimeout;
+       register CLIENT *client;
+
+       minutetimeout.tv_sec = 60;
+       minutetimeout.tv_usec = 0;
+       address->sin_port = htons(PMAPPORT);
+       client = clnttcp_create(address, PMAPPROG,
+           PMAPVERS, &socket, 50, 500);
+       if (client != (CLIENT *)NULL) {
+               if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
+                   &head, minutetimeout) != RPC_SUCCESS) {
+                       clnt_perror(client, "pmap_getmaps rpc problem");
+               }
+               CLNT_DESTROY(client);
+       }
+       (void)close(socket);
+       address->sin_port = 0;
+       return (head);
+}
diff --git a/libc/inet/rpc/pmap_getport.c b/libc/inet/rpc/pmap_getport.c
new file mode 100644 (file)
index 0000000..77b9cf7
--- /dev/null
@@ -0,0 +1,87 @@
+/* @(#)pmap_getport.c  2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_getport.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+/*
+ * Find the mapped port for program,version.
+ * Calls the pmap service remotely to do the lookup.
+ * Returns 0 if no map exists.
+ */
+u_short
+pmap_getport(address, program, version, protocol)
+       struct sockaddr_in *address;
+       u_long program;
+       u_long version;
+       u_int protocol;
+{
+       u_short port = 0;
+       int socket = -1;
+       register CLIENT *client;
+       struct pmap parms;
+
+       address->sin_port = htons(PMAPPORT);
+       client = clntudp_bufcreate(address, PMAPPROG,
+           PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+       if (client != (CLIENT *)NULL) {
+               parms.pm_prog = program;
+               parms.pm_vers = version;
+               parms.pm_prot = protocol;
+               parms.pm_port = 0;  /* not needed or used */
+               if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
+                   xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
+                       rpc_createerr.cf_stat = RPC_PMAPFAILURE;
+                       clnt_geterr(client, &rpc_createerr.cf_error);
+               } else if (port == 0) {
+                       rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
+               }
+               CLNT_DESTROY(client);
+       }
+       (void)close(socket);
+       address->sin_port = 0;
+       return (port);
+}
diff --git a/libc/inet/rpc/pmap_prot.c b/libc/inet/rpc/pmap_prot.c
new file mode 100644 (file)
index 0000000..643c2ff
--- /dev/null
@@ -0,0 +1,57 @@
+/* @(#)pmap_prot.c     2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_prot.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+bool_t
+xdr_pmap(xdrs, regs)
+       XDR *xdrs;
+       struct pmap *regs;
+{
+
+       if (xdr_u_long(xdrs, &regs->pm_prog) && 
+               xdr_u_long(xdrs, &regs->pm_vers) && 
+               xdr_u_long(xdrs, &regs->pm_prot))
+               return (xdr_u_long(xdrs, &regs->pm_port));
+       return (FALSE);
+}
diff --git a/libc/inet/rpc/pmap_prot2.c b/libc/inet/rpc/pmap_prot2.c
new file mode 100644 (file)
index 0000000..e2a8214
--- /dev/null
@@ -0,0 +1,116 @@
+/* @(#)pmap_prot2.c    2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_prot2.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+/* 
+ * What is going on with linked lists? (!)
+ * First recall the link list declaration from pmap_prot.h:
+ *
+ * struct pmaplist {
+ *     struct pmap pml_map;
+ *     struct pmaplist *pml_map;
+ * };
+ *
+ * Compare that declaration with a corresponding xdr declaration that 
+ * is (a) pointer-less, and (b) recursive:
+ *
+ * typedef union switch (bool_t) {
+ * 
+ *     case TRUE: struct {
+ *             struct pmap;
+ *             pmaplist_t foo;
+ *     };
+ *
+ *     case FALSE: struct {};
+ * } pmaplist_t;
+ *
+ * Notice that the xdr declaration has no nxt pointer while
+ * the C declaration has no bool_t variable.  The bool_t can be
+ * interpreted as ``more data follows me''; if FALSE then nothing
+ * follows this bool_t; if TRUE then the bool_t is followed by
+ * an actual struct pmap, and then (recursively) by the 
+ * xdr union, pamplist_t.  
+ *
+ * This could be implemented via the xdr_union primitive, though this
+ * would cause a one recursive call per element in the list.  Rather than do
+ * that we can ``unwind'' the recursion
+ * into a while loop and do the union arms in-place.
+ *
+ * The head of the list is what the C programmer wishes to past around
+ * the net, yet is the data that the pointer points to which is interesting;
+ * this sounds like a job for xdr_reference!
+ */
+bool_t
+xdr_pmaplist(xdrs, rp)
+       register XDR *xdrs;
+       register struct pmaplist **rp;
+{
+       /*
+        * more_elements is pre-computed in case the direction is
+        * XDR_ENCODE or XDR_FREE.  more_elements is overwritten by
+        * xdr_bool when the direction is XDR_DECODE.
+        */
+       bool_t more_elements;
+       register int freeing = (xdrs->x_op == XDR_FREE);
+       register struct pmaplist **next;
+
+       while (TRUE) {
+               more_elements = (bool_t)(*rp != NULL);
+               if (! xdr_bool(xdrs, &more_elements))
+                       return (FALSE);
+               if (! more_elements)
+                       return (TRUE);  /* we are done */
+               /*
+                * the unfortunate side effect of non-recursion is that in
+                * the case of freeing we must remember the next object
+                * before we free the current object ...
+                */
+               if (freeing)
+                       next = &((*rp)->pml_next); 
+               if (! xdr_reference(xdrs, (caddr_t *)rp,
+                   (u_int)sizeof(struct pmaplist), xdr_pmap))
+                       return (FALSE);
+               rp = (freeing) ? next : &((*rp)->pml_next);
+       }
+}
diff --git a/libc/inet/rpc/pmap_rmt.c b/libc/inet/rpc/pmap_rmt.c
new file mode 100644 (file)
index 0000000..08b6beb
--- /dev/null
@@ -0,0 +1,408 @@
+/* @(#)pmap_rmt.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_rmt.c
+ * Client interface to pmap rpc service.
+ * remote call and broadcast service
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_rmt.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#define MAX_BROADCAST_SIZE 1400
+
+extern int errno;
+static struct timeval timeout = { 3, 0 };
+
+
+/*
+ * pmapper remote-call-service interface.
+ * This routine is used to call the pmapper remote call service
+ * which will look up a service program in the port maps, and then
+ * remotely call that routine with the given parameters.  This allows
+ * programs to do a lookup and call in one step.
+*/
+enum clnt_stat
+pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr)
+       struct sockaddr_in *addr;
+       u_long prog, vers, proc;
+       xdrproc_t xdrargs, xdrres;
+       caddr_t argsp, resp;
+       struct timeval tout;
+       u_long *port_ptr;
+{
+       int socket = -1;
+       register CLIENT *client;
+       struct rmtcallargs a;
+       struct rmtcallres r;
+       enum clnt_stat stat;
+
+       addr->sin_port = htons(PMAPPORT);
+       client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket);
+       if (client != (CLIENT *)NULL) {
+               a.prog = prog;
+               a.vers = vers;
+               a.proc = proc;
+               a.args_ptr = argsp;
+               a.xdr_args = xdrargs;
+               r.port_ptr = port_ptr;
+               r.results_ptr = resp;
+               r.xdr_results = xdrres;
+               stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a,
+                   xdr_rmtcallres, &r, tout);
+               CLNT_DESTROY(client);
+       } else {
+               stat = RPC_FAILED;
+       }
+       (void)close(socket);
+       addr->sin_port = 0;
+       return (stat);
+}
+
+
+/*
+ * XDR remote call arguments
+ * written for XDR_ENCODE direction only
+ */
+bool_t
+xdr_rmtcall_args(xdrs, cap)
+       register XDR *xdrs;
+       register struct rmtcallargs *cap;
+{
+       u_int lenposition, argposition, position;
+
+       if (xdr_u_long(xdrs, &(cap->prog)) &&
+           xdr_u_long(xdrs, &(cap->vers)) &&
+           xdr_u_long(xdrs, &(cap->proc))) {
+               lenposition = XDR_GETPOS(xdrs);
+               if (! xdr_u_long(xdrs, &(cap->arglen)))
+                   return (FALSE);
+               argposition = XDR_GETPOS(xdrs);
+               if (! (*(cap->xdr_args))(xdrs, cap->args_ptr))
+                   return (FALSE);
+               position = XDR_GETPOS(xdrs);
+               cap->arglen = (u_long)position - (u_long)argposition;
+               XDR_SETPOS(xdrs, lenposition);
+               if (! xdr_u_long(xdrs, &(cap->arglen)))
+                   return (FALSE);
+               XDR_SETPOS(xdrs, position);
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/*
+ * XDR remote call results
+ * written for XDR_DECODE direction only
+ */
+bool_t
+xdr_rmtcallres(xdrs, crp)
+       register XDR *xdrs;
+       register struct rmtcallres *crp;
+{
+       caddr_t port_ptr;
+
+       port_ptr = (caddr_t)crp->port_ptr;
+       if (xdr_reference(xdrs, &port_ptr, sizeof (u_long),
+           xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
+               crp->port_ptr = (u_long *)port_ptr;
+               return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
+       }
+       return (FALSE);
+}
+
+
+/*
+ * The following is kludged-up support for simple rpc broadcasts.
+ * Someday a large, complicated system will replace these trivial 
+ * routines which only support udp/ip .
+ */
+
+static int
+getbroadcastnets(addrs, sock, buf)
+       struct in_addr *addrs;
+       int sock;  /* any valid socket will do */
+       char *buf;  /* why allocxate more when we can use existing... */
+{
+#ifdef linux
+       struct sockaddr_in addr;
+
+       get_myaddress(&addr);
+#if 1
+       printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__);
+#else
+       addrs[0] = inet_makeaddr(inet_netof(addr.sin_addr), INADDR_ANY);
+#endif
+       return 1;
+#else
+       struct ifconf ifc;
+        struct ifreq ifreq, *ifr;
+       struct sockaddr_in *sin;
+        int n, i;
+
+        ifc.ifc_len = UDPMSGSIZE;
+        ifc.ifc_buf = buf;
+        if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+                perror("broadcast: ioctl (get interface configuration)");
+                return (0);
+        }
+        ifr = ifc.ifc_req;
+        for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) {
+                ifreq = *ifr;
+                if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+                        perror("broadcast: ioctl (get interface flags)");
+                        continue;
+                }
+                if ((ifreq.ifr_flags & IFF_BROADCAST) &&
+                   (ifreq.ifr_flags & IFF_UP) &&
+                   ifr->ifr_addr.sa_family == AF_INET) {
+                       sin = (struct sockaddr_in *)&ifr->ifr_addr;
+#ifdef SIOCGIFBRDADDR   /* 4.3BSD */
+                       if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
+#if 1
+printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__);
+#else
+                               addrs[i++] = inet_makeaddr(inet_netof
+                           (sin->sin_addr.s_addr), INADDR_ANY);
+#endif
+                       } else {
+                               addrs[i++] = ((struct sockaddr_in*)
+                                 &ifreq.ifr_addr)->sin_addr;
+                       }
+#else /* 4.2 BSD */
+#if 1
+printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__);
+#else
+                       addrs[i++] = inet_makeaddr(inet_netof
+                         (sin->sin_addr.s_addr), INADDR_ANY);
+#endif
+#endif
+               }
+       }
+       return (i);
+#endif
+}
+
+typedef bool_t (*resultproc_t)();
+
+enum clnt_stat 
+clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
+       u_long          prog;           /* program number */
+       u_long          vers;           /* version number */
+       u_long          proc;           /* procedure number */
+       xdrproc_t       xargs;          /* xdr routine for args */
+       caddr_t         argsp;          /* pointer to args */
+       xdrproc_t       xresults;       /* xdr routine for results */
+       caddr_t         resultsp;       /* pointer to results */
+       resultproc_t    eachresult;     /* call with each result obtained */
+{
+       enum clnt_stat stat;
+       AUTH *unix_auth = authunix_create_default();
+       XDR xdr_stream;
+       register XDR *xdrs = &xdr_stream;
+       int outlen, inlen, fromlen, nets;
+       register int sock;
+       int on = 1;
+#ifdef FD_SETSIZE
+       fd_set mask;
+       fd_set readfds;
+#else
+       int readfds;
+       register int mask;
+#endif /* def FD_SETSIZE */
+       register int i;
+       bool_t done = FALSE;
+       register u_long xid;
+       u_long port;
+       struct in_addr addrs[20];
+       struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
+       struct rmtcallargs a;
+       struct rmtcallres r;
+       struct rpc_msg msg;
+       struct timeval t; 
+       char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
+
+       /*
+        * initialization: create a socket, a broadcast address, and
+        * preserialize the arguments into a send buffer.
+        */
+       if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+               perror("Cannot create socket for broadcast rpc");
+               stat = RPC_CANTSEND;
+               goto done_broad;
+       }
+#ifdef SO_BROADCAST
+       if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
+               perror("Cannot set socket option SO_BROADCAST");
+               stat = RPC_CANTSEND;
+               goto done_broad;
+       }
+#endif /* def SO_BROADCAST */
+#ifdef FD_SETSIZE
+       FD_ZERO(&mask);
+       FD_SET(sock, &mask);
+#else
+       mask = (1 << sock);
+#endif /* def FD_SETSIZE */
+       nets = getbroadcastnets(addrs, sock, inbuf);
+       bzero((char *)&baddr, sizeof (baddr));
+       baddr.sin_family = AF_INET;
+       baddr.sin_port = htons(PMAPPORT);
+       baddr.sin_addr.s_addr = htonl(INADDR_ANY);
+/*     baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */
+       (void)gettimeofday(&t, (struct timezone *)0);
+       msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec;
+       t.tv_usec = 0;
+       msg.rm_direction = CALL;
+       msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+       msg.rm_call.cb_prog = PMAPPROG;
+       msg.rm_call.cb_vers = PMAPVERS;
+       msg.rm_call.cb_proc = PMAPPROC_CALLIT;
+       msg.rm_call.cb_cred = unix_auth->ah_cred;
+       msg.rm_call.cb_verf = unix_auth->ah_verf;
+       a.prog = prog;
+       a.vers = vers;
+       a.proc = proc;
+       a.xdr_args = xargs;
+       a.args_ptr = argsp;
+       r.port_ptr = &port;
+       r.xdr_results = xresults;
+       r.results_ptr = resultsp;
+       xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
+       if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
+               stat = RPC_CANTENCODEARGS;
+               goto done_broad;
+       }
+       outlen = (int)xdr_getpos(xdrs);
+       xdr_destroy(xdrs);
+       /*
+        * Basic loop: broadcast a packet and wait a while for response(s).
+        * The response timeout grows larger per iteration.
+        */
+       for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
+               for (i = 0; i < nets; i++) {
+                       baddr.sin_addr = addrs[i];
+                       if (sendto(sock, outbuf, outlen, 0,
+                               (struct sockaddr *)&baddr,
+                               sizeof (struct sockaddr)) != outlen) {
+                               perror("Cannot send broadcast packet");
+                               stat = RPC_CANTSEND;
+                               goto done_broad;
+                       }
+               }
+               if (eachresult == NULL) {
+                       stat = RPC_SUCCESS;
+                       goto done_broad;
+               }
+       recv_again:
+               msg.acpted_rply.ar_verf = _null_auth;
+               msg.acpted_rply.ar_results.where = (caddr_t)&r;
+                msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
+               readfds = mask;
+               switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, 
+                              (int *)NULL, &t)) {
+
+               case 0:  /* timed out */
+                       stat = RPC_TIMEDOUT;
+                       continue;
+
+               case -1:  /* some kind of error */
+                       if (errno == EINTR)
+                               goto recv_again;
+                       perror("Broadcast select problem");
+                       stat = RPC_CANTRECV;
+                       goto done_broad;
+
+               }  /* end of select results switch */
+       try_again:
+               fromlen = sizeof(struct sockaddr);
+               inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0,
+                       (struct sockaddr *)&raddr, &fromlen);
+               if (inlen < 0) {
+                       if (errno == EINTR)
+                               goto try_again;
+                       perror("Cannot receive reply to broadcast");
+                       stat = RPC_CANTRECV;
+                       goto done_broad;
+               }
+               if (inlen < sizeof(u_long))
+                       goto recv_again;
+               /*
+                * see if reply transaction id matches sent id.
+                * If so, decode the results.
+                */
+               xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
+               if (xdr_replymsg(xdrs, &msg)) {
+                       if ((msg.rm_xid == xid) &&
+                               (msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
+                               (msg.acpted_rply.ar_stat == SUCCESS)) {
+                               raddr.sin_port = htons((u_short)port);
+                               done = (*eachresult)(resultsp, &raddr);
+                       }
+                       /* otherwise, we just ignore the errors ... */
+               } else {
+#ifdef notdef
+                       /* some kind of deserialization problem ... */
+                       if (msg.rm_xid == xid)
+                               fprintf(stderr, "Broadcast deserialization problem");
+                       /* otherwise, just random garbage */
+#endif
+               }
+               xdrs->x_op = XDR_FREE;
+               msg.acpted_rply.ar_results.proc = xdr_void;
+               (void)xdr_replymsg(xdrs, &msg);
+               (void)(*xresults)(xdrs, resultsp);
+               xdr_destroy(xdrs);
+               if (done) {
+                       stat = RPC_SUCCESS;
+                       goto done_broad;
+               } else {
+                       goto recv_again;
+               }
+       }
+done_broad:
+       (void)close(sock);
+       AUTH_DESTROY(unix_auth);
+       return (stat);
+}
+
diff --git a/libc/inet/rpc/rpc_callmsg.c b/libc/inet/rpc/rpc_callmsg.c
new file mode 100644 (file)
index 0000000..d9d815a
--- /dev/null
@@ -0,0 +1,190 @@
+/* @(#)rpc_callmsg.c   2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * rpc_callmsg.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+
+#include <sys/param.h>
+
+#include <rpc/rpc.h>
+
+/*
+ * XDR a call message
+ */
+bool_t
+xdr_callmsg(xdrs, cmsg)
+       register XDR *xdrs;
+       register struct rpc_msg *cmsg;
+{
+       register long *buf;
+       register struct opaque_auth *oa;
+
+       if (xdrs->x_op == XDR_ENCODE) {
+               if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
+                       return (FALSE);
+               }
+               if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
+                       return (FALSE);
+               }
+               buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
+                       + RNDUP(cmsg->rm_call.cb_cred.oa_length)
+                       + 2 * BYTES_PER_XDR_UNIT
+                       + RNDUP(cmsg->rm_call.cb_verf.oa_length));
+               if (buf != NULL) {
+                       IXDR_PUT_LONG(buf, cmsg->rm_xid);
+                       IXDR_PUT_ENUM(buf, cmsg->rm_direction);
+                       if (cmsg->rm_direction != CALL) {
+                               return (FALSE);
+                       }
+                       IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
+                       if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+                               return (FALSE);
+                       }
+                       IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
+                       IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
+                       IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
+                       oa = &cmsg->rm_call.cb_cred;
+                       IXDR_PUT_ENUM(buf, oa->oa_flavor);
+                       IXDR_PUT_LONG(buf, oa->oa_length);
+                       if (oa->oa_length) {
+                               bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
+                               buf += RNDUP(oa->oa_length) / sizeof (long);
+                       }
+                       oa = &cmsg->rm_call.cb_verf;
+                       IXDR_PUT_ENUM(buf, oa->oa_flavor);
+                       IXDR_PUT_LONG(buf, oa->oa_length);
+                       if (oa->oa_length) {
+                               bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
+                               /* no real need....
+                               buf += RNDUP(oa->oa_length) / sizeof (long);
+                               */
+                       }
+                       return (TRUE);
+               }
+       }
+       if (xdrs->x_op == XDR_DECODE) {
+               buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
+               if (buf != NULL) {
+                       cmsg->rm_xid = IXDR_GET_LONG(buf);
+                       cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
+                       if (cmsg->rm_direction != CALL) {
+                               return (FALSE);
+                       }
+                       cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
+                       if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+                               return (FALSE);
+                       }
+                       cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
+                       cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
+                       cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
+                       oa = &cmsg->rm_call.cb_cred;
+                       oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+                       oa->oa_length = IXDR_GET_LONG(buf);
+                       if (oa->oa_length) {
+                               if (oa->oa_length > MAX_AUTH_BYTES) {
+                                       return (FALSE);
+                               }
+                               if (oa->oa_base == NULL) {
+                                       oa->oa_base = (caddr_t)
+                                               mem_alloc(oa->oa_length);
+                               }
+                               buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+                               if (buf == NULL) {
+                                       if (xdr_opaque(xdrs, oa->oa_base,
+                                           oa->oa_length) == FALSE) {
+                                               return (FALSE);
+                                       }
+                               } else {
+                                       bcopy((caddr_t)buf, oa->oa_base,
+                                           oa->oa_length);
+                                       /* no real need....
+                                       buf += RNDUP(oa->oa_length) /
+                                               sizeof (long);
+                                       */
+                               }
+                       }
+                       oa = &cmsg->rm_call.cb_verf;
+                       buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
+                       if (buf == NULL) {
+                               if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
+                                   xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
+                                       return (FALSE);
+                               }
+                       } else {
+                               oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+                               oa->oa_length = IXDR_GET_LONG(buf);
+                       }
+                       if (oa->oa_length) {
+                               if (oa->oa_length > MAX_AUTH_BYTES) {
+                                       return (FALSE);
+                               }
+                               if (oa->oa_base == NULL) {
+                                       oa->oa_base = (caddr_t)
+                                               mem_alloc(oa->oa_length);
+                               }
+                               buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+                               if (buf == NULL) {
+                                       if (xdr_opaque(xdrs, oa->oa_base,
+                                           oa->oa_length) == FALSE) {
+                                               return (FALSE);
+                                       }
+                               } else {
+                                       bcopy((caddr_t)buf, oa->oa_base,
+                                           oa->oa_length);
+                                       /* no real need...
+                                       buf += RNDUP(oa->oa_length) /
+                                               sizeof (long);
+                                       */
+                               }
+                       }
+                       return (TRUE);
+               }
+       }
+       if (
+           xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
+           xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+           (cmsg->rm_direction == CALL) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+           (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) &&
+           xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
+           return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
+       return (FALSE);
+}
+
diff --git a/libc/inet/rpc/rpc_commondata.c b/libc/inet/rpc/rpc_commondata.c
new file mode 100644 (file)
index 0000000..75cead0
--- /dev/null
@@ -0,0 +1,41 @@
+/* @(#)rpc_commondata.c        2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#include <rpc/rpc.h>
+/*
+ * This file should only contain common data (global data) that is exported
+ * by public interfaces 
+ */
+struct opaque_auth _null_auth;
+#ifdef FD_SETSIZE
+fd_set svc_fdset;
+#else
+int svc_fds;
+#endif /* def FD_SETSIZE */
+struct rpc_createerr rpc_createerr;
diff --git a/libc/inet/rpc/rpc_dtablesize.c b/libc/inet/rpc/rpc_dtablesize.c
new file mode 100644 (file)
index 0000000..a848817
--- /dev/null
@@ -0,0 +1,46 @@
+/* @(#)rpc_dtablesize.c        2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";
+#endif
+
+/*
+ * Cache the result of getdtablesize(), so we don't have to do an
+ * expensive system call every time.
+ */
+_rpc_dtablesize()
+{
+       static int size;
+       
+       if (size == 0) {
+               size = getdtablesize();
+       }
+       return (size);
+}
diff --git a/libc/inet/rpc/rpc_prot.c b/libc/inet/rpc/rpc_prot.c
new file mode 100644 (file)
index 0000000..4b1319a
--- /dev/null
@@ -0,0 +1,289 @@
+/* @(#)rpc_prot.c      2.3 88/08/07 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * rpc_prot.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements the rpc message definition,
+ * its serializer and some common rpc utility routines.
+ * The routines are meant for various implementations of rpc -
+ * they are NOT for the rpc client or rpc service implementations!
+ * Because authentication stuff is easy and is part of rpc, the opaque
+ * routines are also in this program.
+ */
+
+#include <sys/param.h>
+
+#include <rpc/rpc.h>
+
+/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
+
+struct opaque_auth _null_auth;
+
+/*
+ * XDR an opaque authentication struct
+ * (see auth.h)
+ */
+bool_t
+xdr_opaque_auth(xdrs, ap)
+       register XDR *xdrs;
+       register struct opaque_auth *ap;
+{
+
+       if (xdr_enum(xdrs, &(ap->oa_flavor)))
+               return (xdr_bytes(xdrs, &ap->oa_base,
+                       &ap->oa_length, MAX_AUTH_BYTES));
+       return (FALSE);
+}
+
+/*
+ * XDR a DES block
+ */
+bool_t
+xdr_des_block(xdrs, blkp)
+       register XDR *xdrs;
+       register des_block *blkp;
+{
+       return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
+}
+
+/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
+
+/*
+ * XDR the MSG_ACCEPTED part of a reply message union
+ */
+bool_t 
+xdr_accepted_reply(xdrs, ar)
+       register XDR *xdrs;   
+       register struct accepted_reply *ar;
+{
+
+       /* personalized union, rather than calling xdr_union */
+       if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
+               return (FALSE);
+       if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
+               return (FALSE);
+       switch (ar->ar_stat) {
+
+       case SUCCESS:
+               return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
+
+       case PROG_MISMATCH:
+               if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
+                       return (FALSE);
+               return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
+       }
+       return (TRUE);  /* TRUE => open ended set of problems */
+}
+
+/*
+ * XDR the MSG_DENIED part of a reply message union
+ */
+bool_t 
+xdr_rejected_reply(xdrs, rr)
+       register XDR *xdrs;
+       register struct rejected_reply *rr;
+{
+
+       /* personalized union, rather than calling xdr_union */
+       if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
+               return (FALSE);
+       switch (rr->rj_stat) {
+
+       case RPC_MISMATCH:
+               if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
+                       return (FALSE);
+               return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
+
+       case AUTH_ERROR:
+               return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
+       }
+       return (FALSE);
+}
+
+static struct xdr_discrim reply_dscrm[3] = {
+       { (int)MSG_ACCEPTED, xdr_accepted_reply },
+       { (int)MSG_DENIED, xdr_rejected_reply },
+       { __dontcare__, NULL_xdrproc_t } };
+
+/*
+ * XDR a reply message
+ */
+bool_t
+xdr_replymsg(xdrs, rmsg)
+       register XDR *xdrs;
+       register struct rpc_msg *rmsg;
+{
+       if (
+           xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
+           xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
+           (rmsg->rm_direction == REPLY) )
+               return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
+                  (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
+       return (FALSE);
+}
+
+
+/*
+ * Serializes the "static part" of a call message header.
+ * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
+ * The rm_xid is not really static, but the user can easily munge on the fly.
+ */
+bool_t
+xdr_callhdr(xdrs, cmsg)
+       register XDR *xdrs;
+       register struct rpc_msg *cmsg;
+{
+
+       cmsg->rm_direction = CALL;
+       cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
+       if (
+           (xdrs->x_op == XDR_ENCODE) &&
+           xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
+           xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
+           return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
+       return (FALSE);
+}
+
+/* ************************** Client utility routine ************* */
+
+static void
+accepted(acpt_stat, error)
+       register enum accept_stat acpt_stat;
+       register struct rpc_err *error;
+{
+
+       switch (acpt_stat) {
+
+       case PROG_UNAVAIL:
+               error->re_status = RPC_PROGUNAVAIL;
+               return;
+
+       case PROG_MISMATCH:
+               error->re_status = RPC_PROGVERSMISMATCH;
+               return;
+
+       case PROC_UNAVAIL:
+               error->re_status = RPC_PROCUNAVAIL;
+               return;
+
+       case GARBAGE_ARGS:
+               error->re_status = RPC_CANTDECODEARGS;
+               return;
+
+       case SYSTEM_ERR:
+               error->re_status = RPC_SYSTEMERROR;
+               return;
+
+       case SUCCESS:
+               error->re_status = RPC_SUCCESS;
+               return;
+       }
+       /* something's wrong, but we don't know what ... */
+       error->re_status = RPC_FAILED;
+       error->re_lb.s1 = (long)MSG_ACCEPTED;
+       error->re_lb.s2 = (long)acpt_stat;
+}
+
+static void 
+rejected(rjct_stat, error)
+       register enum reject_stat rjct_stat;
+       register struct rpc_err *error;
+{
+
+       switch (rjct_stat) {
+
+       case RPC_VERSMISMATCH:
+               error->re_status = RPC_VERSMISMATCH;
+               return;
+
+       case AUTH_ERROR:
+               error->re_status = RPC_AUTHERROR;
+               return;
+       }
+       /* something's wrong, but we don't know what ... */
+       error->re_status = RPC_FAILED;
+       error->re_lb.s1 = (long)MSG_DENIED;
+       error->re_lb.s2 = (long)rjct_stat;
+}
+
+/*
+ * given a reply message, fills in the error
+ */
+void
+_seterr_reply(msg, error)
+       register struct rpc_msg *msg;
+       register struct rpc_err *error;
+{
+
+       /* optimized for normal, SUCCESSful case */
+       switch (msg->rm_reply.rp_stat) {
+
+       case MSG_ACCEPTED:
+               if (msg->acpted_rply.ar_stat == SUCCESS) {
+                       error->re_status = RPC_SUCCESS;
+                       return;
+               };
+               accepted(msg->acpted_rply.ar_stat, error);
+               break;
+
+       case MSG_DENIED:
+               rejected(msg->rjcted_rply.rj_stat, error);
+               break;
+
+       default:
+               error->re_status = RPC_FAILED;
+               error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
+               break;
+       }
+       switch (error->re_status) {
+
+       case RPC_VERSMISMATCH:
+               error->re_vers.low = msg->rjcted_rply.rj_vers.low;
+               error->re_vers.high = msg->rjcted_rply.rj_vers.high;
+               break;
+
+       case RPC_AUTHERROR:
+               error->re_why = msg->rjcted_rply.rj_why;
+               break;
+
+       case RPC_PROGVERSMISMATCH:
+               error->re_vers.low = msg->acpted_rply.ar_vers.low;
+               error->re_vers.high = msg->acpted_rply.ar_vers.high;
+               break;
+       }
+}
diff --git a/libc/inet/rpc/svc.c b/libc/inet/rpc/svc.c
new file mode 100644 (file)
index 0000000..feac646
--- /dev/null
@@ -0,0 +1,492 @@
+/* @(#)svc.c   2.4 88/08/11 4.0 RPCSRC; from 1.44 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc.c 1.41 87/10/13 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc.c, Server-side remote procedure call interface.
+ *
+ * There are two sets of procedures here.  The xprt routines are
+ * for handling transport handles.  The svc routines handle the
+ * list of service routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <sys/errno.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#ifdef linux
+#include <sys/types.h>
+#endif
+
+extern int errno;
+
+#ifdef FD_SETSIZE
+static SVCXPRT **xports;
+#else
+#define NOFILE 32
+
+static SVCXPRT *xports[NOFILE];
+#endif /* def FD_SETSIZE */
+
+#define NULL_SVC ((struct svc_callout *)0)
+#define        RQCRED_SIZE     400             /* this size is excessive */
+
+/*
+ * The services list
+ * Each entry represents a set of procedures (an rpc program).
+ * The dispatch routine takes request structs and runs the
+ * apropriate procedure.
+ */
+static struct svc_callout {
+       struct svc_callout *sc_next;
+       u_long              sc_prog;
+       u_long              sc_vers;
+       void                (*sc_dispatch)();
+} *svc_head;
+
+static struct svc_callout *svc_find();
+
+/* ***************  SVCXPRT related stuff **************** */
+
+/*
+ * Activate a transport handle.
+ */
+void
+xprt_register(xprt)
+       SVCXPRT *xprt;
+{
+       register int sock = xprt->xp_sock;
+
+#ifdef FD_SETSIZE
+       if (xports == NULL) {
+               xports = (SVCXPRT **)
+                       mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *));
+       }
+       if (sock < _rpc_dtablesize()) {
+               xports[sock] = xprt;
+               FD_SET(sock, &svc_fdset);
+       }
+#else
+       if (sock < NOFILE) {
+               xports[sock] = xprt;
+               svc_fds |= (1 << sock);
+       }
+#endif /* def FD_SETSIZE */
+
+}
+
+/*
+ * De-activate a transport handle. 
+ */
+void
+xprt_unregister(xprt) 
+       SVCXPRT *xprt;
+{ 
+       register int sock = xprt->xp_sock;
+
+#ifdef FD_SETSIZE
+       if ((sock < _rpc_dtablesize()) && (xports[sock] == xprt)) {
+               xports[sock] = (SVCXPRT *)0;
+               FD_CLR(sock, &svc_fdset);
+       }
+#else
+       if ((sock < NOFILE) && (xports[sock] == xprt)) {
+               xports[sock] = (SVCXPRT *)0;
+               svc_fds &= ~(1 << sock);
+       }
+#endif /* def FD_SETSIZE */
+}
+
+
+/* ********************** CALLOUT list related stuff ************* */
+
+/*
+ * Add a service program to the callout list.
+ * The dispatch routine will be called when a rpc request for this
+ * program number comes in.
+ */
+bool_t
+svc_register(xprt, prog, vers, dispatch, protocol)
+       SVCXPRT *xprt;
+       u_long prog;
+       u_long vers;
+       void (*dispatch)();
+       int protocol;
+{
+       struct svc_callout *prev;
+       register struct svc_callout *s;
+
+       if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) {
+               if (s->sc_dispatch == dispatch)
+                       goto pmap_it;  /* he is registering another xptr */
+               return (FALSE);
+       }
+       s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout));
+       if (s == (struct svc_callout *)0) {
+               return (FALSE);
+       }
+       s->sc_prog = prog;
+       s->sc_vers = vers;
+       s->sc_dispatch = dispatch;
+       s->sc_next = svc_head;
+       svc_head = s;
+pmap_it:
+       /* now register the information with the local binder service */
+       if (protocol) {
+               return (pmap_set(prog, vers, protocol, xprt->xp_port));
+       }
+       return (TRUE);
+}
+
+/*
+ * Remove a service program from the callout list.
+ */
+void
+svc_unregister(prog, vers)
+       u_long prog;
+       u_long vers;
+{
+       struct svc_callout *prev;
+       register struct svc_callout *s;
+
+       if ((s = svc_find(prog, vers, &prev)) == NULL_SVC)
+               return;
+       if (prev == NULL_SVC) {
+               svc_head = s->sc_next;
+       } else {
+               prev->sc_next = s->sc_next;
+       }
+       s->sc_next = NULL_SVC;
+       mem_free((char *) s, (u_int) sizeof(struct svc_callout));
+       /* now unregister the information with the local binder service */
+       (void)pmap_unset(prog, vers);
+}
+
+/*
+ * Search the callout list for a program number, return the callout
+ * struct.
+ */
+static struct svc_callout *
+svc_find(prog, vers, prev)
+       u_long prog;
+       u_long vers;
+       struct svc_callout **prev;
+{
+       register struct svc_callout *s, *p;
+
+       p = NULL_SVC;
+       for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+               if ((s->sc_prog == prog) && (s->sc_vers == vers))
+                       goto done;
+               p = s;
+       }
+done:
+       *prev = p;
+       return (s);
+}
+
+/* ******************* REPLY GENERATION ROUTINES  ************ */
+
+/*
+ * Send a reply to an rpc request
+ */
+bool_t
+svc_sendreply(xprt, xdr_results, xdr_location)
+       register SVCXPRT *xprt;
+       xdrproc_t xdr_results;
+       caddr_t xdr_location;
+{
+       struct rpc_msg rply; 
+
+       rply.rm_direction = REPLY;  
+       rply.rm_reply.rp_stat = MSG_ACCEPTED; 
+       rply.acpted_rply.ar_verf = xprt->xp_verf; 
+       rply.acpted_rply.ar_stat = SUCCESS;
+       rply.acpted_rply.ar_results.where = xdr_location;
+       rply.acpted_rply.ar_results.proc = xdr_results;
+       return (SVC_REPLY(xprt, &rply)); 
+}
+
+/*
+ * No procedure error reply
+ */
+void
+svcerr_noproc(xprt)
+       register SVCXPRT *xprt;
+{
+       struct rpc_msg rply;
+
+       rply.rm_direction = REPLY;
+       rply.rm_reply.rp_stat = MSG_ACCEPTED;
+       rply.acpted_rply.ar_verf = xprt->xp_verf;
+       rply.acpted_rply.ar_stat = PROC_UNAVAIL;
+       SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Can't decode args error reply
+ */
+void
+svcerr_decode(xprt)
+       register SVCXPRT *xprt;
+{
+       struct rpc_msg rply; 
+
+       rply.rm_direction = REPLY; 
+       rply.rm_reply.rp_stat = MSG_ACCEPTED; 
+       rply.acpted_rply.ar_verf = xprt->xp_verf;
+       rply.acpted_rply.ar_stat = GARBAGE_ARGS;
+       SVC_REPLY(xprt, &rply); 
+}
+
+/*
+ * Some system error
+ */
+void
+svcerr_systemerr(xprt)
+       register SVCXPRT *xprt;
+{
+       struct rpc_msg rply; 
+
+       rply.rm_direction = REPLY; 
+       rply.rm_reply.rp_stat = MSG_ACCEPTED; 
+       rply.acpted_rply.ar_verf = xprt->xp_verf;
+       rply.acpted_rply.ar_stat = SYSTEM_ERR;
+       SVC_REPLY(xprt, &rply); 
+}
+
+/*
+ * Authentication error reply
+ */
+void
+svcerr_auth(xprt, why)
+       SVCXPRT *xprt;
+       enum auth_stat why;
+{
+       struct rpc_msg rply;
+
+       rply.rm_direction = REPLY;
+       rply.rm_reply.rp_stat = MSG_DENIED;
+       rply.rjcted_rply.rj_stat = AUTH_ERROR;
+       rply.rjcted_rply.rj_why = why;
+       SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Auth too weak error reply
+ */
+void
+svcerr_weakauth(xprt)
+       SVCXPRT *xprt;
+{
+
+       svcerr_auth(xprt, AUTH_TOOWEAK);
+}
+
+/*
+ * Program unavailable error reply
+ */
+void 
+svcerr_noprog(xprt)
+       register SVCXPRT *xprt;
+{
+       struct rpc_msg rply;  
+
+       rply.rm_direction = REPLY;   
+       rply.rm_reply.rp_stat = MSG_ACCEPTED;  
+       rply.acpted_rply.ar_verf = xprt->xp_verf;  
+       rply.acpted_rply.ar_stat = PROG_UNAVAIL;
+       SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Program version mismatch error reply
+ */
+void  
+svcerr_progvers(xprt, low_vers, high_vers)
+       register SVCXPRT *xprt; 
+       u_long low_vers;
+       u_long high_vers;
+{
+       struct rpc_msg rply;
+
+       rply.rm_direction = REPLY;
+       rply.rm_reply.rp_stat = MSG_ACCEPTED;
+       rply.acpted_rply.ar_verf = xprt->xp_verf;
+       rply.acpted_rply.ar_stat = PROG_MISMATCH;
+       rply.acpted_rply.ar_vers.low = low_vers;
+       rply.acpted_rply.ar_vers.high = high_vers;
+       SVC_REPLY(xprt, &rply);
+}
+
+/* ******************* SERVER INPUT STUFF ******************* */
+
+/*
+ * Get server side input from some transport.
+ *
+ * Statement of authentication parameters management:
+ * This function owns and manages all authentication parameters, specifically
+ * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and
+ * the "cooked" credentials (rqst->rq_clntcred).
+ * However, this function does not know the structure of the cooked
+ * credentials, so it make the following assumptions: 
+ *   a) the structure is contiguous (no pointers), and
+ *   b) the cred structure size does not exceed RQCRED_SIZE bytes. 
+ * In all events, all three parameters are freed upon exit from this routine.
+ * The storage is trivially management on the call stack in user land, but
+ * is mallocated in kernel land.
+ */
+
+void
+svc_getreq(rdfds)
+       int rdfds;
+{
+#ifdef FD_SETSIZE
+       fd_set readfds;
+
+       FD_ZERO(&readfds);
+/*#ifdef linux*/
+#if 0
+       readfds = rdfds;
+#else
+       readfds.fds_bits[0] = rdfds;
+#endif
+       svc_getreqset(&readfds);
+#else
+       int readfds = rdfds & svc_fds;
+
+       svc_getreqset(&readfds);
+#endif /* def FD_SETSIZE */
+}
+
+void
+svc_getreqset(readfds)
+#ifdef FD_SETSIZE
+       fd_set *readfds;
+{
+#else
+       int *readfds;
+{
+    int readfds_local = *readfds;
+#endif /* def FD_SETSIZE */
+       enum xprt_stat stat;
+       struct rpc_msg msg;
+       int prog_found;
+       u_long low_vers;
+       u_long high_vers;
+       struct svc_req r;
+       register SVCXPRT *xprt;
+       register u_long mask;
+       register int bit;
+       register u_long *maskp;
+       register int setsize;
+       register int sock;
+       char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];
+       msg.rm_call.cb_cred.oa_base = cred_area;
+       msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
+       r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
+
+
+#ifdef FD_SETSIZE
+       setsize = _rpc_dtablesize();    
+#ifdef linux
+/*#define NFDBITS      32*/
+       maskp = (u_long *)readfds;
+#else
+       maskp = (u_long *)readfds->fds_bits;
+#endif
+       for (sock = 0; sock < setsize; sock += NFDBITS) {
+           for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) {
+               /* sock has input waiting */
+               xprt = xports[sock + bit - 1];
+#else
+       for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) {
+           if ((readfds_local & 1) != 0) {
+               /* sock has input waiting */
+               xprt = xports[sock];
+#endif /* def FD_SETSIZE */
+               /* now receive msgs from xprtprt (support batch calls) */
+               do {
+                       if (SVC_RECV(xprt, &msg)) {
+
+                               /* now find the exported program and call it */
+                               register struct svc_callout *s;
+                               enum auth_stat why;
+
+                               r.rq_xprt = xprt;
+                               r.rq_prog = msg.rm_call.cb_prog;
+                               r.rq_vers = msg.rm_call.cb_vers;
+                               r.rq_proc = msg.rm_call.cb_proc;
+                               r.rq_cred = msg.rm_call.cb_cred;
+                               /* first authenticate the message */
+                               if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
+                                       svcerr_auth(xprt, why);
+                                       goto call_done;
+                               }
+                               /* now match message with a registered service*/
+                               prog_found = FALSE;
+                               low_vers = 0 - 1;
+                               high_vers = 0;
+                               for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+                                       if (s->sc_prog == r.rq_prog) {
+                                               if (s->sc_vers == r.rq_vers) {
+                                                       (*s->sc_dispatch)(&r, xprt);
+                                                       goto call_done;
+                                               }  /* found correct version */
+                                               prog_found = TRUE;
+                                               if (s->sc_vers < low_vers)
+                                                       low_vers = s->sc_vers;
+                                               if (s->sc_vers > high_vers)
+                                                       high_vers = s->sc_vers;
+                                       }   /* found correct program */
+                               }
+                               /*
+                                * if we got here, the program or version
+                                * is not served ...
+                                */
+                               if (prog_found)
+                                       svcerr_progvers(xprt,
+                                       low_vers, high_vers);
+                               else
+                                        svcerr_noprog(xprt);
+                               /* Fall through to ... */
+                       }
+               call_done:
+                       if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
+                               SVC_DESTROY(xprt);
+                               break;
+                       }
+               } while (stat == XPRT_MOREREQS);
+           }
+       }
+}
diff --git a/libc/inet/rpc/svc_auth.c b/libc/inet/rpc/svc_auth.c
new file mode 100644 (file)
index 0000000..ab7ab69
--- /dev/null
@@ -0,0 +1,114 @@
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_auth.c 2.1 88/08/07 4.0 RPCSRC; from 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * svc_auth_nodes.c, Server-side rpc authenticator interface,
+ * *WITHOUT* DES authentication.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+
+/*
+ * svcauthsw is the bdevsw of server side authentication. 
+ * 
+ * Server side authenticators are called from authenticate by
+ * using the client auth struct flavor field to index into svcauthsw.
+ * The server auth flavors must implement a routine that looks  
+ * like: 
+ * 
+ *     enum auth_stat
+ *     flavorx_auth(rqst, msg)
+ *             register struct svc_req *rqst; 
+ *             register struct rpc_msg *msg;
+ *
+ */
+
+enum auth_stat _svcauth_null();                /* no authentication */
+enum auth_stat _svcauth_unix();                /* unix style (uid, gids) */
+enum auth_stat _svcauth_short();       /* short hand unix style */
+
+static struct {
+       enum auth_stat (*authenticator)();
+} svcauthsw[] = {
+       _svcauth_null,                  /* AUTH_NULL */
+       _svcauth_unix,                  /* AUTH_UNIX */
+       _svcauth_short,                 /* AUTH_SHORT */
+};
+#define        AUTH_MAX        2               /* HIGHEST AUTH NUMBER */
+
+
+/*
+ * The call rpc message, msg has been obtained from the wire.  The msg contains
+ * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
+ * if the msg is successfully authenticated.  If AUTH_OK then the routine also
+ * does the following things:
+ * set rqst->rq_xprt->verf to the appropriate response verifier;
+ * sets rqst->rq_client_cred to the "cooked" form of the credentials.
+ *
+ * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
+ * its length is set appropriately.
+ *
+ * The caller still owns and is responsible for msg->u.cmb.cred and
+ * msg->u.cmb.verf.  The authentication system retains ownership of
+ * rqst->rq_client_cred, the cooked credentials.
+ *
+ * There is an assumption that any flavour less than AUTH_NULL is
+ * invalid.
+ */
+enum auth_stat
+_authenticate(rqst, msg)
+       register struct svc_req *rqst;
+       struct rpc_msg *msg;
+{
+       register int cred_flavor;
+
+       rqst->rq_cred = msg->rm_call.cb_cred;
+       rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
+       rqst->rq_xprt->xp_verf.oa_length = 0;
+       cred_flavor = rqst->rq_cred.oa_flavor;
+       if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL)) {
+               return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg));
+       }
+
+       return (AUTH_REJECTEDCRED);
+}
+
+enum auth_stat
+_svcauth_null(/*rqst, msg*/)
+       /*struct svc_req *rqst;
+       struct rpc_msg *msg;*/
+{
+
+       return (AUTH_OK);
+}
diff --git a/libc/inet/rpc/svc_auth_unix.c b/libc/inet/rpc/svc_auth_unix.c
new file mode 100644 (file)
index 0000000..ea00b78
--- /dev/null
@@ -0,0 +1,134 @@
+/* @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC; from 1.28 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_auth_unix.c
+ * Handles UNIX flavor authentication parameters on the service side of rpc.
+ * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT.
+ * _svcauth_unix does full blown unix style uid,gid+gids auth,
+ * _svcauth_short uses a shorthand auth to index into a cache of longhand auths.
+ * Note: the shorthand has been gutted for efficiency.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+
+/*
+ * Unix longhand authenticator
+ */
+enum auth_stat
+_svcauth_unix(rqst, msg)
+       register struct svc_req *rqst;
+       register struct rpc_msg *msg;
+{
+       register enum auth_stat stat;
+       XDR xdrs;
+       register struct authunix_parms *aup;
+       register long *buf;
+       struct area {
+               struct authunix_parms area_aup;
+               char area_machname[MAX_MACHINE_NAME+1];
+               int area_gids[NGRPS];
+       } *area;
+       u_int auth_len;
+       int str_len, gid_len;
+       register int i;
+
+       area = (struct area *) rqst->rq_clntcred;
+       aup = &area->area_aup;
+       aup->aup_machname = area->area_machname;
+       aup->aup_gids = area->area_gids;
+       auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
+       xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
+       buf = XDR_INLINE(&xdrs, auth_len);
+       if (buf != NULL) {
+               aup->aup_time = IXDR_GET_LONG(buf);
+               str_len = IXDR_GET_U_LONG(buf);
+               if (str_len > MAX_MACHINE_NAME) {
+                       stat = AUTH_BADCRED;
+                       goto done;
+               }
+               bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len);
+               aup->aup_machname[str_len] = 0;
+               str_len = RNDUP(str_len);
+               buf += str_len / sizeof (long);
+               aup->aup_uid = IXDR_GET_LONG(buf);
+               aup->aup_gid = IXDR_GET_LONG(buf);
+               gid_len = IXDR_GET_U_LONG(buf);
+               if (gid_len > NGRPS) {
+                       stat = AUTH_BADCRED;
+                       goto done;
+               }
+               aup->aup_len = gid_len;
+               for (i = 0; i < gid_len; i++) {
+                       aup->aup_gids[i] = IXDR_GET_LONG(buf);
+               }
+               /*
+                * five is the smallest unix credentials structure -
+                * timestamp, hostname len (0), uid, gid, and gids len (0).
+                */
+               if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
+                       (void) printf("bad auth_len gid %d str %d auth %d\n",
+                           gid_len, str_len, auth_len);
+                       stat = AUTH_BADCRED;
+                       goto done;
+               }
+       } else if (! xdr_authunix_parms(&xdrs, aup)) {
+               xdrs.x_op = XDR_FREE;
+               (void)xdr_authunix_parms(&xdrs, aup);
+               stat = AUTH_BADCRED;
+               goto done;
+       }
+       rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
+       rqst->rq_xprt->xp_verf.oa_length = 0;
+       stat = AUTH_OK;
+done:
+       XDR_DESTROY(&xdrs);
+       return (stat);
+}
+
+
+/*
+ * Shorthand unix authenticator
+ * Looks up longhand in a cache.
+ */
+/*ARGSUSED*/
+enum auth_stat 
+_svcauth_short(rqst, msg)
+       struct svc_req *rqst;
+       struct rpc_msg *msg;
+{
+       return (AUTH_REJECTEDCRED);
+}
diff --git a/libc/inet/rpc/svc_raw.c b/libc/inet/rpc/svc_raw.c
new file mode 100644 (file)
index 0000000..1170ece
--- /dev/null
@@ -0,0 +1,166 @@
+/* @(#)svc_raw.c       2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_raw.c,   This a toy for simple testing and timing.
+ * Interface to create an rpc client and server in the same UNIX process.
+ * This lets us similate rpc and get rpc (round trip) overhead, without
+ * any interference from the kernal.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+
+
+/*
+ * This is the "network" that we will be moving data over
+ */
+static struct svcraw_private {
+       char    _raw_buf[UDPMSGSIZE];
+       SVCXPRT server;
+       XDR     xdr_stream;
+       char    verf_body[MAX_AUTH_BYTES];
+} *svcraw_private;
+
+static bool_t          svcraw_recv();
+static enum xprt_stat  svcraw_stat();
+static bool_t          svcraw_getargs();
+static bool_t          svcraw_reply();
+static bool_t          svcraw_freeargs();
+static void            svcraw_destroy();
+
+static struct xp_ops server_ops = {
+       svcraw_recv,
+       svcraw_stat,
+       svcraw_getargs,
+       svcraw_reply,
+       svcraw_freeargs,
+       svcraw_destroy
+};
+
+SVCXPRT *
+svcraw_create()
+{
+       register struct svcraw_private *srp = svcraw_private;
+
+       if (srp == 0) {
+               srp = (struct svcraw_private *)calloc(1, sizeof (*srp));
+               if (srp == 0)
+                       return (0);
+       }
+       srp->server.xp_sock = 0;
+       srp->server.xp_port = 0;
+       srp->server.xp_ops = &server_ops;
+       srp->server.xp_verf.oa_base = srp->verf_body;
+       xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+       return (&srp->server);
+}
+
+static enum xprt_stat
+svcraw_stat()
+{
+
+       return (XPRT_IDLE);
+}
+
+static bool_t
+svcraw_recv(xprt, msg)
+       SVCXPRT *xprt;
+       struct rpc_msg *msg;
+{
+       register struct svcraw_private *srp = svcraw_private;
+       register XDR *xdrs;
+
+       if (srp == 0)
+               return (0);
+       xdrs = &srp->xdr_stream;
+       xdrs->x_op = XDR_DECODE;
+       XDR_SETPOS(xdrs, 0);
+       if (! xdr_callmsg(xdrs, msg))
+              return (FALSE);
+       return (TRUE);
+}
+
+static bool_t
+svcraw_reply(xprt, msg)
+       SVCXPRT *xprt;
+       struct rpc_msg *msg;
+{
+       register struct svcraw_private *srp = svcraw_private;
+       register XDR *xdrs;
+
+       if (srp == 0)
+               return (FALSE);
+       xdrs = &srp->xdr_stream;
+       xdrs->x_op = XDR_ENCODE;
+       XDR_SETPOS(xdrs, 0);
+       if (! xdr_replymsg(xdrs, msg))
+              return (FALSE);
+       (void)XDR_GETPOS(xdrs);  /* called just for overhead */
+       return (TRUE);
+}
+
+static bool_t
+svcraw_getargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{
+       register struct svcraw_private *srp = svcraw_private;
+
+       if (srp == 0)
+               return (FALSE);
+       return ((*xdr_args)(&srp->xdr_stream, args_ptr));
+}
+
+static bool_t
+svcraw_freeargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{ 
+       register struct svcraw_private *srp = svcraw_private;
+       register XDR *xdrs;
+
+       if (srp == 0)
+               return (FALSE);
+       xdrs = &srp->xdr_stream;
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_args)(xdrs, args_ptr));
+} 
+
+static void
+svcraw_destroy()
+{
+}
diff --git a/libc/inet/rpc/svc_run.c b/libc/inet/rpc/svc_run.c
new file mode 100644 (file)
index 0000000..c1c3e04
--- /dev/null
@@ -0,0 +1,72 @@
+/* @(#)svc_run.c       2.1 88/07/29 4.0 RPCSRC */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * This is the rpc server side idle loop
+ * Wait for input, call server program.
+ */
+#include <rpc/rpc.h>
+#include <sys/errno.h>
+
+void
+svc_run()
+{
+#ifdef FD_SETSIZE
+       fd_set readfds;
+#else
+      int readfds;
+#endif /* def FD_SETSIZE */
+       extern int errno;
+
+       for (;;) {
+#ifdef FD_SETSIZE
+               readfds = svc_fdset;
+#else
+               readfds = svc_fds;
+#endif /* def FD_SETSIZE */
+               switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0,
+                              (struct timeval *)0)) {
+               case -1:
+                       if (errno == EINTR) {
+                               continue;
+                       }
+                       perror("svc_run: - select failed");
+                       return;
+               case 0:
+                       continue;
+               default:
+                       svc_getreqset(&readfds);
+               }
+       }
+}
diff --git a/libc/inet/rpc/svc_simple.c b/libc/inet/rpc/svc_simple.c
new file mode 100644 (file)
index 0000000..d6bcbd3
--- /dev/null
@@ -0,0 +1,143 @@
+/* @(#)svc_simple.c    2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/* 
+ * svc_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+static struct proglst {
+       char *(*p_progname)();
+       int  p_prognum;
+       int  p_procnum;
+       xdrproc_t p_inproc, p_outproc;
+       struct proglst *p_nxt;
+} *proglst;
+static void universal();
+static SVCXPRT *transp;
+struct proglst *pl;
+
+registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
+       char *(*progname)();
+       xdrproc_t inproc, outproc;
+{
+       
+       if (procnum == NULLPROC) {
+               (void) fprintf(stderr,
+                   "can't reassign procedure number %d\n", NULLPROC);
+               return (-1);
+       }
+       if (transp == 0) {
+               transp = svcudp_create(RPC_ANYSOCK);
+               if (transp == NULL) {
+                       (void) fprintf(stderr, "couldn't create an rpc server\n");
+                       return (-1);
+               }
+       }
+       (void) pmap_unset((u_long)prognum, (u_long)versnum);
+       if (!svc_register(transp, (u_long)prognum, (u_long)versnum, 
+           universal, IPPROTO_UDP)) {
+               (void) fprintf(stderr, "couldn't register prog %d vers %d\n",
+                   prognum, versnum);
+               return (-1);
+       }
+       pl = (struct proglst *)malloc(sizeof(struct proglst));
+       if (pl == NULL) {
+               (void) fprintf(stderr, "registerrpc: out of memory\n");
+               return (-1);
+       }
+       pl->p_progname = progname;
+       pl->p_prognum = prognum;
+       pl->p_procnum = procnum;
+       pl->p_inproc = inproc;
+       pl->p_outproc = outproc;
+       pl->p_nxt = proglst;
+       proglst = pl;
+       return (0);
+}
+
+static void
+universal(rqstp, transp)
+       struct svc_req *rqstp;
+       SVCXPRT *transp;
+{
+       int prog, proc;
+       char *outdata;
+       char xdrbuf[UDPMSGSIZE];
+       struct proglst *pl;
+
+       /* 
+        * enforce "procnum 0 is echo" convention
+        */
+       if (rqstp->rq_proc == NULLPROC) {
+               if (svc_sendreply(transp, xdr_void, (char *)NULL) == FALSE) {
+                       (void) fprintf(stderr, "xxx\n");
+                       exit(1);
+               }
+               return;
+       }
+       prog = rqstp->rq_prog;
+       proc = rqstp->rq_proc;
+       for (pl = proglst; pl != NULL; pl = pl->p_nxt)
+               if (pl->p_prognum == prog && pl->p_procnum == proc) {
+                       /* decode arguments into a CLEAN buffer */
+                       bzero(xdrbuf, sizeof(xdrbuf)); /* required ! */
+                       if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) {
+                               svcerr_decode(transp);
+                               return;
+                       }
+                       outdata = (*(pl->p_progname))(xdrbuf);
+                       if (outdata == NULL && pl->p_outproc != xdr_void)
+                               /* there was an error */
+                               return;
+                       if (!svc_sendreply(transp, pl->p_outproc, outdata)) {
+                               (void) fprintf(stderr,
+                                   "trouble replying to prog %d\n",
+                                   pl->p_prognum);
+                               exit(1);
+                       }
+                       /* free the decoded arguments */
+                       (void)svc_freeargs(transp, pl->p_inproc, xdrbuf);
+                       return;
+               }
+       (void) fprintf(stderr, "never registered prog %d\n", prog);
+       exit(1);
+}
+
diff --git a/libc/inet/rpc/svc_tcp.c b/libc/inet/rpc/svc_tcp.c
new file mode 100644 (file)
index 0000000..2f85947
--- /dev/null
@@ -0,0 +1,421 @@
+/* @(#)svc_tcp.c       2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_tcp.c, Server side for TCP/IP based RPC. 
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Actually implements two flavors of transporter -
+ * a tcp rendezvouser (a listner and connection establisher)
+ * and a record/tcp stream.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <errno.h>
+/*#ifndef linux*/
+extern bool_t abort();
+/*#endif*/
+extern errno;
+
+/*
+ * Ops vector for TCP/IP based rpc service handle
+ */
+static bool_t          svctcp_recv();
+static enum xprt_stat  svctcp_stat();
+static bool_t          svctcp_getargs();
+static bool_t          svctcp_reply();
+static bool_t          svctcp_freeargs();
+static void            svctcp_destroy();
+
+static struct xp_ops svctcp_op = {
+       svctcp_recv,
+       svctcp_stat,
+       svctcp_getargs,
+       svctcp_reply,
+       svctcp_freeargs,
+       svctcp_destroy
+};
+
+/*
+ * Ops vector for TCP/IP rendezvous handler
+ */
+static bool_t          rendezvous_request();
+static enum xprt_stat  rendezvous_stat();
+
+static struct xp_ops svctcp_rendezvous_op = {
+       rendezvous_request,
+       rendezvous_stat,
+       abort,
+       abort,
+       abort,
+       svctcp_destroy
+};
+
+static int readtcp(), writetcp();
+static SVCXPRT *makefd_xprt();
+
+struct tcp_rendezvous { /* kept in xprt->xp_p1 */
+       u_int sendsize;
+       u_int recvsize;
+};
+
+struct tcp_conn {  /* kept in xprt->xp_p1 */
+       enum xprt_stat strm_stat;
+       u_long x_id;
+       XDR xdrs;
+       char verf_body[MAX_AUTH_BYTES];
+};
+
+/*
+ * Usage:
+ *     xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
+ *
+ * Creates, registers, and returns a (rpc) tcp based transporter.
+ * Once *xprt is initialized, it is registered as a transporter
+ * see (svc.h, xprt_register).  This routine returns
+ * a NULL if a problem occurred.
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svctcp_create
+ * binds it to an arbitrary port.  The routine then starts a tcp
+ * listener on the socket's associated port.  In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ *
+ * Since tcp streams do buffered io similar to stdio, the caller can specify
+ * how big the send and receive buffers are via the second and third parms;
+ * 0 => use the system default.
+ */
+SVCXPRT *
+svctcp_create(sock, sendsize, recvsize)
+       register int sock;
+       u_int sendsize;
+       u_int recvsize;
+{
+       bool_t madesock = FALSE;
+       register SVCXPRT *xprt;
+       register struct tcp_rendezvous *r;
+       struct sockaddr_in addr;
+       int len = sizeof(struct sockaddr_in);
+
+       if (sock == RPC_ANYSOCK) {
+               if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+                       perror("svc_tcp.c - tcp socket creation problem");
+                       return ((SVCXPRT *)NULL);
+               }
+               madesock = TRUE;
+       }
+       bzero((char *)&addr, sizeof (addr));
+       addr.sin_family = AF_INET;
+       if (bindresvport(sock, &addr)) {
+               addr.sin_port = 0;
+               (void)bind(sock, (struct sockaddr *)&addr, len);
+       }
+       if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0)  ||
+           (listen(sock, 2) != 0)) {
+               perror("svctcp_.c - cannot getsockname or listen");
+               if (madesock)
+                      (void)close(sock);
+               return ((SVCXPRT *)NULL);
+       }
+       r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r));
+       if (r == NULL) {
+               (void) fprintf(stderr, "svctcp_create: out of memory\n");
+               return (NULL);
+       }
+       r->sendsize = sendsize;
+       r->recvsize = recvsize;
+       xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+       if (xprt == NULL) {
+               (void) fprintf(stderr, "svctcp_create: out of memory\n");
+               return (NULL);
+       }
+       xprt->xp_p2 = NULL;
+       xprt->xp_p1 = (caddr_t)r;
+       xprt->xp_verf = _null_auth;
+       xprt->xp_ops = &svctcp_rendezvous_op;
+       xprt->xp_port = ntohs(addr.sin_port);
+       xprt->xp_sock = sock;
+       xprt_register(xprt);
+       return (xprt);
+}
+
+/*
+ * Like svtcp_create(), except the routine takes any *open* UNIX file
+ * descriptor as its first input.
+ */
+SVCXPRT *
+svcfd_create(fd, sendsize, recvsize)
+       int fd;
+       u_int sendsize;
+       u_int recvsize;
+{
+
+       return (makefd_xprt(fd, sendsize, recvsize));
+}
+
+static SVCXPRT *
+makefd_xprt(fd, sendsize, recvsize)
+       int fd;
+       u_int sendsize;
+       u_int recvsize;
+{
+       register SVCXPRT *xprt;
+       register struct tcp_conn *cd;
+       xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+       if (xprt == (SVCXPRT *)NULL) {
+               (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+               goto done;
+       }
+       cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn));
+       if (cd == (struct tcp_conn *)NULL) {
+               (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+               mem_free((char *) xprt, sizeof(SVCXPRT));
+               xprt = (SVCXPRT *)NULL;
+               goto done;
+       }
+       cd->strm_stat = XPRT_IDLE;
+       xdrrec_create(&(cd->xdrs), sendsize, recvsize,
+           (caddr_t)xprt, readtcp, writetcp);
+       xprt->xp_p2 = NULL;
+       xprt->xp_p1 = (caddr_t)cd;
+       xprt->xp_verf.oa_base = cd->verf_body;
+       xprt->xp_addrlen = 0;
+       xprt->xp_ops = &svctcp_op;  /* truely deals with calls */
+       xprt->xp_port = 0;  /* this is a connection, not a rendezvouser */
+       xprt->xp_sock = fd;
+       xprt_register(xprt);
+    done:
+       return (xprt);
+}
+
+static bool_t
+rendezvous_request(xprt)
+       register SVCXPRT *xprt;
+{
+       int sock;
+       struct tcp_rendezvous *r;
+       struct sockaddr_in addr;
+       int len;
+
+       r = (struct tcp_rendezvous *)xprt->xp_p1;
+    again:
+       len = sizeof(struct sockaddr_in);
+       if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr,
+           &len)) < 0) {
+               if (errno == EINTR)
+                       goto again;
+              return (FALSE);
+       }
+       /*
+        * make a new transporter (re-uses xprt)
+        */
+       xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
+       xprt->xp_raddr = addr;
+       xprt->xp_addrlen = len;
+       return (FALSE); /* there is never an rpc msg to be processed */
+}
+
+static enum xprt_stat
+rendezvous_stat()
+{
+
+       return (XPRT_IDLE);
+}
+
+static void
+svctcp_destroy(xprt)
+       register SVCXPRT *xprt;
+{
+       register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1;
+
+       xprt_unregister(xprt);
+       (void)close(xprt->xp_sock);
+       if (xprt->xp_port != 0) {
+               /* a rendezvouser socket */
+               xprt->xp_port = 0;
+       } else {
+               /* an actual connection socket */
+               XDR_DESTROY(&(cd->xdrs));
+       }
+       mem_free((caddr_t)cd, sizeof(struct tcp_conn));
+       mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+/*
+ * All read operations timeout after 35 seconds.
+ * A timeout is fatal for the connection.
+ */
+static struct timeval wait_per_try = { 35, 0 };
+
+/*
+ * reads data from the tcp conection.
+ * any error is fatal and the connection is closed.
+ * (And a read of zero bytes is a half closed stream => error.)
+ */
+static int
+readtcp(xprt, buf, len)
+       register SVCXPRT *xprt;
+       caddr_t buf;
+       register int len;
+{
+       register int sock = xprt->xp_sock;
+#ifdef FD_SETSIZE
+       fd_set mask;
+       fd_set readfds;
+
+       FD_ZERO(&mask);
+       FD_SET(sock, &mask);
+#else
+       register int mask = 1 << sock;
+       int readfds;
+#endif /* def FD_SETSIZE */
+       do {
+               readfds = mask;
+               if (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL, 
+                          &wait_per_try) <= 0) {
+                       if (errno == EINTR) {
+                               continue;
+                       }
+                       goto fatal_err;
+               }
+#ifdef FD_SETSIZE
+       } while (!FD_ISSET(sock, &readfds));
+#else
+       } while (readfds != mask);
+#endif /* def FD_SETSIZE */
+       if ((len = read(sock, buf, len)) > 0) {
+               return (len);
+       }
+fatal_err:
+       ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+       return (-1);
+}
+
+/*
+ * writes data to the tcp connection.
+ * Any error is fatal and the connection is closed.
+ */
+static int
+writetcp(xprt, buf, len)
+       register SVCXPRT *xprt;
+       caddr_t buf;
+       int len;
+{
+       register int i, cnt;
+
+       for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+               if ((i = write(xprt->xp_sock, buf, cnt)) < 0) {
+                       ((struct tcp_conn *)(xprt->xp_p1))->strm_stat =
+                           XPRT_DIED;
+                       return (-1);
+               }
+       }
+       return (len);
+}
+
+static enum xprt_stat
+svctcp_stat(xprt)
+       SVCXPRT *xprt;
+{
+       register struct tcp_conn *cd =
+           (struct tcp_conn *)(xprt->xp_p1);
+
+       if (cd->strm_stat == XPRT_DIED)
+               return (XPRT_DIED);
+       if (! xdrrec_eof(&(cd->xdrs)))
+               return (XPRT_MOREREQS);
+       return (XPRT_IDLE);
+}
+
+static bool_t
+svctcp_recv(xprt, msg)
+       SVCXPRT *xprt;
+       register struct rpc_msg *msg;
+{
+       register struct tcp_conn *cd =
+           (struct tcp_conn *)(xprt->xp_p1);
+       register XDR *xdrs = &(cd->xdrs);
+
+       xdrs->x_op = XDR_DECODE;
+       (void)xdrrec_skiprecord(xdrs);
+       if (xdr_callmsg(xdrs, msg)) {
+               cd->x_id = msg->rm_xid;
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+static bool_t
+svctcp_getargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{
+
+       return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr));
+}
+
+static bool_t
+svctcp_freeargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{
+       register XDR *xdrs =
+           &(((struct tcp_conn *)(xprt->xp_p1))->xdrs);
+
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static bool_t
+svctcp_reply(xprt, msg)
+       SVCXPRT *xprt;
+       register struct rpc_msg *msg;
+{
+       register struct tcp_conn *cd =
+           (struct tcp_conn *)(xprt->xp_p1);
+       register XDR *xdrs = &(cd->xdrs);
+       register bool_t stat;
+
+       xdrs->x_op = XDR_ENCODE;
+       msg->rm_xid = cd->x_id;
+       stat = xdr_replymsg(xdrs, msg);
+       (void)xdrrec_endofrecord(xdrs, TRUE);
+       return (stat);
+}
diff --git a/libc/inet/rpc/svc_udp.c b/libc/inet/rpc/svc_udp.c
new file mode 100644 (file)
index 0000000..69ef7a1
--- /dev/null
@@ -0,0 +1,475 @@
+/* @(#)svc_udp.c       2.2 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_udp.c,
+ * Server side for UDP/IP based RPC.  (Does some caching in the hopes of
+ * achieving execute-at-most-once semantics.)
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+
+#define rpc_buffer(xprt) ((xprt)->xp_p1)
+#define MAX(a, b)     ((a > b) ? a : b)
+
+static bool_t          svcudp_recv();
+static bool_t          svcudp_reply();
+static enum xprt_stat  svcudp_stat();
+static bool_t          svcudp_getargs();
+static bool_t          svcudp_freeargs();
+static void            svcudp_destroy();
+
+static struct xp_ops svcudp_op = {
+       svcudp_recv,
+       svcudp_stat,
+       svcudp_getargs,
+       svcudp_reply,
+       svcudp_freeargs,
+       svcudp_destroy
+};
+
+extern int errno;
+
+/*
+ * kept in xprt->xp_p2
+ */
+struct svcudp_data {
+       u_int   su_iosz;        /* byte size of send.recv buffer */
+       u_long  su_xid;         /* transaction id */
+       XDR     su_xdrs;        /* XDR handle */
+       char    su_verfbody[MAX_AUTH_BYTES];    /* verifier body */
+       char *  su_cache;       /* cached data, NULL if no cache */
+};
+#define        su_data(xprt)   ((struct svcudp_data *)(xprt->xp_p2))
+
+/*
+ * Usage:
+ *     xprt = svcudp_create(sock);
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svcudp_create
+ * binds it to an arbitrary port.  In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ * Once *xprt is initialized, it is registered as a transporter;
+ * see (svc.h, xprt_register).
+ * The routines returns NULL if a problem occurred.
+ */
+SVCXPRT *
+svcudp_bufcreate(sock, sendsz, recvsz)
+       register int sock;
+       u_int sendsz, recvsz;
+{
+       bool_t madesock = FALSE;
+       register SVCXPRT *xprt;
+       register struct svcudp_data *su;
+       struct sockaddr_in addr;
+       int len = sizeof(struct sockaddr_in);
+
+       if (sock == RPC_ANYSOCK) {
+               if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+                       perror("svcudp_create: socket creation problem");
+                       return ((SVCXPRT *)NULL);
+               }
+               madesock = TRUE;
+       }
+       bzero((char *)&addr, sizeof (addr));
+       addr.sin_family = AF_INET;
+       if (bindresvport(sock, &addr)) {
+               addr.sin_port = 0;
+               (void)bind(sock, (struct sockaddr *)&addr, len);
+       }
+       if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
+               perror("svcudp_create - cannot getsockname");
+               if (madesock)
+                       (void)close(sock);
+               return ((SVCXPRT *)NULL);
+       }
+       xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+       if (xprt == NULL) {
+               (void)fprintf(stderr, "svcudp_create: out of memory\n");
+               return (NULL);
+       }
+       su = (struct svcudp_data *)mem_alloc(sizeof(*su));
+       if (su == NULL) {
+               (void)fprintf(stderr, "svcudp_create: out of memory\n");
+               return (NULL);
+       }
+       su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
+       if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) {
+               (void)fprintf(stderr, "svcudp_create: out of memory\n");
+               return (NULL);
+       }
+       xdrmem_create(
+           &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
+       su->su_cache = NULL;
+       xprt->xp_p2 = (caddr_t)su;
+       xprt->xp_verf.oa_base = su->su_verfbody;
+       xprt->xp_ops = &svcudp_op;
+       xprt->xp_port = ntohs(addr.sin_port);
+       xprt->xp_sock = sock;
+       xprt_register(xprt);
+       return (xprt);
+}
+
+SVCXPRT *
+svcudp_create(sock)
+       int sock;
+{
+
+       return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum xprt_stat
+svcudp_stat(xprt)
+       SVCXPRT *xprt;
+{
+
+       return (XPRT_IDLE); 
+}
+
+static bool_t
+svcudp_recv(xprt, msg)
+       register SVCXPRT *xprt;
+       struct rpc_msg *msg;
+{
+       register struct svcudp_data *su = su_data(xprt);
+       register XDR *xdrs = &(su->su_xdrs);
+       register int rlen;
+       char *reply;
+       u_long replylen;
+
+    again:
+       xprt->xp_addrlen = sizeof(struct sockaddr_in);
+       rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz,
+           0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
+       if (rlen == -1 && errno == EINTR)
+               goto again;
+       if (rlen < 4*sizeof(u_long))
+               return (FALSE);
+       xdrs->x_op = XDR_DECODE;
+       XDR_SETPOS(xdrs, 0);
+       if (! xdr_callmsg(xdrs, msg))
+               return (FALSE);
+       su->su_xid = msg->rm_xid;
+       if (su->su_cache != NULL) {
+               if (cache_get(xprt, msg, &reply, &replylen)) {
+                       (void) sendto(xprt->xp_sock, reply, (int) replylen, 0,
+                         (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen);
+                       return (TRUE);
+               }
+       }
+       return (TRUE);
+}
+
+static bool_t
+svcudp_reply(xprt, msg)
+       register SVCXPRT *xprt; 
+       struct rpc_msg *msg; 
+{
+       register struct svcudp_data *su = su_data(xprt);
+       register XDR *xdrs = &(su->su_xdrs);
+       register int slen;
+       register bool_t stat = FALSE;
+
+       xdrs->x_op = XDR_ENCODE;
+       XDR_SETPOS(xdrs, 0);
+       msg->rm_xid = su->su_xid;
+       if (xdr_replymsg(xdrs, msg)) {
+               slen = (int)XDR_GETPOS(xdrs);
+               if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
+                   (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
+                   == slen) {
+                       stat = TRUE;
+                       if (su->su_cache && slen >= 0) {
+                               cache_set(xprt, (u_long) slen);
+                       }
+               }
+       }
+       return (stat);
+}
+
+static bool_t
+svcudp_getargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{
+
+       return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr));
+}
+
+static bool_t
+svcudp_freeargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{
+       register XDR *xdrs = &(su_data(xprt)->su_xdrs);
+
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static void
+svcudp_destroy(xprt)
+       register SVCXPRT *xprt;
+{
+       register struct svcudp_data *su = su_data(xprt);
+
+       xprt_unregister(xprt);
+       (void)close(xprt->xp_sock);
+       XDR_DESTROY(&(su->su_xdrs));
+       mem_free(rpc_buffer(xprt), su->su_iosz);
+       mem_free((caddr_t)su, sizeof(struct svcudp_data));
+       mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+
+/***********this could be a separate file*********************/
+
+/*
+ * Fifo cache for udp server
+ * Copies pointers to reply buffers into fifo cache
+ * Buffers are sent again if retransmissions are detected.
+ */
+
+#define SPARSENESS 4   /* 75% sparse */
+
+#define CACHE_PERROR(msg)      \
+       (void) fprintf(stderr,"%s\n", msg)
+
+#define ALLOC(type, size)      \
+       (type *) mem_alloc((unsigned) (sizeof(type) * (size)))
+
+#define BZERO(addr, type, size)         \
+       bzero((char *) addr, sizeof(type) * (int) (size)) 
+
+/*
+ * An entry in the cache
+ */
+typedef struct cache_node *cache_ptr;
+struct cache_node {
+       /*
+        * Index into cache is xid, proc, vers, prog and address
+        */
+       u_long cache_xid;
+       u_long cache_proc;
+       u_long cache_vers;
+       u_long cache_prog;
+       struct sockaddr_in cache_addr;
+       /*
+        * The cached reply and length
+        */
+       char * cache_reply;
+       u_long cache_replylen;
+       /*
+        * Next node on the list, if there is a collision
+        */
+       cache_ptr cache_next;   
+};
+
+
+
+/*
+ * The entire cache
+ */
+struct udp_cache {
+       u_long uc_size;         /* size of cache */
+       cache_ptr *uc_entries;  /* hash table of entries in cache */
+       cache_ptr *uc_fifo;     /* fifo list of entries in cache */
+       u_long uc_nextvictim;   /* points to next victim in fifo list */
+       u_long uc_prog;         /* saved program number */
+       u_long uc_vers;         /* saved version number */
+       u_long uc_proc;         /* saved procedure number */
+       struct sockaddr_in uc_addr; /* saved caller's address */
+};
+
+
+/*
+ * the hashing function
+ */
+#define CACHE_LOC(transp, xid) \
+ (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size))        
+
+
+/*
+ * Enable use of the cache. 
+ * Note: there is no disable.
+ */
+svcudp_enablecache(transp, size)
+       SVCXPRT *transp;
+       u_long size;
+{
+       struct svcudp_data *su = su_data(transp);
+       struct udp_cache *uc;
+
+       if (su->su_cache != NULL) {
+               CACHE_PERROR("enablecache: cache already enabled");
+               return(0);      
+       }
+       uc = ALLOC(struct udp_cache, 1);
+       if (uc == NULL) {
+               CACHE_PERROR("enablecache: could not allocate cache");
+               return(0);
+       }
+       uc->uc_size = size;
+       uc->uc_nextvictim = 0;
+       uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS);
+       if (uc->uc_entries == NULL) {
+               CACHE_PERROR("enablecache: could not allocate cache data");
+               return(0);
+       }
+       BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS);
+       uc->uc_fifo = ALLOC(cache_ptr, size);
+       if (uc->uc_fifo == NULL) {
+               CACHE_PERROR("enablecache: could not allocate cache fifo");
+               return(0);
+       }
+       BZERO(uc->uc_fifo, cache_ptr, size);
+       su->su_cache = (char *) uc;
+       return(1);
+}
+
+
+/*
+ * Set an entry in the cache
+ */
+static
+cache_set(xprt, replylen)
+       SVCXPRT *xprt;
+       u_long replylen;        
+{
+       register cache_ptr victim;      
+       register cache_ptr *vicp;
+       register struct svcudp_data *su = su_data(xprt);
+       struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+       u_int loc;
+       char *newbuf;
+
+       /*
+        * Find space for the new entry, either by
+        * reusing an old entry, or by mallocing a new one
+        */
+       victim = uc->uc_fifo[uc->uc_nextvictim];
+       if (victim != NULL) {
+               loc = CACHE_LOC(xprt, victim->cache_xid);
+               for (vicp = &uc->uc_entries[loc]; 
+                 *vicp != NULL && *vicp != victim; 
+                 vicp = &(*vicp)->cache_next) 
+                               ;
+               if (*vicp == NULL) {
+                       CACHE_PERROR("cache_set: victim not found");
+                       return;
+               }
+               *vicp = victim->cache_next;     /* remote from cache */
+               newbuf = victim->cache_reply;
+       } else {
+               victim = ALLOC(struct cache_node, 1);
+               if (victim == NULL) {
+                       CACHE_PERROR("cache_set: victim alloc failed");
+                       return;
+               }
+               newbuf = mem_alloc(su->su_iosz);
+               if (newbuf == NULL) {
+                       CACHE_PERROR("cache_set: could not allocate new rpc_buffer");
+                       return;
+               }
+       }
+
+       /*
+        * Store it away
+        */
+       victim->cache_replylen = replylen;
+       victim->cache_reply = rpc_buffer(xprt);
+       rpc_buffer(xprt) = newbuf;
+       xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE);
+       victim->cache_xid = su->su_xid;
+       victim->cache_proc = uc->uc_proc;
+       victim->cache_vers = uc->uc_vers;
+       victim->cache_prog = uc->uc_prog;
+       victim->cache_addr = uc->uc_addr;
+       loc = CACHE_LOC(xprt, victim->cache_xid);
+       victim->cache_next = uc->uc_entries[loc];       
+       uc->uc_entries[loc] = victim;
+       uc->uc_fifo[uc->uc_nextvictim++] = victim;
+       uc->uc_nextvictim %= uc->uc_size;
+}
+
+/*
+ * Try to get an entry from the cache
+ * return 1 if found, 0 if not found
+ */
+static
+cache_get(xprt, msg, replyp, replylenp)
+       SVCXPRT *xprt;
+       struct rpc_msg *msg;
+       char **replyp;
+       u_long *replylenp;
+{
+       u_int loc;
+       register cache_ptr ent;
+       register struct svcudp_data *su = su_data(xprt);
+       register struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+
+#      define EQADDR(a1, a2)   (bcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0)
+
+       loc = CACHE_LOC(xprt, su->su_xid);
+       for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) {
+               if (ent->cache_xid == su->su_xid &&
+                 ent->cache_proc == uc->uc_proc &&
+                 ent->cache_vers == uc->uc_vers &&
+                 ent->cache_prog == uc->uc_prog &&
+                 EQADDR(ent->cache_addr, uc->uc_addr)) {
+                       *replyp = ent->cache_reply;
+                       *replylenp = ent->cache_replylen;
+                       return(1);
+               }
+       }
+       /*
+        * Failed to find entry
+        * Remember a few things so we can do a set later
+        */
+       uc->uc_proc = msg->rm_call.cb_proc;
+       uc->uc_vers = msg->rm_call.cb_vers;
+       uc->uc_prog = msg->rm_call.cb_prog;
+       uc->uc_addr = xprt->xp_raddr;
+       return(0);
+}
+
diff --git a/libc/inet/rpc/xdr.c b/libc/inet/rpc/xdr.c
new file mode 100644 (file)
index 0000000..cc27838
--- /dev/null
@@ -0,0 +1,576 @@
+/* @(#)xdr.c   2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
+#endif
+
+/*
+ * xdr.c, Generic XDR routines implementation.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ *
+ * These are the "generic" xdr routines used to serialize and de-serialize
+ * most common data items.  See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * constants specific to the xdr "protocol"
+ */
+#define XDR_FALSE      ((long) 0)
+#define XDR_TRUE       ((long) 1)
+#define LASTUNSIGNED   ((u_int) 0-1)
+
+/*
+ * for unit alignment
+ */
+static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
+
+/*
+ * Free a data structure using XDR
+ * Not a filter, but a convenient utility nonetheless
+ */
+void
+xdr_free(proc, objp)
+       xdrproc_t proc;
+       char *objp;
+{
+       XDR x;
+       
+       x.x_op = XDR_FREE;
+       (*proc)(&x, objp);
+}
+
+/*
+ * XDR nothing
+ */
+bool_t
+xdr_void(/* xdrs, addr */)
+       /* XDR *xdrs; */
+       /* caddr_t addr; */
+{
+
+       return (TRUE);
+}
+
+/*
+ * XDR integers
+ */
+bool_t
+xdr_int(xdrs, ip)
+       XDR *xdrs;
+       int *ip;
+{
+
+#ifdef lint
+       (void) (xdr_short(xdrs, (short *)ip));
+       return (xdr_long(xdrs, (long *)ip));
+#else
+       if (sizeof (int) == sizeof (long)) {
+               return (xdr_long(xdrs, (long *)ip));
+       } else {
+               return (xdr_short(xdrs, (short *)ip));
+       }
+#endif
+}
+
+/*
+ * XDR unsigned integers
+ */
+bool_t
+xdr_u_int(xdrs, up)
+       XDR *xdrs;
+       u_int *up;
+{
+
+#ifdef lint
+       (void) (xdr_short(xdrs, (short *)up));
+       return (xdr_u_long(xdrs, (u_long *)up));
+#else
+       if (sizeof (u_int) == sizeof (u_long)) {
+               return (xdr_u_long(xdrs, (u_long *)up));
+       } else {
+               return (xdr_short(xdrs, (short *)up));
+       }
+#endif
+}
+
+/*
+ * XDR long integers
+ * same as xdr_u_long - open coded to save a proc call!
+ */
+bool_t
+xdr_long(xdrs, lp)
+       register XDR *xdrs;
+       long *lp;
+{
+
+       if (xdrs->x_op == XDR_ENCODE)
+               return (XDR_PUTLONG(xdrs, lp));
+
+       if (xdrs->x_op == XDR_DECODE)
+               return (XDR_GETLONG(xdrs, lp));
+
+       if (xdrs->x_op == XDR_FREE)
+               return (TRUE);
+
+       return (FALSE);
+}
+
+/*
+ * XDR unsigned long integers
+ * same as xdr_long - open coded to save a proc call!
+ */
+bool_t
+xdr_u_long(xdrs, ulp)
+       register XDR *xdrs;
+       u_long *ulp;
+{
+
+       if (xdrs->x_op == XDR_DECODE)
+               return (XDR_GETLONG(xdrs, (long *)ulp));
+       if (xdrs->x_op == XDR_ENCODE)
+               return (XDR_PUTLONG(xdrs, (long *)ulp));
+       if (xdrs->x_op == XDR_FREE)
+               return (TRUE);
+       return (FALSE);
+}
+
+/*
+ * XDR short integers
+ */
+bool_t
+xdr_short(xdrs, sp)
+       register XDR *xdrs;
+       short *sp;
+{
+       long l;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               l = (long) *sp;
+               return (XDR_PUTLONG(xdrs, &l));
+
+       case XDR_DECODE:
+               if (!XDR_GETLONG(xdrs, &l)) {
+                       return (FALSE);
+               }
+               *sp = (short) l;
+               return (TRUE);
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/*
+ * XDR unsigned short integers
+ */
+bool_t
+xdr_u_short(xdrs, usp)
+       register XDR *xdrs;
+       u_short *usp;
+{
+       u_long l;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               l = (u_long) *usp;
+               return (XDR_PUTLONG(xdrs, &l));
+
+       case XDR_DECODE:
+               if (!XDR_GETLONG(xdrs, &l)) {
+                       return (FALSE);
+               }
+               *usp = (u_short) l;
+               return (TRUE);
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+
+/*
+ * XDR a char
+ */
+bool_t
+xdr_char(xdrs, cp)
+       XDR *xdrs;
+       char *cp;
+{
+       int i;
+
+       i = (*cp);
+       if (!xdr_int(xdrs, &i)) {
+               return (FALSE);
+       }
+       *cp = i;
+       return (TRUE);
+}
+
+/*
+ * XDR an unsigned char
+ */
+bool_t
+xdr_u_char(xdrs, cp)
+       XDR *xdrs;
+       char *cp;
+{
+       u_int u;
+
+       u = (*cp);
+       if (!xdr_u_int(xdrs, &u)) {
+               return (FALSE);
+       }
+       *cp = u;
+       return (TRUE);
+}
+
+/*
+ * XDR booleans
+ */
+bool_t
+xdr_bool(xdrs, bp)
+       register XDR *xdrs;
+       bool_t *bp;
+{
+       long lb;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               lb = *bp ? XDR_TRUE : XDR_FALSE;
+               return (XDR_PUTLONG(xdrs, &lb));
+
+       case XDR_DECODE:
+               if (!XDR_GETLONG(xdrs, &lb)) {
+                       return (FALSE);
+               }
+               *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
+               return (TRUE);
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/*
+ * XDR enumerations
+ */
+bool_t
+xdr_enum(xdrs, ep)
+       XDR *xdrs;
+       enum_t *ep;
+{
+#ifndef lint
+       enum sizecheck { SIZEVAL };     /* used to find the size of an enum */
+
+       /*
+        * enums are treated as ints
+        */
+       if (sizeof (enum sizecheck) == sizeof (long)) {
+               return (xdr_long(xdrs, (long *)ep));
+       } else if (sizeof (enum sizecheck) == sizeof (short)) {
+               return (xdr_short(xdrs, (short *)ep));
+       } else {
+               return (FALSE);
+       }
+#else
+       (void) (xdr_short(xdrs, (short *)ep));
+       return (xdr_long(xdrs, (long *)ep));
+#endif
+}
+
+/*
+ * XDR opaque data
+ * Allows the specification of a fixed size sequence of opaque bytes.
+ * cp points to the opaque object and cnt gives the byte length.
+ */
+bool_t
+xdr_opaque(xdrs, cp, cnt)
+       register XDR *xdrs;
+       caddr_t cp;
+       register u_int cnt;
+{
+       register u_int rndup;
+       static crud[BYTES_PER_XDR_UNIT];
+
+       /*
+        * if no data we are done
+        */
+       if (cnt == 0)
+               return (TRUE);
+
+       /*
+        * round byte count to full xdr units
+        */
+       rndup = cnt % BYTES_PER_XDR_UNIT;
+       if (rndup > 0)
+               rndup = BYTES_PER_XDR_UNIT - rndup;
+
+       if (xdrs->x_op == XDR_DECODE) {
+               if (!XDR_GETBYTES(xdrs, cp, cnt)) {
+                       return (FALSE);
+               }
+               if (rndup == 0)
+                       return (TRUE);
+               return (XDR_GETBYTES(xdrs, crud, rndup));
+       }
+
+       if (xdrs->x_op == XDR_ENCODE) {
+               if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
+                       return (FALSE);
+               }
+               if (rndup == 0)
+                       return (TRUE);
+               return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
+       }
+
+       if (xdrs->x_op == XDR_FREE) {
+               return (TRUE);
+       }
+
+       return (FALSE);
+}
+
+/*
+ * XDR counted bytes
+ * *cpp is a pointer to the bytes, *sizep is the count.
+ * If *cpp is NULL maxsize bytes are allocated
+ */
+bool_t
+xdr_bytes(xdrs, cpp, sizep, maxsize)
+       register XDR *xdrs;
+       char **cpp;
+       register u_int *sizep;
+       u_int maxsize;
+{
+       register char *sp = *cpp;  /* sp is the actual string pointer */
+       register u_int nodesize;
+
+       /*
+        * first deal with the length since xdr bytes are counted
+        */
+       if (! xdr_u_int(xdrs, sizep)) {
+               return (FALSE);
+       }
+       nodesize = *sizep;
+       if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
+               return (FALSE);
+       }
+
+       /*
+        * now deal with the actual bytes
+        */
+       switch (xdrs->x_op) {
+
+       case XDR_DECODE:
+               if (nodesize == 0) {
+                       return (TRUE);
+               }
+               if (sp == NULL) {
+                       *cpp = sp = (char *)mem_alloc(nodesize);
+               }
+               if (sp == NULL) {
+                       (void) fprintf(stderr, "xdr_bytes: out of memory\n");
+                       return (FALSE);
+               }
+               /* fall into ... */
+
+       case XDR_ENCODE:
+               return (xdr_opaque(xdrs, sp, nodesize));
+
+       case XDR_FREE:
+               if (sp != NULL) {
+                       mem_free(sp, nodesize);
+                       *cpp = NULL;
+               }
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/*
+ * Implemented here due to commonality of the object.
+ */
+bool_t
+xdr_netobj(xdrs, np)
+       XDR *xdrs;
+       struct netobj *np;
+{
+
+       return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
+}
+
+/*
+ * XDR a descriminated union
+ * Support routine for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * an entry with a null procedure pointer.  The routine gets
+ * the discriminant value and then searches the array of xdrdiscrims
+ * looking for that value.  It calls the procedure given in the xdrdiscrim
+ * to handle the discriminant.  If there is no specific routine a default
+ * routine may be called.
+ * If there is no specific or default routine an error is returned.
+ */
+bool_t
+xdr_union(xdrs, dscmp, unp, choices, dfault)
+       register XDR *xdrs;
+       enum_t *dscmp;          /* enum to decide which arm to work on */
+       char *unp;              /* the union itself */
+       struct xdr_discrim *choices;    /* [value, xdr proc] for each arm */
+       xdrproc_t dfault;       /* default xdr routine */
+{
+       register enum_t dscm;
+
+       /*
+        * we deal with the discriminator;  it's an enum
+        */
+       if (! xdr_enum(xdrs, dscmp)) {
+               return (FALSE);
+       }
+       dscm = *dscmp;
+
+       /*
+        * search choices for a value that matches the discriminator.
+        * if we find one, execute the xdr routine for that value.
+        */
+       for (; choices->proc != NULL_xdrproc_t; choices++) {
+               if (choices->value == dscm)
+                       return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
+       }
+
+       /*
+        * no match - execute the default xdr routine if there is one
+        */
+       return ((dfault == NULL_xdrproc_t) ? FALSE :
+           (*dfault)(xdrs, unp, LASTUNSIGNED));
+}
+
+
+/*
+ * Non-portable xdr primitives.
+ * Care should be taken when moving these routines to new architectures.
+ */
+
+
+/*
+ * XDR null terminated ASCII strings
+ * xdr_string deals with "C strings" - arrays of bytes that are
+ * terminated by a NULL character.  The parameter cpp references a
+ * pointer to storage; If the pointer is null, then the necessary
+ * storage is allocated.  The last parameter is the max allowed length
+ * of the string as specified by a protocol.
+ */
+bool_t
+xdr_string(xdrs, cpp, maxsize)
+       register XDR *xdrs;
+       char **cpp;
+       u_int maxsize;
+{
+       register char *sp = *cpp;  /* sp is the actual string pointer */
+       u_int size;
+       u_int nodesize;
+
+       /*
+        * first deal with the length since xdr strings are counted-strings
+        */
+       switch (xdrs->x_op) {
+       case XDR_FREE:
+               if (sp == NULL) {
+                       return(TRUE);   /* already free */
+               }
+               /* fall through... */
+       case XDR_ENCODE:
+               size = strlen(sp);
+               break;
+       }
+       if (! xdr_u_int(xdrs, &size)) {
+               return (FALSE);
+       }
+       if (size > maxsize) {
+               return (FALSE);
+       }
+       nodesize = size + 1;
+
+       /*
+        * now deal with the actual bytes
+        */
+       switch (xdrs->x_op) {
+
+       case XDR_DECODE:
+               if (nodesize == 0) {
+                       return (TRUE);
+               }
+               if (sp == NULL)
+                       *cpp = sp = (char *)mem_alloc(nodesize);
+               if (sp == NULL) {
+                       (void) fprintf(stderr, "xdr_string: out of memory\n");
+                       return (FALSE);
+               }
+               sp[size] = 0;
+               /* fall into ... */
+
+       case XDR_ENCODE:
+               return (xdr_opaque(xdrs, sp, size));
+
+       case XDR_FREE:
+               mem_free(sp, nodesize);
+               *cpp = NULL;
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/* 
+ * Wrapper for xdr_string that can be called directly from 
+ * routines like clnt_call
+ */
+bool_t
+xdr_wrapstring(xdrs, cpp)
+       XDR *xdrs;
+       char **cpp;
+{
+       if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
+               return (TRUE);
+       }
+       return (FALSE);
+}
diff --git a/libc/inet/rpc/xdr_array.c b/libc/inet/rpc/xdr_array.c
new file mode 100644 (file)
index 0000000..7c2831c
--- /dev/null
@@ -0,0 +1,153 @@
+/* @(#)xdr_array.c     2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_array.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * arrays.  See xdr.h for more info on the interface to xdr.
+ */
+
+#include <stdio.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED   ((u_int)0-1)
+
+
+/*
+ * XDR an array of arbitrary elements
+ * *addrp is a pointer to the array, *sizep is the number of elements.
+ * If addrp is NULL (*sizep * elsize) bytes are allocated.
+ * elsize is the size (in bytes) of each element, and elproc is the
+ * xdr procedure to call to handle each element of the array.
+ */
+bool_t
+xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc)
+       register XDR *xdrs;
+       caddr_t *addrp;         /* array pointer */
+       u_int *sizep;           /* number of elements */
+       u_int maxsize;          /* max numberof elements */
+       u_int elsize;           /* size in bytes of each element */
+       xdrproc_t elproc;       /* xdr routine to handle each element */
+{
+       register u_int i;
+       register caddr_t target = *addrp;
+       register u_int c;  /* the actual element count */
+       register bool_t stat = TRUE;
+       register u_int nodesize;
+
+       /* like strings, arrays are really counted arrays */
+       if (! xdr_u_int(xdrs, sizep)) {
+               return (FALSE);
+       }
+       c = *sizep;
+       if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
+               return (FALSE);
+       }
+       nodesize = c * elsize;
+
+       /*
+        * if we are deserializing, we may need to allocate an array.
+        * We also save time by checking for a null array if we are freeing.
+        */
+       if (target == NULL)
+               switch (xdrs->x_op) {
+               case XDR_DECODE:
+                       if (c == 0)
+                               return (TRUE);
+                       *addrp = target = mem_alloc(nodesize);
+                       if (target == NULL) {
+                               (void) fprintf(stderr, 
+                                       "xdr_array: out of memory\n");
+                               return (FALSE);
+                       }
+                       bzero(target, nodesize);
+                       break;
+
+               case XDR_FREE:
+                       return (TRUE);
+       }
+       
+       /*
+        * now we xdr each element of array
+        */
+       for (i = 0; (i < c) && stat; i++) {
+               stat = (*elproc)(xdrs, target, LASTUNSIGNED);
+               target += elsize;
+       }
+
+       /*
+        * the array may need freeing
+        */
+       if (xdrs->x_op == XDR_FREE) {
+               mem_free(*addrp, nodesize);
+               *addrp = NULL;
+       }
+       return (stat);
+}
+
+/*
+ * xdr_vector():
+ *
+ * XDR a fixed length array. Unlike variable-length arrays,
+ * the storage of fixed length arrays is static and unfreeable.
+ * > basep: base of the array
+ * > size: size of the array
+ * > elemsize: size of each element
+ * > xdr_elem: routine to XDR each element
+ */
+bool_t
+xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem)
+       register XDR *xdrs;
+       register char *basep;
+       register u_int nelem;
+       register u_int elemsize;
+       register xdrproc_t xdr_elem;    
+{
+       register u_int i;
+       register char *elptr;
+
+       elptr = basep;
+       for (i = 0; i < nelem; i++) {
+               if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) {
+                       return(FALSE);
+               }
+               elptr += elemsize;
+       }
+       return(TRUE);   
+}
+
diff --git a/libc/inet/rpc/xdr_float.c b/libc/inet/rpc/xdr_float.c
new file mode 100644 (file)
index 0000000..ad221a7
--- /dev/null
@@ -0,0 +1,272 @@
+/* @(#)xdr_float.c     2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_float.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "floating point" xdr routines used to (de)serialize
+ * most common data items.  See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <stdio.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * NB: Not portable.
+ * This routine works on Suns (Sky / 68000's) and Vaxen.
+ */
+
+#ifdef linux
+/* cheat big time */
+#define sparc
+#endif
+
+#ifdef vax
+
+/* What IEEE single precision floating point looks like on a Vax */
+struct ieee_single {
+       unsigned int    mantissa: 23;
+       unsigned int    exp     : 8;
+       unsigned int    sign    : 1;
+};
+
+/* Vax single precision floating point */
+struct vax_single {
+       unsigned int    mantissa1 : 7;
+       unsigned int    exp       : 8;
+       unsigned int    sign      : 1;
+       unsigned int    mantissa2 : 16;
+};
+
+#define VAX_SNG_BIAS   0x81
+#define IEEE_SNG_BIAS  0x7f
+
+static struct sgl_limits {
+       struct vax_single s;
+       struct ieee_single ieee;
+} sgl_limits[2] = {
+       {{ 0x7f, 0xff, 0x0, 0xffff },   /* Max Vax */
+       { 0x0, 0xff, 0x0 }},            /* Max IEEE */
+       {{ 0x0, 0x0, 0x0, 0x0 },        /* Min Vax */
+       { 0x0, 0x0, 0x0 }}              /* Min IEEE */
+};
+#endif /* vax */
+
+bool_t
+xdr_float(xdrs, fp)
+       register XDR *xdrs;
+       register float *fp;
+{
+#if !defined(mc68000) && !defined(sparc)
+       struct ieee_single is;
+       struct vax_single vs, *vsp;
+       struct sgl_limits *lim;
+       int i;
+#endif
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+#if defined(mc68000) || defined(sparc)
+               return (XDR_PUTLONG(xdrs, (long *)fp));
+#else
+               vs = *((struct vax_single *)fp);
+               for (i = 0, lim = sgl_limits;
+                       i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
+                       i++, lim++) {
+                       if ((vs.mantissa2 == lim->s.mantissa2) &&
+                               (vs.exp == lim->s.exp) &&
+                               (vs.mantissa1 == lim->s.mantissa1)) {
+                               is = lim->ieee;
+                               goto shipit;
+                       }
+               }
+               is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
+               is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
+       shipit:
+               is.sign = vs.sign;
+               return (XDR_PUTLONG(xdrs, (long *)&is));
+#endif
+
+       case XDR_DECODE:
+#if defined(mc68000) || defined(sparc)
+               return (XDR_GETLONG(xdrs, (long *)fp));
+#else
+               vsp = (struct vax_single *)fp;
+               if (!XDR_GETLONG(xdrs, (long *)&is))
+                       return (FALSE);
+               for (i = 0, lim = sgl_limits;
+                       i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
+                       i++, lim++) {
+                       if ((is.exp == lim->ieee.exp) &&
+                               (is.mantissa == lim->ieee.mantissa)) {
+                               *vsp = lim->s;
+                               goto doneit;
+                       }
+               }
+               vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
+               vsp->mantissa2 = is.mantissa;
+               vsp->mantissa1 = (is.mantissa >> 16);
+       doneit:
+               vsp->sign = is.sign;
+               return (TRUE);
+#endif
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/*
+ * This routine works on Suns (Sky / 68000's) and Vaxen.
+ */
+
+#ifdef vax
+/* What IEEE double precision floating point looks like on a Vax */
+struct ieee_double {
+       unsigned int    mantissa1 : 20;
+       unsigned int    exp       : 11;
+       unsigned int    sign      : 1;
+       unsigned int    mantissa2 : 32;
+};
+
+/* Vax double precision floating point */
+struct  vax_double {
+       unsigned int    mantissa1 : 7;
+       unsigned int    exp       : 8;
+       unsigned int    sign      : 1;
+       unsigned int    mantissa2 : 16;
+       unsigned int    mantissa3 : 16;
+       unsigned int    mantissa4 : 16;
+};
+
+#define VAX_DBL_BIAS   0x81
+#define IEEE_DBL_BIAS  0x3ff
+#define MASK(nbits)    ((1 << nbits) - 1)
+
+static struct dbl_limits {
+       struct  vax_double d;
+       struct  ieee_double ieee;
+} dbl_limits[2] = {
+       {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },   /* Max Vax */
+       { 0x0, 0x7ff, 0x0, 0x0 }},                      /* Max IEEE */
+       {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},               /* Min Vax */
+       { 0x0, 0x0, 0x0, 0x0 }}                         /* Min IEEE */
+};
+
+#endif /* vax */
+
+
+bool_t
+xdr_double(xdrs, dp)
+       register XDR *xdrs;
+       double *dp;
+{
+       register long *lp;
+#if !defined(mc68000) && !defined(sparc)
+       struct  ieee_double id;
+       struct  vax_double vd;
+       register struct dbl_limits *lim;
+       int i;
+#endif
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+#if defined(mc68000) || defined(sparc)
+               lp = (long *)dp;
+#else
+               vd = *((struct vax_double *)dp);
+               for (i = 0, lim = dbl_limits;
+                       i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+                       i++, lim++) {
+                       if ((vd.mantissa4 == lim->d.mantissa4) &&
+                               (vd.mantissa3 == lim->d.mantissa3) &&
+                               (vd.mantissa2 == lim->d.mantissa2) &&
+                               (vd.mantissa1 == lim->d.mantissa1) &&
+                               (vd.exp == lim->d.exp)) {
+                               id = lim->ieee;
+                               goto shipit;
+                       }
+               }
+               id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
+               id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
+               id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
+                               (vd.mantissa3 << 13) |
+                               ((vd.mantissa4 >> 3) & MASK(13));
+       shipit:
+               id.sign = vd.sign;
+               lp = (long *)&id;
+#endif
+               return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
+
+       case XDR_DECODE:
+#if defined(mc68000) || defined(sparc)
+               lp = (long *)dp;
+               return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
+#else
+               lp = (long *)&id;
+               if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
+                       return (FALSE);
+               for (i = 0, lim = dbl_limits;
+                       i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+                       i++, lim++) {
+                       if ((id.mantissa2 == lim->ieee.mantissa2) &&
+                               (id.mantissa1 == lim->ieee.mantissa1) &&
+                               (id.exp == lim->ieee.exp)) {
+                               vd = lim->d;
+                               goto doneit;
+                       }
+               }
+               vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
+               vd.mantissa1 = (id.mantissa1 >> 13);
+               vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
+                               (id.mantissa2 >> 29);
+               vd.mantissa3 = (id.mantissa2 >> 13);
+               vd.mantissa4 = (id.mantissa2 << 3);
+       doneit:
+               vd.sign = id.sign;
+               *dp = *((double *)&vd);
+               return (TRUE);
+#endif
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
diff --git a/libc/inet/rpc/xdr_mem.c b/libc/inet/rpc/xdr_mem.c
new file mode 100644 (file)
index 0000000..558d369
--- /dev/null
@@ -0,0 +1,184 @@
+/* @(#)xdr_mem.c       2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_mem.h, XDR implementation using memory buffers.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * If you have some data to be interpreted as external data representation
+ * or to be converted to external data representation in a memory buffer,
+ * then this is the package for you.
+ *
+ */
+
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+static bool_t  xdrmem_getlong();
+static bool_t  xdrmem_putlong();
+static bool_t  xdrmem_getbytes();
+static bool_t  xdrmem_putbytes();
+static u_int   xdrmem_getpos();
+static bool_t  xdrmem_setpos();
+static long *  xdrmem_inline();
+static void    xdrmem_destroy();
+
+static struct  xdr_ops xdrmem_ops = {
+       xdrmem_getlong,
+       xdrmem_putlong,
+       xdrmem_getbytes,
+       xdrmem_putbytes,
+       xdrmem_getpos,
+       xdrmem_setpos,
+       xdrmem_inline,
+       xdrmem_destroy
+};
+
+/*
+ * The procedure xdrmem_create initializes a stream descriptor for a
+ * memory buffer.  
+ */
+void
+xdrmem_create(xdrs, addr, size, op)
+       register XDR *xdrs;
+       caddr_t addr;
+       u_int size;
+       enum xdr_op op;
+{
+
+       xdrs->x_op = op;
+       xdrs->x_ops = &xdrmem_ops;
+       xdrs->x_private = xdrs->x_base = addr;
+       xdrs->x_handy = size;
+}
+
+static void
+xdrmem_destroy(/*xdrs*/)
+       /*XDR *xdrs;*/
+{
+}
+
+static bool_t
+xdrmem_getlong(xdrs, lp)
+       register XDR *xdrs;
+       long *lp;
+{
+
+       if ((xdrs->x_handy -= sizeof(long)) < 0)
+               return (FALSE);
+       *lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private))));
+       xdrs->x_private += sizeof(long);
+       return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong(xdrs, lp)
+       register XDR *xdrs;
+       long *lp;
+{
+
+       if ((xdrs->x_handy -= sizeof(long)) < 0)
+               return (FALSE);
+       *(long *)xdrs->x_private = (long)htonl((u_long)(*lp));
+       xdrs->x_private += sizeof(long);
+       return (TRUE);
+}
+
+static bool_t
+xdrmem_getbytes(xdrs, addr, len)
+       register XDR *xdrs;
+       caddr_t addr;
+       register u_int len;
+{
+
+       if ((xdrs->x_handy -= len) < 0)
+               return (FALSE);
+       bcopy(xdrs->x_private, addr, len);
+       xdrs->x_private += len;
+       return (TRUE);
+}
+
+static bool_t
+xdrmem_putbytes(xdrs, addr, len)
+       register XDR *xdrs;
+       caddr_t addr;
+       register u_int len;
+{
+
+       if ((xdrs->x_handy -= len) < 0)
+               return (FALSE);
+       bcopy(addr, xdrs->x_private, len);
+       xdrs->x_private += len;
+       return (TRUE);
+}
+
+static u_int
+xdrmem_getpos(xdrs)
+       register XDR *xdrs;
+{
+
+       return ((u_int)xdrs->x_private - (u_int)xdrs->x_base);
+}
+
+static bool_t
+xdrmem_setpos(xdrs, pos)
+       register XDR *xdrs;
+       u_int pos;
+{
+       register caddr_t newaddr = xdrs->x_base + pos;
+       register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
+
+       if ((long)newaddr > (long)lastaddr)
+               return (FALSE);
+       xdrs->x_private = newaddr;
+       xdrs->x_handy = (int)lastaddr - (int)newaddr;
+       return (TRUE);
+}
+
+static long *
+xdrmem_inline(xdrs, len)
+       register XDR *xdrs;
+       int len;
+{
+       long *buf = 0;
+
+       if (xdrs->x_handy >= len) {
+               xdrs->x_handy -= len;
+               buf = (long *) xdrs->x_private;
+               xdrs->x_private += len;
+       }
+       return (buf);
+}
diff --git a/libc/inet/rpc/xdr_rec.c b/libc/inet/rpc/xdr_rec.c
new file mode 100644 (file)
index 0000000..4d0d4ec
--- /dev/null
@@ -0,0 +1,580 @@
+/* @(#)xdr_rec.c       2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
+ * layer above tcp (for rpc's use).
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These routines interface XDRSTREAMS to a tcp/ip connection.
+ * There is a record marking layer between the xdr stream
+ * and the tcp transport level.  A record is composed on one or more
+ * record fragments.  A record fragment is a thirty-two bit header followed
+ * by n bytes of data, where n is contained in the header.  The header
+ * is represented as a htonl(u_long).  Thegh order bit encodes
+ * whether or not the fragment is the last fragment of the record
+ * (1 => fragment is last, 0 => more fragments to follow. 
+ * The other 31 bits encode the byte length of the fragment.
+ */
+
+#include <stdio.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+extern long    lseek();
+
+static u_int   fix_buf_size();
+
+static bool_t  xdrrec_getlong();
+static bool_t  xdrrec_putlong();
+static bool_t  xdrrec_getbytes();
+static bool_t  xdrrec_putbytes();
+static u_int   xdrrec_getpos();
+static bool_t  xdrrec_setpos();
+static long *  xdrrec_inline();
+static void    xdrrec_destroy();
+
+static struct  xdr_ops xdrrec_ops = {
+       xdrrec_getlong,
+       xdrrec_putlong,
+       xdrrec_getbytes,
+       xdrrec_putbytes,
+       xdrrec_getpos,
+       xdrrec_setpos,
+       xdrrec_inline,
+       xdrrec_destroy
+};
+
+/*
+ * A record is composed of one or more record fragments.
+ * A record fragment is a two-byte header followed by zero to
+ * 2**32-1 bytes.  The header is treated as a long unsigned and is
+ * encode/decoded to the network via htonl/ntohl.  The low order 31 bits
+ * are a byte count of the fragment.  The highest order bit is a boolean:
+ * 1 => this fragment is the last fragment of the record,
+ * 0 => this fragment is followed by more fragment(s).
+ *
+ * The fragment/record machinery is not general;  it is constructed to
+ * meet the needs of xdr and rpc based on tcp.
+ */
+
+#define LAST_FRAG ((u_long)(1 << 31))
+
+typedef struct rec_strm {
+       caddr_t tcp_handle;
+       caddr_t the_buffer;
+       /*
+        * out-goung bits
+        */
+       int (*writeit)();
+       caddr_t out_base;       /* output buffer (points to frag header) */
+       caddr_t out_finger;     /* next output position */
+       caddr_t out_boundry;    /* data cannot up to this address */
+       u_long *frag_header;    /* beginning of curren fragment */
+       bool_t frag_sent;       /* true if buffer sent in middle of record */
+       /*
+        * in-coming bits
+        */
+       int (*readit)();
+       u_long in_size; /* fixed size of the input buffer */
+       caddr_t in_base;
+       caddr_t in_finger;      /* location of next byte to be had */
+       caddr_t in_boundry;     /* can read up to this location */
+       long fbtbc;             /* fragment bytes to be consumed */
+       bool_t last_frag;
+       u_int sendsize;
+       u_int recvsize;
+} RECSTREAM;
+
+
+/*
+ * Create an xdr handle for xdrrec
+ * xdrrec_create fills in xdrs.  Sendsize and recvsize are
+ * send and recv buffer sizes (0 => use default).
+ * tcp_handle is an opaque handle that is passed as the first parameter to
+ * the procedures readit and writeit.  Readit and writeit are read and
+ * write respectively.   They are like the system
+ * calls expect that they take an opaque handle rather than an fd.
+ */
+void
+xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
+       register XDR *xdrs;
+       register u_int sendsize;
+       register u_int recvsize;
+       caddr_t tcp_handle;
+       int (*readit)();  /* like read, but pass it a tcp_handle, not sock */
+       int (*writeit)();  /* like write, but pass it a tcp_handle, not sock */
+{
+       register RECSTREAM *rstrm =
+               (RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
+
+       if (rstrm == NULL) {
+               (void)fprintf(stderr, "xdrrec_create: out of memory\n");
+               /* 
+                *  This is bad.  Should rework xdrrec_create to 
+                *  return a handle, and in this case return NULL
+                */
+               return;
+       }
+       /*
+        * adjust sizes and allocate buffer quad byte aligned
+        */
+       rstrm->sendsize = sendsize = fix_buf_size(sendsize);
+       rstrm->recvsize = recvsize = fix_buf_size(recvsize);
+       rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT);
+       if (rstrm->the_buffer == NULL) {
+               (void)fprintf(stderr, "xdrrec_create: out of memory\n");
+               return;
+       }
+       for (rstrm->out_base = rstrm->the_buffer;
+               (u_int)rstrm->out_base % BYTES_PER_XDR_UNIT != 0;
+               rstrm->out_base++);
+       rstrm->in_base = rstrm->out_base + sendsize;
+       /*
+        * now the rest ...
+        */
+       xdrs->x_ops = &xdrrec_ops;
+       xdrs->x_private = (caddr_t)rstrm;
+       rstrm->tcp_handle = tcp_handle;
+       rstrm->readit = readit;
+       rstrm->writeit = writeit;
+       rstrm->out_finger = rstrm->out_boundry = rstrm->out_base;
+       rstrm->frag_header = (u_long *)rstrm->out_base;
+       rstrm->out_finger += sizeof(u_long);
+       rstrm->out_boundry += sendsize;
+       rstrm->frag_sent = FALSE;
+       rstrm->in_size = recvsize;
+       rstrm->in_boundry = rstrm->in_base;
+       rstrm->in_finger = (rstrm->in_boundry += recvsize);
+       rstrm->fbtbc = 0;
+       rstrm->last_frag = TRUE;
+}
+
+
+/*
+ * The reoutines defined below are the xdr ops which will go into the
+ * xdr handle filled in by xdrrec_create.
+ */
+
+static bool_t
+xdrrec_getlong(xdrs, lp)
+       XDR *xdrs;
+       long *lp;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+       register long *buflp = (long *)(rstrm->in_finger);
+       long mylong;
+
+       /* first try the inline, fast case */
+       if ((rstrm->fbtbc >= sizeof(long)) &&
+               (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) {
+               *lp = (long)ntohl((u_long)(*buflp));
+               rstrm->fbtbc -= sizeof(long);
+               rstrm->in_finger += sizeof(long);
+       } else {
+               if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long)))
+                       return (FALSE);
+               *lp = (long)ntohl((u_long)mylong);
+       }
+       return (TRUE);
+}
+
+static bool_t
+xdrrec_putlong(xdrs, lp)
+       XDR *xdrs;
+       long *lp;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+       register long *dest_lp = ((long *)(rstrm->out_finger));
+
+       if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) {
+               /*
+                * this case should almost never happen so the code is
+                * inefficient
+                */
+               rstrm->out_finger -= sizeof(long);
+               rstrm->frag_sent = TRUE;
+               if (! flush_out(rstrm, FALSE))
+                       return (FALSE);
+               dest_lp = ((long *)(rstrm->out_finger));
+               rstrm->out_finger += sizeof(long);
+       }
+       *dest_lp = (long)htonl((u_long)(*lp));
+       return (TRUE);
+}
+
+static bool_t  /* must manage buffers, fragments, and records */
+xdrrec_getbytes(xdrs, addr, len)
+       XDR *xdrs;
+       register caddr_t addr;
+       register u_int len;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+       register int current;
+
+       while (len > 0) {
+               current = rstrm->fbtbc;
+               if (current == 0) {
+                       if (rstrm->last_frag)
+                               return (FALSE);
+                       if (! set_input_fragment(rstrm))
+                               return (FALSE);
+                       continue;
+               }
+               current = (len < current) ? len : current;
+               if (! get_input_bytes(rstrm, addr, current))
+                       return (FALSE);
+               addr += current; 
+               rstrm->fbtbc -= current;
+               len -= current;
+       }
+       return (TRUE);
+}
+
+static bool_t
+xdrrec_putbytes(xdrs, addr, len)
+       XDR *xdrs;
+       register caddr_t addr;
+       register u_int len;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+       register int current;
+
+       while (len > 0) {
+               current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger;
+               current = (len < current) ? len : current;
+               bcopy(addr, rstrm->out_finger, current);
+               rstrm->out_finger += current;
+               addr += current;
+               len -= current;
+               if (rstrm->out_finger == rstrm->out_boundry) {
+                       rstrm->frag_sent = TRUE;
+                       if (! flush_out(rstrm, FALSE))
+                               return (FALSE);
+               }
+       }
+       return (TRUE);
+}
+
+static u_int
+xdrrec_getpos(xdrs)
+       register XDR *xdrs;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+       register long pos;
+
+       pos = lseek((int)rstrm->tcp_handle, (long) 0, 1);
+       if (pos != -1)
+               switch (xdrs->x_op) {
+
+               case XDR_ENCODE:
+                       pos += rstrm->out_finger - rstrm->out_base;
+                       break;
+
+               case XDR_DECODE:
+                       pos -= rstrm->in_boundry - rstrm->in_finger;
+                       break;
+
+               default:
+                       pos = (u_int) -1;
+                       break;
+               }
+       return ((u_int) pos);
+}
+
+static bool_t
+xdrrec_setpos(xdrs, pos)
+       register XDR *xdrs;
+       u_int pos;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+       u_int currpos = xdrrec_getpos(xdrs);
+       int delta = currpos - pos;
+       caddr_t newpos;
+
+       if ((int)currpos != -1)
+               switch (xdrs->x_op) {
+
+               case XDR_ENCODE:
+                       newpos = rstrm->out_finger - delta;
+                       if ((newpos > (caddr_t)(rstrm->frag_header)) &&
+                               (newpos < rstrm->out_boundry)) {
+                               rstrm->out_finger = newpos;
+                               return (TRUE);
+                       }
+                       break;
+
+               case XDR_DECODE:
+                       newpos = rstrm->in_finger - delta;
+                       if ((delta < (int)(rstrm->fbtbc)) &&
+                               (newpos <= rstrm->in_boundry) &&
+                               (newpos >= rstrm->in_base)) {
+                               rstrm->in_finger = newpos;
+                               rstrm->fbtbc -= delta;
+                               return (TRUE);
+                       }
+                       break;
+               }
+       return (FALSE);
+}
+
+static long *
+xdrrec_inline(xdrs, len)
+       register XDR *xdrs;
+       int len;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+       long * buf = NULL;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
+                       buf = (long *) rstrm->out_finger;
+                       rstrm->out_finger += len;
+               }
+               break;
+
+       case XDR_DECODE:
+               if ((len <= rstrm->fbtbc) &&
+                       ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
+                       buf = (long *) rstrm->in_finger;
+                       rstrm->fbtbc -= len;
+                       rstrm->in_finger += len;
+               }
+               break;
+       }
+       return (buf);
+}
+
+static void
+xdrrec_destroy(xdrs)
+       register XDR *xdrs;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+
+       mem_free(rstrm->the_buffer,
+               rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT);
+       mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
+}
+
+
+/*
+ * Exported routines to manage xdr records
+ */
+
+/*
+ * Before reading (deserializing from the stream, one should always call
+ * this procedure to guarantee proper record alignment.
+ */
+bool_t
+xdrrec_skiprecord(xdrs)
+       XDR *xdrs;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+       while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+               if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+                       return (FALSE);
+               rstrm->fbtbc = 0;
+               if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+                       return (FALSE);
+       }
+       rstrm->last_frag = FALSE;
+       return (TRUE);
+}
+
+/*
+ * Look ahead fuction.
+ * Returns TRUE iff there is no more input in the buffer 
+ * after consuming the rest of the current record.
+ */
+bool_t
+xdrrec_eof(xdrs)
+       XDR *xdrs;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+       while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+               if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+                       return (TRUE);
+               rstrm->fbtbc = 0;
+               if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+                       return (TRUE);
+       }
+       if (rstrm->in_finger == rstrm->in_boundry)
+               return (TRUE);
+       return (FALSE);
+}
+
+/*
+ * The client must tell the package when an end-of-record has occurred.
+ * The second paraemters tells whether the record should be flushed to the
+ * (output) tcp stream.  (This let's the package support batched or
+ * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection.
+ */
+bool_t
+xdrrec_endofrecord(xdrs, sendnow)
+       XDR *xdrs;
+       bool_t sendnow;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+       register u_long len;  /* fragment length */
+
+       if (sendnow || rstrm->frag_sent ||
+               ((u_long)rstrm->out_finger + sizeof(u_long) >=
+               (u_long)rstrm->out_boundry)) {
+               rstrm->frag_sent = FALSE;
+               return (flush_out(rstrm, TRUE));
+       }
+       len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
+          sizeof(u_long);
+       *(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG);
+       rstrm->frag_header = (u_long *)rstrm->out_finger;
+       rstrm->out_finger += sizeof(u_long);
+       return (TRUE);
+}
+
+
+/*
+ * Internal useful routines
+ */
+static bool_t
+flush_out(rstrm, eor)
+       register RECSTREAM *rstrm;
+       bool_t eor;
+{
+       register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0;
+       register u_long len = (u_long)(rstrm->out_finger) - 
+               (u_long)(rstrm->frag_header) - sizeof(u_long);
+
+       *(rstrm->frag_header) = htonl(len | eormask);
+       len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base);
+       if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
+               != (int)len)
+               return (FALSE);
+       rstrm->frag_header = (u_long *)rstrm->out_base;
+       rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long);
+       return (TRUE);
+}
+
+static bool_t  /* knows nothing about records!  Only about input buffers */
+fill_input_buf(rstrm)
+       register RECSTREAM *rstrm;
+{
+       register caddr_t where;
+       u_int i;
+       register int len;
+
+       where = rstrm->in_base;
+       i = (u_int)rstrm->in_boundry % BYTES_PER_XDR_UNIT;
+       where += i;
+       len = rstrm->in_size - i;
+       if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
+               return (FALSE);
+       rstrm->in_finger = where;
+       where += len;
+       rstrm->in_boundry = where;
+       return (TRUE);
+}
+
+static bool_t  /* knows nothing about records!  Only about input buffers */
+get_input_bytes(rstrm, addr, len)
+       register RECSTREAM *rstrm;
+       register caddr_t addr;
+       register int len;
+{
+       register int current;
+
+       while (len > 0) {
+               current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
+               if (current == 0) {
+                       if (! fill_input_buf(rstrm))
+                               return (FALSE);
+                       continue;
+               }
+               current = (len < current) ? len : current;
+               bcopy(rstrm->in_finger, addr, current);
+               rstrm->in_finger += current;
+               addr += current;
+               len -= current;
+       }
+       return (TRUE);
+}
+
+static bool_t  /* next two bytes of the input stream are treated as a header */
+set_input_fragment(rstrm)
+       register RECSTREAM *rstrm;
+{
+       u_long header;
+
+       if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
+               return (FALSE);
+       header = (long)ntohl(header);
+       rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
+       rstrm->fbtbc = header & (~LAST_FRAG);
+       return (TRUE);
+}
+
+static bool_t  /* consumes input bytes; knows nothing about records! */
+skip_input_bytes(rstrm, cnt)
+       register RECSTREAM *rstrm;
+       long cnt;
+{
+       register int current;
+
+       while (cnt > 0) {
+               current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
+               if (current == 0) {
+                       if (! fill_input_buf(rstrm))
+                               return (FALSE);
+                       continue;
+               }
+               current = (cnt < current) ? cnt : current;
+               rstrm->in_finger += current;
+               cnt -= current;
+       }
+       return (TRUE);
+}
+
+static u_int
+fix_buf_size(s)
+       register u_int s;
+{
+
+       if (s < 100)
+               s = 4000;
+       return (RNDUP(s));
+}
diff --git a/libc/inet/rpc/xdr_reference.c b/libc/inet/rpc/xdr_reference.c
new file mode 100644 (file)
index 0000000..32d91d9
--- /dev/null
@@ -0,0 +1,132 @@
+/* @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_reference.c 1.11 87/08/11 SMI";
+#endif
+
+/*
+ * xdr_reference.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * "pointers".  See xdr.h for more info on the interface to xdr.
+ */
+
+#include <stdio.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED   ((u_int)0-1)
+
+/*
+ * XDR an indirect pointer
+ * xdr_reference is for recursively translating a structure that is
+ * referenced by a pointer inside the structure that is currently being
+ * translated.  pp references a pointer to storage. If *pp is null
+ * the  necessary storage is allocated.
+ * size is the sizeof the referneced structure.
+ * proc is the routine to handle the referenced structure.
+ */
+bool_t
+xdr_reference(xdrs, pp, size, proc)
+       register XDR *xdrs;
+       caddr_t *pp;            /* the pointer to work on */
+       u_int size;             /* size of the object pointed to */
+       xdrproc_t proc;         /* xdr routine to handle the object */
+{
+       register caddr_t loc = *pp;
+       register bool_t stat;
+
+       if (loc == NULL)
+               switch (xdrs->x_op) {
+               case XDR_FREE:
+                       return (TRUE);
+
+               case XDR_DECODE:
+                       *pp = loc = (caddr_t) mem_alloc(size);
+                       if (loc == NULL) {
+                               (void) fprintf(stderr,
+                                   "xdr_reference: out of memory\n");
+                               return (FALSE);
+                       }
+                       bzero(loc, (int)size);
+                       break;
+       }
+
+       stat = (*proc)(xdrs, loc, LASTUNSIGNED);
+
+       if (xdrs->x_op == XDR_FREE) {
+               mem_free(loc, size);
+               *pp = NULL;
+       }
+       return (stat);
+}
+
+
+/*
+ * xdr_pointer():
+ *
+ * XDR a pointer to a possibly recursive data structure. This
+ * differs with xdr_reference in that it can serialize/deserialiaze
+ * trees correctly.
+ *
+ *  What's sent is actually a union:
+ *
+ *  union object_pointer switch (boolean b) {
+ *  case TRUE: object_data data;
+ *  case FALSE: void nothing;
+ *  }
+ *
+ * > objpp: Pointer to the pointer to the object.
+ * > obj_size: size of the object.
+ * > xdr_obj: routine to XDR an object.
+ *
+ */
+bool_t
+xdr_pointer(xdrs,objpp,obj_size,xdr_obj)
+       register XDR *xdrs;
+       char **objpp;
+       u_int obj_size;
+       xdrproc_t xdr_obj;
+{
+
+       bool_t more_data;
+
+       more_data = (*objpp != NULL);
+       if (! xdr_bool(xdrs,&more_data)) {
+               return (FALSE);
+       }
+       if (! more_data) {
+               *objpp = NULL;
+               return (TRUE);
+       }
+       return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
+}
diff --git a/libc/inet/rpc/xdr_stdio.c b/libc/inet/rpc/xdr_stdio.c
new file mode 100644 (file)
index 0000000..694774f
--- /dev/null
@@ -0,0 +1,189 @@
+/* @(#)xdr_stdio.c     2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_stdio.c, XDR implementation on standard i/o file.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements a XDR on a stdio stream.
+ * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
+ * from the stream.
+ */
+
+#include <rpc/types.h>
+#include <stdio.h>
+#include <rpc/xdr.h>
+
+static bool_t  xdrstdio_getlong();
+static bool_t  xdrstdio_putlong();
+static bool_t  xdrstdio_getbytes();
+static bool_t  xdrstdio_putbytes();
+static u_int   xdrstdio_getpos();
+static bool_t  xdrstdio_setpos();
+static long *  xdrstdio_inline();
+static void    xdrstdio_destroy();
+
+/*
+ * Ops vector for stdio type XDR
+ */
+static struct xdr_ops  xdrstdio_ops = {
+       xdrstdio_getlong,       /* deseraialize a long int */
+       xdrstdio_putlong,       /* seraialize a long int */
+       xdrstdio_getbytes,      /* deserialize counted bytes */
+       xdrstdio_putbytes,      /* serialize counted bytes */
+       xdrstdio_getpos,        /* get offset in the stream */
+       xdrstdio_setpos,        /* set offset in the stream */
+       xdrstdio_inline,        /* prime stream for inline macros */
+       xdrstdio_destroy        /* destroy stream */
+};
+
+/*
+ * Initialize a stdio xdr stream.
+ * Sets the xdr stream handle xdrs for use on the stream file.
+ * Operation flag is set to op.
+ */
+void
+xdrstdio_create(xdrs, file, op)
+       register XDR *xdrs;
+       FILE *file;
+       enum xdr_op op;
+{
+
+       xdrs->x_op = op;
+       xdrs->x_ops = &xdrstdio_ops;
+       xdrs->x_private = (caddr_t)file;
+       xdrs->x_handy = 0;
+       xdrs->x_base = 0;
+}
+
+/*
+ * Destroy a stdio xdr stream.
+ * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
+ */
+static void
+xdrstdio_destroy(xdrs)
+       register XDR *xdrs;
+{
+       (void)fflush((FILE *)xdrs->x_private);
+       /* xx should we close the file ?? */
+};
+
+static bool_t
+xdrstdio_getlong(xdrs, lp)
+       XDR *xdrs;
+       register long *lp;
+{
+
+       if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
+               return (FALSE);
+#ifndef mc68000
+       *lp = ntohl(*lp);
+#endif
+       return (TRUE);
+}
+
+static bool_t
+xdrstdio_putlong(xdrs, lp)
+       XDR *xdrs;
+       long *lp;
+{
+
+#ifndef mc68000
+       long mycopy = htonl(*lp);
+       lp = &mycopy;
+#endif
+       if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
+               return (FALSE);
+       return (TRUE);
+}
+
+static bool_t
+xdrstdio_getbytes(xdrs, addr, len)
+       XDR *xdrs;
+       caddr_t addr;
+       u_int len;
+{
+
+       if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+               return (FALSE);
+       return (TRUE);
+}
+
+static bool_t
+xdrstdio_putbytes(xdrs, addr, len)
+       XDR *xdrs;
+       caddr_t addr;
+       u_int len;
+{
+
+       if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+               return (FALSE);
+       return (TRUE);
+}
+
+static u_int
+xdrstdio_getpos(xdrs)
+       XDR *xdrs;
+{
+
+       return ((u_int) ftell((FILE *)xdrs->x_private));
+}
+
+static bool_t
+xdrstdio_setpos(xdrs, pos) 
+       XDR *xdrs;
+       u_int pos;
+{ 
+
+       return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
+               FALSE : TRUE);
+}
+
+static long *
+xdrstdio_inline(xdrs, len)
+       XDR *xdrs;
+       u_int len;
+{
+
+       /*
+        * Must do some work to implement this: must insure
+        * enough data in the underlying stdio buffer,
+        * that the buffer is aligned so that we can indirect through a
+        * long *, and stuff this pointer in xdrs->x_buf.  Doing
+        * a fread or fwrite to a scratch buffer would defeat
+        * most of the gains to be had here and require storage
+        * management on this buffer, so we don't do this.
+        */
+       return (NULL);
+}
diff --git a/libc/misc/time/Makefile b/libc/misc/time/Makefile
new file mode 100644 (file)
index 0000000..ab47a7e
--- /dev/null
@@ -0,0 +1,24 @@
+# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk>
+# This file is part of the Linux-8086 C library and is distributed
+# under the GNU Library General Public License.
+
+LIBC=../libc.a
+
+CC=m68k-pic-coff-gcc
+AR=m68k-pic-coff-ar
+RANLIB=m68k-pic-coff-ranlib
+
+CCFLAGS= -O2 -m68000 -msoft-float -I../include
+
+OBJ=localtime.o gmtime.o asctime.o ctime.o asc_conv.o tm_conv.o mktime.o \
+       localtime_r.o gmtime_r.o asctime_r.o ctime_r.o
+
+CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
+
+all: $(LIBC)
+       @$(RM) $(OBJ)
+
+$(LIBC): $(LIBC)($(OBJ))
+
+clean:
+       rm -f *.o libc.a
diff --git a/libc/misc/time/README b/libc/misc/time/README
new file mode 100644 (file)
index 0000000..da4f4e6
--- /dev/null
@@ -0,0 +1,8 @@
+Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk>
+This file is part of the Linux-8086 C library and is distributed
+under the GNU Library General Public License.
+
+There are two ways of converting the time_t to a struct tm, I'm not
+quite sure which is better.
+
+-Robert
diff --git a/libc/misc/time/asc_conv.c b/libc/misc/time/asc_conv.c
new file mode 100644 (file)
index 0000000..78cbcdd
--- /dev/null
@@ -0,0 +1,49 @@
+
+#include <time.h>
+#include <string.h>
+/*
+ * Internal ascii conversion routine, avoid use of printf, it's a bit big!
+ */
+
+
+static void
+hit(buf, val)
+char * buf;
+int val;
+{
+   *buf = '0' + val%10;
+}
+
+void
+__asctime(buffer, ptm)
+register char * buffer;
+struct tm * ptm;
+{
+static char days[] = "SunMonTueWedThuFriSat";
+static char mons[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
+   int year;
+
+   /*              012345678901234567890123456 */
+   strcpy(buffer, "Err Err .. ..:..:.. ....\n");
+   if( (ptm->tm_wday >= 0) && (ptm->tm_wday <= 6) )
+     memcpy(buffer, days+3*(ptm->tm_wday), 3);
+
+   if( (ptm->tm_mon >= 0) && (ptm->tm_mon <= 11) )
+     memcpy(buffer+4, mons+3*(ptm->tm_mon), 3);
+
+
+   hit(buffer+ 8, ptm->tm_mday/10);
+   hit(buffer+ 9, ptm->tm_mday   );
+   hit(buffer+11, ptm->tm_hour/10);
+   hit(buffer+12, ptm->tm_hour   );
+   hit(buffer+14, ptm->tm_min/10);
+   hit(buffer+15, ptm->tm_min   );
+   hit(buffer+17, ptm->tm_sec/10);
+   hit(buffer+18, ptm->tm_sec   );
+
+   year = ptm->tm_year + 1900;
+   hit(buffer+20, year/1000);
+   hit(buffer+21, year/100);
+   hit(buffer+22, year/10);
+   hit(buffer+23, year);
+}
diff --git a/libc/misc/time/asctime.c b/libc/misc/time/asctime.c
new file mode 100644 (file)
index 0000000..08673cb
--- /dev/null
@@ -0,0 +1,15 @@
+
+#include <time.h>
+
+extern void __asctime();
+
+char *
+asctime(timeptr)
+__const struct tm * timeptr;
+{
+   static char timebuf[26];
+
+   if( timeptr == 0 ) return 0;
+   __asctime(timebuf, timeptr);
+   return timebuf;
+}
diff --git a/libc/misc/time/asctime_r.c b/libc/misc/time/asctime_r.c
new file mode 100644 (file)
index 0000000..ff2b6bf
--- /dev/null
@@ -0,0 +1,15 @@
+
+#include <time.h>
+
+extern void __asctime();
+
+char *
+asctime_r(timeptr, buf)
+__const struct tm * timeptr;
+char * buf;
+{
+
+   if( timeptr == 0 ) return 0;
+   __asctime(buf, timeptr);
+   return buf;
+}
diff --git a/libc/misc/time/ctime.c b/libc/misc/time/ctime.c
new file mode 100644 (file)
index 0000000..2f42cd3
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include <time.h>
+
+extern void __tm_conv();
+extern void __asctime();
+
+char *
+ctime(timep)
+__const time_t * timep;
+{
+  static char cbuf[26];
+  struct tm tmb;
+  struct timezone tz;
+  time_t offt;
+  
+  gettimeofday((void*)0, &tz);
+  
+  offt = -tz.tz_minuteswest*60L;
+  
+  /* tmb.tm_isdst = ? */
+  __tm_conv(&tmb, timep, offt);
+  
+  __asctime(cbuf, &tmb);
+  
+  return cbuf;
+}
diff --git a/libc/misc/time/ctime_r.c b/libc/misc/time/ctime_r.c
new file mode 100644 (file)
index 0000000..ac267b0
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include <time.h>
+
+extern void __tm_conv();
+extern void __asctime();
+
+char *
+ctime_r(timep, buf)
+__const time_t * timep;
+char * buf;
+{
+  struct tm tmb;
+  struct timezone tz;
+  time_t offt;
+  
+  gettimeofday((void*)0, &tz);
+  
+  offt = -tz.tz_minuteswest*60L;
+  
+  /* tmb.tm_isdst = ? */
+  __tm_conv(&tmb, timep, offt);
+  
+  __asctime(buf, &tmb);
+  
+  return buf;
+}
diff --git a/libc/misc/time/gmtime.c b/libc/misc/time/gmtime.c
new file mode 100644 (file)
index 0000000..69d5393
--- /dev/null
@@ -0,0 +1,16 @@
+
+#include <time.h>
+
+extern void __tm_conv();
+
+struct tm *
+gmtime(timep)
+__const time_t * timep;
+{
+   static struct tm tmb;
+
+   __tm_conv(&tmb, timep, 0L);
+
+   return &tmb;
+}
+
diff --git a/libc/misc/time/gmtime_r.c b/libc/misc/time/gmtime_r.c
new file mode 100644 (file)
index 0000000..00c41b3
--- /dev/null
@@ -0,0 +1,14 @@
+
+#include <time.h>
+
+extern void __tm_conv();
+
+struct tm *
+gmtime_r(timep, tp)
+__const time_t * timep;
+struct tm * tp;
+{
+   __tm_conv(tp, timep, 0L);
+   return tp;
+}
+
diff --git a/libc/misc/time/localtime.c b/libc/misc/time/localtime.c
new file mode 100644 (file)
index 0000000..9d9b46d
--- /dev/null
@@ -0,0 +1,22 @@
+
+#include <time.h>
+
+extern void __tm_conv();
+
+struct tm *
+localtime(timep)
+__const time_t * timep;
+{
+   static struct tm tmb;
+   struct timezone tz;
+   time_t offt;
+
+   gettimeofday((void*)0, &tz);
+
+   offt = -tz.tz_minuteswest*60L;
+
+   /* tmb.tm_isdst = ? */
+   __tm_conv(&tmb, timep, offt);
+
+   return &tmb;
+}
diff --git a/libc/misc/time/localtime_r.c b/libc/misc/time/localtime_r.c
new file mode 100644 (file)
index 0000000..fe02467
--- /dev/null
@@ -0,0 +1,22 @@
+
+#include <time.h>
+
+extern void __tm_conv();
+
+struct tm *
+localtime_r(timep, tp)
+__const time_t * timep;
+struct tm * tp;
+{
+   struct timezone tz;
+   time_t offt;
+
+   gettimeofday((void*)0, &tz);
+
+   offt = -tz.tz_minuteswest*60L;
+
+   /* tmb.tm_isdst = ? */
+   __tm_conv(tp, timep, offt);
+
+   return tp;
+}
diff --git a/libc/misc/time/mktime.c b/libc/misc/time/mktime.c
new file mode 100644 (file)
index 0000000..7f7aabc
--- /dev/null
@@ -0,0 +1,259 @@
+
+/* This is adapted from glibc */
+/* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc. */
+
+
+/* Assume that leap seconds are possible, unless told otherwise.
+   If the host has a `zic' command with a -L leapsecondfilename' option,
+   then it supports leap seconds; otherwise it probably doesn't.  */
+#ifndef LEAP_SECONDS_POSSIBLE
+#define LEAP_SECONDS_POSSIBLE 1
+#endif
+
+#include <sys/types.h>          /* Some systems define `time_t' here.  */
+#include <time.h>
+
+#if __STDC__ || __GNU_LIBRARY__ || STDC_HEADERS
+#include <limits.h>
+#endif
+
+#if DEBUG
+#include <stdio.h>
+#if __STDC__ || __GNU_LIBRARY__ || STDC_HEADERS
+#include <stdlib.h>
+#endif
+/* Make it work even if the system's libc has its own mktime routine.  */
+#define mktime my_mktime
+#endif /* DEBUG */
+
+#ifndef __P
+#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif  /* GCC.  */
+#endif  /* Not __P.  */
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#ifndef INT_MIN
+#define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
+#endif
+#ifndef INT_MAX
+#define INT_MAX (~0 - INT_MIN)
+#endif
+
+#ifndef TIME_T_MIN
+#define TIME_T_MIN (0 < (time_t) -1 ? (time_t) 0 \
+                    : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
+#endif
+#ifndef TIME_T_MAX
+#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
+#endif
+
+#define TM_YEAR_BASE 1900
+#define EPOCH_YEAR 1970
+
+#ifndef __isleap
+/* Nonzero if YEAR is a leap year (every 4 years,
+   except every 100th isn't, and every 400th is).  */
+#define __isleap(year)  \
+  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+#endif
+
+/* How many days come before each month (0-12).  */
+const unsigned short int __mon_yday[2][13] =
+  {
+    /* Normal years.  */
+    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+    /* Leap years.  */
+    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+  };
+
+static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
+time_t __mktime_internal __P ((struct tm *,
+                               struct tm *(*) (const time_t *, struct tm *),
+                               time_t *));
+
+/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
+   measured in seconds, ignoring leap seconds.
+   YEAR uses the same numbering as TM->tm_year.
+   All values are in range, except possibly YEAR.
+   If overflow occurs, yield the low order bits of the correct answer.  */
+static time_t
+ydhms_tm_diff (year, yday, hour, min, sec, tp)
+     int year, yday, hour, min, sec;
+     const struct tm *tp;
+{
+  /* Compute intervening leap days correctly even if year is negative.
+     Take care to avoid int overflow.  time_t overflow is OK, since
+     only the low order bits of the correct time_t answer are needed.
+     Don't convert to time_t until after all divisions are done, since
+     time_t might be unsigned.  */
+  int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
+  int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
+  int a100 = a4 / 25 - (a4 % 25 < 0);
+  int b100 = b4 / 25 - (b4 % 25 < 0);
+  int a400 = a100 >> 2;
+  int b400 = b100 >> 2;
+  int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+  time_t years = year - (time_t) tp->tm_year;
+  time_t days = (365 * years + intervening_leap_days
+                 + (yday - tp->tm_yday));
+  return (60 * (60 * (24 * days + (hour - tp->tm_hour))
+                + (min - tp->tm_min))
+          + (sec - tp->tm_sec));
+}
+
+
+static time_t localtime_offset;
+
+
+/* Convert *TP to a time_t value.  */
+time_t
+mktime (tp)
+     struct tm *tp;
+{
+#ifdef _LIBC
+  /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
+     time zone names contained in the external variable `tzname' shall
+     be set as if the tzset() function had been called.  */
+  __tzset ();
+#endif
+
+  return __mktime_internal (tp, localtime_r, &localtime_offset);
+}
+
+/* Convert *TP to a time_t value, inverting
+   the monotonic and mostly-unit-linear conversion function CONVERT.
+   Use *OFFSET to keep track of a guess at the offset of the result,
+   compared to what the result would be for UTC without leap seconds.
+   If *OFFSET's guess is correct, only one CONVERT call is needed.  */
+time_t
+__mktime_internal (tp, convert, offset)
+     struct tm *tp;
+     struct tm *(*convert) __P ((const time_t *, struct tm *));
+     time_t *offset;
+{
+  time_t t, dt, t0;
+  struct tm tm;
+
+  /* The maximum number of probes (calls to CONVERT) should be enough
+     to handle any combinations of time zone rule changes, solar time,
+     and leap seconds.  Posix.1 prohibits leap seconds, but some hosts
+     have them anyway.  */
+  int remaining_probes = 4;
+
+  /* Time requested.  Copy it in case CONVERT modifies *TP; this can
+     occur if TP is localtime's returned value and CONVERT is localtime.  */
+  int sec = tp->tm_sec;
+  int min = tp->tm_min;
+  int hour = tp->tm_hour;
+  int mday = tp->tm_mday;
+  int mon = tp->tm_mon;
+  int year_requested = tp->tm_year;
+  int isdst = tp->tm_isdst;
+
+  /* Ensure that mon is in range, and set year accordingly.  */
+  int mon_remainder = mon % 12;
+  int negative_mon_remainder = mon_remainder < 0;
+  int mon_years = mon / 12 - negative_mon_remainder;
+  int year = year_requested + mon_years;
+
+  /* The other values need not be in range:
+     the remaining code handles minor overflows correctly,
+     assuming int and time_t arithmetic wraps around.
+     Major overflows are caught at the end.  */
+
+  /* Calculate day of year from year, month, and day of month.
+     The result need not be in range.  */
+  int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
+               [mon_remainder + 12 * negative_mon_remainder])
+              + mday - 1);
+
+#if LEAP_SECONDS_POSSIBLE
+  /* Handle out-of-range seconds specially,
+     since ydhms_tm_diff assumes every minute has 60 seconds.  */
+  int sec_requested = sec;
+  if (sec < 0)
+    sec = 0;
+  if (59 < sec)
+    sec = 59;
+#endif
+
+  /* Invert CONVERT by probing.  First assume the same offset as last time.
+     Then repeatedly use the error to improve the guess.  */
+
+  tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
+  tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+  t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
+
+  for (t = t0 + *offset;
+       (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
+       t += dt)
+    if (--remaining_probes == 0)
+      return -1;
+
+  /* Check whether tm.tm_isdst has the requested value, if any.  */
+  if (0 <= isdst && 0 <= tm.tm_isdst)
+    {
+      int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
+      if (dst_diff)
+        {
+          /* Move two hours in the direction indicated by the disagreement,
+             probe some more, and switch to a new time if found.
+             The largest known fallback due to daylight savings is two hours:
+             once, in Newfoundland, 1988-10-30 02:00 -> 00:00.  */
+          time_t ot = t - 2 * 60 * 60 * dst_diff;
+          while (--remaining_probes != 0)
+            {
+              struct tm otm;
+              if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
+                                         (*convert) (&ot, &otm))))
+                {
+                  t = ot;
+                  tm = otm;
+                  break;
+                }
+              if ((ot += dt) == t)
+                break;  /* Avoid a redundant probe.  */
+            }
+        }
+    }
+
+  *offset = t - t0;
+
+#if LEAP_SECONDS_POSSIBLE
+  if (sec_requested != tm.tm_sec)
+    {
+      /* Adjust time to reflect the tm_sec requested, not the normalized value.
+         Also, repair any damage from a false match due to a leap second.  */
+      t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
+      (*convert) (&t, &tm);
+    }
+#endif
+
+#if 0
+  if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
+    {
+      /* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
+         so check for major overflows.  A gross check suffices,
+         since if t has overflowed, it is off by a multiple of
+         TIME_T_MAX - TIME_T_MIN + 1.  So ignore any component of
+         the difference that is bounded by a small value.  */
+
+      double dyear = (double) year_requested + mon_years - tm.tm_year;
+      double dday = 366 * dyear + mday;
+      double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
+
+      if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
+        return -1;
+    }
+#endif
+
+  *tp = tm;
+  return t;
+}
+
diff --git a/libc/misc/time/tm_conv.c b/libc/misc/time/tm_conv.c
new file mode 100644 (file)
index 0000000..ffd524c
--- /dev/null
@@ -0,0 +1,138 @@
+
+#if 0
+#include <time.h>
+
+/* This is a translation from ALGOL in Collected Algorithms of CACM. */
+/* Copied from Algorithm 199, Author: Robert G. Tantzen */
+
+void
+__tm_conv(tmbuf, timep, offset)
+struct tm *tmbuf;
+time_t *timep;
+time_t offset;
+{
+static int   moffset[] =
+   {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+
+   long s;
+   long  j, d, m, y;
+
+   offset += *timep;
+
+   tmbuf->tm_isdst = 0;                /* Someone else can set this */
+
+   j = offset / 86400L + 719469;
+   s = offset % 86400L;
+
+   if( s < 0 ) { s += 86400L; j--; }
+
+   tmbuf->tm_sec = s % 60;
+   tmbuf->tm_min = (s / 60) % 60;
+   tmbuf->tm_hour = s / 3600;
+
+   tmbuf->tm_wday = (j+2) % 7;
+
+   /*
+    * Julian date converter. Takes a julian date (the number of days since
+    * some distant epoch or other), and fills tmbuf.
+    */
+
+   y = (4L * j - 1L) / 146097L;
+   j = 4L * j - 1L - 146097L * y;
+   d = j / 4L;
+   j = (4L * d + 3L) / 1461L;
+   d = 4L * d + 3L - 1461L * j;
+   d = (d + 4L) / 4L;
+   m = (5L * d - 3L) / 153L;
+   d = 5L * d - 3 - 153L * m;
+   d = (d + 5L) / 5L;
+   y = 100L * y + j;
+   if (m < 10)
+      m += 2;
+   else
+   {
+      m -= 10;
+      ++y;
+   }
+
+   tmbuf->tm_year = y - 1900;
+   tmbuf->tm_mon = m;
+   tmbuf->tm_mday = d;
+
+   tmbuf->tm_yday = d + moffset[m];
+   if (m > 1 && ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)))
+      tmbuf->tm_yday++;
+}
+
+#else
+
+/* This is adapted from glibc */
+/* Copyright (C) 1991, 1993 Free Software Foundation, Inc */
+
+#define SECS_PER_HOUR 3600L
+#define SECS_PER_DAY  86400L
+
+#include <time.h>
+
+static const unsigned short int __mon_lengths[2][12] =
+  {
+    /* Normal years.  */
+    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+    /* Leap years.  */
+    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+  };
+
+
+void
+__tm_conv(tmbuf, t, offset)
+struct tm *tmbuf;
+time_t *t;
+time_t offset;
+{
+  long days, rem;
+  register int y;
+  register unsigned short int *ip;
+
+  days = *t / SECS_PER_DAY;
+  rem = *t % SECS_PER_DAY;
+  rem += offset;
+  while (rem < 0)
+    {
+      rem += SECS_PER_DAY;
+      --days;
+    }
+  while (rem >= SECS_PER_DAY)
+    {
+      rem -= SECS_PER_DAY;
+      ++days;
+    }
+  tmbuf->tm_hour = rem / SECS_PER_HOUR;
+  rem %= SECS_PER_HOUR;
+  tmbuf->tm_min = rem / 60;
+  tmbuf->tm_sec = rem % 60;
+  /* January 1, 1970 was a Thursday.  */
+  tmbuf->tm_wday = (4 + days) % 7;
+  if (tmbuf->tm_wday < 0)
+    tmbuf->tm_wday += 7;
+  y = 1970;
+  while (days >= (rem = __isleap(y) ? 366 : 365))
+    {
+      ++y;
+      days -= rem;
+    }
+  while (days < 0)
+    {
+      --y;
+      days += __isleap(y) ? 366 : 365;
+    }
+  tmbuf->tm_year = y - 1900;
+  tmbuf->tm_yday = days;
+  ip = __mon_lengths[__isleap(y)];
+  for (y = 0; days >= ip[y]; ++y)
+    days -= ip[y];
+  tmbuf->tm_mon = y;
+  tmbuf->tm_mday = days + 1;
+  tmbuf->tm_isdst = -1;
+}
+
+#endif
diff --git a/libc/pwd_grp/Makefile b/libc/pwd_grp/Makefile
new file mode 100644 (file)
index 0000000..ce50648
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 1996 Nat Friedman <ndf@aleph1.mit.edu>
+# This file is part of the Linux-8086 C library and is distributed
+# under the GNU Library General Public License.
+
+LIBC=../libc.a
+
+CC=m68k-pic-coff-gcc
+AR=m68k-pic-coff-ar
+RANLIB=m68k-pic-coff-ranlib
+
+CCFLAGS= -O2 -m68000 -msoft-float -I../include
+
+CFLAGS=$(ARCH) -ansi $(CCFLAGS) $(DEFS)
+
+PSRC=__getpwent.c pwent.c getpwnam.c getpwuid.c putpwent.c getpw.c fgetpwent.c
+GSRC=__getgrent.c grent.c getgrnam.c getgrgid.c fgetgrent.c initgroups.c \
+       config-grp.h
+USRC=utent.c
+
+POBJ=__getpwent.o pwent.o getpwnam.o getpwuid.o putpwent.o getpw.o fgetpwent.o
+GOBJ=__getgrent.o grent.o getgrnam.o getgrgid.o fgetgrent.o initgroups.o 
+UOBJ=utent.o
+
+OBJ=$(POBJ) $(GOBJ) $(UOBJ)
+
+all: $(LIBC)($(OBJ))
+       @$(RM) $(OBJ)
+
+$(LIBC)($(GOBJ)): config-grp.h
+
+clean:
+       rm -f *.o libc.a
+
diff --git a/libc/pwd_grp/__getgrent.c b/libc/pwd_grp/__getgrent.c
new file mode 100644 (file)
index 0000000..612f112
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * __getgrent.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <grp.h>
+#include "config.h"
+
+/*
+ * This is the core group-file read function.  It behaves exactly like
+ * getgrent() except that it is passed a file descriptor.  getgrent()
+ * is just a wrapper for this function.
+ */
+struct group *
+__getgrent(int grp_fd)
+{
+#ifndef GR_SCALE_DYNAMIC  
+  static char line_buff[GR_MAX_LINE_LEN];
+  static char * members[GR_MAX_MEMBERS];
+#else
+  static char * line_buff = NULL;
+  static char ** members = NULL;
+  short line_index;
+  short buff_size;
+#endif
+  static struct group group;
+  register char * ptr;
+  char * field_begin;
+  short member_num;
+  char * endptr;
+  int line_len;
+
+
+  /* We use the restart label to handle malformatted lines */
+restart:
+#ifdef GR_SCALE_DYNAMIC
+  line_index=0;
+  buff_size=256;
+#endif
+
+#ifndef GR_SCALE_DYNAMIC
+  /* Read the line into the static buffer */
+  if ((line_len=read(grp_fd, line_buff, GR_MAX_LINE_LEN))<=0)
+    return NULL;
+  field_begin=strchr(line_buff, '\n');
+  if (field_begin!=NULL)
+    lseek(grp_fd, (long) (1+field_begin-(line_buff+line_len)), SEEK_CUR);
+  else /* The line is too long - skip it :-\ */
+    {
+      do { if ((line_len=read(grp_fd, line_buff, GR_MAX_LINE_LEN))<=0)
+       return NULL;
+      } while (!(field_begin=strchr(line_buff, '\n')));
+      lseek(grp_fd, (long) ((field_begin-line_buff)-line_len+1), SEEK_CUR);
+      goto restart;
+    }
+  if (*line_buff=='#' || *line_buff==' ' || *line_buff=='\n' ||
+      *line_buff=='\t')
+    goto restart;
+  *field_begin='\0';
+
+#else /* !GR_SCALE_DYNAMIC */
+  line_buff=realloc(line_buff, buff_size);
+  while (1)
+    {
+      if ((line_len=read(grp_fd, line_buff+line_index,
+                        buff_size-line_index))<=0)
+         return NULL;
+      field_begin=strchr(line_buff, '\n');
+      if (field_begin!=NULL)
+       {
+         lseek(grp_fd, (long) (1+field_begin-(line_len+line_index+line_buff)),
+               SEEK_CUR);
+         *field_begin='\0';
+         if (*line_buff=='#' || *line_buff==' ' || *line_buff=='\n' ||
+             *line_buff=='\t')
+           goto restart;
+         break;
+       }
+      else /* Allocate some more space */
+       {
+         line_index=buff_size;
+         buff_size+=256;
+         line_buff=realloc(line_buff, buff_size);
+       }
+    }
+#endif /* GR_SCALE_DYNAMIC */
+
+  /* Now parse the line */
+  group.gr_name=line_buff;
+  ptr=strchr(line_buff, ':');
+  if (ptr==NULL) goto restart;
+  *ptr++='\0';
+
+  group.gr_passwd=ptr;
+  ptr=strchr(ptr, ':');
+  if (ptr==NULL) goto restart;
+  *ptr++='\0';
+
+  field_begin=ptr;
+  ptr=strchr(ptr, ':');
+  if (ptr==NULL) goto restart;
+  *ptr++='\0';
+
+  group.gr_gid=(gid_t) strtoul(field_begin, &endptr, 10);
+  if (*endptr!='\0') goto restart;
+
+  member_num=0;
+  field_begin=ptr;
+
+#ifndef GR_SCALE_DYNAMIC
+  while ((ptr=strchr(ptr, ','))!=NULL)
+    {
+      *ptr='\0';
+      ptr++;
+      members[member_num]=field_begin;
+      field_begin=ptr;
+      member_num++;
+    }
+  if (*field_begin=='\0')
+    members[member_num]=NULL;
+  else
+    {
+      members[member_num]=field_begin;
+      members[member_num+1]=NULL;
+    }
+#else /* !GR_SCALE_DYNAMIC */
+  if (members!=NULL)
+    free (members);
+  members=(char **) malloc(1*sizeof(char *));
+  while ((ptr=strchr(ptr, ','))!=NULL)
+    {
+      *ptr='\0';
+      ptr++;
+      members[member_num]=field_begin;
+      field_begin=ptr;
+      member_num++;
+      members=(char **)realloc((void *)members, (member_num+1)*sizeof(char *));
+    }
+  if (*field_begin=='\0')
+      members[member_num]=NULL;
+  else
+    {
+      members[member_num]=field_begin;
+      members[member_num+1]=NULL;
+    }
+#endif /* GR_SCALE_DYNAMIC */
+
+  group.gr_mem=members;
+  return &group;
+}
diff --git a/libc/pwd_grp/config.h b/libc/pwd_grp/config.h
new file mode 100644 (file)
index 0000000..699434b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * config-grp.h - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#ifndef _CONFIG_GRP_H
+#define _CONFIG_GRP_H
+
+/*
+ * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer
+ * so that lines of any length can be used.  On very very small systems,
+ * you may want to leave this undefined becasue it will make the grp functions
+ * somewhat larger (because of the inclusion of malloc and the code necessary).
+ * On larger systems, you will want to define this, because grp will _not_
+ * deal with long lines gracefully (they will be skipped).
+ */
+#undef GR_SCALE_DYNAMIC
+
+#ifndef GR_SCALE_DYNAMIC
+/*
+ * If scaling is not dynamic, the buffers will be statically allocated, and
+ * maximums must be chosen.  GR_MAX_LINE_LEN is the maximum number of
+ * characters per line in the group file.  GR_MAX_MEMBERS is the maximum
+ * number of members of any given group.
+ */
+#define GR_MAX_LINE_LEN 128
+/* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */
+#define GR_MAX_MEMBERS 11
+
+#endif /* !GR_SCALE_DYNAMIC */
+
+
+/*
+ * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate
+ * space for it's GID array before calling setgroups().  This is probably
+ * unnecessary scalage, so it's undefined by default.
+ */
+#undef GR_DYNAMIC_GROUP_LIST
+
+#ifndef GR_DYNAMIC_GROUP_LIST
+/*
+ * GR_MAX_GROUPS is the size of the static array initgroups() uses for
+ * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined.
+ */
+#define GR_MAX_GROUPS 64
+
+#endif /* !GR_DYNAMIC_GROUP_LIST */
+
+#endif /* !_CONFIG_GRP_H */
diff --git a/libc/pwd_grp/fgetgrent.c b/libc/pwd_grp/fgetgrent.c
new file mode 100644 (file)
index 0000000..800236f
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * fgetgrent.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <grp.h>
+
+struct group *
+fgetgrent(FILE * file)
+{
+  if (file==NULL)
+    {
+      errno=EINTR;
+      return NULL;
+    }
+  
+  return __getgrent(fileno(file));
+}
diff --git a/libc/pwd_grp/fgetpwent.c b/libc/pwd_grp/fgetpwent.c
new file mode 100644 (file)
index 0000000..e12b890
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * fgetpwent.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <pwd.h>
+
+struct passwd *
+fgetpwent(FILE * file)
+{
+  if (file==NULL)
+    {
+      errno=EINTR;
+      return NULL;
+    }
+
+  return __getpwent(fileno(file));
+}
diff --git a/libc/pwd_grp/getgrgid.c b/libc/pwd_grp/getgrgid.c
new file mode 100644 (file)
index 0000000..c1dd20e
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * getgrgid.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <grp.h>
+
+struct group *
+getgrgid(const gid_t gid)
+{
+  struct group * group;
+  int grp_fd;
+
+  if ((grp_fd=open("/etc/group", O_RDONLY))<0)
+    return NULL;
+
+  while ((group=__getgrent(grp_fd))!=NULL)
+    if (group->gr_gid==gid)
+      {
+       close(grp_fd);
+       return group;
+      }
+
+  close(grp_fd);
+  return NULL;
+}
+
+
+
+
diff --git a/libc/pwd_grp/getgrnam.c b/libc/pwd_grp/getgrnam.c
new file mode 100644 (file)
index 0000000..e6c27fc
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * getgrnam.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+
+struct group *
+getgrnam(const char * name)
+{
+  int grp_fd;
+  struct group * group;
+
+  if (name==NULL)
+    {
+      errno=EINVAL;
+      return NULL;
+    }
+
+  if ((grp_fd=open("/etc/group", O_RDONLY))<0)
+    return NULL;
+
+  while ((group=__getgrent(grp_fd))!=NULL)
+    if (!strcmp(group->gr_name, name))
+      {
+       close(grp_fd);
+       return group;
+      }
+
+  close(grp_fd);
+  return NULL;
+}
diff --git a/libc/pwd_grp/getpw.c b/libc/pwd_grp/getpw.c
new file mode 100644 (file)
index 0000000..4f4e390
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * getpw.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <pwd.h>
+
+int
+getpw(uid_t uid, char *buf)
+{
+  struct passwd * passwd;
+
+  if (buf==NULL)
+    {
+      errno=EINVAL;
+      return -1;
+    }
+  if ((passwd=getpwuid(uid))==NULL)
+    return -1;
+
+  if (sprintf(buf, "%s:%s:%u:%u:%s:%s:%s", passwd->pw_name, passwd->pw_passwd,
+         passwd->pw_gid, passwd->pw_uid, passwd->pw_gecos,
+         passwd->pw_dir, passwd->pw_shell)<0)
+    {
+      errno=ENOBUFS;
+      return -1;
+    }
+
+  return 0;
+}  
+
+
+
diff --git a/libc/pwd_grp/getpwnam.c b/libc/pwd_grp/getpwnam.c
new file mode 100644 (file)
index 0000000..85dbc8e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * getpwnam.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+
+
+struct passwd *
+getpwnam(const char * name)
+{
+  int passwd_fd;
+  struct passwd * passwd;
+
+  if (name==NULL)
+    {
+      errno=EINVAL;
+      return NULL;
+    }
+
+  if ((passwd_fd=open("/etc/passwd", O_RDONLY))<0)
+    return NULL;
+
+  while ((passwd=__getpwent(passwd_fd))!=NULL)
+    if (!strcmp(passwd->pw_name, name))
+      {
+       close(passwd_fd);
+       return passwd;
+      }          
+
+  close(passwd_fd);
+  return NULL;
+}
diff --git a/libc/pwd_grp/getpwuid.c b/libc/pwd_grp/getpwuid.c
new file mode 100644 (file)
index 0000000..ffd58c1
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * getpwuid.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+
+struct passwd *
+getpwuid(uid_t uid)
+{
+  int passwd_fd;
+  struct passwd * passwd;
+
+  if ((passwd_fd=open("/etc/passwd", O_RDONLY))<0)
+    return NULL;
+
+  while ((passwd=__getpwent(passwd_fd))!=NULL)
+    if (passwd->pw_uid==uid)
+      {
+       close(passwd_fd);
+       return passwd;
+      }
+
+  close (passwd_fd);
+  return NULL;
+}
diff --git a/libc/pwd_grp/grent.c b/libc/pwd_grp/grent.c
new file mode 100644 (file)
index 0000000..19d618b
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * grent.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * setgrent(), endgrent(), and getgrent() are mutually-dependent functions,
+ * so they are all included in the same object file, and thus all linked
+ * in together.
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <grp.h>
+
+static int grp_fd=-1;
+
+void
+setgrent(void)
+{
+  if (grp_fd!=-1)
+    close(grp_fd);
+  grp_fd=open("/etc/group", O_RDONLY);
+}
+
+void
+endgrent(void)
+{
+ if (grp_fd!=-1)
+   close(grp_fd);
+ grp_fd=-1;
+}
+
+struct group *
+getgrent(void)
+{
+  if (grp_fd==-1)
+    return NULL;
+  return __getgrent(grp_fd);
+}
+
+
diff --git a/libc/pwd_grp/initgroups.c b/libc/pwd_grp/initgroups.c
new file mode 100644 (file)
index 0000000..35e1d03
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * initgroups.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <grp.h>
+#include "config.h"
+
+int
+initgroups(__const char * user, gid_t gid)
+{
+  register struct group * group;
+#ifndef GR_DYNAMIC_GROUP_LIST
+  gid_t group_list[GR_MAX_GROUPS];
+#else
+  gid_t * group_list=NULL;
+#endif
+  register char ** tmp_mem;
+  int num_groups;
+  int grp_fd;
+
+
+  if ((grp_fd=open("/etc/group", O_RDONLY))<0)
+    return -1;
+
+  num_groups=0;
+#ifdef GR_DYNAMIC_GROUP_LIST
+  group_list=(gid_t *) realloc(group_list, 1);
+#endif
+  group_list[num_groups]=gid;
+#ifndef GR_DYNAMIC_GROUP_LIST
+  while (num_groups<GR_MAX_GROUPS &&
+        (group=__getgrent(grp_fd))!=NULL)
+#else
+  while ((group=__getgrent(grp_fd))!=NULL)
+#endif      
+    {
+      if (group->gr_gid!=gid);
+        {
+         tmp_mem=group->gr_mem;
+         while(*tmp_mem!=NULL)
+           {
+             if (!strcmp(*tmp_mem, user))
+               {
+                 num_groups++;
+#ifdef GR_DYNAMIC_GROUP_LIST  
+                 group_list=(gid_t *)realloc(group_list,
+                                             num_groups*sizeof(gid_t *));
+#endif           
+                 group_list[num_groups]=group->gr_gid;
+               }
+             tmp_mem++;
+           }
+       }
+    }
+  close(grp_fd);
+  return setgroups(num_groups, group_list);
+}
+
+
+
+
diff --git a/libc/pwd_grp/putpwent.c b/libc/pwd_grp/putpwent.c
new file mode 100644 (file)
index 0000000..a0035ea
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * putpwent.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <pwd.h>
+
+int
+putpwent(const struct passwd * passwd, FILE * f)
+{
+  if (passwd == NULL || f == NULL)
+    {
+      errno=EINVAL;
+      return -1;
+    }
+  if (fprintf(f, "%s:%s:%u:%u:%s:%s:%s\n", passwd->pw_name, passwd->pw_passwd,
+         passwd->pw_gid, passwd->pw_uid, passwd->pw_gecos,
+         passwd->pw_dir, passwd->pw_shell)<0)
+      return -1;
+
+  return 0;
+}
diff --git a/libc/pwd_grp/pwent.c b/libc/pwd_grp/pwent.c
new file mode 100644 (file)
index 0000000..fd65db2
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * pwent.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <pwd.h>
+#include <fcntl.h>
+
+/*
+ * setpwent(), endpwent(), and getpwent() are included in the same object
+ * file, since one cannot be used without the other two, so it makes sense to
+ * link them all in together.
+ */
+
+/* file descriptor for the password file currently open */
+static int pw_fd = -1;
+
+void
+setpwent(void)
+{
+  if (pw_fd!=-1)
+    close(pw_fd);
+
+  pw_fd=open("/etc/passwd", O_RDONLY);
+}
+
+void
+endpwent(void)
+{
+  if (pw_fd!=-1)
+    close(pw_fd);
+  pw_fd=-1;
+}
+
+struct passwd *
+getpwent(void)
+{
+  if (pw_fd!=-1)
+    return __getpwent(pw_fd);
+  return NULL;  
+}
+
+
diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile
new file mode 100644 (file)
index 0000000..badf78c
--- /dev/null
@@ -0,0 +1,53 @@
+# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+# This file is part of the Linux-8086 C library and is distributed
+# under the GNU Library General Public License.
+
+LIBC=../libc.a
+
+CC=m68k-pic-coff-gcc
+AR=m68k-pic-coff-ar
+RANLIB=m68k-pic-coff-ranlib
+
+CCFLAGS= -O2 -m68000 -msoft-float -I../include
+
+ASRC=stdio.c
+AOBJ=_stdio_init.o fputc.o fgetc.o fflush.o fgets.o gets.o fputs.o     \
+     puts.o fread.o fwrite.o fopen.o fclose.o fseek.o rewind.o ftell.o \
+     setbuffer.o setvbuf.o ungetc.o
+
+PSRC=printf.c
+POBJ=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o
+
+SSRC=scanf.c
+SOBJ=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o
+
+OBJ= $(AOBJ) $(POBJ) $(SOBJ) dputs.o
+
+CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
+
+all: $(LIBC)
+       @$(RM) $(OBJ)
+
+$(LIBC): $(LIBC)($(OBJ))
+
+$(LIBC)($(AOBJ)): $(ASRC)
+       $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+       $(AR) $(ARFLAGS) $@ $*.o
+
+$(LIBC)($(POBJ)): $(PSRC)
+       $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+       $(AR) $(ARFLAGS) $@ $*.o
+
+$(LIBC)($(SOBJ)): $(SSRC)
+       $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+       $(AR) $(ARFLAGS) $@ $*.o
+
+transfer:
+       -@rm -f ../include/stdio.h
+       cp -p stdio.h ../include/.
+
+clean:
+       rm -f *.o libc.a
+
+$(LIBC)($(OBJ)): stdio.h
+
diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c
new file mode 100644 (file)
index 0000000..873f1cb
--- /dev/null
@@ -0,0 +1,387 @@
+/*
+ * This file based on printf.c from 'Dlibs' on the atari ST  (RdeBath)
+ *
+ * 
+ *    Dale Schumacher                         399 Beacon Ave.
+ *    (alias: Dalnefre')                      St. Paul, MN  55104
+ *    dal@syntel.UUCP                         United States of America
+ *  "It's not reality that's important, but how you perceive things."
+ */
+
+/* Altered to use stdarg, made the core function vfprintf.
+ * Hooked into the stdio package using 'inside information'
+ * Altered sizeof() assumptions, now assumes all integers except chars
+ * will be either
+ *  sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short)
+ *
+ * -RDB
+ */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef __STDC__
+#include <stdarg.h>
+#define va_strt      va_start
+#else
+#include <varargs.h>
+#define va_strt(p,i) va_start(p)
+#endif
+
+#include "stdio.h"
+
+#ifdef L_printf
+
+#ifdef __STDC__
+int printf(const char * fmt, ...)
+#else
+int printf(fmt, va_alist)
+__const char *fmt;
+va_dcl
+#endif
+{
+  va_list ptr;
+  int rv;
+
+  va_strt(ptr, fmt);
+  rv = vfprintf(stdout,fmt,ptr);
+  va_end(ptr);
+  return rv;
+}
+#endif
+
+#ifdef L_sprintf
+#ifdef __STDC__
+int sprintf(char * sp, const char * fmt, ...)
+#else
+int sprintf(sp, fmt, va_alist)
+char * sp;
+__const char *fmt;
+va_dcl
+#endif
+{
+static FILE  string[1] =
+{
+   {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1,
+    _IOFBF | __MODE_WRITE}
+};
+
+  va_list ptr;
+  int rv;
+  va_strt(ptr, fmt);
+  string->bufpos = sp;
+  rv = vfprintf(string,fmt,ptr);
+  va_end(ptr);
+  *(string->bufpos) = 0;
+  return rv;
+}
+#endif
+
+#ifdef L_fprintf
+#ifdef __STDC__
+int fprintf(FILE * fp, const char * fmt, ...)
+#else
+int fprintf(fp, fmt, va_alist)
+FILE * fp;
+__const char *fmt;
+va_dcl
+#endif
+{
+  va_list ptr;
+  int rv;
+  va_strt(ptr, fmt);
+  rv = vfprintf(fp,fmt,ptr);
+  va_end(ptr);
+  return rv;
+}
+#endif
+
+#ifdef L_vprintf
+int vprintf(fmt, ap)
+__const char *fmt;
+va_list ap;
+{
+  return vfprintf(stdout,fmt,ap);
+}
+#endif
+
+#ifdef L_vsprintf
+int vsprintf(sp, fmt, ap)
+char * sp;
+__const char *fmt;
+va_list ap;
+{
+static FILE  string[1] =
+{
+   {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1,
+    _IOFBF | __MODE_WRITE}
+};
+
+  int rv;
+  string->bufpos = sp;
+  rv = vfprintf(string,fmt,ap);
+  *(string->bufpos) = 0;
+  return rv;
+}
+#endif
+
+#ifdef L_vfprintf
+
+#if FLOATS
+int _vfprintf_fp_ref = 1;
+#else
+int _vfprintf_fp_ref = 0;
+#endif
+
+static int
+prtfld(op, buf, ljustf, sign, pad, width, preci, buffer_mode)
+register FILE *op;
+register unsigned char *buf;
+int   ljustf;
+register char sign;
+char  pad;
+register int width;
+int   preci;
+int   buffer_mode;
+/*
+ * Output the given field in the manner specified by the arguments. Return
+ * the number of characters output.
+ */
+{
+   register int cnt = 0, len;
+   register unsigned char ch;
+
+   len = strlen(buf);
+
+   if (*buf == '-')
+      sign = *buf++;
+   else if (sign)
+      len++;
+
+   if ((preci != -1) && (len > preci)) /* limit max data width */
+      len = preci;
+
+   if (width < len)            /* flexible field width or width overflow */
+      width = len;
+
+   /*
+    * at this point: width = total field width len   = actual data width
+    * (including possible sign character)
+    */
+   cnt = width;
+   width -= len;
+
+   while (width || len)
+   {
+      if (!ljustf && width)    /* left padding */
+      {
+        if (len && sign && (pad == '0'))
+           goto showsign;
+        ch = pad;
+        --width;
+      }
+      else if (len)
+      {
+        if (sign)
+        {
+         showsign:ch = sign;   /* sign */
+           sign = '\0';
+        }
+        else
+           ch = *buf++;        /* main field */
+        --len;
+      }
+      else
+      {
+        ch = pad;              /* right padding */
+        --width;
+      }
+      putc(ch, op);
+      if( ch == '\n' && buffer_mode == _IOLBF ) fflush(op);
+   }
+
+   return (cnt);
+}
+
+int
+vfprintf(op, fmt, ap)
+FILE *op;
+register __const char *fmt;
+register va_list ap;
+{
+   register int i, cnt = 0, ljustf, lval;
+   int   preci, dpoint, width;
+   char  pad, sign, radix, hash;
+   register char *ptmp;
+   char  tmp[64], *ltostr(), *ultostr();
+   int buffer_mode;
+
+   /* This speeds things up a bit for unbuffered */
+   buffer_mode = (op->mode&__MODE_BUF);
+   op->mode &= (~__MODE_BUF);
+
+   while (*fmt)
+   {
+      if (*fmt == '%')
+      {
+         if( buffer_mode == _IONBF ) fflush(op);
+        ljustf = 0;            /* left justify flag */
+        sign = '\0';           /* sign char & status */
+        pad = ' ';             /* justification padding char */
+        width = -1;            /* min field width */
+        dpoint = 0;            /* found decimal point */
+        preci = -1;            /* max data width */
+        radix = 10;            /* number base */
+        ptmp = tmp;            /* pointer to area to print */
+        hash = 0;
+        lval = (sizeof(int)==sizeof(long));    /* long value flaged */
+       fmtnxt:
+        i = 0;
+        for(;;)
+        {
+           ++fmt;
+           if(*fmt < '0' || *fmt > '9' ) break;
+           i = (i * 10) + (*fmt - '0');
+           if (dpoint)
+              preci = i;
+           else if (!i && (pad == ' '))
+           {
+              pad = '0';
+              goto fmtnxt;
+           }
+           else
+              width = i;
+        }
+
+        switch (*fmt)
+        {
+        case '\0':             /* early EOS */
+           --fmt;
+           goto charout;
+
+        case '-':              /* left justification */
+           ljustf = 1;
+           goto fmtnxt;
+
+        case ' ':
+        case '+':              /* leading sign flag */
+           sign = *fmt;
+           goto fmtnxt;
+
+        case '*':              /* parameter width value */
+           i = va_arg(ap, int);
+           if (dpoint)
+              preci = i;
+           else
+              width = i;
+           goto fmtnxt;
+
+        case '.':              /* secondary width field */
+           dpoint = 1;
+           goto fmtnxt;
+
+        case 'l':              /* long data */
+           lval = 1;
+           goto fmtnxt;
+
+        case 'h':              /* short data */
+           lval = 0;
+           goto fmtnxt;
+
+        case 'd':              /* Signed decimal */
+        case 'i':
+           ptmp = ltostr((long) ((lval)
+                        ? va_arg(ap, long)
+                        : va_arg(ap, short)),
+                10, 0);
+           goto printit;
+
+        case 'b':              /* Unsigned binary */
+           radix = 2;
+           goto usproc;
+
+        case 'o':              /* Unsigned octal */
+           radix = 8;
+           goto usproc;
+
+        case 'p':              /* Pointer */
+           lval = (sizeof(char*) == sizeof(long));
+           pad = '0';
+           width = 6;
+           preci = 8;
+           /* fall thru */
+
+        case 'x':              /* Unsigned hexadecimal */
+        case 'X':
+           radix = 16;
+           /* fall thru */
+
+        case 'u':              /* Unsigned decimal */
+         usproc:
+           ptmp = ultostr((unsigned long) ((lval)
+                                  ? va_arg(ap, unsigned long)
+                                  : va_arg(ap, unsigned short)),
+                 radix, (*fmt == 'X') ? 1 : 0);
+           if( hash && radix == 8 ) { width = strlen(ptmp)+1; pad='0'; }
+           goto printit;
+
+        case '#':
+           hash=1;
+           goto fmtnxt;
+
+        case 'c':              /* Character */
+           ptmp[0] = va_arg(ap, int);
+           ptmp[1] = '\0';
+           goto nopad;
+
+        case 's':              /* String */
+           ptmp = va_arg(ap, char*);
+         nopad:
+           sign = '\0';
+           pad = ' ';
+         printit:
+           cnt += prtfld(op, ptmp, ljustf,
+                          sign, pad, width, preci, buffer_mode);
+           break;
+
+#if FLOATS
+        case 'e':              /* float */
+        case 'f':
+        case 'g':
+        case 'E':
+        case 'G':
+        fprintf(stderr, "LIBM:PRINTF");
+           gcvt(va_arg(ap, double), preci, ptmp);
+           preci = -1;
+           goto printit;
+#else
+        case 'e':              /* float */
+        case 'f':
+        case 'g':
+        case 'E':
+        case 'G':
+               fprintf(stderr, "LIBC:PRINTF");
+               exit(-1);
+#endif
+
+        default:               /* unknown character */
+           goto charout;
+        }
+      }
+      else
+      {
+       charout:
+        putc(*fmt, op);        /* normal char out */
+        ++cnt;
+         if( *fmt == '\n' && buffer_mode == _IOLBF ) fflush(op);
+      }
+      ++fmt;
+   }
+   op->mode |= buffer_mode;
+   if( buffer_mode == _IONBF ) fflush(op);
+   if( buffer_mode == _IOLBF ) op->bufwrite = op->bufstart;
+   return (cnt);
+}
+#endif
diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c
new file mode 100644 (file)
index 0000000..7c5f521
--- /dev/null
@@ -0,0 +1,536 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#ifdef __STDC__
+#include <stdarg.h>
+#define va_strt      va_start
+#else
+#include <varargs.h>
+#define va_strt(p,i) va_start(p)
+#endif
+
+#ifdef L_scanf
+#ifdef __STDC__
+int scanf(const char * fmt, ...)
+#else
+int scanf(fmt, va_alist)
+__const char *fmt;
+va_dcl
+#endif
+{
+  va_list ptr;
+  int rv;
+  va_strt(ptr, fmt);
+  rv = vfscanf(stdin,fmt,ptr);
+  va_end(ptr);
+  return rv;
+}
+#endif
+
+#ifdef L_sscanf
+#ifdef __STDC__
+int sscanf(char * sp, const char * fmt, ...)
+#else
+int sscanf(sp, fmt, va_alist)
+char * sp;
+__const char *fmt;
+va_dcl
+#endif
+{
+static FILE  string[1] =
+{
+   {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1,
+    _IOFBF | __MODE_READ}
+};
+
+  va_list ptr;
+  int rv;
+  va_strt(ptr, fmt);
+  string->bufpos = sp;
+  rv = vfscanf(string,fmt,ptr);
+  va_end(ptr);
+  return rv;
+}
+#endif
+
+#ifdef L_fscanf
+#ifdef __STDC__
+int fscanf(FILE * fp, const char * fmt, ...)
+#else
+int fscanf(fp, fmt, va_alist)
+FILE * fp;
+__const char *fmt;
+va_dcl
+#endif
+{
+  va_list ptr;
+  int rv;
+  va_strt(ptr, fmt);
+  rv = vfscanf(fp,fmt,ptr);
+  va_end(ptr);
+  return rv;
+}
+#endif
+
+#ifdef L_vscanf
+int vscanf(fmt, ap)
+__const char *fmt;
+va_list ap;
+{
+  return vfscanf(stdin,fmt,ap);
+}
+#endif
+
+#ifdef L_vsscanf
+int vsscanf(sp, fmt, ap)
+char * sp;
+__const char *fmt;
+{
+static FILE  string[1] =
+{
+   {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1,
+    _IOFBF | __MODE_READ}
+};
+
+  string->bufpos = sp;
+  return vfscanf(string,fmt,ap);
+}
+#endif
+
+#ifdef L_vfscanf
+
+#if FLOATS
+int _vfscanf_fp_ref = 1;
+#else
+int _vfscanf_fp_ref = 0;
+#endif
+
+/* #define     skip()  do{c=getc(fp); if (c<1) goto done;}while(isspace(c))*/
+
+#define        skip()  while(isspace(c)) { if ((c=getc(fp))<1) goto done; }
+
+#if FLOATS
+/* fp scan actions */
+#define F_NADA 0       /* just change state */
+#define F_SIGN 1       /* set sign */
+#define F_ESIGN        2       /* set exponent's sign */
+#define F_INT  3       /* adjust integer part */
+#define F_FRAC 4       /* adjust fraction part */
+#define F_EXP  5       /* adjust exponent part */
+#define F_QUIT 6
+
+#define NSTATE 8
+#define FS_INIT                0       /* initial state */
+#define FS_SIGNED      1       /* saw sign */
+#define FS_DIGS                2       /* saw digits, no . */
+#define FS_DOT         3       /* saw ., no digits */
+#define FS_DD          4       /* saw digits and . */
+#define FS_E           5       /* saw 'e' */
+#define FS_ESIGN       6       /* saw exp's sign */
+#define FS_EDIGS       7       /* saw exp's digits */
+
+#define FC_DIG         0
+#define FC_DOT         1
+#define FC_E           2
+#define FC_SIGN                3
+
+/* given transition,state do what action? */
+int fp_do[][NSTATE] = {
+       {F_INT,F_INT,F_INT,
+        F_FRAC,F_FRAC,
+        F_EXP,F_EXP,F_EXP},    /* see digit */
+       {F_NADA,F_NADA,F_NADA,
+        F_QUIT,F_QUIT,F_QUIT,F_QUIT,F_QUIT},   /* see '.' */
+       {F_QUIT,F_QUIT,
+        F_NADA,F_QUIT,F_NADA,
+        F_QUIT,F_QUIT,F_QUIT}, /* see e/E */
+       {F_SIGN,F_QUIT,F_QUIT,F_QUIT,F_QUIT,
+        F_ESIGN,F_QUIT,F_QUIT},        /* see sign */
+};
+/* given transition,state what is new state? */
+int fp_ns[][NSTATE] = {
+       {FS_DIGS,FS_DIGS,FS_DIGS,
+        FS_DD,FS_DD,
+        FS_EDIGS,FS_EDIGS,FS_EDIGS},   /* see digit */
+       {FS_DOT,FS_DOT,FS_DD,
+        },     /* see '.' */
+       {0,0,
+        FS_E,0,FS_E,
+       },      /* see e/E */
+       {FS_SIGNED,0,0,0,0,
+        FS_ESIGN,0,0}, /* see sign */
+};
+/* which states are valid terminators? */
+int fp_sval[NSTATE] = {
+       0,0,1,0,1,0,0,1
+};
+#endif
+
+int
+vfscanf(fp, fmt, ap)
+register FILE *fp;
+register char *fmt;
+va_list ap;
+
+{
+   register long n;
+   register int c, width, lval, cnt = 0;
+   int   store, neg, base, wide1, endnull, rngflag, c2;
+   register unsigned char *p;
+   unsigned char delim[128], digits[17], *q;
+#if FLOATS
+   long  frac, expo;
+   int   eneg, fraclen, fstate, trans;
+   double fx, fp_scan();
+#endif
+
+   if (!*fmt)
+      return (0);
+
+   c = getc(fp);
+   while (c > 0)
+   {
+      store = 0;
+      if (*fmt == '%')
+      {
+        n = 0;
+        width = -1;
+        wide1 = 1;
+        base = 10;
+        lval = (sizeof(long) == sizeof(int));
+        store = 1;
+        endnull = 1;
+        neg = -1;
+
+        strcpy(delim, "\011\012\013\014\015 ");
+        strcpy(digits, "0123456789ABCDEF");
+
+        if (fmt[1] == '*')
+        {
+           endnull = store = 0;
+           ++fmt;
+        }
+
+        while (isdigit(*++fmt))/* width digit(s) */
+        {
+           if (width == -1)
+              width = 0;
+           wide1 = width = (width * 10) + (*fmt - '0');
+        }
+        --fmt;
+       fmtnxt:
+        ++fmt;
+        switch (tolower(*fmt)) /* tolower() is a MACRO! */
+        {
+        case '*':
+           endnull = store = 0;
+           goto fmtnxt;
+
+        case 'l':              /* long data */
+           lval = 1;
+           goto fmtnxt;
+        case 'h':              /* short data */
+           lval = 0;
+           goto fmtnxt;
+
+        case 'i':              /* any-base numeric */
+           base = 0;
+           goto numfmt;
+
+        case 'b':              /* unsigned binary */
+           base = 2;
+           goto numfmt;
+
+        case 'o':              /* unsigned octal */
+           base = 8;
+           goto numfmt;
+
+        case 'x':              /* unsigned hexadecimal */
+           base = 16;
+           goto numfmt;
+
+        case 'd':              /* SIGNED decimal */
+           neg = 0;
+           /* FALL-THRU */
+
+        case 'u':              /* unsigned decimal */
+         numfmt:skip();
+
+           if (isupper(*fmt))
+              lval = 1;
+
+           if (!base)
+           {
+              base = 10;
+              neg = 0;
+              if (c == '%')
+              {
+                 base = 2;
+                 goto skip1;
+              }
+              else if (c == '0')
+              {
+                 c = getc(fp);
+                 if (c < 1)
+                    goto savnum;
+                 if ((c != 'x')
+                     && (c != 'X'))
+                 {
+                    base = 8;
+                    digits[8] = '\0';
+                    goto zeroin;
+                 }
+                 base = 16;
+                 goto skip1;
+              }
+           }
+
+           if ((neg == 0) && (base == 10)
+               && ((neg = (c == '-')) || (c == '+')))
+           {
+            skip1:
+              c = getc(fp);
+              if (c < 1)
+                 goto done;
+           }
+
+           digits[base] = '\0';
+           p = ((unsigned char *)
+                strchr(digits, toupper(c)));
+
+           if ((!c || !p) && width)
+              goto done;
+
+           while (p && width-- && c)
+           {
+              n = (n * base) + (p - digits);
+              c = getc(fp);
+            zeroin:
+              p = ((unsigned char *)
+                   strchr(digits, toupper(c)));
+           }
+         savnum:
+           if (store)
+           {
+              if (neg == 1)
+                 n = -n;
+              if (lval)
+                 *va_arg(ap, long*) = n;
+              else
+                 *va_arg(ap, short*) = n;
+              ++cnt;
+           }
+           break;
+
+#if FLOATS
+        case 'e':              /* float */
+        case 'f':
+        case 'g':
+           skip();
+           fprintf(stderr,"LIBM:SCANF");
+
+           if (isupper(*fmt))
+              lval = 1;
+
+           fstate = FS_INIT;
+           neg = 0;
+           eneg = 0;
+           n = 0;
+           frac = 0;
+           expo = 0;
+           fraclen = 0;
+
+           while (c && width--)
+           {
+              if (c >= '0' && c <= '9')
+                 trans = FC_DIG;
+              else if (c == '.')
+                 trans = FC_DOT;
+              else if (c == '+' || c == '-')
+                 trans = FC_SIGN;
+              else if (tolower(c) == 'e')
+                 trans = FC_E;
+              else
+                 goto fdone;
+
+              switch (fp_do[trans][fstate])
+              {
+              case F_SIGN:
+                 neg = (c == '-');
+                 break;
+              case F_ESIGN:
+                 eneg = (c == '-');
+                 break;
+              case F_INT:
+                 n = 10 * n + (c - '0');
+                 break;
+              case F_FRAC:
+                 frac = 10 * frac + (c - '0');
+                 fraclen++;
+                 break;
+              case F_EXP:
+                 expo = 10 * expo + (c - '0');
+                 break;
+              case F_QUIT:
+                 goto fdone;
+              }
+              fstate = fp_ns[trans][fstate];
+              c = getc(fp);
+           }
+
+         fdone:
+           if (!fp_sval[fstate])
+              goto done;
+           if (store)
+           {
+              fx = fp_scan(neg, eneg, n, frac, expo, fraclen);
+              if (lval)
+                 *va_arg(ap, double *) = fx;
+              else
+                 *va_arg(ap, float *) = fx;
+              ++cnt;
+           }
+           break;
+#else
+        case 'e':              /* float */
+        case 'f':
+        case 'g':
+               fprintf(stderr, "LIBC:SCANF");
+               exit(-1);
+#endif
+
+        case 'c':              /* character data */
+           width = wide1;
+           lval = endnull = 0;
+           delim[0] = '\0';
+           goto strproc;
+
+        case '[':              /* string w/ delimiter set */
+
+           /* get delimiters */
+           p = delim;
+
+           if (*++fmt == '^')
+           {
+              fmt++;
+              lval = 0;
+           }
+           else
+              lval = 1;
+
+           rngflag = 2;
+           if ((*fmt == ']') || (*fmt == '-'))
+           {
+              *p++ = *fmt++;
+              rngflag = 0;
+           }
+
+           while (*fmt != ']')
+           {
+              if (*fmt == '\0')
+                 goto done;
+              switch (rngflag)
+              {
+              case 1:
+                 c2 = *(p - 2);
+                 if (c2 <= *fmt)
+                 {
+                    p -= 2;
+                    while (c2 < *fmt)
+                       *p++ = c2++;
+                    rngflag = 2;
+                    break;
+                 }
+                 /* fall thru intentional */
+
+              case 0:
+                 rngflag = (*fmt == '-');
+                 break;
+
+              case 2:
+                 rngflag = 0;
+              }
+
+              *p++ = *fmt++;
+           }
+
+           *p = '\0';
+           goto strproc;
+
+        case 's':              /* string data */
+           lval = 0;
+           skip();
+         strproc:
+           /* process string */
+           p = va_arg(ap, unsigned char *);
+
+           /* if the 1st char fails, match fails */
+           if (width)
+           {
+              q = ((unsigned char *)
+                   strchr(delim, c));
+              if ((c < 1) || lval == (q==0))
+              {
+                 if (endnull)
+                    *p = '\0';
+                 goto done;
+              }
+           }
+
+           for (;;)            /* FOREVER */
+           {
+              if (store)
+                 *p++ = c;
+              if (((c = getc(fp)) < 1) ||
+                  (--width == 0))
+                 break;
+
+              q = ((unsigned char *)
+                   strchr(delim, c));
+              if (lval == (q==0))
+                 break;
+           }
+
+           if (store)
+           {
+              if (endnull)
+                 *p = '\0';
+              ++cnt;
+           }
+           break;
+
+        case '\0':             /* early EOS */
+           --fmt;
+           /* FALL THRU */
+
+        default:
+           goto cmatch;
+        }
+      }
+      else if (isspace(*fmt))  /* skip whitespace */
+      {
+        skip();
+      }
+      else
+      {                                /* normal match char */
+       cmatch:
+        if (c != *fmt)
+           break;
+        c = getc(fp);
+      }
+
+      if (!*++fmt)
+        break;
+   }
+
+ done:                         /* end of scan */
+   if ((c == EOF) && (cnt == 0))
+      return (EOF);
+
+   if( c != EOF )
+      ungetc(c, fp);
+   return (cnt);
+}
+
+#endif
diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c
new file mode 100644 (file)
index 0000000..98d0ba3
--- /dev/null
@@ -0,0 +1,925 @@
+/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+/* This is an implementation of the C standard IO package.
+ */
+
+#include <stdio.h>
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <malloc.h>
+#include <errno.h>
+
+#undef STUB_FWRITE
+
+extern FILE *__IO_list;                /* For fflush at exit */
+
+#define FIXED_BUFFERS 2
+struct fixed_buffer {
+       unsigned char data[BUFSIZ];
+       int used;
+};
+
+extern struct fixed_buffer _fixed_buffers[2];
+
+#define Inline_init __io_init_vars()
+
+#ifdef L__stdio_init
+
+#define buferr (stderr->unbuf) /* Stderr is unbuffered */
+
+FILE *__IO_list = 0;           /* For fflush at exit */
+
+#if 0
+static char bufin[BUFSIZ];
+static char bufout[BUFSIZ];
+#ifndef buferr
+static char buferr[BUFSIZ];
+#endif
+
+#else
+static char *bufin;
+static char *bufout;
+#ifndef buferr
+static char *buferr;
+#endif
+#endif
+
+FILE  stdin[1] =
+{
+#if 0
+   {bufin, bufin, bufin, bufin, bufin + sizeof(bufin),
+#else
+   {0, 0, 0, 0, 0,
+#endif
+    0, _IOFBF | __MODE_READ | __MODE_IOTRAN}
+};
+
+FILE  stdout[1] =
+{
+#if 0
+   {bufout, bufout, bufout, bufout, bufout + sizeof(bufout),
+#else
+   {0, 0, 0, 0, 0,
+#endif
+    1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN}
+};
+
+FILE  stderr[1] =
+{
+#if 0
+   {buferr, buferr, buferr, buferr, buferr + sizeof(buferr),
+#else
+   {0, 0, 0, 0, 0,
+#endif
+    2, _IONBF | __MODE_WRITE | __MODE_IOTRAN}
+};
+
+/* Call the stdio initiliser; it's main job it to call atexit */
+
+#define STATIC
+
+STATIC int 
+__stdio_close_all()
+{
+   FILE *fp;
+   fflush(stdout);
+   fflush(stderr);
+   for (fp = __IO_list; fp; fp = fp->next)
+   {
+      fflush(fp);
+      close(fp->fd);
+      /* Note we're not de-allocating the memory */
+      /* There doesn't seem to be much point :-) */
+      fp->fd = -1;
+   }
+}
+
+static int first_time = 0;
+
+struct fixed_buffer _fixed_buffers[2];
+
+
+STATIC void 
+__io_init_vars()
+{
+   if( first_time ) return;
+   first_time = 1;
+
+   stdin->bufpos = bufin = _fixed_buffers[0].data; /*(char *)malloc(BUFSIZ)*/;
+   stdin->bufread =  bufin;
+   stdin->bufwrite = bufin;
+   stdin->bufstart = bufin;
+   stdin->bufend =  bufin + sizeof(bufin);
+   stdin->fd = 0;
+   stdin->mode = _IOFBF | __MODE_READ | __MODE_IOTRAN | __MODE_FREEBUF;
+   
+   _fixed_buffers[0].used = 1;
+
+   stdout->bufpos = bufout = _fixed_buffers[1].data; /*(char *)malloc(BUFSIZ);*/
+   stdout->bufread =  bufout;
+   stdout->bufwrite = bufout;
+   stdout->bufstart = bufout;
+   stdout->bufend =  bufout + sizeof(bufout);
+   stdout->fd = 1;
+   stdout->mode = _IOFBF | __MODE_WRITE | __MODE_IOTRAN | __MODE_FREEBUF;
+   
+   _fixed_buffers[1].used = 1;
+
+#if 0
+   stderr->bufpos = buferr = (char *)malloc(BUFSIZ);
+#else
+   stderr->bufpos = buferr;
+#endif
+   stderr->bufread =  buferr;
+   stderr->bufwrite = buferr;
+   stderr->bufstart = buferr;
+   stderr->bufend =  buferr + sizeof(buferr);
+   stderr->fd = 2;
+   stderr->mode = _IONBF | __MODE_WRITE | __MODE_IOTRAN;
+
+   if (isatty(1))
+      stdout->mode |= _IOLBF;
+   atexit(__stdio_close_all);
+}
+#endif
+
+#ifdef L_fputc
+int
+fputc(ch, fp)
+int   ch;
+FILE *fp;
+{
+   register int v;
+   Inline_init;
+
+   v = fp->mode;
+   /* If last op was a read ... */
+   if ((v & __MODE_READING) && fflush(fp))
+      return EOF;
+
+   /* Can't write or there's been an EOF or error then return EOF */
+   if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE)
+      return EOF;
+
+   /* In MSDOS translation mode */
+#if __MODE_IOTRAN
+   if (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF)
+      return EOF;
+#endif
+
+   /* Buffer is full */
+   if (fp->bufpos >= fp->bufend && fflush(fp))
+      return EOF;
+
+   /* Right! Do it! */
+   *(fp->bufpos++) = ch;
+   fp->mode |= __MODE_WRITING;
+
+   /* Unbuffered or Line buffered and end of line */
+   if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF))
+       && fflush(fp))
+      return EOF;
+
+   /* Can the macro handle this by itself ? */
+   if (v & (__MODE_IOTRAN | _IOLBF | _IONBF))
+      fp->bufwrite = fp->bufstart;     /* Nope */
+   else
+      fp->bufwrite = fp->bufend;       /* Yup */
+
+   /* Correct return val */
+   return (unsigned char) ch;
+}
+#endif
+
+#ifdef L_fgetc
+int
+fgetc(fp)
+FILE *fp;
+{
+   int   ch;
+   Inline_init;
+
+   if (fp->mode & __MODE_WRITING)
+      fflush(fp);
+
+ try_again:
+   /* Can't read or there's been an EOF or error then return EOF */
+   if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ)
+      return EOF;
+
+   /* Nothing in the buffer - fill it up */
+   if (fp->bufpos >= fp->bufread)
+   {
+      fp->bufpos = fp->bufread = fp->bufstart;
+      ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp);
+      if (ch == 0)
+        return EOF;
+      fp->bufread += ch;
+      fp->mode |= __MODE_READING;
+      fp->mode &= ~__MODE_UNGOT;
+   }
+   ch = *(fp->bufpos++);
+
+#if __MODE_IOTRAN
+   /* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */
+   if (ch == '\r' && (fp->mode & __MODE_IOTRAN))
+      goto try_again;
+#endif
+
+   return ch;
+}
+#endif
+
+#ifdef L_fflush
+int
+fflush(fp)
+FILE *fp;
+{
+   int   len, cc, rv=0;
+   char * bstart;
+   if (fp == NULL)             /* On NULL flush the lot. */
+   {
+      if (fflush(stdin))
+        return EOF;
+      if (fflush(stdout))
+        return EOF;
+      if (fflush(stderr))
+        return EOF;
+
+      for (fp = __IO_list; fp; fp = fp->next)
+        if (fflush(fp))
+           return EOF;
+
+      return 0;
+   }
+
+   /* If there's output data pending */
+   if (fp->mode & __MODE_WRITING)
+   {
+      len = fp->bufpos - fp->bufstart;
+
+      if (len)
+      {
+        bstart = fp->bufstart;
+        /*
+         * The loop is so we don't get upset by signals or partial writes.
+         */
+        do
+        {
+           cc = write(fp->fd, bstart, len);
+           if( cc > 0 )
+           {
+              bstart+=cc; len-=cc;
+           }
+        }
+        while ( cc>0 || (cc == -1 && errno == EINTR));
+        /*
+         * If we get here with len!=0 there was an error, exactly what to
+         * do about it is another matter ...
+         *
+         * I'll just clear the buffer.
+         */
+        if (len)
+        {
+           fp->mode |= __MODE_ERR;
+           rv = EOF;
+        }
+      }
+   }
+   /* If there's data in the buffer sychronise the file positions */
+   else if (fp->mode & __MODE_READING)
+   {
+      /* Humm, I think this means sync the file like fpurge() ... */
+      /* Anyway the user isn't supposed to call this function when reading */
+
+      len = fp->bufread - fp->bufpos;  /* Bytes buffered but unread */
+      /* If it's a file, make it good */
+      if (len > 0 && lseek(fp->fd, (long)-len, 1) < 0)
+      {
+        /* Hummm - Not certain here, I don't think this is reported */
+        /*
+         * fp->mode |= __MODE_ERR; return EOF;
+         */
+      }
+   }
+
+   /* All done, no problem */
+   fp->mode &= (~(__MODE_READING|__MODE_WRITING|__MODE_EOF|__MODE_UNGOT));
+   fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart;
+   return rv;
+}
+#endif
+
+#ifdef L_fgets
+/* Nothing special here ... */
+char *
+fgets(s, count, f)
+char *s;
+size_t count;
+FILE *f;
+{
+   char *ret;
+   register size_t i;
+   register int ch;
+
+   ret = s;
+   for (i = count; i > 0; i--)
+   {
+      ch = getc(f);
+      if (ch == EOF)
+      {
+        if (s == ret)
+           return 0;
+        break;
+      }
+      *s++ = (char) ch;
+      if (ch == '\n')
+        break;
+   }
+   *s = 0;
+
+   if (ferror(f))
+      return 0;
+   return ret;
+}
+#endif
+
+#ifdef L_gets
+char *
+gets(str)                      /* BAD function; DON'T use it! */
+char *str;
+{
+   /* Auwlright it will work but of course _your_ program will crash */
+   /* if it's given a too long line */
+   register char *p = str;
+   register int c;
+
+   while (((c = getc(stdin)) != EOF) && (c != '\n'))
+      *p++ = c;
+   *p = '\0';
+   return (((c == EOF) && (p == str)) ? NULL : str);   /* NULL == EOF */
+}
+#endif
+
+#ifdef L_fputs
+int
+fputs(str, fp)
+char *str;
+FILE *fp;
+{
+   register int n = 0;
+   while (*str)
+   {
+      if (putc(*str++, fp) == EOF)
+        return (EOF);
+      ++n;
+   }
+   return (n);
+}
+#endif
+
+#ifdef L_puts
+int
+puts(str)
+char *str;
+{
+   register int n;
+
+   if (((n = fputs(str, stdout)) == EOF)
+       || (putc('\n', stdout) == EOF))
+      return (EOF);
+   return (++n);
+}
+#endif
+
+#ifdef L_fread
+/*
+ * fread will often be used to read in large chunks of data calling read()
+ * directly can be a big win in this case. Beware also fgetc calls this
+ * function to fill the buffer.
+ * 
+ * This ignores __MODE__IOTRAN; probably exactly what you want. (It _is_ what
+ * fgetc wants)
+ */
+int
+fread(buf, size, nelm, fp)
+char *buf;
+int   size;
+int   nelm;
+FILE *fp;
+{
+   int   len, v;
+   unsigned bytes, got = 0;
+   Inline_init;
+
+   v = fp->mode;
+
+   /* Want to do this to bring the file pointer up to date */
+   if (v & __MODE_WRITING)
+      fflush(fp);
+
+   /* Can't read or there's been an EOF or error then return zero */
+   if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ)
+      return 0;
+
+   /* This could be long, doesn't seem much point tho */
+   bytes = size * nelm;
+
+   len = fp->bufread - fp->bufpos;
+   if (len >= bytes)           /* Enough buffered */
+   {
+      memcpy(buf, fp->bufpos, (unsigned) bytes);
+      fp->bufpos += bytes;
+      return bytes;
+   }
+   else if (len > 0)           /* Some buffered */
+   {
+      memcpy(buf, fp->bufpos, len);
+      got = len;
+   }
+
+   /* Need more; do it with a direct read */
+   len = read(fp->fd, buf + got, (unsigned) (bytes - got));
+
+   /* Possibly for now _or_ later */
+   if (len < 0)
+   {
+      fp->mode |= __MODE_ERR;
+      len = 0;
+   }
+   else if (len == 0)
+      fp->mode |= __MODE_EOF;
+
+   return (got + len) / size;
+}
+#endif
+
+#ifdef L_fwrite
+/*
+ * Like fread, fwrite will often be used to write out large chunks of
+ * data; calling write() directly can be a big win in this case.
+ * 
+ * But first we check to see if there's space in the buffer.
+ * 
+ * Again this ignores __MODE__IOTRAN.
+ */
+int
+fwrite(buf, size, nelm, fp)
+char *buf;
+int   size;
+int   nelm;
+FILE *fp;
+{
+   register int v;
+   int   len;
+   unsigned bytes, put;
+
+#ifdef STUB_FWRITE
+       bytes = size * nelm;
+       while(bytes>0) {
+               len=write(fp->fd, buf, bytes);
+               if (len<=0) {
+                       break;
+               }
+               bytes -= len;
+               buf += len;
+       }
+       return nelm;
+#else
+               
+   v = fp->mode;
+   /* If last op was a read ... */
+   if ((v & __MODE_READING) && fflush(fp))
+      return 0;
+
+   /* Can't write or there's been an EOF or error then return 0 */
+   if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE)
+      return 0;
+
+   /* This could be long, doesn't seem much point tho */
+   bytes = size * nelm;
+
+   len = fp->bufend - fp->bufpos;
+
+   /* Flush the buffer if not enough room */
+   if (bytes > len)
+      if (fflush(fp))
+        return 0;
+
+   len = fp->bufend - fp->bufpos;
+   if (bytes <= len)           /* It'll fit in the buffer ? */
+   {
+      fp->mode |= __MODE_WRITING;
+      memcpy(fp->bufpos, buf, bytes);
+      fp->bufpos += bytes;
+
+      /* If we're not fully buffered */
+      if (v & (_IOLBF | _IONBF))
+        fflush(fp);
+
+      return nelm;
+   }
+   else
+      /* Too big for the buffer */
+   {
+      put = bytes;
+      do
+      {
+         len = write(fp->fd, buf, bytes);
+        if( len > 0 )
+        {
+           buf+=len; bytes-=len;
+        }
+      }
+      while (len > 0 || (len == -1 && errno == EINTR));
+
+      if (len < 0)
+        fp->mode |= __MODE_ERR;
+
+      put -= bytes;
+   }
+
+   return put / size;
+#endif
+}
+#endif
+
+#ifdef L_rewind
+void
+rewind(fp)
+FILE * fp;
+{
+   fseek(fp, (long)0, 0);
+   clearerr(fp);
+}
+#endif
+
+#ifdef L_fseek
+int
+fseek(fp, offset, ref)
+FILE *fp;
+long  offset;
+int   ref;
+{
+#if 0 
+   /* FIXME: this is broken!  BROKEN!!!! */
+   /* if __MODE_READING and no ungetc ever done can just move pointer */
+   /* This needs testing! */
+
+   if ( (fp->mode &(__MODE_READING | __MODE_UNGOT)) == __MODE_READING && 
+        ( ref == SEEK_SET || ref == SEEK_CUR ))
+   {
+      long fpos = lseek(fp->fd, 0L, SEEK_CUR);
+      if( fpos == -1 ) return EOF;
+
+      if( ref == SEEK_CUR )
+      {
+         ref = SEEK_SET;
+        offset = fpos + offset + fp->bufpos - fp->bufread;
+      }
+      if( ref == SEEK_SET )
+      {
+         if ( offset < fpos && offset >= fpos + fp->bufstart - fp->bufread )
+        {
+           fp->bufpos = offset - fpos + fp->bufread;
+           return 0;
+        }
+      }
+   }
+#endif
+
+   /* Use fflush to sync the pointers */
+
+   if (fflush(fp) == EOF)
+      return EOF;
+   if (lseek(fp->fd, offset, ref) < 0)
+      return EOF;
+   return 0;
+}
+#endif
+
+#ifdef L_ftell
+long ftell(fp)
+FILE * fp;
+{
+   long rv;
+   if (fflush(fp) == EOF)
+      return EOF;
+   return lseek(fp->fd, 0L, SEEK_CUR);
+}
+#endif
+
+#ifdef L_fopen
+/*
+ * This Fopen is all three of fopen, fdopen and freopen. The macros in
+ * stdio.h show the other names.
+ */
+FILE *
+__fopen(fname, fd, fp, mode)
+char *fname;
+int   fd;
+FILE *fp;
+char *mode;
+{
+   int   open_mode = 0;
+#if __MODE_IOTRAN
+   int  do_iosense = 1;
+#endif
+   int   fopen_mode = 0;
+   FILE *nfp = 0;
+
+   /* If we've got an fp close the old one (freopen) */
+   if (fp)
+   {
+      /* Careful, don't de-allocate it */
+      fopen_mode |= (fp->mode & (__MODE_BUF | __MODE_FREEFIL | __MODE_FREEBUF));
+      fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF);
+      fclose(fp);
+   }
+
+   /* decode the new open mode */
+   while (*mode)
+      switch (*mode++)
+      {
+      case 'r':
+        fopen_mode |= __MODE_READ;
+        break;
+      case 'w':
+        fopen_mode |= __MODE_WRITE;
+        open_mode = (O_CREAT | O_TRUNC);
+        break;
+      case 'a':
+        fopen_mode |= __MODE_WRITE;
+        open_mode = (O_CREAT | O_APPEND);
+        break;
+      case '+':
+        fopen_mode |= __MODE_RDWR;
+        break;
+#if __MODE_IOTRAN
+      case 'b':                /* Binary */
+        fopen_mode &= ~__MODE_IOTRAN;
+        do_iosense=0;
+        break;
+      case 't':                /* Text */
+        fopen_mode |= __MODE_IOTRAN;
+        do_iosense=0;
+        break;
+#endif
+      }
+
+   /* Add in the read/write options to mode for open() */
+   switch (fopen_mode & (__MODE_READ | __MODE_WRITE))
+   {
+   case 0:
+      return 0;
+   case __MODE_READ:
+      open_mode |= O_RDONLY;
+      break;
+   case __MODE_WRITE:
+      open_mode |= O_WRONLY;
+      break;
+   default:
+      open_mode |= O_RDWR;
+      break;
+   }
+
+   /* Allocate the (FILE) before we do anything irreversable */
+   if (fp == 0)
+   {
+      nfp = malloc(sizeof(FILE));
+      if (nfp == 0)
+        return 0;
+   }
+
+   /* Open the file itself */
+   if (fname)
+      fd = open(fname, open_mode, 0666);
+   if (fd < 0)                 /* Grrrr */
+   {
+      if (nfp)
+        free(nfp);
+      return 0;
+   }
+
+   /* If this isn't freopen create a (FILE) and buffer for it */
+   if (fp == 0)
+   {
+      int i;
+      fp = nfp;
+      fp->next = __IO_list;
+      __IO_list = fp;
+
+      fp->mode = __MODE_FREEFIL;
+      if( isatty(fd) )
+      {
+        fp->mode |= _IOLBF;
+#if __MODE_IOTRAN
+        if( do_iosense ) fopen_mode |= __MODE_IOTRAN;
+#endif
+      }
+      else
+        fp->mode |= _IOFBF;
+
+      for(i=0;i<FIXED_BUFFERS;i++)
+         if (!_fixed_buffers[i].used) {
+            fp->bufstart = _fixed_buffers[i].data;
+            _fixed_buffers[i].used = 1;
+            break;
+         }
+
+      if (i == FIXED_BUFFERS)
+         fp->bufstart = malloc(BUFSIZ);
+         
+      if (fp->bufstart == 0)   /* Oops, no mem */
+      {                                /* Humm, full buffering with a two(!) byte
+                                * buffer. */
+        fp->bufstart = fp->unbuf;
+        fp->bufend = fp->unbuf + sizeof(fp->unbuf);
+      }
+      else
+      {
+        fp->bufend = fp->bufstart + BUFSIZ;
+        fp->mode |= __MODE_FREEBUF;
+      }
+   }
+   /* Ok, file's ready clear the buffer and save important bits */
+   fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart;
+   fp->mode |= fopen_mode;
+   fp->fd = fd;
+   return fp;
+}
+#endif
+
+#ifdef L_fclose
+int
+fclose(fp)
+FILE *fp;
+{
+   int   rv = 0;
+
+   if (fp == 0)
+   {
+      errno = EINVAL;
+      return EOF;
+   }
+   if (fflush(fp))
+      return EOF;
+
+   if (close(fp->fd))
+      rv = EOF;
+   fp->fd = -1;
+
+   if (fp->mode & __MODE_FREEBUF)
+   {
+      int i;
+      for(i=0;i<FIXED_BUFFERS;i++)
+         if (fp->bufstart == _fixed_buffers[i].data) {
+           _fixed_buffers[i].used = 0;
+           break;
+         }
+      if(i==FIXED_BUFFERS)
+         free(fp->bufstart);
+      fp->mode &= ~__MODE_FREEBUF;
+      fp->bufstart = fp->bufend = 0;
+   }
+
+   if (fp->mode & __MODE_FREEFIL)
+   {
+      FILE *prev = 0, *ptr;
+      fp->mode = 0;
+
+      for (ptr = __IO_list; ptr && ptr != fp; ptr = ptr->next)
+        ;
+      if (ptr == fp)
+      {
+        if (prev == 0)
+           __IO_list = fp->next;
+        else
+           prev->next = fp->next;
+      }
+      free(fp);
+   }
+   else
+      fp->mode = 0;
+
+   return rv;
+}
+#endif
+
+#ifdef L_setbuffer
+void
+setbuffer(fp, buf, size)
+FILE * fp;
+char * buf;
+int size;
+{
+   fflush(fp);
+   
+   if ((fp->bufstart == (unsigned char*)buf) && (fp->bufend == ((unsigned char*)buf + size)))
+      return;
+   
+   if( fp->mode & __MODE_FREEBUF ) {
+      int i;
+      for(i=0;i<FIXED_BUFFERS;i++)
+         if (fp->bufstart == _fixed_buffers[i].data) {
+           _fixed_buffers[i].used = 0;
+           break;
+         }
+      if(i==FIXED_BUFFERS)
+         free(fp->bufstart);
+   }
+   fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF);
+
+   if( buf == 0 )
+   {
+      fp->bufstart = fp->unbuf;
+      fp->bufend = fp->unbuf + sizeof(fp->unbuf);
+      fp->mode |= _IONBF;
+   }
+   else
+   {
+      fp->bufstart = buf;
+      fp->bufend = buf+size;
+      fp->mode |= _IOFBF;
+   }
+   fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart;
+}
+#endif
+
+#ifdef L_setvbuf
+int setvbuf(fp, buf, mode, size)
+FILE * fp;
+char * buf;
+int mode;
+size_t size;
+{
+   fflush(fp);
+   if( fp->mode & __MODE_FREEBUF ) {
+      int i;
+      for(i=0;i<FIXED_BUFFERS;i++)
+         if (fp->bufstart == _fixed_buffers[i].data) {
+           _fixed_buffers[i].used = 0;
+           break;
+         }
+      if(i==FIXED_BUFFERS)
+         free(fp->bufstart);
+   }
+   fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF);
+   fp->bufstart = fp->unbuf;
+   fp->bufend = fp->unbuf + sizeof(fp->unbuf);
+   fp->mode |= _IONBF;
+
+   if( mode == _IOFBF || mode == _IOLBF )
+   {
+      if( size <= 0  ) size = BUFSIZ;
+      if( buf == 0 )
+         if (size == BUFSIZ) {
+            int i;
+            for(i=0;i<FIXED_BUFFERS;i++)
+               if (!_fixed_buffers[i].used) {
+                 _fixed_buffers[i].used = 1;
+                 buf = _fixed_buffers[i].data;
+                 break;
+               }
+            if(i==FIXED_BUFFERS)
+               buf = malloc(size);
+         } else
+            buf = malloc(size);
+      if( buf == 0 ) return EOF;
+
+      fp->bufstart = buf;
+      fp->bufend = buf+size;
+      fp->mode |= mode;
+   }
+   fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart;
+}
+#endif
+
+#ifdef L_ungetc
+int
+ungetc(c, fp)
+int c;
+FILE *fp;
+{
+   if (fp->mode & __MODE_WRITING)
+      fflush(fp);
+
+   /* Can't read or there's been an error then return EOF */
+   if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ)
+      return EOF;
+
+   /* Can't do fast fseeks */
+   fp->mode |= __MODE_UNGOT;
+
+   if( fp->bufpos > fp->bufstart )
+      return *--fp->bufpos = (unsigned char) c;
+   else if( fp->bufread == fp->bufstart )
+      return *fp->bufread++ = (unsigned char) c;
+   else
+      return EOF;
+}
+#endif
diff --git a/libc/stdlib/Makefile b/libc/stdlib/Makefile
new file mode 100644 (file)
index 0000000..da8053f
--- /dev/null
@@ -0,0 +1,64 @@
+# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+# This file is part of the Linux-8086 C library and is distributed
+# under the GNU Library General Public License.
+
+LIBC=../libc.a
+
+CC=m68k-pic-coff-gcc
+AR=m68k-pic-coff-ar
+RANLIB=m68k-pic-coff-ranlib
+
+CCFLAGS= -O2 -m68000 -msoft-float -fno-builtin -I../include
+
+MSRC=aliases.c
+MOBJ=abs.o remove.o creat.o bcopy.o bzero.o
+# raise.o bcmp.o index.o rindex.o 
+
+
+ESRC=atexit.c
+EOBJ=on_exit.o atexit.o __do_exit.o exit.o
+
+GOBJ=atoi.o atol.o ltoa.o ltostr.o \
+     ctype.o qsort.o bsearch.o rand.o lsearch.o getopt.o \
+     itoa.o strtol.o crypt.o sleep.o mkstemp.o mktemp.o
+
+UOBJ=getenv.o putenv.o popen.o system.o getcwd.o setenv.o \
+     execl.o execv.o execlp.o execvp.o execvep.o
+
+
+OBJ=$(MOBJ) $(EOBJ) $(GOBJ) $(UOBJ)
+
+## No ELKS strtod() until BCC does 16 bit FP...
+#ifneq ($(LIB_CPU),i86)
+#OBJ+=strtod.o
+#endif
+
+CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
+
+all: $(LIBC)
+       @$(RM) $(OBJ)
+
+$(LIBC): $(LIBC)($(OBJ))
+
+$(LIBC)($(MOBJ)): $(MSRC)
+       $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+       $(AR) $(ARFLAGS) $@ $*.o
+
+$(LIBC)($(EOBJ)): $(ESRC)
+       $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+       $(AR) $(ARFLAGS) $@ $*.o
+
+clean:
+       rm -f *.o libc.a
+
+$(LIBC)(strtol.o): strtol.c
+       $(CC) -c -ansi $(ARCH) $(CCFLAGS) $(DEFS) $*.c
+       $(AR) $(ARFLAGS) $@ $*.o
+
+$(LIBC)(strtod.o): strtod.c
+       $(CC) -c -ansi $(ARCH) $(CCFLAGS) $(DEFS) $*.c
+       $(AR) $(ARFLAGS) $@ $*.o
+
+$(LIBC)(crypt.o): crypt.c
+       $(CC) -c -ansi $(ARCH) $(CCFLAGS) $(DEFS) $*.c
+       $(AR) $(ARFLAGS) $@ $*.o
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
new file mode 100644 (file)
index 0000000..2a82c6e
--- /dev/null
@@ -0,0 +1,117 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+/*
+ * This deals with both the atexit and on_exit function calls
+ * 
+ * Note calls installed with atexit are called with the same args as on_exit
+ * fuctions; the void* is given the NULL value.
+ * 
+ */
+
+#include <errno.h>
+
+/* ATEXIT.H */
+#define MAXONEXIT 20           /* AIUI Posix requires 10 */
+
+typedef void (*vfuncp) ();
+
+extern vfuncp __cleanup;
+extern void __do_exit();
+
+extern struct exit_table
+{
+   vfuncp called;
+   void *argument;
+}
+__on_exit_table[MAXONEXIT];
+
+extern int __on_exit_count;
+
+/* End ATEXIT.H */
+
+#ifdef L_atexit
+vfuncp __cleanup;
+
+int
+atexit(ptr)
+vfuncp ptr;
+{
+   if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT)
+   {
+      errno = ENOMEM;
+      return -1;
+   }
+   __cleanup = __do_exit;
+   if( ptr )
+   {
+      __on_exit_table[__on_exit_count].called = ptr;
+      __on_exit_table[__on_exit_count].argument = 0;
+      __on_exit_count++;
+   }
+   return 0;
+}
+
+#endif
+
+#ifdef L_on_exit
+int
+on_exit(ptr, arg)
+vfuncp ptr;
+void *arg;
+{
+   if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT)
+   {
+      errno = ENOMEM;
+      return -1;
+   }
+   __cleanup = __do_exit;
+   if( ptr )
+   {
+      __on_exit_table[__on_exit_count].called = ptr;
+      __on_exit_table[__on_exit_count].argument = arg;
+      __on_exit_count++;
+   }
+   return 0;
+}
+
+#endif
+
+#ifdef L___do_exit
+
+int   __on_exit_count = 0;
+struct exit_table __on_exit_table[MAXONEXIT];
+
+void
+__do_exit(rv)
+int   rv;
+{
+   register int   count = __on_exit_count-1;
+   register vfuncp ptr;
+   __on_exit_count = -1;               /* ensure no more will be added */
+   __cleanup = 0;                      /* Calling exit won't re-do this */
+
+   /* In reverse order */
+   for (; count >= 0; count--)
+   {
+      ptr = __on_exit_table[count].called;
+      (*ptr) (rv, __on_exit_table[count].argument);
+   }
+}
+
+#endif
+
+#ifdef L_exit
+
+void
+exit(rv)
+int    rv;
+{
+   if (__cleanup)
+      __cleanup();
+   _exit(rv);
+}
+
+#endif
diff --git a/libc/stdlib/bsearch.c b/libc/stdlib/bsearch.c
new file mode 100644 (file)
index 0000000..9898667
--- /dev/null
@@ -0,0 +1,46 @@
+
+/*
+ * This file lifted in toto from 'Dlibs' on the atari ST  (RdeBath)
+ *
+ * 
+ *    Dale Schumacher                         399 Beacon Ave.
+ *    (alias: Dalnefre')                      St. Paul, MN  55104
+ *    dal@syntel.UUCP                         United States of America
+ *  "It's not reality that's important, but how you perceive things."
+ */
+#include <stdio.h>
+
+static int _bsearch;           /* index of element found, or where to
+                                * insert */
+
+char *
+bsearch(key, base, num, size, cmp)
+register char *key;            /* item to search for */
+register char *base;           /* base address */
+int   num;                     /* number of elements */
+register int size;             /* element size in bytes */
+register int (*cmp) ();                /* comparison function */
+{
+   register int a, b, c, dir;
+
+   a = 0;
+   b = num - 1;
+   while (a <= b)
+   {
+      c = (a + b) >> 1;                /* == ((a + b) / 2) */
+      if (dir = (*cmp) ((base + (c * size)), key))
+      {
+        if (dir > 0)
+           b = c - 1;
+        else                   /* (dir < 0) */
+           a = c + 1;
+      }
+      else
+      {
+        _bsearch = c;
+        return (base + (c * size));
+      }
+   }
+   _bsearch = b;
+   return (NULL);
+}
diff --git a/libc/stdlib/getenv.c b/libc/stdlib/getenv.c
new file mode 100644 (file)
index 0000000..1ed83a6
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+
+extern char ** environ;
+
+char *
+getenv(var)
+const char * var;
+{
+   char **p;
+   int len;
+
+   len = strlen(var);
+   
+   if (!environ)
+      return 0;
+
+   for(p=environ; *p; p++)
+   {
+      if( memcmp(var, *p, len) == 0 && (*p)[len] == '=' )
+         return *p + len + 1;
+   }
+   return 0;
+}
+
+
diff --git a/libc/stdlib/malloc/Makefile b/libc/stdlib/malloc/Makefile
new file mode 100644 (file)
index 0000000..36872c3
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk>
+# This file is part of the Linux-8086 C library and is distributed
+# under the GNU Library General Public License.
+
+LIBC=../libc.a
+
+CC=m68k-pic-coff-gcc
+AR=m68k-pic-coff-ar
+RANLIB=m68k-pic-coff-ranlib
+
+CCFLAGS= -O2 -m68000 -msoft-float -I../include
+
+
+MSRC=alloc.c
+MOBJ=malloc.o free.o calloc.o malloc_dbg.o free_dbg.o calloc_dbg.o
+
+OBJ=$(MOBJ)
+
+CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
+
+all: $(LIBC)
+       @$(RM) $(OBJ)
+
+$(LIBC): $(LIBC)($(OBJ))
+
+$(LIBC)($(MOBJ)): $(MSRC)
+       $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+       $(AR) $(ARFLAGS) $@ $*.o
+
+clean:
+       rm -f *.o libc.a
+
+
diff --git a/libc/stdlib/malloc/alloc.c b/libc/stdlib/malloc/alloc.c
new file mode 100644 (file)
index 0000000..b92cb7c
--- /dev/null
@@ -0,0 +1,82 @@
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef L_calloc_dbg
+
+void *
+calloc_dbg(size_t num, size_t size, char * function, char * file, int line)
+{
+       void * ptr;
+       fprintf(stderr, "calloc of %d bytes at %s @%s:%d = ", num*size, function, file, line);
+       ptr = calloc(num,size);
+       fprtinf(stderr, "%p\n", ptr);
+       return ptr;
+}
+
+#endif
+
+#ifdef L_malloc_dbg
+
+void *
+malloc_dbg(size_t len, char * function, char * file, int line)
+{
+       void * result;
+       fprintf(stderr, "malloc of %d bytes at %s @%s:%d = ", len, function, file, line);
+       result = malloc(len);
+       fprintf(stderr, "%p\n", result);    
+       return result;
+}
+
+#endif
+
+#ifdef L_free_dbg
+
+void
+free_dbg(void * ptr, char * function, char * file, int line)
+{
+       fprintf(stderr, "free of %p at %s @%s:%d\n", ptr, function, file, line);
+       free(ptr);
+}
+
+#endif
+
+
+#ifdef L_calloc
+
+void *
+calloc(size_t num, size_t size)
+{
+       void * ptr = malloc(num*size);
+       if (ptr)
+               memset(ptr, 0, num*size);
+       return ptr;
+}
+
+#endif
+
+#ifdef L_malloc
+
+void *
+malloc(size_t len)
+{
+  void * result = mmap((void *)0, len, PROT_READ | PROT_WRITE,
+                 MAP_SHARED | MAP_ANONYMOUS, 0, 0);
+  if (result == (void*)-1)
+    return 0;
+    
+  return result;
+}
+
+#endif
+
+#ifdef L_free
+
+void
+free(void * ptr)
+{
+  munmap(ptr, 0);
+}
+
+#endif
diff --git a/libc/stdlib/mkstemp.c b/libc/stdlib/mkstemp.c
new file mode 100644 (file)
index 0000000..d65ada4
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <features.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+int mkstemp(template)
+char * template;
+{
+       int i;
+       int num; /* UNINITIALIZED */
+       int n2;
+       int l = strlen(template);
+       
+       if (l<6) {
+               errno = EINVAL;
+               return -1;
+       }
+       
+       for(i=l-6;i<l;i++)
+               if (template[i] != 'X') {
+                       errno = EINVAL;
+                       return -1;
+               }
+       
+again: 
+       n2 = num;
+       for(i=l-1;i>=l-6;i--) {
+               template[i] = '0' + n2 % 10;
+               n2 /= 10;
+       }
+       
+       i = open(template, O_RDWR|O_EXCL|O_CREAT, 0666);
+       
+       if (i==-1) {
+               if (errno == EEXIST) {
+                       num++;
+                       goto again;
+               } else
+                       return -1;
+       }
+       
+       return i;
+}
diff --git a/libc/stdlib/mktemp.c b/libc/stdlib/mktemp.c
new file mode 100644 (file)
index 0000000..08b3567
--- /dev/null
@@ -0,0 +1,40 @@
+
+#include <features.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+char * mktemp(template)
+char * template;
+{
+       int i;
+       int num; /* UNINITIALIZED */
+       int n2;
+       int l = strlen(template);
+       struct stat stbuf;
+       
+       if (l<6) {
+               errno = EINVAL;
+               return 0;
+       }
+       
+       for(i=l-6;i<l;i++)
+               if (template[i] != 'X') {
+                       errno = EINVAL;
+                       return 0;
+               }
+       
+again: 
+       n2 = num;
+       for(i=l-1;i>=l-6;i--) {
+               template[i] = '0' + n2 % 10;
+               n2 /= 10;
+       }
+       
+       if (stat(template, &stbuf) == 0) {
+               num++;
+               goto again;
+       }
+       
+       return template;
+}
diff --git a/libc/stdlib/putenv.c b/libc/stdlib/putenv.c
new file mode 100644 (file)
index 0000000..a7a453d
--- /dev/null
@@ -0,0 +1,62 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+
+extern char ** environ;
+#define ADD_NUM 4
+
+int
+putenv(var)
+const char * var;
+{
+static char ** mall_env = 0;
+static int extras = 0;
+   char **p, **d;
+   char * r;
+   int len;
+
+   r = strchr(var, '=');
+   if( r == 0 )  len = strlen(var);
+   else          len = r-var;
+
+   if (!environ) {
+       environ = (char**)malloc(ADD_NUM * sizeof(char*));
+       memset(environ, 0, sizeof(char*)*ADD_NUM);
+       extras = ADD_NUM;
+   }
+   
+   for(p=environ; *p; p++)
+   {
+      if( memcmp(var, *p, len) == 0 && (*p)[len] == '=' )
+      {
+         while( p[0] = p[1] ) p++;
+         extras++;
+         break;
+      }
+   }
+   if( r == 0 ) return 0;
+   if( extras <= 0 )   /* Need more space */
+   {
+      d = malloc((p-environ+1+ADD_NUM)*sizeof(char*));
+      if( d == 0 ) return -1;
+
+      memcpy((void*) d, (void*) environ, (p-environ+1)*sizeof(char*));
+      p = d + (p-environ);
+      extras=ADD_NUM;
+
+      if( mall_env ) free(mall_env);
+      environ = d;
+      mall_env = d;
+   }
+   *p++ = strdup((char*)var);
+   *p = '\0';
+   extras--;
+
+   return 0;
+}
+
+
diff --git a/libc/stdlib/qsort.c b/libc/stdlib/qsort.c
new file mode 100644 (file)
index 0000000..cee53c3
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * This file lifted in toto from 'Dlibs' on the atari ST  (RdeBath)
+ *
+ * 
+ *    Dale Schumacher                         399 Beacon Ave.
+ *    (alias: Dalnefre')                      St. Paul, MN  55104
+ *    dal@syntel.UUCP                         United States of America
+ *  "It's not reality that's important, but how you perceive things."
+ */
+#include <string.h>
+
+char *_qbuf = 0;               /* pointer to storage for qsort() */
+
+#define        PIVOT                   ((i+j)>>1)
+#define moveitem(dst,src,size) if(dst != src) memcpy(dst, src, size)
+
+static 
+_wqsort(base, lo, hi, cmp)
+register int *base;
+register int lo;
+register int hi;
+register int (*cmp) ();
+{
+   int   k;
+   register int i, j, t;
+   register int *p = &k;
+
+   while (hi > lo)
+   {
+      i = lo;
+      j = hi;
+      t = PIVOT;
+      *p = base[t];
+      base[t] = base[i];
+      base[i] = *p;
+      while (i < j)
+      {
+        while (((*cmp) ((base + j), p)) > 0)
+           --j;
+        base[i] = base[j];
+        while ((i < j) && (((*cmp) ((base + i), p)) <= 0))
+           ++i;
+        base[j] = base[i];
+      }
+      base[i] = *p;
+      if ((i - lo) < (hi - i))
+      {
+        _wqsort(base, lo, (i - 1), cmp);
+        lo = i + 1;
+      }
+      else
+      {
+        _wqsort(base, (i + 1), hi, cmp);
+        hi = i - 1;
+      }
+   }
+}
+
+static 
+_lqsort(base, lo, hi, cmp)
+register long *base;
+register int lo;
+register int hi;
+register int (*cmp) ();
+{
+   long  k;
+   register int i, j, t;
+   register long *p = &k;
+
+   while (hi > lo)
+   {
+      i = lo;
+      j = hi;
+      t = PIVOT;
+      *p = base[t];
+      base[t] = base[i];
+      base[i] = *p;
+      while (i < j)
+      {
+        while (((*cmp) ((base + j), p)) > 0)
+           --j;
+        base[i] = base[j];
+        while ((i < j) && (((*cmp) ((base + i), p)) <= 0))
+           ++i;
+        base[j] = base[i];
+      }
+      base[i] = *p;
+      if ((i - lo) < (hi - i))
+      {
+        _lqsort(base, lo, (i - 1), cmp);
+        lo = i + 1;
+      }
+      else
+      {
+        _lqsort(base, (i + 1), hi, cmp);
+        hi = i - 1;
+      }
+   }
+}
+
+static 
+_nqsort(base, lo, hi, size, cmp)
+register char *base;
+register int lo;
+register int hi;
+register int size;
+register int (*cmp) ();
+{
+   register int i, j;
+   register char *p = _qbuf;
+
+   while (hi > lo)
+   {
+      i = lo;
+      j = hi;
+      p = (base + size * PIVOT);
+      moveitem(_qbuf, p, size);
+      moveitem(p, (base + size * i), size);
+      moveitem((base + size * i), _qbuf, size);
+      p = _qbuf;
+      while (i < j)
+      {
+        while (((*cmp) ((base + size * j), p)) > 0)
+           --j;
+        moveitem((base + size * i), (base + size * j), size);
+        while ((i < j) && (((*cmp) ((base + size * i), p)) <= 0))
+           ++i;
+        moveitem((base + size * j), (base + size * i), size);
+      }
+      moveitem((base + size * i), p, size);
+      if ((i - lo) < (hi - i))
+      {
+        _nqsort(base, lo, (i - 1), size, cmp);
+        lo = i + 1;
+      }
+      else
+      {
+        _nqsort(base, (i + 1), hi, size, cmp);
+        hi = i - 1;
+      }
+   }
+}
+
+qsort(base, num, size, cmp)
+char *base;
+int   num;
+int   size;
+int   (*cmp) ();
+{
+   char  _qtemp[128];
+
+   if (_qbuf == 0)
+   {
+      if (size > sizeof(_qtemp))/* records too large! */
+        return;
+      _qbuf = _qtemp;
+   }
+   if (size == 2)
+      _wqsort(base, 0, num - 1, cmp);
+   else if (size == 4)
+      _lqsort(base, 0, num - 1, cmp);
+   else
+      _nqsort(base, 0, num - 1, size, cmp);
+   if (_qbuf == _qtemp)
+      _qbuf = 0;
+}
diff --git a/libc/stdlib/rand.c b/libc/stdlib/rand.c
new file mode 100644 (file)
index 0000000..4eb0789
--- /dev/null
@@ -0,0 +1,61 @@
+#ifdef ZX81_RNG
+/*
+ * This is my favorite tiny RNG, If you had a ZX81 you may recognise it :-)
+ *                                                             (RdeBath)
+ */
+
+#include <stdlib.h>
+
+#define MAXINT (((unsigned)-1)>>1)
+
+static unsigned int sseed = 0;
+
+int rand()
+{
+   return ( sseed = (((sseed+1L)*75L)%65537L)-1 ) & MAXINT;
+}
+
+void srand(seed)
+unsigned int seed;
+{
+   sseed=seed;
+}
+
+#else
+
+/*
+ * This generator is a combination of three linear congruential generators
+ * with periods or 2^15-405, 2^15-1041 and 2^15-1111. It has a period that
+ * is the product of these three numbers.
+ */
+
+static int seed1 = 1;
+static int seed2 = 1;
+static int seed3 = 1;
+#define MAXINT (((unsigned)-1)>>1)
+
+#define CRANK(a,b,c,m,s)       \
+       q = s/a;                \
+       s = b*(s-a*q) - c*q;    \
+       if(s<0) s+=m;
+
+int rand()
+{
+   register int q, z;
+   CRANK(206, 157,  31, 32363, seed1);
+   CRANK(217, 146,  45, 31727, seed2);
+   CRANK(222, 142, 133, 31657, seed3);
+
+   return seed1^seed2^seed3;
+}
+
+void srand(seed)
+unsigned int seed;
+{
+   seed &= MAXINT;
+   seed1= seed%32362 + 1;
+   seed2= seed%31726 + 1;
+   seed3= seed%31656 + 1;
+}
+
+#endif
diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c
new file mode 100644 (file)
index 0000000..0990fde
--- /dev/null
@@ -0,0 +1,73 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+
+extern char ** environ;
+#define ADD_NUM 4
+
+int
+setenv(var, value, overwrite)
+const char * var;
+const char * value;
+int overwrite;
+{
+static char ** mall_env = 0;
+static int extras = 0;
+   char **p, **d;
+   char * t;
+   int len;
+
+   len = strlen(var);
+
+   if (!environ) {
+       environ = (char**)malloc(ADD_NUM * sizeof(char*));
+       memset(environ, 0, sizeof(char*)*ADD_NUM);
+       extras = ADD_NUM;
+   }
+
+   for(p=environ; *p; p++)
+   {
+      if( memcmp(var, *p, len) == 0 && (*p)[len] == '=' )
+      {
+         if (!overwrite)
+               return -1;
+         while( p[0] = p[1] ) p++;
+         extras++;
+         break;
+      }
+   }
+
+   if( extras <= 0 )   /* Need more space */
+   {
+      d = malloc((p-environ+1+ADD_NUM)*sizeof(char*));
+      if( d == 0 ) return -1;
+
+      memcpy((void*) d, (void*) environ, (p-environ+1)*sizeof(char*));
+      p = d + (p-environ);
+      extras=ADD_NUM;
+
+      if( mall_env ) free(mall_env);
+      environ = d;
+      mall_env = d;
+   }
+
+   t = malloc(len + 1 + strlen(value) + 1);
+   if (!t)
+       return -1;
+
+   strcpy(t, var);
+   strcat(t, "=");
+   strcat(t, value);
+
+   *p++ = (char*)t;
+   *p = '\0';
+   extras--;
+
+   return 0;
+}
+
+
diff --git a/libc/stdlib/strtod.c b/libc/stdlib/strtod.c
new file mode 100644 (file)
index 0000000..0d3bb79
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * strtod.c - This file is part of the libc-8086 package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ * 
+ *  This 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.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <stdlib.h>
+#include <ctype.h>
+
+float
+strtod(const char *nptr, char ** endptr)
+{
+  unsigned short negative;
+  float number;
+  float fp_part;
+  int exponent;
+  unsigned short exp_negative;
+
+  /* advance beyond any leading whitespace */
+  while (isspace(*nptr))
+    nptr++;
+
+  /* check for optional '+' or '-' */
+  negative=0;
+  if (*nptr=='-')
+    {
+      negative=1;
+      nptr++;
+    }
+  else
+    if (*nptr=='+')
+      nptr++;
+
+  number=0;
+  while (isdigit(*nptr))
+    {
+      number=number*10+(*nptr-'0');
+      nptr++;
+    }
+
+  if (*nptr=='.')
+    {
+      nptr++;
+      fp_part=0;
+      while (isdigit(*nptr))
+       {
+         fp_part=fp_part/10.0 + (*nptr-'0')/10.0;
+         nptr++;
+       }
+      number+=fp_part;
+    }
+
+  if (*nptr=='e' || *nptr=='E')
+    {
+      nptr++;
+      exp_negative=0;
+      if (*nptr=='-')
+       {
+         exp_negative=1;
+         nptr++;
+       }
+      else
+       if (*nptr=='+')
+         nptr++;
+
+      exponent=0;
+      while (isdigit(*nptr))
+       {
+         exponent=exponent*10+(*nptr-'0');
+         exponent++;
+       }
+    }
+
+  while (exponent)
+    {
+      if (exp_negative)
+       number/=10;
+      else
+       number*=10;
+      exponent--;
+    }
+  return (negative ? -number:number);
+}
diff --git a/libc/stdlib/system.c b/libc/stdlib/system.c
new file mode 100644 (file)
index 0000000..b764613
--- /dev/null
@@ -0,0 +1,48 @@
+
+#include <stddef.h>
+#include <signal.h>
+#include <unistd.h>
+
+int
+system(command)
+char * command;
+{
+   int wait_val, wait_ret, pid;
+   __sighandler_t save_quit, save_int, save_chld;
+
+   if( command == 0 ) return 1;
+
+   save_quit = signal(SIGQUIT, SIG_IGN);
+   save_int  = signal(SIGINT,  SIG_IGN);
+   save_chld = signal(SIGCHLD, SIG_DFL);
+
+   if( (pid=vfork()) < 0 )
+   {
+      signal(SIGQUIT, save_quit);
+      signal(SIGINT,  save_int);
+      signal(SIGCHLD, save_chld);
+      return -1;
+   }
+   if( pid == 0 )
+   {
+      signal(SIGQUIT, SIG_DFL);
+      signal(SIGINT,  SIG_DFL);
+      signal(SIGCHLD, SIG_DFL);
+
+      execl("/bin/sh", "sh", "-c", command, (char*)0);
+      _exit(127);
+   }
+   /* Signals are not absolutly guarenteed with vfork */
+   signal(SIGQUIT, SIG_IGN);
+   signal(SIGINT,  SIG_IGN);
+   
+   printf("Waiting for child %d\n", pid);
+
+   if (wait4(pid, &wait_val, 0, 0) == -1)
+      wait_val = -1;
+
+   signal(SIGQUIT, save_quit);
+   signal(SIGINT,  save_int);
+   signal(SIGCHLD, save_chld);
+   return wait_val;
+}
diff --git a/libc/string/Makefile b/libc/string/Makefile
new file mode 100644 (file)
index 0000000..af288e6
--- /dev/null
@@ -0,0 +1,37 @@
+# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+# This file is part of the Linux-8086 C library and is distributed
+# under the GNU Library General Public License.
+
+LIBC=../libc.a
+
+CC=m68k-pic-coff-gcc
+AR=m68k-pic-coff-ar
+RANLIB=m68k-pic-coff-ranlib
+
+CCFLAGS= -O2 -m68000 -msoft-float -I../include
+
+SSRC=string.c
+SOBJ=strlen.o strcat.o strcpy.o strcmp.o strncat.o strncpy.o strncmp.o \
+    strchr.o strrchr.o strdup.o memcpy.o memccpy.o memchr.o memset.o   \
+    memcmp.o memmove.o movedata.o
+
+OBJ=$(SOBJ) strpbrk.o strsep.o strstr.o strtok.o strcspn.o     \
+    strspn.o strcasecmp.o strncasecmp.o config.o
+
+CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
+
+all: $(LIBC)
+       @$(RM) $(OBJ)
+
+$(LIBC): $(LIBC)($(OBJ))
+
+$(LIBC)($(SOBJ)): $(SSRC)
+       $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+       $(AR) $(ARFLAGS) $@ $*.o
+
+transfer:
+       -@rm -f ../include/string.h
+       cp -p string.h ../include/.
+
+clean:
+       rm -f *.o
diff --git a/libc/string/config.c b/libc/string/config.c
new file mode 100644 (file)
index 0000000..545207f
--- /dev/null
@@ -0,0 +1,93 @@
+/* config.c: Config file reader.
+ *
+ * Copyright 1999 D. Jeff Dionne, <jeff@rt-control.com>
+ *
+ * This is free software, under the LGPL V2.0
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <cfgfile.h>
+
+/* This is a quick and dirty config file parser.  It reads the file once for
+ * each request, there is no cache.  Each line must be less than 128bytes.
+ */
+
+static char *args[16];
+static char cfgbuf[128];
+
+static char *
+ws(char **buf)
+{
+  char *b = *buf;
+  char *p;
+
+  /* eat ws */
+  while (*b &&
+        (*b == ' '  ||
+         *b == '\n' ||
+         *b == '\t')) b++;
+  p = b;
+
+  /* find the end */
+  while (*p &&
+        !(*p == ' '  ||
+          *p == '\n' ||
+          *p == '\t')) p++;
+  *p = 0;
+  *buf = p+1;
+  return b;
+}
+
+char **
+cfgread(FILE *fp)
+{
+  char *ebuf;
+  char *p;
+  int i;
+  int j;
+
+  if (!fp) {
+    errno = EIO;
+    return (void *)0;
+  }
+  
+  while (fgets(cfgbuf, sizeof(cfgbuf), fp)) {
+
+    /* ship comment lines */
+    if (cfgbuf[0] == '#') continue;
+
+    ebuf = cfgbuf + strlen(cfgbuf);
+
+    p = cfgbuf;
+    for (i = 0; i < 16 && p < ebuf; i++) {
+      args[i] = ws(&p);
+    }
+    args[i] = (void *)0;
+
+    /* return if we found something */
+    if (strlen(args[0])) return args;
+  }
+  return (void *)0;
+}
+
+char **
+cfgfind(FILE *fp, char *var)
+{
+  char **ret;
+  char search[80];
+
+  if (!fp || !var) {
+    errno = EIO;
+    return (void *)0;
+  }
+
+  strncpy(search, var, sizeof(search));
+
+  fseek(fp, 0, SEEK_SET);
+  while (ret = cfgread(fp)) {
+    if (!strcmp(ret[0], search)) return ret;
+  }
+  return (void *)0;
+}
diff --git a/libc/string/strcasecmp.c b/libc/string/strcasecmp.c
new file mode 100644 (file)
index 0000000..0e7b038
--- /dev/null
@@ -0,0 +1,26 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+#include <string.h>
+#include <ctype.h>
+
+int
+strcasecmp(s, d)
+char *s;
+char *d;
+{
+   for(;;)
+   {
+      if( *s != *d )
+      {
+        if( tolower(*s) != tolower(*d) )
+           return *s - *d;
+      }
+      else if( *s == '\0' ) break;
+      s++; d++;
+   }
+   return 0;
+}
+
diff --git a/libc/string/strcspn.c b/libc/string/strcspn.c
new file mode 100644 (file)
index 0000000..619c8be
--- /dev/null
@@ -0,0 +1,32 @@
+/* strcspn.c */
+
+/* from Schumacher's Atari library, improved */
+
+#include <string.h>
+
+size_t strcspn(string, set)
+register char *string;
+char *set;
+/*
+ *     Return the length of the sub-string of <string> that consists
+ *     entirely of characters not found in <set>.  The terminating '\0'
+ *     in <set> is not considered part of the match set.  If the first
+ *     character if <string> is in <set>, 0 is returned.
+ */
+{
+    register char *setptr;
+    char *start;
+
+    start = string;
+    while (*string)
+    {
+       setptr = set;
+       do
+           if (*setptr == *string)
+               goto break2;
+       while (*setptr++);
+       ++string;
+    }
+break2:
+    return string - start;
+}
diff --git a/libc/string/string.c b/libc/string/string.c
new file mode 100644 (file)
index 0000000..664929b
--- /dev/null
@@ -0,0 +1,672 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+#include <string.h>
+#include <malloc.h>
+
+#ifdef __AS386_16__
+#if __FIRST_ARG_IN_AX__
+#define BCC_AX_ASM     /* BCC Assembler that can cope with arg in AX  */
+#else
+#define BCC_AX_ASM
+#define BCC_ASM                /* Use 16 bit BCC assembler */
+#endif
+
+#define PARANOID       /* Include extra code for cld and ES register */
+#endif
+
+/* This is a basic string package; it includes the most used functions
+
+   strlen strcat strcpy strcmp strncat strncpy strncmp strchr strrchr strdup
+   memcpy memccpy memchr memset memcmp memmove
+
+   These functions are in seperate files.
+    strpbrk.o strsep.o strstr.o strtok.o strcspn.o
+    strspn.o strcasecmp.o strncasecmp.o
+ */
+
+/********************** Function strlen ************************************/
+
+#ifdef L_strlen
+size_t strlen(str)
+const char * str;
+{
+#ifdef BCC_AX_ASM
+#asm
+#if !__FIRST_ARG_IN_AX__
+  mov  bx,sp
+#endif
+  push di
+
+#ifdef PARANOID
+  push es
+  push ds      ; Im not sure if this is needed, so just in case.
+  pop  es
+  cld
+#endif         ! This is almost the same as memchr, but it can
+               ! stay as a special.
+
+#if __FIRST_ARG_IN_AX__
+  mov  di,ax
+#else
+  mov  di,[bx+2]
+#endif
+  mov  cx,#-1
+  xor  ax,ax
+  repne
+  scasb
+  not  cx
+  dec  cx
+  mov  ax,cx
+
+#ifdef PARANOID
+  pop  es
+#endif
+  pop  di
+#endasm
+#else
+   register char * p =(char *) str;
+   while(*p) p++;
+   return p-str;
+#endif  /* ifdef BCC_AX_ASM */
+}
+#endif
+
+/********************** Function strcat ************************************/
+
+#ifdef L_strcat
+char * strcat(d, s)
+char *d; 
+const char * s;
+{
+   (void) strcpy(d+strlen(d), s);
+   return d;
+}
+#endif
+
+/********************** Function strcpy ************************************/
+
+#ifdef L_strcpy
+char * strcpy(d, s)
+char *d;
+const char * s;
+{
+   /* This is probably the quickest on an 8086 but a CPU with a cache will
+    * prefer to do this in one pass */
+   return memcpy(d, s, strlen(s)+1);
+}
+#endif
+
+/********************** Function strcmp ************************************/
+
+#ifdef L_strcmp
+int strcmp(d, s)
+const char *d;
+const char * s;
+{
+  /* There are a number of ways to do this and it really does depend on the
+     types of strings given as to which is better, nevertheless the Glib
+     method is quite reasonable so we'll take that */
+
+#ifdef BCC_AX_ASM
+#asm
+  mov  bx,sp
+  push di
+  push si
+
+#ifdef PARANOID
+  push es
+  push ds      ; Im not sure if this is needed, so just in case.
+  pop  es
+  cld
+#endif
+
+#if __FIRST_ARG_IN_AX__
+  mov  di,ax           ; dest
+  mov  si,[bx+2]       ; source
+#else
+  mov  di,[bx+2]       ; dest
+  mov  si,[bx+4]       ; source
+#endif
+sc_1:
+  lodsb
+  scasb
+  jne  sc_2            ; If bytes are diff skip out.
+  testb        al,al
+  jne  sc_1            ; If this byte in str1 is nul the strings are equal
+  xor  ax,ax           ; so return zero
+  jmp  sc_3
+sc_2:
+  sbb  ax,ax           ; Collect correct val (-1,1).
+  orb  al,#1
+sc_3:
+
+#ifdef PARANOID
+  pop  es
+#endif
+  pop  si
+  pop  di
+#endasm
+#else /* ifdef BCC_AX_ASM */
+   register char *s1=(char *)d, *s2=(char *)s, c1,c2;
+   while((c1= *s1++) == (c2= *s2++) && c1 );
+   return c1 - c2;
+#endif /* ifdef BCC_AX_ASM */
+}
+#endif
+
+/********************** Function strncat ************************************/
+
+#ifdef L_strncat
+char * strncat(d, s, l)
+char *d;
+const char *s;
+size_t l;
+{
+   register char *s1=d+strlen(d), *s2;
+   
+   s2 = memchr(s, 0, l);
+   if( s2 )
+      memcpy(s1, s, s2-s+1);
+   else
+   {
+      memcpy(s1, s, l);
+      s1[l] = '\0';
+   }
+   return d;
+}
+#endif
+
+/********************** Function strncpy ************************************/
+
+#ifdef L_strncpy
+char * strncpy(d, s, l)                /* FIXME need the fast version of this */
+char *d;
+const char *s;
+size_t l;
+{
+   register char *s1=d;
+   register const char *s2=s;
+   while(l > 0)
+   {
+      l--;
+      if( (*s1++ = *s2++) == '\0')
+         break;
+   }
+
+   /* This _is_ correct strncpy is supposed to zap */
+   for(; l>0; l--) *s1++ = '\0';
+   return d;
+}
+#endif
+
+/********************** Function strncmp ************************************/
+
+#ifdef L_strncmp
+int strncmp(d, s, l)
+const char *d, *s;
+size_t l;
+{
+#ifdef BCC_AX_ASM
+#asm
+  mov  bx,sp
+  push si
+  push di
+
+#ifdef PARANOID
+  push es
+  push ds      ! Im not sure if this is needed, so just in case.
+  pop  es
+  cld
+#endif
+
+#if __FIRST_ARG_IN_AX__
+  mov  si,ax
+  mov  di,[bx+2]
+  mov  cx,[bx+4]
+#else
+  mov  si,[bx+2]       ! Fetch
+  mov  di,[bx+4]
+  mov  cx,[bx+6]
+#endif
+
+  inc  cx
+lp1:
+  dec  cx
+  je   lp2
+  lodsb
+  scasb
+  jne  lp3
+  testb        al,al
+  jne  lp1
+lp2:
+  xor  ax,ax
+  jmp  lp4
+lp3:
+  sbb  ax,ax
+  or   al,#1
+lp4:
+
+#ifdef PARANOID
+  pop  es
+#endif
+  pop  di
+  pop  si
+#endasm
+#else
+   register char c1=0, c2=0;
+   while(l-- >0)
+      if( (c1= *d++) != (c2= *s++) || c1 == '\0' )
+         break;
+   return c1-c2;
+#endif
+}
+#endif
+
+/********************** Function strchr ************************************/
+
+#ifdef L_strchr
+char *
+strchr(s, c)
+char * s;
+int c;
+{
+#ifdef BCC_AX_ASM
+#asm
+  mov  bx,sp
+  push si
+#if __FIRST_ARG_IN_AX__
+  mov  bx,[bx+2]
+  mov  si,ax
+#else
+  mov  si,[bx+2]
+  mov  bx,[bx+4]
+#endif
+  xor  ax,ax
+
+#ifdef PARANOID
+  cld
+#endif
+
+in_loop:
+  lodsb
+  cmp  al,bl
+  jz   got_it
+  or   al,al
+  jnz  in_loop
+  pop  si
+  ret
+got_it:
+  lea  ax,[si-1]
+  pop  si
+
+#endasm
+#else /* ifdef BCC_AX_ASM */
+   register char ch;
+   for(;;)
+   {
+     if( (ch= *s) == c ) return s;
+     if( ch == 0 ) return 0;
+     s++;
+   }
+#endif /* ifdef BCC_AX_ASM */
+}
+#endif
+
+/********************** Function strrchr ************************************/
+
+#ifdef L_strrchr
+char * strrchr(s, c)
+char * s;
+int c;
+{
+   register char * prev = 0;
+   register char * p = s;
+   /* For null it's just like strlen */
+   if( c == '\0' ) return p+strlen(p);
+
+   /* everything else just step along the string. */
+   while( (p=strchr(p, c)) != 0 )
+   {
+      prev = p; p++;
+   }
+   return prev;
+}
+#endif
+
+/********************** Function strdup ************************************/
+
+#ifdef L_strdup
+char * strdup(s)
+const char * s;
+{
+   register size_t len;
+   register char * p;
+
+   len = strlen(s)+1;
+   p = (char *) malloc(len);
+   if(p) memcpy(p, s, len); /* Faster than strcpy */
+   return p;
+}
+#endif
+
+/********************** Function memcpy ************************************/
+
+#ifdef L_memcpy
+void *
+memcpy(d, s, l)
+void *d;
+const void *s;
+size_t l;
+{
+#ifdef BCC_AX_ASM
+#asm
+  mov  bx,sp
+  push di
+  push si
+
+#ifdef PARANOID
+  push es
+  push ds      ; Im not sure if this is needed, so just in case.
+  pop  es
+  cld
+#endif
+
+#if __FIRST_ARG_IN_AX__
+  mov  di,ax           ; dest
+  mov  si,[bx+2]       ; source
+  mov  cx,[bx+4]       ; count
+#else
+  mov  di,[bx+2]       ; dest
+  mov  si,[bx+4]       ; source
+  mov  cx,[bx+6]       ; count
+
+  mov  ax,di
+#endif
+               ; If di is odd mov 1 byte before doing word move
+               ; this will speed slightly but
+               ; NB 8086 has no problem with mis-aligned access.
+
+  shr  cx,#1   ; Do this faster by doing a mov word
+  rep
+  movsw
+  adc  cx,cx   ; Retrieve the leftover 1 bit from cflag.
+  rep
+  movsb
+
+#ifdef PARANOID
+  pop  es
+#endif
+  pop  si
+  pop  di
+#endasm
+#else /* ifdef BCC_AX_ASM */
+   register char *s1=d, *s2=(char *)s;
+   for( ; l>0; l--) *((unsigned char*)s1++) = *((unsigned char*)s2++);
+   return d;
+#endif /* ifdef BCC_AX_ASM */
+}
+#endif
+
+/********************** Function memccpy ************************************/
+
+#ifdef L_memccpy
+void * memccpy(d, s, c, l)     /* Do we need a fast one ? */
+void *s, *d;
+int c;
+size_t l;
+{
+   register char *s1=d, *s2=s;
+   while(l-- > 0)
+      if((*s1++ = *s2++) == c )
+         return s1;
+   return 0;
+}
+#endif
+
+/********************** Function memchr ************************************/
+
+#ifdef L_memchr
+void * memchr(str, c, l)
+const void * str;
+int c;
+size_t l;
+{
+#ifdef BCC_ASM
+#asm
+  mov  bx,sp
+  push di
+
+#ifdef PARANOID
+  push es
+  push ds      ; Im not sure if this is needed, so just in case.
+  pop  es
+  cld
+#endif
+
+  mov  di,[bx+2]
+  mov  ax,[bx+4]
+  mov  cx,[bx+6]
+  test cx,cx
+  je   is_z    ! Zero length, do not find.
+
+  repne                ! Scan
+  scasb
+  jne  is_z    ! Not found, ret zero
+  dec  di      ! Adjust ptr
+  mov  ax,di   ! return
+  jmp  xit
+is_z:
+  xor  ax,ax
+xit:
+
+#ifdef PARANOID
+  pop  es
+#endif
+  pop  di
+#endasm
+#else /* ifdef BCC_ASM */
+   register char *p=(char *)str;
+   while(l-- > 0)
+   {
+      if(*p == c) return p;
+      p++;
+   }
+   return 0;
+#endif /* ifdef BCC_ASM */
+}
+#endif
+
+/********************** Function memset ************************************/
+
+#ifdef L_memset
+void * memset(str, c, l)
+void * str;
+int c;
+size_t l;
+{
+#ifdef BCC_AX_ASM
+#asm
+  mov  bx,sp
+  push di
+
+#ifdef PARANOID
+  push es
+  push ds      ; Im not sure if this is needed, so just in case.
+  pop  es
+  cld
+#endif
+
+#if __FIRST_ARG_IN_AX__
+  mov  di,ax           ; Fetch
+  mov  ax,[bx+2]
+  mov  cx,[bx+4]
+#else
+  mov  di,[bx+2]       ; Fetch
+  mov  ax,[bx+4]
+  mov  cx,[bx+6]
+#endif
+
+; How much difference does this alignment make ?
+; I don`t think it`s significant cause most will already be aligned.
+
+;  test        cx,cx           ; Zero size - skip
+;  je  xit
+;
+;  test        di,#1           ; Line it up
+;  je  s_1
+;  stosb
+;  dec cx
+;s_1:
+
+  mov  ah,al           ; Replicate byte
+  shr  cx,#1           ; Do this faster by doing a sto word
+  rep                  ; Bzzzzz ...
+  stosw
+  adc  cx,cx           ; Retrieve the leftover 1 bit from cflag.
+
+  rep                  ; ... z
+  stosb
+
+xit:
+  mov  ax,[bx+2]
+#ifdef PARANOID
+  pop  es
+#endif
+  pop  di
+#endasm
+#else /* ifdef BCC_AX_ASM */
+   register char *s1=str;
+   while(l-->0) *s1++ = c;
+   return str;
+#endif /* ifdef BCC_AX_ASM */
+}
+#endif
+
+/********************** Function memcmp ************************************/
+
+#ifdef L_memcmp
+int memcmp(s, d, l)
+const void *s, *d;
+size_t l;
+{
+#ifdef BCC_ASM
+#asm
+  mov  bx,sp
+  push di
+  push si
+
+#ifdef PARANOID
+  push es
+  push ds      ! Im not sure if this is needed, so just in case.
+  pop  es
+  cld
+#endif
+
+  mov  si,[bx+2]       ! Fetch
+  mov  di,[bx+4]
+  mov  cx,[bx+6]
+  xor  ax,ax
+
+  rep                  ! Bzzzzz
+  cmpsb
+  je   xit             ! All the same!
+  sbb  ax,ax
+  sbb  ax,#-1          ! choose +/-1
+xit:
+#ifdef PARANOID
+  pop  es
+#endif
+  pop  si
+  pop  di
+#endasm
+#else /* ifdef BCC_ASM */
+   register const char *s1=d, *s2=s;
+   register char c1=0, c2=0;
+   while(l-- > 0)
+      if( (c1= *s1++) != (c2= *s2++) )
+         break;
+   return c1-c2;
+#endif /* ifdef BCC_ASM */
+}
+#endif
+
+/********************** Function memmove ************************************/
+
+#ifdef L_memmove
+void *
+memmove(d, s, l)
+void *d, *s;
+size_t l;
+{
+   register char *s1=d, *s2=s;
+   /* This bit of sneakyness c/o Glibc, it assumes the test is unsigned */
+   if( s1-s2 >= l ) return memcpy(d,s,l);
+
+   /* This reverse copy only used if we absolutly have to */
+   s1+=l; s2+=l;
+   while(l-- >0)
+      *(--s1) = *(--s2);
+   return d;
+}
+#endif
+
+/********************** Function movedata ***********************************/
+
+#ifdef L_movedata
+
+/* NB There isn't any C version of this function ... */
+
+#ifdef BCC_AX_ASM
+void
+__movedata(srcseg, srcoff, destseg, destoff, len)
+unsigned int srcseg, srcoff, destseg, destoff, len;
+{
+#asm
+  push bp
+  mov  bp,sp
+  push si
+  push di
+  push ds
+#ifdef PARANOID
+  push es
+  cld
+#endif
+
+  ! sei                        ! Are we _really_ paranoid ?
+
+#if !__FIRST_ARG_IN_AX__
+  mov  ds,[bp+4]       ! Careful, [bp+xx] is SS based.
+  mov  si,[bp+6]
+  mov  es,[bp+8]
+  mov  di,[bp+10]
+  mov  cx,[bp+12]
+#else
+  mov  ds,ax
+  mov  si,[bp+4]
+  mov  es,[bp+6]
+  mov  di,[bp+8]
+  mov  cx,[bp+10]
+#endif
+  rep
+   movsb
+
+  ! cli                        ! Are we _really_ paranoid ?
+  
+#ifdef PARANOID
+  pop  es
+#endif
+  pop  ds
+  pop  di
+  pop  si
+  pop  bp
+#endasm
+}
+#endif
+
+#endif
+
+/********************** THE END ********************************************/
+
diff --git a/libc/string/strncasecmp.c b/libc/string/strncasecmp.c
new file mode 100644 (file)
index 0000000..561f72a
--- /dev/null
@@ -0,0 +1,28 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+#include <string.h>
+#include <ctype.h>
+
+int
+strncasecmp(s, d, l)
+char *s;
+char *d;
+size_t l;
+{
+   while(l>0)
+   {
+      if( *s != *d )
+      {
+        if( tolower(*s) != tolower(*d) )
+           return *s - *d;
+      }
+      else
+        if( *s == '\0' ) return 0;
+      s++; d++; l--;
+   }
+   return 0;
+}
+
diff --git a/libc/string/strpbrk.c b/libc/string/strpbrk.c
new file mode 100644 (file)
index 0000000..3fc27ec
--- /dev/null
@@ -0,0 +1,21 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+#include <string.h>
+
+/* This uses strchr, strchr should be in assembler */
+
+char *strpbrk(str, set)
+register char *str;
+char *set;
+{
+  while (*str != '\0')
+    if (strchr(set, *str) == 0)
+      ++str;
+    else
+      return (char *) str;
+
+  return 0;
+}
diff --git a/libc/string/strsep.c b/libc/string/strsep.c
new file mode 100644 (file)
index 0000000..21aa1bb
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (C) 1992, 1993 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 <string.h>
+
+char *
+strsep(pp, delim)
+char **pp;
+char *delim;
+{
+  char *p, *q;
+
+  if (!(p = *pp))
+    return 0;
+  if (q = strpbrk (p, delim))
+    {
+      *pp = q + 1;
+      *q = '\0';
+    }
+  else
+    *pp = 0;
+  return p;
+}
diff --git a/libc/string/strspn.c b/libc/string/strspn.c
new file mode 100644 (file)
index 0000000..2094caa
--- /dev/null
@@ -0,0 +1,44 @@
+/* Copyright (C) 1992, 1993 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 <string.h>
+
+/* Return the length of the maximum initial segment
+   of S which contains only characters in ACCEPT.  */
+size_t
+strspn(s, accept)
+char *s;
+char *accept;
+{
+  register char *p;
+  register char *a;
+  register size_t count = 0;
+
+  for (p = s; *p != '\0'; ++p)
+    {
+      for (a = accept; *a != '\0'; ++a)
+       if (*p == *a)
+         break;
+      if (*a == '\0')
+       return count;
+      else
+       ++count;
+    }
+
+  return count;
+}
diff --git a/libc/string/strstr.c b/libc/string/strstr.c
new file mode 100644 (file)
index 0000000..aafcaf9
--- /dev/null
@@ -0,0 +1,54 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+#include <string.h>
+
+#if 1
+/* We've now got a nice fast strchr and memcmp use them */
+
+char *
+strstr(s1, s2)
+char *s1; char *s2;
+{
+   register int l = strlen(s2);
+   register char * p = s1;
+
+   if( l==0 ) return p;
+
+   while (p = strchr(p, *s2))
+   {
+      if( memcmp(p, s2, l) == 0 )
+         return p;
+      p++;
+   }
+   return (char *) 0;
+}
+
+#else
+/* This is a nice simple self contained strstr,
+   now go and work out why the GNU one is faster :-) */
+
+char *strstr(str1, str2)
+char *str1, *str2;
+{
+    register char *Sptr, *Tptr;
+    int        len = strlen(str1) -strlen(str2) + 1;
+
+    if (*str2)
+       for (; len > 0; len--, str1++){
+           if (*str1 != *str2)
+               continue;
+
+           for (Sptr = str1, Tptr = str2; *Tptr != '\0'; Sptr++, Tptr++)
+               if (*Sptr != *Tptr)
+                   break;
+
+           if (*Tptr == '\0')
+               return (char*) str1;
+       }
+
+    return (char*)0;
+}
+#endif
diff --git a/libc/string/strtok.c b/libc/string/strtok.c
new file mode 100644 (file)
index 0000000..27d8f25
--- /dev/null
@@ -0,0 +1,71 @@
+/* Copyright (C) 1991 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 <string.h>
+
+
+static char *olds = 0;
+
+/* Parse S into tokens separated by characters in DELIM.
+   If S is NULL, the last string strtok() was called with is
+   used.  For example:
+       char s[] = "-abc=-def";
+       x = strtok(s, "-");             // x = "abc"
+       x = strtok(NULL, "=-");         // x = "def"
+       x = strtok(NULL, "=");          // x = NULL
+               // s = "abc\0-def\0"
+*/
+char *
+strtok(s, delim)
+register char *s;
+register char *delim;
+{
+  char *token;
+
+  if (s == 0)
+    {
+      if (olds == 0)
+       {
+         return 0;
+       }
+      else
+       s = olds;
+    }
+
+  /* Scan leading delimiters.  */
+  s += strspn(s, delim);
+  if (*s == '\0')
+    {
+      olds = 0;
+      return 0;
+    }
+
+  /* Find the end of the token.  */
+  token = s;
+  s = strpbrk(token, delim);
+  if (s == 0)
+    /* This token finishes the string.  */
+    olds = 0;
+  else
+    {
+      /* Terminate the token and make OLDS point past it.  */
+      *s = '\0';
+      olds = s + 1;
+    }
+  return token;
+}
diff --git a/libc/sysdeps/linux/i386/bits/setjmp.h b/libc/sysdeps/linux/i386/bits/setjmp.h
new file mode 100644 (file)
index 0000000..20786d6
--- /dev/null
@@ -0,0 +1,176 @@
+#if defined(__arm__) || defined(__thumb__)
+/*
+ * All callee preserved registers:
+ * v1 - v7, fp, ip, sp, lr, f4, f5, f6, f7
+ */
+#define _JBLEN 23
+#endif
+
+#ifdef __sparc__
+/*
+ * onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext).
+ * All else recovered by under/over(flow) handling.
+ */
+#define        _JBLEN  13
+#endif
+
+/* necv70 was 9 as well. */
+
+#ifdef __mc68000__
+/*
+ * onsstack,sigmask,sp,pc,psl,d2-d7,a2-a6,
+ * fp2-fp7     for 68881.
+ * All else recovered by under/over(flow) handling.
+ */
+#define        _JBLEN  34
+#endif
+
+#if defined(__Z8001__) || defined(__Z8002__)
+/* 16 regs + pc */
+#define _JBLEN 20
+#endif
+
+#ifdef _AM29K
+/*
+ * onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext).
+ * All else recovered by under/over(flow) handling.
+ */
+#define        _JBLEN  9
+#endif
+
+#ifdef __i386__
+#ifdef __unix__
+# define _JBLEN        36
+#elif defined(_WIN32)
+#define _JBLEN (13 * 4)
+#else
+#include "setjmp-dj.h"
+#endif
+#endif
+
+#ifdef __i960__
+#define _JBLEN 35
+#endif
+
+#ifdef __M32R__
+/* Only 8 words are currently needed.  10 gives us some slop if we need
+   to expand.  */
+#define _JBLEN 10
+#endif
+
+#ifdef __mips__
+#define _JBLEN 11
+#endif
+
+#ifdef __m88000__
+#define _JBLEN 21
+#endif
+
+#ifdef __H8300__
+#define _JBLEN 5
+typedef int jmp_buf[_JBLEN];
+#endif
+
+#ifdef __H8300H__
+/* same as H8/300 but registers are twice as big */
+#define _JBLEN 5
+#define _JBTYPE long
+#endif
+
+#ifdef __H8300S__
+/* same as H8/300 but registers are twice as big */
+#define _JBLEN 5
+#define _JBTYPE long
+#endif
+
+#ifdef __H8500__
+#define _JBLEN 4
+#endif
+
+#ifdef  __sh__
+#define _JBLEN 20
+#endif
+
+#ifdef  __v800
+#define _JBLEN 28
+#endif
+
+#ifdef __PPC__
+#define _JBLEN 32
+#define _JBTYPE double
+#endif
+
+#ifdef __hppa__
+/* %r30, %r2-%r18, %r27, pad, %fr12-%fr15.
+   Note space exists for the FP registers, but they are not
+   saved.  */
+#define _JBLEN 28
+#endif
+
+#if defined(mn10300) || defined(mn10200)
+/* A guess */
+#define _JBLEN 10
+#endif
+
+#ifdef __v850
+/* I think our setjmp is saving 15 regs at the moment.  Gives us one word
+   slop if we need to expand.  */
+#define _JBLEN 16
+#endif
+
+
+#ifdef __D10V__
+#define _JBLEN 8
+#endif
+
+/* start-sanitize-d30v */
+#ifdef __D30V__
+#define _JBLEN (64 /* GPR */ + (2*2) /* ACs */ + 18 /* CRs */)
+#endif
+/* end-sanitize-d30v */
+
+#ifdef _JBLEN
+#ifdef _JBTYPE
+typedef        _JBTYPE jmp_buf[_JBLEN];
+#else
+typedef        int jmp_buf[_JBLEN];
+#endif
+
+#ifdef __CYGWIN32__
+#include <signal.h>
+
+/* POSIX sigsetjmp/siglongjmp macros */
+typedef int sigjmp_buf[_JBLEN+2];
+
+#define _SAVEMASK      _JBLEN
+#define _SIGMASK       (_JBLEN+1)
+
+#define sigsetjmp(env, savemask) (env[_SAVEMASK] = savemask,\
+               sigprocmask (SIG_SETMASK, 0, (sigset_t *) &env[_SIGMASK]),\
+               setjmp (env))
+
+#define siglongjmp(env, val) (((env[_SAVEMASK])?\
+               sigprocmask (SIG_SETMASK, (sigset_t *) &env[_SIGMASK], 0):0),\
+               longjmp (env, val))
+
+#endif /* __CYGWIN32__*/
+
+#if defined(__linux__) && defined(__mc68000__)
+#include <signal.h>
+
+/* POSIX sigsetjmp/siglongjmp macros */
+typedef int sigjmp_buf[_JBLEN];
+
+#define _SAVEMASK      4
+#define _SIGMASK       1
+
+#define sigsetjmp(env, savemask) (env[_SAVEMASK] = savemask,\
+               sigprocmask (SIG_SETMASK, 0, (sigset_t *) &env[_SIGMASK]),\
+               setjmp (env))
+
+#define siglongjmp(env, val) (((env[_SAVEMASK])?\
+               sigprocmask (SIG_SETMASK, (sigset_t *) &env[_SIGMASK], 0):0),\
+               longjmp (env, val))
+
+#endif /* __linux__*/
+#endif
diff --git a/libc/termios/Makefile b/libc/termios/Makefile
new file mode 100644 (file)
index 0000000..089fdc0
--- /dev/null
@@ -0,0 +1,36 @@
+# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk>
+# This file is part of the Linux-8086 C library and is distributed
+# under the GNU Library General Public License.
+
+LIBC=../libc.a
+
+CC=m68k-pic-coff-gcc
+AR=m68k-pic-coff-ar
+RANLIB=m68k-pic-coff-ranlib
+
+CCFLAGS= -O2 -m68000 -msoft-float -I../include
+
+TSRC=termios.c
+TOBJ=tcsetattr.o tcgetattr.o tcdrain.o tcflow.o tcflush.o tcsendbreak.o        \
+     tcsetpgrp.o tcgetpgrp.o isatty.o  \
+     cfgetospeed.o cfgetispeed.o cfsetospeed.o cfsetispeed.o cfmakeraw.o
+
+#     cfgetospeedn.o cfgetispeedn.o cfsetospeedn.o cfsetispeedn.o tcspeed.o
+
+OBJ=$(TOBJ) ttyname.o
+# unlike everything else, this does not compile out of the box...
+#  ttyname.o
+
+CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
+
+all: $(LIBC)
+       @$(RM) $(OBJ)
+
+$(LIBC): $(LIBC)($(OBJ))
+
+$(LIBC)($(TOBJ)): $(TSRC)
+       $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+       $(AR) $(ARFLAGS) $@ $*.o
+
+clean:
+       rm -f *.o libc.a
diff --git a/libc/termios/termios.c b/libc/termios/termios.c
new file mode 100644 (file)
index 0000000..c6c0117
--- /dev/null
@@ -0,0 +1,348 @@
+/* Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> This
+ * file is part of the Linux-8086 C library and is distributed under the
+ * GNU Library General Public License.
+ */
+
+/* Note: This is based loosely on the Glib termios routines. */
+
+#ifndef __MSDOS__
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+
+#ifdef L_isatty
+isatty(fd)
+int fd;
+{
+   struct termios term;
+   int rv, err = errno;
+   rv= (ioctl(fd, TCGETS, &term)==0);
+   if( rv==0 && errno == ENOSYS )
+      rv = (fd<3);
+   errno = err;
+   return rv;
+}
+#endif 
+
+#ifdef L_tcgetattr
+int
+tcgetattr(fd, term)
+int   fd;
+struct termios *term;
+{
+   return ioctl(fd, TCGETS, term);
+}
+#endif
+
+#ifdef L_tcsetattr
+int
+tcsetattr(fildes, optional_actions, termios_p)
+int fildes;
+int optional_actions;
+struct termios *termios_p;
+{
+   switch (optional_actions)
+   {
+   case TCSANOW:
+      return ioctl(fildes, TCSETS, termios_p);
+   case TCSADRAIN:
+      return ioctl(fildes, TCSETSW, termios_p);
+   case TCSAFLUSH:
+      return ioctl(fildes, TCSETSF, termios_p);
+   default:
+      errno = EINVAL;
+      return -1;
+   }
+}
+#endif
+
+#ifdef L_tcdrain
+/* Wait for pending output to be written on FD.  */
+int
+tcdrain(fd)
+int   fd;
+{
+   /* With an argument of 1, TCSBRK just waits for output to drain.  */
+   return ioctl(fd, TCSBRK, 1);
+}
+#endif
+
+#ifdef L_tcflow
+int 
+tcflow(fd, action)
+int fd;
+int action;
+{
+   return ioctl(fd, TCXONC, action);
+}
+#endif
+
+#ifdef L_tcflush
+/* Flush pending data on FD.  */
+int
+tcflush(fd, queue_selector)
+int   fd;
+int   queue_selector;
+{
+   return ioctl(fd, TCFLSH, queue_selector);
+}
+#endif
+
+#ifdef L_tcsendbreak
+/* Send zero bits on FD.  */
+int
+tcsendbreak(fd, duration)
+int   fd;
+int   duration;
+{
+   /*
+    * The break lasts 0.25 to 0.5 seconds if DURATION is zero, and an
+    * implementation-defined period if DURATION is nonzero. We define a
+    * positive DURATION to be number of milliseconds to break.
+    */
+   if (duration <= 0)
+      return ioctl(fd, TCSBRK, 0);
+
+   /*
+    * ioctl can't send a break of any other duration for us. This could be
+    * changed to use trickery (e.g. lower speed and send a '\0') to send
+    * the break, but for now just return an error.
+    */
+   errno = EINVAL;
+   return -1;
+}
+#endif
+
+#ifdef L_tcsetpgrp
+/* Set the foreground process group ID of FD set PGRP_ID.  */
+int
+tcsetpgrp(fd, pgrp_id)
+int   fd;
+pid_t pgrp_id;
+{
+   return ioctl(fd, TIOCSPGRP, &pgrp_id);
+}
+#endif
+
+#ifdef L_tcgetpgrp
+/* Return the foreground process group ID of FD.  */
+pid_t
+tcgetpgrp(fd)
+int   fd;
+{
+   int   pgrp;
+   if (ioctl(fd, TIOCGPGRP, &pgrp) < 0)
+      return (pid_t) - 1;
+   return (pid_t) pgrp;
+}
+#endif
+
+#ifdef L_cfgetospeed
+speed_t cfgetospeed(tp)
+struct termios *tp;
+{
+    return (tp->c_cflag & CBAUD);
+}
+#endif
+
+#ifdef L_cfgetispeed
+speed_t cfgetispeed(tp)
+struct termios *tp;
+{
+    return (tp->c_cflag & CBAUD);
+}
+#endif
+
+#ifdef L_cfsetospeed
+int cfsetospeed(tp, speed)
+struct termios *tp; speed_t speed;
+{
+#ifdef CBAUDEX
+    if ((speed & ~CBAUD) || 
+       ((speed & CBAUDEX) && (speed < B57600 || speed > B115200)))
+       return 0;
+#else
+    if (speed & ~CBAUD)
+       return 0;
+#endif
+    tp->c_cflag &= ~CBAUD;
+    tp->c_cflag |= speed;
+
+    return 0;
+}
+#endif
+
+#ifdef L_cfsetispeed
+int cfsetispeed(tp, speed)
+struct termios *tp; speed_t speed;
+{
+    return cfsetospeed(tp, speed);
+}
+#endif
+
+#if 0
+
+/* Not POSIX standard, not worth the bother to keep it up */
+
+#ifdef L_tcspeed
+static struct {
+       int number;
+       speed_t code;
+} tcspeeds[] = {
+#ifdef B50
+       {50, B50},
+#endif
+#ifdef B75
+       {75, B75},
+#endif
+#ifdef B110
+       {110, B110},
+#endif
+#ifdef B134
+       {134, B134},
+#endif
+#ifdef B150
+       {150, B150},
+#endif
+#ifdef B200
+       {200, B200},
+#endif
+#ifdef B300
+       {300, B300},
+#endif
+#ifdef B600
+       {600, B600},
+#endif
+#ifdef B1200
+       {1200, B1200},
+#endif
+#ifdef B1800
+       {1800, B1800},
+#endif
+#ifdef B2400
+       {2400, B2400},
+#endif
+#ifdef B4800
+       {4800, B4800},
+#endif
+#ifdef B9600
+       {9600, B9600},
+#endif
+#ifdef B19200
+       {19200, B19200},
+#endif
+#ifdef B38400
+       {38400, B38400},
+#endif
+#ifdef B57600
+       {57600, B57600},
+#endif
+#ifdef B115200
+       {115200, B115200},
+#endif
+#ifdef B230400
+       {230400, B230400},
+#endif
+#ifdef B460800
+       {460800, B460800},
+#endif
+#ifdef B0
+       {0, B0},
+#endif
+       {0, 0}
+};
+
+int tcspeed_to_number(code)
+speed_t code;
+{
+    int i;
+    code &= CBAUD;
+    for(i=0;tcspeeds[i].code;i++)
+        if (tcspeeds[i].code == code)
+          return tcspeeds[i].number;
+    return 0;
+}
+
+speed_t tcspeed_from_number(number)
+int number;
+{
+    int i;
+    for(i=0;tcspeeds[i].code;i++)
+        if (tcspeeds[i].number == number)
+          return tcspeeds[i].code;
+    return B0;
+}
+#endif
+
+#ifdef L_cfgetospeedn
+int cfgetospeedn(tp)
+struct termios *tp;
+{
+    return tcspeed_to_number(cfgetospeed(tp));
+}
+#endif
+
+#ifdef L_cfgetispeedn
+int cfgetispeedn(tp)
+struct termios *tp;
+{
+    return tcspeed_to_number(cfgetispeed(tp));
+}
+#endif
+
+#ifdef L_cfsetospeedn
+int cfsetospeedn(tp, speed)
+struct termios *tp; int speed;
+{
+    return cfsetospeed(tp, tcspeed_from_number(speed));
+}
+#endif
+
+#ifdef L_cfsetispeedn
+int cfsetispeedn(tp, speed)
+struct termios *tp; int speed;
+{
+    return cfsetispeedn(tp, tcspeed_from_number(speed));
+}
+#endif
+
+#endif
+
+/* From linux libc-4.6.27 again */
+#ifdef L_cfmakeraw
+/* Copyright (C) 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.*/
+
+void
+cfmakeraw(t)
+struct termios *t;
+{
+/* I changed it to the current form according to the suggestions 
+ * from Bruce Evans. Thanks Bruce. Please report the problems to
+ * H.J. Lu (hlu@eecs.wsu.edu).
+ */
+
+/*
+ * I took out the bits commented out by #if 1...#else    - RHP
+ */
+
+    /*  VMIN = 0 means non-blocking for Linux */
+    t->c_cc[VMIN] = 1; t->c_cc[VTIME] = 1;
+    /* clear some bits with &= ~(bits), set others with |= */
+    t->c_cflag &= ~(CSIZE|PARENB|CSTOPB);
+    t->c_cflag |=  (CS8|HUPCL|CREAD);
+    t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INPCK|ISTRIP);
+    t->c_iflag &= ~(INLCR|IGNCR|ICRNL|IXON|IXOFF);
+    t->c_iflag |=  (BRKINT|IGNPAR);
+    t->c_oflag &= ~(OPOST|OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL);
+    t->c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
+    t->c_oflag |=  (ONLCR|NL0|CR0|TAB3|BS0|VT0|FF0);
+    t->c_lflag &= ~(ISIG|ICANON|IEXTEN|ECHO|ECHOE|ECHOK|ECHONL);
+    t->c_lflag &= ~(NOFLSH|XCASE);
+    t->c_lflag &= ~(ECHOPRT|ECHOCTL|ECHOKE);
+}
+#endif
+
+#endif
diff --git a/libc/termios/ttyname.c b/libc/termios/ttyname.c
new file mode 100644 (file)
index 0000000..897243e
--- /dev/null
@@ -0,0 +1,45 @@
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+char *
+ttyname(fd)
+int   fd;
+{
+   static char dev[] = "/dev";
+   struct stat st, dst;
+   DIR  *fp;
+   struct dirent *d;
+   static char name[NAME_MAX];
+   int noerr = errno;
+
+   if (fstat(fd, &st) < 0)
+      return 0;
+   if (!isatty(fd))
+   {
+      errno = ENOTTY;
+      return 0;
+   }
+
+   fp = opendir(dev);
+   if (fp == 0)
+      return 0;
+   strcpy(name, dev);
+   strcat(name, "/");
+
+   while ((d = readdir(fp)) != 0)
+   {
+      strcpy(name + sizeof(dev), d->d_name);
+      if (stat(name, &dst) == 0
+         && st.st_dev == dst.st_dev && st.st_ino == dst.st_ino)
+      {
+        closedir(fp);
+        errno = noerr;
+        return name;
+      }
+   }
+   closedir(fp);
+   errno = noerr;
+   return 0;
+}